Skip to content

Instantly share code, notes, and snippets.

@Tirpitz93
Forked from jorge-lavin/gist:238ccb229ac594a50b0a
Last active June 12, 2018 15:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Tirpitz93/b552dc9d1456f61f758dd9a3183221e9 to your computer and use it in GitHub Desktop.
Save Tirpitz93/b552dc9d1456f61f758dd9a3183221e9 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
from email.utils import formatdate
from past.types import basestring
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 = MIMEMultipart()
msg['From'] = self.fromaddr
msg['To'] = ",".join(self.toaddrs)
msg['Date'] = formatdate(localtime=True)
msg['Subject'] = self.getSubject('')
# fixed to deal with exception
msg.attach(MIMEText(self.format(record).replace("\n", "<br>").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, 'r') 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