Mercurial > kallithea
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) |