def validate(self, value): if utils.is_string_type(value): try: value = json.loads(value) except JSONDecodeError as e: return str(e) if isinstance(value, collections.Mapping): value = [value] if utils.is_list_type(value): if len(value) < self.length_min: return _('length[%(length)s] < minimum length[%(minimum)s]') % { 'length': len(value), 'minimum': self.length_min } if self.length_max is not None and len(value) > self.length_max: return _('length[%(length)s] > maximum length[%(maximum)s]') % { 'length': len(value), 'maximum': self.length_max } for idx, item in enumerate(value): try: self.validate_func(self.rules, item, self.situation) except exceptions.Error as e: return _('validate failed for index[%(index)s], because: %(msg)s' % { 'index': idx + 1, 'msg': str(e) }) else: return _('expected type of list/tuple/set, not %(type)s ') % {'type': type(value).__name__} return True
def on_delete(self, req, resp, **kwargs): self._validate_method(req) self._validate_data(req) datas = req.json if not utils.is_list_type(datas): raise exceptions.BodyParseError(_('must be list type')) rets = [] ex_rets = [] for idx, data in enumerate(datas): try: res_instance = self.make_resource(req) ref_count, ref_details = self.delete(req, rid=data) rets.append(ref_details[0]) except exceptions.Error as e: ex_rets.append({'index': idx + 1, 'message': str(e)}) if len(ex_rets): raise my_exceptions.BatchPartialError( num=len(ex_rets), action='delete', exception_data={'data': ex_rets}) resp.json = { 'code': 200, 'status': 'OK', 'data': rets, 'message': 'success' } resp.status = falcon.HTTP_200
def on_post(self, req, resp, **kwargs): self._validate_method(req) self._validate_data(req) datas = req.json if not utils.is_list_type(datas): raise exceptions.PluginError(_('data must be list type')) rets = [] ex_rets = [] for idx, data in enumerate(datas): try: rets.append(self.create(req, data, **kwargs)) except base_ex.Error as e: ex_rets.append({'index': idx + 1, 'message': str(e)}) if len(ex_rets): raise exceptions.BatchPartialError( num=len(ex_rets), action='create', exception_data={'data': ex_rets}) resp.json = { 'code': 200, 'status': 'OK', 'data': rets, 'message': 'success' } resp.status = falcon.HTTP_200
def on_patch(self, req, resp, **kwargs): self._validate_method(req) self._validate_data(req) datas = req.json if not utils.is_list_type(datas): raise exceptions.BodyParseError(_('must be list type')) rets = [] ex_rets = [] for idx, data in enumerate(datas): try: res_instance = self.make_resource(req) if res_instance.primary_keys not in data: raise exceptions.FieldRequired( attribute=res_instance.primary_keys) rid = data.pop(res_instance.primary_keys) before_update, after_update = self.update(req, data, rid=rid) if after_update is None: raise exceptions.NotFoundError( resource='%s[%s]' % (self.resource.__name__, rid)) rets.append(after_update) except exceptions.Error as e: ex_rets.append({'index': idx + 1, 'message': str(e)}) if len(ex_rets): raise my_exceptions.BatchPartialError( num=len(ex_rets), action='update', exception_data={'data': ex_rets}) resp.json = { 'code': 200, 'status': 'OK', 'data': rets, 'message': 'success' } resp.status = falcon.HTTP_200
def _match_in(stores, value, value_cmp): if utils.is_list_type(value): tmp_result = False for v in value: if v in value_cmp: tmp_result = True break stores.add(True) if tmp_result else stores.add(False) else: stores.add(True) if value in value_cmp else stores.add(False)
def _match_ne(stores, value, value_cmp): if utils.is_list_type(value): tmp_result = True if not value: tmp_result = value_cmp != value else: for v in value: if value_cmp == v: tmp_result = False break stores.add(True) if tmp_result else stores.add(False) else: stores.add(True) if value_cmp != value else stores.add(False)
def _match_like(stores, value, value_cmp): if utils.is_list_type(value): tmp_result = False for v in value: if value_cmp in v: tmp_result = True break stores.add(True) if tmp_result else stores.add(False) else: if not utils.is_string_type(value): stores.add(False) else: stores.add(True) if value_cmp in value else stores.add(False)
def _match_nin(stores, value, value_cmp): if utils.is_list_type(value): tmp_result = True if not value: tmp_result = value not in value_cmp # every item in value not in value_cmp means true for v in value: if v in value_cmp: tmp_result = False break stores.add(True) if tmp_result else stores.add(False) else: stores.add(True) if value not in value_cmp else stores.add(False)
def expr_query(expr, ci_getter, ci_mapping): ''' fetch data according to expression :param expr: result of () :param ci_getter: function (expr_data, is_backref, guids) => {} ci_getter: if is_backref ci[with filters][expr_data.backref_attrubute].guid in guids else ci[with filters].guid in guids ''' results = [] is_backref = False guids = None expr_origin = expr expr_groups = expr_parse(expr_origin) for i in range(len(expr_groups)): expr = expr_groups[i] expr_data = expr['data'] if expr['type'] == 'expr': # user ci, backref_attribute.guid in guids[if is_backref], filters if guids is not None and len(guids) == 0: # can not find any data that match expression results = [] break results = ci_getter(expr_data, is_backref, guids, ci_mapping) guids = [] for j in range(len(results)): guid = "" if len(expr_data['attribute']) > 0: result_item = results[j]['data'][expr_data['attribute']] if utils.is_list_type(result_item): guids.extend([ i_result_item['guid'] for i_result_item in result_item ]) else: guid = result_item['guid'] else: guid = results[j]['data']['guid'] if guid: guids.append(guid) elif expr['type'] == 'op': if expr['value'] == '>' or expr['value'] == '->': is_backref = False elif expr['value'] == '~' or expr['value'] == '<-': is_backref = True return results
def _match_regex(stores, value, value_cmp, ignore_case=False): flag = 0 if ignore_case: flag = flag | re.IGNORECASE if utils.is_list_type(value): tmp_result = False for v in value: if re.search(value_cmp, v, flag): tmp_result = True break stores.add(True) if tmp_result else stores.add(False) else: if not utils.is_string_type(value): stores.add(False) else: stores.add(True) if re.search(value_cmp, value, flag) else stores.add(False)
def expr_match_input(expr_groups, ci_getter, input_data, ci_mapping): ''' fetch data according to expression by specific source(input_data), see if there are any matches :param expr_groups: result of expr_parse() :param ci_getter: function (expr_data, is_backref, guids) => {} :param input_data: list of input ci ci_getter: if is_backref ci[with filters][expr_data.backref_attrubute].guid in guids else ci[with filters].guid in guids ''' results = {} for el in input_data: is_backref = False guids = [] cur_data = [] for i in range(len(expr_groups)): expr = expr_groups[i] expr_data = expr['data'] # user input_data if i == 0: if len(expr_data['attribute']) > 0: guid = el['data'][expr_data['attribute']]['guid'] else: guid = el['data']['guid'] if guid: guids.append(guid) continue if expr['type'] == 'expr': # user ci, backref_attribute.guid in guids[if is_backref], filters if len(guids) == 0: # can not find any data that match expression cur_data = [] break cur_data = ci_getter(expr_data, is_backref, guids, ci_mapping) guids = [] for j in range(len(cur_data)): guid = "" if len(expr_data['attribute']) > 0: result_item = cur_data[j]['data'][ expr_data['attribute']] if utils.is_list_type(result_item): guids.extend([ i_result_item['guid'] for i_result_item in result_item ]) else: guid = result_item['guid'] else: guid = cur_data[j]['data']['guid'] if guid: guids.append(guid) elif expr['type'] == 'op': if expr['value'] == '>' or expr['value'] == '->': is_backref = False elif expr['value'] == '~' or expr['value'] == '<-': is_backref = True results[el['data']['guid']] = cur_data return results
def match_all(filters, data): ''' check if data match all filters :param filters: [{xx eq xx}, {...}] :param data: {...} ''' results = set([True]) for _filter in filters: val = utils.get_item(data, _filter['name']) if _filter['operator'] == 'set': results.add(True) if val else results.add(False) elif _filter['operator'] == 'notset': results.add(False) if val else results.add(True) elif _filter['operator'] == 'null': results.add(True) if val is None else results.add(False) elif _filter['operator'] == 'notNull': results.add(True) if val is not None else results.add(False) elif _filter['operator'] == 'ilike': if utils.is_list_type(val): tmp_result = False for v in val: if _filter['value'].lower() in v.lower(): tmp_result = True break results.add(True) if tmp_result else results.add(False) else: results.add(True) if _filter['value'].lower() in val.lower() else results.add(False) elif _filter['operator'] == 'like': if utils.is_list_type(val): tmp_result = False for v in val: if _filter['value'] in v: tmp_result = True break results.add(True) if tmp_result else results.add(False) else: results.add(True) if _filter['value'] in val else results.add(False) elif _filter['operator'] == 'eq': if utils.is_list_type(val): tmp_result = False for v in val: if _filter['value'] == v: tmp_result = True break results.add(True) if tmp_result else results.add(False) else: results.add(True) if _filter['value'] == val else results.add(False) elif _filter['operator'] == 'ne': if utils.is_list_type(val): tmp_result = True for v in val: if _filter['value'] == v: tmp_result = False break results.add(True) if tmp_result else results.add(False) else: results.add(True) if _filter['value'] != val else results.add(False) elif _filter['operator'] == 'in': if utils.is_list_type(val): tmp_result = False for v in val: if v in _filter['value']: tmp_result = True break results.add(True) if tmp_result else results.add(False) else: results.add(True) if val in _filter['value'] else results.add(False) elif _filter['operator'] == 'nin': if utils.is_list_type(val): results.add(False) else: results.add(True) if val not in _filter['value'] else results.add(False) elif _filter['operator'] in ('regex', 'iregex'): flag = 0 if _filter['operator'] == 'iregex': flag = flag | re.IGNORECASE if utils.is_list_type(val): tmp_result = False for v in val: if re.search(_filter['value'], v, flag): tmp_result = True break results.add(True) if tmp_result else results.add(False) else: results.add(True) if re.search(_filter['value'], val, flag) else results.add(False) # TODO: other operator else: # unregconize operator, ignore it results.add(False) if False in results or len(results) == 0: return False return True