comparison 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
comparison
equal deleted inserted replaced
2005:ab0e122b38a7 2031:82a88013a3fd
1 from rhodecode.lib.rcmail.response import MailResponse
2
3 from rhodecode.lib.rcmail.exceptions import BadHeaders
4 from rhodecode.lib.rcmail.exceptions import InvalidMessage
5
6 class Attachment(object):
7 """
8 Encapsulates file attachment information.
9
10 :param filename: filename of attachment
11 :param content_type: file mimetype
12 :param data: the raw file data, either as string or file obj
13 :param disposition: content-disposition (if any)
14 """
15
16 def __init__(self,
17 filename=None,
18 content_type=None,
19 data=None,
20 disposition=None):
21
22 self.filename = filename
23 self.content_type = content_type
24 self.disposition = disposition or 'attachment'
25 self._data = data
26
27 @property
28 def data(self):
29 if isinstance(self._data, basestring):
30 return self._data
31 self._data = self._data.read()
32 return self._data
33
34
35 class Message(object):
36 """
37 Encapsulates an email message.
38
39 :param subject: email subject header
40 :param recipients: list of email addresses
41 :param body: plain text message
42 :param html: HTML message
43 :param sender: email sender address
44 :param cc: CC list
45 :param bcc: BCC list
46 :param extra_headers: dict of extra email headers
47 :param attachments: list of Attachment instances
48 :param recipients_separator: alternative separator for any of
49 'From', 'To', 'Delivered-To', 'Cc', 'Bcc' fields
50 """
51
52 def __init__(self,
53 subject=None,
54 recipients=None,
55 body=None,
56 html=None,
57 sender=None,
58 cc=None,
59 bcc=None,
60 extra_headers=None,
61 attachments=None,
62 recipients_separator="; "):
63
64 self.subject = subject or ''
65 self.sender = sender
66 self.body = body
67 self.html = html
68
69 self.recipients = recipients or []
70 self.attachments = attachments or []
71 self.cc = cc or []
72 self.bcc = bcc or []
73 self.extra_headers = extra_headers or {}
74
75 self.recipients_separator = recipients_separator
76
77 @property
78 def send_to(self):
79 return set(self.recipients) | set(self.bcc or ()) | set(self.cc or ())
80
81 def to_message(self):
82 """
83 Returns raw email.Message instance.Validates message first.
84 """
85
86 self.validate()
87
88 return self.get_response().to_message()
89
90 def get_response(self):
91 """
92 Creates a Lamson MailResponse instance
93 """
94
95 response = MailResponse(Subject=self.subject,
96 To=self.recipients,
97 From=self.sender,
98 Body=self.body,
99 Html=self.html,
100 separator=self.recipients_separator)
101
102 if self.cc:
103 response.base['Cc'] = self.cc
104
105 for attachment in self.attachments:
106
107 response.attach(attachment.filename,
108 attachment.content_type,
109 attachment.data,
110 attachment.disposition)
111
112 response.update(self.extra_headers)
113
114 return response
115
116 def is_bad_headers(self):
117 """
118 Checks for bad headers i.e. newlines in subject, sender or recipients.
119 """
120
121 headers = [self.subject, self.sender]
122 headers += list(self.send_to)
123 headers += self.extra_headers.values()
124
125 for val in headers:
126 for c in '\r\n':
127 if c in val:
128 return True
129 return False
130
131 def validate(self):
132 """
133 Checks if message is valid and raises appropriate exception.
134 """
135
136 if not self.recipients:
137 raise InvalidMessage, "No recipients have been added"
138
139 if not self.body and not self.html:
140 raise InvalidMessage, "No body has been set"
141
142 if not self.sender:
143 raise InvalidMessage, "No sender address has been set"
144
145 if self.is_bad_headers():
146 raise BadHeaders
147
148 def add_recipient(self, recipient):
149 """
150 Adds another recipient to the message.
151
152 :param recipient: email address of recipient.
153 """
154
155 self.recipients.append(recipient)
156
157 def add_cc(self, recipient):
158 """
159 Adds an email address to the CC list.
160
161 :param recipient: email address of recipient.
162 """
163
164 self.cc.append(recipient)
165
166 def add_bcc(self, recipient):
167 """
168 Adds an email address to the BCC list.
169
170 :param recipient: email address of recipient.
171 """
172
173 self.bcc.append(recipient)
174
175 def attach(self, attachment):
176 """
177 Adds an attachment to the message.
178
179 :param attachment: an **Attachment** instance.
180 """
181
182 self.attachments.append(attachment)