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 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 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) 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 submit_sheet(sheetId): sheet = m.Sheet.query.get(sheetId) if not sheet: raise InvalidUsage(_('sheet {0} not found').format(sheetId), 404) me = session['current_user'] if sheet.userId != me.userId: raise InvalidUsage( _('you are not the owner of sheet {0}').format(sheetId)) now = datetime.datetime.utcnow().replace(tzinfo=pytz.utc) if sheet.status == m.Sheet.STATUS_EXPIRED: raise InvalidUsage(_('sheet {0} has expired already').format(sheetId)) elif sheet.status == m.Sheet.STATUS_FINISHED: raise InvalidUsage(_('sheet {0} is finished already').format(sheetId)) elif sheet.status == m.Sheet.STATUS_SHOULD_EXPIRE: # if sheet.tExpiresBy < now: sheet.tExpiredAt = now SS.flush() SS.commit() raise InvalidUsage(_('sheet {0} has expired already').format(sheetId)) finished = all([entry.answerId != None for entry in sheet.entries]) if not finished: raise InvalidUsage(_('sheet {0} is not finished').format(sheetId)) sheet.tFinishedAt = now SS.flush() # TODO: define autoScoring property on sheet autoScoring = all([i.question.autoScoring for i in sheet.entries]) if autoScoring: passed = mark_answer_sheet(sheet) if passed: message = _(sheet.test.messageSuccess) or _( 'Congratulations, you passed!', 'Your score is {0}.').format( sheet.score) else: message = _(sheet.test.messageFailure) or _( 'Sorry, you failed.', 'Your score is {0}.').format(sheet.score) else: message = _( 'Thank you for taking the test!', 'The translation supervisor will be marking your test in next 7-10 working days,', 'and your result will then be available in AppenOnline.') return jsonify({ 'message': message, })
def submit_answer(sheetId): sheet = m.Sheet.query.get(sheetId) if not sheet: raise InvalidUsage(_('sheet {0} not found').format(sheetId), 404) now = datetime.datetime.utcnow().replace(tzinfo=pytz.utc) if sheet.tExpiresBy < now: sheet.tExpiredAt = now SS.flush() SS.commit() raise InvalidUsage(_('sheet {0} has expired already').format(sheetId)) me = session['current_user'] if sheet.userId != me.userId: raise InvalidUsage( _('you are not the owner of sheet {0}').format(sheetId)) data = MyForm( Field('sheetEntryId', is_mandatory=True, validators=[ (check_sheet_entry_existence, (sheetId, )), ]), Field('answer', is_mandatory=True, validators=[ validators.is_string, check_answer, ]), ).get_data(with_view_args=False) answer = m.Answer(**data) SS.add(answer) SS.flush() assert answer.answerId # TODO: define relationship on SheetEntry entry = m.SheetEntry.query.get(data['sheetEntryId']) entry.answerId = answer.answerId return jsonify({ 'message': _('created answer {0} successfully').format(answer.answerId), 'answer': m.Answer.dump(answer), })
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 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_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 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
m.PayableEvent.rawPieceId, m.PayableEvent.workEntryId, m.PayableEvent.batchId, m.PayableEvent.pageId).having(func.count('*') > 1) for rawPieceId, workEntryId, batchId, pageId in q_keys.all(): events = m.PayableEvent.query.filter( m.PayableEvent.rawPieceId == rawPieceId).filter( m.PayableEvent.workEntryId == workEntryId).filter( m.PayableEvent.batchId == batchId).filter( m.PayableEvent.pageId == pageId).order_by( m.PayableEvent.created).all() while events: ev = events.pop(0) # delete event if it is neither paid nor the latest if ev.calculatedPaymentId is None and events: SS.delete(ev) 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() else: log.info('succeeded') SS.commit()
def create_product(): data = MyForm().get_data() product = m.Product(**data) SS.add(product) SS.commit() return dict(value=m.Product.dump(product), )
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'), 403, {'missing': list(missing)}
def create_user(): data = MyForm().get_data() user = m.User(**data) SS.add(user) SS.commit() return dict(value=m.User.dump(user), )
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)
def create_merchandise(): data = MyForm().get_data() merchandise = m.Merchandise(**data) SS.add(merchandise) SS.commit() return dict(value=m.Merchandise.dump(merchandise), )