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