def test_smtp_connection(self): for server in self: smtp = False try: smtp = self.connect(mail_server_id=server.id) # simulate sending an email from current user's address - without sending it! email_from, email_to = server._get_test_email_addresses() # Testing the MAIL FROM step should detect sender filter problems (code, repl) = smtp.mail(email_from) if code != 250: raise UserError(_('The server refused the sender address (%(email_from)s) ' 'with error %(repl)s') % locals()) # Testing the RCPT TO step should detect most relaying problems (code, repl) = smtp.rcpt(email_to) if code not in (250, 251): raise UserError(_('The server refused the test recipient (%(email_to)s) ' 'with error %(repl)s') % locals()) # Beginning the DATA step should detect some deferred rejections # Can't use self.data() as it would actually send the mail! smtp.putcmd("data") (code, repl) = smtp.getreply() if code != 354: raise UserError(_('The server refused the test connection ' 'with error %(repl)s') % locals()) except UserError as e: # let UserErrors (messages) bubble up raise e except (UnicodeError, idna.core.InvalidCodepoint) as e: raise UserError(_("Invalid server name !\n %s", ustr(e))) except (gaierror, timeout) as e: raise UserError(_("No response received. Check server address and port number.\n %s", ustr(e))) except smtplib.SMTPServerDisconnected as e: raise UserError(_("The server has closed the connection unexpectedly. Check configuration served on this port number.\n %s", ustr(e.strerror))) except smtplib.SMTPResponseException as e: raise UserError(_("Server replied with following exception:\n %s", ustr(e.smtp_error))) except smtplib.SMTPException as e: raise UserError(_("An SMTP exception occurred. Check port number and connection security type.\n %s", ustr(e))) except SSLError as e: raise UserError(_("An SSL exception occurred. Check connection security type.\n %s", ustr(e))) except Exception as e: raise UserError(_("Connection Test Failed! Here is what we got instead:\n %s", ustr(e))) finally: try: if smtp: smtp.close() except Exception: # ignored, just a consequence of the previous exception pass title = _("Connection Test Succeeded!") message = _("Everything seems properly set up!") return { 'type': 'ir.actions.client', 'tag': 'display_notification', 'params': { 'title': title, 'message': message, 'sticky': False, } }
def amount_to_text(self, amount): self.ensure_one() def _num2words(number, lang): try: return num2words(number, lang=lang).title() except NotImplementedError: return num2words(number, lang='en').title() if num2words is None: logging.getLogger(__name__).warning("The library 'num2words' is missing, cannot render textual amounts.") return "" formatted = "%.{0}f".format(self.decimal_places) % amount parts = formatted.partition('.') integer_value = int(parts[0]) fractional_value = int(parts[2] or 0) lang = tools.get_lang(self.env) amount_words = tools.ustr('{amt_value} {amt_word}').format( amt_value=_num2words(integer_value, lang=lang.iso_code), amt_word=self.currency_unit_label, ) if not self.is_zero(amount - integer_value): amount_words += ' ' + _('and') + tools.ustr(' {amt_value} {amt_word}').format( amt_value=_num2words(fractional_value, lang=lang.iso_code), amt_word=self.currency_subunit_label, ) return amount_words
def get_record_data(self, values): """ Returns a defaults-like dict with initial values for the composition wizard when sending an email related a previous email (parent_id) or a document (model, res_id). This is based on previously computed default values. """ result, subject = {}, False if values.get('parent_id'): parent = self.env['mail.message'].browse(values.get('parent_id')) result['record_name'] = parent.record_name, subject = tools.ustr(parent.subject or parent.record_name or '') if not values.get('model'): result['model'] = parent.model if not values.get('res_id'): result['res_id'] = parent.res_id partner_ids = values.get('partner_ids', list()) + parent.partner_ids.ids result['partner_ids'] = partner_ids elif values.get('model') and values.get('res_id'): doc_name_get = self.env[values.get('model')].browse( values.get('res_id')).name_get() result['record_name'] = doc_name_get and doc_name_get[0][1] or '' subject = tools.ustr(result['record_name']) re_prefix = _('Re:') if subject and not (subject.startswith('Re:') or subject.startswith(re_prefix)): subject = "%s %s" % (re_prefix, subject) result['subject'] = subject return result
def amount_to_text(self, amount): self.ensure_one() def _num2words(number, lang): try: return num2words(number, lang=lang).title() except NotImplementedError: return num2words(number, lang='en').title() if num2words is None: logging.getLogger(__name__).warning( "The library 'num2words' is missing, cannot render textual amounts." ) return "" fractional_value, integer_value = math.modf(amount) fractional_amount = round(abs(fractional_value), self.decimal_places) * (math.pow( 10, self.decimal_places)) lang_code = self.env.context.get('lang') or self.env.user.lang lang = self.env['res.lang'].search([('code', '=', lang_code)]) amount_words = tools.ustr('{amt_value} {amt_word}').format( amt_value=_num2words(int(integer_value), lang=lang.iso_code), amt_word=self.currency_unit_label, ) if not self.is_zero(fractional_value): amount_words += ' ' + _('and') + tools.ustr( ' {amt_value} {amt_word}').format( amt_value=_num2words(int(fractional_amount), lang=lang.iso_code), amt_word=self.currency_subunit_label, ) return amount_words
def inter_call(self, data): ctx = dict(self._context) ctx.update(({'depends': {}})) res = base_module_save._create_module(self.with_context(ctx), data) res_id = self.env.ref('base_module_record.module_create_form_view').id rec_id = self.create({ 'module_filename': ustr(res['module_filename']), 'module_file': ustr(res['module_file']), 'name': ustr(res['name']), 'directory_name': ustr(res['directory_name']), 'version': ustr(res['version']), 'author': ustr(res['author']), 'website': ustr(res['website']), 'category': ustr(res['category']), 'description': ustr(res['description']), }).id return { 'name': _('Module Recording'), 'view_type': 'form', 'view_mode': 'form', 'res_id': rec_id, 'res_model': 'base.module.record.objects', 'views': [(res_id, 'form')], 'type': 'ir.actions.act_window', 'target': 'new', }
def initialize_sys_path(): """ Setup the addons path ``flectra.addons.__path__`` with various defaults and explicit directories. """ # hook flectra.addons on data dir dd = os.path.normcase(tools.config.addons_data_dir) if os.access(dd, os.R_OK) and dd not in flectra.addons.__path__: flectra.addons.__path__.append(dd) # hook flectra.addons on addons paths for ad in tools.config['addons_path'].split(','): ad = os.path.normcase(os.path.abspath(tools.ustr(ad.strip()))) if ad not in flectra.addons.__path__: flectra.addons.__path__.append(ad) # hook flectra.addons on base module path base_path = os.path.normcase( os.path.abspath( os.path.join(os.path.dirname(os.path.dirname(__file__)), 'addons'))) if base_path not in flectra.addons.__path__ and os.path.isdir(base_path): flectra.addons.__path__.append(base_path) # hook flectra.upgrade on upgrade-path from flectra import upgrade legacy_upgrade_path = os.path.join(base_path, 'base', 'maintenance', 'migrations') for up in (tools.config['upgrade_path'] or legacy_upgrade_path).split(','): up = os.path.normcase(os.path.abspath(tools.ustr(up.strip()))) if up not in upgrade.__path__: upgrade.__path__.append(up) # create decrecated module alias from flectra.addons.base.maintenance.migrations to flectra.upgrade spec = importlib.machinery.ModuleSpec("flectra.addons.base.maintenance", None, is_package=True) maintenance_pkg = importlib.util.module_from_spec(spec) maintenance_pkg.migrations = upgrade sys.modules["flectra.addons.base.maintenance"] = maintenance_pkg sys.modules["flectra.addons.base.maintenance.migrations"] = upgrade # hook deprecated module alias from openerp to flectra and "crm"-like to flectra.addons if not getattr(initialize_sys_path, 'called', False): # only initialize once sys.meta_path.insert(0, UpgradeHook()) sys.meta_path.insert(0, FlectraHook()) sys.meta_path.insert(0, AddonsHook()) initialize_sys_path.called = True
def write(self, vals): if vals.get('user_domain'): users = self._get_challenger_users(ustr(vals.get('user_domain'))) if not vals.get('user_ids'): vals['user_ids'] = [] vals['user_ids'].extend((4, user.id) for user in users) write_res = super(Challenge, self).write(vals) if vals.get('report_message_frequency', 'never') != 'never': # _recompute_challenge_users do not set users for challenges with no reports, subscribing them now for challenge in self: challenge.message_subscribe( [user.partner_id.id for user in challenge.user_ids]) if vals.get('state') == 'inprogress': self._recompute_challenge_users() self._generate_goals_from_challenge() elif vals.get('state') == 'done': self._check_challenge_reward(force=True) elif vals.get('state') == 'draft': # resetting progress if self.env['gamification.goal'].search( [('challenge_id', 'in', self.ids), ('state', '=', 'inprogress')], limit=1): raise exceptions.UserError( _("You can not reset a challenge with unfinished goals.")) return write_res
def confirm(self, **kw): tx_id = int(kw.get('tx_id', 0)) access_token = kw.get('access_token') if tx_id: if access_token: tx = request.env['payment.transaction'].sudo().browse(tx_id) secret = request.env['ir.config_parameter'].sudo().get_param('database.secret') valid_token_str = '%s%s%s' % (tx.id, tx.reference, float_repr(tx.amount, precision_digits=tx.currency_id.decimal_places)) valid_token = hmac.new(secret.encode('utf-8'), valid_token_str.encode('utf-8'), hashlib.sha256).hexdigest() if not consteq(ustr(valid_token), access_token): raise werkzeug.exceptions.NotFound else: tx = request.env['payment.transaction'].browse(tx_id) if tx.state in ['done', 'authorized']: status = 'success' message = tx.acquirer_id.done_msg elif tx.state == 'pending': status = 'warning' message = tx.acquirer_id.pending_msg else: status = 'danger' message = tx.state_message or _('An error occured during the processing of this payment') PaymentProcessing.remove_payment_transaction(tx) return request.render('payment.confirm', {'tx': tx, 'status': status, 'message': message}) else: return request.redirect('/my/home')
def pack_jobs_request(self, term_ids, context=None): ''' prepare the terms that will be requested to gengo and returns them in a dictionary with following format {'jobs': { 'term1.id': {...} 'term2.id': {...} } }''' base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url') IrTranslation = self.env['ir.translation'] jobs = {} user = self.env.user auto_approve = 1 if user.company_id.gengo_auto_approve else 0 for term in term_ids: if re.search(r"\w", term.src or ""): comment = user.company_id.gengo_comment or '' if term.gengo_comment: comment += '\n' + term.gengo_comment jobs[time.strftime('%Y%m%d%H%M%S') + '-' + str(term.id)] = { 'type': 'text', 'slug': 'Single :: English to ' + term.lang, 'tier': tools.ustr(term.gengo_translation), 'custom_data': str(term.id), 'body_src': term.src, 'lc_src': 'en', 'lc_tgt': IrTranslation._get_gengo_corresponding_language(term.lang), 'auto_approve': auto_approve, 'comment': comment, 'callback_url': "%s/website/gengo_callback?pgk=%s&db=%s" % (base_url, self.get_gengo_key(), self.env.cr.dbname) } return {'jobs': jobs, 'as_group': 0}
def write(self, vals): if 'image' in vals: image = ustr(vals['image'] or '').encode('utf-8') vals['image_payment_form'] = image_resize_image(image, size=(45, 30)) vals['image'] = image_resize_image(image, size=(64, 64)) return super(PaymentIcon, self).write(vals)
def check_token(self, access_token, partner_id, amount, currency_id): secret = self.env['ir.config_parameter'].sudo().get_param('database.secret') token_str = '%s%s%s' % (partner_id, amount, currency_id) correct_token = hmac.new(secret.encode('utf-8'), token_str.encode('utf-8'), hashlib.sha256).hexdigest() if consteq(ustr(access_token), correct_token): return True return False
def slugify(self, s): s = ustr(s) uni = unicodedata.normalize('NFKD', s).encode('ascii', 'ignore').decode('ascii') slug_str = re.sub('[\W_]', ' ', uni).strip().lower() slug_str = re.sub('[-\s]+', '_', slug_str) return slug_str
def change_product_qty(self): """ Changes the Product Quantity by making a Physical Inventory. """ Inventory = self.env['stock.inventory'] for wizard in self: product = wizard.product_id.with_context( location=wizard.location_id.id, lot_id=wizard.lot_id.id) line_data = wizard._action_start_line() if wizard.product_id.id and wizard.lot_id.id: inventory_filter = 'none' elif wizard.product_id.id: inventory_filter = 'product' else: inventory_filter = 'none' inventory = Inventory.create({ 'name': _('INV: %s') % tools.ustr(wizard.product_id.name), 'filter': inventory_filter, 'product_id': wizard.product_id.id, 'location_id': wizard.location_id.id, 'lot_id': wizard.lot_id.id, 'line_ids': [(0, 0, line_data)], }) inventory.action_done() return {'type': 'ir.actions.act_window_close'}
def test_mail_body(self): bodies = [ 'content', '<p>content</p>', '<head><meta content="text/html; charset=utf-8" http-equiv="Content-Type"></head><body><p>content</p></body>', test_mail_examples.MISC_HTML_SOURCE, test_mail_examples.QUOTE_THUNDERBIRD_HTML, ] expected_list = [ 'content', 'content', 'content', "test1\n*test2*\ntest3\ntest4\ntest5\ntest6 test7\ntest8 test9\ntest10\ntest11\ntest12\ngoogle [1]\ntest link [2]\n\n\n[1] http://google.com\n[2] javascript:alert('malicious code')", 'On 01/05/2016 10:24 AM, Raoul\nPoilvache wrote:\n\n* Test reply. The suite. *\n\n--\nRaoul Poilvache\n\nTop cool !!!\n\n--\nRaoul Poilvache', ] for body, expected in zip(bodies, expected_list): message = self.env['ir.mail_server'].build_email( '*****@*****.**', '*****@*****.**', body=body, subject='Subject', subtype='html', ) body_alternative = False for part in message.walk(): if part.get_content_maintype() == 'multipart': continue # skip container if part.get_content_type() == 'text/plain': if not part.get_payload(): continue body_alternative = tools.ustr(part.get_content()) # remove ending new lines as it just adds noise body_alternative = body_alternative.strip('\n') self.assertEqual(body_alternative, expected)
def remove_accents(input_str): """Suboptimal-but-better-than-nothing way to replace accented latin letters by an ASCII equivalent. Will obviously change the meaning of input_str and work only for some cases""" input_str = ustr(input_str) nkfd_form = unicodedata.normalize('NFKD', input_str) return u''.join([c for c in nkfd_form if not unicodedata.combining(c)])
def get_graph_data(self, question, current_filters=None): '''Returns formatted data required by graph library on basis of filter''' # TODO refactor this terrible method and merge it with prepare_result_dict current_filters = current_filters if current_filters else [] Survey = request.env['survey.survey'] result = [] if question.type == 'multiple_choice': result.append({ 'key': ustr(question.question), 'values': Survey.prepare_result(question, current_filters)['answers'] }) if question.type == 'simple_choice': result = Survey.prepare_result(question, current_filters)['answers'] if question.type == 'matrix': data = Survey.prepare_result(question, current_filters) for answer in data['answers']: values = [] for row in data['rows']: values.append({ 'text': data['rows'].get(row), 'count': data['result'].get((row, answer)) }) result.append({ 'key': data['answers'].get(answer), 'values': values }) return json.dumps(result)
def get_or_create_user(self, conf, login, ldap_entry): """ Retrieve an active resource of model res_users with the specified login. Create the user if it is not initially found. :param dict conf: LDAP configuration :param login: the user's login :param tuple ldap_entry: single LDAP result (dn, attrs) :return: res_users id :rtype: int """ user_id = False login = tools.ustr(login.lower().strip()) self.env.cr.execute( "SELECT id, active FROM res_users WHERE lower(login)=%s", (login, )) res = self.env.cr.fetchone() if res: if res[1]: user_id = res[0] elif conf['create_user']: _logger.debug("Creating new Flectra user \"%s\" from LDAP" % login) values = self.map_ldap_attributes(conf, login, ldap_entry) SudoUser = self.env['res.users'].sudo().with_context( no_reset_password=True) if conf['user']: values['active'] = True user_id = SudoUser.browse( conf['user'][0]).copy(default=values).id else: user_id = SudoUser.create(values).id return user_id
def save_as_template(self): """ hit save as template button: current form value will be a new template attached to the current document. """ for record in self: model = self.env['ir.model']._get(record.model or 'mail.message') model_name = model.name or '' template_name = "%s: %s" % (model_name, tools.ustr(record.subject)) values = { 'name': template_name, 'subject': record.subject or False, 'body_html': record.body or False, 'model_id': model.id or False, 'attachment_ids': [(6, 0, [att.id for att in record.attachment_ids])], } template = self.env['mail.template'].create(values) # generate the saved template record.write({'template_id': template.id}) record.onchange_template_id_wrapper() return _reopen(self, record.id, record.model, context=self._context)
def _get_source(self, name, types, lang, source=None, res_id=None): """ Return the translation for the given combination of ``name``, ``type``, ``language`` and ``source``. All values passed to this method should be unicode (not byte strings), especially ``source``. :param name: identification of the term to translate, such as field name (optional if source is passed) :param types: single string defining type of term to translate (see ``type`` field on ir.translation), or sequence of allowed types (strings) :param lang: language code of the desired translation :param source: optional source term to translate (should be unicode) :param res_id: optional resource id or a list of ids to translate (if used, ``source`` should be set) :rtype: unicode :return: the request translation, or an empty unicode string if no translation was found and `source` was not passed """ # FIXME: should assert that `source` is unicode and fix all callers to # always pass unicode so we can remove the string encoding/decoding. if not lang: return tools.ustr(source or '') if isinstance(types, str): types = (types, ) if res_id: if isinstance(res_id, int): res_id = (res_id, ) else: res_id = tuple(res_id) return self.__get_source(name, types, lang, source, res_id)
def execute_callback(self): res = None for transaction in self: # limited sudo env, only for checking callback presence, not for running it! # manual transactions have no callback, and can pass without being run by admin user tx_sudo = transaction.sudo() if not (tx_sudo.callback_model_id and tx_sudo.callback_res_id and tx_sudo.callback_method): continue valid_token = transaction._generate_callback_hash() if not consteq(ustr(valid_token), transaction.callback_hash): _logger.warning( "Invalid callback signature for transaction %d" % (transaction.id)) continue record = self.env[transaction.callback_model_id.model].browse( transaction.callback_res_id).exists() if record: res = getattr(record, transaction.callback_method)(transaction) else: _logger.warning( "Did not found record %s.%s for callback of transaction %d" % (transaction.callback_model_id.model, transaction.callback_res_id, transaction.id)) return res
def onchange_employee_id(self, date_from, date_to, employee_id=False, contract_id=False): # defaults res = { 'value': { 'line_ids': [], # delete old input lines 'input_line_ids': [(2, x,) for x in self.input_line_ids.ids], # delete old worked days lines 'worked_days_line_ids': [(2, x,) for x in self.worked_days_line_ids.ids], # 'details_by_salary_head':[], TODO put me back 'name': '', 'contract_id': False, 'struct_id': False, } } if (not employee_id) or (not date_from) or (not date_to): return res ttyme = datetime.combine(fields.Date.from_string(date_from), time.min) employee = self.env['hr.employee'].browse(employee_id) locale = self.env.context.get('lang') or 'en_US' res['value'].update({ 'name': _('Salary Slip of %s for %s') % ( employee.name, tools.ustr(babel.dates.format_date(date=ttyme, format='MMMM-y', locale=locale))), 'company_id': employee.company_id.id, }) if not self.env.context.get('contract'): # fill with the first contract of the employee contract_ids = self.get_contract(employee, date_from, date_to) else: if contract_id: # set the list of contract for which the input have to be filled contract_ids = [contract_id] else: # if we don't give the contract, then the input to fill should be for all current contracts of the employee contract_ids = self.get_contract(employee, date_from, date_to) if not contract_ids: return res contract = self.env['hr.contract'].browse(contract_ids[0]) res['value'].update({ 'contract_id': contract.id }) struct = contract.struct_id if not struct: return res res['value'].update({ 'struct_id': struct.id, }) # computation of the salary input contracts = self.env['hr.contract'].browse(contract_ids) worked_days_line_ids = self.get_worked_day_lines(contracts, date_from, date_to) input_line_ids = self.get_inputs(contracts, date_from, date_to) res['value'].update({ 'worked_days_line_ids': worked_days_line_ids, 'input_line_ids': input_line_ids, }) return res
def record_objects(self): data = self.read([])[0] check_date = data['check_date'] filter_cond = data['filter_cond'] mod_obj = self.env['ir.model'] recording_data = [] self = self.with_context({'recording_data': recording_data}) for o_id in data['objects']: obj_name = (mod_obj.browse(o_id)).model obj_pool = self.env[obj_name] if filter_cond == 'created': search_condition = [('create_date', '>', check_date)] elif filter_cond == 'modified': search_condition = [('write_date', '>', check_date)] elif filter_cond == 'created_modified': search_condition = [ '|', ('create_date', '>', check_date), ('write_date', '>', check_date) ] if '_log_access' in dir(obj_pool): if not (obj_pool._log_access): search_condition = [] if '_auto' in dir(obj_pool): if not obj_pool._auto: continue search_ids = obj_pool.search(search_condition) for s_id in search_ids: dbname = self.env.cr.dbname args = (dbname, self.env.user.id, obj_name, 'copy', s_id.id, {}) recording_data.append(('query', args, {}, s_id.id)) if len(recording_data): res = self._create_xml(data) res_id = self.env.ref( 'base_module_record.module_create_xml_view').id return { 'name': _('Data Recording'), 'context': { 'default_res_text': ustr(res['res_text']) }, 'view_type': 'form', 'view_mode': 'form', 'res_model': 'base.module.record.data', 'views': [(res_id, 'form')], 'type': 'ir.actions.act_window', 'target': 'new', } res_id = self.env.ref( 'base_module_record.module_recording_message_view').id return { 'name': _('Module Recording'), 'context': {}, 'view_type': 'form', 'view_mode': 'form', 'res_model': 'base.module.record.objects', 'views': [(res_id, 'form')], 'type': 'ir.actions.act_window', 'target': 'new', }
def _render_template_jinja(self, template_txt, model, res_ids, add_context=None): """ Render a string-based template on records given by a model and a list of IDs, using jinja. In addition to the generic evaluation context given by _render_jinja_eval_context some new variables are added, depending on each record * ``object``: record based on which the template is rendered; :param str template_txt: template text to render :param str model: model name of records on which we want to perform rendering :param list res_ids: list of ids of records (all belonging to same model) :return dict: {res_id: string of rendered template based on record} """ # TDE FIXME: remove that brol (6dde919bb9850912f618b561cd2141bffe41340c) no_autoescape = self._context.get('safe') results = dict.fromkeys(res_ids, u"") if not template_txt: return results # try to load the template try: jinja_env = jinja_safe_template_env if no_autoescape else jinja_template_env template = jinja_env.from_string(tools.ustr(template_txt)) except Exception: _logger.info("Failed to load template %r", template_txt, exc_info=True) return results # prepare template variables variables = self._render_jinja_eval_context() if add_context: variables.update(**add_context) safe_eval.check_values(variables) # TDE CHECKME # records = self.env[model].browse(it for it in res_ids if it) # filter to avoid browsing [None] if any(r is None for r in res_ids): raise ValueError(_('Unsuspected None')) for record in self.env[model].browse(res_ids): variables['object'] = record try: render_result = template.render(variables) except Exception as e: _logger.info("Failed to render template : %s" % e, exc_info=True) raise UserError(_("Failed to render template : %s", e)) if render_result == u"False": render_result = u"" results[record.id] = render_result return results
def dump_bytes(self, value, write): # XML 1.0 disallows control characters, check for them immediately to # see if this is a "real" binary (rather than base64 or somesuch) and # blank it out, otherwise they get embedded in the output and break # client-side parsers if XML_INVALID.search(value): self.dump_unicode('', write) else: self.dump_unicode(ustr(value), write)
def extract_rfc2822_addresses(text): """Returns a list of valid RFC2822 addresses that can be found in ``source``, ignoring malformed ones and non-ASCII ones. """ if not text: return [] candidates = address_pattern.findall(ustr(text)) return [c for c in candidates if is_ascii(c)]
def _geoip_setup_resolver(cls): # Lazy init of GeoIP resolver if flectra._geoip_resolver is not None: return geofile = config.get('geoip_database') try: flectra._geoip_resolver = GeoIPResolver.open(geofile) or False except Exception as e: _logger.warning('Cannot load GeoIP: %s', ustr(e))
def __get_source(self, name, types, lang, source, res_id): # res_id is a tuple or None, otherwise ormcache cannot cache it! query, params = self._get_source_query(name, types, lang, source, res_id) self._cr.execute(query, params) res = self._cr.fetchone() trad = res and res[0] or u'' if source and not trad: return tools.ustr(source) return trad
def geo_query_address(street=None, zip=None, city=None, state=None, country=None): if country and ',' in country and (country.endswith(' of') or country.endswith(' of the')): # put country qualifier in front, otherwise GMap gives wrong results, # e.g. 'Congo, Democratic Republic of the' => 'Democratic Republic of the Congo' country = '{1} {0}'.format(*country.split(',', 1)) return tools.ustr(', '.join( field for field in [street, ("%s %s" % (zip or '', city or '')).strip(), state, country] if field ))
def render_template(self, template_txt, model, res_ids, post_process=False): """ Render the given template text, replace mako expressions ``${expr}`` with the result of evaluating these expressions with an evaluation context containing: - ``user``: Model of the current user - ``object``: record of the document record this mail is related to - ``context``: the context passed to the mail composition wizard :param str template_txt: the template text to render :param str model: model name of the document record this mail is related to. :param int res_ids: list of ids of document records those mails are related to. """ multi_mode = True if isinstance(res_ids, pycompat.integer_types): multi_mode = False res_ids = [res_ids] results = dict.fromkeys(res_ids, u"") # try to load the template try: mako_env = mako_safe_template_env if self.env.context.get('safe') else mako_template_env template = mako_env.from_string(tools.ustr(template_txt)) except Exception: _logger.info("Failed to load template %r", template_txt, exc_info=True) return multi_mode and results or results[res_ids[0]] # prepare template variables records = self.env[model].browse(it for it in res_ids if it) # filter to avoid browsing [None] res_to_rec = dict.fromkeys(res_ids, None) for record in records: res_to_rec[record.id] = record variables = { 'format_date': lambda date, format=False, context=self._context: format_date(self.env, date, format), 'format_tz': lambda dt, tz=False, format=False, context=self._context: format_tz(self.env, dt, tz, format), 'format_amount': lambda amount, currency, context=self._context: format_amount(self.env, amount, currency), 'user': self.env.user, 'ctx': self._context, # context kw would clash with mako internals } for res_id, record in res_to_rec.items(): variables['object'] = record try: render_result = template.render(variables) except Exception: _logger.info("Failed to render template %r using values %r" % (template, variables), exc_info=True) raise UserError(_("Failed to render template %r using values %r")% (template, variables)) if render_result == u"False": render_result = u"" results[res_id] = render_result if post_process: for res_id, result in results.items(): results[res_id] = self.render_post_process(result) return multi_mode and results or results[res_ids[0]]
def schema_valid(arch): """ Get RNG validator and validate RNG file.""" validator = relaxng(arch.tag) if validator and not validator.validate(arch): result = True for error in validator.error_log: _logger.error(tools.ustr(error)) result = False return result return True