def main(taskId=None):
    logging.basicConfig(level=logging.DEBUG)
    if taskId is None:
        tasks = m.Task.query.filter(
            m.Task.status.notin_([
                m.Task.STATUS_ARCHIVED, m.Task.STATUS_CLOSED,
                m.Task.STATUS_FINISHED
            ])).all()
    else:
        task = m.Task.query.get(taskId)
        if not task:
            raise ValueError('task {0} not found'.format(taskId))
        tasks = [task]

    for task in tasks:
        try:
            end_work_intervals(task)
        except:
            out = cStringIO.StringIO()
            traceback.print_exc(file=out)
            log.error(out.getvalue())
            SS.rollback()
            break
        else:
            log.info('task {} succeeded'.format(task.taskId))
            SS.commit()
Пример #2
0
def api(fn):
    @wraps(fn)
    def decorated(*args, **kwargs):
        '''
		api handlers generally return responses with mimetype set to json,
		this can be changed by returning a response instead (e.g. froma file
		download handler).
		'''
        try:
            result = fn(*args, **kwargs)
            if isinstance(result, dict):
                resp = jsonify(result)
            elif isinstance(result, Response):
                resp = result
            else:
                raise RuntimeError, 'unexpected datatype returned from api handler'
        except InvalidUsage, e:
            resp = make_response(jsonify(e.to_dict()), e.status_code, {})
            SS.rollback()
        except HTTPException, e:
            #
            # Normally we should not end up being here because all api
            # handlers are suppose to raise InvalidUsage and such Exceptions
            # should be caught by api version blueprint's error handler.
            # In case there are non-compliant handlers that are still using
            # using HTTPException directly, we explicitly convert it to a
            # JSON response.
            #
            resp = make_response(jsonify({'error': '%s' % e}), e.code, {})
            SS.rollback()
Пример #3
0
def create_language(self):
    desc = json.loads(self.Message)
    data = util.edm.decode_changes('Language', desc['changes'])
    current_app.logger.info(
        'a language is being created using {}'.format(data))
    try:
        lang = m.Language.query.filter(m.Language.name == data['name']).one()
        current_app.logger.info(
            'found language {}, applying changes {}'.format(lang.name, data))
        changes = {}
        for k, v in data.iteritems():
            try:
                if getattr(lang, k) != v:
                    setattr(lang, k, v)
                    changes[k] = v
            except AttributeError:
                continue
        current_app.logger.debug('actual changes {}'.format(changes))
        SS.flush()
        SS.commit()
    except sqlalchemy.orm.exc.NoResultFound:
        SS.rollback()
        lang = m.Language(**data)
        SS.add(lang)
        SS.flush()
        SS.commit()
Пример #4
0
def api(fn):
	@wraps(fn)
	def decorated(*args, **kwargs):
		'''
		api handlers generally return responses with mimetype set to json,
		this can be changed by returning a response instead (e.g. froma file
		download handler).
		'''
		try:
			result = fn(*args, **kwargs)
			if isinstance(result, dict):
				resp = jsonify(result)
			elif isinstance(result, Response):
				resp = result
			else:
				raise RuntimeError, 'unexpected datatype returned from api handler'
		except InvalidUsage, e:
			resp = make_response(jsonify(e.to_dict()), e.status_code, {})
			SS.rollback()
		except HTTPException, e:
			#
			# Normally we should not end up being here because all api
			# handlers are suppose to raise InvalidUsage and such Exceptions
			# should be caught by api version blueprint's error handler.
			# In case there are non-compliant handlers that are still using
			# using HTTPException directly, we explicitly convert it to a
			# JSON response.
			#
			resp = make_response(jsonify({'error': '%s' % e}), e.code, {})
			SS.rollback()
