Пример #1
0
    def test_SMTPDataManager(self, get_smtp_server):
        'Test SMTPDataManager'
        transaction = Transaction()
        get_smtp_server.return_value = server = Mock()

        datamanager = transaction.join(SMTPDataManager())

        # multiple join must return the same
        self.assertEqual(transaction.join(SMTPDataManager()), datamanager)

        msg1 = MagicMock(Message)
        msg2 = MagicMock(Message)
        datamanager.put('*****@*****.**', '*****@*****.**', msg1)
        datamanager.put('*****@*****.**', '*****@*****.**', msg2)

        transaction.commit()

        server.sendmail.assert_has_calls([
            call('*****@*****.**', '*****@*****.**', msg1.as_string()),
            call('*****@*****.**', '*****@*****.**', msg2.as_string()),
        ])
        server.quit.assert_called_once_with()
        self.assertFalse(datamanager.queue)

        server.reset_mock()

        datamanager.put('*****@*****.**', '*****@*****.**',
                        MagicMock(Message))
        transaction.rollback()

        server.sendmail.assert_not_called()
        self.assertFalse(datamanager.queue)
Пример #2
0
    def send_email(self, records, trigger):
        pool = Pool()
        Log = pool.get('notification.email.log')
        datamanager = SMTPDataManager()
        Transaction().join(datamanager)
        from_ = self.from_ or config.get('email', 'from')
        logs = []
        for record in records:
            languagues = set()
            to = []
            if self.recipients:
                recipients = getattr(record, self.recipients.name, None)
                if recipients:
                    languagues.update(self._get_languages(recipients))
                    to = self._get_addresses(recipients)
            if not to and self.fallback_recipients:
                languagues.update(self._get_languages(
                    self.fallback_recipients))
                to = self._get_addresses(self.fallback_recipients)

            cc = []
            if self.recipients_secondary:
                recipients_secondary = getattr(record,
                                               self.recipients_secondary.name,
                                               None)
                if recipients_secondary:
                    languagues.update(
                        self._get_languages(recipients_secondary))
                    cc = self._get_addresses(recipients_secondary)
            if not cc and self.fallback_recipients_secondary:
                languagues.update(
                    self._get_languages(self.fallback_recipients_secondary))
                cc = self._get_addresses(self.fallback_recipients_secondary)

            bcc = []
            if self.recipients_hidden:
                recipients_hidden = getattr(record,
                                            self.recipients_hidden.name, None)
                if recipients_hidden:
                    languagues.update(self._get_languages(recipients_hidden))
                    bcc = self._get_addresses(recipients_hidden)
            if not bcc and self.fallback_recipients_hidden:
                languagues.update(
                    self._get_languages(self.fallback_recipients_hidden))
                bcc = self._get_addresses(self.fallback_recipients_hidden)

            msg = self.get_email(record, from_, to, cc, bcc, languagues)
            to_addrs = [e for _, e in getaddresses(to + cc + bcc)]
            if to_addrs:
                sendmail_transactional(from_,
                                       to_addrs,
                                       msg,
                                       datamanager=datamanager)
                logs.append(
                    self.get_log(record, trigger, msg, bcc=', '.join(bcc)))
        if logs:
            Log.create(logs)
Пример #3
0
 def transition_send_email(self):
     pool = Pool()
     Dunning = pool.get('account.dunning')
     Log = pool.get('account.dunning.email.log')
     datamanager = SMTPDataManager()
     if not pool.test:
         Transaction().join(datamanager)
     dunnings = Dunning.browse(Transaction().context['active_ids'])
     logs = []
     for dunning in dunnings:
         if dunning.level.send_email:
             log = dunning.send_email(datamanager=datamanager)
             if log:
                 logs.append(log)
     if logs:
         Log.create(logs)
     return self.next_state('send_email')
Пример #4
0
 def send_email(self, records, trigger):
     pool = Pool()
     Log = pool.get('notification.email.log')
     datamanager = SMTPDataManager()
     Transaction().join(datamanager)
     from_ = (config.get('notification_email', 'from')
              or config.get('email', 'from'))
     logs = []
     for record in records:
         to, to_languages = self._get_to(record)
         cc, cc_languages = self._get_cc(record)
         bcc, bcc_languages = self._get_bcc(record)
         languagues = to_languages | cc_languages | bcc_languages
         to_addrs = [e for _, e in getaddresses(to + cc + bcc)]
         if to_addrs:
             msg = self.get_email(record, from_, to, cc, bcc, languagues)
             sendmail_transactional(from_,
                                    to_addrs,
                                    msg,
                                    datamanager=datamanager)
             logs.append(
                 self.get_log(record, trigger, msg, bcc=', '.join(bcc)))
     if logs:
         Log.create(logs)
