Example #1
0
	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')
Example #2
0
    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')
Example #3
0
    def test_with_undefined_domain(self):
        _.domain('jp')

        self.assertEqual(_('potato'), 'potato')
        self.assertEqual(_('rice'), 'rice')
        self.assertEqual(_('milkfish'), 'milkfish')
        self.assertEqual(_('banana'), 'banana')
Example #4
0
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),
    })
Example #5
0
 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')
Example #7
0
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),
    })
Example #8
0
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')
Example #10
0
    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")
Example #12
0
    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')
Example #13
0
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
Example #14
0
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)
Example #15
0
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')
Example #16
0
 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
Example #17
0
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))
Example #18
0
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
Example #19
0
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)
Example #20
0
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),
    })
Example #21
0
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))
Example #22
0
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
Example #23
0
 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
Example #24
0
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
Example #25
0
 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
Example #26
0
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')
Example #27
0
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)])
Example #28
0
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,
    })
Example #29
0
 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))
Example #30
0
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),
    })
Example #31
0
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'),
    })
Example #32
0
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}),
    })
Example #33
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()])
Example #34
0
 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)
Example #36
0
    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
Example #37
0
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)])
Example #38
0
	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
Example #40
0
		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)
Example #41
0
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)
Example #42
0
	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)
Example #43
0
 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 {} {}')
Example #44
0
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)
Example #46
0
    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)
Example #50
0
	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)
Example #52
0
	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'))
Example #53
0
	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)
Example #55
0
	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)
Example #57
0
 def test_command_param_translate(self):
     self.assertEqual(_('price'), 'harga')
     self.assertEqual(_('all'), 'semua')
Example #58
0
 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)