Пример #5
0
def create_person(self):
    desc = json.loads(self.Message)
    globalId = desc['global_id']
    data = util.edm.decode_changes('Person', desc['changes'])
    iso3 = data.pop('_countryIso3', None)

    if iso3:
        try:
            country = m.Country.query.filter(m.Country.iso3 == iso3).one()

        # country not found - create country from edm
        except sqlalchemy.orm.exc.NoResultFound:
            result = util.edm.get_country(iso3)
            country_data = dict(
                name=result['name_eng'],
                iso2=result['iso2'],
                iso3=iso3,
                isoNum=result['iso_num'],
                internet=result['internet'],
                active=result['active'],
            )
            country = m.Country(**country_data)
            SS.add(country)

        data['countryId'] = country.countryId

    try:
        user = m.User.query.filter_by(emailAddress=data['emailAddress']).one()

    # user not found via email address - create user
    except sqlalchemy.orm.exc.NoResultFound:
        user = m.User(**data)
        user.globalId = globalId
        SS.add(user)
        current_app.logger.info('user {0} was created using {1}'.format(
            user.userId, data))

    # user found via email address - apply updates
    else:
        for k, v in data.items():
            if k == 'emailAddress':
                continue
            setattr(user, k, v)
        user.globalId = globalId
        current_app.logger.info('user {0} was updated using {1}'.format(
            user.userId, data))

    current_app.logger.info("committing create_person changes")

    try:
        SS.commit()
    except (psycopg2.Error, sqlalchemy.exc.IntegrityError), e:
        current_app.logger.error(
            "error while committing create_person changes, rolling back: {0}".
            format(e))
        SS.rollback()
        raise
Пример #6
0
def main(taskId=None):
    logging.basicConfig(level=logging.DEBUG)
    log.debug('collapsing payable events, taskId={}'.format(taskId))
    try:
        collapse_payable_events()
    except Exception, e:
        out = cStringIO.StringIO()
        traceback.print_exc(file=out)
        log.error(out.getvalue())
        SS.rollback()
Пример #7
0
def main(taskId=None):
    logging.basicConfig(level=logging.DEBUG)
    progress_work_intervals()
    if taskId is None:
        tasks = m.Task.query.filter(
            m.Task.status.notin_([
                m.Task.STATUS_ARCHIVED, m.Task.STATUS_CLOSED,
                m.Task.STATUS_FINISHED
            ])).all()
    else:
        task = m.Task.query.get(taskId)
        if not task:
            raise ValueError('task {0} not found'.format(taskId))
        tasks = [task]

    payroll_data = ao.get_payroll()

    # print 'payroll to use for payment submission:\n{}'.format(payroll_data)

    payrollId = payroll_data['payrollId']
    payroll = m.BasicPayroll.query.get(payrollId)
    if not payroll:
        payroll = m.BasicPayroll(payrollId=payrollId)
        SS.add(payroll)

    for task in tasks:
        try:
            update_payroll_status(task, payrollId)
        except:
            log.info('task {} failed'.format(task.taskId))
            out = cStringIO.StringIO()
            traceback.print_exc(file=out)
            log.error(out.getvalue())
            SS.rollback()
            # break
        else:
            log.info('task {} succeeded'.format(task.taskId))
            # SS.commit()
            pass
    SS.commit()

    # find all CalculatedPayment entries and send them as package
    payments = m.CalculatedPayment.query.filter(
        m.CalculatedPayment.receipt.is_(None)).filter(
            m.CalculatedPayment.payrollId == payrollId).filter(
                m.CalculatedPayment.unitCount > 0).all()
    # print 'payments to submit: ', len(payments)
    receipts = ao.send_payments(payments)
    # print receipts
    for cp in payments:
        cp.receipt = receipts.get(cp.calculatedPaymentId, None)
    SS.commit()
