Exemplo n.º 1
0
    def send_get_mail_body(self, partner=None):
        """ Override to add the tracking URL to the body and to add
        Statistic_id in shorted urls """
        # TDE: temporary addition (mail was parameter) due to semi-new-API
        self.ensure_one()
        body = super(MailMail, self).send_get_mail_body(partner=partner)

        if self.mailing_id and body and self.statistics_ids:
            for match in re.findall(URL_REGEX, self.body_html):
                href = match[0]
                url = match[1]

                parsed = werkzeug.urls.url_parse(url, scheme='http')

                if parsed.scheme.startswith('http') and parsed.path.startswith(
                        '/r/'):
                    new_href = href.replace(
                        url, url + '/m/' + str(self.statistics_ids[0].id))
                    body = body.replace(href, new_href)

        # prepend <base> tag for images using absolute urls
        domain = self.env["ir.config_parameter"].sudo().get_param(
            "web.base.url")
        base = "<base href='%s'>" % domain
        body = tools.append_content_to_html(base,
                                            body,
                                            plaintext=False,
                                            container_tag='div')

        # resolve relative image url to absolute for outlook.com
        def _sub_relative2absolute(match):
            return match.group(1) + werkzeug.urls.url_join(
                domain, match.group(2))

        body = re.sub('(<img(?=\s)[^>]*\ssrc=")(/[^/][^"]+)',
                      _sub_relative2absolute, body)
        body = re.sub(r'(<[^>]+\bstyle="[^"]+\burl\(\'?)(/[^/\'][^\'")]+)',
                      _sub_relative2absolute, body)

        # generate tracking URL
        if self.statistics_ids:
            tracking_url = self._get_tracking_url(partner)
            if tracking_url:
                body = tools.append_content_to_html(body,
                                                    tracking_url,
                                                    plaintext=False,
                                                    container_tag='div')
        return body
Exemplo n.º 2
0
 def send_get_mail_body(self, partner=None):
     """ Short-circuit parent method for mail groups, replace the default
         footer with one appropriate for mailing-lists."""
     if self.model == 'mail.channel' and self.res_id:
         # no super() call on purpose, no private links that could be quoted!
         channel = self.env['mail.channel'].browse(self.res_id)
         base_url = self.env['ir.config_parameter'].sudo().get_param(
             'web.base.url')
         vals = {
             'maillist':
             _('Mailing-List'),
             'post_to':
             _('Post to'),
             'unsub':
             _('Unsubscribe'),
             'mailto':
             'mailto:%s@%s' % (channel.alias_name, channel.alias_domain),
             'group_url':
             '%s/groups/%s' % (base_url, slug(channel)),
             'unsub_url':
             '%s/groups?unsubscribe' % (base_url, ),
         }
         footer = """_______________________________________________
                     %(maillist)s: %(group_url)s
                     %(post_to)s: %(mailto)s
                     %(unsub)s: %(unsub_url)s
                 """ % vals
         body = tools.append_content_to_html(self.body,
                                             footer,
                                             container_tag='div')
         return body
     else:
         return super(MailMail, self).send_get_mail_body(partner=partner)
Exemplo n.º 3
0
    def _send_prepare_body(self):
        """ Override to add the tracking URL to the body and to add
        trace ID in shortened urls """
        # TDE: temporary addition (mail was parameter) due to semi-new-API
        self.ensure_one()
        body = super(MailMail, self)._send_prepare_body()

        if self.mailing_id and body and self.mailing_trace_ids:
            for match in re.findall(tools.URL_REGEX, self.body_html):
                href = match[0]
                url = match[1]

                parsed = werkzeug.urls.url_parse(url, scheme='http')

                if parsed.scheme.startswith('http') and parsed.path.startswith(
                        '/r/'):
                    new_href = href.replace(
                        url, url + '/m/' + str(self.mailing_trace_ids[0].id))
                    body = body.replace(href, new_href)

            # generate tracking URL
            tracking_url = self._get_tracking_url()
            body = tools.append_content_to_html(
                body,
                '<img src="%s"/>' % tracking_url,
                plaintext=False,
            )

        body = self.env['mail.render.mixin']._replace_local_links(body)

        return body
