[IMP] email_template: relocate url rewritign stuff directly into the rendering method.

bzr revid: tde@openerp.com-20140303104044-hgmii31ga6msf72z
This commit is contained in:
Thibault Delavallée 2014-03-03 11:40:44 +01:00
parent a9a4767d17
commit 05fdc2290a
4 changed files with 54 additions and 88 deletions

View File

@ -24,6 +24,8 @@ import base64
import datetime
import dateutil.relativedelta as relativedelta
import logging
import lxml
import urlparse
import openerp
from openerp import SUPERUSER_ID
@ -70,6 +72,7 @@ try:
except ImportError:
_logger.warning("jinja2 not available, templating features will not work!")
class email_template(osv.osv):
"Templates for sending email"
_name = "email.template"
@ -82,7 +85,48 @@ class email_template(osv.osv):
res['model_id'] = self.pool['ir.model'].search(cr, uid, [('model', '=', res.pop('model'))], context=context)[0]
return res
def render_template_batch(self, cr, uid, template, model, res_ids, context=None):
def _replace_local_links(self, cr, uid, html, context=None):
""" Post-processing of html content to replace local links to absolute
links, using web.base.url as base url. """
if not html:
return html
# form a tree
root = lxml.html.fromstring(html)
if not len(root) and root.text is None and root.tail is None:
html = '<div>%s</div>' % html
root = lxml.html.fromstring(html)
base_url = self.pool['ir.config_parameter'].get_param(cr, uid, 'web.base.url')
(base_scheme, base_netloc, bpath, bparams, bquery, bfragment) = urlparse.urlparse(base_url)
def _process_link(url):
new_url = url
(scheme, netloc, path, params, query, fragment) = urlparse.urlparse(url)
if not scheme and not netloc:
new_url = urlparse.urlunparse((base_scheme, base_netloc, path, params, query, fragment))
return new_url
# check all nodes, replace :
# - img src -> check URL
# - a href -> check URL
for node in root.iter():
if node.tag == 'a':
node.set('href', _process_link(node.get('href')))
elif node.tag == 'img' and not node.get('src', 'data').startswith('data'):
node.set('src', _process_link(node.get('src')))
html = lxml.html.tostring(root, pretty_print=False, method='html')
# this is ugly, but lxml/etree tostring want to put everything in a 'div' that breaks the editor -> remove that
if html.startswith('<div>') and html.endswith('</div>'):
html = html[5:-6]
return html
def render_post_process(self, cr, uid, html, context=None):
html = self._replace_local_links(cr, uid, html, context=context)
return html
def render_template_batch(self, cr, uid, template, model, res_ids, context=None, post_processing=None):
"""Render the given template text, replace mako expressions ``${expr}``
with the result of evaluating these expressions with
an evaluation context containing:
@ -125,6 +169,10 @@ class email_template(osv.osv):
if render_result == u"False":
render_result = u""
results[res_id] = render_result
if post_processing:
for res_id, result in results.iteritems():
results[res_id] = self.render_post_process(cr, uid, result, context=context)
return results
def get_email_template_batch(self, cr, uid, template_id=False, res_ids=None, context=None):
@ -357,7 +405,10 @@ class email_template(osv.osv):
for template, template_res_ids in templates_to_res_ids.iteritems():
# generate fields value for all res_ids linked to the current template
for field in fields:
generated_field_values = self.render_template_batch(cr, uid, getattr(template, field), template.model, template_res_ids, context=context)
generated_field_values = self.render_template_batch(
cr, uid, getattr(template, field), template.model, template_res_ids,
post_processing=(field == 'body_html'),
context=context)
for res_id, field_value in generated_field_values.iteritems():
results.setdefault(res_id, dict())[field] = field_value
# update values for all res_ids

View File

@ -1,4 +1,3 @@
import mail_message
import mail_thread
import email_template
import mail_compose_message
import email_template

View File

@ -19,9 +19,6 @@
#
##############################################################################
import lxml
import urlparse
from openerp.osv import osv, fields
from openerp.tools.translate import _
@ -39,50 +36,3 @@ class EmailTemplate(osv.Model):
help='Link to the website',
),
}
def _postprocess_html_replace_links(self, cr, uid, body_html, context=None):
""" Post-processing of body_html. Indeed the content generated by the
website builder contains references to local addresses, for example
for images. This method changes those addresses to absolute addresses. """
html = body_html
if not body_html:
return html
# form a tree
root = lxml.html.fromstring(html)
if not len(root) and root.text is None and root.tail is None:
html = '<div>%s</div>' % html
root = lxml.html.fromstring(html)
base_url = self.pool['ir.config_parameter'].get_param(cr, uid, 'web.base.url')
(base_scheme, base_netloc, bpath, bparams, bquery, bfragment) = urlparse.urlparse(base_url)
def _process_link(url):
new_url = url
(scheme, netloc, path, params, query, fragment) = urlparse.urlparse(url)
if not scheme and not netloc:
new_url = urlparse.urlunparse((base_scheme, base_netloc, path, params, query, fragment))
return new_url
# check all nodes, replace :
# - img src -> check URL
# - a href -> check URL
for node in root.iter():
if node.tag == 'a':
node.set('href', _process_link(node.get('href')))
elif node.tag == 'img' and not node.get('src', 'data').startswith('data'):
node.set('src', _process_link(node.get('src')))
html = lxml.html.tostring(root, pretty_print=False, method='html')
# this is ugly, but lxml/etree tostring want to put everything in a 'div' that breaks the editor -> remove that
if html.startswith('<div>') and html.endswith('</div>'):
html = html[5:-6]
return html
def generate_email_batch(self, cr, uid, template_id, res_ids, context=None, fields=None):
""" Add a post processing after rendering, aka replace local URLs to absolute URLs. """
results = super(EmailTemplate, self).generate_email_batch(cr, uid, template_id, res_ids, context=context, fields=fields)
for res_id, value in results.iteritems():
if 'body_html' in value:
results[res_id]['body_html'] = self._postprocess_html_replace_links(cr, uid, value['body_html'], context=context)
return results

View File

@ -1,34 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2014-Today OpenERP SA (<http://www.openerp.com>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp.osv import osv
class MailComposeMessage(osv.Model):
_inherit = 'mail.compose.message'
def generate_email_for_composer_batch(self, cr, uid, template_id, res_ids, context=None, fields=None):
""" Add a post processing after rendering, aka replace local URLs to absolute URLs. """
results = super(MailComposeMessage, self).generate_email_for_composer_batch(cr, uid, template_id, res_ids, context=context, fields=fields)
for res_id, value in results.iteritems():
if 'body' in value:
results[res_id]['body'] = self.pool['email.template']._postprocess_html_replace_links(cr, uid, value['body'], context=context)
return results