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()
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()
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()
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
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()
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()
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()
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
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, )
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
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
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
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
@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)
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)
# 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'),