Exemplo n.º 4
0
 def test_append_to_html(self):
     test_samples = [
         ('<!DOCTYPE...><HTML encoding="blah">some <b>content</b></HtMl>',
          '--\nYours truly', True, True, False,
          '<!DOCTYPE...><html encoding="blah">some <b>content</b>\n<pre>--\nYours truly</pre>\n</html>'
          ),
         ('<!DOCTYPE...><HTML encoding="blah">some <b>content</b></HtMl>',
          '--\nYours truly', True, False, False,
          '<!DOCTYPE...><html encoding="blah">some <b>content</b>\n<p>--<br/>Yours truly</p>\n</html>'
          ),
         ('<html><body>some <b>content</b></body></html>',
          '--\nYours & <truly>', True, True, False,
          '<html><body>some <b>content</b>\n<pre>--\nYours &amp; &lt;truly&gt;</pre>\n</body></html>'
          ),
         ('<html><body>some <b>content</b></body></html>',
          '<!DOCTYPE...>\n<html><body>\n<p>--</p>\n<p>Yours truly</p>\n</body>\n</html>',
          False, False, False,
          '<html><body>some <b>content</b>\n\n\n<p>--</p>\n<p>Yours truly</p>\n\n\n</body></html>'
          ),
     ]
     for html, content, plaintext_flag, preserve_flag, container_tag, expected in test_samples:
         self.assertEqual(
             append_content_to_html(html, content, plaintext_flag,
                                    preserve_flag, container_tag), expected,
             'append_content_to_html is broken')
Exemplo n.º 5
0
    def onchange_template_id(self, template_id, composition_mode, model, res_id):
        """ - mass_mailing: we cannot render, so return the template values
            - normal mode: return rendered values
            /!\ for x2many field, this onchange return command instead of ids
        """
        if template_id and composition_mode == 'mass_mail':
            template = self.env['mail.template'].browse(template_id)
            fields = ['subject', 'body_html', 'email_from', 'reply_to', 'mail_server_id']
            values = dict((field, getattr(template, field)) for field in fields if getattr(template, field))
            if template.attachment_ids:
                values['attachment_ids'] = [att.id for att in template.attachment_ids]
            if template.mail_server_id:
                values['mail_server_id'] = template.mail_server_id.id
            if template.user_signature and 'body_html' in values:
                signature = self.env.user.signature
                values['body_html'] = tools.append_content_to_html(values['body_html'], signature, plaintext=False)
        elif template_id:
            values = self.generate_email_for_composer(template_id, [res_id])[res_id]
            # transform attachments into attachment_ids; not attached to the document because this will
            # be done further in the posting process, allowing to clean database if email not send
            Attachment = self.env['ir.attachment']
            for attach_fname, attach_datas in values.pop('attachments', []):
                data_attach = {
                    'name': attach_fname,
                    'datas': attach_datas,
                    'datas_fname': attach_fname,
                    'res_model': 'mail.compose.message',
                    'res_id': 0,
                    'type': 'binary',  # override default_type from context, possibly meant for another model!
                }
                values.setdefault('attachment_ids', list()).append(Attachment.create(data_attach).id)
        else:
            default_values = self.with_context(default_composition_mode=composition_mode, default_model=model, default_res_id=res_id).default_get(['composition_mode', 'model', 'res_id', 'parent_id', 'partner_ids', 'subject', 'body', 'email_from', 'reply_to', 'attachment_ids', 'mail_server_id'])
            values = dict((key, default_values[key]) for key in ['subject', 'body', 'partner_ids', 'email_from', 'reply_to', 'attachment_ids', 'mail_server_id'] if key in default_values)

        if values.get('body_html'):
            values['body'] = values.pop('body_html')

        # This onchange should return command instead of ids for x2many field.
        # ORM handle the assignation of command list on new onchange (api.v8),
        # this force the complete replacement of x2many field with
        # command and is compatible with onchange api.v7
        values = self._convert_to_write(values)

        return {'value': values}
