[FIX] ir.mail.server: restore parsing of multiple RFC2822 addresses including non...
authorOlivier Dony <odo@openerp.com>
Fri, 10 Oct 2014 15:04:03 +0000 (17:04 +0200)
committerOlivier Dony <odo@openerp.com>
Fri, 10 Oct 2014 16:32:00 +0000 (18:32 +0200)
Rev f2cf6ced1 modified RFC2822 parsing in order to better support
unicode characters inside the Name part of an address header.
However the patch broke handling of multiple addresses (comma
separated) - silently discarding all recipients except the
first one, as soon as any non-ASCII character was present.

This patch restores the functionality while preserving the
fix from f2cf6ced1, and simplifies the code using email.utils
utility functions.

Fixes (again) lp:1272610, OPW 607683

openerp/addons/base/ir/ir_mail_server.py

index 7851d70..2624abb 100644 (file)
@@ -24,7 +24,7 @@ from email.MIMEBase import MIMEBase
 from email.MIMEMultipart import MIMEMultipart
 from email.Charset import Charset
 from email.Header import Header
-from email.Utils import formatdate, make_msgid, COMMASPACE, parseaddr
+from email.utils import formatdate, make_msgid, COMMASPACE, getaddresses, formataddr
 from email import Encoders
 import logging
 import re
@@ -138,29 +138,14 @@ def encode_rfc2822_address_header(header_text):
        ``"Name"`` portion by the RFC2047-encoded
        version, preserving the address part untouched.
     """
-    header_text_utf8 = tools.ustr(header_text).encode('utf-8')
-    header_text_ascii = try_coerce_ascii(header_text_utf8)
-    if header_text_ascii:
-        return header_text_ascii
-
-    name, email = parseaddr(header_text_utf8)
-    if not name:
-      return email
-
-    # non-ASCII characters are present, attempt to
-    # replace all "Name" patterns with the RFC2047-
-    # encoded version
-    name_encoded = str(Header(name, 'utf-8'))
-    header_text_utf8 = "%s <%s>" % (name_encoded, email)
-    # try again after encoding
-    header_text_ascii = try_coerce_ascii(header_text_utf8)
-    if header_text_ascii:
-        return header_text_ascii
-    # fallback to extracting pure addresses only, which could
-    # still cause a failure downstream if the actual addresses
-    # contain non-ASCII characters
-    return COMMASPACE.join(extract_rfc2822_addresses(header_text_utf8))
-
+    def encode_addr(addr):
+        name, email = addr
+        if not try_coerce_ascii(name):
+            name = str(Header(name, 'utf-8'))
+        return formataddr((name, email))
+
+    addresses = getaddresses([tools.ustr(header_text).encode('utf-8')])
+    return COMMASPACE.join(map(encode_addr, addresses))
  
 class ir_mail_server(osv.osv):
     """Represents an SMTP server, able to send outgoing emails, with SSL and TLS capabilities."""