Skip to content

Instantly share code, notes, and snippets.

@jorge-lavin
Created November 25, 2014 13:03
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jorge-lavin/238ccb229ac594a50b0a to your computer and use it in GitHub Desktop.
Save jorge-lavin/238ccb229ac594a50b0a to your computer and use it in GitHub Desktop.
SMTPHandler with support to attachments
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.Utils import formatdate
from logging.handlers import SMTPHandler
import logging
import os.path
import smtplib
class SMTPHandlerWithAttachment(SMTPHandler):
"""
A handler class which sends an SMTP email for each logging event.
"""
def __init__(self, mailhost, fromaddr, toaddrs, subject,
credentials=None, secure=None, attachment=None):
"""
Initialize the handler.
Initialize the instance with the from and to addresses and subject
line of the email. To specify a non-standard SMTP port, use the
(host, port) tuple format for the mailhost argument. To specify
authentication credentials, supply a (username, password) tuple
for the credentials argument. To specify the use of a secure
protocol (TLS), pass in a tuple for the secure argument. This will
only be used when authentication credentials are supplied. The tuple
will be either an empty tuple, or a single-value tuple with the name
of a keyfile, or a 2-value tuple with the names of the keyfile and
certificate file. (This tuple is passed to the `starttls` method).
"""
logging.Handler.__init__(self)
if isinstance(mailhost, tuple):
self.mailhost, self.mailport = mailhost
else:
self.mailhost, self.mailport = mailhost, None
if isinstance(credentials, tuple):
self.username, self.password = credentials
else:
self.username = None
self.fromaddr = fromaddr
if isinstance(toaddrs, basestring):
toaddrs = [toaddrs]
self.toaddrs = toaddrs
self.subject = subject
self.secure = secure
self._timeout = 5.0
self.attachment = attachment
def emit(self, record):
"""
Emit a record.
Format the record and send it to the specified addressees.
"""
try:
port = self.mailport
if not port:
port = smtplib.SMTP_PORT
smtp = smtplib.SMTP(self.mailhost, port, timeout=self._timeout)
# msg = self.format(record)
# msg = "From: %s\r\nTo: %s\r\nSubject: %s\r\nDate: %s\r\n\r\n%s" % (
# self.fromaddr,
# ",".join(self.toaddrs),
# self.getSubject(record),
# formatdate(), msg)
msg = self.format(record)
msg = MIMEMultipart()
msg['From'] = self.fromaddr
msg['To'] = ",".join(self.toaddrs)
msg['Date'] = formatdate(localtime=True)
msg['Subject'] = self.getSubject('')
msg.attach(MIMEText(record.msg.encode('utf-8'), 'html', 'utf-8'))
#Prepare attachments
for arg in self.attachment:
attach_properties = os.path.splitext(os.path.basename(arg))
with open(arg, 'rb') as fp:
if attach_properties[0].lower() in ['.jpg', '.png', '.gif', '.jpeg', '.bmp']:
attachment = MIMEImage(fp.read())
else:
attachment = MIMEText(fp.read())
attachment.add_header('Content-Disposition', 'attachment', filename='.'.join(attach_properties))
msg.attach(attachment)
if self.username:
if self.secure is not None:
smtp.ehlo()
smtp.starttls(*self.secure)
smtp.ehlo()
smtp.login(self.username, self.password)
smtp.sendmail(self.fromaddr, self.toaddrs, msg.as_string())
smtp.quit()
except (KeyboardInterrupt, SystemExit):
raise
except:
self.handleError(record)
if __name__ == '__main__':
MAILHOST ='foo.smtp.org'
SENDER = 'someone@somewhere.com'
TO_ADDRS = ['me@somewhere.com', 'someoneelse@somewhere.com']
SUBJECT = 'Subject'
ATTACHMENT = 'some_file.txt'
log = logging.getLogger('')
log.setLevel(logging.DEBUG)
mail_attachment_handler = SMTPHandlerWithAttachment(mailhost=MAILHOST,
fromaddr=SENDER,
toaddrs=TO_ADDRS,
subject=SUBJECT,
secure=None,
attachment=ATTACHMENT)
fmt = "%(msg)s"
mail_attachment_handler.setLevel(logging.INFO)
mail_attachment_handler.setFormatter(fmt)
log.addHandler(mail_attachment_handler)
log.info("Did something")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment