1
2
3
4 """NPSGD e-mail related module for blocking/non-blocking sends."""
5 import smtplib
6 import Queue
7 from email.mime.audio import MIMEAudio
8 from email.mime.base import MIMEBase
9 from email.mime.image import MIMEImage
10 from email.mime.multipart import MIMEMultipart
11 from email.mime.text import MIMEText
12 from email.Utils import formatdate
13 from email import Encoders
14 from threading import Thread
15 import mimetypes
16 import logging
17 import socket
18 from config import config
19
21
23 """Attempt to send an e-mail synchronously, reporting an error if we fail."""
24 try:
25 s = smtpServer()
26 except socket.gaierror, e:
27 raise EmailSendError("Unable to connect to smtp server")
28
29
30 try:
31 logging.info("Connected to SMTP server, sending email")
32 email.sendThrough(s)
33 finally:
34 s.close()
35
36 email_manager_thread = None
50
52 smtpserver = smtplib.SMTP(config.smtpServer, config.smtpPort)
53 smtpserver.ehlo()
54 if config.smtpUseTLS:
55 smtpserver.starttls()
56 if config.smtpUseAuth:
57 smtpserver.ehlo()
58 smtpserver.login(config.smtpUsername, config.smtpPassword)
59
60 return smtpserver
61
63 """Thread for sending e-mail in the background (using a queue of e-mails)."""
64
66 Thread.__init__(self)
67 self.daemon = True
68 self.queue = Queue.Queue()
69
72
74 """Blocks on the queue until it has an e-mail in it, then send it."""
75 while True:
76 try:
77 email = self.queue.get(True)
78 logging.info("Email Manager: Found email in the queue, attempting to send")
79 blockingEmailSend(email)
80 except Exception:
81 logging.exception("Unhandled exception in email thread!")
82 self.queue.put(email)
83
85 """Actual e-mail object containing all information needed to send an e-mail.
86
87 The e-mail object includes the recipient, subject, body, attachments and
88 also contains a method to send through a given smtp server."""
89
90 - def __init__(self, recipient, subject, body, binaryAttachments=[], textAttachments=[]):
91 self.recipient = recipient
92 self.subject = subject
93 self.body = body
94 self.binaryAttachments = binaryAttachments
95 self.textAttachments = textAttachments
96
98 """Sends this e-mail through a given smtp server (blocking)."""
99 msg = MIMEMultipart()
100
101 msg['To'] = self.recipient
102 if len(config.cc) > 0:
103 msg['Cc'] = ",".join(config.cc)
104 msg['From'] = config.fromAddress
105 msg['Subject'] = self.subject
106
107
108 recipients = [self.recipient] + config.cc + config.bcc
109
110 msg.attach(MIMEText(self.body))
111
112 for (name, attach) in self.textAttachments:
113 part = MIMEText(attach, 'plain', 'UTF-8')
114 part.add_header("Content-Disposition", "attachment; filename=%s" % name)
115 msg.attach(part)
116
117 for (name, attach) in self.binaryAttachments:
118 ctype, encoding = mimetypes.guess_type(name)
119 if ctype is None or encoding is not None:
120 ctype = 'application/octet-stream'
121
122 maintype, subtype = ctype.split('/', 1)
123 if maintype == 'text':
124 part = MIMEText(attach, _subtype=subtype)
125 elif maintype == 'image':
126 part = MIMEImage(attach, _subtype=subtype)
127 elif maintype == 'audio':
128 part = MIMEAudio(attach, _subtype=subtype)
129 else:
130 part = MIMEBase(maintype, subtype)
131 part.set_payload(attach)
132 Encoders.encode_base64(part)
133
134 part.add_header("Content-Disposition", "attachment; filename=%s" % name)
135 msg.attach(part)
136
137 logging.info("Email: constructed email object, sending to %s", ", ".join(recipients))
138 smtpServer.sendmail(config.fromAddress, recipients, msg.as_string())
139 logging.info("Email: sent")
140