Source code for uw.local.outgoing.make_mail

"""Outgoing mail handler API implementation.

This module provides Python routines for accessing the database functions that
are responsible for creating the mail messages within the database.
"""

import sys
import email

from uw.sql.wrap import open_psycopg2_db_service_cursor

from uw.emailutils import emailaddr

[docs]class mailout (object): """An Outgoing mail message being created. :param cursor: DB connection cursor. :param uw.emailutils.emailaddr sender: the sender of the email. :param str subject: the subject of the email, or None. :param str content: the contents of the email, or None. Creating an instance of this class creates an email message in progress in the database. """ def __init__ (self, cursor, sender, subject, content, content_html=None): self.__cursor = cursor self.__msg_id = cursor.callproc_required_value ("mailout_create", sender.email, sender.realname, subject, content, content_html) @property def cursor (self): """The DB connection cursor. """ return self.__cursor @property def msg_id (self): """The Message ID of the newly-created message. This is initialized upon creation of the object. """ return self.__msg_id
[docs] def add_recipient (self, type, recipient): """Add a recipient. :param str type: the recipient type, one of "To", "Cc", "Bcc". :param uw.emailutils.emailaddr recipient: email recipient. """ self.cursor.callproc_none ("mailout_add_recipient", self.msg_id, type, recipient.email, recipient.realname)
[docs] def add_recipient_person (self, type, person_id): """Add a recipient by their Person ID. :param str type: the recipient type, one of "To", "Cc", "Bcc". :param int person_id: the Person ID of the recipient. """ self.cursor.callproc_none ("mailout_add_recipient", self.msg_id, type, person_id)
[docs] def add_attachment (self, content_maintype, content_subtype, content_charset, content, filename=None): """Add an attachment. The content_maintype and content_subtype together give the MIME type (e.g. "text/plain"). The content_charset is the charset for text content, or None. The content is the content as bytes or Unicode. If the content is supplied as Unicode, it will automatically be encoded in the specified content_charset or utf-8 if None is specified. The charset parameter will automatically be added to the MIME type. """ if isinstance (content, str): if content_charset is None: content_charset = 'utf-8' content = content.encode (content_charset) elif not isinstance (content, bytes): raise ValueError ('content is of wrong type: %s' % type (content)) self.cursor.callproc_none ("mailout_add_attachment", self.msg_id, content_maintype, content_subtype, content_charset, content, filename)
[docs] def done (self): """Finish the message and release it for sending. """ self.cursor.callproc_none ("mailout_done", self.msg_id)
[docs] @staticmethod def send (cursor, msg): """Use Outgoing to send a message created using the Python email module. :param cursor: DB connection cursor. :param email.message.Message msg: email message to send. """ if msg.is_multipart (): raise CantHandleMultiPart db_msg = mailout (cursor, emailaddr.parse1 (msg['From']), msg['Subject'], msg.get_payload ()) for type in ['To', 'Cc', 'Bcc']: for recipient in emailaddr.parse (msg.get_all (type, [])): db_msg.add_recipient (type, recipient) db_msg.done () return db_msg.msg_id
[docs]def main (): """Program entry point for sending a message assembled separately. This is intended for testing and debugging. Take an email message on stdin and parse it into an :py:class:`email.message.Message` object, then send it using a :py:class:`mailout` object. """ cursor = open_psycopg2_db_service_cursor () msg = email.message_from_file (sys.stdin) print(mailout.send (cursor, msg)) cursor.commit ()