Mercurial > kallithea
diff rhodecode/lib/rcmail/message.py @ 2031:82a88013a3fd
merge 1.3 into stable
author | Marcin Kuzminski <marcin@python-works.com> |
---|---|
date | Sun, 26 Feb 2012 17:25:09 +0200 |
parents | 69e95ad5b6f0 |
children | d95ef6587bca |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rhodecode/lib/rcmail/message.py Sun Feb 26 17:25:09 2012 +0200 @@ -0,0 +1,182 @@ +from rhodecode.lib.rcmail.response import MailResponse + +from rhodecode.lib.rcmail.exceptions import BadHeaders +from rhodecode.lib.rcmail.exceptions import InvalidMessage + +class Attachment(object): + """ + Encapsulates file attachment information. + + :param filename: filename of attachment + :param content_type: file mimetype + :param data: the raw file data, either as string or file obj + :param disposition: content-disposition (if any) + """ + + def __init__(self, + filename=None, + content_type=None, + data=None, + disposition=None): + + self.filename = filename + self.content_type = content_type + self.disposition = disposition or 'attachment' + self._data = data + + @property + def data(self): + if isinstance(self._data, basestring): + return self._data + self._data = self._data.read() + return self._data + + +class Message(object): + """ + Encapsulates an email message. + + :param subject: email subject header + :param recipients: list of email addresses + :param body: plain text message + :param html: HTML message + :param sender: email sender address + :param cc: CC list + :param bcc: BCC list + :param extra_headers: dict of extra email headers + :param attachments: list of Attachment instances + :param recipients_separator: alternative separator for any of + 'From', 'To', 'Delivered-To', 'Cc', 'Bcc' fields + """ + + def __init__(self, + subject=None, + recipients=None, + body=None, + html=None, + sender=None, + cc=None, + bcc=None, + extra_headers=None, + attachments=None, + recipients_separator="; "): + + self.subject = subject or '' + self.sender = sender + self.body = body + self.html = html + + self.recipients = recipients or [] + self.attachments = attachments or [] + self.cc = cc or [] + self.bcc = bcc or [] + self.extra_headers = extra_headers or {} + + self.recipients_separator = recipients_separator + + @property + def send_to(self): + return set(self.recipients) | set(self.bcc or ()) | set(self.cc or ()) + + def to_message(self): + """ + Returns raw email.Message instance.Validates message first. + """ + + self.validate() + + return self.get_response().to_message() + + def get_response(self): + """ + Creates a Lamson MailResponse instance + """ + + response = MailResponse(Subject=self.subject, + To=self.recipients, + From=self.sender, + Body=self.body, + Html=self.html, + separator=self.recipients_separator) + + if self.cc: + response.base['Cc'] = self.cc + + for attachment in self.attachments: + + response.attach(attachment.filename, + attachment.content_type, + attachment.data, + attachment.disposition) + + response.update(self.extra_headers) + + return response + + def is_bad_headers(self): + """ + Checks for bad headers i.e. newlines in subject, sender or recipients. + """ + + headers = [self.subject, self.sender] + headers += list(self.send_to) + headers += self.extra_headers.values() + + for val in headers: + for c in '\r\n': + if c in val: + return True + return False + + def validate(self): + """ + Checks if message is valid and raises appropriate exception. + """ + + if not self.recipients: + raise InvalidMessage, "No recipients have been added" + + if not self.body and not self.html: + raise InvalidMessage, "No body has been set" + + if not self.sender: + raise InvalidMessage, "No sender address has been set" + + if self.is_bad_headers(): + raise BadHeaders + + def add_recipient(self, recipient): + """ + Adds another recipient to the message. + + :param recipient: email address of recipient. + """ + + self.recipients.append(recipient) + + def add_cc(self, recipient): + """ + Adds an email address to the CC list. + + :param recipient: email address of recipient. + """ + + self.cc.append(recipient) + + def add_bcc(self, recipient): + """ + Adds an email address to the BCC list. + + :param recipient: email address of recipient. + """ + + self.bcc.append(recipient) + + def attach(self, attachment): + """ + Adds an attachment to the message. + + :param attachment: an **Attachment** instance. + """ + + self.attachments.append(attachment)