Пример #8
0
    def decorated(*args, **kwargs):
        '''
		api handlers generally return responses with mimetype set to json,
		this can be changed by returning a response instead (e.g. froma file
		download handler).
		'''
        try:
            result = fn(*args, **kwargs)
            if isinstance(result, dict):
                resp = jsonify(result)
            elif isinstance(result, Response):
                resp = result
            else:
                raise RuntimeError, 'unexpected datatype returned from api handler'
        except InvalidUsage, e:
            resp = make_response(jsonify(e.to_dict()), e.status_code, {})
            SS.rollback()
Пример #9
0
	def decorated(*args, **kwargs):
		'''
		api handlers generally return responses with mimetype set to json,
		this can be changed by returning a response instead (e.g. froma file
		download handler).
		'''
		try:
			result = fn(*args, **kwargs)
			if isinstance(result, dict):
				resp = jsonify(result)
			elif isinstance(result, Response):
				resp = result
			else:
				raise RuntimeError, 'unexpected datatype returned from api handler'
		except InvalidUsage, e:
			resp = make_response(jsonify(e.to_dict()), e.status_code, {})
			SS.rollback()
Пример #10
0
def _get_user(userId):
    user = m.User.query.get(userId)
    if user is None:
        # user not found locally
        try:
            user = edm.make_new_user(userId)
        except:
            # error getting user from edm
            user = None
        else:
            try:
                SS.add(user)
                SS.commit()
            except:
                # error adding user locally
                SS.rollback()
                user = None
    return user
Пример #11
0
def submit_batch(batchId):
    batch = m.Batch.query.get(batchId)
    if not batch:
        raise InvalidUsage(_('batch {0} not found').format(batchId))
    me = session['current_user']
    if batch.userId != me.userId:
        raise InvalidUsage(
            _('batch {0} is not owned by user {1}').format(batchId, me.userId))
    if not batch.isFinished:
        raise InvalidUsage(_('batch {0} is not finished').format(batchId))

    SS.rollback()
    batch = m.Batch.query.get(batchId)
    batch.submit(me, request.json)

    remaining = m.Batch.query.filter_by(subTaskId=batch.subTaskId).filter(
        m.Batch.onHold.isnot(True)).filter(m.Batch.userId.is_(None)).count()
    return jsonify(
        message=_('batch {0} has been submitted by user {1}').format(
            batchId, me.userId),
        remainingBatches=remaining,
    )
Пример #12
0
def update_country(self):
    desc = json.loads(self.Message)
    iso3 = desc['iso3']
    try:
        country = m.Country.query.filter(m.Country.iso3 == iso3).one()
        data = util.edm.decode_changes('Country', desc['changes'])
        current_app.logger.info('found country {}, applying changes {}'.format(
            country.name, data))
        changes = {}
        for k, v in data.items():
            try:
                if getattr(country, k) != v:
                    setattr(country, k, v)
                    changes[k] = v
            except AttributeError:
                continue
        current_app.logger.debug('actual changes {}'.format(changes))
        SS.flush()
        SS.commit()
    except sqlalchemy.orm.exc.NoResultFound:
        SS.rollback()
        current_app.logger.info(
            'country {} not found, get country from edm'.format(iso3))
        result = util.edm.get_country(iso3)
        data = dict(
            name=result['name_eng'],
            iso2=result['iso2'],
            iso3=iso3,
            isoNum=result['iso_num'],
            internet=result['internet'],
            active=result['active'],
        )
        country = m.Country(**data)
        SS.add(country)
        SS.flush()
        SS.commit()
        current_app.logger.info('country {} is added locally'.format(
            country.name))
    return