Пример #5
0
    def send(cls,
             to='',
             cc='',
             bcc='',
             subject='',
             body='',
             files=None,
             record=None,
             reports=None,
             attachments=None):
        pool = Pool()
        User = pool.get('res.user')
        ActionReport = pool.get('ir.action.report')
        Attachment = pool.get('ir.attachment')
        transaction = Transaction()
        user = User(transaction.user)

        Model = pool.get(record[0])
        record = Model(record[1])

        body_html = HTML_EMAIL % {
            'subject': subject,
            'body': body,
            'signature': user.signature or '',
        }
        content = MIMEMultipart('alternative')
        if html2text:
            body_text = HTML_EMAIL % {
                'subject': subject,
                'body': body,
                'signature': '',
            }
            converter = html2text.HTML2Text()
            body_text = converter.handle(body_text)
            if user.signature:
                body_text += '\n-- \n' + converter.handle(user.signature)
            part = MIMEText(body_text, 'plain', _charset='utf-8')
            content.attach(part)
        part = MIMEText(body_html, 'html', _charset='utf-8')
        content.attach(part)
        if files or reports or attachments:
            msg = MIMEMultipart('mixed')
            msg.attach(content)
            if files is None:
                files = []
            else:
                files = list(files)

            for report_id in (reports or []):
                report = ActionReport(report_id)
                Report = pool.get(report.report_name, type='report')
                ext, content, _, title = Report.execute([record.id], {
                    'action_id': report.id,
                })
                name = '%s.%s' % (title, ext)
                if isinstance(content, str):
                    content = content.encode('utf-8')
                files.append((name, content))
            if attachments:
                files += [(a.name, a.data)
                          for a in Attachment.browse(attachments)]
            for name, data in files:
                mimetype, _ = mimetypes.guess_type(name)
                if mimetype:
                    attachment = MIMENonMultipart(*mimetype.split('/'))
                    attachment.set_payload(data)
                    encode_base64(attachment)
                else:
                    attachment = MIMEApplication(data)
                attachment.add_header('Content-Disposition',
                                      'attachment',
                                      filename=('utf-8', '', name))
                msg.attach(attachment)
        else:
            msg = content
        from_ = config.get('email', 'from')
        set_from_header(msg, from_, user.email or from_)
        msg['To'] = ', '.join(formataddr(a) for a in getaddresses([to]))
        msg['Cc'] = ', '.join(formataddr(a) for a in getaddresses([cc]))
        msg['Subject'] = Header(subject, 'utf-8')

        to_addrs = list(
            filter(
                None,
                map(str.strip,
                    _get_emails(to) + _get_emails(cc) + _get_emails(bcc))))
        sendmail_transactional(from_,
                               to_addrs,
                               msg,
                               datamanager=SMTPDataManager(strict=True))

        email = cls(recipients=to,
                    recipients_secondary=cc,
                    recipients_hidden=bcc,
                    addresses=[{
                        'address': a
                    } for a in to_addrs],
                    subject=subject,
                    body=body,
                    resource=record)
        email.save()
        with Transaction().set_context(_check_access=False):
            attachments_ = []
            for name, data in files:
                attachments_.append(
                    Attachment(resource=email, name=name, data=data))
            Attachment.save(attachments_)
        return email
Пример #6
0
    def process(cls, messages=None, emails=None, smtpd_datamanager=None):
        pool = Pool()
        WebShortener = pool.get('web.shortened_url')
        spy_pixel = config.getboolean('marketing',
                                      'email_spy_pixel',
                                      default=False)

        @lru_cache(None)
        def short(url, record):
            url = WebShortener(record=record, redirect_url=url)
            url.save()
            return url.shortened_url

        def convert_href(message):
            def filter_(stream):
                for kind, data, pos in stream:
                    if kind is START:
                        tag, attrs = data
                        if tag == 'a':
                            href = attrs.get('href')
                            attrs -= 'href'
                            href = short(href, str(message))
                            attrs |= [(QName('href'), href)]
                            data = tag, attrs
                    elif kind is END and data == 'body' and spy_pixel:
                        yield START, (QName('img'),
                                      Attrs([
                                          (QName('src'),
                                           short(URL_OPEN, str(message))),
                                          (QName('height'), '1'),
                                          (QName('width'), '1'),
                                      ])), pos
                        yield END, QName('img'), pos
                    yield kind, data, pos

            return filter_

        if not smtpd_datamanager:
            smtpd_datamanager = SMTPDataManager()
        if messages is None:
            messages = cls.search([
                ('state', '=', 'sending'),
            ])

        for message in messages:
            template = MarkupTemplate(message.content)
            for email in (emails or message.list_.emails):
                content = (template.generate(email=email).filter(
                    convert_href(message)).render())

                name = email.party.rec_name if email.party else ''
                from_cfg = (config.get('marketing', 'email_from')
                            or config.get('email', 'from'))
                to = _formataddr(name, email.email)

                msg = MIMEMultipart('alternative')
                set_from_header(msg, from_cfg, message.from_ or from_cfg)
                msg['To'] = to
                msg['Subject'] = Header(message.title, 'utf-8')
                if html2text:
                    converter = html2text.HTML2Text()
                    part = MIMEText(converter.handle(content),
                                    'plain',
                                    _charset='utf-8')
                    msg.attach(part)
                part = MIMEText(content, 'html', _charset='utf-8')
                msg.attach(part)

                sendmail_transactional(from_cfg,
                                       getaddresses([to]),
                                       msg,
                                       datamanager=smtpd_datamanager)
        if not emails:
            cls.sent(messages)