def is_bool(cls, data, key, value): if value is not None: if not (value is True or value is False): # expression: # value not in (False, True) # won't work because 1 == True is always True raise ValueError, _('value must be a boolean')
def execute(self): cmd = self.command user = self.command.sms.user if RECORD_SELL not in user.permissions: logging.info('{} - User {} does not have permission {}'.format( cmd.sms.id, user.id, RECORD_SELL)) return _('Command not allowed') harvest_total = Farm.query(ndb.AND(Farm.district_id == user.district_id, Farm.crop_name == cmd.plant, Farm.action == 'harvest')).get() if not harvest_total or harvest_total.quantity < cmd.amount: logging.info('{} - Not enough {} harvested'.format(cmd.sms.id, cmd.plant)) return _('Not enough {} harvested').format(cmd.plant) sell_total = Farm.query(ndb.AND(Farm.district_id == user.district_id, Farm.crop_name == cmd.plant, Farm.action == 'sell')).get() if not sell_total: sell_total = Farm(id=Farm.id(), district_id=user.district_id, action=self.CMD, crop_name=cmd.plant, quantity=0) harvest_total.quantity -= cmd.amount harvest_total.put() sell_total.quantity += cmd.amount sell_total.put() return _('Sell command succeeded')
def test_with_undefined_domain(self): _.domain('jp') self.assertEqual(_('potato'), 'potato') self.assertEqual(_('rice'), 'rice') self.assertEqual(_('milkfish'), 'milkfish') self.assertEqual(_('banana'), 'banana')
def assign_batch_to_user(batchId, userId): batch = m.Batch.query.get(batchId) if not batch: raise InvalidUsage(_('batch {0} not found').format(batchId), 404) user = m.User.query.get(userId) if not user: raise InvalidUsage(_('user {0} not found').format(userId), 404) # TODO: perform more checks according to policy if policy.active_worker_only: if m.TaskWorker.query.filter_by(taskId=batch.taskId).filter_by( subTaskId=batch.subTaskId).filter_by(userId=userId).filter_by( removed=False).count() == 0: raise InvalidUsage( _('user {0} is not working on sub task {1}').format( userId, batch.subTaskId)) # TODO: change time from naive to timezone aware batch.leaseGranted = datetime.utcnow().replace(tzinfo=pytz.utc) # batch.leaseGranted = datetime.now() batch.leaseExpires = batch.leaseGranted + batch.subTask.defaultLeaseLife batch.user = user SS.flush() return jsonify({ 'message': _('batch {0} has been assigned to user {1}, expires at {2}').format( batchId, user.userName, batch.leaseExpires), 'batch': m.Batch.dump(batch), })
def create_label_group(labelSetId): ''' creates a new label group ''' labelSet = m.LabelSet.query.get(labelSetId) if not labelSet: raise InvalidUsage( _('label set {0} not found').format(labelSetId), 404) data = MyForm( Field('name', is_mandatory=True, validators=[ validators.is_string, (check_label_group_name_uniqueness, (labelSetId, None)), ]), Field('dropDownDisplay', default=False, validators=[ validators.is_bool, ]), Field('isMandatory', default=False, validators=[ validators.is_bool, ]), ).get_data() labelGroup = m.LabelGroup(**data) SS.add(labelGroup) SS.flush() return jsonify({ 'message': _('created label group {0} successfully').format(labelGroup.name), 'labelGroup': m.LabelGroup.dump(labelGroup), })
def create_sub_task_rate_record(subTaskId): subTask = m.SubTask.query.get(subTaskId) if not subTask: raise InvalidUsage(_('sub task {0} not found').format(subTaskId)) data = MyForm( Field('rateId', is_mandatory=True, validators=[]), Field('multiplier', is_mandatory=True, normalizer=lambda data, key, value: float(value), validators=[ (validators.is_number, (), dict(min_value=0)), ]), Field('bonus', default=None, validators=[ (validators.is_number, (), dict(ge=0)), ]), ).get_data() me = session['current_user'] subTaskRate = m.SubTaskRate(taskId=subTask.taskId, updatedBy=me.userId, **data) SS.add(subTaskRate) SS.flush() return jsonify({ 'message': _('created sub task rate {0} successfully').format( subTaskRate.subTaskRateId), 'subTaskRate': m.SubTaskRate.dump(subTaskRate), })
def execute(self): """ Update plant totals """ cmd = self.command user = cmd.sms.user if RECORD_PLANT not in user.permissions: logging.info('{} - User {} does not have permission {}'.format( cmd.sms.id, user.id, RECORD_PLANT)) return _('Command not allowed') plant = Farm.query(ndb.AND(Farm.district_id == user.district_id, Farm.crop_name == cmd.plant, Farm.action == 'plant')).get() if not plant: plant = Farm(id=Farm.id(), district_id=user.district_id, action=self.CMD, crop_name=cmd.plant, quantity=0) plant.quantity += cmd.amount plant.put() return _('Plant command succeeded')
def test_with_domain(self): _.domain('idn') self.assertEqual(_('potato'), 'kentang') self.assertEqual(_('rice'), 'padi') self.assertEqual(_('milkfish'), 'bandeng') self.assertEqual(_('banana'), 'pisang')
def execute(self): """ Update plant and harvest totals """ cmd = self.command user = cmd.sms.user if RECORD_HARVEST not in user.permissions: logging.info("{} - User {} does not have permission {}".format(cmd.sms, user.id, RECORD_HARVEST)) return _("Command not allowed") plant_total = Farm.query( ndb.AND(Farm.district_id == user.district_id, Farm.crop_name == cmd.plant, Farm.action == "plant") ).get() if not plant_total or plant_total.quantity < cmd.amount: logging.info("{} - Not enough {} planted".format(cmd.sms.id, cmd.plant)) return _("Not enough {} planted").format(cmd.plant) harvest_total = Farm.query( ndb.AND(Farm.district_id == user.district_id, Farm.crop_name == cmd.plant, Farm.action == "harvest") ).get() if not harvest_total: harvest_total = Farm( id=Farm.id(), district_id=user.district_id, action=self.CMD, crop_name=cmd.plant, quantity=0 ) plant_total.quantity -= cmd.amount plant_total.put() harvest_total.quantity += cmd.amount harvest_total.put() return _("Harvest command succeeded")
def execute(self): user = self.command.sms.user words = self.command.msg.split() message = self.command.msg farmers = None district = None for i in range(self.MULTI_DISTRICT_LIMIT): if district: message = ' '.join(words[i - 1:]) break district_name = ' '.join(words[:i]) slug = district_name.lower() district = District.query(District.slug == slug).get() if BROADCAST_ALL in user.permissions: # district must be specified if self.command.district != EVERYONE and not district: logging.info('{} - District {} is unknown'.format( self.command.sms.id, words[0])) return _('District {} is unknown').format(words[0]) if self.command.district == EVERYONE: farmers = User.query(User.role == User.ROLE_FARMER).fetch() if district: farmers = User.query( ndb.AND(User.role == User.ROLE_FARMER, User.district_id == district.key.id())).fetch() elif BROADCAST_OWN_DISTRICT in user.permissions: if self.command.district == EVERYONE: words.insert(0, EVERYONE) # own district is not specified but valid if not district or \ (district and district.key.id() != user.district_id): message = ' '.join(words) farmers = User.query( ndb.AND(User.role == User.ROLE_FARMER, User.district_id == user.district_id)).fetch() else: return _('Command not allowed') phone_numbers = [farmer.phone_number for farmer in farmers] if phone_numbers: taskqueue.add(queue_name=self.QUEUE_NAME, url=self.QUEUE_URL, payload=json.dumps({ 'task': { 'phone_numbers': phone_numbers, 'message': message } })) return _('Message delivered') return _('Message delivery failed')
def normalize_u(data, key, value): try: userId = int(data['u']) except KeyError: raise ValueError(_('userId must be specified by parameter u')) except ValueError: raise ValueError(_('invalid user id: {0}').format(data['u'])) return userId
def check_label_shortcut_key_uniqueness(data, key, shortcutKey, labelSetId, labelId): if shortcutKey is not None: if m.Label.query.filter_by(labelSetId=labelSetId).filter_by( shortcutKey=shortcutKey).filter( m.Label.labelId != labelId).count() > 0: raise ValueError, _( 'shortcut key \'{0}\' is already in use').format(shortcutKey)
def check_test_size(data, key, size): if data['testType'] == 'static': if size is not None: raise ValueError, _('size must not be specified for static tests') else: pool = m.Pool.query.get(data['poolId']) if size > len(pool.questions): raise ValueError, _('test size must not be greater than pool size')
def validate(self, data, output): key = self.name # print '\033[1;32m' # print '=' * 80 # print '\033[0;36m' # print 'validating', key # print '\033[1;34m' # print '-' * 80 # print '\033[0m' if key in data: value = data[key] else: if self.default is not None: value = self.default() if callable( self.default) else self.default else: if self.is_mandatory: raise InvalidUsage( _('{0}: mandatory parameter missing').format(key)) # non-mandatory parameter is omitted, skip further validation return try: if self.normalizer: # # use output as context, this makes it possible # to pass in extra parameters to normalizers # either as view_args, or mandatory parameters # value = self.normalizer(output, key, value) # #value = self.normalizer(data, key, value) # for func, args, kwargs in self.validators: # # Note: # To make context-aware validators work properly, # we use normalized output as context, as below: # func(output, key, value, *args, **kwargs) # # instead of following: # # func(data, key, value, *args, **kwargs) # # This is because validators of later fields # may need to work on normalized values # except ValueError as exc: raise InvalidUsage(_('{0}: {1}').format(key, exc)) except Exception as exc: # out = cStringIO.StringIO() # traceback.print_exc(file=out) # error = out.getvalue() # current_app.logger.error('\033[1;31mERROR caught inside validate():\033[0m\n%s\n' % error) raise raise RuntimeError(_('{0}: {1}').format(key, exc)) output[key] = value return
def check_sub_task_attribute(data, key, subTaskId, **kwargs): subTask = m.SubTask.query.get(subTaskId) if not subTask: raise ValueError, _('sub task {0} not found') for key, value in kwargs.iteritems(): if getattr(subTask, key) != value: raise ValueError, _( 'unexpected value of {0}, expecting {1}, got {2}').format( key, value, getattr(subTask, key))
def normalize_prority_expression(data, key, value): literal = str(value) if not re.match(r'\+?\d+$', literal): raise ValueError, _('invalid priority expression') if literal[0] == '+': value = lambda x: x + int(literal[1:]) else: value = lambda x: int(literal) return value
def check_label_group_existence(data, key, labelGroupId, labelSetId): if labelGroupId is not None: g = m.LabelGroup.query.get(labelGroupId) if not g: raise ValueError, _('label group {0} not found').format( labelGroupId) if g.labelSetId != labelSetId: raise ValueError, _( 'label group {0} does not belong to label set {1}').format( labelGroupId, labelSetId)
def update_label(labelSetId, labelId): ''' updates label settings ''' labelSet = m.LabelSet.query.get(labelSetId) if not labelSet: raise InvalidUsage( _('label set {0} not found').format(labelSetId), 404) label = m.Label.query.get(labelId) if not label or label.labelSetId != labelSetId: raise InvalidUsage(_('label {0} not found').format(lableId), 404) data = MyForm( Field('name', validators=[ (check_label_name_uniqueness, (labelSetId, labelId)), ]), Field('description'), Field('shortcutKey', validators=[ (validators.is_string, (), dict(length=1)), check_label_shortcut_key_non_space, (check_label_shortcut_key_uniqueness, (labelSetId, labelId)), ]), Field('extract', validators=[ validators.non_blank, (check_label_extract_uniqueness, (labelSetId, labelId)), ]), Field('labelGroupId', validators=[ (check_label_group_existence, (labelSetId, )), ]), Field('enabled', validators=[ validators.is_bool, ]), ).get_data() # data['labelSetId'] = labelSetId for key in data.keys(): value = data[key] if getattr(label, key) != value: setattr(label, key, value) else: del data[key] SS.flush() return jsonify({ 'message': _('updated label {0} successfully').format(labelId), 'updatedFields': data.keys(), 'label': m.Label.dump(label), })
def abandon_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)) batch.abandon() return jsonify(message=_( 'batch {0} has been abandoned by user {1}').format(batchId, me.userId))
def normalize_test_size(data, key, value): if data['testType'] == 'static': value = None else: if value is None: raise ValueError, _('size must be specified for dynamic tests') try: value = int(value) except: raise ValueError, _('invalid test size: {0}').format(size) return value
def register_handler(cls, name, func): if cls._registry.has_key(name): raise RuntimeError( _('file handler {0} already registered').format(name)) if not callable(func): raise RuntimeError(_('\'func\' must be a callable')) handler = super(FileHandler, cls).__new__(cls) handler.name = name handler.func = func cls._registry[name] = handler return handler
def normalize_test_requirement(data, key, value): if value is None: pool = m.Pool.query.get(data['poolId']) value = pool.meta else: try: d = json.loads(str(value)) except: raise ValueError, _('invalid requirement value: {0}').format(value) value = d return value
def validate(self): # check if all mandatory keys are present for key in self._KEYS['']: if key not in self._data: raise MessageError( _('invalid message: key missing: {}'.format(key))) for key in self._KEYS[self.Type]: if key not in self._data: raise MessageError( _('invalid message: key missing: {}'.format(key))) return True
def normalize_expiry_date_expression(data, key, value): literal = str(value) # print 'leaseExpires literal', `literal` try: if literal.startswith('+'): delay = int(literal[1:]) delta = datetime.timedelta(seconds=delay * 60 * 60) return lambda x: None if x is None else x + delta expires_by = iso8601.parse_date(literal) return lambda x: None if x is None else expires_by except: raise ValueError, _('invalid expiry date expression')
def filter_qa_severity(task, isMoreThan, score, isCorrect): try: assert isMoreThan in (MyFilter.TRUE, MyFilter.FALSE) except: raise ValueError(_('invalid option value: {}').format(isMoreThan)) else: isMoreThan = isMoreThan == MyFilter.TRUE try: assert isCorrect in (MyFilter.TRUE, MyFilter.FALSE) except: raise ValueError(_('invalid option value: {}').format(isCorrect)) else: isCorrect = isCorrect == MyFilter.TRUE try: score = float(score) except: raise ValueError(_('invalid score value: {}').format(score)) if isMoreThan: if isCorrect: predicate = lambda qaErrorSum: qaErrorSum == None or ( 1 - qaErrorSum) > score else: predicate = lambda qaErrorSum: qaErrorSum > score else: if correct: predicate = lambda qaErrorSum: 1 - (qaErrorSum or 0) < score else: predicate = lambda qaErrorSum: qaErrorSum == None or qaErrorSum < score # latest QA result q1 = SS.query(m.WorkEntry.entryId, m.WorkEntry.qaedEntryId, m.WorkEntry.rawPieceId).distinct( m.WorkEntry.qaedEntryId).filter( m.WorkEntry.taskId == task.taskId).filter( m.WorkEntry.workType == m.WorkType.QA).order_by( m.WorkEntry.qaedEntryId, m.WorkEntry.created.desc()) sub_q = q1.subquery('sub_q') stmt = SS.query(m.AppliedError.entryId, func.sum( m.AppliedError.severity).label('qaErrorSum')).group_by( m.AppliedError.entryId).subquery() q = SS.query(sub_q.c.rawPieceId, stmt.c.qaErrorSum).join(stmt, stmt.c.entryId == sub_q.c.entryId) return set([r.rawPieceId for r in q.all() if predicate(r.qaErrorSum)])
def delete_sub_task_qa_settings(subTaskId): subTask = m.SubTask.query.get(subTaskId) if not subTask: raise InvalidUsage(_('sub task {0} not found').format(subTaskId)) if subTask.qaConfig: SS.delete(subTask.qaConfig) message = _('deleted default QA settings of sub task {0}').format( subTaskId) else: message = _('sub task {0} does not have default QA settings').format( subTaskId) return jsonify({ 'message': message, })
def validate(self, data, output): key = self.name # print '\033[1;32m' # print '=' * 80 # print '\033[0;36m' # print 'validating', key # print '\033[1;34m' # print '-' * 80 # print '\033[0m' if key in data: value = data[key] else: if self.default is not None: value = self.default() if callable( self.default) else self.default else: if self.is_mandatory: raise InvalidUsage( _('{0}: mandatory parameter missing').format(key)) # non-mandatory parameter is omitted, skip further validation return try: if self.normalizer: # # use output as context, this makes it possible # to pass in extra parameters to normalizers # either as view_args, or mandatory parameters # value = self.normalizer(output, key, value) # #value = self.normalizer(data, key, value) # for func, args, kwargs in self.validators: # # Note: # To make context-aware validators work properly, # we use normalized output as context, as below: # func(output, key, value, *args, **kwargs) # # instead of following: # # func(data, key, value, *args, **kwargs) # # This is because validators of later fields # may need to work on normalized values # except ValueError, exc: raise InvalidUsage(_('{0}: {1}').format(key, exc))
def create_alphabet(): data = MyForm( Field('name', is_mandatory=True, validators=[ validators.non_blank, check_name_uniqueness, ]), Field('description'), Field('dialectId', is_mandatory=True, validators=[ validators.is_number, check_dialect_existence, ]), Field( 'url', default=lambda: None, ), ).get_data() alphabet = m.Alphabet(**data) SS.add(alphabet) SS.flush() return jsonify({ 'message': _('created alphabet {0} successfully').format(alphabet.name), 'alphabet': m.Alphabet.dump(alphabet), })
def get_alphabet(alphabetId): alphabet = m.Alphabet.query.get(alphabetId) if not alphabet: raise InvalidUsage(_('alphabet {0} not found').format(taskId), 404) return jsonify({ 'alphabet': m.Alphabet.dump(alphabet, use='full'), })
def get_pool(poolId): pool = m.Pool.query.get(poolId) if not pool: raise InvalidUsage(_('pool {0} not found').format(poolId), 404) return jsonify({ 'pool': m.Pool.dump(pool, context={'level': 0}), })
def filter_qa_error_type(task, errorTypeId): try: errorTypeId = int(erorrTypeId) except: raise ValueError(_('invalid error type id: {}').format(errorTypeId)) taskErrorType = m.TaskErrorType.query.get((task.taskId, errorTypeId)) if not taskErrorType: return set() # latest QA result inner = SS.query( m.WorkEntry.entryId, m.WorkEntry.qaedEntryId, m.WorkEntry.rawPieceId).distinct(m.WorkEntry.qaedEntryId).filter( m.WorkEntry.taskId == task.taskId).filter( m.WorkEntry.workType == m.WorkType.QA).order_by( m.WorkEntry.qaedEntryId, m.WorkEntry.created.desc()) sub_q = inner.subquery('sub_q') q = SS.query(sub_q.c.rawPieceId).distinct(sub_q.c.rawPieceId).join( m.AppliedError, m.AppliedError.entryId == sub_q.c.entryId).filter( m.AppliedError.errorTypeId == errorTypeId) return set([r.rawPieceId for r in q.all()])
def get_data(self, with_view_args=True, is_json=True, copy=False, use_args=False): if is_json: try: data = request.get_json() or {} if use_args: data.update(request.args) except Exception as exc: raise InvalidUsage( _('error decoding json from incoming request')) else: data = request.values data = CombinedMultiDict([data, request.files]) output = {} if copy: # for some reason, following statement doesn't work # output.update(data) # so we have to use following statement for k in data.keys(): output[k] = data[k] if with_view_args: output.update(request.view_args) for key in self.field_names: f = self.field_by_name[key] f.validate(data, output) return output
def test_broadcast(self): # add farmers User(role="farmer", phone_number="123", first_name="farmer1", district_id="sum123").put() res = self.send("broadcast hello world") self.assertIn(_("Message delivered"), res.data)
def select(selection): # TODO: implemet this taskId = getattr(selection, 'taskId') task = m.Task.query.get(taskId) if taskId is None: raise ValueError(_('must specify taskId')) filters = { True: {}, # inclusive False: {}, # exclusive } for f in selection.filters: filters[f.isInclusive].setdefault(f.filterType, []).append(f) rs = set([ r.rawPieceId for r in SS.query(m.RawPiece.rawPieceId).filter( m.RawPiece.taskId == taskId) ]) for filter_type, fs in filters[True].iteritems(): result = reduce(operator.or_, [MyFilter.run(f, task) for f in fs]) rs &= result for filter_type, fs in filters[False].iteritems(): result = reduce(operator.or_, [MyFilter.run(f, task) for f in fs]) rs -= result rs = sorted(rs) if selection.limit != None: limit = min(selection.limit, len(rs)) rs = random.sample(rs, limit) return rs
def filter_sub_task_work(task, workOption, subTaskId): try: subTaskId = int(subTaskId) except: raise ValueError(_('invalid sub task id: {}').format(subTaskId)) subTask = m.SubTask.query.get(subTaskId) if not subTask or subTask.taskId != task.taskId: return set() inner = SS.query(m.WorkEntry.rawPieceId, m.WorkEntry.subTaskId).distinct( m.WorkEntry.rawPieceId).filter(m.WorkEntry.taskId == task.taskId) if workOption == MyFilter.ANY: inner = inner.filter(m.WorkEntry.subTaskId == subTaskId) elif workOption == MyFilter.FIRST: inner = inner.order_by(m.WorkEntry.rawPieceId, m.WorkEntry.created) elif workOption == MyFilter.MOST_RECENT: inner = inner.order_by(m.WorkEntry.rawPieceId, m.WorkEntry.created.desc()) elif workOption == MyFilter.MOST_RECENT_MODIFIED: inner = inner.filter( m.WorkEntry.modifiesTranscription.is_(True)).order_by( m.WorkEntry.rawPieceId, m.WorkEntry.created.desc()) sub_q = inner.subquery('sub_q') sel_stmt = select([sub_q.c.rawPieceId], distinct=True, from_obj=sub_q).where(sub_q.c.subTaskId == subTaskId) return set([r.rawPieceId for r in SS.bind.execute(sel_stmt)])
def validate(self, data, output): key = self.name # print '\033[1;32m' # print '=' * 80 # print '\033[0;36m' # print 'validating', key # print '\033[1;34m' # print '-' * 80 # print '\033[0m' if key in data: value = data[key] else: if self.default is not None: value = self.default() if callable(self.default) else self.default else: if self.is_mandatory: raise InvalidUsage(_('{0}: mandatory parameter missing').format(key)) # non-mandatory parameter is omitted, skip further validation return try: if self.normalizer: # # use output as context, this makes it possible # to pass in extra parameters to normalizers # either as view_args, or mandatory parameters # value = self.normalizer(output, key, value) # #value = self.normalizer(data, key, value) # for func, args, kwargs in self.validators: # # Note: # To make context-aware validators work properly, # we use normalized output as context, as below: # func(output, key, value, *args, **kwargs) # # instead of following: # # func(data, key, value, *args, **kwargs) # # This is because validators of later fields # may need to work on normalized values # except ValueError, exc: raise InvalidUsage(_('{0}: {1}').format(key, exc))
def execute(self): filter = self.command.filter user = self.command.sms.user if RETRIEVE_ALL_DISTRICT not in user.permissions: logging.info('{} - User {} does not have permission {}'.format( self.command.sms.key.id(), user.key.id(), RETRIEVE_ALL_DISTRICT)) return _('Command not allowed') district_name = self.command.district slug = district_name.lower() district = District.query(District.slug == slug).get() if not district: logging.info('{} - District {} is unknown'.format( self.command.sms.key.id(), district_name)) return _('District {} is unknown').format(district_name) query = Farm.query(ndb.AND(Farm.action == filter, Farm.district_id == district.key.id())) crops = query.order(-Farm.ts_updated).fetch() if not crops: return _('{} data is none').format(_(filter)) response = _('Total {} in {}:').format(_(filter), district.name) for crop in crops: response += '\n{} {}'.format(_(crop.crop_name).title(), crop.quantity) return response
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)} ) return fn(*args, **kwargs)
def incoming_twilio_sms(): sms = SmsRequest(id=SmsRequest.id(), from_number=request.form.get('From'), to_number=request.form.get('To'), body=request.form.get('Body'), twilio_message_id=request.form.get('MessageSid'), from_city=request.form.get('FromCity'), from_state=request.form.get('FromState'), from_zip=request.form.get('FromZip'), from_country=request.form.get('FromCountry'), to_city=request.form.get('ToCity'), to_state=request.form.get('ToState'), to_zip=request.form.get('ToZip'), to_country=request.form.get('ToCountry')) if not sms.valid: app.logger.error(request) abort(400, 'invalid request') # store all sms for auditing sms.put() # load application data associated with the sms user = User.query(User.phone_number == sms.from_number).fetch() if not user: abort(400, 'The phone number {} does not belong to a user'.format(sms.from_number)) sms.user = user[0] response_twiml = twiml.Response() response_message = None # dispatch sms request try: response_message = dispatcher.dispatch(sms) except (NoRouteError, MultipleRouteError): response_message = _('Unknown command, valid format below:\n' 'PLANT [qty] [type]\n' 'HARVEST [qty] [type]\n' 'SELL [qty] [type]\n' 'BROADCAST [msg]') if response_message: config = Config.query().get() response_twiml.sms(to=sms.from_number, sender=config.twilio_phone_number, msg=response_message) # update sms processed state sms.processed = True sms.ts_processed = datetime.now() sms.put() return str(response_twiml)
def is_string(cls, data, key, value, length=None, max_length=None, min_length=None): if value is not None: if not isinstance(value, basestring): raise ValueError, _('value must of a string') if length is not None and len(value) != length: raise ValueError, _('value length must be {0}' ).format(length) if max_length is not None and len(value) > max_length: raise ValueError, _('value length must not be longer than {0}' ).format(max_length) if min_length is not None and len(value) < min_length: raise ValueError, _('value length must not be shorter than {0}' ).format(min_length)
def test_command_translate(self): self.assertEqual(_('harvest {} {}'), 'panen {} {}') self.assertEqual(_('plant {} {}'), 'tanam {} {}') self.assertEqual(_('sell {} {}'), 'jual {} {}') self.assertEqual(_('look {}'), 'lihat {}') self.assertEqual(_('look {} {}'), 'lihat {} {}') self.assertEqual(_('broadcast {} {}'), 'kirim {} {}')
def incoming_twilio_sms(): sms = SmsRequest( id=SmsRequest.id(), from_number=request.form.get("From"), to_number=request.form.get("To"), body=request.form.get("Body"), twilio_message_id=request.form.get("MessageSid"), from_city=request.form.get("FromCity"), from_state=request.form.get("FromState"), from_zip=request.form.get("FromZip"), from_country=request.form.get("FromCountry"), to_city=request.form.get("ToCity"), to_state=request.form.get("ToState"), to_zip=request.form.get("ToZip"), to_country=request.form.get("ToCountry"), ) if not sms.valid: app.logger.error(request) abort(400, "invalid request") # store all sms for auditing sms.put() # load application data associated with the sms user = User.query(User.phone_number == sms.from_number).fetch() if not user: abort(400, "The phone number {} does not belong to a user".format(sms.from_number)) sms.user = user[0] response_twiml = twiml.Response() response_message = None # dispatch sms request try: response_message = dispatcher.dispatch(sms) except (NoRouteError, MultipleRouteError): response_message = _("Unknown command") if response_message: config = Config.query().get() response_twiml.sms(to=sms.from_number, sender=config.twilio_phone_number, msg=response_message) # update sms processed state sms.processed = True sms.ts_processed = datetime.now() sms.put() return str(response_twiml)
def test_dispatcher_multiple_route_error(self, mock): mock.dispatch.side_effect = MultipleRouteError() res = self.app.post('/v1/sms/twilio', data={ 'MessageSid': 'sid', 'From': self.user.phone_number, 'To': '+321', 'Body': 'jual' }) # should return an sms response to the user self.assertEqual(200, res.status_code) self.assertEqual('<?xml version="1.0" encoding="UTF-8"?>' '<Response><Sms from="+321" to="+123">' '{}' '</Sms></Response>'.format(_('Unknown command')), res.data)
def test_dispatcher_no_route_error(self, mock): mock.dispatch.side_effect = NoRouteError() res = self.app.post('/v1/sms/twilio', data={ 'MessageSid': 'sid', 'From': self.user.phone_number, 'To': '+321', 'Body': 'jual' }) # should return an sms response to the user self.assertEqual(200, res.status_code) self.assertEqual('<?xml version="1.0" encoding="UTF-8"?>' '<Response><Sms from="+321" to="+123">' '{}' '</Sms></Response>'.format( _('Unknown command, valid format below:\n' 'PLANT [qty] [type]\n' 'HARVEST [qty] [type]\n' 'SELL [qty] [type]\n' 'BROADCAST [msg]')), res.data)
def test_should_respond_with_error_sms_when_not_enough_harvested(self): msg = SellAction(self._sell('potato', 100000)).execute() self.assertEqual(_('Not enough {} harvested').format('potato'), msg)
def test_should_respond_with_error_sms_when_not_enough_planted(self): msg = HarvestAction(self._harvest("potato", 100000)).execute() self.assertEqual(_("Not enough {} planted").format("potato"), msg)
def test_should_not_allow_user_without_permission(self): self.sms.user.role = None msg = HarvestAction(self._harvest("potato", 1)).execute() self.assertEqual(_("Command not allowed"), msg)
def is_number(cls, data, key, value, max_value=None, min_value=None, le=None, lt=None, gt=None, ge=None): if max_value is not None and value > max_value: raise ValueError, _('value {0} must not be greater than {1}' ).format(value, max_value) if min_value is not None and value < min_value: raise ValueError, _('value {0} must not be less than {1}' ).format(value, min_value) if le and not value <= le: raise ValueError, _('value {0} must be less than or equal to {1}' ).format(value, le) if lt and not value < lt: raise ValueError, _('value {0} must be less than {1}' ).format(value, lt) if ge and not value >= ge: raise ValueError, _('value {0} must be greater than or equal to {1}' ).format(value, ge) if gt and not value > gt: raise ValueError, _('value {0} must be greater than {1}' ).format(value, gt)
def test_should_respond_with_success(self): msg = HarvestAction(self._harvest("potato", 5)).execute() self.assertEqual(_("Harvest command succeeded"), msg)
def get_data(self, with_view_args=True, is_json=True, copy=False): if is_json: try: data = request.get_json() or {} except Exception, exc: raise InvalidUsage(_('error decoding json from incoming request'))
def not_null(cls, data, key, value): if value is None: raise ValueError, _('value must not be None')
def test_should_respond_with_success(self): msg = SellAction(self._sell('potato', 5)).execute() self.assertEqual(_('Sell command succeeded'), msg)
def is_mandatory(cls, data, key, value): if key not in data: raise ValueError, _('mandatory parameter missing')
def test_should_not_allow_user_without_permission(self): self.sms.user.role = None msg = SellAction(self._sell('potato', 1)).execute() self.assertEqual(_('Command not allowed'), msg)
def test_command_param_translate(self): self.assertEqual(_('price'), 'harga') self.assertEqual(_('all'), 'semua')
def test_with_undefined_phrase(self): self.assertEqual(_('tokyo'), 'tokyo') self.assertEqual(_('london'), 'london') self.assertEqual(_('bandung'), 'bandung')
def test_should_respond_with_success(self): msg = BroadcastAction( self._broadcast(self.user_leader, 'hello')).execute() self.assertEqual(_('Message delivered'), msg)
def test_hb_district_does_not_exist(self): msg = BroadcastAction( self._broadcast(self.user_hb, 'Sumatra hello')).execute() self.assertEqual(_('District {} is unknown').format('Sumatra'), msg)