Пример #13
0
def update_language(self):
    desc = json.loads(self.Message)
    iso3 = desc['iso3']
    try:
        lang = m.Language.query.filter(m.Language.iso3 == iso3).one()
        data = util.edm.decode_changes('Language', desc['changes'])
        current_app.logger.info(
            'found language {}, applying changes {}'.format(lang.name, data))
        changes = {}
        for k, v in data.items():
            try:
                if getattr(lang, k) != v:
                    setattr(lang, k, v)
                    changes[k] = v
            except AttributeError:
                continue
        current_app.logger.debug('actual changes {}'.format(changes))
        SS.flush()
        SS.commit()
    except sqlalchemy.orm.exc.NoResultFound:
        SS.rollback()
        current_app.logger.info(
            'language {} not found, get language from edm'.format(iso3))
        result = util.edm.get_language(iso3)
        data = dict(
            name=result['name_eng'],
            iso2=result['iso2'],
            iso3=iso3,
            active=result['active'],
        )
        lang = m.Language(**data)
        SS.add(lang)
        SS.flush()
        SS.commit()
        current_app.logger.info('language {} is added locally'.format(
            lang.name))
    return
Пример #14
0
    def decorated(*args, **kwargs):
        '''
        api handlers generally return responses with mimetype set to json,
        this can be changed by returning a response instead (e.g. froma file
        download handler).
        '''
        try:
            result = fn(*args, **kwargs)
            if isinstance(result, dict):
                resp = jsonify(result)
            elif isinstance(result, Response):
                resp = result
            else:
                raise RuntimeError(
                    'unexpected datatype returned from api handler')
        except InvalidUsage as e:
            resp = make_response(jsonify(e.to_dict()), e.status_code, {})
            SS.rollback()
        except HTTPException as e:
            #
            # Normally we should not end up being here because all api
            # handlers are suppose to raise InvalidUsage and such Exceptions
            # should be caught by api version blueprint's error handler.
            # In case there are non-compliant handlers that are still using
            # using HTTPException directly, we explicitly convert it to a
            # JSON response.
            #
            resp = make_response(jsonify({'error': '%s' % e}), e.code, {})
            SS.rollback()
        except Exception as e:
            #
            # Oops! Caught unhandled exception, log what happend
            # and return an error response to client
            #
            # out = cStringIO.StringIO()
            # traceback.print_exc(file=out)
            # current_app.logger.error('\033[1;31mERROR caught inside api:\033[0m\n%s\n' % out.getvalue())

            # TODO: hide debug information for production deployment
            resp = make_response((jsonify({'error': '%s' % e}), 500, {}))
            SS.rollback()
        else:
            SS.commit()
        return resp
Пример #15
0
def update_person(self):
    desc = json.loads(self.Message)
    globalId = desc['global_id']
    data = util.edm.decode_changes('Person', desc['changes'])
    iso3 = data.pop('_countryIso3', None)

    if iso3:
        try:
            country = m.Country.query.filter(m.Country.iso3 == iso3).one()

        # country not found - create country from edm
        except sqlalchemy.orm.exc.NoResultFound:
            result = util.edm.get_country(iso3)
            country_data = dict(
                name=result['name_eng'],
                iso2=result['iso2'],
                iso3=iso3,
                isoNum=result['iso_num'],
                internet=result['internet'],
                active=result['active'],
            )
            country = m.Country(**country_data)
            SS.add(country)

        data['countryId'] = country.countryId

    try:
        user = m.User.query.filter(m.User.globalId == globalId).one()

    # user not found via appen ID - create user from edm
    except sqlalchemy.orm.exc.NoResultFound:
        current_app.logger.info(
            'user {} not found, get user from edm'.format(globalId))
        user = util.edm.make_new_user(globalId)
        SS.add(user)
        current_app.logger.info('user {} is added locally'.format(globalId))

    # user found via appen ID - apply changes
    else:
        current_app.logger.info('found user {}, applying changes {}'.format(
            globalId, data))
        changes = {}
        for k, v in data.items():
            try:
                if getattr(user, k) != v:
                    setattr(user, k, v)
                    changes[k] = v
            except AttributeError:
                continue

        current_app.logger.debug('actual changes {}'.format(changes))

    current_app.logger.info("committing update_person changes")

    try:
        SS.commit()
    except (psycopg2.Error, sqlalchemy.exc.IntegrityError), e:
        current_app.logger.error(
            "error while committing update_person changes, rolling back: {0}".
            format(e))
        SS.rollback()
        raise
