From c33d61a7891887c5e267426f8dabb3baf71cbdce Mon Sep 17 00:00:00 2001 From: Albert Cervera i Areny Date: Mon, 10 Jul 2023 18:13:24 +0200 Subject: [PATCH] Add issue10650.diff to fix e-mails with special characters. --- issue10650.diff | 197 ++++++++++++++++++++++++++++++++++++++++++++++++ series | 2 + 2 files changed, 199 insertions(+) create mode 100644 issue10650.diff diff --git a/issue10650.diff b/issue10650.diff new file mode 100644 index 0000000..6e6036a --- /dev/null +++ b/issue10650.diff @@ -0,0 +1,197 @@ +diff --git a/tryton/modules/account_dunning_email/account.py b/modules/account_dunning_email/account.py +index 8513c27751c0e841f630bc6f4e511c0d8ee68ff0_bW9kdWxlcy9hY2NvdW50X2R1bm5pbmdfZW1haWwvYWNjb3VudC5weQ==..c7b9a8fd886428d866f215591c176269cab6a5c6_bW9kdWxlcy9hY2NvdW50X2R1bm5pbmdfZW1haWwvYWNjb3VudC5weQ== 100644 +--- a/tryton/modules/account_dunning_email/account.py ++++ b/tryton/modules/account_dunning_email/account.py +@@ -9,8 +9,8 @@ + from trytond.pyson import Bool, Eval + from trytond.report import get_email + from trytond.sendmail import SMTPDataManager, sendmail_transactional +-from trytond.tools.email_ import set_from_header ++from trytond.tools.email_ import convert_ascii_email, set_from_header + from trytond.transaction import Transaction + from trytond.wizard import StateTransition + + +@@ -13,7 +13,14 @@ + from trytond.transaction import Transaction + from trytond.wizard import StateTransition + + ++def _formataddr(pair): ++ name, address = pair ++ if name: ++ name = str(Header(name, 'utf-8')) ++ return formataddr((name, convert_ascii_email(address))) ++ ++ + class Configuration(metaclass=PoolMeta): + __name__ = 'account.configuration' + +@@ -117,8 +124,8 @@ + contact = self.party.contact_mechanism_get( + 'email', usage=self.level.email_contact_mechanism) + if contact and contact.email: +- name = str(Header(contact.name or self.party.rec_name)) +- to.append(formataddr((name, contact.email))) ++ name = contact.name or self.party.rec_name ++ to.append(_formataddr((name, contact.email))) + elif account_config.dunning_email_fallback: + user = account_config.get_multivalue( + 'dunning_email_fallback', company=self.company.id) +@@ -122,7 +129,7 @@ + elif account_config.dunning_email_fallback: + user = account_config.get_multivalue( + 'dunning_email_fallback', company=self.company.id) +- to.append(formataddr((self.party.rec_name, user.email))) ++ to.append(_formataddr((self.party.rec_name, user.email))) + cc = [] + bcc = [] + languages = set() +diff --git a/tryton/modules/marketing_automation/marketing_automation.py b/modules/marketing_automation/marketing_automation.py +index 8513c27751c0e841f630bc6f4e511c0d8ee68ff0_bW9kdWxlcy9tYXJrZXRpbmdfYXV0b21hdGlvbi9tYXJrZXRpbmdfYXV0b21hdGlvbi5weQ==..c7b9a8fd886428d866f215591c176269cab6a5c6_bW9kdWxlcy9tYXJrZXRpbmdfYXV0b21hdGlvbi9tYXJrZXRpbmdfYXV0b21hdGlvbi5weQ== 100644 +--- a/tryton/modules/marketing_automation/marketing_automation.py ++++ b/tryton/modules/marketing_automation/marketing_automation.py +@@ -32,7 +32,7 @@ + from trytond.report import Report + from trytond.sendmail import SMTPDataManager, sendmail_transactional + from trytond.tools import grouped_slice, reduce_ids +-from trytond.tools.email_ import set_from_header ++from trytond.tools.email_ import convert_ascii_email, set_from_header + from trytond.transaction import Transaction + from trytond.url import http_host + from trytond.wsgi import Base64Converter +@@ -55,7 +55,7 @@ + def _formataddr(name, email): + if name: + name = str(Header(name, 'utf-8')) +- return formataddr((name, email)) ++ return formataddr((name, convert_ascii_email(email))) + + + class Scenario(Workflow, ModelSQL, ModelView): +diff --git a/tryton/modules/marketing_email/marketing.py b/modules/marketing_email/marketing.py +index 8513c27751c0e841f630bc6f4e511c0d8ee68ff0_bW9kdWxlcy9tYXJrZXRpbmdfZW1haWwvbWFya2V0aW5nLnB5..c7b9a8fd886428d866f215591c176269cab6a5c6_bW9kdWxlcy9tYXJrZXRpbmdfZW1haWwvbWFya2V0aW5nLnB5 100644 +--- a/tryton/modules/marketing_email/marketing.py ++++ b/tryton/modules/marketing_email/marketing.py +@@ -31,7 +31,7 @@ + from trytond.report import Report, get_email + from trytond.sendmail import SMTPDataManager, sendmail_transactional + from trytond.tools import grouped_slice, reduce_ids +-from trytond.tools.email_ import set_from_header ++from trytond.tools.email_ import convert_ascii_email, set_from_header + from trytond.transaction import Transaction, inactive_records + from trytond.url import http_host + from trytond.wizard import Button, StateTransition, StateView, Wizard +@@ -51,7 +51,7 @@ + def _formataddr(name, email): + if name: + name = str(Header(name, 'utf-8')) +- return formataddr((name, email)) ++ return formataddr((name, convert_ascii_email(email))) + + + def _add_params(url, **params): +@@ -297,7 +297,8 @@ + set_from_header(msg, from_cfg, from_ or from_cfg) + msg['To'] = record.email + msg['Subject'] = Header(title, 'utf-8') +- sendmail_transactional(from_cfg, [record.email], msg) ++ sendmail_transactional( ++ from_cfg, [convert_ascii_email(record.email)], msg) + + def request_unsubscribe(self, email, from_=None): + pool = Pool() +@@ -322,7 +323,8 @@ + set_from_header(msg, from_cfg, from_ or from_cfg) + msg['To'] = record.email + msg['Subject'] = Header(title, 'utf-8') +- sendmail_transactional(from_cfg, [record.email], msg) ++ sendmail_transactional( ++ from_cfg, [convert_ascii_email(record.email)], msg) + + + class Message(Workflow, ModelSQL, ModelView): +diff --git a/tryton/modules/notification_email/notification.py b/modules/notification_email/notification.py +index 8513c27751c0e841f630bc6f4e511c0d8ee68ff0_bW9kdWxlcy9ub3RpZmljYXRpb25fZW1haWwvbm90aWZpY2F0aW9uLnB5..c7b9a8fd886428d866f215591c176269cab6a5c6_bW9kdWxlcy9ub3RpZmljYXRpb25fZW1haWwvbm90aWZpY2F0aW9uLnB5 100644 +--- a/tryton/modules/notification_email/notification.py ++++ b/tryton/modules/notification_email/notification.py +@@ -6,7 +6,7 @@ + from email.mime.application import MIMEApplication + from email.mime.multipart import MIMEMultipart + from email.mime.nonmultipart import MIMENonMultipart +-from email.utils import formataddr, getaddresses, parseaddr ++from email.utils import formataddr, getaddresses + + from genshi.template import TextTemplate + +@@ -17,7 +17,7 @@ + from trytond.pyson import Eval, TimeDelta + from trytond.report import get_email + from trytond.sendmail import SMTPDataManager, sendmail_transactional +-from trytond.tools.email_ import set_from_header ++from trytond.tools.email_ import convert_ascii_email, set_from_header + from trytond.transaction import Transaction + + from .exceptions import TemplateError +@@ -195,8 +195,12 @@ + msg = content + + set_from_header(msg, sender, from_) +- msg['To'] = ', '.join(formataddr(parseaddr(a)) for a in to) +- msg['Cc'] = ', '.join(formataddr(parseaddr(a)) for a in cc) ++ msg['To'] = ', '.join( ++ formataddr((n, convert_ascii_email(a))) ++ for n, a in getaddresses(to)) ++ msg['Cc'] = ', '.join( ++ formataddr((n, convert_ascii_email(a))) ++ for n, a in getaddresses(cc)) + msg['Subject'] = Header(title, 'utf-8') + msg['Auto-Submitted'] = 'auto-generated' + return msg, title +@@ -238,7 +242,8 @@ + cc, cc_languages = self._get_cc(record) + bcc, bcc_languages = self._get_bcc(record) + languages = to_languages | cc_languages | bcc_languages +- to_addrs = [e for _, e in getaddresses(to + cc + bcc)] ++ to_addrs = [ ++ convert_ascii_email(e) for _, e in getaddresses(to + cc + bcc)] + if to_addrs: + msg, title = self.get_email( + record, from_, to, cc, bcc, languages) +diff --git a/tryton/trytond/trytond/ir/email_.py b/trytond/trytond/ir/email_.py +index 8513c27751c0e841f630bc6f4e511c0d8ee68ff0_dHJ5dG9uZC90cnl0b25kL2lyL2VtYWlsXy5weQ==..c7b9a8fd886428d866f215591c176269cab6a5c6_dHJ5dG9uZC90cnl0b25kL2lyL2VtYWlsXy5weQ== 100644 +--- a/tryton/trytond/trytond/ir/email_.py ++++ b/tryton/trytond/trytond/ir/email_.py +@@ -27,7 +27,7 @@ + from trytond.rpc import RPC + from trytond.sendmail import sendmail_transactional + from trytond.tools import escape_wildcard +-from trytond.tools.email_ import set_from_header ++from trytond.tools.email_ import convert_ascii_email, set_from_header + from trytond.tools.string_ import StringMatcher + from trytond.transaction import Transaction + +@@ -56,7 +56,7 @@ + def _formataddr(pair): + "Format address without encoding" + name, address = pair +- address.encode('ascii') ++ convert_ascii_email(address).encode('ascii') + if name: + quotes = '' + if specialsre.search(name): +@@ -167,8 +167,12 @@ + 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['To'] = ', '.join( ++ formataddr((n, convert_ascii_email(a))) ++ for n, a in getaddresses([to])) ++ msg['Cc'] = ', '.join( ++ formataddr((n, convert_ascii_email(a))) ++ for n, a in getaddresses([cc])) + msg['Subject'] = Header(subject, 'utf-8') + + to_addrs = list(filter(None, map( diff --git a/series b/series index c3f2713..693d2d7 100644 --- a/series +++ b/series @@ -34,3 +34,5 @@ issue11966.diff # [sao] Overlap label links in form view issue12226.diff # [sale_credit_limit] Do not deduce negative sale quantities from credit amount issue12338.diff # [account_invoice] Show ID message "account_invoice.msg_invoice_similar" in ES language + +issue10650.diff # [account_dunning_email] [marketing_automation] [marketing_email] [notification_email] [trytond] Support RFC6530 on email formatting