Merge ~cjwatson/launchpad:py3only-message-from-bytes into launchpad:master
- Git
- lp:~cjwatson/launchpad
- py3only-message-from-bytes
- Merge into master
Proposed by
Colin Watson
Status: | Merged |
---|---|
Approved by: | Colin Watson |
Approved revision: | 5baa1c0d154199d3b8524ce0e291be0ee9cb98bf |
Merge reported by: | Otto Co-Pilot |
Merged at revision: | not available |
Proposed branch: | ~cjwatson/launchpad:py3only-message-from-bytes |
Merge into: | launchpad:master |
Diff against target: |
1083 lines (+100/-118) 31 files modified
lib/lp/blueprints/doc/specification-notifications.txt (+6/-6) lib/lp/bugs/doc/externalbugtracker-debbugs.txt (+3/-4) lib/lp/bugs/doc/initial-bug-contacts.txt (+2/-2) lib/lp/bugs/externalbugtracker/debbugs.py (+4/-4) lib/lp/bugs/scripts/debbugs.py (+2/-4) lib/lp/bugs/tests/bugs-emailinterface.txt (+10/-9) lib/lp/bugs/utilities/filebugdataparser.py (+2/-2) lib/lp/code/doc/codeimport.txt (+2/-2) lib/lp/code/mail/tests/test_codeimport.py (+8/-8) lib/lp/code/model/tests/test_gitrepository.py (+2/-2) lib/lp/codehosting/scanner/tests/test_email.py (+5/-5) lib/lp/registry/browser/tests/test_person.py (+2/-2) lib/lp/registry/doc/distribution-mirror.txt (+2/-2) lib/lp/registry/stories/gpg-coc/xx-gpg-coc.txt (+5/-5) lib/lp/registry/stories/mailinglists/hosted-email-address.txt (+2/-2) lib/lp/registry/stories/person/xx-add-sshkey.txt (+2/-2) lib/lp/registry/tests/test_mailinglistapi.py (+4/-7) lib/lp/services/compat.py (+0/-6) lib/lp/services/mail/doc/emailauthentication.txt (+3/-6) lib/lp/services/mail/doc/mailbox.txt (+3/-3) lib/lp/services/mail/doc/sending-mail.txt (+13/-13) lib/lp/services/mail/notification.py (+2/-2) lib/lp/services/mail/signedmessage.py (+2/-2) lib/lp/services/mail/stub.py (+3/-5) lib/lp/services/mail/tests/incomingmail.txt (+1/-2) lib/lp/services/mail/tests/test_stub.py (+1/-1) lib/lp/services/messages/model/message.py (+2/-2) lib/lp/services/verification/doc/logintoken.txt (+1/-1) lib/lp/services/verification/tests/logintoken.py (+2/-3) lib/lp/testing/mail_helpers.py (+2/-2) lib/lp/translations/doc/translations-export-to-branch.txt (+2/-2) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Cristian Gonzalez (community) | Approve | ||
Review via email: mp+408168@code.launchpad.net |
Commit message
Use email.message_
Description of the change
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | diff --git a/lib/lp/blueprints/doc/specification-notifications.txt b/lib/lp/blueprints/doc/specification-notifications.txt | |||
2 | index 7eb04ab..63130a4 100644 | |||
3 | --- a/lib/lp/blueprints/doc/specification-notifications.txt | |||
4 | +++ b/lib/lp/blueprints/doc/specification-notifications.txt | |||
5 | @@ -116,9 +116,9 @@ are now subscribed. | |||
6 | 116 | 116 | ||
7 | 117 | Now let's take a look at what the notification looks like: | 117 | Now let's take a look at what the notification looks like: |
8 | 118 | 118 | ||
10 | 119 | >>> from lp.services.compat import message_from_bytes | 119 | >>> import email |
11 | 120 | >>> notifications = [ | 120 | >>> notifications = [ |
13 | 121 | ... message_from_bytes(raw_message) | 121 | ... email.message_from_bytes(raw_message) |
14 | 122 | ... for from_addr, to_addrs, raw_message in sorted(stub.test_emails)] | 122 | ... for from_addr, to_addrs, raw_message in sorted(stub.test_emails)] |
15 | 123 | >>> status_notification = notifications[0] | 123 | >>> status_notification = notifications[0] |
16 | 124 | >>> status_notification['To'] | 124 | >>> status_notification['To'] |
17 | @@ -158,7 +158,7 @@ Whiteboard change: | |||
18 | 158 | >>> transaction.commit() | 158 | >>> transaction.commit() |
19 | 159 | 159 | ||
20 | 160 | >>> notifications = [ | 160 | >>> notifications = [ |
22 | 161 | ... message_from_bytes(raw_message) | 161 | ... email.message_from_bytes(raw_message) |
23 | 162 | ... for from_addr, to_addrs, raw_message in sorted(stub.test_emails)] | 162 | ... for from_addr, to_addrs, raw_message in sorted(stub.test_emails)] |
24 | 163 | >>> status_notification = notifications[0] | 163 | >>> status_notification = notifications[0] |
25 | 164 | >>> status_notification['To'] | 164 | >>> status_notification['To'] |
26 | @@ -198,7 +198,7 @@ Definition status and whiteboard change: | |||
27 | 198 | >>> transaction.commit() | 198 | >>> transaction.commit() |
28 | 199 | 199 | ||
29 | 200 | >>> notifications = [ | 200 | >>> notifications = [ |
31 | 201 | ... message_from_bytes(raw_message) | 201 | ... email.message_from_bytes(raw_message) |
32 | 202 | ... for from_addr, to_addrs, raw_message in sorted(stub.test_emails)] | 202 | ... for from_addr, to_addrs, raw_message in sorted(stub.test_emails)] |
33 | 203 | >>> status_notification = notifications[0] | 203 | >>> status_notification = notifications[0] |
34 | 204 | >>> status_notification['To'] | 204 | >>> status_notification['To'] |
35 | @@ -238,7 +238,7 @@ Change priority: | |||
36 | 238 | >>> transaction.commit() | 238 | >>> transaction.commit() |
37 | 239 | 239 | ||
38 | 240 | >>> notifications = [ | 240 | >>> notifications = [ |
40 | 241 | ... message_from_bytes(raw_message) | 241 | ... email.message_from_bytes(raw_message) |
41 | 242 | ... for from_addr, to_addrs, raw_message in sorted(stub.test_emails)] | 242 | ... for from_addr, to_addrs, raw_message in sorted(stub.test_emails)] |
42 | 243 | >>> status_notification = notifications[0] | 243 | >>> status_notification = notifications[0] |
43 | 244 | >>> status_notification['To'] | 244 | >>> status_notification['To'] |
44 | @@ -272,7 +272,7 @@ Change approver, assignee and drafter: | |||
45 | 272 | >>> transaction.commit() | 272 | >>> transaction.commit() |
46 | 273 | 273 | ||
47 | 274 | >>> notifications = [ | 274 | >>> notifications = [ |
49 | 275 | ... message_from_bytes(raw_message) | 275 | ... email.message_from_bytes(raw_message) |
50 | 276 | ... for from_addr, to_addrs, raw_message in sorted(stub.test_emails)] | 276 | ... for from_addr, to_addrs, raw_message in sorted(stub.test_emails)] |
51 | 277 | >>> status_notification = notifications[0] | 277 | >>> status_notification = notifications[0] |
52 | 278 | >>> status_notification['To'] | 278 | >>> status_notification['To'] |
53 | diff --git a/lib/lp/bugs/doc/externalbugtracker-debbugs.txt b/lib/lp/bugs/doc/externalbugtracker-debbugs.txt | |||
54 | index 9dce3b5..aec439d 100644 | |||
55 | --- a/lib/lp/bugs/doc/externalbugtracker-debbugs.txt | |||
56 | +++ b/lib/lp/bugs/doc/externalbugtracker-debbugs.txt | |||
57 | @@ -416,10 +416,9 @@ same comment. | |||
58 | 416 | If we query the DebBugs database directly we'll see that there are two | 416 | If we query the DebBugs database directly we'll see that there are two |
59 | 417 | copies of the same comment. | 417 | copies of the same comment. |
60 | 418 | 418 | ||
61 | 419 | >>> from lp.services.compat import message_from_bytes | ||
62 | 420 | >>> debian_bug = external_debbugs._findBug(bug_watch.remotebug) | 419 | >>> debian_bug = external_debbugs._findBug(bug_watch.remotebug) |
63 | 421 | >>> for comment in debian_bug.comments: | 420 | >>> for comment in debian_bug.comments: |
65 | 422 | ... comment_email = message_from_bytes(comment) | 421 | ... comment_email = email.message_from_bytes(comment) |
66 | 423 | ... print(comment_email['message-id']) | 422 | ... print(comment_email['message-id']) |
67 | 424 | <20040309081430.98BF411EE67@tux> | 423 | <20040309081430.98BF411EE67@tux> |
68 | 425 | <20040309081430.98BF411EE67@tux> | 424 | <20040309081430.98BF411EE67@tux> |
69 | @@ -493,7 +492,7 @@ datecreated comes not from the Date header but from the Received header. | |||
70 | 493 | 492 | ||
71 | 494 | >>> from lp.bugs.tests.externalbugtracker import ( | 493 | >>> from lp.bugs.tests.externalbugtracker import ( |
72 | 495 | ... read_test_file) | 494 | ... read_test_file) |
74 | 496 | >>> parsed_message = message_from_bytes( | 495 | >>> parsed_message = email.message_from_bytes( |
75 | 497 | ... read_test_file('debbugs-comment-with-received-date.txt').encode( | 496 | ... read_test_file('debbugs-comment-with-received-date.txt').encode( |
76 | 498 | ... 'UTF-8')) | 497 | ... 'UTF-8')) |
77 | 499 | 498 | ||
78 | @@ -519,7 +518,7 @@ default to using the Date header again. | |||
79 | 519 | >>> print(message.datecreated) | 518 | >>> print(message.datecreated) |
80 | 520 | 2007-12-14 18:54:30+00:00 | 519 | 2007-12-14 18:54:30+00:00 |
81 | 521 | 520 | ||
83 | 522 | >>> parsed_message = message_from_bytes( | 521 | >>> parsed_message = email.message_from_bytes( |
84 | 523 | ... read_test_file('debbugs-comment-with-received-date.txt').encode( | 522 | ... read_test_file('debbugs-comment-with-received-date.txt').encode( |
85 | 524 | ... 'UTF-8')) | 523 | ... 'UTF-8')) |
86 | 525 | 524 | ||
87 | diff --git a/lib/lp/bugs/doc/initial-bug-contacts.txt b/lib/lp/bugs/doc/initial-bug-contacts.txt | |||
88 | index 46e8ed2..7161f17 100644 | |||
89 | --- a/lib/lp/bugs/doc/initial-bug-contacts.txt | |||
90 | +++ b/lib/lp/bugs/doc/initial-bug-contacts.txt | |||
91 | @@ -167,8 +167,8 @@ notification). The email has the X-Launchpad-Message-Rationale header to | |||
92 | 167 | track why daf received the email. The rational is repeated in the footer | 167 | track why daf received the email. The rational is repeated in the footer |
93 | 168 | of the email with the bug title and URL. | 168 | of the email with the bug title and URL. |
94 | 169 | 169 | ||
95 | 170 | >>> import email | ||
96 | 170 | >>> from operator import itemgetter | 171 | >>> from operator import itemgetter |
97 | 171 | >>> from lp.services.compat import message_from_bytes | ||
98 | 172 | 172 | ||
99 | 173 | >>> test_emails = list(stub.test_emails) | 173 | >>> test_emails = list(stub.test_emails) |
100 | 174 | >>> test_emails.sort(key=itemgetter(1)) | 174 | >>> test_emails.sort(key=itemgetter(1)) |
101 | @@ -183,7 +183,7 @@ of the email with the bug title and URL. | |||
102 | 183 | >>> print(to_addr) | 183 | >>> print(to_addr) |
103 | 184 | ['daf@canonical.com'] | 184 | ['daf@canonical.com'] |
104 | 185 | 185 | ||
106 | 186 | >>> msg = message_from_bytes(raw_message) | 186 | >>> msg = email.message_from_bytes(raw_message) |
107 | 187 | >>> msg['References'] == ( | 187 | >>> msg['References'] == ( |
108 | 188 | ... bug_one_in_ubuntu_firefox.bug.initial_message.rfc822msgid) | 188 | ... bug_one_in_ubuntu_firefox.bug.initial_message.rfc822msgid) |
109 | 189 | True | 189 | True |
110 | diff --git a/lib/lp/bugs/externalbugtracker/debbugs.py b/lib/lp/bugs/externalbugtracker/debbugs.py | |||
111 | index 360c2b5..1bca0c7 100644 | |||
112 | --- a/lib/lp/bugs/externalbugtracker/debbugs.py | |||
113 | +++ b/lib/lp/bugs/externalbugtracker/debbugs.py | |||
114 | @@ -10,6 +10,7 @@ __all__ = [ | |||
115 | 10 | ] | 10 | ] |
116 | 11 | 11 | ||
117 | 12 | from datetime import datetime | 12 | from datetime import datetime |
118 | 13 | import email | ||
119 | 13 | from email.utils import ( | 14 | from email.utils import ( |
120 | 14 | mktime_tz, | 15 | mktime_tz, |
121 | 15 | parseaddr, | 16 | parseaddr, |
122 | @@ -41,7 +42,6 @@ from lp.bugs.interfaces.externalbugtracker import ( | |||
123 | 41 | UNKNOWN_REMOTE_IMPORTANCE, | 42 | UNKNOWN_REMOTE_IMPORTANCE, |
124 | 42 | ) | 43 | ) |
125 | 43 | from lp.bugs.scripts import debbugs | 44 | from lp.bugs.scripts import debbugs |
126 | 44 | from lp.services.compat import message_from_bytes | ||
127 | 45 | from lp.services.config import config | 45 | from lp.services.config import config |
128 | 46 | from lp.services.database.isolation import ensure_no_transaction | 46 | from lp.services.database.isolation import ensure_no_transaction |
129 | 47 | from lp.services.mail.sendmail import simple_sendmail | 47 | from lp.services.mail.sendmail import simple_sendmail |
130 | @@ -242,7 +242,7 @@ class DebBugs(ExternalBugTracker): | |||
131 | 242 | 242 | ||
132 | 243 | comment_ids = [] | 243 | comment_ids = [] |
133 | 244 | for comment in debian_bug.comments: | 244 | for comment in debian_bug.comments: |
135 | 245 | parsed_comment = message_from_bytes(comment) | 245 | parsed_comment = email.message_from_bytes(comment) |
136 | 246 | 246 | ||
137 | 247 | # It's possible for the same message to appear several times | 247 | # It's possible for the same message to appear several times |
138 | 248 | # in a DebBugs comment log, since each control command in a | 248 | # in a DebBugs comment log, since each control command in a |
139 | @@ -271,7 +271,7 @@ class DebBugs(ExternalBugTracker): | |||
140 | 271 | self._loadLog(debian_bug) | 271 | self._loadLog(debian_bug) |
141 | 272 | 272 | ||
142 | 273 | for comment in debian_bug.comments: | 273 | for comment in debian_bug.comments: |
144 | 274 | parsed_comment = message_from_bytes(comment) | 274 | parsed_comment = email.message_from_bytes(comment) |
145 | 275 | if parsed_comment['message-id'] == comment_id: | 275 | if parsed_comment['message-id'] == comment_id: |
146 | 276 | return parseaddr(parsed_comment['from']) | 276 | return parseaddr(parsed_comment['from']) |
147 | 277 | 277 | ||
148 | @@ -324,7 +324,7 @@ class DebBugs(ExternalBugTracker): | |||
149 | 324 | self._loadLog(debian_bug) | 324 | self._loadLog(debian_bug) |
150 | 325 | 325 | ||
151 | 326 | for comment in debian_bug.comments: | 326 | for comment in debian_bug.comments: |
153 | 327 | parsed_comment = message_from_bytes(comment) | 327 | parsed_comment = email.message_from_bytes(comment) |
154 | 328 | if parsed_comment['message-id'] == comment_id: | 328 | if parsed_comment['message-id'] == comment_id: |
155 | 329 | msg_date = self._getDateForComment(parsed_comment) | 329 | msg_date = self._getDateForComment(parsed_comment) |
156 | 330 | message = getUtility(IMessageSet).fromEmail(comment, poster, | 330 | message = getUtility(IMessageSet).fromEmail(comment, poster, |
157 | diff --git a/lib/lp/bugs/scripts/debbugs.py b/lib/lp/bugs/scripts/debbugs.py | |||
158 | index 81055c1..d693df1 100644 | |||
159 | --- a/lib/lp/bugs/scripts/debbugs.py | |||
160 | +++ b/lib/lp/bugs/scripts/debbugs.py | |||
161 | @@ -11,8 +11,6 @@ import sys | |||
162 | 11 | 11 | ||
163 | 12 | import six | 12 | import six |
164 | 13 | 13 | ||
165 | 14 | from lp.services.compat import message_from_bytes | ||
166 | 15 | |||
167 | 16 | 14 | ||
168 | 17 | class Bug: | 15 | class Bug: |
169 | 18 | def __init__(self, db, id, package=None, date=None, status=None, | 16 | def __init__(self, db, id, package=None, date=None, status=None, |
170 | @@ -59,7 +57,7 @@ class Bug: | |||
171 | 59 | if self._emails: | 57 | if self._emails: |
172 | 60 | return self._emails | 58 | return self._emails |
173 | 61 | for comment in self.comments: | 59 | for comment in self.comments: |
175 | 62 | message = message_from_bytes(comment) | 60 | message = email.message_from_bytes(comment) |
176 | 63 | self._emails.append(message) | 61 | self._emails.append(message) |
177 | 64 | return self._emails | 62 | return self._emails |
178 | 65 | 63 | ||
179 | @@ -207,7 +205,7 @@ class Database: | |||
180 | 207 | bug.report = fd.read() | 205 | bug.report = fd.read() |
181 | 208 | fd.close() | 206 | fd.close() |
182 | 209 | 207 | ||
184 | 210 | report_msg = message_from_bytes(bug.report) | 208 | report_msg = email.message_from_bytes(bug.report) |
185 | 211 | charset = report_msg.get_content_charset('ascii') | 209 | charset = report_msg.get_content_charset('ascii') |
186 | 212 | description = report_msg.get_payload(decode=True) | 210 | description = report_msg.get_payload(decode=True) |
187 | 213 | bug.description = description.decode(charset) | 211 | bug.description = description.decode(charset) |
188 | diff --git a/lib/lp/bugs/tests/bugs-emailinterface.txt b/lib/lp/bugs/tests/bugs-emailinterface.txt | |||
189 | index 452b6bf..94d9412 100644 | |||
190 | --- a/lib/lp/bugs/tests/bugs-emailinterface.txt | |||
191 | +++ b/lib/lp/bugs/tests/bugs-emailinterface.txt | |||
192 | @@ -70,11 +70,11 @@ we'll have to authenticate the user manually: | |||
193 | 70 | Now if we pass the message to the Malone handler, we can see that the | 70 | Now if we pass the message to the Malone handler, we can see that the |
194 | 71 | bug got submitted correctly: | 71 | bug got submitted correctly: |
195 | 72 | 72 | ||
196 | 73 | >>> import email | ||
197 | 73 | >>> from lp.bugs.mail.handler import MaloneHandler | 74 | >>> from lp.bugs.mail.handler import MaloneHandler |
198 | 74 | >>> from lp.services.compat import message_from_bytes | ||
199 | 75 | >>> handler = MaloneHandler() | 75 | >>> handler = MaloneHandler() |
200 | 76 | >>> def construct_email(raw_mail): | 76 | >>> def construct_email(raw_mail): |
202 | 77 | ... msg = message_from_bytes(raw_mail, _class=MockSignedMessage) | 77 | ... msg = email.message_from_bytes(raw_mail, _class=MockSignedMessage) |
203 | 78 | ... if 'Message-Id' not in msg: | 78 | ... if 'Message-Id' not in msg: |
204 | 79 | ... msg['Message-Id'] = factory.makeUniqueRFC822MsgId() | 79 | ... msg['Message-Id'] = factory.makeUniqueRFC822MsgId() |
205 | 80 | ... return msg | 80 | ... return msg |
206 | @@ -356,7 +356,7 @@ And the person sending the email has received an error message. | |||
207 | 356 | ... if not stub.test_emails: | 356 | ... if not stub.test_emails: |
208 | 357 | ... raise AssertionError("No emails queued!") | 357 | ... raise AssertionError("No emails queued!") |
209 | 358 | ... from_addr, to_addrs, raw_message = stub.test_emails[-1] | 358 | ... from_addr, to_addrs, raw_message = stub.test_emails[-1] |
211 | 359 | ... sent_msg = message_from_bytes(raw_message) | 359 | ... sent_msg = email.message_from_bytes(raw_message) |
212 | 360 | ... error_mail, original_mail = sent_msg.get_payload() | 360 | ... error_mail, original_mail = sent_msg.get_payload() |
213 | 361 | ... print("Subject: %s" % sent_msg['Subject']) | 361 | ... print("Subject: %s" % sent_msg['Subject']) |
214 | 362 | ... print("To: %s" % ', '.join(to_addrs)) | 362 | ... print("To: %s" % ', '.join(to_addrs)) |
215 | @@ -456,7 +456,8 @@ The same will happen if we send the same email without signing it: | |||
216 | 456 | >>> class MockUnsignedMessage(email.message.Message): | 456 | >>> class MockUnsignedMessage(email.message.Message): |
217 | 457 | ... signedMessage = None | 457 | ... signedMessage = None |
218 | 458 | ... signature = None | 458 | ... signature = None |
220 | 459 | >>> msg = message_from_bytes(comment_mail, _class=MockUnsignedMessage) | 459 | >>> msg = email.message_from_bytes( |
221 | 460 | ... comment_mail, _class=MockUnsignedMessage) | ||
222 | 460 | >>> handler.process( | 461 | >>> handler.process( |
223 | 461 | ... msg, msg['To'], | 462 | ... msg, msg['To'], |
224 | 462 | ... ) | 463 | ... ) |
225 | @@ -2040,7 +2041,7 @@ Let's take a closer look at send_process_error_notification(), which is | |||
226 | 2040 | used to send the error messages. It needs the message that caused the | 2041 | used to send the error messages. It needs the message that caused the |
227 | 2041 | error, so let's create one. | 2042 | error, so let's create one. |
228 | 2042 | 2043 | ||
230 | 2043 | >>> test_msg = message_from_bytes(b"""From: foo.bar@canonical.com | 2044 | >>> test_msg = email.message_from_bytes(b"""From: foo.bar@canonical.com |
231 | 2044 | ... To: bugs@launchpad.net | 2045 | ... To: bugs@launchpad.net |
232 | 2045 | ... Message-Id: <original@msg> | 2046 | ... Message-Id: <original@msg> |
233 | 2046 | ... Subject: Original Message Subject | 2047 | ... Subject: Original Message Subject |
234 | @@ -2063,7 +2064,7 @@ The To and Subject headers got set to the values we provided: | |||
235 | 2063 | 2064 | ||
236 | 2064 | >>> transaction.commit() | 2065 | >>> transaction.commit() |
237 | 2065 | >>> from_addr, to_addrs, raw_message = stub.test_emails[-1] | 2066 | >>> from_addr, to_addrs, raw_message = stub.test_emails[-1] |
239 | 2066 | >>> sent_msg = message_from_bytes(raw_message) | 2067 | >>> sent_msg = email.message_from_bytes(raw_message) |
240 | 2067 | >>> sent_msg['To'] | 2068 | >>> sent_msg['To'] |
241 | 2068 | 'test@canonical.com' | 2069 | 'test@canonical.com' |
242 | 2069 | >>> sent_msg['Subject'] | 2070 | >>> sent_msg['Subject'] |
243 | @@ -2123,7 +2124,7 @@ the original message. | |||
244 | 2123 | ... max_return_size=max_return_size) | 2124 | ... max_return_size=max_return_size) |
245 | 2124 | >>> transaction.commit() | 2125 | >>> transaction.commit() |
246 | 2125 | >>> from_addr, to_addrs, raw_message = stub.test_emails[-1] | 2126 | >>> from_addr, to_addrs, raw_message = stub.test_emails[-1] |
248 | 2126 | >>> sent_msg = message_from_bytes(raw_message) | 2127 | >>> sent_msg = email.message_from_bytes(raw_message) |
249 | 2127 | >>> failure_msg, original_msg = sent_msg.get_payload() | 2128 | >>> failure_msg, original_msg = sent_msg.get_payload() |
250 | 2128 | >>> msg = original_msg.get_payload()[0] | 2129 | >>> msg = original_msg.get_payload()[0] |
251 | 2129 | 2130 | ||
252 | @@ -2220,7 +2221,7 @@ The 'subscribe' command failed, and the user is being notified of the | |||
253 | 2220 | failure in an email. | 2221 | failure in an email. |
254 | 2221 | 2222 | ||
255 | 2222 | >>> from_addr, to_addrs, raw_message = stub.test_emails[-1] | 2223 | >>> from_addr, to_addrs, raw_message = stub.test_emails[-1] |
257 | 2223 | >>> sent_msg = message_from_bytes(raw_message) | 2224 | >>> sent_msg = email.message_from_bytes(raw_message) |
258 | 2224 | >>> failure_msg, original_msg = sent_msg.get_payload() | 2225 | >>> failure_msg, original_msg = sent_msg.get_payload() |
259 | 2225 | >>> print(failure_msg.get_payload(decode=True).decode('UTF-8')) | 2226 | >>> print(failure_msg.get_payload(decode=True).decode('UTF-8')) |
260 | 2226 | An error occurred while processing a mail you sent to Launchpad's email | 2227 | An error occurred while processing a mail you sent to Launchpad's email |
261 | @@ -2268,7 +2269,7 @@ And the sender receives an email to let them know about the failing | |||
262 | 2268 | 'security' command. | 2269 | 'security' command. |
263 | 2269 | 2270 | ||
264 | 2270 | >>> from_addr, to_addrs, raw_message = stub.test_emails[-1] | 2271 | >>> from_addr, to_addrs, raw_message = stub.test_emails[-1] |
266 | 2271 | >>> sent_msg = message_from_bytes(raw_message) | 2272 | >>> sent_msg = email.message_from_bytes(raw_message) |
267 | 2272 | >>> failure_msg, original_msg = sent_msg.get_payload() | 2273 | >>> failure_msg, original_msg = sent_msg.get_payload() |
268 | 2273 | >>> print(failure_msg.get_payload(decode=True).decode('UTF-8')) | 2274 | >>> print(failure_msg.get_payload(decode=True).decode('UTF-8')) |
269 | 2274 | An error occurred while processing a mail you sent to Launchpad's email | 2275 | An error occurred while processing a mail you sent to Launchpad's email |
270 | diff --git a/lib/lp/bugs/utilities/filebugdataparser.py b/lib/lp/bugs/utilities/filebugdataparser.py | |||
271 | index 3b320be..4ffc0a1 100644 | |||
272 | --- a/lib/lp/bugs/utilities/filebugdataparser.py | |||
273 | +++ b/lib/lp/bugs/utilities/filebugdataparser.py | |||
274 | @@ -9,12 +9,12 @@ __all__ = [ | |||
275 | 9 | ] | 9 | ] |
276 | 10 | 10 | ||
277 | 11 | import base64 | 11 | import base64 |
278 | 12 | import email | ||
279 | 12 | import tempfile | 13 | import tempfile |
280 | 13 | 14 | ||
281 | 14 | import six | 15 | import six |
282 | 15 | 16 | ||
283 | 16 | from lp.bugs.model.bug import FileBugData | 17 | from lp.bugs.model.bug import FileBugData |
284 | 17 | from lp.services.compat import message_from_bytes | ||
285 | 18 | 18 | ||
286 | 19 | 19 | ||
287 | 20 | class FileBugDataParser: | 20 | class FileBugDataParser: |
288 | @@ -62,7 +62,7 @@ class FileBugDataParser: | |||
289 | 62 | header_text = self._consumeBytes(b'\n\n') | 62 | header_text = self._consumeBytes(b'\n\n') |
290 | 63 | # Use the email package to return a dict-like object of the | 63 | # Use the email package to return a dict-like object of the |
291 | 64 | # headers, so we don't have to parse the text ourselves. | 64 | # headers, so we don't have to parse the text ourselves. |
293 | 65 | return message_from_bytes(header_text) | 65 | return email.message_from_bytes(header_text) |
294 | 66 | 66 | ||
295 | 67 | def readLine(self): | 67 | def readLine(self): |
296 | 68 | """Read a line of the message.""" | 68 | """Read a line of the message.""" |
297 | diff --git a/lib/lp/code/doc/codeimport.txt b/lib/lp/code/doc/codeimport.txt | |||
298 | index 3856ed3..d5da426 100644 | |||
299 | --- a/lib/lp/code/doc/codeimport.txt | |||
300 | +++ b/lib/lp/code/doc/codeimport.txt | |||
301 | @@ -103,8 +103,8 @@ three members of the vcs-imports team. | |||
302 | 103 | >>> vcs_imports = getUtility(ILaunchpadCelebrities).vcs_imports | 103 | >>> vcs_imports = getUtility(ILaunchpadCelebrities).vcs_imports |
303 | 104 | >>> len(get_contact_email_addresses(vcs_imports)) | 104 | >>> len(get_contact_email_addresses(vcs_imports)) |
304 | 105 | 3 | 105 | 3 |
307 | 106 | >>> from lp.services.compat import message_from_bytes | 106 | >>> import email |
308 | 107 | >>> message = message_from_bytes(stub.test_emails[0][2]) | 107 | >>> message = email.message_from_bytes(stub.test_emails[0][2]) |
309 | 108 | >>> print(message['subject']) | 108 | >>> print(message['subject']) |
310 | 109 | New code import: ~import-person/widget/trunk-cvs | 109 | New code import: ~import-person/widget/trunk-cvs |
311 | 110 | >>> print(message['X-Launchpad-Message-Rationale']) | 110 | >>> print(message['X-Launchpad-Message-Rationale']) |
312 | diff --git a/lib/lp/code/mail/tests/test_codeimport.py b/lib/lp/code/mail/tests/test_codeimport.py | |||
313 | index 18ecb59..ee62761 100644 | |||
314 | --- a/lib/lp/code/mail/tests/test_codeimport.py | |||
315 | +++ b/lib/lp/code/mail/tests/test_codeimport.py | |||
316 | @@ -3,6 +3,7 @@ | |||
317 | 3 | 3 | ||
318 | 4 | """Tests for code import related mailings""" | 4 | """Tests for code import related mailings""" |
319 | 5 | 5 | ||
320 | 6 | import email | ||
321 | 6 | import textwrap | 7 | import textwrap |
322 | 7 | 8 | ||
323 | 8 | import six | 9 | import six |
324 | @@ -14,7 +15,6 @@ from lp.code.enums import ( | |||
325 | 14 | TargetRevisionControlSystems, | 15 | TargetRevisionControlSystems, |
326 | 15 | ) | 16 | ) |
327 | 16 | from lp.code.tests.helpers import GitHostingFixture | 17 | from lp.code.tests.helpers import GitHostingFixture |
328 | 17 | from lp.services.compat import message_from_bytes | ||
329 | 18 | from lp.services.mail import stub | 18 | from lp.services.mail import stub |
330 | 19 | from lp.testing import ( | 19 | from lp.testing import ( |
331 | 20 | login_celebrity, | 20 | login_celebrity, |
332 | @@ -40,7 +40,7 @@ class TestNewCodeImports(TestCaseWithFactory): | |||
333 | 40 | cvs_module='a_module', branch_name='import', | 40 | cvs_module='a_module', branch_name='import', |
334 | 41 | product=fooix, registrant=eric) | 41 | product=fooix, registrant=eric) |
335 | 42 | transaction.commit() | 42 | transaction.commit() |
337 | 43 | msg = message_from_bytes(stub.test_emails[0][2]) | 43 | msg = email.message_from_bytes(stub.test_emails[0][2]) |
338 | 44 | self.assertEqual('code-import', msg['X-Launchpad-Notification-Type']) | 44 | self.assertEqual('code-import', msg['X-Launchpad-Notification-Type']) |
339 | 45 | self.assertEqual('~eric/fooix/import', msg['X-Launchpad-Branch']) | 45 | self.assertEqual('~eric/fooix/import', msg['X-Launchpad-Branch']) |
340 | 46 | self.assertEqual( | 46 | self.assertEqual( |
341 | @@ -64,7 +64,7 @@ class TestNewCodeImports(TestCaseWithFactory): | |||
342 | 64 | branch_name='trunk', product=fooix, registrant=eric, | 64 | branch_name='trunk', product=fooix, registrant=eric, |
343 | 65 | rcs_type=RevisionControlSystems.BZR_SVN) | 65 | rcs_type=RevisionControlSystems.BZR_SVN) |
344 | 66 | transaction.commit() | 66 | transaction.commit() |
346 | 67 | msg = message_from_bytes(stub.test_emails[0][2]) | 67 | msg = email.message_from_bytes(stub.test_emails[0][2]) |
347 | 68 | self.assertEqual('code-import', msg['X-Launchpad-Notification-Type']) | 68 | self.assertEqual('code-import', msg['X-Launchpad-Notification-Type']) |
348 | 69 | self.assertEqual('~eric/fooix/trunk', msg['X-Launchpad-Branch']) | 69 | self.assertEqual('~eric/fooix/trunk', msg['X-Launchpad-Branch']) |
349 | 70 | self.assertEqual( | 70 | self.assertEqual( |
350 | @@ -87,7 +87,7 @@ class TestNewCodeImports(TestCaseWithFactory): | |||
351 | 87 | git_repo_url='git://git.example.com/fooix.git', | 87 | git_repo_url='git://git.example.com/fooix.git', |
352 | 88 | branch_name='master', product=fooix, registrant=eric) | 88 | branch_name='master', product=fooix, registrant=eric) |
353 | 89 | transaction.commit() | 89 | transaction.commit() |
355 | 90 | msg = message_from_bytes(stub.test_emails[0][2]) | 90 | msg = email.message_from_bytes(stub.test_emails[0][2]) |
356 | 91 | self.assertEqual('code-import', msg['X-Launchpad-Notification-Type']) | 91 | self.assertEqual('code-import', msg['X-Launchpad-Notification-Type']) |
357 | 92 | self.assertEqual('~eric/fooix/master', msg['X-Launchpad-Branch']) | 92 | self.assertEqual('~eric/fooix/master', msg['X-Launchpad-Branch']) |
358 | 93 | self.assertEqual( | 93 | self.assertEqual( |
359 | @@ -113,7 +113,7 @@ class TestNewCodeImports(TestCaseWithFactory): | |||
360 | 113 | branch_name=u'master', product=fooix, registrant=eric, | 113 | branch_name=u'master', product=fooix, registrant=eric, |
361 | 114 | target_rcs_type=TargetRevisionControlSystems.GIT) | 114 | target_rcs_type=TargetRevisionControlSystems.GIT) |
362 | 115 | transaction.commit() | 115 | transaction.commit() |
364 | 116 | msg = message_from_bytes(stub.test_emails[0][2]) | 116 | msg = email.message_from_bytes(stub.test_emails[0][2]) |
365 | 117 | self.assertEqual('code-import', msg['X-Launchpad-Notification-Type']) | 117 | self.assertEqual('code-import', msg['X-Launchpad-Notification-Type']) |
366 | 118 | self.assertEqual('~eric/fooix/+git/master', msg['X-Launchpad-Branch']) | 118 | self.assertEqual('~eric/fooix/+git/master', msg['X-Launchpad-Branch']) |
367 | 119 | self.assertEqual( | 119 | self.assertEqual( |
368 | @@ -141,7 +141,7 @@ class TestNewCodeImports(TestCaseWithFactory): | |||
369 | 141 | git_repo_url='git://git.example.com/fooix.git', | 141 | git_repo_url='git://git.example.com/fooix.git', |
370 | 142 | branch_name='master', sourcepackage=fooix, registrant=eric) | 142 | branch_name='master', sourcepackage=fooix, registrant=eric) |
371 | 143 | transaction.commit() | 143 | transaction.commit() |
373 | 144 | msg = message_from_bytes(stub.test_emails[0][2]) | 144 | msg = email.message_from_bytes(stub.test_emails[0][2]) |
374 | 145 | self.assertEqual('code-import', msg['X-Launchpad-Notification-Type']) | 145 | self.assertEqual('code-import', msg['X-Launchpad-Notification-Type']) |
375 | 146 | self.assertEqual( | 146 | self.assertEqual( |
376 | 147 | '~eric/foobuntu/manic/fooix/master', msg['X-Launchpad-Branch']) | 147 | '~eric/foobuntu/manic/fooix/master', msg['X-Launchpad-Branch']) |
377 | @@ -164,7 +164,7 @@ class TestUpdatedCodeImports(TestCaseWithFactory): | |||
378 | 164 | layer = DatabaseFunctionalLayer | 164 | layer = DatabaseFunctionalLayer |
379 | 165 | 165 | ||
380 | 166 | def assertSameDetailsEmail(self, details, unique_name): | 166 | def assertSameDetailsEmail(self, details, unique_name): |
382 | 167 | msg = message_from_bytes(stub.test_emails[0][2]) | 167 | msg = email.message_from_bytes(stub.test_emails[0][2]) |
383 | 168 | self.assertEqual( | 168 | self.assertEqual( |
384 | 169 | 'code-import-updated', msg['X-Launchpad-Notification-Type']) | 169 | 'code-import-updated', msg['X-Launchpad-Notification-Type']) |
385 | 170 | self.assertEqual(unique_name, msg['X-Launchpad-Branch']) | 170 | self.assertEqual(unique_name, msg['X-Launchpad-Branch']) |
386 | @@ -183,7 +183,7 @@ class TestUpdatedCodeImports(TestCaseWithFactory): | |||
387 | 183 | 183 | ||
388 | 184 | def assertDifferentDetailsEmail(self, old_details, new_details, | 184 | def assertDifferentDetailsEmail(self, old_details, new_details, |
389 | 185 | unique_name): | 185 | unique_name): |
391 | 186 | msg = message_from_bytes(stub.test_emails[0][2]) | 186 | msg = email.message_from_bytes(stub.test_emails[0][2]) |
392 | 187 | self.assertEqual( | 187 | self.assertEqual( |
393 | 188 | 'code-import-updated', msg['X-Launchpad-Notification-Type']) | 188 | 'code-import-updated', msg['X-Launchpad-Notification-Type']) |
394 | 189 | self.assertEqual(unique_name, msg['X-Launchpad-Branch']) | 189 | self.assertEqual(unique_name, msg['X-Launchpad-Branch']) |
395 | diff --git a/lib/lp/code/model/tests/test_gitrepository.py b/lib/lp/code/model/tests/test_gitrepository.py | |||
396 | index de296a7..6edeb1e 100644 | |||
397 | --- a/lib/lp/code/model/tests/test_gitrepository.py | |||
398 | +++ b/lib/lp/code/model/tests/test_gitrepository.py | |||
399 | @@ -13,6 +13,7 @@ from datetime import ( | |||
400 | 13 | datetime, | 13 | datetime, |
401 | 14 | timedelta, | 14 | timedelta, |
402 | 15 | ) | 15 | ) |
403 | 16 | import email | ||
404 | 16 | from functools import partial | 17 | from functools import partial |
405 | 17 | import hashlib | 18 | import hashlib |
406 | 18 | import json | 19 | import json |
407 | @@ -145,7 +146,6 @@ from lp.registry.interfaces.personociproject import IPersonOCIProjectFactory | |||
408 | 145 | from lp.registry.interfaces.personproduct import IPersonProductFactory | 146 | from lp.registry.interfaces.personproduct import IPersonProductFactory |
409 | 146 | from lp.registry.tests.test_accesspolicy import get_policies_for_artifact | 147 | from lp.registry.tests.test_accesspolicy import get_policies_for_artifact |
410 | 147 | from lp.services.authserver.xmlrpc import AuthServerAPIView | 148 | from lp.services.authserver.xmlrpc import AuthServerAPIView |
411 | 148 | from lp.services.compat import message_from_bytes | ||
412 | 149 | from lp.services.config import config | 149 | from lp.services.config import config |
413 | 150 | from lp.services.database.constants import UTC_NOW | 150 | from lp.services.database.constants import UTC_NOW |
414 | 151 | from lp.services.database.interfaces import IStore | 151 | from lp.services.database.interfaces import IStore |
415 | @@ -1326,7 +1326,7 @@ class TestGitRepositoryModificationNotifications(TestCaseWithFactory): | |||
416 | 1326 | getUtility(IGitRepositoryModifiedMailJobSource)).runAll() | 1326 | getUtility(IGitRepositoryModifiedMailJobSource)).runAll() |
417 | 1327 | bodies_by_recipient = {} | 1327 | bodies_by_recipient = {} |
418 | 1328 | for from_addr, to_addrs, message in stub.test_emails: | 1328 | for from_addr, to_addrs, message in stub.test_emails: |
420 | 1329 | body = message_from_bytes(message).get_payload(decode=True) | 1329 | body = email.message_from_bytes(message).get_payload(decode=True) |
421 | 1330 | for to_addr in to_addrs: | 1330 | for to_addr in to_addrs: |
422 | 1331 | bodies_by_recipient[to_addr] = six.ensure_text(body) | 1331 | bodies_by_recipient[to_addr] = six.ensure_text(body) |
423 | 1332 | # Both the owner and the unprivileged subscriber receive email. | 1332 | # Both the owner and the unprivileged subscriber receive email. |
424 | diff --git a/lib/lp/codehosting/scanner/tests/test_email.py b/lib/lp/codehosting/scanner/tests/test_email.py | |||
425 | index 3072ec2..34af406 100644 | |||
426 | --- a/lib/lp/codehosting/scanner/tests/test_email.py | |||
427 | +++ b/lib/lp/codehosting/scanner/tests/test_email.py | |||
428 | @@ -5,6 +5,7 @@ | |||
429 | 5 | 5 | ||
430 | 6 | __metaclass__ = type | 6 | __metaclass__ = type |
431 | 7 | 7 | ||
432 | 8 | import email | ||
433 | 8 | import os | 9 | import os |
434 | 9 | 10 | ||
435 | 10 | from breezy.uncommit import uncommit | 11 | from breezy.uncommit import uncommit |
436 | @@ -25,7 +26,6 @@ from lp.codehosting.scanner import events | |||
437 | 25 | from lp.codehosting.scanner.bzrsync import BzrSync | 26 | from lp.codehosting.scanner.bzrsync import BzrSync |
438 | 26 | from lp.codehosting.scanner.tests.test_bzrsync import BzrSyncTestCase | 27 | from lp.codehosting.scanner.tests.test_bzrsync import BzrSyncTestCase |
439 | 27 | from lp.registry.interfaces.person import IPersonSet | 28 | from lp.registry.interfaces.person import IPersonSet |
440 | 28 | from lp.services.compat import message_from_bytes | ||
441 | 29 | from lp.services.config import config | 29 | from lp.services.config import config |
442 | 30 | from lp.services.features.testing import FeatureFixture | 30 | from lp.services.features.testing import FeatureFixture |
443 | 31 | from lp.services.job.runner import JobRunner | 31 | from lp.services.job.runner import JobRunner |
444 | @@ -72,7 +72,7 @@ class TestBzrSyncEmail(BzrSyncTestCase): | |||
445 | 72 | self.assertEqual(len(stub.test_emails), 1) | 72 | self.assertEqual(len(stub.test_emails), 1) |
446 | 73 | [initial_email] = stub.test_emails | 73 | [initial_email] = stub.test_emails |
447 | 74 | expected = 'First scan of the branch detected 0 revisions' | 74 | expected = 'First scan of the branch detected 0 revisions' |
449 | 75 | message = message_from_bytes(initial_email[2]) | 75 | message = email.message_from_bytes(initial_email[2]) |
450 | 76 | email_body = message.get_payload() | 76 | email_body = message.get_payload() |
451 | 77 | self.assertIn(expected, email_body) | 77 | self.assertIn(expected, email_body) |
452 | 78 | self.assertEmailHeadersEqual( | 78 | self.assertEmailHeadersEqual( |
453 | @@ -87,7 +87,7 @@ class TestBzrSyncEmail(BzrSyncTestCase): | |||
454 | 87 | [initial_email] = stub.test_emails | 87 | [initial_email] = stub.test_emails |
455 | 88 | expected = ('First scan of the branch detected 1 revision' | 88 | expected = ('First scan of the branch detected 1 revision' |
456 | 89 | ' in the revision history of the=\n branch.') | 89 | ' in the revision history of the=\n branch.') |
458 | 90 | message = message_from_bytes(initial_email[2]) | 90 | message = email.message_from_bytes(initial_email[2]) |
459 | 91 | email_body = message.get_payload() | 91 | email_body = message.get_payload() |
460 | 92 | self.assertIn(expected, email_body) | 92 | self.assertIn(expected, email_body) |
461 | 93 | self.assertEmailHeadersEqual( | 93 | self.assertEmailHeadersEqual( |
462 | @@ -105,7 +105,7 @@ class TestBzrSyncEmail(BzrSyncTestCase): | |||
463 | 105 | self.assertEqual(len(stub.test_emails), 1) | 105 | self.assertEqual(len(stub.test_emails), 1) |
464 | 106 | [uncommit_email] = stub.test_emails | 106 | [uncommit_email] = stub.test_emails |
465 | 107 | expected = '1 revision was removed from the branch.' | 107 | expected = '1 revision was removed from the branch.' |
467 | 108 | message = message_from_bytes(uncommit_email[2]) | 108 | message = email.message_from_bytes(uncommit_email[2]) |
468 | 109 | email_body = message.get_payload() | 109 | email_body = message.get_payload() |
469 | 110 | self.assertIn(expected, email_body) | 110 | self.assertIn(expected, email_body) |
470 | 111 | self.assertEmailHeadersEqual( | 111 | self.assertEmailHeadersEqual( |
471 | @@ -137,7 +137,7 @@ class TestBzrSyncEmail(BzrSyncTestCase): | |||
472 | 137 | 'Subject: [Branch %s] Test branch' % self.db_branch.unique_name) | 137 | 'Subject: [Branch %s] Test branch' % self.db_branch.unique_name) |
473 | 138 | self.assertIn(expected, uncommit_email_body) | 138 | self.assertIn(expected, uncommit_email_body) |
474 | 139 | 139 | ||
476 | 140 | recommit_email_msg = message_from_bytes(recommit_email[2]) | 140 | recommit_email_msg = email.message_from_bytes(recommit_email[2]) |
477 | 141 | recommit_email_body = recommit_email_msg.get_payload()[0].get_payload( | 141 | recommit_email_body = recommit_email_msg.get_payload()[0].get_payload( |
478 | 142 | decode=True) | 142 | decode=True) |
479 | 143 | subject = '[Branch %s] Rev 1: second' % self.db_branch.unique_name | 143 | subject = '[Branch %s] Rev 1: second' % self.db_branch.unique_name |
480 | diff --git a/lib/lp/registry/browser/tests/test_person.py b/lib/lp/registry/browser/tests/test_person.py | |||
481 | index 2b015ce..b21e38e 100644 | |||
482 | --- a/lib/lp/registry/browser/tests/test_person.py | |||
483 | +++ b/lib/lp/registry/browser/tests/test_person.py | |||
484 | @@ -5,6 +5,7 @@ | |||
485 | 5 | __metaclass__ = type | 5 | __metaclass__ = type |
486 | 6 | 6 | ||
487 | 7 | import doctest | 7 | import doctest |
488 | 8 | import email | ||
489 | 8 | from operator import attrgetter | 9 | from operator import attrgetter |
490 | 9 | import re | 10 | import re |
491 | 10 | from textwrap import dedent | 11 | from textwrap import dedent |
492 | @@ -67,7 +68,6 @@ from lp.registry.interfaces.teammembership import ( | |||
493 | 67 | from lp.registry.model.karma import KarmaCategory | 68 | from lp.registry.model.karma import KarmaCategory |
494 | 68 | from lp.registry.model.milestone import milestone_sort_key | 69 | from lp.registry.model.milestone import milestone_sort_key |
495 | 69 | from lp.scripts.garbo import PopulateLatestPersonSourcePackageReleaseCache | 70 | from lp.scripts.garbo import PopulateLatestPersonSourcePackageReleaseCache |
496 | 70 | from lp.services.compat import message_from_bytes | ||
497 | 71 | from lp.services.config import config | 71 | from lp.services.config import config |
498 | 72 | from lp.services.database.interfaces import IStore | 72 | from lp.services.database.interfaces import IStore |
499 | 73 | from lp.services.features.testing import FeatureFixture | 73 | from lp.services.features.testing import FeatureFixture |
500 | @@ -938,7 +938,7 @@ class TestPersonEditView(TestPersonRenameFormMixin, TestCaseWithFactory): | |||
501 | 938 | messages = [msg for from_addr, to_addr, msg in stub.test_emails] | 938 | messages = [msg for from_addr, to_addr, msg in stub.test_emails] |
502 | 939 | raw_msg = None | 939 | raw_msg = None |
503 | 940 | for orig_msg in messages: | 940 | for orig_msg in messages: |
505 | 941 | msg = message_from_bytes(orig_msg) | 941 | msg = email.message_from_bytes(orig_msg) |
506 | 942 | if msg.get('to') == added_email: | 942 | if msg.get('to') == added_email: |
507 | 943 | raw_msg = orig_msg | 943 | raw_msg = orig_msg |
508 | 944 | token_url = get_token_url_from_email(raw_msg) | 944 | token_url = get_token_url_from_email(raw_msg) |
509 | diff --git a/lib/lp/registry/doc/distribution-mirror.txt b/lib/lp/registry/doc/distribution-mirror.txt | |||
510 | index 29c35dc..8939a83 100644 | |||
511 | --- a/lib/lp/registry/doc/distribution-mirror.txt | |||
512 | +++ b/lib/lp/registry/doc/distribution-mirror.txt | |||
513 | @@ -364,7 +364,7 @@ up on the public mirror listings. | |||
514 | 364 | >>> import transaction | 364 | >>> import transaction |
515 | 365 | >>> transaction.commit() | 365 | >>> transaction.commit() |
516 | 366 | 366 | ||
518 | 367 | >>> from lp.services.compat import message_from_bytes | 367 | >>> import email |
519 | 368 | >>> from lp.services.mail import stub | 368 | >>> from lp.services.mail import stub |
520 | 369 | >>> len(stub.test_emails) | 369 | >>> len(stub.test_emails) |
521 | 370 | 2 | 370 | 2 |
522 | @@ -377,7 +377,7 @@ up on the public mirror listings. | |||
523 | 377 | ['mark@example.com'] | 377 | ['mark@example.com'] |
524 | 378 | >>> valid_mirror.enabled | 378 | >>> valid_mirror.enabled |
525 | 379 | False | 379 | False |
527 | 380 | >>> msg = message_from_bytes(raw_message) | 380 | >>> msg = email.message_from_bytes(raw_message) |
528 | 381 | >>> print(msg.get_payload()) | 381 | >>> print(msg.get_payload()) |
529 | 382 | Dear mirror administrator, | 382 | Dear mirror administrator, |
530 | 383 | <BLANKLINE> | 383 | <BLANKLINE> |
531 | diff --git a/lib/lp/registry/stories/gpg-coc/xx-gpg-coc.txt b/lib/lp/registry/stories/gpg-coc/xx-gpg-coc.txt | |||
532 | index 09342e8..1b81c27 100644 | |||
533 | --- a/lib/lp/registry/stories/gpg-coc/xx-gpg-coc.txt | |||
534 | +++ b/lib/lp/registry/stories/gpg-coc/xx-gpg-coc.txt | |||
535 | @@ -5,9 +5,9 @@ Claiming GPG Keys | |||
536 | 5 | Setup | 5 | Setup |
537 | 6 | ----- | 6 | ----- |
538 | 7 | 7 | ||
539 | 8 | >>> import email | ||
540 | 8 | >>> from zope.component import getUtility | 9 | >>> from zope.component import getUtility |
541 | 9 | >>> from lp.registry.interfaces.person import IPersonSet | 10 | >>> from lp.registry.interfaces.person import IPersonSet |
542 | 10 | >>> from lp.services.compat import message_from_bytes | ||
543 | 11 | >>> from lp.services.mail import stub | 11 | >>> from lp.services.mail import stub |
544 | 12 | >>> from lp.testing.keyserver import KeyServerTac | 12 | >>> from lp.testing.keyserver import KeyServerTac |
545 | 13 | >>> from lp.testing.pages import setupBrowserFreshLogin | 13 | >>> from lp.testing.pages import setupBrowserFreshLogin |
546 | @@ -56,7 +56,7 @@ text part that provides useful information to users who -- for whatever reason | |||
547 | 56 | -- cannot decrypt the token url. Start by grabbing the confirmation message. | 56 | -- cannot decrypt the token url. Start by grabbing the confirmation message. |
548 | 57 | 57 | ||
549 | 58 | >>> from_addr, to_addrs, raw_msg = stub.test_emails.pop() | 58 | >>> from_addr, to_addrs, raw_msg = stub.test_emails.pop() |
551 | 59 | >>> msg = message_from_bytes(raw_msg) | 59 | >>> msg = email.message_from_bytes(raw_msg) |
552 | 60 | >>> msg.get_content_type() | 60 | >>> msg.get_content_type() |
553 | 61 | 'text/plain' | 61 | 'text/plain' |
554 | 62 | 62 | ||
555 | @@ -178,7 +178,7 @@ their Launchpad account. | |||
556 | 178 | Sample Person checks their email. | 178 | Sample Person checks their email. |
557 | 179 | 179 | ||
558 | 180 | >>> from_addr, to_addrs, raw_msg = stub.test_emails.pop() | 180 | >>> from_addr, to_addrs, raw_msg = stub.test_emails.pop() |
560 | 181 | >>> msg = message_from_bytes(raw_msg) | 181 | >>> msg = email.message_from_bytes(raw_msg) |
561 | 182 | >>> msg.get_content_type() | 182 | >>> msg.get_content_type() |
562 | 183 | 'text/plain' | 183 | 'text/plain' |
563 | 184 | >>> body = msg.get_payload(decode=True) | 184 | >>> body = msg.get_payload(decode=True) |
564 | @@ -512,7 +512,7 @@ Get the token from the body of the email sent. | |||
565 | 512 | >>> import re | 512 | >>> import re |
566 | 513 | >>> from lp.services.mail import stub | 513 | >>> from lp.services.mail import stub |
567 | 514 | >>> from_addr, to_addrs, raw_msg = stub.test_emails.pop() | 514 | >>> from_addr, to_addrs, raw_msg = stub.test_emails.pop() |
569 | 515 | >>> msg = message_from_bytes(raw_msg) | 515 | >>> msg = email.message_from_bytes(raw_msg) |
570 | 516 | >>> cipher_body = msg.get_payload(decode=1) | 516 | >>> cipher_body = msg.get_payload(decode=1) |
571 | 517 | >>> body = decrypt_content(cipher_body, six.ensure_str('test')) | 517 | >>> body = decrypt_content(cipher_body, six.ensure_str('test')) |
572 | 518 | >>> link = get_token_url_from_bytes(body) | 518 | >>> link = get_token_url_from_bytes(body) |
573 | @@ -628,7 +628,7 @@ Test if the advertisement email was sent: | |||
574 | 628 | 628 | ||
575 | 629 | >>> from lp.services.mail import stub | 629 | >>> from lp.services.mail import stub |
576 | 630 | >>> from_addr, to_addrs, raw_msg = stub.test_emails.pop() | 630 | >>> from_addr, to_addrs, raw_msg = stub.test_emails.pop() |
578 | 631 | >>> msg = message_from_bytes(raw_msg) | 631 | >>> msg = email.message_from_bytes(raw_msg) |
579 | 632 | >>> print(six.ensure_text(msg.get_payload(decode=True))) | 632 | >>> print(six.ensure_text(msg.get_payload(decode=True))) |
580 | 633 | <BLANKLINE> | 633 | <BLANKLINE> |
581 | 634 | ... | 634 | ... |
582 | diff --git a/lib/lp/registry/stories/mailinglists/hosted-email-address.txt b/lib/lp/registry/stories/mailinglists/hosted-email-address.txt | |||
583 | index 9952c67..3853b24 100644 | |||
584 | --- a/lib/lp/registry/stories/mailinglists/hosted-email-address.txt | |||
585 | +++ b/lib/lp/registry/stories/mailinglists/hosted-email-address.txt | |||
586 | @@ -46,8 +46,8 @@ Launchpad sends that address a confirmation message. | |||
587 | 46 | >>> from_addr, to_addrs, raw_msg = stub.test_emails.pop() | 46 | >>> from_addr, to_addrs, raw_msg = stub.test_emails.pop() |
588 | 47 | >>> stub.test_emails | 47 | >>> stub.test_emails |
589 | 48 | [] | 48 | [] |
592 | 49 | >>> from lp.services.compat import message_from_bytes | 49 | >>> import email |
593 | 50 | >>> msg = message_from_bytes(raw_msg) | 50 | >>> msg = email.message_from_bytes(raw_msg) |
594 | 51 | >>> print(msg['From']) | 51 | >>> print(msg['From']) |
595 | 52 | Launchpad Email Validator <noreply@launchpad.net> | 52 | Launchpad Email Validator <noreply@launchpad.net> |
596 | 53 | >>> print(msg['Subject']) | 53 | >>> print(msg['Subject']) |
597 | diff --git a/lib/lp/registry/stories/person/xx-add-sshkey.txt b/lib/lp/registry/stories/person/xx-add-sshkey.txt | |||
598 | index c58405f..8c1095d 100644 | |||
599 | --- a/lib/lp/registry/stories/person/xx-add-sshkey.txt | |||
600 | +++ b/lib/lp/registry/stories/person/xx-add-sshkey.txt | |||
601 | @@ -225,7 +225,7 @@ this case we'll raise an UnexpectedFormData. | |||
602 | 225 | If he removes a key then he will get a security warning email notification | 225 | If he removes a key then he will get a security warning email notification |
603 | 226 | that the key has been removed. | 226 | that the key has been removed. |
604 | 227 | 227 | ||
606 | 228 | >>> from lp.services.compat import message_from_bytes | 228 | >>> import email |
607 | 229 | >>> from lp.services.mail import stub | 229 | >>> from lp.services.mail import stub |
608 | 230 | >>> stub.test_emails = [] | 230 | >>> stub.test_emails = [] |
609 | 231 | >>> browser.open('http://launchpad.test/~salgado/+editsshkeys') | 231 | >>> browser.open('http://launchpad.test/~salgado/+editsshkeys') |
610 | @@ -233,7 +233,7 @@ that the key has been removed. | |||
611 | 233 | >>> from_addr, to_addr, msg = stub.test_emails.pop() | 233 | >>> from_addr, to_addr, msg = stub.test_emails.pop() |
612 | 234 | >>> to_addr | 234 | >>> to_addr |
613 | 235 | ['guilherme.salgado@canonical.com'] | 235 | ['guilherme.salgado@canonical.com'] |
615 | 236 | >>> payload = message_from_bytes(msg).get_payload() | 236 | >>> payload = email.message_from_bytes(msg).get_payload() |
616 | 237 | >>> assert payload.startswith('The SSH Key') | 237 | >>> assert payload.startswith('The SSH Key') |
617 | 238 | 238 | ||
618 | 239 | 239 | ||
619 | diff --git a/lib/lp/registry/tests/test_mailinglistapi.py b/lib/lp/registry/tests/test_mailinglistapi.py | |||
620 | index 256bbfa..ec689eb 100644 | |||
621 | --- a/lib/lp/registry/tests/test_mailinglistapi.py | |||
622 | +++ b/lib/lp/registry/tests/test_mailinglistapi.py | |||
623 | @@ -6,7 +6,7 @@ | |||
624 | 6 | __metaclass__ = type | 6 | __metaclass__ = type |
625 | 7 | __all__ = [] | 7 | __all__ = [] |
626 | 8 | 8 | ||
628 | 9 | from email import message_from_string | 9 | import email |
629 | 10 | from textwrap import dedent | 10 | from textwrap import dedent |
630 | 11 | 11 | ||
631 | 12 | from six.moves import xmlrpc_client | 12 | from six.moves import xmlrpc_client |
632 | @@ -36,10 +36,7 @@ from lp.registry.xmlrpc.mailinglist import ( | |||
633 | 36 | ENABLED, | 36 | ENABLED, |
634 | 37 | MailingListAPIView, | 37 | MailingListAPIView, |
635 | 38 | ) | 38 | ) |
640 | 39 | from lp.services.compat import ( | 39 | from lp.services.compat import message_as_bytes |
637 | 40 | message_as_bytes, | ||
638 | 41 | message_from_bytes, | ||
639 | 42 | ) | ||
641 | 43 | from lp.services.config import config | 40 | from lp.services.config import config |
642 | 44 | from lp.services.identity.interfaces.account import AccountStatus | 41 | from lp.services.identity.interfaces.account import AccountStatus |
643 | 45 | from lp.services.identity.interfaces.emailaddress import ( | 42 | from lp.services.identity.interfaces.emailaddress import ( |
644 | @@ -449,7 +446,7 @@ class MailingListAPIMessageTestCase(TestCaseWithFactory): | |||
645 | 449 | self.factory.makeMailingList(team, owner) | 446 | self.factory.makeMailingList(team, owner) |
646 | 450 | sender = self.factory.makePerson(email='me@eg.dom') | 447 | sender = self.factory.makePerson(email='me@eg.dom') |
647 | 451 | with person_logged_in(sender): | 448 | with person_logged_in(sender): |
649 | 452 | message = message_from_string(dedent("""\ | 449 | message = email.message_from_string(dedent("""\ |
650 | 453 | From: me@eg.dom | 450 | From: me@eg.dom |
651 | 454 | To: team@lists.launchpad.test | 451 | To: team@lists.launchpad.test |
652 | 455 | Subject: A question | 452 | Subject: A question |
653 | @@ -493,7 +490,7 @@ class MailingListAPIMessageTestCase(TestCaseWithFactory): | |||
654 | 493 | # Non-ascii messages headers are re-encoded for moderators. | 490 | # Non-ascii messages headers are re-encoded for moderators. |
655 | 494 | team, sender, message = self.makeMailingListAndHeldMessage() | 491 | team, sender, message = self.makeMailingListAndHeldMessage() |
656 | 495 | with person_logged_in(sender): | 492 | with person_logged_in(sender): |
658 | 496 | message = message_from_bytes(dedent("""\ | 493 | message = email.message_from_bytes(dedent("""\ |
659 | 497 | From: \xa9 me <me@eg.dom> | 494 | From: \xa9 me <me@eg.dom> |
660 | 498 | To: team@lists.launchpad.test | 495 | To: team@lists.launchpad.test |
661 | 499 | Subject: \xa9 gremlins | 496 | Subject: \xa9 gremlins |
662 | diff --git a/lib/lp/services/compat.py b/lib/lp/services/compat.py | |||
663 | index 88df437..835b123 100644 | |||
664 | --- a/lib/lp/services/compat.py | |||
665 | +++ b/lib/lp/services/compat.py | |||
666 | @@ -10,15 +10,9 @@ __metaclass__ = type | |||
667 | 10 | __all__ = [ | 10 | __all__ = [ |
668 | 11 | 'escape', | 11 | 'escape', |
669 | 12 | 'message_as_bytes', | 12 | 'message_as_bytes', |
670 | 13 | 'message_from_bytes', | ||
671 | 14 | ] | 13 | ] |
672 | 15 | 14 | ||
673 | 16 | try: | 15 | try: |
674 | 17 | from email import message_from_bytes | ||
675 | 18 | except ImportError: | ||
676 | 19 | from email import message_from_string as message_from_bytes | ||
677 | 20 | |||
678 | 21 | try: | ||
679 | 22 | from html import escape | 16 | from html import escape |
680 | 23 | except ImportError: | 17 | except ImportError: |
681 | 24 | from cgi import escape | 18 | from cgi import escape |
682 | diff --git a/lib/lp/services/mail/doc/emailauthentication.txt b/lib/lp/services/mail/doc/emailauthentication.txt | |||
683 | index efcdce9..8cd8a8b 100644 | |||
684 | --- a/lib/lp/services/mail/doc/emailauthentication.txt | |||
685 | +++ b/lib/lp/services/mail/doc/emailauthentication.txt | |||
686 | @@ -108,14 +108,11 @@ be canonicalised to \r\n. In order to ensure that the line endings in | |||
687 | 108 | signed_canonicalised.txt are not already '\r\n', we recreate the test | 108 | signed_canonicalised.txt are not already '\r\n', we recreate the test |
688 | 109 | message. | 109 | message. |
689 | 110 | 110 | ||
694 | 111 | >>> from lp.services.compat import ( | 111 | >>> from lp.services.compat import message_as_bytes |
691 | 112 | ... message_as_bytes, | ||
692 | 113 | ... message_from_bytes, | ||
693 | 114 | ... ) | ||
695 | 115 | >>> from lp.services.mail.signedmessage import SignedMessage | 112 | >>> from lp.services.mail.signedmessage import SignedMessage |
696 | 116 | >>> msg = read_test_message('signed_canonicalised.txt') | 113 | >>> msg = read_test_message('signed_canonicalised.txt') |
697 | 117 | >>> msg_lines = message_as_bytes(msg).splitlines() | 114 | >>> msg_lines = message_as_bytes(msg).splitlines() |
699 | 118 | >>> msg = message_from_bytes( | 115 | >>> msg = email.message_from_bytes( |
700 | 119 | ... b'\n'.join(msg_lines), _class=SignedMessage) | 116 | ... b'\n'.join(msg_lines), _class=SignedMessage) |
701 | 120 | >>> msg.parsed_bytes = message_as_bytes(msg) | 117 | >>> msg.parsed_bytes = message_as_bytes(msg) |
702 | 121 | 118 | ||
703 | @@ -135,7 +132,7 @@ authenticateEmail() doesn't have any problems verifying the signature: | |||
704 | 135 | 132 | ||
705 | 136 | >>> from lp.registry.interfaces.person import IPerson | 133 | >>> from lp.registry.interfaces.person import IPerson |
706 | 137 | >>> for line_ending in b'\n', b'\r\n': | 134 | >>> for line_ending in b'\n', b'\r\n': |
708 | 138 | ... msg = message_from_bytes( | 135 | ... msg = email.message_from_bytes( |
709 | 139 | ... line_ending.join(msg_lines), _class=SignedMessage) | 136 | ... line_ending.join(msg_lines), _class=SignedMessage) |
710 | 140 | ... msg.parsed_bytes = message_as_bytes(msg) | 137 | ... msg.parsed_bytes = message_as_bytes(msg) |
711 | 141 | ... principal = authenticateEmail(msg, accept_any_timestamp) | 138 | ... principal = authenticateEmail(msg, accept_any_timestamp) |
712 | diff --git a/lib/lp/services/mail/doc/mailbox.txt b/lib/lp/services/mail/doc/mailbox.txt | |||
713 | index aa9ac88..6424f2d 100644 | |||
714 | --- a/lib/lp/services/mail/doc/mailbox.txt | |||
715 | +++ b/lib/lp/services/mail/doc/mailbox.txt | |||
716 | @@ -74,8 +74,8 @@ before: | |||
717 | 74 | >>> len(mails) | 74 | >>> len(mails) |
718 | 75 | 2 | 75 | 2 |
719 | 76 | >>> id, raw_mail = mails[0] | 76 | >>> id, raw_mail = mails[0] |
722 | 77 | >>> from lp.services.compat import message_from_bytes | 77 | >>> import email |
723 | 78 | >>> mail = message_from_bytes(raw_mail) | 78 | >>> mail = email.message_from_bytes(raw_mail) |
724 | 79 | >>> print(mail['Message-ID']) | 79 | >>> print(mail['Message-ID']) |
725 | 80 | <test1> | 80 | <test1> |
726 | 81 | 81 | ||
727 | @@ -90,7 +90,7 @@ Since we didn't delete the mail, it's still in there: | |||
728 | 90 | >>> len(mails) | 90 | >>> len(mails) |
729 | 91 | 2 | 91 | 2 |
730 | 92 | >>> id, raw_mail = mails[0] | 92 | >>> id, raw_mail = mails[0] |
732 | 93 | >>> mail = message_from_bytes(raw_mail) | 93 | >>> mail = email.message_from_bytes(raw_mail) |
733 | 94 | >>> print(mail['Message-ID']) | 94 | >>> print(mail['Message-ID']) |
734 | 95 | <test1> | 95 | <test1> |
735 | 96 | 96 | ||
736 | diff --git a/lib/lp/services/mail/doc/sending-mail.txt b/lib/lp/services/mail/doc/sending-mail.txt | |||
737 | index de0483f..b520983 100644 | |||
738 | --- a/lib/lp/services/mail/doc/sending-mail.txt | |||
739 | +++ b/lib/lp/services/mail/doc/sending-mail.txt | |||
740 | @@ -17,10 +17,10 @@ The mail get sent when the transaction gets commited: | |||
741 | 17 | 17 | ||
742 | 18 | Now let's look at the sent email: | 18 | Now let's look at the sent email: |
743 | 19 | 19 | ||
745 | 20 | >>> from lp.services.compat import message_from_bytes | 20 | >>> import email |
746 | 21 | >>> from lp.services.mail import stub | 21 | >>> from lp.services.mail import stub |
747 | 22 | >>> from_addr, to_addr, raw_message = stub.test_emails.pop() | 22 | >>> from_addr, to_addr, raw_message = stub.test_emails.pop() |
749 | 23 | >>> msg = message_from_bytes(raw_message) | 23 | >>> msg = email.message_from_bytes(raw_message) |
750 | 24 | >>> msg['To'] | 24 | >>> msg['To'] |
751 | 25 | 'test@canonical.com' | 25 | 'test@canonical.com' |
752 | 26 | >>> msg['From'] | 26 | >>> msg['From'] |
753 | @@ -52,7 +52,7 @@ the person's name is encoded properly. | |||
754 | 52 | 52 | ||
755 | 53 | >>> transaction.commit() | 53 | >>> transaction.commit() |
756 | 54 | >>> from_addr, to_addr, raw_message = stub.test_emails.pop() | 54 | >>> from_addr, to_addr, raw_message = stub.test_emails.pop() |
758 | 55 | >>> msg = message_from_bytes(raw_message) | 55 | >>> msg = email.message_from_bytes(raw_message) |
759 | 56 | >>> msg['To'] | 56 | >>> msg['To'] |
760 | 57 | 'test@canonical.com' | 57 | 'test@canonical.com' |
761 | 58 | >>> msg['From'] | 58 | >>> msg['From'] |
762 | @@ -86,7 +86,7 @@ simple_sendmail_from_person uses the Person's preferred email address: | |||
763 | 86 | >>> transaction.commit() | 86 | >>> transaction.commit() |
764 | 87 | >>> found = False | 87 | >>> found = False |
765 | 88 | >>> for from_addr, to_addr, raw_message in stub.test_emails: | 88 | >>> for from_addr, to_addr, raw_message in stub.test_emails: |
767 | 89 | ... msg = message_from_bytes(raw_message) | 89 | ... msg = email.message_from_bytes(raw_message) |
768 | 90 | ... if msg['From'] == 'Sample Person <testing@canonical.com>': | 90 | ... if msg['From'] == 'Sample Person <testing@canonical.com>': |
769 | 91 | ... found = True | 91 | ... found = True |
770 | 92 | >>> assert found | 92 | >>> assert found |
771 | @@ -109,7 +109,7 @@ the header will appear more than once in the output message. | |||
772 | 109 | >>> transaction.commit() | 109 | >>> transaction.commit() |
773 | 110 | 110 | ||
774 | 111 | >>> from_addr, to_addr, raw_message = stub.test_emails.pop() | 111 | >>> from_addr, to_addr, raw_message = stub.test_emails.pop() |
776 | 112 | >>> msg = message_from_bytes(raw_message) | 112 | >>> msg = email.message_from_bytes(raw_message) |
777 | 113 | >>> msg["X-Foo"] | 113 | >>> msg["X-Foo"] |
778 | 114 | 'test' | 114 | 'test' |
779 | 115 | >>> msg.get_all("X-Bar") | 115 | >>> msg.get_all("X-Bar") |
780 | @@ -129,7 +129,7 @@ only. | |||
781 | 129 | Now let's look at the sent email again. | 129 | Now let's look at the sent email again. |
782 | 130 | 130 | ||
783 | 131 | >>> from_addr, to_addr, raw_message = stub.test_emails.pop() | 131 | >>> from_addr, to_addr, raw_message = stub.test_emails.pop() |
785 | 132 | >>> msg = message_from_bytes(raw_message) | 132 | >>> msg = email.message_from_bytes(raw_message) |
786 | 133 | 133 | ||
787 | 134 | >>> from email.header import decode_header | 134 | >>> from email.header import decode_header |
788 | 135 | >>> subject_str, charset = decode_header(msg['Subject'])[0] | 135 | >>> subject_str, charset = decode_header(msg['Subject'])[0] |
789 | @@ -154,7 +154,7 @@ contain non-ASCII characters: | |||
790 | 154 | >>> transaction.commit() | 154 | >>> transaction.commit() |
791 | 155 | 155 | ||
792 | 156 | >>> from_addr, to_addr, raw_message = stub.test_emails.pop() | 156 | >>> from_addr, to_addr, raw_message = stub.test_emails.pop() |
794 | 157 | >>> msg = message_from_bytes(raw_message) | 157 | >>> msg = email.message_from_bytes(raw_message) |
795 | 158 | 158 | ||
796 | 159 | >>> from email.utils import parseaddr | 159 | >>> from email.utils import parseaddr |
797 | 160 | >>> from_name_encoded, from_addr = parseaddr(msg['From']) | 160 | >>> from_name_encoded, from_addr = parseaddr(msg['From']) |
798 | @@ -185,7 +185,7 @@ surrounded by quotes and quoted if necessary: | |||
799 | 185 | >>> transaction.commit() | 185 | >>> transaction.commit() |
800 | 186 | 186 | ||
801 | 187 | >>> from_addr, to_addr, raw_message = stub.test_emails.pop() | 187 | >>> from_addr, to_addr, raw_message = stub.test_emails.pop() |
803 | 188 | >>> msg = message_from_bytes(raw_message) | 188 | >>> msg = email.message_from_bytes(raw_message) |
804 | 189 | >>> parseaddr(msg['From']) | 189 | >>> parseaddr(msg['From']) |
805 | 190 | ('Foo [Baz] " Bar', 'foo.bar@canonical.com') | 190 | ('Foo [Baz] " Bar', 'foo.bar@canonical.com') |
806 | 191 | 191 | ||
807 | @@ -244,7 +244,7 @@ The message is the same as the one from the simple_sendmail test except | |||
808 | 244 | that the precedence header was not added. | 244 | that the precedence header was not added. |
809 | 245 | 245 | ||
810 | 246 | >>> from_addr, to_addr, raw_message = stub.test_emails.pop() | 246 | >>> from_addr, to_addr, raw_message = stub.test_emails.pop() |
812 | 247 | >>> msg = message_from_bytes(raw_message) | 247 | >>> msg = email.message_from_bytes(raw_message) |
813 | 248 | >>> msg['To'] | 248 | >>> msg['To'] |
814 | 249 | 'test@canonical.com' | 249 | 'test@canonical.com' |
815 | 250 | >>> msg['From'] | 250 | >>> msg['From'] |
816 | @@ -282,7 +282,7 @@ provide better bounce handling. | |||
817 | 282 | 282 | ||
818 | 283 | >>> from lp.services.config import config | 283 | >>> from lp.services.config import config |
819 | 284 | >>> from_addr, to_add, raw_message = stub.test_emails.pop() | 284 | >>> from_addr, to_add, raw_message = stub.test_emails.pop() |
821 | 285 | >>> sent_msg = message_from_bytes(raw_message) | 285 | >>> sent_msg = email.message_from_bytes(raw_message) |
822 | 286 | >>> sent_msg['Return-Path'] == config.canonical.bounce_address | 286 | >>> sent_msg['Return-Path'] == config.canonical.bounce_address |
823 | 287 | True | 287 | True |
824 | 288 | >>> sent_msg['Errors-To'] == config.canonical.bounce_address | 288 | >>> sent_msg['Errors-To'] == config.canonical.bounce_address |
825 | @@ -301,7 +301,7 @@ It's possible to set Return-Path manually if needed. | |||
826 | 301 | >>> transaction.commit() | 301 | >>> transaction.commit() |
827 | 302 | 302 | ||
828 | 303 | >>> from_addr, to_add, raw_message = stub.test_emails.pop() | 303 | >>> from_addr, to_add, raw_message = stub.test_emails.pop() |
830 | 304 | >>> sent_msg = message_from_bytes(raw_message) | 304 | >>> sent_msg = email.message_from_bytes(raw_message) |
831 | 305 | >>> sent_msg['Return-Path'] | 305 | >>> sent_msg['Return-Path'] |
832 | 306 | '<>' | 306 | '<>' |
833 | 307 | 307 | ||
834 | @@ -322,7 +322,7 @@ are ignored. | |||
835 | 322 | ... print(to_addr) | 322 | ... print(to_addr) |
836 | 323 | no-priv@canonical.com | 323 | no-priv@canonical.com |
837 | 324 | 324 | ||
839 | 325 | >>> sent_msg = message_from_bytes(raw_message) | 325 | >>> sent_msg = email.message_from_bytes(raw_message) |
840 | 326 | >>> sent_msg['To'] | 326 | >>> sent_msg['To'] |
841 | 327 | 'test@canonical.com' | 327 | 'test@canonical.com' |
842 | 328 | >>> sent_msg['CC'] | 328 | >>> sent_msg['CC'] |
843 | @@ -332,7 +332,7 @@ Since sendmail() gets the addresses to send to from the email header, | |||
844 | 332 | it needs to take care of unfolding the headers, so that they don't | 332 | it needs to take care of unfolding the headers, so that they don't |
845 | 333 | contain any line breaks. | 333 | contain any line breaks. |
846 | 334 | 334 | ||
848 | 335 | >>> folded_message = message_from_bytes(b"""Subject: required | 335 | >>> folded_message = email.message_from_bytes(b"""Subject: required |
849 | 336 | ... From: Not used | 336 | ... From: Not used |
850 | 337 | ... <from.address@example.com> | 337 | ... <from.address@example.com> |
851 | 338 | ... To: To Address | 338 | ... To: To Address |
852 | diff --git a/lib/lp/services/mail/notification.py b/lib/lp/services/mail/notification.py | |||
853 | index 1d55202..9704416 100644 | |||
854 | --- a/lib/lp/services/mail/notification.py | |||
855 | +++ b/lib/lp/services/mail/notification.py | |||
856 | @@ -10,13 +10,13 @@ __all__ = [ | |||
857 | 10 | 10 | ||
858 | 11 | 11 | ||
859 | 12 | from difflib import unified_diff | 12 | from difflib import unified_diff |
860 | 13 | import email | ||
861 | 13 | from email.mime.message import MIMEMessage | 14 | from email.mime.message import MIMEMessage |
862 | 14 | from email.mime.multipart import MIMEMultipart | 15 | from email.mime.multipart import MIMEMultipart |
863 | 15 | from email.mime.text import MIMEText | 16 | from email.mime.text import MIMEText |
864 | 16 | import re | 17 | import re |
865 | 17 | 18 | ||
866 | 18 | from lp.bugs.mail.bugnotificationbuilder import get_bugmail_error_address | 19 | from lp.bugs.mail.bugnotificationbuilder import get_bugmail_error_address |
867 | 19 | from lp.services.compat import message_from_bytes | ||
868 | 20 | from lp.services.config import config | 20 | from lp.services.config import config |
869 | 21 | from lp.services.mail.helpers import get_email_template | 21 | from lp.services.mail.helpers import get_email_template |
870 | 22 | from lp.services.mail.mailwrapper import MailWrapper | 22 | from lp.services.mail.mailwrapper import MailWrapper |
871 | @@ -72,7 +72,7 @@ def send_process_error_notification(to_address, subject, error_msg, | |||
872 | 72 | original_msg_str = bytes(original_msg) | 72 | original_msg_str = bytes(original_msg) |
873 | 73 | if len(original_msg_str) > max_return_size: | 73 | if len(original_msg_str) > max_return_size: |
874 | 74 | truncated_msg_str = original_msg_str[:max_return_size] | 74 | truncated_msg_str = original_msg_str[:max_return_size] |
876 | 75 | original_msg = message_from_bytes(truncated_msg_str) | 75 | original_msg = email.message_from_bytes(truncated_msg_str) |
877 | 76 | msg.attach(MIMEMessage(original_msg)) | 76 | msg.attach(MIMEMessage(original_msg)) |
878 | 77 | sendmail(msg) | 77 | sendmail(msg) |
879 | 78 | 78 | ||
880 | diff --git a/lib/lp/services/mail/signedmessage.py b/lib/lp/services/mail/signedmessage.py | |||
881 | index 02eeb90..732a397 100644 | |||
882 | --- a/lib/lp/services/mail/signedmessage.py | |||
883 | +++ b/lib/lp/services/mail/signedmessage.py | |||
884 | @@ -11,12 +11,12 @@ __all__ = [ | |||
885 | 11 | 'strip_pgp_signature', | 11 | 'strip_pgp_signature', |
886 | 12 | ] | 12 | ] |
887 | 13 | 13 | ||
888 | 14 | import email | ||
889 | 14 | from email.message import Message | 15 | from email.message import Message |
890 | 15 | import re | 16 | import re |
891 | 16 | 17 | ||
892 | 17 | from zope.interface import implementer | 18 | from zope.interface import implementer |
893 | 18 | 19 | ||
894 | 19 | from lp.services.compat import message_from_bytes | ||
895 | 20 | from lp.services.mail.interfaces import ISignedMessage | 20 | from lp.services.mail.interfaces import ISignedMessage |
896 | 21 | 21 | ||
897 | 22 | 22 | ||
898 | @@ -42,7 +42,7 @@ def signed_message_from_bytes(buf): | |||
899 | 42 | It makes sure that the SignedMessage instance has access to the | 42 | It makes sure that the SignedMessage instance has access to the |
900 | 43 | parsed bytes. | 43 | parsed bytes. |
901 | 44 | """ | 44 | """ |
903 | 45 | msg = message_from_bytes(buf, _class=SignedMessage) | 45 | msg = email.message_from_bytes(buf, _class=SignedMessage) |
904 | 46 | msg.parsed_bytes = buf | 46 | msg.parsed_bytes = buf |
905 | 47 | return msg | 47 | return msg |
906 | 48 | 48 | ||
907 | diff --git a/lib/lp/services/mail/stub.py b/lib/lp/services/mail/stub.py | |||
908 | index b63265c..c63d2fd 100644 | |||
909 | --- a/lib/lp/services/mail/stub.py | |||
910 | +++ b/lib/lp/services/mail/stub.py | |||
911 | @@ -5,16 +5,14 @@ | |||
912 | 5 | 5 | ||
913 | 6 | __metaclass__ = type | 6 | __metaclass__ = type |
914 | 7 | 7 | ||
915 | 8 | import email | ||
916 | 8 | from logging import getLogger | 9 | from logging import getLogger |
917 | 9 | 10 | ||
918 | 10 | from zope.component import getUtility | 11 | from zope.component import getUtility |
919 | 11 | from zope.interface import implementer | 12 | from zope.interface import implementer |
920 | 12 | from zope.sendmail.interfaces import IMailer | 13 | from zope.sendmail.interfaces import IMailer |
921 | 13 | 14 | ||
926 | 14 | from lp.services.compat import ( | 15 | from lp.services.compat import message_as_bytes |
923 | 15 | message_as_bytes, | ||
924 | 16 | message_from_bytes, | ||
925 | 17 | ) | ||
927 | 18 | 16 | ||
928 | 19 | 17 | ||
929 | 20 | @implementer(IMailer) | 18 | @implementer(IMailer) |
930 | @@ -41,7 +39,7 @@ class StubMailer: | |||
931 | 41 | # headers that determine the actual To: address. However, this might | 39 | # headers that determine the actual To: address. However, this might |
932 | 42 | # be required to bypass some spam filters. | 40 | # be required to bypass some spam filters. |
933 | 43 | if self.rewrite: | 41 | if self.rewrite: |
935 | 44 | message = message_from_bytes(message) | 42 | message = email.message_from_bytes(message) |
936 | 45 | message['X-Orig-To'] = message['To'] | 43 | message['X-Orig-To'] = message['To'] |
937 | 46 | message['X-Orig-Cc'] = message['Cc'] | 44 | message['X-Orig-Cc'] = message['Cc'] |
938 | 47 | message['X-Orig-From'] = message['From'] | 45 | message['X-Orig-From'] = message['From'] |
939 | diff --git a/lib/lp/services/mail/tests/incomingmail.txt b/lib/lp/services/mail/tests/incomingmail.txt | |||
940 | index 6fa33ca..bd77caa 100644 | |||
941 | --- a/lib/lp/services/mail/tests/incomingmail.txt | |||
942 | +++ b/lib/lp/services/mail/tests/incomingmail.txt | |||
943 | @@ -301,8 +301,7 @@ to the user, citing the OOPS ID, with the original message attached. | |||
944 | 301 | 301 | ||
945 | 302 | OOPS notifications work even if the From: address isn't properly MIME-encoded. | 302 | OOPS notifications work even if the From: address isn't properly MIME-encoded. |
946 | 303 | 303 | ||
949 | 304 | >>> from lp.services.compat import message_from_bytes | 304 | >>> msg = email.message_from_bytes( |
948 | 305 | >>> msg = message_from_bytes( | ||
950 | 306 | ... u"""From: \u05D1 <bet@canonical.com> | 305 | ... u"""From: \u05D1 <bet@canonical.com> |
951 | 307 | ... To: launchpad@oops.com | 306 | ... To: launchpad@oops.com |
952 | 308 | ... X-Launchpad-Original-To: launchpad@oops.com | 307 | ... X-Launchpad-Original-To: launchpad@oops.com |
953 | diff --git a/lib/lp/services/mail/tests/test_stub.py b/lib/lp/services/mail/tests/test_stub.py | |||
954 | index 85a549f..e1af47a 100644 | |||
955 | --- a/lib/lp/services/mail/tests/test_stub.py | |||
956 | +++ b/lib/lp/services/mail/tests/test_stub.py | |||
957 | @@ -15,9 +15,9 @@ def test_simple_sendmail(): | |||
958 | 15 | r""" | 15 | r""" |
959 | 16 | Send an email (faked by TestMailer - no actual email is sent) | 16 | Send an email (faked by TestMailer - no actual email is sent) |
960 | 17 | 17 | ||
961 | 18 | >>> from email import message_from_bytes | ||
962 | 18 | >>> from email.mime.text import MIMEText | 19 | >>> from email.mime.text import MIMEText |
963 | 19 | >>> import transaction | 20 | >>> import transaction |
964 | 20 | >>> from lp.services.compat import message_from_bytes | ||
965 | 21 | >>> from lp.services.mail import stub | 21 | >>> from lp.services.mail import stub |
966 | 22 | >>> from lp.services.mail.sendmail import simple_sendmail | 22 | >>> from lp.services.mail.sendmail import simple_sendmail |
967 | 23 | 23 | ||
968 | diff --git a/lib/lp/services/messages/model/message.py b/lib/lp/services/messages/model/message.py | |||
969 | index f6638b2..a2943ea 100644 | |||
970 | --- a/lib/lp/services/messages/model/message.py | |||
971 | +++ b/lib/lp/services/messages/model/message.py | |||
972 | @@ -11,6 +11,7 @@ __all__ = [ | |||
973 | 11 | ] | 11 | ] |
974 | 12 | 12 | ||
975 | 13 | from datetime import datetime | 13 | from datetime import datetime |
976 | 14 | import email | ||
977 | 14 | from email.header import ( | 15 | from email.header import ( |
978 | 15 | decode_header, | 16 | decode_header, |
979 | 16 | make_header, | 17 | make_header, |
980 | @@ -57,7 +58,6 @@ from lp.registry.interfaces.person import ( | |||
981 | 57 | PersonCreationRationale, | 58 | PersonCreationRationale, |
982 | 58 | validate_public_person, | 59 | validate_public_person, |
983 | 59 | ) | 60 | ) |
984 | 60 | from lp.services.compat import message_from_bytes | ||
985 | 61 | from lp.services.config import config | 61 | from lp.services.config import config |
986 | 62 | from lp.services.database.constants import UTC_NOW | 62 | from lp.services.database.constants import UTC_NOW |
987 | 63 | from lp.services.database.datetimecol import UtcDateTimeCol | 63 | from lp.services.database.datetimecol import UtcDateTimeCol |
988 | @@ -376,7 +376,7 @@ class MessageSet: | |||
989 | 376 | # Parse the raw message into an email.message.Message instance, | 376 | # Parse the raw message into an email.message.Message instance, |
990 | 377 | # if we haven't been given one already. | 377 | # if we haven't been given one already. |
991 | 378 | if parsed_message is None: | 378 | if parsed_message is None: |
993 | 379 | parsed_message = message_from_bytes(email_message) | 379 | parsed_message = email.message_from_bytes(email_message) |
994 | 380 | 380 | ||
995 | 381 | # We could easily generate a default, but a missing message-id | 381 | # We could easily generate a default, but a missing message-id |
996 | 382 | # almost certainly means a developer is using this method when | 382 | # almost certainly means a developer is using this method when |
997 | diff --git a/lib/lp/services/verification/doc/logintoken.txt b/lib/lp/services/verification/doc/logintoken.txt | |||
998 | index 9a8587c..201c15a 100644 | |||
999 | --- a/lib/lp/services/verification/doc/logintoken.txt | |||
1000 | +++ b/lib/lp/services/verification/doc/logintoken.txt | |||
1001 | @@ -49,7 +49,7 @@ Let's create a new LoginToken to confirm an email address for foobar. | |||
1002 | 49 | The email does not have a precedence header because the user implicitly | 49 | The email does not have a precedence header because the user implicitly |
1003 | 50 | requested it to complete their task. | 50 | requested it to complete their task. |
1004 | 51 | 51 | ||
1006 | 52 | >>> from lp.services.compat import message_from_bytes | 52 | >>> from email import message_from_bytes |
1007 | 53 | 53 | ||
1008 | 54 | >>> msg = message_from_bytes(found_msg) | 54 | >>> msg = message_from_bytes(found_msg) |
1009 | 55 | >>> print(msg['Precedence']) | 55 | >>> print(msg['Precedence']) |
1010 | diff --git a/lib/lp/services/verification/tests/logintoken.py b/lib/lp/services/verification/tests/logintoken.py | |||
1011 | index 4f7d3ee..fda3d6a 100644 | |||
1012 | --- a/lib/lp/services/verification/tests/logintoken.py | |||
1013 | +++ b/lib/lp/services/verification/tests/logintoken.py | |||
1014 | @@ -3,16 +3,15 @@ | |||
1015 | 3 | 3 | ||
1016 | 4 | """Helper functions for logintoken-related tests.""" | 4 | """Helper functions for logintoken-related tests.""" |
1017 | 5 | 5 | ||
1018 | 6 | import email | ||
1019 | 6 | import re | 7 | import re |
1020 | 7 | 8 | ||
1021 | 8 | import six | 9 | import six |
1022 | 9 | 10 | ||
1023 | 10 | from lp.services.compat import message_from_bytes | ||
1024 | 11 | |||
1025 | 12 | 11 | ||
1026 | 13 | def get_token_url_from_email(email_msg): | 12 | def get_token_url_from_email(email_msg): |
1027 | 14 | """Return the logintoken URL contained in the given email message.""" | 13 | """Return the logintoken URL contained in the given email message.""" |
1029 | 15 | msg = message_from_bytes(email_msg) | 14 | msg = email.message_from_bytes(email_msg) |
1030 | 16 | return get_token_url_from_bytes(msg.get_payload(decode=True)) | 15 | return get_token_url_from_bytes(msg.get_payload(decode=True)) |
1031 | 17 | 16 | ||
1032 | 18 | 17 | ||
1033 | diff --git a/lib/lp/testing/mail_helpers.py b/lib/lp/testing/mail_helpers.py | |||
1034 | index 16bdcc2..23112fe 100644 | |||
1035 | --- a/lib/lp/testing/mail_helpers.py | |||
1036 | +++ b/lib/lp/testing/mail_helpers.py | |||
1037 | @@ -5,6 +5,7 @@ | |||
1038 | 5 | 5 | ||
1039 | 6 | __metaclass__ = type | 6 | __metaclass__ = type |
1040 | 7 | 7 | ||
1041 | 8 | import email | ||
1042 | 8 | import operator | 9 | import operator |
1043 | 9 | 10 | ||
1044 | 10 | import six | 11 | import six |
1045 | @@ -18,7 +19,6 @@ from lp.registry.interfaces.persontransferjob import ( | |||
1046 | 18 | ITeamInvitationNotificationJobSource, | 19 | ITeamInvitationNotificationJobSource, |
1047 | 19 | ITeamJoinNotificationJobSource, | 20 | ITeamJoinNotificationJobSource, |
1048 | 20 | ) | 21 | ) |
1049 | 21 | from lp.services.compat import message_from_bytes | ||
1050 | 22 | from lp.services.config import config | 22 | from lp.services.config import config |
1051 | 23 | from lp.services.job.runner import JobRunner | 23 | from lp.services.job.runner import JobRunner |
1052 | 24 | from lp.services.log.logger import DevNullLogger | 24 | from lp.services.log.logger import DevNullLogger |
1053 | @@ -44,7 +44,7 @@ def pop_notifications(sort_key=None, commit=True): | |||
1054 | 44 | 44 | ||
1055 | 45 | notifications = [] | 45 | notifications = [] |
1056 | 46 | for fromaddr, toaddrs, raw_message in stub.test_emails: | 46 | for fromaddr, toaddrs, raw_message in stub.test_emails: |
1058 | 47 | notification = message_from_bytes(raw_message) | 47 | notification = email.message_from_bytes(raw_message) |
1059 | 48 | notification['X-Envelope-To'] = ', '.join(toaddrs) | 48 | notification['X-Envelope-To'] = ', '.join(toaddrs) |
1060 | 49 | notification['X-Envelope-From'] = fromaddr | 49 | notification['X-Envelope-From'] = fromaddr |
1061 | 50 | notifications.append(notification) | 50 | notifications.append(notification) |
1062 | diff --git a/lib/lp/translations/doc/translations-export-to-branch.txt b/lib/lp/translations/doc/translations-export-to-branch.txt | |||
1063 | index c8b74b0..76b63db 100644 | |||
1064 | --- a/lib/lp/translations/doc/translations-export-to-branch.txt | |||
1065 | +++ b/lib/lp/translations/doc/translations-export-to-branch.txt | |||
1066 | @@ -223,8 +223,8 @@ The Launchpad UI allows users to register branches in the Launchpad | |||
1067 | 223 | database without populating them in bzr. Exporting to such a branch | 223 | database without populating them in bzr. Exporting to such a branch |
1068 | 224 | won't work, so we email a notification to the branch owner. | 224 | won't work, so we email a notification to the branch owner. |
1069 | 225 | 225 | ||
1070 | 226 | >>> import email | ||
1071 | 226 | >>> from lp.codehosting.vfs import get_rw_server | 227 | >>> from lp.codehosting.vfs import get_rw_server |
1072 | 227 | >>> from lp.services.compat import message_from_bytes | ||
1073 | 228 | >>> from lp.services.mail import stub | 228 | >>> from lp.services.mail import stub |
1074 | 229 | >>> from lp.testing.factory import ( | 229 | >>> from lp.testing.factory import ( |
1075 | 230 | ... remove_security_proxy_and_shout_at_engineer) | 230 | ... remove_security_proxy_and_shout_at_engineer) |
1076 | @@ -255,7 +255,7 @@ won't work, so we email a notification to the branch owner. | |||
1077 | 255 | >>> transaction.commit() | 255 | >>> transaction.commit() |
1078 | 256 | 256 | ||
1079 | 257 | >>> sender, recipients, body = stub.test_emails.pop() | 257 | >>> sender, recipients, body = stub.test_emails.pop() |
1081 | 258 | >>> message = message_from_bytes(body) | 258 | >>> message = email.message_from_bytes(body) |
1082 | 259 | >>> print(message['Subject']) | 259 | >>> print(message['Subject']) |
1083 | 260 | Launchpad: translations branch has not been set up. | 260 | Launchpad: translations branch has not been set up. |
1084 | 261 | 261 |
Looks good!