def check_fields_pyson(cls, templates, field_names=None): pyson_fields = { 'recipients_pyson', 'recipients_secondary_pyson', 'recipients_hidden_pyson', } if field_names: pyson_fields &= field_names if not pyson_fields: return encoder = PYSONDecoder(noeval=True) for template in templates: for field in pyson_fields: value = getattr(template, field) if not value: continue try: pyson = encoder.decode(value) except Exception as exception: raise EmailTemplateError( gettext('ir.msg_email_template_invalid_field_pyson', template=template.rec_name, field=cls.__names__(field)['field'], exception=exception)) from exception if not isinstance(pyson, list) and pyson.types() != {list}: raise EmailTemplateError( gettext( 'ir.msg_email_template_invalid_field_pyson_type', template=template.rec_name, field=cls.__names__(field)['field'], ))
def check_domain(cls, actions): "Check domain and search_value" for action in actions: for domain in (action.domain, action.search_value): if not domain: continue try: value = PYSONDecoder().decode(domain) except Exception: raise DomainError( gettext('ir.msg_action_invalid_domain', domain=domain, action=action.rec_name)) if isinstance(value, PYSON): if not value.types() == set([list]): raise DomainError( gettext('ir.msg_action_invalid_domain', domain=domain, action=action.rec_name)) elif not isinstance(value, list): raise DomainError( gettext('ir.msg_action_invalid_domain', domain=domain, action=action.rec_name)) else: try: fields.domain_validate(value) except Exception: raise DomainError( gettext('ir.msg_action_invalid_domain', domain=domain, action=action.rec_name))
def check_domain(self): if not self.model_domain: return try: value = PYSONDecoder().decode(self.model_domain) except Exception: raise UserError( gettext('shine.invalid_domain', domain=self.model_domain, dataset=self.rec_name)) if isinstance(value, PYSON): if not value.types() == set([list]): raise UserError( gettext('shine.invalid_domain', domain=self.model_domain, dataset=self.rec_name)) elif not isinstance(value, list): raise UserError( gettext('shine.invalid_domain', domain=self.model_domain, dataset=self.rec_name)) else: try: fields.domain_validate(value) except Exception: raise UserError( gettext('shine.invalid_domain', domain=self.model_domain, dataset=self.rec_name))
def check_context(self): if not self.model_context: return try: value = PYSONDecoder().decode(self.model_context) except Exception: raise UserError( gettext('shine.invalid_context', context=self.model_context, dataset=self.rec_name)) if isinstance(value, PYSON): if not value.types() == set([dict]): raise UserError( gettext('shine.invalid_context', context=self.model_context, dataset=self.rec_name)) elif not isinstance(value, dict): raise UserError( gettext('shine.invalid_context', context=self.model_context, dataset=self.rec_name)) else: try: fields.context_validate(value) except Exception: raise UserError( gettext('shine.invalid_context', context=self.model_context, dataset=self.rec_name))
def check_domain(cls, actions, field_names=None): if field_names and 'domain' not in field_names: return for action in actions: if not action.domain: continue try: value = PYSONDecoder().decode(action.domain) except Exception as exception: raise DomainError(gettext( 'ir.msg_action_invalid_domain', domain=action.domain, action=action.rec_name)) from exception if isinstance(value, PYSON): if not value.types() == set([list]): raise DomainError(gettext( 'ir.msg_action_invalid_domain', domain=action.domain, action=action.rec_name)) elif not isinstance(value, list): raise DomainError(gettext( 'ir.msg_action_invalid_domain', domain=action.domain, action=action.rec_name)) else: try: fields.domain_validate(value) except Exception as exception: raise DomainError(gettext( 'ir.msg_action_invalid_domain', domain=action.domain, action=action.rec_name)) from exception
def check_domain(cls, searches, field_names): decoder = PYSONDecoder() if field_names and 'domain' not in field_names: return for search in searches: try: value = decoder.decode(search.domain) except Exception as exception: raise DomainError( gettext('ir.msg_view_search_invalid_domain', domain=search.domain, search=search.rec_name)) from exception if isinstance(value, PYSON): if not value.types() == set([list]): raise DomainError( gettext('ir.msg_view_search_invalid_domain', domain=search.domain, search=search.rec_name)) elif not isinstance(value, list): raise DomainError( gettext('ir.msg_view_search_invalid_domain', domain=search.domain, search=search.rec_name)) else: try: fields.domain_validate(value) except Exception as exception: raise DomainError( gettext('ir.msg_view_search_invalid_domain', domain=search.domain, search=search.rec_name)) from exception
def check_fields_pyson(self): encoder = PYSONDecoder(noeval=True) for field in [ 'recipients_pyson', 'recipients_secondary_pyson', 'recipients_hidden_pyson', ]: value = getattr(self, field) if not value: continue try: pyson = encoder.decode(value) except Exception as exception: raise EmailTemplateError( gettext('ir.msg_email_template_invalid_field_pyson', template=self.rec_name, field=self.__names__(field)['field'], exception=exception)) from exception if not isinstance(pyson, list) and pyson.types() != {list}: raise EmailTemplateError( gettext( 'ir.msg_email_template_invalid_field_pyson_type', template=self.rec_name, field=self.__names__(field)['field'], ))
def check_context(cls, actions): "Check context" for action in actions: if action.context: try: value = PYSONDecoder().decode(action.context) except Exception: raise ContextError( gettext('ir.msg_action_invalid_context', context=action.context, action=action.rec_name)) if isinstance(value, PYSON): if not value.types() == set([dict]): raise ContextError( gettext('ir.msg_action_invalid_context', context=action.context, action=action.rec_name)) elif not isinstance(value, dict): raise ContextError( gettext('ir.msg_action_invalid_context', context=action.context, action=action.rec_name)) else: try: fields.context_validate(value) except Exception: raise ContextError( gettext('ir.msg_action_invalid_context', context=action.context, action=action.rec_name))
def get_search(cls, user_id=None): if user_id is None: user_id = Transaction().user decoder = PYSONDecoder() searches = cls.search([("user", "=", user_id)], order=[("model", "ASC"), ("name", "ASC")]) result = {} for search in searches: result.setdefault(search.model, []).append((search.id, search.name, decoder.decode(search.domain))) return result
def get_search(cls, user_id=None): if user_id is None: user_id = Transaction().user decoder = PYSONDecoder() searches = cls.search([ ('user', '=', user_id), ], order=[('model', 'ASC'), ('name', 'ASC')]) result = {} for search in searches: result.setdefault(search.model, []).append( (search.id, search.name, decoder.decode(search.domain))) return result
def test_button_change(self): "Test button change" pool = Pool() Model = pool.get('test.modelview.button_change') decoder = PYSONDecoder() view = Model.fields_view_get() tree = etree.fromstring(view['arch']) button = tree.xpath('//button[@name="test"]')[0] self.assertEqual(set(decoder.decode(button.attrib['change'])), {'name', 'extra'})
def get_search(cls): decoder = PYSONDecoder() searches = cls.search_read( [], order=[('model', 'ASC'), ('name', 'ASC')], fields_names=['id', 'name', 'model', 'domain', '_delete']) result = {} for search in searches: result.setdefault(search['model'], []).append( (search['id'], search['name'], decoder.decode(search['domain']), search['_delete'])) return result
def test_action_window(action_window): if not action_window.res_model: return Model = pool.get(action_window.res_model) for active_id, active_ids in [ (None, []), (1, [1]), (1, [1, 2]), ]: decoder = PYSONDecoder({ 'active_id': active_id, 'active_ids': active_ids, 'active_model': action_window.res_model, }) domain = decoder.decode(action_window.pyson_domain) order = decoder.decode(action_window.pyson_order) context = decoder.decode(action_window.pyson_context) search_value = decoder.decode(action_window.pyson_search_value) if action_window.context_domain: domain = [ 'AND', domain, decoder.decode(action_window.context_domain) ] with Transaction().set_context(context): Model.search(domain, order=order, limit=action_window.limit) if search_value: Model.search(search_value) for action_domain in action_window.act_window_domains: if not action_domain.domain: continue Model.search(decoder.decode(action_domain.domain)) if action_window.context_model: pool.get(action_window.context_model)
def view_get(self, model=None): key = (self.id, model) result = self._view_get_cache.get(key) if result: return result if self.inherit: if self.model == model: return self.inherit.view_get(model=model) else: arch = self.inherit.arch view_id = self.inherit.id else: arch = self.arch view_id = self.id views = self.__class__.search([ 'OR', [ ('inherit', '=', view_id), ('model', '=', model), ], [ ('id', '=', view_id), ('inherit', '!=', None), ], ]) views.sort(key=lambda v: self._module_index.get(v.module, -1), reverse=True) parser = etree.XMLParser(remove_comments=True, resolve_entities=False) tree = etree.fromstring(arch, parser=parser) decoder = PYSONDecoder({'context': Transaction().context}) for view in views: if view.domain and not decoder.decode(view.domain): continue if not view.arch or not view.arch.strip(): continue tree_inherit = etree.fromstring(view.arch, parser=parser) tree = self.inherit_apply(tree, tree_inherit) arch = etree.tostring(tree, encoding='utf-8').decode('utf-8') result = { 'type': self.rng_type, 'view_id': view_id, 'arch': arch, 'field_childs': self.field_childs, } self._view_get_cache.set(key, result) return result
def digits(self): digits = 4 if self.field.ttype in ('float', 'numeric'): Model = Pool().get(self.field.model.model) digits = Model._fields.get(self.field.name).digits[1] if isinstance(digits, PYSON): digits = PYSONDecoder().decode(PYSONEncoder().encode(digits)) return digits
def fields_get(cls, fields_names=None): """ Return the definition of each field on the model. """ definition = {} pool = Pool() Translation = pool.get('ir.translation') FieldAccess = pool.get('ir.model.field.access') ModelAccess = pool.get('ir.model.access') # Add translation to cache language = Transaction().language trans_args = [] for fname, field in cls._fields.items(): if fields_names and fname not in fields_names: continue trans_args.extend(field.definition_translations(cls, language)) Translation.get_sources(trans_args) encoder = PYSONEncoder() decoder = PYSONDecoder(noeval=True) accesses = FieldAccess.get_access([cls.__name__])[cls.__name__] for fname, field in cls._fields.items(): if fields_names and fname not in fields_names: continue definition[fname] = field.definition(cls, language) if not accesses.get(fname, {}).get('write', True): definition[fname]['readonly'] = True states = decoder.decode(definition[fname]['states']) states.pop('readonly', None) definition[fname]['states'] = encoder.encode(states) for right in ['create', 'delete']: definition[fname][right] = accesses.get(fname, {}).get(right, True) for fname in list(definition.keys()): # filter out fields which aren't in the fields_names list if fields_names: if fname not in fields_names: del definition[fname] elif not ModelAccess.check_relation( cls.__name__, fname, mode='read'): del definition[fname] return definition
def eval(self, record, pyson, _env=None): 'Evaluate the pyson with the record' if _env is None: env = {} else: env = _env.copy() env['context'] = Transaction().context env['self'] = EvalEnvironment(record, record.__class__) return PYSONDecoder(env).decode(pyson)
def do_open(self, action): action, data = super(ProductByLocationExcludeAssigned, self).do_open(action) # Decode pyson context context = PYSONDecoder().decode(action['pyson_context']) # Update context context['stock_assign'] = True # Encode the new context to create new pyson context action['pyson_context'] = PYSONEncoder().encode(context) return action, data
def eval(self, record): """ Evaluate the condition of trigger """ env = {} env['current_date'] = datetime.datetime.today() env['time'] = time env['context'] = Transaction().context env['self'] = EvalEnvironment(record, record.__class__) return bool(PYSONDecoder(env).decode(self.condition))
def do_open_(self, action): Product = Pool().get('product.product') action, data = super(OpenProductQuantitiesByWarehouse, self).do_open_(action) product = Product(Transaction().context['active_id']) if product.product_suppliers: product_supplier = product.product_suppliers[0] supply_date = product_supplier.compute_supply_date() if supply_date != datetime.date.max: search_value = \ PYSONDecoder().decode(action['pyson_search_value']) clause = ('date', '<=', supply_date) if search_value and search_value[0] != 'OR': search_value.append(clause) else: search_value = [search_value, clause] action['pyson_search_value'] = PYSONEncoder().encode( search_value) return action, data
def check_condition(cls, triggers): ''' Check condition ''' for trigger in triggers: try: PYSONDecoder(noeval=True).decode(trigger.condition) except Exception: raise ConditionError( gettext('ir.msg_trigger_invalid_condition', condition=trigger.condition, trigger=trigger.rec_name))
def test_ir_action_window(self): 'Test action windows are correctly defined' pool = Pool() ModelData = pool.get('ir.model.data') ActionWindow = pool.get('ir.action.act_window') for model_data in ModelData.search([ ('module', '=', self.module), ('model', '=', 'ir.action.act_window'), ]): action_window = ActionWindow(model_data.db_id) if not action_window.res_model: continue Model = pool.get(action_window.res_model) decoder = PYSONDecoder({ 'active_id': None, 'active_ids': [], 'active_model': action_window.res_model, }) domain = decoder.decode(action_window.pyson_domain) order = decoder.decode(action_window.pyson_order) context = decoder.decode(action_window.pyson_context) with Transaction().set_context(context): Model.search(domain, order=order, limit=action_window.limit) for action_domain in action_window.act_window_domains: if not action_domain.domain: continue Model.search(decoder.decode(action_domain.domain))
def encode(element): for attr in ('states', 'domain', 'spell', 'colors'): if element.get(attr): try: value = PYSONDecoder().decode(element.get(attr)) validates.get(attr, lambda a: True)(value) except Exception, e: logger.error( 'Invalid pyson view element "%s:%s":' '\n%s\n%s', element.get('id') or element.get('name'), attr, str(e), xml) return False
def instantiate_context(field, record): from ..modelstorage import EvalEnvironment ctx = {} if field.context: pyson_context = PYSONEncoder().encode(field.context) ctx.update( PYSONDecoder(EvalEnvironment( record, record.__class__)).decode(pyson_context)) datetime_ = None if getattr(field, 'datetime_field', None): datetime_ = getattr(record, field.datetime_field, None) ctx = {'_datetime': datetime_} return ctx
def check_domain(cls, schemas): for schema in schemas: if not schema.domain: continue try: value = PYSONDecoder().decode(schema.domain) except Exception: raise DomainError( gettext('ir.msg_dict_schema_invalid_domain', schema=schema.rec_name)) if not isinstance(value, list): raise DomainError( gettext('ir.msg_dict_schema_invalid_domain', schema=schema.rec_name))
def check_domain(cls, schemas): for schema in schemas: if not schema.domain: continue try: value = PYSONDecoder().decode(schema.domain) except Exception: cls.raise_user_error('invalid_domain', { 'schema': schema.rec_name, }) if not isinstance(value, list): cls.raise_user_error('invalid_domain', { 'schema': schema.rec_name, })
def check_domain(cls, actions): for action in actions: if not action.domain: continue try: value = PYSONDecoder().decode(action.domain) except Exception: value = None if isinstance(value, PYSON): if not value.types() == set([list]): value = None elif not isinstance(value, list): value = None else: try: fields.domain_validate(value) except Exception: value = None if value is None: raise DomainError( gettext('ir.msg_action_invalid_domain', domain=action.domain, action=action.rec_name))
def check_condition(cls, triggers, field_names=None): ''' Check condition ''' if field_names and 'condition' not in field_names: return for trigger in triggers: try: PYSONDecoder(noeval=True).decode(trigger.condition) except Exception: raise ConditionError( gettext('ir.msg_trigger_invalid_condition', condition=trigger.condition, trigger=trigger.rec_name))
def encode(element): for attr in ('states', 'domain', 'spell'): if not element.get(attr): continue try: value = PYSONDecoder().decode(element.get(attr)) validates.get(attr, lambda a: True)(value) except Exception, e: error_log = '%s: <%s %s="%s"/>' % ( e, element.get('id') or element.get('name'), attr, element.get(attr)) logger.error('Invalid XML view %s:\n%s\n%s', view.rec_name, error_log, xml) cls.raise_user_error('invalid_xml', (view.rec_name, ), error_log)
def get_data_model(self): pool = Pool() Model = pool.get(self.model.model) domain = [] if self.model_domain: domain = PYSONDecoder().decode(self.model_domain) context = {} if self.model_context: context = PYSONDecoder().decode(self.model_context) order = [('id', 'ASC')] if self.model_order: order = PYSONDecoder().decode(self.model_order) limit = RECORD_CACHE_SIZE offset = 0 with Transaction().set_context(context): while True: records = Model.search(domain, offset=offset, limit=limit, order=order) if records: yield records if len(records) < limit: break
def encode(element): for attr in ('states', 'domain', 'spell'): if not element.get(attr): continue try: value = PYSONDecoder().decode(element.get(attr)) validates.get(attr, lambda a: True)(value) except Exception as e: error_log = '%s: <%s %s="%s"/>' % ( e, element.get('id') or element.get('name'), attr, element.get(attr)) raise XMLError( gettext('ir.msg_view_invalid_xml', name=view.rec_name), error_log) from e for child in element: encode(child)