Пример #16
0

@bp.route('/process', methods=['POST'])
def edm_callback():
    current_app.logger.debug('received incoming message {}'.format(
        request.data))
    try:
        return SnsMessage.processMessage(
            request, topics=current_app.config['EDM_TOPICS'])

    except MessageError, e:
        return make_response('%s' % e, 400)

    except psycopg2.IntegrityError, e:
        current_app.logger.error("database integrity error: {0}".format(e))
        SS.rollback()
        raise

    except Exception, e:
        out = cStringIO.StringIO()
        traceback.print_exc(file=out)
        current_app.logger.error('ERROR caught inside api:\n%s\n' %
                                 out.getvalue())
        # TODO: hide debug information for production deployment
        return make_response(_('internal server error: {}').format(e), 500)


@SnsMessage.message_handler(Type='SubscriptionConfirmation')
def confirm_subscription(self):
    current_app.logger.debug('confirming subscription from %s' %
                             self.SubscribeURL)
Пример #17
0
def create_app(config_name):
    app = Flask(__name__)
    app.config.from_object(config[config_name])
    config[config_name].init_app(app)
    db.init_app(app)
    audio_server.init_app(
        app, lambda: create_access_token(int(app.config["ADMIN_APPEN_ID"])))
    pdb.init_app(
        app, lambda: create_access_token(int(app.config["ADMIN_APPEN_ID"])))
    CORS(app, resources={'/api/1.0/*': {'origins': '*'}})

    logging.basicConfig(level=app.config["LOG_LEVEL"])

    public_url_patterns = map(re.compile, [
        '/static/',
        '/favicon.ico',
        '/edm',
        '/webservices',
        '/logout',
        '/authorization_response',
        '/health-check',
        "/api/1.0/status",
        "/api/1.0/get-token",
    ])
    json_url_patterns = map(re.compile, ['/whoami', '/api'])

    from app.api import api_1_0
    from app.edm import edm
    from app.tagimages import tagimages
    from app.webservices import webservices
    from app.views import views
    app.register_blueprint(api_1_0, url_prefix='/api/1.0/')
    app.register_blueprint(edm, url_prefix='/edm')
    app.register_blueprint(tagimages, url_prefix='/tagimages')
    app.register_blueprint(webservices, url_prefix='/webservices')
    app.register_blueprint(views, url_prefix='')

    oauth = OAuth()
    soteria = oauth.remote_app(
        'soteria',
        base_url=None,
        request_token_url=None,
        access_token_url=app.config['OAUTH2_TOKEN_ENDPOINT'],
        authorize_url=app.config['OAUTH2_AUTHORIZATION_ENDPOINT'],
        consumer_key=app.config['OAUTH2_CLIENT_ID'],
        consumer_secret=app.config['OAUTH2_CLIENT_SECRET'],
        request_token_params={
            'scope': 'user',
            'state': 'blah'
        },
    )

    @app.before_request
    def authenticate_request():
        # current_app.logger.debug('{} {}'.format(request.method, request.url))

        # do not authenticate public urls
        for p in public_url_patterns:
            if p.match(request.path):
                # current_app.logger.debug(\
                # 	'skip authencation for public url: {}'\
                # 	.format(request.url))
                return None

        # current_app.logger.debug('{} {}'.format(request.method, request.url))

        if not current_app.config['SSO_COOKIE_NAME']:
            check = lambda (x): True
        else:
            try:
                sso_cookie = request.cookies.get(
                    current_app.config['SSO_COOKIE_NAME'])
                appenId = jwt.decode(
                    sso_cookie,
                    current_app.config['APPEN_API_SECRET_KEY'])['appen_id']
                check = lambda (x): appenId == int(x)
            except:
                check = lambda (x): False

        # authenticate by cookie
        try:
            cookie_name = current_app.config['APP_COOKIE_NAME']
            cookie = request.cookies.get(cookie_name)
            if not cookie:
                raise RuntimeError('cookie {} not found'\
                 .format(cookie_name))

            secret = current_app.config['APP_COOKIE_SECRET']
            try:
                user_dict = auth.decode_cookie(cookie, secret)
                if not check(user_dict['REMOTE_USER_ID']):
                    # current_app.logger.debug('gnx cookie stale')
                    raise RuntimeError('gnx cookie is stale')
                user = m.User.query.get(user_dict['REMOTE_USER_ID'])
                session['current_user'] = user
                session['current_user_caps'] = user_dict['CAPABILITIES']
                session['current_user_type'] = user_dict['USER_TYPE']
                session['current_user_roles'] = user_dict['ROLES']
                return None
            except:
                raise RuntimeError('cookie corrupted or expired')

        except RuntimeError, e:
            # current_app.logger.debug('cookie authentication failed: {}'\
            # 	.format(e))
            pass

        # authenticate by header
        try:
            authorization_info = request.headers.get('authorization', None)
            # current_app.logger.debug('authorization header: {}'\
            # 	.format(authorization_info))
            if not authorization_info:
                raise RuntimeError('authorization header not found')
            try:
                globalId, token = authorization_info.split('~', 1)
            except:
                raise RuntimeError('unknown header format: {}'\
                  .format(authorization_info))
            try:
                result = util.go.check_token_for_user(globalId)
                current_app.logger.debug('token info: {}'.format(result))
                # result = {
                # 	'token': token,
                # 	'expires_at': 'something',
                # 	'appen_id': 15517,
                # 	'app_id': 'appen_global'
                # }
            except RuntimeError, e:
                # token validation failed, return 500 to indicate server error
                return make_response(jsonify(error=\
                 _('token validation failed: {}').format(e), ), 500)

            token_should_be = result.get('token', None)
            if token != token_should_be:
                raise RuntimeError(\
                 'token validation failed: expecting {}, got {}'\
                 .format(token_should_be, token))

            current_app.logger.debug(
                'token validation passed, add user if necessary')
            try:
                user = m.User.query.filter(m.User.globalId == globalId).one()
                current_app.logger.debug('found local user {}'\
                 .format(user.emailAddress))
            except NoResultFound:
                SS.rollback()
                current_app.logger.debug(\
                 'user {} not found, get it from edm'.format(globalId))
                try:
                    user = util.edm.make_new_user(globalId)
                    SS.add(user)
                    SS.flush()
                    SS.commit()
                except Exception, e:
                    SS.rollback()
                    current_app.logger.error(\
                     'failed to add user locally: {}'.format(e))
                    return make_response(\
                     jsonify(error=_('failed to add user {} locally'\
                      ).format(globalId), ), 500)
Пример #18
0
			# JSON response.
			#
			resp = make_response(jsonify({'error': '%s' % e}), e.code, {})
			SS.rollback()
		except Exception, e:
			#
			# Oops! Caught unhandled exception, log what happend
			# and return an error response to client
			#
			out = cStringIO.StringIO()
			traceback.print_exc(file=out)
			current_app.logger.error('\033[1;31mERROR caught inside api:\033[0m\n%s\n' % out.getvalue())

			# TODO: hide debug information for production deployment
			resp = make_response((jsonify({'error': '%s' % e}), 500, {}))
			SS.rollback()
		else:
			SS.commit()
		return resp
	return decorated


def caps(*caps):
	def customized_decorator(fn):
		@wraps(fn)
		def decorated(*args, **kwargs):
			user = session['current_user']
			missing = set(caps) - set(getattr(user, 'caps', set()))
			if missing:
				raise InvalidUsage(
					_('not enough capabilities to perform requested operation'),