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)
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)
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')
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)
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
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)