2 sendmail.py - Send email messages
8 from email.mime.text import MIMEText
9 from email.header import Header
10 from smtplib import SMTP
12 from PLC.Logger import logger
13 from PLC.Faults import PLCAPIError
14 # from PLC.Faults import *
17 def sendmail(api, To, Subject, Body, From=None, Cc=None, Bcc=None):
19 Uses sendmail (must be installed and running locally) to send a
20 message to the specified recipients. If the API is running under
21 mod_python, the apache user must be listed in e.g.,
22 /etc/mail/trusted-users.
24 To, Cc, and Bcc may be addresses or lists of addresses. Each
25 address may be either a plain text address or a tuple of (name,
30 if not isinstance(To, list):
32 if Cc is not None and not isinstance(Cc, list):
34 if Bcc is not None and not isinstance(Bcc, list):
37 From = ("%s Support" % api.config.PLC_NAME,
38 api.config.PLC_MAIL_SUPPORT_ADDRESS)
40 # Create a MIME-encoded UTF-8 message
43 # Unicode subject headers are automatically encoded correctly
44 msg['Subject'] = Subject
46 def encode_addresses(addresses, header_name=None):
48 Unicode address headers are automatically encoded by
49 email.Header, but not correctly. The correct way is to put the
50 textual name inside quotes and the address inside brackets:
52 To: "=?utf-8?b?encoded" <recipient@domain>
54 Each address in addrs may be a tuple of (name, address) or
55 just an address. Returns a tuple of (header, addrlist)
56 representing the encoded header text and the list of plain
63 for addr in addresses:
64 if isinstance(addr, tuple):
66 h = Header(name, charset=api.encoding, header_name=header_name)
67 header.append('"%s" <%s>' % (h, addr))
72 return (", ".join(header), addrs)
74 (msg['From'], from_addrs) = encode_addresses([From], 'From')
75 (msg['To'], to_addrs) = encode_addresses(To, 'To')
78 (msg['Cc'], cc_addrs) = encode_addresses(Cc, 'Cc')
82 (_, bcc_addrs) = encode_addresses(Bcc, 'Bcc')
85 # Needed to pass some spam filters
86 msg['Reply-To'] = msg['From']
87 msg['X-Mailer'] = "Python/" + sys.version.split(" ")[0]
89 if not api.config.PLC_MAIL_ENABLED:
90 logger.info("PLC_MAIL_ENABLED not set")
91 logger.info("From: %(From)s, To: %(To)s, Subject: %(Subject)s" % msg)
97 rejected = s.sendmail(
98 from_addrs[0], to_addrs,
99 msg.as_string(), rcpt_options=["NOTIFY=NEVER"])
102 raise PLCAPIError("Error sending message to "
103 + ", ".join(list(rejected.keys())))