[FIX] ir.mail.server: restore parsing of multiple RFC2822 addresses including non-ASCII chars

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
This commit is contained in:
Olivier Dony 2014-10-10 17:04:03 +02:00
parent d38adf3d92
commit 1b49a87619
1 changed files with 8 additions and 23 deletions

View File

@ -24,7 +24,7 @@ from email.MIMEBase import MIMEBase
from email.MIMEMultipart import MIMEMultipart from email.MIMEMultipart import MIMEMultipart
from email.Charset import Charset from email.Charset import Charset
from email.Header import Header 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 from email import Encoders
import logging import logging
import re import re
@ -138,29 +138,14 @@ def encode_rfc2822_address_header(header_text):
``"Name"`` portion by the RFC2047-encoded ``"Name"`` portion by the RFC2047-encoded
version, preserving the address part untouched. version, preserving the address part untouched.
""" """
header_text_utf8 = tools.ustr(header_text).encode('utf-8') def encode_addr(addr):
header_text_ascii = try_coerce_ascii(header_text_utf8) name, email = addr
if header_text_ascii: if not try_coerce_ascii(name):
return header_text_ascii name = str(Header(name, 'utf-8'))
return formataddr((name, email))
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))
addresses = getaddresses([tools.ustr(header_text).encode('utf-8')])
return COMMASPACE.join(map(encode_addr, addresses))
class ir_mail_server(osv.osv): class ir_mail_server(osv.osv):
"""Represents an SMTP server, able to send outgoing emails, with SSL and TLS capabilities.""" """Represents an SMTP server, able to send outgoing emails, with SSL and TLS capabilities."""