Skip to content

Commit 9528943

Browse files
author
Richard Jones
committed
Attempt to generate more human-readable addresses in email
1 parent 715b160 commit 9528943

File tree

4 files changed

+48
-9
lines changed

4 files changed

+48
-9
lines changed

CHANGES.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ Fixes:
2525
- Display 'today' in the account user's timezone, thanks David Wolever
2626
- Fix file handle leak in some web interfaces with logging turned on,
2727
fixes issue1675845
28+
- Attempt to generate more human-readable addresses in email, fixes
29+
issue2550632
2830

2931

3032
2009-12-21 1.4.11 (r4413)

roundup/mailer.py

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from roundup import __version__
1010
from roundup.date import get_timezone
1111

12-
from email.Utils import formatdate, formataddr
12+
from email.Utils import formatdate, formataddr, specialsre, escapesre
1313
from email.Message import Message
1414
from email.Header import Header
1515
from email.MIMEText import MIMEText
@@ -25,6 +25,21 @@ def encode_quopri(msg):
2525
del msg['Content-Transfer-Encoding']
2626
msg['Content-Transfer-Encoding'] = 'quoted-printable'
2727

28+
def nice_sender_header(name, address, charset):
29+
# construct an address header so it's as human-readable as possible
30+
# even in the presence of a non-ASCII name part
31+
h = Header(charset=charset)
32+
# the important bits of formataddr()
33+
if specialsre.search(name):
34+
name = '"%s"'%escapesre.sub(r'\\\g<0>', name)
35+
try:
36+
name.encode('ASCII')
37+
h.append(name, 'ASCII')
38+
except UnicodeEncodeError:
39+
h.append(name)
40+
h.append('<%s>'%address, 'ASCII')
41+
return str(h)
42+
2843
class Mailer:
2944
"""Roundup-specific mail sending."""
3045
def __init__(self, config):
@@ -65,11 +80,7 @@ def get_standard_message(self, to, subject, author=None, multipart=False):
6580
name = author[0]
6681
else:
6782
name = unicode(author[0], 'utf-8')
68-
try:
69-
name = name.encode('ascii')
70-
except UnicodeError:
71-
name = Header(name, charset).encode()
72-
author = formataddr((name, author[1]))
83+
author = nice_sender_header(name, author[1], charset)
7384

7485
if multipart:
7586
message = MIMEMultipart()

roundup/roundupdb.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@
3535
from roundup.i18n import _
3636

3737
# MessageSendError is imported for backwards compatibility
38-
from roundup.mailer import Mailer, MessageSendError, encode_quopri
38+
from roundup.mailer import Mailer, MessageSendError, encode_quopri, \
39+
nice_sender_header
3940

4041
class Database:
4142

@@ -406,9 +407,10 @@ def send_message(self, nodeid, msgid, note, sendto, from_address=None,
406407
else:
407408
sendto = [sendto]
408409

410+
# tracker sender info
409411
tracker_name = unicode(self.db.config.TRACKER_NAME, 'utf-8')
410-
tracker_name = formataddr((tracker_name, from_address))
411-
tracker_name = Header(tracker_name, charset)
412+
tracker_name = nice_sender_header(tracker_name, from_address,
413+
charset)
412414

413415
# now send one or more messages
414416
# TODO: I believe we have to create a new message each time as we

test/test_mailer.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#-*- encoding: utf8 -*-
2+
import unittest
3+
4+
from roundup import mailer
5+
6+
class EncodingTestCase(unittest.TestCase):
7+
def test(self):
8+
a = lambda n, a, c, o: self.assertEquals(mailer.nice_sender_header(n,
9+
a, c), o)
10+
a('ascii', '[email protected]', 'latin1', 'ascii <[email protected]>')
11+
a(u'café', '[email protected]', 'latin1',
12+
'=?latin1?q?caf=E9?= <[email protected]>')
13+
a('as"ii', '[email protected]', 'latin1', '"as\\"ii" <[email protected]>')
14+
15+
def test_suite():
16+
suite = unittest.TestSuite()
17+
suite.addTest(unittest.makeSuite(EncodingTestCase))
18+
return suite
19+
20+
if __name__ == '__main__':
21+
runner = unittest.TextTestRunner()
22+
unittest.main(testRunner=runner)
23+
24+
# vim: set et sts=4 sw=4 :

0 commit comments

Comments
 (0)