[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.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."""