3
PackageUpload has a notify() method to send emails.
4
We need to be logged into the security model in order to get any further.
6
>>> login('foo.bar@canonical.com')
4
PackageUpload has a notify() method to send emails. We need to be logged
5
into the security model in order to get any further.
7
>>> login('foo.bar@canonical.com')
8
9
Get a packageupload object for netapplet, which has a relatively intact
9
set of supporting sample data. It has rows in distribution, distroseries,
10
sourcepackagerelease, person and a librarian entry for the changes file
11
which are all needed for successful operation of notify().
13
>>> from lp.soyuz.interfaces.queue import IPackageUploadSet
14
>>> netapplet_upload = getUtility(IPackageUploadSet)[3]
15
>>> print netapplet_upload.displayname
18
Set up some library files for the netapplet source package. These are not
19
already present in the sample data.
21
>>> from canonical.launchpad.interfaces.librarian import ILibraryFileAliasSet
22
>>> from lp.archiveuploader.tests import datadir
24
>>> netapplet_spr = netapplet_upload.sources[0].sourcepackagerelease
25
>>> librarian = getUtility(ILibraryFileAliasSet)
26
>>> files = ['netapplet_1.0-1.dsc', 'netapplet_1.0.orig.tar.gz',
27
... 'netapplet_1.0-1.diff.gz']
28
>>> for file in files:
29
... filepath = datadir('suite/netapplet_1.0-1/%s' % file)
30
... fileobj = open(filepath, 'rb')
31
... filesize = os.stat(filepath).st_size
32
... lfa = librarian.create(file, filesize, fileobj, 'dummytype')
33
... sprf = netapplet_spr.addFile(lfa)
36
The notify() method generates one email here on this unsigned package. It
37
requires an announcement list email address, a "changes_file_object" that is
38
just an open file object for the original changes file, and a special
39
logger object that will extract tracebacks for the purposes of this doctest.
41
>>> changes_file_path = datadir(
42
... 'suite/netapplet_1.0-1/netapplet_1.0-1_source.changes')
43
>>> changes_file = open(changes_file_path,'r')
44
>>> from lp.services.log.logger import FakeLogger
45
>>> netapplet_upload.notify(
46
... changes_file_object=changes_file, logger=FakeLogger())
47
DEBUG Building recipients list.
48
DEBUG Changes file is unsigned, adding changer as recipient
52
DEBUG Recipients: Daniel Silverstone <daniel.silverstone@canonical.com>
54
DEBUG above if files already exist in other distroseries.
56
DEBUG signer of the above package.
10
set of supporting sample data. It has rows in distribution,
11
distroseries, sourcepackagerelease, person and a librarian entry for the
12
changes file which are all needed for successful operation of notify().
14
>>> from lp.soyuz.interfaces.queue import IPackageUploadSet
15
>>> netapplet_upload = getUtility(IPackageUploadSet)[3]
16
>>> print netapplet_upload.displayname
19
Set up some library files for the netapplet source package. These are
20
not already present in the sample data.
22
>>> from canonical.launchpad.interfaces.librarian import (
23
... ILibraryFileAliasSet)
24
>>> from lp.archiveuploader.tests import datadir
26
>>> netapplet_spr = netapplet_upload.sources[0].sourcepackagerelease
27
>>> librarian = getUtility(ILibraryFileAliasSet)
29
... 'netapplet_1.0-1.dsc',
30
... 'netapplet_1.0.orig.tar.gz',
31
... 'netapplet_1.0-1.diff.gz',
33
>>> for file in files:
34
... filepath = datadir('suite/netapplet_1.0-1/%s' % file)
35
... fileobj = open(filepath, 'rb')
36
... filesize = os.stat(filepath).st_size
37
... lfa = librarian.create(file, filesize, fileobj, 'dummytype')
38
... sprf = netapplet_spr.addFile(lfa)
41
The notify() method generates one email here on this unsigned package.
42
It requires an announcement list email address, a "changes_file_object"
43
that is just an open file object for the original changes file, and a
44
special logger object that will extract tracebacks for the purposes of
47
>>> changes_file_path = datadir(
48
... 'suite/netapplet_1.0-1/netapplet_1.0-1_source.changes')
49
>>> changes_file = open(changes_file_path,'r')
50
>>> from lp.services.log.logger import FakeLogger
51
>>> netapplet_upload.notify(
52
... changes_file_object=changes_file, logger=FakeLogger())
53
DEBUG Building recipients list.
54
DEBUG Changes file is unsigned; adding changer as recipient.
58
DEBUG Recipients: ... Silverstone ...
60
DEBUG above if files already exist in other distroseries.
62
DEBUG signer of the above package.
58
64
Helper functions to examine emails that were sent:
60
>>> from lp.services.mail import stub
61
>>> from lp.testing.mail_helpers import pop_notifications
62
>>> def by_to_addrs(a, b):
63
... return cmp(a[1], b[1])
66
>>> from lp.services.mail import stub
67
>>> from lp.testing.mail_helpers import pop_notifications
65
69
There's only one email generated from the preceding upload:
67
>>> [notification] = pop_notifications()
71
>>> [notification] = pop_notifications()
69
73
The mail headers contain our To: as set on the notify() call. The
70
subject contains "Accepted", the package name, its version and whether it's
71
source or binary. The Bcc field also always contains the uploader's email
74
>>> notification['To']
75
'Daniel Silverstone <daniel.silverstone@canonical.com>'
76
>>> notification['Bcc']
77
'Root <root@localhost>'
79
>>> notification['Subject']
80
'[ubuntu/breezy-autotest] netapplet 0.99.6-1 (New)'
74
subject contains "Accepted", the package name, its version and whether
75
it's source or binary. The Bcc field also always contains the
76
uploader's email address.
78
>>> notification['To']
79
'Daniel Silverstone <daniel.silverstone@canonical.com>'
81
>>> notification['Bcc']
82
'Root <root@localhost>'
84
>>> notification['Subject']
85
'[ubuntu/breezy-autotest] netapplet 0.99.6-1 (New)'
82
87
The mail body contains a list of files that were accepted:
84
>>> print notification.get_payload(0) # doctest: -NORMALIZE_WHITESPACE
87
NEW: netapplet_1.0-1.dsc
88
NEW: netapplet_1.0.orig.tar.gz
89
NEW: netapplet_1.0-1.diff.gz
92
You may have gotten the distroseries wrong. If so, you may get warnings
93
above if files already exist in other distroseries.
97
You are receiving this email because you are the uploader, maintainer or
98
signer of the above package.
101
Now we will process a signed package. Signed packages will potentially have
102
a different recipient list to unsigned ones; recipients for signed package
103
uploads can be the signer, the maintainer and the changer, where these people
104
are different. Unsigned packages only send notifications to the changer.
106
>>> from zope.security.proxy import removeSecurityProxy
107
>>> from lp.registry.interfaces.gpg import IGPGKeySet
108
>>> gpgkey = getUtility(IGPGKeySet).get(1)
109
>>> removeSecurityProxy(netapplet_upload).signing_key = gpgkey
89
>>> print notification.get_payload(0) # doctest: -NORMALIZE_WHITESPACE
92
NEW: netapplet_1.0-1.dsc
93
NEW: netapplet_1.0.orig.tar.gz
94
NEW: netapplet_1.0-1.diff.gz
97
You may have gotten the distroseries wrong. If so, you may get warnings
98
above if files already exist in other distroseries.
102
You are receiving this email because you are the uploader, maintainer or
103
signer of the above package.
106
Now we will process a signed package. Signed packages will potentially
107
have a different recipient list to unsigned ones; recipients for signed
108
package uploads can be the signer, the maintainer and the changer, where
109
these people are different. Unsigned packages only send notifications
112
>>> from zope.security.proxy import removeSecurityProxy
113
>>> from lp.registry.interfaces.gpg import IGPGKeySet
114
>>> gpgkey = getUtility(IGPGKeySet).get(1)
115
>>> removeSecurityProxy(netapplet_upload).signing_key = gpgkey
111
117
Now request the email:
113
>>> changes_file_path = datadir(
114
... 'suite/netapplet_1.0-1-signed/netapplet_1.0-1_source.changes')
115
>>> changes_file = open(changes_file_path,'r')
116
>>> netapplet_upload.setAccepted()
117
>>> netapplet_upload.notify(
118
... changes_file_object=changes_file, logger=FakeLogger())
119
DEBUG Building recipients list.
123
DEBUG Recipients: Foo Bar <foo.bar@canonical.com>, Daniel Silverstone <daniel.silverstone@canonical.com>
125
DEBUG Announcing to autotest_changes@ubuntu.com
130
There are two emails, the upload acknowledgement and the announcement, because
131
this upload is already accepted.
133
>>> msgs = pop_notifications()
137
The mail 'To:' addresses contain the signer and the changer's email. The
138
announcement email contains the serieses changeslist.
140
>>> [msg['To'] for msg in msgs]
141
['Foo Bar <foo.bar@canonical.com>,\n\tDaniel Silverstone <daniel.silverstone@canonical.com>', 'autotest_changes@ubuntu.com']
143
The mail 'Bcc:' address is the uploader. The announcement has the uploader
144
and the Debian derivatives address for the package uploaded.
146
>>> [msg['Bcc'] for msg in msgs]
147
['Root <root@localhost>', 'Root <root@localhost>, netapplet_derivatives@packages.qa.debian.org']
119
>>> changes_file_path = datadir(
120
... 'suite/netapplet_1.0-1-signed/netapplet_1.0-1_source.changes')
121
>>> changes_file = open(changes_file_path,'r')
122
>>> netapplet_upload.setAccepted()
123
>>> netapplet_upload.notify(
124
... changes_file_object=changes_file, logger=FakeLogger())
125
DEBUG Building recipients list.
129
DEBUG Recipients: ... Bar ...
131
DEBUG Announcing to autotest_changes@ubuntu.com
136
There are two emails, the upload acknowledgement and the announcement,
137
because this upload is already accepted.
139
>>> msgs = pop_notifications()
143
The mail 'To:' addresses contain the signer and the changer's email.
144
The announcement email contains the serieses changeslist.
146
>>> def to_lower(address):
147
... """Return lower-case version of email address."""
148
... return address.lower()
150
>>> def extract_addresses(header_field):
151
... """Extract and sort addresses from an email header field."""
153
... [addr.strip() for addr in header_field.split(',')],
156
>>> for addr in extract_addresses(msgs[0]['To']):
158
Daniel Silverstone <daniel.silverstone@canonical.com>
159
Foo Bar <foo.bar@canonical.com>
161
>>> print msgs[1]['To']
162
autotest_changes@ubuntu.com
164
The mail 'Bcc:' address is the uploader. The announcement has the
165
uploader and the Debian derivatives address for the package uploaded.
168
... print extract_addresses(msg['Bcc'])
169
['Root <root@localhost>']
170
['netapplet_derivatives@packages.qa.debian.org', 'Root <root@localhost>']
149
172
The mail 'From:' addresses are the uploader and the changer.
151
>>> [msg['From'] for msg in msgs]
152
['Root <root@localhost>', 'Daniel Silverstone <daniel.silverstone@canonical.com>']
175
... print msg['From']
176
Root <root@localhost>
177
Daniel Silverstone <daniel.silverstone@canonical.com>
154
>>> notification['Subject']
155
'[ubuntu/breezy-autotest] netapplet 0.99.6-1 (New)'
179
>>> print notification['Subject']
180
[ubuntu/breezy-autotest] netapplet 0.99.6-1 (New)
157
182
The mail body contains the same list of files again:
159
>>> print notification.get_payload(0) # doctest: -NORMALIZE_WHITESPACE
162
NEW: netapplet_1.0-1.dsc
163
NEW: netapplet_1.0.orig.tar.gz
164
NEW: netapplet_1.0-1.diff.gz
167
You may have gotten the distroseries wrong. If so, you may get warnings
168
above if files already exist in other distroseries.
172
You are receiving this email because you are the uploader, maintainer or
173
signer of the above package.
177
notify() will also work without passing the changes_file_object parameter
178
provided that everything is already committed to the database (which is not
179
the case when nascent upload runs). This example demonstrates this usage:
181
>>> from canonical.librarian.testing.server import fillLibrarianFile
182
>>> changes_file = open(changes_file_path,"r")
183
>>> fillLibrarianFile(1, content=changes_file.read())
184
>>> changes_file.close()
185
>>> netapplet_upload.setNew()
186
>>> netapplet_upload.notify(logger=FakeLogger())
187
DEBUG Building recipients list.
191
DEBUG Recipients: Foo Bar <foo.bar@canonical.com>, Daniel Silverstone <daniel.silverstone@canonical.com>
193
DEBUG above if files already exist in other distroseries.
195
DEBUG signer of the above package.
184
>>> print notification.get_payload(0) # doctest: -NORMALIZE_WHITESPACE
187
NEW: netapplet_1.0-1.dsc
188
NEW: netapplet_1.0.orig.tar.gz
189
NEW: netapplet_1.0-1.diff.gz
192
You may have gotten the distroseries wrong. If so, you may get warnings
193
above if files already exist in other distroseries.
197
You are receiving this email because you are the uploader, maintainer or
198
signer of the above package.
201
notify() will also work without passing the changes_file_object
202
parameter provided that everything is already committed to the database
203
(which is not the case when nascent upload runs). This example
204
demonstrates this usage:
206
>>> from canonical.librarian.testing.server import fillLibrarianFile
207
>>> changes_file = open(changes_file_path,"r")
208
>>> fillLibrarianFile(1, content=changes_file.read())
209
>>> changes_file.close()
210
>>> netapplet_upload.setNew()
211
>>> netapplet_upload.notify(logger=FakeLogger())
212
DEBUG Building recipients list.
216
DEBUG Recipients: ... Silverstone ...
218
DEBUG above if files already exist in other distroseries.
220
DEBUG signer of the above package.
197
222
Only one email is generated:
199
>>> [notification] = pop_notifications()
224
>>> [notification] = pop_notifications()
201
226
The mail headers are the same as before:
203
>>> notification['To']
204
'Foo Bar <foo.bar@canonical.com>,\n\tDaniel Silverstone <daniel.silverstone@canonical.com>'
205
>>> notification['Bcc']
206
'Root <root@localhost>'
208
>>> notification['Subject']
209
'[ubuntu/breezy-autotest] netapplet 0.99.6-1 (New)'
228
>>> for addr in extract_addresses(notification['To']):
230
Daniel Silverstone <daniel.silverstone@canonical.com>
231
Foo Bar <foo.bar@canonical.com>
233
>>> print notification['Bcc']
234
Root <root@localhost>
236
>>> print notification['Subject']
237
[ubuntu/breezy-autotest] netapplet 0.99.6-1 (New)
211
239
The mail body contains the same list of files again:
213
>>> print notification.get_payload(0) # doctest: -NORMALIZE_WHITESPACE
216
NEW: netapplet_1.0-1.dsc
217
NEW: netapplet_1.0.orig.tar.gz
218
NEW: netapplet_1.0-1.diff.gz
221
You may have gotten the distroseries wrong. If so, you may get warnings
222
above if files already exist in other distroseries.
226
You are receiving this email because you are the uploader, maintainer or
227
signer of the above package.
241
>>> print notification.get_payload(0) # doctest: -NORMALIZE_WHITESPACE
244
NEW: netapplet_1.0-1.dsc
245
NEW: netapplet_1.0.orig.tar.gz
246
NEW: netapplet_1.0-1.diff.gz
249
You may have gotten the distroseries wrong. If so, you may get warnings
250
above if files already exist in other distroseries.
254
You are receiving this email because you are the uploader, maintainer or
255
signer of the above package.
231
258
notify() will also generate rejection notices if the upload failed. The
232
summary_text argument is text that is appended to any auto-generated text for
233
the summary. Rejections don't currently auto-generate anything.
259
summary_text argument is text that is appended to any auto-generated
260
text for the summary. Rejections don't currently auto-generate
235
>>> netapplet_upload.setRejected()
236
>>> netapplet_upload.notify(summary_text="Testing rejection message",
237
... logger=FakeLogger())
238
DEBUG Building recipients list.
240
DEBUG Sending rejection email.
242
DEBUG Subject: [ubuntu/breezy-autotest] netapplet 0.99.6-1 (Rejected)
243
DEBUG Sender: Root <root@localhost>
244
DEBUG Recipients: Foo Bar <foo.bar@canonical.com>, Daniel Silverstone <daniel.silverstone@canonical.com>
245
DEBUG Bcc: Root <root@localhost>
248
DEBUG Testing rejection message
250
DEBUG If you don't understand why your files were rejected, or if the
252
DEBUG signer of the above package.
263
>>> netapplet_upload.setRejected()
264
>>> netapplet_upload.notify(
265
... summary_text="Testing rejection message", logger=FakeLogger())
266
DEBUG Building recipients list.
268
DEBUG Sending rejection email.
270
DEBUG Subject: [ubuntu/breezy-autotest] netapplet 0.99.6-1 (Rejected)
271
DEBUG Sender: Root <root@localhost>
272
DEBUG Recipients: ... Bar ...
273
DEBUG Bcc: Root <root@localhost>
276
DEBUG Testing rejection message
278
DEBUG If you don't understand why your files were rejected, or if the
280
DEBUG signer of the above package.
254
282
Only one email is generated:
256
>>> transaction.commit()
257
>>> len(stub.test_emails)
284
>>> transaction.commit()
285
>>> len(stub.test_emails)
260
288
Clean up, otherwise stuff is left lying around in /var/tmp.
262
>>> from canonical.testing.layers import LibrarianLayer
263
>>> LibrarianLayer.librarian_fixture.clear()
290
>>> from canonical.testing.layers import LibrarianLayer
291
>>> LibrarianLayer.librarian_fixture.clear()