Source code for photon.tools.mail

from email import charset as _charset
from email.mime.multipart import MIMEMultipart as _MIMEMultipart
from email.mime.text import MIMEText as _MIMEText
from email.utils import formatdate as _formatdate
from itertools import chain as _chain
from pprint import pformat as _pformat
from smtplib import SMTP as _SMTP
from smtplib import SMTPException as _SMTPException
from socket import error as _error

from photon import IDENT

from photon.photon import check_m
from photon.util.structures import to_list
from photon.util.system import get_timestamp


[docs]class Mail(object): ''' The Mail tool helps to send out mails. :param to: Where to send the mail ('user@example.com') :param sender: Yourself ('me@example.com') * set a reverse DNS entry for ``example.com`` \ so your mail does not get caught up in spamfilters. :param subject: The subject line :param cc: One or a list of CCs :param bcc: One or a list of BCCs ''' def __init__(self, m, to, sender, subject=None, cc=None, bcc=None): super().__init__() self.m = check_m(m) to = to_list(to) cc = to_list(cc) bcc = to_list(bcc) if not subject: subject = '%s mailer' % (IDENT) subject = '%s - %s' % (subject, get_timestamp()) self.__sender = sender self.__recipients = list(_chain(to, cc, bcc)) _charset.add_charset('utf-8', _charset.QP, _charset.QP, 'UTF-8') self.__message = _MIMEMultipart() self.__message.add_header('To', ', '.join(to)) if cc: self.__message.add_header('CC', ', '.join(cc)) self.__message.add_header('From', sender) self.__message.add_header('Subject', subject) self.__message.add_header('Date', _formatdate()) self.__message.add_header('X-Mailer', '%s mailer' % (IDENT)) self.m( 'mail tool startup done', more=dict(to=to, cc=cc, bcc=bcc, sender=sender, subject=subject), verbose=False ) @property def text(self): ''' :param text: Add some more text :returns: All text & headers as raw mail source ''' return self.__message.as_string().encode('UTF-8') @text.setter def text(self, text): ''' .. seealso:: :attr:`text` ''' if text: if not isinstance(text, str): text = _pformat(text) text += '\n\n' self.m( 'add text to mail', more=dict(len=len(text)) ) self.__message.attach(_MIMEText(text, 'plain', 'UTF-8')) @property def send(self): ''' :returns: A dictionary with the following: * 'sender': The `sender` * 'recipients': All recipients, compiled from `to`, `cc` and `bcc` * 'result': The :py:meth:`smtplib.SMTP.sendmail`-result * 'exception': The exception message (if any) .. note:: You need to have a postfix/sendmail running and listening on localhost. ''' res = dict(sender=self.__sender, recipients=self.__recipients) try: s = _SMTP() s.connect('localhost') res.update(dict( result=s.sendmail(self.__sender, self.__recipients, self.text) )) self.m('mail sent', more=res) except (_SMTPException, _error) as ex: res.update(dict( exception=str(ex) )) self.m('error sending mail', verbose=True, more=res) return res