[FIX] mail: encoding of sender name with unicode

When sending an email, both formats 'Name <email>' or '"Name" <email>' can be used for fields 'From', 'To' and others. If the name contains unicode characters, a regex only matching '"Name" <email>' was used to encode the name with RFC2047. That meant that the name was not encoded and eventually dropped, using only the email part.
Instead of using a limited regex, use the parseaddr method from email library.
Fixes lp:1272610, opw 607683
This commit is contained in:
Martin Trigaux 2014-09-10 17:35:44 +02:00
parent 2459cd5dd1
commit f2cf6ced17
1 changed files with 9 additions and 7 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 from email.Utils import formatdate, make_msgid, COMMASPACE, parseaddr
from email import Encoders from email import Encoders
import logging import logging
import re import re
@ -118,6 +118,7 @@ def encode_header_param(param_text):
return param_text_ascii if param_text_ascii\ return param_text_ascii if param_text_ascii\
else Charset('utf8').header_encode(param_text_utf8) else Charset('utf8').header_encode(param_text_utf8)
# TODO master, remove me, no longer used internaly
name_with_email_pattern = re.compile(r'("[^<@>]+")\s*<([^ ,<@]+@[^> ,]+)>') name_with_email_pattern = re.compile(r'("[^<@>]+")\s*<([^ ,<@]+@[^> ,]+)>')
address_pattern = re.compile(r'([^ ,<@]+@[^> ,]+)') address_pattern = re.compile(r'([^ ,<@]+@[^> ,]+)')
@ -141,15 +142,16 @@ def encode_rfc2822_address_header(header_text):
header_text_ascii = try_coerce_ascii(header_text_utf8) header_text_ascii = try_coerce_ascii(header_text_utf8)
if header_text_ascii: if header_text_ascii:
return 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 # non-ASCII characters are present, attempt to
# replace all "Name" patterns with the RFC2047- # replace all "Name" patterns with the RFC2047-
# encoded version # encoded version
def replace(match_obj): name_encoded = str(Header(name, 'utf-8'))
name, email = match_obj.group(1), match_obj.group(2) header_text_utf8 = "%s <%s>" % (name_encoded, email)
name_encoded = str(Header(name, 'utf-8'))
return "%s <%s>" % (name_encoded, email)
header_text_utf8 = name_with_email_pattern.sub(replace,
header_text_utf8)
# try again after encoding # try again after encoding
header_text_ascii = try_coerce_ascii(header_text_utf8) header_text_ascii = try_coerce_ascii(header_text_utf8)
if header_text_ascii: if header_text_ascii: