def get_google_drive_config(self, cr, uid, res_model, res_id, context=None): ''' Function called by the js, when no google doc are yet associated with a record, with the aim to create one. It will first seek for a google.docs.config associated with the model `res_model` to find out what's the template of google doc to copy (this is usefull if you want to start with a non-empty document, a type or a name different than the default values). If no config is associated with the `res_model`, then a blank text document with a default name is created. :param res_model: the object for which the google doc is created :param ids: the list of ids of the objects for which the google doc is created. This list is supposed to have a length of 1 element only (batch processing is not supported in the code, though nothing really prevent it) :return: the config id and config name ''' if not res_id: raise UserError(_("Creating google drive may only be done by one at a time.")) # check if a model is configured with a template config_ids = self.search(cr, uid, [('model_id', '=', res_model)], context=context) configs = [] for config in self.browse(cr, uid, config_ids, context=context): if config.filter_id: if (config.filter_id.user_id and config.filter_id.user_id.id != uid): #Private continue domain = [('id', 'in', [res_id])] + eval(config.filter_id.domain) local_context = context and context.copy() or {} local_context.update(eval(config.filter_id.context)) google_doc_configs = self.pool.get(config.filter_id.model_id).search(cr, uid, domain, context=local_context) if google_doc_configs: configs.append({'id': config.id, 'name': config.name}) else: configs.append({'id': config.id, 'name': config.name}) return configs
def transfer_node_to_modifiers(node, modifiers, context=None, in_tree_view=False): if node.get('attrs'): modifiers.update(eval(node.get('attrs'))) if node.get('states'): if 'invisible' in modifiers and isinstance(modifiers['invisible'], list): # TODO combine with AND or OR, use implicit AND for now. modifiers['invisible'].append( ('state', 'not in', node.get('states').split(','))) else: modifiers['invisible'] = [('state', 'not in', node.get('states').split(','))] for a in ('invisible', 'readonly', 'required'): if node.get(a): v = bool(eval(node.get(a), {'context': context or {}})) if in_tree_view and a == 'invisible': # Invisible in a tree view has a specific meaning, make it a # new key in the modifiers attribute. modifiers['tree_invisible'] = v elif v or (a not in modifiers or not isinstance(modifiers[a], list)): # Don't set the attribute to False if a dynamic value was # provided (i.e. a domain from attrs or states). modifiers[a] = v
def _child_get(node, self=None, tagname=None): for n in node: if self and self.localcontext and n.get('rml_loop'): for ctx in eval(n.get('rml_loop'), {}, self.localcontext): self.localcontext.update(ctx) if (tagname is None) or (n.tag == tagname): if n.get('rml_except', False): try: eval(n.get('rml_except'), {}, self.localcontext) except GeneratorExit: continue except Exception, e: _logger.info('rml_except: "%s"', n.get('rml_except', ''), exc_info=True) continue if n.get('rml_tag'): try: (tag, attr) = eval(n.get('rml_tag'), {}, self.localcontext) n2 = copy.deepcopy(n) n2.tag = tag n2.attrib.update(attr) yield n2 except GeneratorExit: yield n except Exception, e: _logger.info('rml_tag: "%s"', n.get('rml_tag', ''), exc_info=True) yield n else: yield n continue
def compute_rule(self, cr, uid, rule_id, localdict, context=None): """ :param rule_id: id of rule to compute :param localdict: dictionary containing the environement in which to compute the rule :return: returns a tuple build as the base/amount computed, the quantity and the rate :rtype: (float, float, float) """ rule = self.browse(cr, uid, rule_id, context=context) if rule.amount_select == 'fix': try: return rule.amount_fix, float(eval(rule.quantity, localdict)), 100.0 except: raise UserError(_('Wrong quantity defined for salary rule %s (%s).') % (rule.name, rule.code)) elif rule.amount_select == 'percentage': try: return (float(eval(rule.amount_percentage_base, localdict)), float(eval(rule.quantity, localdict)), rule.amount_percentage) except: raise UserError(_('Wrong percentage base or quantity defined for salary rule %s (%s).') % (rule.name, rule.code)) else: try: eval(rule.amount_python_compute, localdict, mode='exec', nocopy=True) return float(localdict['result']), 'result_qty' in localdict and localdict['result_qty'] or 1.0, 'result_rate' in localdict and localdict['result_rate'] or 100.0 except: raise UserError(_('Wrong python code defined for salary rule %s (%s).') % (rule.name, rule.code))
def _child_get(node, self=None, tagname=None): for n in node: if self and self.localcontext and n.get('rml_loop'): for ctx in eval(n.get('rml_loop'),{}, self.localcontext): self.localcontext.update(ctx) if (tagname is None) or (n.tag==tagname): if n.get('rml_except', False): try: eval(n.get('rml_except'), {}, self.localcontext) except GeneratorExit: continue except Exception, e: _logger.info('rml_except: "%s"', n.get('rml_except',''), exc_info=True) continue if n.get('rml_tag'): try: (tag,attr) = eval(n.get('rml_tag'),{}, self.localcontext) n2 = copy.deepcopy(n) n2.tag = tag n2.attrib.update(attr) yield n2 except GeneratorExit: yield n except Exception, e: _logger.info('rml_tag: "%s"', n.get('rml_tag',''), exc_info=True) yield n else: yield n continue
def _row_get(self, cr, uid, objs, fields, conditions, row_canvas=None, group_by=None): result = [] for obj in objs: tobreak = False for cond in conditions: if cond and cond[0]: c = cond[0] temp = c[0](eval('obj.'+c[1],{'obj': obj})) if not eval('\''+temp+'\''+' '+c[2]+' '+'\''+str(c[3])+'\''): tobreak = True if tobreak: break levels = {} row = [] for i in range(len(fields)): if not fields[i]: row.append(row_canvas and row_canvas[i]) if row_canvas[i]: row_canvas[i]=False elif len(fields[i])==1: if obj: row.append(str(eval('obj.'+fields[i][0],{'obj': obj}))) else: row.append(None) else: row.append(None) levels[fields[i][0]]=True if not levels: result.append(row) else: # Process group_by data first key = [] if group_by is not None and fields[group_by] is not None: if fields[group_by][0] in levels.keys(): key.append(fields[group_by][0]) for l in levels.keys(): if l != fields[group_by][0]: key.append(l) else: key = levels.keys() for l in key: objs = eval('obj.'+l,{'obj': obj}) if not isinstance(objs, (BaseModel, list)): objs = [objs] field_new = [] cond_new = [] for f in range(len(fields)): if (fields[f] and fields[f][0])==l: field_new.append(fields[f][1:]) cond_new.append(conditions[f][1:]) else: field_new.append(None) cond_new.append(None) if len(objs): result += self._row_get(cr, uid, objs, field_new, cond_new, row, group_by) else: result.append(row) return result
def _check(self, cr, uid, automatic=False, use_new_cursor=False, context=None): """ This Function is called by scheduler. """ context = context or {} # retrieve all the action rules to run based on a timed condition action_dom = [('kind', '=', 'on_time')] action_ids = self.search(cr, uid, action_dom, context=dict(context, active_test=True)) eval_context = self._get_eval_context(cr, uid, context=context) for action in self.browse(cr, uid, action_ids, context=context): now = datetime.now() if action.last_run: last_run = get_datetime(action.last_run) else: last_run = datetime.utcfromtimestamp(0) # retrieve all the records that satisfy the action's condition model = self.pool[action.model_id.model] domain = [] ctx = dict(context) if action.filter_domain is not False: domain = eval(action.filter_domain, eval_context) elif action.filter_id: domain = eval(action.filter_id.domain, eval_context) ctx.update(eval(action.filter_id.context)) if 'lang' not in ctx: # Filters might be language-sensitive, attempt to reuse creator lang # as we are usually running this as super-user in background [filter_meta] = action.filter_id.get_metadata() user_id = filter_meta['write_uid'] and filter_meta['write_uid'][0] or \ filter_meta['create_uid'][0] ctx['lang'] = self.pool['res.users'].browse(cr, uid, user_id).lang record_ids = model.search(cr, uid, domain, context=ctx) # determine when action should occur for the records date_field = action.trg_date_id.name if date_field == 'date_action_last' and 'create_date' in model._fields: get_record_dt = lambda record: record[date_field] or record.create_date else: get_record_dt = lambda record: record[date_field] # process action on the records that should be executed for record in model.browse(cr, uid, record_ids, context=context): record_dt = get_record_dt(record) if not record_dt: continue action_dt = self._check_delay(cr, uid, action, record, record_dt, context=context) if last_run <= action_dt < now: try: context = dict(context or {}, action=True) self._process(cr, uid, action, [record.id], context=context) except Exception: import traceback _logger.error(traceback.format_exc()) action.write({'last_run': now.strftime(DEFAULT_SERVER_DATETIME_FORMAT)}) if automatic: # auto-commit for batch processing cr.commit()
def get_needaction_data(self, cr, uid, ids, context=None): """ Return for each menu entry of ids : - if it uses the needaction mechanism (needaction_enabled) - the needaction counter of the related action, taking into account the action domain """ if context is None: context = {} res = {} menu_ids = set() for menu in self.browse(cr, uid, ids, context=context): menu_ids.add(menu.id) ctx = None if menu.action and menu.action.type in ('ir.actions.act_window', 'ir.actions.client') and menu.action.context: try: # use magical UnquoteEvalContext to ignore undefined client-side variables such as `active_id` eval_ctx = tools.UnquoteEvalContext(**context) ctx = eval(menu.action.context, locals_dict=eval_ctx, nocopy=True) or None except Exception: # if the eval still fails for some reason, we'll simply skip this menu pass menu_ref = ctx and ctx.get('needaction_menu_ref') if menu_ref: if not isinstance(menu_ref, list): menu_ref = [menu_ref] model_data_obj = self.pool.get('ir.model.data') for menu_data in menu_ref: try: model, id = model_data_obj.get_object_reference(cr, uid, menu_data.split('.')[0], menu_data.split('.')[1]) if (model == 'ir.ui.menu'): menu_ids.add(id) except Exception: pass menu_ids = list(menu_ids) for menu in self.browse(cr, uid, menu_ids, context=context): res[menu.id] = { 'needaction_enabled': False, 'needaction_counter': False, } if menu.action and menu.action.type in ('ir.actions.act_window', 'ir.actions.client') and menu.action.res_model: if menu.action.res_model in self.pool: obj = self.pool[menu.action.res_model] if obj._needaction: if menu.action.type == 'ir.actions.act_window': eval_context = self.pool['ir.actions.act_window']._get_eval_context(cr, uid, context=context) dom = menu.action.domain and eval(menu.action.domain, eval_context) or [] else: dom = eval(menu.action.params_store or '{}', {'uid': uid}).get('domain') res[menu.id]['needaction_enabled'] = obj._needaction res[menu.id]['needaction_counter'] = obj._needaction_count(cr, uid, dom, context=context) return res
def execute_code(self, code_exec): def reconciled_inv(): """ returns the list of invoices that are set as reconciled = True """ return self.env['account.invoice'].search([('reconciled', '=', True)]).ids def order_columns(item, cols=None): """ This function is used to display a dictionary as a string, with its columns in the order chosen. :param item: dict :param cols: list of field names :returns: a list of tuples (fieldname: value) in a similar way that would dict.items() do except that the returned values are following the order given by cols :rtype: [(key, value)] """ if cols is None: cols = item.keys() return [(col, item.get(col)) for col in cols if col in item.keys()] localdict = { 'cr': self.env.cr, 'uid': self.env.uid, 'reconciled_inv': reconciled_inv, # specific function used in different tests 'result': None, # used to store the result of the test 'column_order': None, # used to choose the display order of columns (in case you are returning a list of dict) } eval(code_exec, localdict, mode="exec", nocopy=True) result = localdict['result'] column_order = localdict.get('column_order', None) if not isinstance(result, (tuple, list, set)): result = [result] if not result: result = [_('The test was passed successfully')] else: def _format(item): if isinstance(item, dict): return ', '.join([ "%s: %s" % (tup[0], tup[1]) for tup in order_columns(item, column_order) ]) else: return item result = [_(_format(rec)) for rec in result] return result
def _filter_post(self, records): """ Filter the records that satisfy the postcondition of action ``self``. """ if self.filter_id and records: eval_context = self._get_eval_context() domain = [('id', 'in', records.ids)] + eval(self.filter_id.domain, eval_context) ctx = eval(self.filter_id.context) return records.with_context(**ctx).search(domain).with_env(records.env) elif self.filter_domain and records: eval_context = self._get_eval_context() domain = [('id', 'in', records.ids)] + eval(self.filter_domain, eval_context) return records.search(domain) else: return records
def _process_text(self, txt): """Translate ``txt`` according to the language in the local context, replace dynamic ``[[expr]]`` with their real value, then escape the result for XML. :param str txt: original text to translate (must NOT be XML-escaped) :return: translated text, with dynamic expressions evaluated and with special XML characters escaped (``&,<,>``). """ if not self.localcontext: return str2xml(txt) if not txt: return '' result = '' sps = _regex.split(txt) while sps: # This is a simple text to translate to_translate = tools.ustr(sps.pop(0)) result += tools.ustr(self.localcontext.get('translate', lambda x:x)(to_translate)) if sps: txt = None try: expr = sps.pop(0) txt = eval(expr, self.localcontext) if txt and isinstance(txt, basestring): txt = tools.ustr(txt) except Exception: _logger.info("Failed to evaluate expression [[ %s ]] with context %r while rendering report, ignored.", expr, self.localcontext) if isinstance(txt, basestring): result += txt elif txt and (txt is not None) and (txt is not False): result += ustr(txt) return str2xml(result)
def _check_alias_defaults(self): try: dict(eval(self.alias_defaults)) except Exception: raise UserError( _('Invalid expression, it must be a literal python dictionary definition e.g. "{\'field\': \'value\'}"' ))
def message_get_email_values(self, cr, uid, id, notif_mail=None, context=None): res = super(MailGroup, self).message_get_email_values(cr, uid, id, notif_mail=notif_mail, context=context) group = self.browse(cr, uid, id, context=context) base_url = self.pool['ir.config_parameter'].get_param( cr, uid, 'web.base.url') headers = {} if res.get('headers'): try: headers = eval(res['headers']) except Exception: pass headers.update({ 'List-Archive': '<%s/groups/%s>' % (base_url, slug(group)), 'List-Subscribe': '<%s/groups>' % (base_url), 'List-Unsubscribe': '<%s/groups?unsubscribe>' % (base_url, ), }) res['headers'] = repr(headers) return res
def _search_product_quantity(self, cr, uid, obj, name, domain, context): res = [] for field, operator, value in domain: #to prevent sql injections assert field in ('qty_available', 'virtual_available', 'incoming_qty', 'outgoing_qty'), 'Invalid domain left operand' assert operator in ('<', '>', '=', '!=', '<=', '>='), 'Invalid domain operator' assert isinstance(value, (float, int)), 'Invalid domain right operand' if operator == '=': operator = '==' ids = [] if name == 'qty_available' and (value != 0.0 or operator not in ('==', '>=', '<=')): res.append(('id', 'in', self._search_qty_available(cr, uid, operator, value, context))) else: product_ids = self.search(cr, uid, [], context=context) if product_ids: #TODO: Still optimization possible when searching virtual quantities for element in self.browse(cr, uid, product_ids, context=context): if eval(str(element[field]) + operator + str(value)): ids.append(element.id) res.append(('id', 'in', ids)) return res
def get_recipients(self, cr, uid, mailing, context=None): if mailing.mailing_domain: domain = eval(mailing.mailing_domain) res_ids = self.pool[mailing.mailing_model].search(cr, uid, domain, context=context) else: res_ids = [] domain = [('id', 'in', res_ids)] # randomly choose a fragment if mailing.contact_ab_pc < 100: contact_nbr = self.pool[mailing.mailing_model].search( cr, uid, domain, count=True, context=context) topick = int(contact_nbr / 100.0 * mailing.contact_ab_pc) if mailing.mass_mailing_campaign_id and mailing.mass_mailing_campaign_id.unique_ab_testing: already_mailed = self.pool[ 'mail.mass_mailing.campaign'].get_recipients( cr, uid, [mailing.mass_mailing_campaign_id.id], context=context)[mailing.mass_mailing_campaign_id.id] else: already_mailed = set([]) remaining = set(res_ids).difference(already_mailed) if topick > len(remaining): topick = len(remaining) res_ids = random.sample(remaining, topick) return res_ids
def generate(self, cr, uid, query=None, args=None, context=None): obj = request.registry[self.model] domain = eval( self.domain, (args or {}).copy()) if query: domain.append((obj._rec_name, 'ilike', '%'+query+'%')) for record in obj.search_read(cr, uid, domain=domain, fields=['write_date',obj._rec_name], context=context): if record.get(obj._rec_name, False): yield {'loc': (record['id'], record[obj._rec_name])}
def _check_grouping(self, cr, uid, ids, context=None): for lang in self.browse(cr, uid, ids, context=context): try: if not all(isinstance(x, int) for x in eval(lang.grouping)): return False except Exception: return False return True
def load_information_from_description_file(module, mod_path=None): """ :param module: The name of the module (sale, purchase, ...) :param mod_path: Physical path of module, if not providedThe name of the module (sale, purchase, ...) """ if not mod_path: mod_path = get_module_path(module) terp_file = mod_path and opj(mod_path, MANIFEST) or False if terp_file: info = {} if os.path.isfile(terp_file): # default values for descriptor info = { 'application': False, 'author': 'eCore SA', 'auto_install': False, 'category': 'Uncategorized', 'depends': [], 'description': '', 'icon': get_module_icon(module), 'installable': True, 'license': 'LGPL-3', 'post_load': None, 'version': '1.0', 'web': False, 'website': 'http://www.ecore.com', 'sequence': 100, 'summary': '', } info.update(itertools.izip( 'depends data demo test init_xml update_xml demo_xml'.split(), iter(list, None))) f = tools.file_open(terp_file) try: info.update(eval(f.read())) finally: f.close() if not info.get('description'): readme_path = [opj(mod_path, x) for x in README if os.path.isfile(opj(mod_path, x))] if readme_path: readme_text = tools.file_open(readme_path[0]).read() info['description'] = readme_text if 'active' in info: # 'active' has been renamed 'auto_install' info['auto_install'] = info['active'] info['version'] = adapt_version(info['version']) return info #TODO: refactor the logger in this file to follow the logging guidelines # for 6.0 _logger.debug('module %s: no %s file found.', module, MANIFEST) return {}
def get_google_drive_config(self, cr, uid, res_model, res_id, context=None): ''' Function called by the js, when no google doc are yet associated with a record, with the aim to create one. It will first seek for a google.docs.config associated with the model `res_model` to find out what's the template of google doc to copy (this is usefull if you want to start with a non-empty document, a type or a name different than the default values). If no config is associated with the `res_model`, then a blank text document with a default name is created. :param res_model: the object for which the google doc is created :param ids: the list of ids of the objects for which the google doc is created. This list is supposed to have a length of 1 element only (batch processing is not supported in the code, though nothing really prevent it) :return: the config id and config name ''' if not res_id: raise UserError( _("Creating google drive may only be done by one at a time.")) # check if a model is configured with a template config_ids = self.search(cr, uid, [('model_id', '=', res_model)], context=context) configs = [] for config in self.browse(cr, uid, config_ids, context=context): if config.filter_id: if (config.filter_id.user_id and config.filter_id.user_id.id != uid): #Private continue domain = [('id', 'in', [res_id])] + eval( config.filter_id.domain) local_context = context and context.copy() or {} local_context.update(eval(config.filter_id.context)) google_doc_configs = self.pool.get( config.filter_id.model_id).search(cr, uid, domain, context=local_context) if google_doc_configs: configs.append({'id': config.id, 'name': config.name}) else: configs.append({'id': config.id, 'name': config.name}) return configs
def execute_code(self, code_exec): def reconciled_inv(): """ returns the list of invoices that are set as reconciled = True """ return self.env['account.invoice'].search([('reconciled', '=', True)]).ids def order_columns(item, cols=None): """ This function is used to display a dictionary as a string, with its columns in the order chosen. :param item: dict :param cols: list of field names :returns: a list of tuples (fieldname: value) in a similar way that would dict.items() do except that the returned values are following the order given by cols :rtype: [(key, value)] """ if cols is None: cols = item.keys() return [(col, item.get(col)) for col in cols if col in item.keys()] localdict = { 'cr': self.env.cr, 'uid': self.env.uid, 'reconciled_inv': reconciled_inv, # specific function used in different tests 'result': None, # used to store the result of the test 'column_order': None, # used to choose the display order of columns (in case you are returning a list of dict) } eval(code_exec, localdict, mode="exec", nocopy=True) result = localdict['result'] column_order = localdict.get('column_order', None) if not isinstance(result, (tuple, list, set)): result = [result] if not result: result = [_('The test was passed successfully')] else: def _format(item): if isinstance(item, dict): return ', '.join(["%s: %s" % (tup[0], tup[1]) for tup in order_columns(item, column_order)]) else: return item result = [_(_format(rec)) for rec in result] return result
def _domain_force_get(self, cr, uid, ids, field_name, arg, context=None): res = {} eval_context = self._eval_context(cr, uid) for rule in self.browse(cr, uid, ids, context): if rule.domain_force: res[rule.id] = expression.normalize_domain(eval(rule.domain_force, eval_context)) else: res[rule.id] = [] return res
def create_source_pdf(self, cr, uid, ids, data, report_xml, context=None): if not context: context={} registry = ecore.registry(cr.dbname) attach = report_xml.attachment if attach: objs = self.getObjects(cr, uid, ids, context) results = [] for obj in objs: aname = eval(attach, {'object':obj, 'time':time}) result = False if report_xml.attachment_use and aname and context.get('attachment_use', True): aids = registry['ir.attachment'].search(cr, uid, [('datas_fname','=',aname+'.pdf'),('res_model','=',self.table),('res_id','=',obj.id)]) if aids: brow_rec = registry['ir.attachment'].browse(cr, uid, aids[0]) if not brow_rec.datas: continue d = base64.decodestring(brow_rec.datas) results.append((d,'pdf')) continue result = self.create_single_pdf(cr, uid, [obj.id], data, report_xml, context) if not result: return False if aname: try: name = aname+'.'+result[1] # Remove the default_type entry from the context: this # is for instance used on the account.account_invoices # and is thus not intended for the ir.attachment type # field. ctx = dict(context) ctx.pop('default_type', None) registry['ir.attachment'].create(cr, uid, { 'name': aname, 'datas': base64.encodestring(result[0]), 'datas_fname': name, 'res_model': self.table, 'res_id': obj.id, }, context=ctx ) except AccessError: #TODO: should probably raise a proper osv_except instead, shouldn't we? see LP bug #325632 _logger.info('Could not create saved report attachment', exc_info=True) results.append(result) if results: if results[0][1]=='pdf': from pyPdf import PdfFileWriter, PdfFileReader output = PdfFileWriter() for r in results: reader = PdfFileReader(cStringIO.StringIO(r[0])) for page in range(reader.getNumPages()): output.addPage(reader.getPage(page)) s = cStringIO.StringIO() output.write(s) return s.getvalue(), results[0][1] return self.create_single_pdf(cr, uid, ids, data, report_xml, context)
def _domain_force_get(self, cr, uid, ids, field_name, arg, context=None): res = {} eval_context = self._eval_context(cr, uid) for rule in self.browse(cr, uid, ids, context): if rule.domain_force: res[rule.id] = expression.normalize_domain( eval(rule.domain_force, eval_context)) else: res[rule.id] = [] return res
def get_interested_action(self, cr, uid, interested, context=None): try: model, action_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'crm_partner_assign', 'crm_lead_channel_interested_act') except ValueError: raise UserError(_("The CRM Channel Interested Action is missing")) action = self.pool[model].read(cr, uid, [action_id], context=context)[0] action_context = eval(action['context']) action_context['interested'] = interested action['context'] = str(action_context) return action
def build_tree(obj, level, depth): res = self._row_get(cr, uid,[obj], new_fields, new_cond) level.append(depth) new_obj = eval('obj.'+report['field_parent'][1],{'obj': obj}) if not isinstance(new_obj, list) : new_obj = [new_obj] for o in new_obj: if o: res += build_tree(o, level, depth+1) return res
def build_tree(obj, level, depth): res = self._row_get(cr, uid, [obj], new_fields, new_cond) level.append(depth) new_obj = eval('obj.' + report['field_parent'][1], {'obj': obj}) if not isinstance(new_obj, list): new_obj = [new_obj] for o in new_obj: if o: res += build_tree(o, level, depth + 1) return res
def generate(self, cr, uid, query=None, args=None, context=None): obj = request.registry[self.model] domain = eval(self.domain, (args or {}).copy()) if query: domain.append((obj._rec_name, 'ilike', '%' + query + '%')) for record in obj.search_read(cr, uid, domain=domain, fields=['write_date', obj._rec_name], context=context): if record.get(obj._rec_name, False): yield {'loc': (record['id'], record[obj._rec_name])}
def _parse_node(self, root_node): result = [] for node in root_node: field_name = node.get('name') if not eval(str(node.attrib.get('invisible',False)),{'context':self.context}): if node.tag == 'field': if field_name in self.groupby: continue result.append(field_name) else: result.extend(self._parse_node(node)) return result
def satisfy_condition(self, cr, uid, rule_id, localdict, context=None): """ @param rule_id: id of hr.salary.rule to be tested @param contract_id: id of hr.contract to be tested @return: returns True if the given rule match the condition for the given contract. Return False otherwise. """ rule = self.browse(cr, uid, rule_id, context=context) if rule.condition_select == 'none': return True elif rule.condition_select == 'range': try: result = eval(rule.condition_range, localdict) return rule.condition_range_min <= result and result <= rule.condition_range_max or False except: raise UserError(_('Wrong range condition defined for salary rule %s (%s).') % (rule.name, rule.code)) else: #python code try: eval(rule.condition_python, localdict, mode='exec', nocopy=True) return 'result' in localdict and localdict['result'] or False except: raise UserError(_('Wrong python condition defined for salary rule %s (%s).') % (rule.name, rule.code))
def _search_qty_available(self, cr, uid, operator, value, context): domain_quant = [] if context.get('lot_id'): domain_quant.append(('lot_id', '=', context['lot_id'])) if context.get('owner_id'): domain_quant.append(('owner_id', '=', context['owner_id'])) if context.get('package_id'): domain_quant.append(('package_id', '=', context['package_id'])) domain_quant += self._get_domain_locations(cr, uid, [], context=context)[0] quants = self.pool.get('stock.quant').read_group(cr, uid, domain_quant, ['product_id', 'qty'], ['product_id'], context=context) quants = dict(map(lambda x: (x['product_id'][0], x['qty']), quants)) quants = dict((k, v) for k, v in quants.iteritems() if eval(str(v) + operator + str(value))) return(list(quants))
def transfer_node_to_modifiers(node, modifiers, context=None, in_tree_view=False): if node.get('attrs'): modifiers.update(eval(node.get('attrs'))) if node.get('states'): if 'invisible' in modifiers and isinstance(modifiers['invisible'], list): # TODO combine with AND or OR, use implicit AND for now. modifiers['invisible'].append(('state', 'not in', node.get('states').split(','))) else: modifiers['invisible'] = [('state', 'not in', node.get('states').split(','))] for a in ('invisible', 'readonly', 'required'): if node.get(a): v = bool(eval(node.get(a), {'context': context or {}})) if in_tree_view and a == 'invisible': # Invisible in a tree view has a specific meaning, make it a # new key in the modifiers attribute. modifiers['tree_invisible'] = v elif v or (a not in modifiers or not isinstance(modifiers[a], list)): # Don't set the attribute to False if a dynamic value was # provided (i.e. a domain from attrs or states). modifiers[a] = v
def _get_alias_defaults_values(self, cr, uid, ids, context=None): res = dict.fromkeys(ids, False) is_group_use_lead = self.pool['res.users'].has_group(cr, uid, 'crm.group_use_lead') for team in self.browse(cr, uid, ids, context=context): alias_defaults = eval(team.alias_defaults) alias_defaults.update({ 'type': 'lead' if is_group_use_lead and team.use_leads else 'opportunity', 'team_id': team.id, }) res[team.id] = { 'alias_defaults': alias_defaults, 'alias_parent_thread_id': team.id, } return res
def process_segment(self, cr, uid, segment_ids=None, context=None): Workitems = self.pool.get('marketing.campaign.workitem') Campaigns = self.pool.get('marketing.campaign') if not segment_ids: segment_ids = self.search(cr, uid, [('state', '=', 'running')], context=context) action_date = time.strftime('%Y-%m-%d %H:%M:%S') campaigns = set() for segment in self.browse(cr, uid, segment_ids, context=context): if segment.campaign_id.state != 'running': continue campaigns.add(segment.campaign_id.id) act_ids = self.pool.get('marketing.campaign.activity').search(cr, uid, [('start', '=', True), ('campaign_id', '=', segment.campaign_id.id)], context=context) model_obj = self.pool[segment.object_id.model] criteria = [] if segment.sync_last_date and segment.sync_mode != 'all': criteria += [(segment.sync_mode, '>', segment.sync_last_date)] if segment.ir_filter_id: criteria += eval(segment.ir_filter_id.domain) object_ids = model_obj.search(cr, uid, criteria, context=context) # XXX TODO: rewrite this loop more efficiently without doing 1 search per record! for record in model_obj.browse(cr, uid, object_ids, context=context): # avoid duplicate workitem for the same resource if segment.sync_mode in ('write_date','all'): if Campaigns._find_duplicate_workitems(cr, uid, record, segment.campaign_id, context=context): continue wi_vals = { 'segment_id': segment.id, 'date': action_date, 'state': 'todo', 'res_id': record.id } partner = self.pool.get('marketing.campaign')._get_partner_for(segment.campaign_id, record) if partner: wi_vals['partner_id'] = partner.id for act_id in act_ids: wi_vals['activity_id'] = act_id Workitems.create(cr, uid, wi_vals, context=context) self.write(cr, uid, segment.id, {'sync_last_date':action_date}, context=context) Workitems.process_all(cr, uid, list(campaigns), context=context) return True
def action_your_pipeline(self, cr, uid, context=None): IrModelData = self.pool['ir.model.data'] action = IrModelData.xmlid_to_object( cr, uid, 'crm.crm_lead_opportunities_tree_view').read([ 'name', 'help', 'res_model', 'target', 'domain', 'context', 'type', 'search_view_id' ]) if not action: action = {} else: action = action[0] user_team_id = self.pool['res.users'].browse( cr, uid, uid, context=context).sale_team_id.id if not user_team_id: user_team_id = self.search(cr, uid, [], context=context, limit=1) user_team_id = user_team_id and user_team_id[0] or False action[ 'help'] = """<p class='oe_view_nocontent_create'>Click here to add new opportunities</p><p> Looks like you are not a member of a sales team. You should add yourself as a member of one of the sales team. </p>""" if user_team_id: action[ 'help'] += "<p>As you don't belong to any sales team, eCore opens the first one by default.</p>" action_context = eval(action['context'], {'uid': uid}) if user_team_id: action_context.update({ 'default_team_id': user_team_id, 'search_default_team_id': user_team_id }) tree_view_id = IrModelData.xmlid_to_res_id( cr, uid, 'crm.crm_case_tree_view_oppor') form_view_id = IrModelData.xmlid_to_res_id( cr, uid, 'crm.crm_case_form_view_oppor') kanb_view_id = IrModelData.xmlid_to_res_id( cr, uid, 'crm.crm_case_kanban_view_leads') action.update({ 'views': [[kanb_view_id, 'kanban'], [tree_view_id, 'tree'], [form_view_id, 'form'], [False, 'graph'], [False, 'calendar'], [False, 'pivot']], 'context': action_context, }) return action
def message_get_email_values(self, cr, uid, id, notif_mail=None, context=None): res = super(MailGroup, self).message_get_email_values(cr, uid, id, notif_mail=notif_mail, context=context) group = self.browse(cr, uid, id, context=context) base_url = self.pool['ir.config_parameter'].get_param(cr, uid, 'web.base.url') headers = {} if res.get('headers'): try: headers = eval(res['headers']) except Exception: pass headers.update({ 'List-Archive': '<%s/groups/%s>' % (base_url, slug(group)), 'List-Subscribe': '<%s/groups>' % (base_url), 'List-Unsubscribe': '<%s/groups?unsubscribe>' % (base_url,), }) res['headers'] = repr(headers) return res
def _check_attachment_use(self, cr, uid, ids, report): """ Check attachment_use field. If set to true and an existing pdf is already saved, load this one now. Else, mark save it. """ save_in_attachment = {} save_in_attachment['model'] = report.model save_in_attachment['loaded_documents'] = {} if report.attachment: for record_id in ids: obj = self.pool[report.model].browse(cr, uid, record_id) filename = eval(report.attachment, { 'object': obj, 'time': time }) # If the user has checked 'Reload from Attachment' if report.attachment_use: alreadyindb = [('datas_fname', '=', filename), ('res_model', '=', report.model), ('res_id', '=', record_id)] attach_ids = self.pool['ir.attachment'].search( cr, uid, alreadyindb) if attach_ids: # Add the loaded pdf in the loaded_documents list pdf = self.pool['ir.attachment'].browse( cr, uid, attach_ids[0]).datas pdf = base64.decodestring(pdf) save_in_attachment['loaded_documents'][record_id] = pdf _logger.info( 'The PDF document %s was loaded from the database' % filename) continue # Do not save this document as we already ignore it # If the user has checked 'Save as Attachment Prefix' if filename is False: # May be false if, for instance, the 'attachment' field contains a condition # preventing to save the file. continue else: save_in_attachment[ record_id] = filename # Mark current document to be saved return save_in_attachment
def _get_alias_defaults_values(self, cr, uid, ids, context=None): res = dict.fromkeys(ids, False) is_group_use_lead = self.pool['res.users'].has_group( cr, uid, 'crm.group_use_lead') for team in self.browse(cr, uid, ids, context=context): alias_defaults = eval(team.alias_defaults) alias_defaults.update({ 'type': 'lead' if is_group_use_lead and team.use_leads else 'opportunity', 'team_id': team.id, }) res[team.id] = { 'alias_defaults': alias_defaults, 'alias_parent_thread_id': team.id, } return res
def wkf_expr_eval_expr(self, lines): """ Evaluate each line of ``lines`` with the ``Environment`` environment, returning the value of the last line. """ assert lines, 'You used a NULL action in a workflow, use dummy node instead.' result = False for line in lines.split('\n'): line = line.strip() if not line: continue if line == 'True': result = True elif line == 'False': result = False else: env = Environment(self.session, self.record) result = eval(line, env, nocopy=True) return result
def wkf_expr_eval_expr(self, lines): """ Evaluate each line of ``lines`` with the ``Environment`` environment, returning the value of the last line. """ assert lines, 'You used a NULL action in a workflow, use dummy node instead.' result = False for line in lines.split('\n'): line = line.strip() if not line: continue if line == 'True': result = True elif line == 'False': result = False else: env = Environment(self.session, self.record) result = eval(line, env, nocopy=True) return result
def action_your_pipeline(self, cr, uid, context=None): IrModelData = self.pool['ir.model.data'] action = IrModelData.xmlid_to_object(cr, uid, 'crm.crm_lead_opportunities_tree_view').read(['name', 'help', 'res_model', 'target', 'domain', 'context', 'type', 'search_view_id']) if not action: action = {} else: action = action[0] user_team_id = self.pool['res.users'].browse(cr, uid, uid, context=context).sale_team_id.id if not user_team_id: user_team_id = self.search(cr, uid, [], context=context, limit=1) user_team_id = user_team_id and user_team_id[0] or False action['help'] = """<p class='oe_view_nocontent_create'>Click here to add new opportunities</p><p> Looks like you are not a member of a sales team. You should add yourself as a member of one of the sales team. </p>""" if user_team_id: action['help'] += "<p>As you don't belong to any sales team, eCore opens the first one by default.</p>" action_context = eval(action['context'], {'uid': uid}) if user_team_id: action_context.update({ 'default_team_id': user_team_id, 'search_default_team_id': user_team_id }) tree_view_id = IrModelData.xmlid_to_res_id(cr, uid, 'crm.crm_case_tree_view_oppor') form_view_id = IrModelData.xmlid_to_res_id(cr, uid, 'crm.crm_case_form_view_oppor') kanb_view_id = IrModelData.xmlid_to_res_id(cr, uid, 'crm.crm_case_kanban_view_leads') action.update({ 'views': [ [kanb_view_id, 'kanban'], [tree_view_id, 'tree'], [form_view_id, 'form'], [False, 'graph'], [False, 'calendar'], [False, 'pivot'] ], 'context': action_context, }) return action
def _search_qty_available(self, cr, uid, operator, value, context): domain_quant = [] if context.get('lot_id'): domain_quant.append(('lot_id', '=', context['lot_id'])) if context.get('owner_id'): domain_quant.append(('owner_id', '=', context['owner_id'])) if context.get('package_id'): domain_quant.append(('package_id', '=', context['package_id'])) domain_quant += self._get_domain_locations(cr, uid, [], context=context)[0] quants = self.pool.get('stock.quant').read_group(cr, uid, domain_quant, ['product_id', 'qty'], ['product_id'], context=context) quants = dict(map(lambda x: (x['product_id'][0], x['qty']), quants)) quants = dict((k, v) for k, v in quants.iteritems() if eval(str(v) + operator + str(value))) return (list(quants))
def format(self, cr, uid, ids, percent, value, grouping=False, monetary=False, context=None): """ Format() will return the language-specific output for float values""" if percent[0] != '%': raise ValueError("format() must be given exactly one %char format specifier") formatted = percent % value # floats and decimal ints need special action! if grouping: lang_grouping, thousands_sep, decimal_point = \ self._lang_data_get(cr, uid, ids[0], monetary) eval_lang_grouping = eval(lang_grouping) if percent[-1] in 'eEfFgG': parts = formatted.split('.') parts[0], _ = intersperse(parts[0], eval_lang_grouping, thousands_sep) formatted = decimal_point.join(parts) elif percent[-1] in 'diu': formatted = intersperse(formatted, eval_lang_grouping, thousands_sep)[0] return formatted
def _search_product_quantity(self, cr, uid, obj, name, domain, context): res = [] for field, operator, value in domain: #to prevent sql injections assert field in ('qty_available', 'virtual_available', 'incoming_qty', 'outgoing_qty'), 'Invalid domain left operand' assert operator in ('<', '>', '=', '!=', '<=', '>='), 'Invalid domain operator' assert isinstance(value, (float, int)), 'Invalid domain right operand' if operator == '=': operator = '==' ids = [] if name == 'qty_available' and (value != 0.0 or operator not in ('==', '>=', '<=')): res.append(('id', 'in', self._search_qty_available(cr, uid, operator, value, context))) else: product_ids = self.search(cr, uid, [], context=context) if product_ids: #TODO: Still optimization possible when searching virtual quantities for element in self.browse(cr, uid, product_ids, context=context): if eval(str(element[field]) + operator + str(value)): ids.append(element.id) res.append(('id', 'in', ids)) return res
def _check_attachment_use(self, cr, uid, ids, report): """ Check attachment_use field. If set to true and an existing pdf is already saved, load this one now. Else, mark save it. """ save_in_attachment = {} save_in_attachment['model'] = report.model save_in_attachment['loaded_documents'] = {} if report.attachment: for record_id in ids: obj = self.pool[report.model].browse(cr, uid, record_id) filename = eval(report.attachment, {'object': obj, 'time': time}) # If the user has checked 'Reload from Attachment' if report.attachment_use: alreadyindb = [('datas_fname', '=', filename), ('res_model', '=', report.model), ('res_id', '=', record_id)] attach_ids = self.pool['ir.attachment'].search(cr, uid, alreadyindb) if attach_ids: # Add the loaded pdf in the loaded_documents list pdf = self.pool['ir.attachment'].browse(cr, uid, attach_ids[0]).datas pdf = base64.decodestring(pdf) save_in_attachment['loaded_documents'][record_id] = pdf _logger.info('The PDF document %s was loaded from the database' % filename) continue # Do not save this document as we already ignore it # If the user has checked 'Save as Attachment Prefix' if filename is False: # May be false if, for instance, the 'attachment' field contains a condition # preventing to save the file. continue else: save_in_attachment[record_id] = filename # Mark current document to be saved return save_in_attachment
def _process_text(self, txt): """Translate ``txt`` according to the language in the local context, replace dynamic ``[[expr]]`` with their real value, then escape the result for XML. :param str txt: original text to translate (must NOT be XML-escaped) :return: translated text, with dynamic expressions evaluated and with special XML characters escaped (``&,<,>``). """ if not self.localcontext: return str2xml(txt) if not txt: return '' result = '' sps = _regex.split(txt) while sps: # This is a simple text to translate to_translate = tools.ustr(sps.pop(0)) result += tools.ustr( self.localcontext.get('translate', lambda x: x)(to_translate)) if sps: txt = None try: expr = sps.pop(0) txt = eval(expr, self.localcontext) if txt and isinstance(txt, basestring): txt = tools.ustr(txt) except Exception: _logger.info( "Failed to evaluate expression [[ %s ]] with context %r while rendering report, ignored.", expr, self.localcontext) if isinstance(txt, basestring): result += txt elif txt and (txt is not None) and (txt is not False): result += ustr(txt) return str2xml(result)
def get_diagram_info(self, req, id, model, node, connector, src_node, des_node, label, **kw): visible_node_fields = kw.get('visible_node_fields', []) invisible_node_fields = kw.get('invisible_node_fields', []) node_fields_string = kw.get('node_fields_string', []) connector_fields = kw.get('connector_fields', []) connector_fields_string = kw.get('connector_fields_string', []) bgcolors = {} shapes = {} bgcolor = kw.get('bgcolor', '') shape = kw.get('shape', '') if bgcolor: for color_spec in bgcolor.split(';'): if color_spec: colour, color_state = color_spec.split(':') bgcolors[colour] = color_state if shape: for shape_spec in shape.split(';'): if shape_spec: shape_colour, shape_color_state = shape_spec.split(':') shapes[shape_colour] = shape_color_state ir_view = req.session.model('ir.ui.view') graphs = ir_view.graph_get(int(id), model, node, connector, src_node, des_node, label, (140, 180), req.session.context) nodes = graphs['nodes'] transitions = graphs['transitions'] isolate_nodes = {} for blnk_node in graphs['blank_nodes']: isolate_nodes[blnk_node['id']] = blnk_node else: y = map( lambda t: t['y'], filter(lambda x: x['y'] if x['x'] == 20 else None, nodes.values())) y_max = (y and max(y)) or 120 connectors = {} list_tr = [] for tr in transitions: list_tr.append(tr) connectors.setdefault( tr, { 'id': int(tr), 's_id': transitions[tr][0], 'd_id': transitions[tr][1] }) connector_tr = req.session.model(connector) connector_ids = connector_tr.search([('id', 'in', list_tr)], 0, 0, 0, req.session.context) data_connectors = connector_tr.read(connector_ids, connector_fields, req.session.context) for tr in data_connectors: transition_id = str(tr['id']) _sourceid, label = graphs['label'][transition_id] t = connectors[transition_id] t.update(source=tr[src_node][1], destination=tr[des_node][1], options={}, signal=label) for i, fld in enumerate(connector_fields): t['options'][connector_fields_string[i]] = tr[fld] fields = req.session.model('ir.model.fields') field_ids = fields.search([('model', '=', model), ('relation', '=', node)], 0, 0, 0, req.session.context) field_data = fields.read(field_ids, ['relation_field'], req.session.context) node_act = req.session.model(node) search_acts = node_act.search( [(field_data[0]['relation_field'], '=', id)], 0, 0, 0, req.session.context) data_acts = node_act.read(search_acts, invisible_node_fields + visible_node_fields, req.session.context) for act in data_acts: n = nodes.get(str(act['id'])) if not n: n = isolate_nodes.get(act['id'], {}) y_max += 140 n.update(x=20, y=y_max) nodes[act['id']] = n n.update(id=act['id'], color='white', options={}) for color, expr in bgcolors.items(): if eval(expr, act): n['color'] = color for shape, expr in shapes.items(): if eval(expr, act): n['shape'] = shape for i, fld in enumerate(visible_node_fields): n['options'][node_fields_string[i]] = act[fld] _id, name = req.session.model(model).name_get([id], req.session.context)[0] return dict(nodes=nodes, conn=connectors, name=name, parent_field=graphs['node_parent_field'])
def send_mail(self, auto_commit=False): """ Process the wizard content and proceed with sending the related email(s), rendering any template patterns on the fly if needed. """ for wizard in self: # Duplicate attachments linked to the email.template. # Indeed, basic mail.compose.message wizard duplicates attachments in mass # mailing mode. But in 'single post' mode, attachments of an email template # also have to be duplicated to avoid changing their ownership. if wizard.attachment_ids and wizard.composition_mode != 'mass_mail' and wizard.template_id: new_attachment_ids = [] for attachment in wizard.attachment_ids: if attachment in wizard.template_id.attachment_ids: new_attachment_ids.append( attachment.copy({ 'res_model': 'mail.compose.message', 'res_id': wizard.id }).id) else: new_attachment_ids.append(attachment.id) wizard.write( {'attachment_ids': [(6, 0, new_attachment_ids)]}) # Mass Mailing mass_mode = wizard.composition_mode in ('mass_mail', 'mass_post') Mail = self.env['mail.mail'] ActiveModel = self.env[wizard.model if wizard. model else 'mail.thread'] if wizard.template_id: # template user_signature is added when generating body_html # mass mailing: use template auto_delete value -> note, for emails mass mailing only Mail = Mail.with_context( mail_notify_user_signature=False, mail_server_id=wizard.template_id.mail_server_id.id) ActiveModel = ActiveModel.with_context( mail_notify_user_signature=False, mail_auto_delete=wizard.template_id.auto_delete) if not hasattr(ActiveModel, 'message_post'): ActiveModel = self.env['mail.thread'].with_context( thread_model=wizard.model) if wizard.composition_mode == 'mass_post': # do not send emails directly but use the queue instead # add context key to avoid subscribing the author ActiveModel = ActiveModel.with_context( mail_notify_force_send=False, mail_create_nosubscribe=True) # wizard works in batch mode: [res_id] or active_ids or active_domain if mass_mode and wizard.use_active_domain and wizard.model: res_ids = self.env[wizard.model].search( eval(wizard.active_domain)).ids elif mass_mode and wizard.model and self._context.get( 'active_ids'): res_ids = self._context['active_ids'] else: res_ids = [wizard.res_id] batch_size = int(self.env['ir.config_parameter'].sudo().get_param( 'mail.batch_size')) or self._batch_size sliced_res_ids = [ res_ids[i:i + batch_size] for i in range(0, len(res_ids), batch_size) ] for res_ids in sliced_res_ids: batch_mails = Mail all_mail_values = wizard.get_mail_values(res_ids) for res_id, mail_values in all_mail_values.iteritems(): if wizard.composition_mode == 'mass_mail': batch_mails |= Mail.create(mail_values) else: subtype = 'mail.mt_comment' if wizard.is_log or (wizard.composition_mode == 'mass_post' and not wizard.notify ): # log a note: subtype is False subtype = False ActiveModel.browse(res_id).message_post( message_type='comment', subtype=subtype, **mail_values) if wizard.composition_mode == 'mass_mail': batch_mails.send(auto_commit=auto_commit) return {'type': 'ir.actions.act_window_close'}
def load_information_from_description_file(module, mod_path=None): """ :param module: The name of the module (sale, purchase, ...) :param mod_path: Physical path of module, if not providedThe name of the module (sale, purchase, ...) """ if not mod_path: mod_path = get_module_path(module) terp_file = mod_path and opj(mod_path, MANIFEST) or False if terp_file: info = {} if os.path.isfile(terp_file): # default values for descriptor info = { 'application': False, 'author': 'eCore SA', 'auto_install': False, 'category': 'Uncategorized', 'depends': [], 'description': '', 'icon': get_module_icon(module), 'installable': True, 'license': 'LGPL-3', 'post_load': None, 'version': '1.0', 'web': False, 'website': 'http://www.ecore.com', 'sequence': 100, 'summary': '', } info.update( itertools.izip( 'depends data demo test init_xml update_xml demo_xml'. split(), iter(list, None))) f = tools.file_open(terp_file) try: info.update(eval(f.read())) finally: f.close() if not info.get('description'): readme_path = [ opj(mod_path, x) for x in README if os.path.isfile(opj(mod_path, x)) ] if readme_path: readme_text = tools.file_open(readme_path[0]).read() info['description'] = readme_text if 'active' in info: # 'active' has been renamed 'auto_install' info['auto_install'] = info['active'] info['version'] = adapt_version(info['version']) return info #TODO: refactor the logger in this file to follow the logging guidelines # for 6.0 _logger.debug('module %s: no %s file found.', module, MANIFEST) return {}
def reverse_anonymize_database(self, cr, uid, ids, context=None): """Set the 'clear' state to defined fields""" ir_model_fields_anonymization_model = self.pool.get('ir.model.fields.anonymization') anonymization_history_model = self.pool.get('ir.model.fields.anonymization.history') # create a new history record: vals = { 'date': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), 'state': 'started', 'direction': 'anonymized -> clear', } history_id = anonymization_history_model.create(cr, uid, vals) # check that all the defined fields are in the 'anonymized' state state = ir_model_fields_anonymization_model._get_global_state(cr, uid, context=context) if state == 'clear': raise UserError(_("The database is not currently anonymized, you cannot reverse the anonymization.")) elif state == 'unstable': msg = _("The database anonymization is currently in an unstable state. Some fields are anonymized," + \ " while some fields are not anonymized. You should try to solve this problem before trying to do anything.") raise UserError(msg) wizards = self.browse(cr, uid, ids, context=context) for wizard in wizards: if not wizard.file_import: msg = _("It is not possible to reverse the anonymization process without supplying the anonymization export file.") self._raise_after_history_update(cr, uid, history_id, 'Error !', msg) # reverse the anonymization: # load the pickle file content into a data structure: data = pickle.loads(base64.decodestring(wizard.file_import)) migration_fix_obj = self.pool.get('ir.model.fields.anonymization.migration.fix') fix_ids = migration_fix_obj.search(cr, uid, [('target_version', '=', '8.0')]) fixes = migration_fix_obj.read(cr, uid, fix_ids, ['model_name', 'field_name', 'query', 'query_type', 'sequence']) fixes = group(fixes, ('model_name', 'field_name')) for line in data: queries = [] table_name = self.pool[line['model_id']]._table if line['model_id'] in self.pool else None # check if custom sql exists: key = (line['model_id'], line['field_id']) custom_updates = fixes.get(key) if custom_updates: custom_updates.sort(key=itemgetter('sequence')) queries = [(record['query'], record['query_type']) for record in custom_updates if record['query_type']] elif table_name: queries = [("update %(table)s set %(field)s = %%(value)s where id = %%(id)s" % { 'table': table_name, 'field': line['field_id'], }, 'sql')] for query in queries: if query[1] == 'sql': sql = query[0] cr.execute(sql, { 'value': line['value'], 'id': line['id'] }) elif query[1] == 'python': raw_code = query[0] code = raw_code % line eval(code) else: raise Exception("Unknown query type '%s'. Valid types are: sql, python." % (query['query_type'], )) # update the anonymization fields: ir_model_fields_anonymization_model = self.pool.get('ir.model.fields.anonymization') field_ids = ir_model_fields_anonymization_model.search(cr, uid, [('state', '<>', 'not_existing')], context=context) values = { 'state': 'clear', } ir_model_fields_anonymization_model.write(cr, uid, field_ids, values, context=context) # add a result message in the wizard: msg = '\n'.join(["Successfully reversed the anonymization.", "", ]) self.write(cr, uid, ids, {'msg': msg}) # update the history record: anonymization_history_model.write(cr, uid, history_id, { 'field_ids': [[6, 0, field_ids]], 'msg': msg, 'filepath': False, 'state': 'done', }) # handle the view: view_id = self.pool['ir.model.data'].xmlid_to_res_id( cr, uid, 'anonymization.view_ir_model_fields_anonymize_wizard_form' ) return { 'res_id': ids[0], 'view_id': [view_id], 'view_type': 'form', "view_mode": 'form', 'res_model': 'ir.model.fields.anonymize.wizard', 'type': 'ir.actions.act_window', 'context': {'step': 'just_desanonymized'}, 'target':'new', }
def create_source_pdf(self, cr, uid, ids, data, report_xml, context=None): if not context: context = {} registry = ecore.registry(cr.dbname) attach = report_xml.attachment if attach: objs = self.getObjects(cr, uid, ids, context) results = [] for obj in objs: aname = eval(attach, {'object': obj, 'time': time}) result = False if report_xml.attachment_use and aname and context.get( 'attachment_use', True): aids = registry['ir.attachment'].search( cr, uid, [('datas_fname', '=', aname + '.pdf'), ('res_model', '=', self.table), ('res_id', '=', obj.id)]) if aids: brow_rec = registry['ir.attachment'].browse( cr, uid, aids[0]) if not brow_rec.datas: continue d = base64.decodestring(brow_rec.datas) results.append((d, 'pdf')) continue result = self.create_single_pdf(cr, uid, [obj.id], data, report_xml, context) if not result: return False if aname: try: name = aname + '.' + result[1] # Remove the default_type entry from the context: this # is for instance used on the account.account_invoices # and is thus not intended for the ir.attachment type # field. ctx = dict(context) ctx.pop('default_type', None) registry['ir.attachment'].create( cr, uid, { 'name': aname, 'datas': base64.encodestring(result[0]), 'datas_fname': name, 'res_model': self.table, 'res_id': obj.id, }, context=ctx) except AccessError: #TODO: should probably raise a proper osv_except instead, shouldn't we? see LP bug #325632 _logger.info( 'Could not create saved report attachment', exc_info=True) results.append(result) if results: if results[0][1] == 'pdf': from pyPdf import PdfFileWriter, PdfFileReader output = PdfFileWriter() for r in results: reader = PdfFileReader(cStringIO.StringIO(r[0])) for page in range(reader.getNumPages()): output.addPage(reader.getPage(page)) s = cStringIO.StringIO() output.write(s) return s.getvalue(), results[0][1] return self.create_single_pdf(cr, uid, ids, data, report_xml, context)
n2.tag = tag n2.attrib.update(attr) yield n2 except GeneratorExit: yield n except Exception, e: _logger.info('rml_tag: "%s"', n.get('rml_tag', ''), exc_info=True) yield n else: yield n continue if self and self.localcontext and n.get('rml_except'): try: eval(n.get('rml_except'), {}, self.localcontext) except GeneratorExit: continue except Exception, e: _logger.info('rml_except: "%s"', n.get('rml_except', ''), exc_info=True) continue if self and self.localcontext and n.get('rml_tag'): try: (tag, attr) = eval(n.get('rml_tag'), {}, self.localcontext) n2 = copy.deepcopy(n) n2.tag = tag n2.attrib.update(attr or {}) yield n2 tagname = ''
def get_diagram_info(self, req, id, model, node, connector, src_node, des_node, label, **kw): visible_node_fields = kw.get('visible_node_fields',[]) invisible_node_fields = kw.get('invisible_node_fields',[]) node_fields_string = kw.get('node_fields_string',[]) connector_fields = kw.get('connector_fields',[]) connector_fields_string = kw.get('connector_fields_string',[]) bgcolors = {} shapes = {} bgcolor = kw.get('bgcolor','') shape = kw.get('shape','') if bgcolor: for color_spec in bgcolor.split(';'): if color_spec: colour, color_state = color_spec.split(':') bgcolors[colour] = color_state if shape: for shape_spec in shape.split(';'): if shape_spec: shape_colour, shape_color_state = shape_spec.split(':') shapes[shape_colour] = shape_color_state ir_view = req.session.model('ir.ui.view') graphs = ir_view.graph_get( int(id), model, node, connector, src_node, des_node, label, (140, 180), req.session.context) nodes = graphs['nodes'] transitions = graphs['transitions'] isolate_nodes = {} for blnk_node in graphs['blank_nodes']: isolate_nodes[blnk_node['id']] = blnk_node else: y = map(lambda t: t['y'],filter(lambda x: x['y'] if x['x']==20 else None, nodes.values())) y_max = (y and max(y)) or 120 connectors = {} list_tr = [] for tr in transitions: list_tr.append(tr) connectors.setdefault(tr, { 'id': int(tr), 's_id': transitions[tr][0], 'd_id': transitions[tr][1] }) connector_tr = req.session.model(connector) connector_ids = connector_tr.search([('id', 'in', list_tr)], 0, 0, 0, req.session.context) data_connectors =connector_tr.read(connector_ids, connector_fields, req.session.context) for tr in data_connectors: transition_id = str(tr['id']) _sourceid, label = graphs['label'][transition_id] t = connectors[transition_id] t.update( source=tr[src_node][1], destination=tr[des_node][1], options={}, signal=label ) for i, fld in enumerate(connector_fields): t['options'][connector_fields_string[i]] = tr[fld] fields = req.session.model('ir.model.fields') field_ids = fields.search([('model', '=', model), ('relation', '=', node)], 0, 0, 0, req.session.context) field_data = fields.read(field_ids, ['relation_field'], req.session.context) node_act = req.session.model(node) search_acts = node_act.search([(field_data[0]['relation_field'], '=', id)], 0, 0, 0, req.session.context) data_acts = node_act.read(search_acts, invisible_node_fields + visible_node_fields, req.session.context) for act in data_acts: n = nodes.get(str(act['id'])) if not n: n = isolate_nodes.get(act['id'], {}) y_max += 140 n.update(x=20, y=y_max) nodes[act['id']] = n n.update( id=act['id'], color='white', options={} ) for color, expr in bgcolors.items(): if eval(expr, act): n['color'] = color for shape, expr in shapes.items(): if eval(expr, act): n['shape'] = shape for i, fld in enumerate(visible_node_fields): n['options'][node_fields_string[i]] = act[fld] _id, name = req.session.model(model).name_get([id], req.session.context)[0] return dict(nodes=nodes, conn=connectors, name=name, parent_field=graphs['node_parent_field'])
def _image(self, node): import urllib import urlparse from reportlab.lib.utils import ImageReader nfile = node.get('file') if not nfile: if node.get('name'): image_data = self.images[node.get('name')] _logger.debug("Image %s used", node.get('name')) s = StringIO(image_data) else: newtext = node.text if self.localcontext: res = utils._regex.findall(newtext) for key in res: newtext = eval(key, {}, self.localcontext) or '' image_data = None if newtext: image_data = base64.decodestring(newtext) if image_data: s = StringIO(image_data) else: _logger.debug("No image data!") return False else: if nfile in self.images: s = StringIO(self.images[nfile]) else: try: up = urlparse.urlparse(str(nfile)) except ValueError: up = False if up and up.scheme: # RFC: do we really want to open external URLs? # Are we safe from cross-site scripting or attacks? _logger.debug("Retrieve image from %s", nfile) u = urllib.urlopen(str(nfile)) s = StringIO(u.read()) else: _logger.debug("Open image file %s ", nfile) s = _open_image(nfile, path=self.path) try: img = ImageReader(s) (sx, sy) = img.getSize() _logger.debug("Image is %dx%d", sx, sy) args = {'x': 0.0, 'y': 0.0, 'mask': 'auto'} for tag in ('width', 'height', 'x', 'y'): if node.get(tag): args[tag] = utils.unit_get(node.get(tag)) if ('width' in args) and (not 'height' in args): args['height'] = sy * args['width'] / sx elif ('height' in args) and (not 'width' in args): args['width'] = sx * args['height'] / sy elif ('width' in args) and ('height' in args): if (float(args['width']) / args['height']) > (float(sx) > sy): args['width'] = sx * args['height'] / sy else: args['height'] = sy * args['width'] / sx self.canvas.drawImage(img, **args) finally: s.close()
def _row_get(self, cr, uid, objs, fields, conditions, row_canvas=None, group_by=None): result = [] for obj in objs: tobreak = False for cond in conditions: if cond and cond[0]: c = cond[0] temp = c[0](eval('obj.' + c[1], {'obj': obj})) if not eval('\'' + temp + '\'' + ' ' + c[2] + ' ' + '\'' + str(c[3]) + '\''): tobreak = True if tobreak: break levels = {} row = [] for i in range(len(fields)): if not fields[i]: row.append(row_canvas and row_canvas[i]) if row_canvas[i]: row_canvas[i] = False elif len(fields[i]) == 1: if obj: row.append( str(eval('obj.' + fields[i][0], {'obj': obj}))) else: row.append(None) else: row.append(None) levels[fields[i][0]] = True if not levels: result.append(row) else: # Process group_by data first key = [] if group_by is not None and fields[group_by] is not None: if fields[group_by][0] in levels.keys(): key.append(fields[group_by][0]) for l in levels.keys(): if l != fields[group_by][0]: key.append(l) else: key = levels.keys() for l in key: objs = eval('obj.' + l, {'obj': obj}) if not isinstance(objs, (BaseModel, list)): objs = [objs] field_new = [] cond_new = [] for f in range(len(fields)): if (fields[f] and fields[f][0]) == l: field_new.append(fields[f][1:]) cond_new.append(conditions[f][1:]) else: field_new.append(None) cond_new.append(None) if len(objs): result += self._row_get(cr, uid, objs, field_new, cond_new, row, group_by) else: result.append(row) return result