|
1 """Common utilies to format / semd emails. |
|
2 |
|
3 :organization: Logilab |
|
4 :copyright: 2001-2008 LOGILAB S.A. (Paris, FRANCE), all rights reserved. |
|
5 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr |
|
6 """ |
|
7 __docformat__ = "restructuredtext en" |
|
8 |
|
9 from email.MIMEMultipart import MIMEMultipart |
|
10 from email.MIMEText import MIMEText |
|
11 from email.MIMEImage import MIMEImage |
|
12 from email.Header import Header |
|
13 |
|
14 |
|
15 def header(ustring): |
|
16 return Header(ustring.encode('UTF-8'), 'UTF-8') |
|
17 |
|
18 def addrheader(uaddr, uname=None): |
|
19 # even if an email address should be ascii, encode it using utf8 since |
|
20 # application tests may generate non ascii email address |
|
21 addr = uaddr.encode('UTF-8') |
|
22 if uname: |
|
23 return '%s <%s>' % (header(uname).encode(), addr) |
|
24 return addr |
|
25 |
|
26 |
|
27 def format_mail(uinfo, to_addrs, content, subject="", |
|
28 cc_addrs=(), msgid=None, references=(), config=None): |
|
29 """Sends an Email to 'e_addr' with content 'content', and subject 'subject' |
|
30 |
|
31 to_addrs and cc_addrs are expected to be a list of email address without |
|
32 name |
|
33 """ |
|
34 assert type(content) is unicode, repr(content) |
|
35 msg = MIMEText(content.encode('UTF-8'), 'plain', 'UTF-8') |
|
36 # safety: keep only the first newline |
|
37 subject = subject.splitlines()[0] |
|
38 msg['Subject'] = header(subject) |
|
39 if uinfo.get('email'): |
|
40 email = uinfo['email'] |
|
41 elif config and config['sender-addr']: |
|
42 email = unicode(config['sender-addr']) |
|
43 else: |
|
44 email = u'' |
|
45 if uinfo.get('name'): |
|
46 name = uinfo['name'] |
|
47 elif config and config['sender-addr']: |
|
48 name = unicode(config['sender-name']) |
|
49 else: |
|
50 name = u'' |
|
51 msg['From'] = addrheader(email, name) |
|
52 if config and config['sender-addr'] and config['sender-addr'] != email: |
|
53 appaddr = addrheader(config['sender-addr'], config['sender-name']) |
|
54 msg['Reply-to'] = '%s, %s' % (msg['From'], appaddr) |
|
55 elif email: |
|
56 msg['Reply-to'] = msg['From'] |
|
57 if config is not None: |
|
58 msg['X-CW'] = config.appid |
|
59 msg['To'] = ', '.join(addrheader(addr) for addr in to_addrs if addr is not None) |
|
60 if cc_addrs: |
|
61 msg['Cc'] = ', '.join(addrheader(addr) for addr in cc_addrs if addr is not None) |
|
62 if msgid: |
|
63 msg['Message-id'] = msgid |
|
64 if references: |
|
65 msg['References'] = ', '.join(references) |
|
66 return msg |
|
67 |
|
68 |
|
69 class HtmlEmail(MIMEMultipart): |
|
70 |
|
71 def __init__(self, subject, textcontent, htmlcontent, |
|
72 sendermail=None, sendername=None, recipients=None, ccrecipients=None): |
|
73 MIMEMultipart.__init__(self, 'related') |
|
74 self['Subject'] = header(subject) |
|
75 self.preamble = 'This is a multi-part message in MIME format.' |
|
76 # Attach alternative text message |
|
77 alternative = MIMEMultipart('alternative') |
|
78 self.attach(alternative) |
|
79 msgtext = MIMEText(textcontent.encode('UTF-8'), 'plain', 'UTF-8') |
|
80 alternative.attach(msgtext) |
|
81 # Attach html message |
|
82 msghtml = MIMEText(htmlcontent.encode('UTF-8'), 'html', 'UTF-8') |
|
83 alternative.attach(msghtml) |
|
84 if sendermail or sendername: |
|
85 self['From'] = addrheader(sendermail, sendername) |
|
86 if recipients: |
|
87 self['To'] = ', '.join(addrheader(addr) for addr in recipients if addr is not None) |
|
88 if ccrecipients: |
|
89 self['Cc'] = ', '.join(addrheader(addr) for addr in ccrecipients if addr is not None) |
|
90 |
|
91 def attach_image(self, data, htmlId): |
|
92 image = MIMEImage(data) |
|
93 image.add_header('Content-ID', '<%s>' % htmlId) |
|
94 self.attach(image) |