Added module for emailing
This commit is contained in:
parent
6fff4bc3c8
commit
51fd560f92
223
emailer.py
Executable file
223
emailer.py
Executable file
@ -0,0 +1,223 @@
|
|||||||
|
#!/usr/bin/python2
|
||||||
|
|
||||||
|
from email import encoders
|
||||||
|
from email.mime.audio import MIMEAudio
|
||||||
|
from email.mime.base import MIMEBase
|
||||||
|
from email.mime.image import MIMEImage
|
||||||
|
from email.mime.multipart import MIMEMultipart
|
||||||
|
from email.mime.text import MIMEText
|
||||||
|
import mimetypes
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import smtplib
|
||||||
|
|
||||||
|
class Email:
|
||||||
|
"""
|
||||||
|
This class handles the creation and sending of email messages
|
||||||
|
via SMTP. This class also handles attachments and can send
|
||||||
|
HTML messages. The code comes from various places around
|
||||||
|
the net and from my own brain.
|
||||||
|
"""
|
||||||
|
def __init__(self, smtpServer):
|
||||||
|
"""
|
||||||
|
Create a new empty email message object.
|
||||||
|
|
||||||
|
@param smtpServer: The address of the SMTP server
|
||||||
|
@type smtpServer: String
|
||||||
|
"""
|
||||||
|
self._textBody = None
|
||||||
|
self._htmlBody = None
|
||||||
|
self._bcc = []
|
||||||
|
self._cc = []
|
||||||
|
self._subject = ""
|
||||||
|
self._smtpServer = smtpServer
|
||||||
|
self._reEmail = re.compile("^([\\w \\._]+\\<[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\>|[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)$")
|
||||||
|
self.clearRecipients()
|
||||||
|
self.clearAttachments()
|
||||||
|
|
||||||
|
def send(self):
|
||||||
|
"""
|
||||||
|
Send the email message represented by this object.
|
||||||
|
"""
|
||||||
|
# Validate message
|
||||||
|
if self._textBody is None and self._htmlBody is None:
|
||||||
|
raise Exception("Error! Must specify at least one body type (HTML or Text)")
|
||||||
|
if len(self._to) == 0:
|
||||||
|
raise Exception("Must specify at least one recipient")
|
||||||
|
|
||||||
|
# Create the message part
|
||||||
|
if self._textBody is not None and self._htmlBody is None:
|
||||||
|
msg = MIMEText(self._textBody, "plain")
|
||||||
|
elif self._textBody is None and self._htmlBody is not None:
|
||||||
|
msg = MIMEText(self._htmlBody, "html")
|
||||||
|
else:
|
||||||
|
msg = MIMEMultipart("alternative")
|
||||||
|
msg.attach(MIMEText(self._textBody, "plain"))
|
||||||
|
msg.attach(MIMEText(self._htmlBody, "html"))
|
||||||
|
# Add attachments, if any
|
||||||
|
if len(self._attach) != 0:
|
||||||
|
tmpmsg = msg
|
||||||
|
msg = MIMEMultipart()
|
||||||
|
msg.attach(tmpmsg)
|
||||||
|
for fname,attachname in self._attach:
|
||||||
|
if not os.path.exists(fname):
|
||||||
|
print "File '%s' does not exist. Not attaching to email." % fname
|
||||||
|
continue
|
||||||
|
if not os.path.isfile(fname):
|
||||||
|
print "Attachment '%s' is not a file. Not attaching to email." % fname
|
||||||
|
continue
|
||||||
|
# Guess at encoding type
|
||||||
|
ctype, encoding = mimetypes.guess_type(fname)
|
||||||
|
if ctype is None or encoding is not None:
|
||||||
|
# No guess could be made so use a binary type.
|
||||||
|
ctype = 'application/octet-stream'
|
||||||
|
maintype, subtype = ctype.split('/', 1)
|
||||||
|
if maintype == 'text':
|
||||||
|
fp = open(fname)
|
||||||
|
attach = MIMEText(fp.read(), _subtype=subtype)
|
||||||
|
fp.close()
|
||||||
|
elif maintype == 'image':
|
||||||
|
fp = open(fname, 'rb')
|
||||||
|
attach = MIMEImage(fp.read(), _subtype=subtype)
|
||||||
|
fp.close()
|
||||||
|
elif maintype == 'audio':
|
||||||
|
fp = open(fname, 'rb')
|
||||||
|
attach = MIMEAudio(fp.read(), _subtype=subtype)
|
||||||
|
fp.close()
|
||||||
|
else:
|
||||||
|
fp = open(fname, 'rb')
|
||||||
|
attach = MIMEBase(maintype, subtype)
|
||||||
|
attach.set_payload(fp.read())
|
||||||
|
fp.close()
|
||||||
|
# Encode the payload using Base64
|
||||||
|
encoders.encode_base64(attach)
|
||||||
|
# Set the filename parameter
|
||||||
|
if attachname is None:
|
||||||
|
filename = os.path.basename(fname)
|
||||||
|
else:
|
||||||
|
filename = attachname
|
||||||
|
attach.add_header('Content-Disposition', 'attachment', filename=filename)
|
||||||
|
msg.attach(attach)
|
||||||
|
# Some header stuff
|
||||||
|
msg['Subject'] = self._subject
|
||||||
|
msg['From'] = self._from
|
||||||
|
msg['To'] = ", ".join(self._to)
|
||||||
|
msg['Cc'] = ", ".join(self._cc)
|
||||||
|
msg.preamble = "You need a MIME enabled mail reader to see this message"
|
||||||
|
# Send message
|
||||||
|
msg = msg.as_string()
|
||||||
|
server = smtplib.SMTP(self._smtpServer)
|
||||||
|
server.sendmail(self._from, self._to + self._cc + self._bcc, msg)
|
||||||
|
server.quit()
|
||||||
|
|
||||||
|
def setSubject(self, subject):
|
||||||
|
"""
|
||||||
|
Set the subject of the email message.
|
||||||
|
"""
|
||||||
|
self._subject = subject
|
||||||
|
|
||||||
|
def setFrom(self, address):
|
||||||
|
"""
|
||||||
|
Set the email sender.
|
||||||
|
"""
|
||||||
|
if not self.validateEmailAddress(address):
|
||||||
|
raise Exception("Invalid email address '%s'" % address)
|
||||||
|
self._from = address
|
||||||
|
|
||||||
|
def clearRecipients(self):
|
||||||
|
"""
|
||||||
|
Remove all currently defined recipients for
|
||||||
|
the email message.
|
||||||
|
"""
|
||||||
|
self._to = []
|
||||||
|
self._cc = []
|
||||||
|
self._bcc = []
|
||||||
|
|
||||||
|
def addRecipient(self, address):
|
||||||
|
"""
|
||||||
|
Add a new recipient to the email message.
|
||||||
|
"""
|
||||||
|
if not self.validateEmailAddress(address):
|
||||||
|
raise Exception("Invalid email address '%s'" % address)
|
||||||
|
self._to.append(address)
|
||||||
|
|
||||||
|
def addCC(self, address):
|
||||||
|
"""
|
||||||
|
Add a new carbon copy recipient to the email message.
|
||||||
|
"""
|
||||||
|
if not self.validateEmailAddress(address):
|
||||||
|
raise Exception("Invalid cc email address '%s'" % address)
|
||||||
|
self._cc.append(address)
|
||||||
|
|
||||||
|
def addBCC(self, address):
|
||||||
|
"""
|
||||||
|
Add a new blind carbon copy recipient to the email message.
|
||||||
|
"""
|
||||||
|
if not self.validateEmailAddress(address):
|
||||||
|
raise Exception("Invalid bcc email address '%s'" % address)
|
||||||
|
self._bcc.append(address)
|
||||||
|
|
||||||
|
def setTextBody(self, body):
|
||||||
|
"""
|
||||||
|
Set the plain text body of the email message.
|
||||||
|
"""
|
||||||
|
self._textBody = body
|
||||||
|
|
||||||
|
def setHtmlBody(self, body):
|
||||||
|
"""
|
||||||
|
Set the HTML portion of the email message.
|
||||||
|
"""
|
||||||
|
self._htmlBody = body
|
||||||
|
|
||||||
|
def clearAttachments(self):
|
||||||
|
"""
|
||||||
|
Remove all file attachments.
|
||||||
|
"""
|
||||||
|
self._attach = []
|
||||||
|
|
||||||
|
def addAttachment(self, fname, attachname=None):
|
||||||
|
"""
|
||||||
|
Add a file attachment to this email message.
|
||||||
|
|
||||||
|
@param fname: The full path and file name of the file
|
||||||
|
to attach.
|
||||||
|
@type fname: String
|
||||||
|
@param attachname: This will be the name of the file in
|
||||||
|
the email message if set. If not set
|
||||||
|
then the filename will be taken from
|
||||||
|
the fname parameter above.
|
||||||
|
@type attachname: String
|
||||||
|
"""
|
||||||
|
if fname is None:
|
||||||
|
return
|
||||||
|
self._attach.append( (fname, attachname) )
|
||||||
|
|
||||||
|
def validateEmailAddress(self, address):
|
||||||
|
"""
|
||||||
|
Validate the specified email address.
|
||||||
|
|
||||||
|
@return: True if valid, False otherwise
|
||||||
|
@rtype: Boolean
|
||||||
|
"""
|
||||||
|
if self._reEmail.search(address) is None:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print "Tests go here..."
|
||||||
|
"""
|
||||||
|
# Run some tests
|
||||||
|
mFrom = 'fredw@northriverboats.com'
|
||||||
|
mTo = "fred.warren@gmail.com"
|
||||||
|
m = Email('northriverboats-com.mail.protection.outlook.com')
|
||||||
|
m.setFrom(mFrom)
|
||||||
|
m.addRecipient(mTo)
|
||||||
|
m.addCC("fredw@northriverboats.com")
|
||||||
|
m.addBCC("w.brokenbourgh@pismotek.com")
|
||||||
|
|
||||||
|
m.setSubject("Text and HTML Message with CC and BCC")
|
||||||
|
m.setTextBody("You should not see this text in a MIME aware reader")
|
||||||
|
m.setHtmlBody("The following should be <b>bold</b>. If this works Will, you will be BCC'd on this.")
|
||||||
|
m.addAttachment('/tmp/shot.png')
|
||||||
|
m.send()
|
||||||
|
"""
|
Loading…
Reference in New Issue
Block a user