Exemplo n.º 6
0
    def generate_email(self, res_ids, fields=None):
        """Generates an email from the template for given the given model based on
        records given by res_ids.

        :param template_id: id of the template to render.
        :param res_id: id of the record to use for rendering the template (model
                       is taken from template definition)
        :returns: a dict containing all relevant fields for creating a new
                  mail.mail entry, with one extra key ``attachments``, in the
                  format [(report_name, data)] where data is base64 encoded.
        """
        self.ensure_one()
        multi_mode = True
        if isinstance(res_ids, pycompat.integer_types):
            res_ids = [res_ids]
            multi_mode = False
        if fields is None:
            fields = [
                'subject', 'body_html', 'email_from', 'email_to', 'partner_to',
                'email_cc', 'reply_to', 'scheduled_date'
            ]

        res_ids_to_templates = self.get_email_template(res_ids)

        # templates: res_id -> template; template -> res_ids
        templates_to_res_ids = {}
        for res_id, template in res_ids_to_templates.items():
            templates_to_res_ids.setdefault(template, []).append(res_id)

        results = dict()
        for template, template_res_ids in templates_to_res_ids.items():
            Template = self.env['mail.template']
            # generate fields value for all res_ids linked to the current template
            if template.lang:
                Template = Template.with_context(
                    lang=template._context.get('lang'))
            for field in fields:
                Template = Template.with_context(safe=field in {'subject'})
                generated_field_values = Template.render_template(
                    getattr(template, field),
                    template.model,
                    template_res_ids,
                    post_process=(field == 'body_html'))
                for res_id, field_value in generated_field_values.items():
                    results.setdefault(res_id, dict())[field] = field_value
            # compute recipients
            if any(field in fields
                   for field in ['email_to', 'partner_to', 'email_cc']):
                results = template.generate_recipients(results,
                                                       template_res_ids)
            # update values for all res_ids
            for res_id in template_res_ids:
                values = results[res_id]
                # body: add user signature, sanitize
                if 'body_html' in fields and template.user_signature:
                    signature = self.env.user.signature
                    if signature:
                        values['body_html'] = tools.append_content_to_html(
                            values['body_html'], signature, plaintext=False)
                if values.get('body_html'):
                    values['body'] = tools.html_sanitize(values['body_html'])
                # technical settings
                values.update(
                    mail_server_id=template.mail_server_id.id or False,
                    auto_delete=template.auto_delete,
                    keep_days=template.keep_days,
                    model=template.model,
                    res_id=res_id or False,
                    attachment_ids=[
                        attach.id for attach in template.attachment_ids
                    ],
                )

            # Add report in attachments: generate once for all template_res_ids
            if template.report_template:
                for res_id in template_res_ids:
                    attachments = []
                    report_name = self.render_template(template.report_name,
                                                       template.model, res_id)
                    report = template.report_template
                    report_service = report.report_name

                    if report.report_type not in ['qweb-html', 'qweb-pdf']:
                        raise UserError(
                            _('Unsupported report type %s found.') %
                            report.report_type)
                    result, format = report.render_qweb_pdf([res_id])

                    # TODO in trunk, change return format to binary to match message_post expected format
                    result = base64.b64encode(result)
                    if not report_name:
                        report_name = 'report.' + report_service
                    ext = "." + format
                    if not report_name.endswith(ext):
                        report_name += ext
                    attachments.append((report_name, result))
                    results[res_id]['attachments'] = attachments

        return multi_mode and results or results[res_ids[0]]