4 from types import StringTypes
5 from email.MIMEText import MIMEText
6 from email.Header import Header
7 from smtplib import SMTP
10 def sendmail(To, Subject, Body, From = None, Cc = None, Bcc = None):
12 Uses sendmail (must be installed and running locally) to send a
13 message to the specified recipients. If the API is running under
14 mod_python, the apache user must be listed in e.g.,
15 /etc/mail/trusted-users.
17 To, Cc, and Bcc may be addresses or lists of addresses. Each
18 address may be either a plain text address or a tuple of (name,
23 if not isinstance(To, list):
25 if Cc is not None and not isinstance(Cc, list):
27 if Bcc is not None and not isinstance(Bcc, list):
30 From = ("Quality Assurance <qa@planet-lab.org>")
32 # Create a MIME-encoded UTF-8 message
33 msg = MIMEText(Body.encode("utf-8"), _charset = "utf-8")
35 # Unicode subject headers are automatically encoded correctly
36 msg['Subject'] = Subject
38 def encode_addresses(addresses, header_name = None):
40 Unicode address headers are automatically encoded by
41 email.Header, but not correctly. The correct way is to put the
42 textual name inside quotes and the address inside brackets:
44 To: "=?utf-8?b?encoded" <recipient@domain>
46 Each address in addrs may be a tuple of (name, address) or
47 just an address. Returns a tuple of (header, addrlist)
48 representing the encoded header text and the list of plain
55 for addr in addresses:
56 if isinstance(addr, tuple):
59 name = name.encode('ascii')
60 header.append('%s <%s>' % (name, addr))
62 h = Header(name, charset = "utf-8", header_name = header_name)
63 header.append('"%s" <%s>' % (h.encode(), addr))
68 return (", ".join(header), addrs)
70 (msg['From'], from_addrs) = encode_addresses([From], 'From')
71 (msg['To'], to_addrs) = encode_addresses(To, 'To')
74 (msg['Cc'], cc_addrs) = encode_addresses(Cc, 'Cc')
78 (unused, bcc_addrs) = encode_addresses(Bcc, 'Bcc')
81 # Needed to pass some spam filters
82 msg['Reply-To'] = msg['From']
83 msg['X-Mailer'] = "Python/" + sys.version.split(" ")[0]
87 rejected = s.sendmail(from_addrs[0], to_addrs, msg.as_string(), rcpt_options = ["NOTIFY=NEVER"])
91 raise Exception, "Error sending message to " + ", ".join(rejected.keys())