Merge ~cjwatson/launchpad:stormify-bugnotification into launchpad:master
- Git
- lp:~cjwatson/launchpad
- stormify-bugnotification
- Merge into master
Proposed by
Colin Watson
Status: | Merged |
---|---|
Approved by: | Colin Watson |
Approved revision: | 298c58e423172143e24be1d0e95be0ef33b8a958 |
Merge reported by: | Otto Co-Pilot |
Merged at revision: | not available |
Proposed branch: | ~cjwatson/launchpad:stormify-bugnotification |
Merge into: | launchpad:master |
Diff against target: |
1144 lines (+244/-148) 30 files modified
lib/lp/bugs/browser/tests/bug-views.txt (+5/-4) lib/lp/bugs/doc/bug-change.txt (+7/-3) lib/lp/bugs/doc/bug-set-status.txt (+3/-1) lib/lp/bugs/doc/bugattachments.txt (+5/-4) lib/lp/bugs/doc/bugnotification-sending.txt (+3/-1) lib/lp/bugs/doc/bugnotification-threading.txt (+1/-2) lib/lp/bugs/doc/bugnotifications.txt (+25/-12) lib/lp/bugs/doc/bugsubscription.txt (+22/-18) lib/lp/bugs/doc/bugwatch.txt (+5/-5) lib/lp/bugs/doc/externalbugtracker-comment-imports.txt (+4/-4) lib/lp/bugs/mail/bugnotificationrecipients.py (+2/-0) lib/lp/bugs/mail/tests/test_bug_duplicate_notifications.py (+3/-1) lib/lp/bugs/mail/tests/test_bug_task_assignment.py (+5/-2) lib/lp/bugs/mail/tests/test_bug_task_deletion.py (+3/-1) lib/lp/bugs/mail/tests/test_bug_task_modification.py (+3/-1) lib/lp/bugs/mail/tests/test_handler.py (+4/-2) lib/lp/bugs/model/bug.py (+5/-4) lib/lp/bugs/model/bugnotification.py (+61/-30) lib/lp/bugs/scripts/tests/test_bugimport.py (+3/-1) lib/lp/bugs/scripts/tests/test_bugnotification.py (+9/-16) lib/lp/bugs/stories/bugs/xx-bugs.txt (+1/-1) lib/lp/bugs/stories/webservice/xx-bug.txt (+3/-1) lib/lp/bugs/subscribers/tests/test_bug.py (+3/-3) lib/lp/bugs/tests/bugs-emailinterface.txt (+20/-10) lib/lp/bugs/tests/bugtarget-questiontarget.txt (+4/-1) lib/lp/bugs/tests/test_bugchanges.py (+7/-6) lib/lp/bugs/tests/test_bugnotification.py (+7/-3) lib/lp/registry/doc/milestone.txt (+4/-3) lib/lp/scripts/tests/test_garbo.py (+11/-5) lib/lp/soyuz/doc/closing-bugs-from-changelogs.txt (+6/-3) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ioana Lasc (community) | Approve | ||
Review via email: mp+385562@code.launchpad.net |
Commit message
Convert BugNotification to Storm
Description of the change
To post a comment you must log in.
Revision history for this message
Ioana Lasc (ilasc) : | # |
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | diff --git a/lib/lp/bugs/browser/tests/bug-views.txt b/lib/lp/bugs/browser/tests/bug-views.txt |
2 | index 2e89e54..2dccbf9 100644 |
3 | --- a/lib/lp/bugs/browser/tests/bug-views.txt |
4 | +++ b/lib/lp/bugs/browser/tests/bug-views.txt |
5 | @@ -648,7 +648,8 @@ Emails are sent out by adding entries to the bugnotification table. We |
6 | need to know how many messages are currently in that table. |
7 | |
8 | >>> from lp.bugs.model.bugnotification import BugNotification |
9 | - >>> bn_set = BugNotification.select(BugNotification.q.bugID == bug_one.id) |
10 | + >>> from lp.services.database.interfaces import IStore |
11 | + >>> bn_set = IStore(BugNotification).find(BugNotification, bug=bug_one) |
12 | >>> start_bugnotification_count = bn_set.count() |
13 | |
14 | Add 'new-tag' multiple times so that we can verify that it will only be added |
15 | @@ -666,11 +667,11 @@ once. |
16 | Since the 'new-tag' was added, a new entry in the bugnotification table |
17 | should exist. |
18 | |
19 | - >>> bn_set = BugNotification.select(BugNotification.q.bugID == bug_one.id, |
20 | - ... orderBy = BugNotification.q.id) |
21 | + >>> bn_set = IStore(BugNotification).find( |
22 | + ... BugNotification, bug=bug_one).order_by(BugNotification.id) |
23 | >>> start_bugnotification_count == bn_set.count() - 1 |
24 | True |
25 | - >>> bn_set[-1].message.text_contents |
26 | + >>> bn_set.last().message.text_contents |
27 | u'** Tags added: new-tag' |
28 | |
29 | |
30 | diff --git a/lib/lp/bugs/doc/bug-change.txt b/lib/lp/bugs/doc/bug-change.txt |
31 | index 1d44ea1..881c389 100644 |
32 | --- a/lib/lp/bugs/doc/bug-change.txt |
33 | +++ b/lib/lp/bugs/doc/bug-change.txt |
34 | @@ -107,7 +107,9 @@ BugActivity entries are added when addChange() is called. |
35 | As are BugNotifications. |
36 | |
37 | >>> from lp.bugs.model.bugnotification import BugNotification |
38 | - >>> latest_notification = BugNotification.selectFirst(orderBy='-id') |
39 | + >>> from lp.services.database.interfaces import IStore |
40 | + >>> latest_notification = IStore(BugNotification).find( |
41 | + ... BugNotification).order_by(BugNotification.id).last() |
42 | >>> print(latest_notification.message.text_contents) |
43 | Some message text |
44 | |
45 | @@ -131,7 +133,8 @@ But if getBugActivity() returns None, no activity entries will be added. |
46 | |
47 | And if getBugNotification() returns None, no notification will be added. |
48 | |
49 | - >>> new_latest_notification = BugNotification.selectFirst(orderBy='-id') |
50 | + >>> new_latest_notification = IStore(BugNotification).find( |
51 | + ... BugNotification).order_by(BugNotification.id).last() |
52 | >>> new_latest_notification.id == latest_notification.id |
53 | True |
54 | |
55 | @@ -158,7 +161,8 @@ bug's target for Meta data changes, but not for lifecycle changes. |
56 | ... filter.bug_notification_level = BugNotificationLevel.METADATA |
57 | >>> example_bug.addChange( |
58 | ... TestBugChange(when=nowish, person=example_person)) |
59 | - >>> latest_notification = BugNotification.selectFirst(orderBy='-id') |
60 | + >>> latest_notification = IStore(BugNotification).find( |
61 | + ... BugNotification).order_by(BugNotification.id).last() |
62 | >>> print(latest_notification.message.text_contents) |
63 | Some message text |
64 | |
65 | diff --git a/lib/lp/bugs/doc/bug-set-status.txt b/lib/lp/bugs/doc/bug-set-status.txt |
66 | index cc9ccfe..0626c48 100644 |
67 | --- a/lib/lp/bugs/doc/bug-set-status.txt |
68 | +++ b/lib/lp/bugs/doc/bug-set-status.txt |
69 | @@ -41,7 +41,9 @@ It also emits an ObjectModifiedEvent so that BugNotification and |
70 | BugActivity records are created. |
71 | |
72 | >>> from lp.bugs.model.bugnotification import BugNotification |
73 | - >>> latest_notification = BugNotification.selectFirst(orderBy='-id') |
74 | + >>> from lp.services.database.interfaces import IStore |
75 | + >>> latest_notification = IStore(BugNotification).find( |
76 | + ... BugNotification).order_by(BugNotification.id).last() |
77 | >>> print(latest_notification.message.owner.displayname) |
78 | No Privileges Person |
79 | >>> print(latest_notification.message.text_contents) |
80 | diff --git a/lib/lp/bugs/doc/bugattachments.txt b/lib/lp/bugs/doc/bugattachments.txt |
81 | index 977c944..ac57c8f 100644 |
82 | --- a/lib/lp/bugs/doc/bugattachments.txt |
83 | +++ b/lib/lp/bugs/doc/bugattachments.txt |
84 | @@ -237,7 +237,9 @@ Since the ObjectCreatedEvent was generated, a notification about the |
85 | attachment was added. |
86 | |
87 | >>> from lp.bugs.model.bugnotification import BugNotification |
88 | - >>> latest_notification = BugNotification.selectFirst(orderBy='-id') |
89 | + >>> from lp.services.database.interfaces import IStore |
90 | + >>> latest_notification = IStore(BugNotification).find( |
91 | + ... BugNotification).order_by(BugNotification.id).last() |
92 | >>> print(latest_notification.message.text_contents) |
93 | ** Attachment added: "RA.txt" |
94 | http://.../RA.txt |
95 | @@ -475,9 +477,8 @@ The libraryfile of this bug attachment is marked as "deleted". |
96 | Deleting an attachment causes a notification to be sent. It's worth |
97 | noting that the notification still includes the URL to the attachment. |
98 | |
99 | - >>> from lp.bugs.model.bugnotification import BugNotification |
100 | - >>> latest_notification = BugNotification |
101 | - >>> latest_notification = BugNotification.selectFirst(orderBy='-id') |
102 | + >>> latest_notification = IStore(BugNotification).find( |
103 | + ... BugNotification).order_by(BugNotification.id).last() |
104 | >>> latest_notification.is_comment |
105 | False |
106 | >>> print(latest_notification.message.text_contents) |
107 | diff --git a/lib/lp/bugs/doc/bugnotification-sending.txt b/lib/lp/bugs/doc/bugnotification-sending.txt |
108 | index 19cd3a8..92c265f 100644 |
109 | --- a/lib/lp/bugs/doc/bugnotification-sending.txt |
110 | +++ b/lib/lp/bugs/doc/bugnotification-sending.txt |
111 | @@ -619,7 +619,9 @@ more carefully at the notifications just to see that the status has |
112 | been set properly. |
113 | |
114 | >>> from lp.bugs.model.bugnotification import BugNotification |
115 | - >>> for notification in BugNotification.select(orderBy='id')[-8:]: |
116 | + >>> from lp.services.database.interfaces import IStore |
117 | + >>> for notification in list(IStore(BugNotification).find( |
118 | + ... BugNotification).order_by(BugNotification.id))[-8:]: |
119 | ... if notification.is_comment: |
120 | ... identifier = 'comment' |
121 | ... else: |
122 | diff --git a/lib/lp/bugs/doc/bugnotification-threading.txt b/lib/lp/bugs/doc/bugnotification-threading.txt |
123 | index 1864f0b..e73b4e3 100644 |
124 | --- a/lib/lp/bugs/doc/bugnotification-threading.txt |
125 | +++ b/lib/lp/bugs/doc/bugnotification-threading.txt |
126 | @@ -139,8 +139,7 @@ References header. |
127 | ... owner=sample_person, title="New bug", comment="New bug.", |
128 | ... target=bug_one.default_bugtask.target) |
129 | >>> bug = getUtility(IBugSet).createBug(params) |
130 | - >>> notifications = IStore(BugNotification).find( |
131 | - ... BugNotification, BugNotification.bug == bug) |
132 | + >>> notifications = IStore(BugNotification).find(BugNotification, bug=bug) |
133 | >>> messages = [emails for notifications, omitted, emails in |
134 | ... get_email_notifications(notifications)] |
135 | >>> len(messages) |
136 | diff --git a/lib/lp/bugs/doc/bugnotifications.txt b/lib/lp/bugs/doc/bugnotifications.txt |
137 | index b16b50a..1e364cc 100644 |
138 | --- a/lib/lp/bugs/doc/bugnotifications.txt |
139 | +++ b/lib/lp/bugs/doc/bugnotifications.txt |
140 | @@ -41,7 +41,9 @@ those notifications look like. |
141 | >>> firefox_crashes = firefox.createBug(params) |
142 | |
143 | >>> from lp.bugs.model.bugnotification import BugNotification |
144 | - >>> latest_notification = BugNotification.selectFirst(orderBy='-id') |
145 | + >>> from lp.services.database.interfaces import IStore |
146 | + >>> latest_notification = IStore(BugNotification).find( |
147 | + ... BugNotification).order_by(BugNotification.id).last() |
148 | >>> print(latest_notification.message.owner.displayname) |
149 | Sample Person |
150 | |
151 | @@ -68,7 +70,8 @@ bugactivity.txt, but for now here is a small demo. |
152 | >>> with notify_modified(firefox_crashes, ["description"]): |
153 | ... firefox_crashes.description = "a new description" |
154 | |
155 | - >>> latest_notification = BugNotification.selectFirst(orderBy='-id') |
156 | + >>> latest_notification = IStore(BugNotification).find( |
157 | + ... BugNotification).order_by(BugNotification.id).last() |
158 | >>> print(latest_notification.message.owner.displayname) |
159 | Sample Person |
160 | |
161 | @@ -107,7 +110,8 @@ bug. Let's take a look at each type. |
162 | >>> notify(ObjectCreatedEvent( |
163 | ... firefox_crashes_in_debian, firefox_crashes_in_debian.owner)) |
164 | |
165 | - >>> latest_notification = BugNotification.selectFirst(orderBy='-id') |
166 | + >>> latest_notification = IStore(BugNotification).find( |
167 | + ... BugNotification).order_by(BugNotification.id).last() |
168 | >>> print(latest_notification.message.owner.displayname) |
169 | Sample Person |
170 | |
171 | @@ -133,7 +137,8 @@ bug. Let's take a look at each type. |
172 | >>> notify(ObjectCreatedEvent( |
173 | ... firefox_crashes_in_sid, firefox_crashes_in_sid.owner)) |
174 | |
175 | - >>> latest_notification = BugNotification.selectFirst(orderBy='-id') |
176 | + >>> latest_notification = IStore(BugNotification).find( |
177 | + ... BugNotification).order_by(BugNotification.id).last() |
178 | >>> print(latest_notification.message.owner.displayname) |
179 | Sample Person |
180 | |
181 | @@ -161,7 +166,8 @@ bug. Let's take a look at each type. |
182 | >>> notify(ObjectCreatedEvent( |
183 | ... evolution_crashes_too, evolution_crashes_too.owner)) |
184 | |
185 | - >>> latest_notification = BugNotification.selectFirst(orderBy='-id') |
186 | + >>> latest_notification = IStore(BugNotification).find( |
187 | + ... BugNotification).order_by(BugNotification.id).last() |
188 | >>> print(latest_notification.message.owner.displayname) |
189 | Sample Person |
190 | |
191 | @@ -183,7 +189,8 @@ bug. Let's take a look at each type. |
192 | >>> notify(ObjectCreatedEvent( |
193 | ... firefox_crashes_in_trunk, firefox_crashes_in_trunk.owner)) |
194 | |
195 | - >>> latest_notification = BugNotification.selectFirst(orderBy='-id') |
196 | + >>> latest_notification = IStore(BugNotification).find( |
197 | + ... BugNotification).order_by(BugNotification.id).last() |
198 | >>> print(latest_notification.message.owner.displayname) |
199 | Sample Person |
200 | |
201 | @@ -205,7 +212,8 @@ bug. Let's take a look at each type. |
202 | ... bug=firefox_crashes, owner=current_user) |
203 | >>> notify(ObjectCreatedEvent(comment_on_firefox_crashes_in_debian)) |
204 | |
205 | - >>> latest_notification = BugNotification.selectFirst(orderBy='-id') |
206 | + >>> latest_notification = IStore(BugNotification).find( |
207 | + ... BugNotification).order_by(BugNotification.id).last() |
208 | >>> print(latest_notification.message.owner.displayname) |
209 | Sample Person |
210 | |
211 | @@ -228,7 +236,8 @@ task Fixed, and assigns themselves to it. |
212 | ... BugTaskStatus.FIXRELEASED, getUtility(ILaunchBag).user) |
213 | ... firefox_crashes_in_debian.transitionToAssignee(bug_submitter) |
214 | |
215 | - >>> latest_notification = BugNotification.selectFirst(orderBy='-id') |
216 | + >>> latest_notification = IStore(BugNotification).find( |
217 | + ... BugNotification).order_by(BugNotification.id).last() |
218 | >>> print(latest_notification.message.owner.displayname) |
219 | Sample Person |
220 | |
221 | @@ -244,7 +253,8 @@ task Fixed, and assigns themselves to it. |
222 | ... BugTaskStatus.FIXRELEASED, getUtility(ILaunchBag).user) |
223 | ... firefox_crashes_in_trunk.transitionToAssignee(bug_submitter) |
224 | |
225 | - >>> latest_notification = BugNotification.selectFirst(orderBy='-id') |
226 | + >>> latest_notification = IStore(BugNotification).find( |
227 | + ... BugNotification).order_by(BugNotification.id).last() |
228 | >>> print(latest_notification.message.owner.displayname) |
229 | Sample Person |
230 | |
231 | @@ -269,7 +279,8 @@ this document: |
232 | >>> bug = Bug.get(1) |
233 | >>> bugcve = cve.linkBug(bug) # note this creates the event and notifies |
234 | |
235 | - >>> latest_notification = BugNotification.selectFirst(orderBy='-id') |
236 | + >>> latest_notification = IStore(BugNotification).find( |
237 | + ... BugNotification).order_by(BugNotification.id).last() |
238 | >>> print(latest_notification.message.owner.displayname) |
239 | Sample Person |
240 | |
241 | @@ -285,7 +296,8 @@ During bulk imports or changes of bugs, we often want to suppress |
242 | email notifications. Due to the previous operation, there is a |
243 | pending bug notification for bug 1: |
244 | |
245 | - >>> notifications = BugNotification.selectBy(bugID=1, date_emailed=None) |
246 | + >>> notifications = IStore(BugNotification).find( |
247 | + ... BugNotification, bug_id=1, date_emailed=None) |
248 | >>> notifications.count() |
249 | 1 |
250 | |
251 | @@ -293,6 +305,7 @@ This notification can be expired using the expireNotifications() |
252 | method: |
253 | |
254 | >>> bug.expireNotifications() |
255 | - >>> notifications = BugNotification.selectBy(bugID=1, date_emailed=None) |
256 | + >>> notifications = IStore(BugNotification).find( |
257 | + ... BugNotification, bug_id=1, date_emailed=None) |
258 | >>> notifications.count() |
259 | 0 |
260 | diff --git a/lib/lp/bugs/doc/bugsubscription.txt b/lib/lp/bugs/doc/bugsubscription.txt |
261 | index fdae4e0..052dee6 100644 |
262 | --- a/lib/lp/bugs/doc/bugsubscription.txt |
263 | +++ b/lib/lp/bugs/doc/bugsubscription.txt |
264 | @@ -365,11 +365,12 @@ INotificationRecipientSet instance for us: |
265 | You can query for the addresses and reasons: |
266 | |
267 | >>> addresses = recipients.getEmails() |
268 | - >>> [(address, recipients.getReason(address)[1]) for address in addresses] |
269 | - [('foo.bar@canonical.com', 'Subscriber'), |
270 | - ('mark@example.com', 'Subscriber'), |
271 | - ('no-priv@canonical.com', u'Subscriber (linux-source-2.6.15 in Ubuntu)'), |
272 | - ('test@canonical.com', 'Assignee')] |
273 | + >>> for address in addresses: |
274 | + ... print('%s: %s' % (address, recipients.getReason(address)[1])) |
275 | + foo.bar@canonical.com: Subscriber |
276 | + mark@example.com: Subscriber |
277 | + no-priv@canonical.com: Subscriber (linux-source-2.6.15 in Ubuntu) |
278 | + test@canonical.com: Assignee |
279 | |
280 | If IBug.getBugNotificationRecipients() is passed a BugNotificationLevel |
281 | in its `level` parameter, only structural subscribers with that |
282 | @@ -378,10 +379,11 @@ notification level or higher will be returned. |
283 | >>> recipients = linux_source_bug.getBugNotificationRecipients( |
284 | ... level=BugNotificationLevel.COMMENTS) |
285 | >>> addresses = recipients.getEmails() |
286 | - >>> [(address, recipients.getReason(address)[1]) for address in addresses] |
287 | - [('foo.bar@canonical.com', 'Subscriber'), |
288 | - ('mark@example.com', 'Subscriber'), |
289 | - ('test@canonical.com', 'Assignee')] |
290 | + >>> for address in addresses: |
291 | + ... print('%s: %s' % (address, recipients.getReason(address)[1])) |
292 | + foo.bar@canonical.com: Subscriber |
293 | + mark@example.com: Subscriber |
294 | + test@canonical.com: Assignee |
295 | |
296 | When Sample Person is unsubscribed from linux_source_bug, they are no |
297 | longer included in the result of getBugNotificationRecipients() for |
298 | @@ -391,10 +393,11 @@ the COMMENTS level... |
299 | >>> recipients = linux_source_bug.getBugNotificationRecipients( |
300 | ... level=BugNotificationLevel.COMMENTS) |
301 | >>> addresses = recipients.getEmails() |
302 | - >>> [(address, recipients.getReason(address)[1]) for address in addresses] |
303 | - [('foo.bar@canonical.com', 'Subscriber'), |
304 | - ('mark@example.com', 'Subscriber'), |
305 | - ('test@canonical.com', 'Assignee')] |
306 | + >>> for address in addresses: |
307 | + ... print('%s: %s' % (address, recipients.getReason(address)[1])) |
308 | + foo.bar@canonical.com: Subscriber |
309 | + mark@example.com: Subscriber |
310 | + test@canonical.com: Assignee |
311 | |
312 | ...but remains included for the level LIFECYCLE. |
313 | |
314 | @@ -402,11 +405,12 @@ the COMMENTS level... |
315 | >>> recipients = linux_source_bug.getBugNotificationRecipients( |
316 | ... level=BugNotificationLevel.LIFECYCLE) |
317 | >>> addresses = recipients.getEmails() |
318 | - >>> [(address, recipients.getReason(address)[1]) for address in addresses] |
319 | - [('foo.bar@canonical.com', 'Subscriber'), |
320 | - ('mark@example.com', 'Subscriber'), |
321 | - ('no-priv@canonical.com', u'Subscriber (linux-source-2.6.15 in Ubuntu)'), |
322 | - ('test@canonical.com', 'Assignee')] |
323 | + >>> for address in addresses: |
324 | + ... print('%s: %s' % (address, recipients.getReason(address)[1])) |
325 | + foo.bar@canonical.com: Subscriber |
326 | + mark@example.com: Subscriber |
327 | + no-priv@canonical.com: Subscriber (linux-source-2.6.15 in Ubuntu) |
328 | + test@canonical.com: Assignee |
329 | |
330 | To find out if someone is already directly subscribed to a bug, call |
331 | IBug.isSubscribed, passing in an IPerson: |
332 | diff --git a/lib/lp/bugs/doc/bugwatch.txt b/lib/lp/bugs/doc/bugwatch.txt |
333 | index c280375..0431c68 100644 |
334 | --- a/lib/lp/bugs/doc/bugwatch.txt |
335 | +++ b/lib/lp/bugs/doc/bugwatch.txt |
336 | @@ -317,14 +317,14 @@ tasks, because it's not a valid person and only valid persons can get karma. |
337 | |
338 | Finally, let's make sure that bug notifications were added: |
339 | |
340 | - >>> from lp.bugs.model.bugnotification import ( |
341 | - ... BugNotification) |
342 | - >>> unsent_notifications = ( |
343 | - ... BugNotification.selectBy(date_emailed=None, orderBy='id')) |
344 | + >>> from lp.bugs.model.bugnotification import BugNotification |
345 | + >>> from lp.services.database.interfaces import IStore |
346 | + >>> unsent_notifications = IStore(BugNotification).find( |
347 | + ... BugNotification, date_emailed=None).order_by(BugNotification.id) |
348 | |
349 | >>> for bug_notification in unsent_notifications: |
350 | ... print("Bug %s changed by %s:" % ( |
351 | - ... bug_notification.bug.id, |
352 | + ... bug_notification.bug_id, |
353 | ... bug_notification.message.owner.displayname)) |
354 | ... print(bug_notification.message.text_contents) |
355 | Bug 1 changed by Bug Watch Updater: |
356 | diff --git a/lib/lp/bugs/doc/externalbugtracker-comment-imports.txt b/lib/lp/bugs/doc/externalbugtracker-comment-imports.txt |
357 | index 4f0aa00..7c7a5b0 100644 |
358 | --- a/lib/lp/bugs/doc/externalbugtracker-comment-imports.txt |
359 | +++ b/lib/lp/bugs/doc/externalbugtracker-comment-imports.txt |
360 | @@ -431,13 +431,13 @@ watch, there can be a lot of comments. To avoid causing a lot of email |
361 | notifications to be sent, only one notification is sent for all the |
362 | comments. |
363 | |
364 | - >>> from lp.bugs.model.bugnotification import ( |
365 | - ... BugNotification) |
366 | + >>> from lp.bugs.model.bugnotification import BugNotification |
367 | + >>> from lp.services.database.interfaces import IStore |
368 | >>> old_notifications = set() |
369 | >>> def get_new_notifications(bug): |
370 | ... new_notifications = [ |
371 | - ... notification for notification in ( |
372 | - ... BugNotification.selectBy(bug=bug, orderBy='id')) |
373 | + ... notification for notification in IStore(BugNotification).find( |
374 | + ... BugNotification, bug=bug).order_by(BugNotification.id) |
375 | ... if notification not in old_notifications] |
376 | ... old_notifications.update(new_notifications) |
377 | ... return new_notifications |
378 | diff --git a/lib/lp/bugs/mail/bugnotificationrecipients.py b/lib/lp/bugs/mail/bugnotificationrecipients.py |
379 | index bcec38d..ff1cf8b 100644 |
380 | --- a/lib/lp/bugs/mail/bugnotificationrecipients.py |
381 | +++ b/lib/lp/bugs/mail/bugnotificationrecipients.py |
382 | @@ -3,6 +3,8 @@ |
383 | |
384 | """Code for handling bug notification recipients in bug mail.""" |
385 | |
386 | +from __future__ import absolute_import, print_function, unicode_literals |
387 | + |
388 | __metaclass__ = type |
389 | __all__ = [ |
390 | 'BugNotificationRecipients', |
391 | diff --git a/lib/lp/bugs/mail/tests/test_bug_duplicate_notifications.py b/lib/lp/bugs/mail/tests/test_bug_duplicate_notifications.py |
392 | index 61ad6ca..431ad45 100644 |
393 | --- a/lib/lp/bugs/mail/tests/test_bug_duplicate_notifications.py |
394 | +++ b/lib/lp/bugs/mail/tests/test_bug_duplicate_notifications.py |
395 | @@ -9,6 +9,7 @@ from zope.component import getUtility |
396 | from lp.bugs.interfaces.bugtask import BugTaskStatus |
397 | from lp.bugs.model.bugnotification import BugNotification |
398 | from lp.bugs.scripts.bugnotification import construct_email_notifications |
399 | +from lp.services.database.interfaces import IStore |
400 | from lp.services.webapp.interfaces import ILaunchBag |
401 | from lp.services.webapp.snapshot import notify_modified |
402 | from lp.testing import TestCaseWithFactory |
403 | @@ -46,7 +47,8 @@ class TestAssignmentNotification(TestCaseWithFactory): |
404 | self.master_bug_task.transitionToStatus( |
405 | BugTaskStatus.CONFIRMED, self.user) |
406 | transaction.commit() |
407 | - latest_notification = BugNotification.selectFirst(orderBy='-id') |
408 | + latest_notification = IStore(BugNotification).find( |
409 | + BugNotification).order_by(BugNotification.id).last() |
410 | notifications, omitted, messages = construct_email_notifications( |
411 | [latest_notification]) |
412 | self.assertEqual( |
413 | diff --git a/lib/lp/bugs/mail/tests/test_bug_task_assignment.py b/lib/lp/bugs/mail/tests/test_bug_task_assignment.py |
414 | index 031bb14..3e34cdd 100644 |
415 | --- a/lib/lp/bugs/mail/tests/test_bug_task_assignment.py |
416 | +++ b/lib/lp/bugs/mail/tests/test_bug_task_assignment.py |
417 | @@ -8,6 +8,7 @@ from zope.component import getUtility |
418 | |
419 | from lp.bugs.model.bugnotification import BugNotification |
420 | from lp.bugs.scripts.bugnotification import construct_email_notifications |
421 | +from lp.services.database.interfaces import IStore |
422 | from lp.services.mail import stub |
423 | from lp.services.webapp.interfaces import ILaunchBag |
424 | from lp.services.webapp.snapshot import notify_modified |
425 | @@ -91,7 +92,8 @@ class TestAssignmentNotification(TestCaseWithFactory): |
426 | task changes and ensure the assignee is not one.""" |
427 | with notify_modified(self.bug_task, ['assignee'], user=self.user): |
428 | self.bug_task.transitionToAssignee(self.person_assigned) |
429 | - latest_notification = BugNotification.selectFirst(orderBy='-id') |
430 | + latest_notification = IStore(BugNotification).find( |
431 | + BugNotification).order_by(BugNotification.id).last() |
432 | notifications, omitted, messages = construct_email_notifications( |
433 | [latest_notification]) |
434 | self.assertEqual(len(notifications), 1, |
435 | @@ -106,7 +108,8 @@ class TestAssignmentNotification(TestCaseWithFactory): |
436 | task changes.""" |
437 | with notify_modified(self.bug_task, ['assignee'], user=self.user): |
438 | self.bug_task.transitionToAssignee(self.team_assigned) |
439 | - latest_notification = BugNotification.selectFirst(orderBy='-id') |
440 | + latest_notification = IStore(BugNotification).find( |
441 | + BugNotification).order_by(BugNotification.id).last() |
442 | notifications, omitted, messages = construct_email_notifications( |
443 | [latest_notification]) |
444 | self.assertEqual(len(notifications), 1, |
445 | diff --git a/lib/lp/bugs/mail/tests/test_bug_task_deletion.py b/lib/lp/bugs/mail/tests/test_bug_task_deletion.py |
446 | index 4811568..0cbb63f 100644 |
447 | --- a/lib/lp/bugs/mail/tests/test_bug_task_deletion.py |
448 | +++ b/lib/lp/bugs/mail/tests/test_bug_task_deletion.py |
449 | @@ -8,6 +8,7 @@ from zope.component import getUtility |
450 | |
451 | from lp.bugs.model.bugnotification import BugNotification |
452 | from lp.bugs.scripts.bugnotification import construct_email_notifications |
453 | +from lp.services.database.interfaces import IStore |
454 | from lp.services.webapp.interfaces import ILaunchBag |
455 | from lp.testing import TestCaseWithFactory |
456 | from lp.testing.layers import DatabaseFunctionalLayer |
457 | @@ -30,7 +31,8 @@ class TestDeletionNotification(TestCaseWithFactory): |
458 | """Test X-Launchpad-Bug-Modifier appears when a bugtask is deleted.""" |
459 | self.bug_task.delete(self.user) |
460 | transaction.commit() |
461 | - latest_notification = BugNotification.selectFirst(orderBy='-id') |
462 | + latest_notification = IStore(BugNotification).find( |
463 | + BugNotification).order_by(BugNotification.id).last() |
464 | notifications, omitted, messages = construct_email_notifications( |
465 | [latest_notification]) |
466 | self.assertEqual(len(notifications), 1, |
467 | diff --git a/lib/lp/bugs/mail/tests/test_bug_task_modification.py b/lib/lp/bugs/mail/tests/test_bug_task_modification.py |
468 | index 6587370..c181a1b 100644 |
469 | --- a/lib/lp/bugs/mail/tests/test_bug_task_modification.py |
470 | +++ b/lib/lp/bugs/mail/tests/test_bug_task_modification.py |
471 | @@ -9,6 +9,7 @@ from zope.component import getUtility |
472 | from lp.bugs.interfaces.bugtask import BugTaskStatus |
473 | from lp.bugs.model.bugnotification import BugNotification |
474 | from lp.bugs.scripts.bugnotification import construct_email_notifications |
475 | +from lp.services.database.interfaces import IStore |
476 | from lp.services.webapp.interfaces import ILaunchBag |
477 | from lp.services.webapp.snapshot import notify_modified |
478 | from lp.testing import TestCaseWithFactory |
479 | @@ -35,7 +36,8 @@ class TestModificationNotification(TestCaseWithFactory): |
480 | self.bug_task.transitionToStatus( |
481 | BugTaskStatus.CONFIRMED, self.user) |
482 | transaction.commit() |
483 | - latest_notification = BugNotification.selectFirst(orderBy='-id') |
484 | + latest_notification = IStore(BugNotification).find( |
485 | + BugNotification).order_by(BugNotification.id).last() |
486 | notifications, omitted, messages = construct_email_notifications( |
487 | [latest_notification]) |
488 | self.assertEqual(len(notifications), 1, |
489 | diff --git a/lib/lp/bugs/mail/tests/test_handler.py b/lib/lp/bugs/mail/tests/test_handler.py |
490 | index e89c8fb..c5af232 100644 |
491 | --- a/lib/lp/bugs/mail/tests/test_handler.py |
492 | +++ b/lib/lp/bugs/mail/tests/test_handler.py |
493 | @@ -30,6 +30,7 @@ from lp.bugs.mail.handler import ( |
494 | from lp.bugs.model.bugnotification import BugNotification |
495 | from lp.registry.enums import BugSharingPolicy |
496 | from lp.services.config import config |
497 | +from lp.services.database.interfaces import IStore |
498 | from lp.services.identity.interfaces.emailaddress import EmailAddressStatus |
499 | from lp.services.webapp.authorization import LaunchpadSecurityPolicy |
500 | from lp.testing import ( |
501 | @@ -220,7 +221,8 @@ class MaloneHandlerProcessTestCase(TestCaseWithFactory): |
502 | |
503 | @staticmethod |
504 | def getLatestBugNotification(): |
505 | - return BugNotification.selectFirst(orderBy='-id') |
506 | + return IStore(BugNotification).find( |
507 | + BugNotification).order_by(BugNotification.id).last() |
508 | |
509 | def test_new_bug(self): |
510 | project = self.factory.makeProduct(name='fnord') |
511 | @@ -322,7 +324,7 @@ class MaloneHandlerProcessTestCase(TestCaseWithFactory): |
512 | self.assertEqual(1, len(bug.bugtasks)) |
513 | self.assertEqual(project, bug.bugtasks[0].target) |
514 | recipients = set() |
515 | - for notification in BugNotification.select(): |
516 | + for notification in IStore(BugNotification).find(BugNotification): |
517 | for recipient in notification.recipients: |
518 | recipients.add(recipient.person) |
519 | self.assertContentEqual([maintainer], recipients) |
520 | diff --git a/lib/lp/bugs/model/bug.py b/lib/lp/bugs/model/bug.py |
521 | index 7ea2576..98169c6 100644 |
522 | --- a/lib/lp/bugs/model/bug.py |
523 | +++ b/lib/lp/bugs/model/bug.py |
524 | @@ -1216,10 +1216,11 @@ class Bug(SQLBase, InformationTypeMixin): |
525 | |
526 | def expireNotifications(self): |
527 | """See `IBug`.""" |
528 | - for notification in BugNotification.selectBy( |
529 | - bug=self, date_emailed=None): |
530 | - notification.date_emailed = UTC_NOW |
531 | - notification.syncUpdate() |
532 | + store = IStore(BugNotification) |
533 | + notifications = store.find( |
534 | + BugNotification, bug=self, date_emailed=None) |
535 | + notifications.set(date_emailed=UTC_NOW) |
536 | + store.flush() |
537 | |
538 | def newMessage(self, owner=None, subject=None, |
539 | content=None, parent=None, bugwatch=None, |
540 | diff --git a/lib/lp/bugs/model/bugnotification.py b/lib/lp/bugs/model/bugnotification.py |
541 | index 77786c9..dc7e089 100644 |
542 | --- a/lib/lp/bugs/model/bugnotification.py |
543 | +++ b/lib/lp/bugs/model/bugnotification.py |
544 | @@ -17,19 +17,17 @@ from datetime import ( |
545 | ) |
546 | |
547 | import pytz |
548 | -from sqlobject import ( |
549 | - BoolCol, |
550 | - ForeignKey, |
551 | - StringCol, |
552 | - ) |
553 | from storm.expr import ( |
554 | In, |
555 | Join, |
556 | LeftJoin, |
557 | ) |
558 | from storm.locals import ( |
559 | + Bool, |
560 | + DateTime, |
561 | Int, |
562 | Reference, |
563 | + Unicode, |
564 | ) |
565 | from storm.store import Store |
566 | from zope.component import getUtility |
567 | @@ -51,34 +49,52 @@ from lp.bugs.model.structuralsubscription import StructuralSubscription |
568 | from lp.registry.interfaces.person import IPersonSet |
569 | from lp.services.config import config |
570 | from lp.services.database import bulk |
571 | -from lp.services.database.datetimecol import UtcDateTimeCol |
572 | -from lp.services.database.enumcol import EnumCol |
573 | +from lp.services.database.enumcol import DBEnum |
574 | from lp.services.database.interfaces import IStore |
575 | -from lp.services.database.sqlbase import SQLBase |
576 | from lp.services.database.stormbase import StormBase |
577 | from lp.services.messages.model.message import Message |
578 | |
579 | |
580 | @implementer(IBugNotification) |
581 | -class BugNotification(SQLBase): |
582 | +class BugNotification(StormBase): |
583 | """A textual representation about a bug change.""" |
584 | |
585 | - message = ForeignKey(dbName='message', notNull=True, foreignKey='Message') |
586 | - activity = ForeignKey( |
587 | - dbName='activity', notNull=False, foreignKey='BugActivity') |
588 | - bug = ForeignKey(dbName='bug', notNull=True, foreignKey='Bug') |
589 | - is_comment = BoolCol(notNull=True) |
590 | - date_emailed = UtcDateTimeCol(notNull=False) |
591 | - status = EnumCol( |
592 | - dbName='status', |
593 | - schema=BugNotificationStatus, default=BugNotificationStatus.PENDING, |
594 | - notNull=True) |
595 | + __storm_table__ = 'BugNotification' |
596 | + |
597 | + id = Int(primary=True) |
598 | + |
599 | + message_id = Int(name='message', allow_none=False) |
600 | + message = Reference(message_id, 'Message.id') |
601 | + |
602 | + activity_id = Int('activity', allow_none=True) |
603 | + activity = Reference(activity_id, 'BugActivity.id') |
604 | + |
605 | + bug_id = Int(name='bug', allow_none=False) |
606 | + bug = Reference(bug_id, 'Bug.id') |
607 | + |
608 | + is_comment = Bool(allow_none=False) |
609 | + date_emailed = DateTime(tzinfo=pytz.UTC, allow_none=True) |
610 | + status = DBEnum( |
611 | + name='status', |
612 | + enum=BugNotificationStatus, default=BugNotificationStatus.PENDING, |
613 | + allow_none=False) |
614 | + |
615 | + def __init__(self, bug, is_comment, message, date_emailed=None, |
616 | + activity=None, status=BugNotificationStatus.PENDING): |
617 | + self.bug = bug |
618 | + self.is_comment = is_comment |
619 | + self.message = message |
620 | + self.date_emailed = date_emailed |
621 | + self.activity = activity |
622 | + self.status = status |
623 | |
624 | @property |
625 | def recipients(self): |
626 | """See `IBugNotification`.""" |
627 | - return BugNotificationRecipient.selectBy( |
628 | - bug_notification=self, orderBy='id') |
629 | + return IStore(BugNotificationRecipient).find( |
630 | + BugNotificationRecipient, |
631 | + BugNotificationRecipient.bug_notification == self).order_by( |
632 | + BugNotificationRecipient.id) |
633 | |
634 | @property |
635 | def bug_filters(self): |
636 | @@ -89,6 +105,9 @@ class BugNotification(SQLBase): |
637 | BugNotificationFilter.bug_subscription_filter_id), |
638 | BugNotificationFilter.bug_notification == self) |
639 | |
640 | + def destroySelf(self): |
641 | + Store.of(self).remove(self) |
642 | + |
643 | |
644 | @implementer(IBugNotificationSet) |
645 | class BugNotificationSet: |
646 | @@ -129,7 +148,7 @@ class BugNotificationSet: |
647 | elif (last_omitted_notification is not None and |
648 | notification.message.ownerID == |
649 | last_omitted_notification.message.ownerID and |
650 | - notification.bugID == last_omitted_notification.bugID and |
651 | + notification.bug_id == last_omitted_notification.bug_id and |
652 | last_omitted_notification.message.datecreated - |
653 | notification.message.datecreated < interval): |
654 | last_omitted_notification = notification |
655 | @@ -137,7 +156,7 @@ class BugNotificationSet: |
656 | last_omitted_notification = None |
657 | pending_notifications.append(notification) |
658 | people_ids.add(notification.message.ownerID) |
659 | - bug_ids.add(notification.bugID) |
660 | + bug_ids.add(notification.bug_id) |
661 | # Now we do some calls that are purely for caching. |
662 | # Converting these into lists forces the queries to execute. |
663 | if pending_notifications: |
664 | @@ -308,15 +327,27 @@ class BugNotificationSet: |
665 | |
666 | |
667 | @implementer(IBugNotificationRecipient) |
668 | -class BugNotificationRecipient(SQLBase): |
669 | +class BugNotificationRecipient(StormBase): |
670 | """A recipient of a bug notification.""" |
671 | |
672 | - bug_notification = ForeignKey( |
673 | - dbName='bug_notification', notNull=True, foreignKey='BugNotification') |
674 | - person = ForeignKey( |
675 | - dbName='person', notNull=True, foreignKey='Person') |
676 | - reason_header = StringCol(dbName='reason_header', notNull=True) |
677 | - reason_body = StringCol(dbName='reason_body', notNull=True) |
678 | + __storm_table__ = 'BugNotificationRecipient' |
679 | + |
680 | + id = Int(primary=True) |
681 | + |
682 | + bug_notification_id = Int(name='bug_notification', allow_none=False) |
683 | + bug_notification = Reference(bug_notification_id, 'BugNotification.id') |
684 | + |
685 | + person_id = Int(name='person', allow_none=False) |
686 | + person = Reference(person_id, 'Person.id') |
687 | + |
688 | + reason_header = Unicode(name='reason_header', allow_none=False) |
689 | + reason_body = Unicode(name='reason_body', allow_none=False) |
690 | + |
691 | + def __init__(self, bug_notification, person, reason_header, reason_body): |
692 | + self.bug_notification = bug_notification |
693 | + self.person = person |
694 | + self.reason_header = reason_header |
695 | + self.reason_body = reason_body |
696 | |
697 | |
698 | @implementer(IBugNotificationFilter) |
699 | diff --git a/lib/lp/bugs/scripts/tests/test_bugimport.py b/lib/lp/bugs/scripts/tests/test_bugimport.py |
700 | index e706052..2e5d7e5 100644 |
701 | --- a/lib/lp/bugs/scripts/tests/test_bugimport.py |
702 | +++ b/lib/lp/bugs/scripts/tests/test_bugimport.py |
703 | @@ -40,6 +40,7 @@ from lp.registry.interfaces.person import ( |
704 | ) |
705 | from lp.registry.interfaces.product import IProductSet |
706 | from lp.services.config import config |
707 | +from lp.services.database.interfaces import IStore |
708 | from lp.services.database.sqlbase import cursor |
709 | from lp.services.identity.interfaces.account import AccountStatus |
710 | from lp.services.identity.interfaces.emailaddress import IEmailAddressSet |
711 | @@ -453,7 +454,8 @@ class ImportBugTestCase(TestCase): |
712 | logout() |
713 | |
714 | def assertNoPendingNotifications(self, bug): |
715 | - notifications = BugNotification.selectBy(bug=bug, date_emailed=None) |
716 | + notifications = IStore(BugNotification).find( |
717 | + BugNotification, bug=bug, date_emailed=None) |
718 | count = notifications.count() |
719 | self.assertEqual(count, 0, |
720 | 'Found %d pending notifications for bug %d' |
721 | diff --git a/lib/lp/bugs/scripts/tests/test_bugnotification.py b/lib/lp/bugs/scripts/tests/test_bugnotification.py |
722 | index 734b68f..99b59c6 100644 |
723 | --- a/lib/lp/bugs/scripts/tests/test_bugnotification.py |
724 | +++ b/lib/lp/bugs/scripts/tests/test_bugnotification.py |
725 | @@ -1,6 +1,8 @@ |
726 | # Copyright 2009-2018 Canonical Ltd. This software is licensed under the |
727 | # GNU Affero General Public License version 3 (see the file LICENSE). |
728 | -"""Tests for construction bug notification emails for sending.""" |
729 | +"""Tests for constructing bug notification emails for sending.""" |
730 | + |
731 | +from __future__ import absolute_import, print_function, unicode_literals |
732 | |
733 | __metaclass__ = type |
734 | |
735 | @@ -15,7 +17,6 @@ import StringIO |
736 | import unittest |
737 | |
738 | import pytz |
739 | -from storm.store import Store |
740 | from testtools.matchers import ( |
741 | MatchesRegex, |
742 | Not, |
743 | @@ -75,10 +76,7 @@ from lp.registry.interfaces.person import IPersonSet |
744 | from lp.registry.interfaces.product import IProductSet |
745 | from lp.services.config import config |
746 | from lp.services.database.interfaces import IStore |
747 | -from lp.services.database.sqlbase import ( |
748 | - flush_database_updates, |
749 | - sqlvalues, |
750 | - ) |
751 | +from lp.services.database.sqlbase import flush_database_updates |
752 | from lp.services.mail.helpers import ( |
753 | get_contact_email_addresses, |
754 | get_email_template, |
755 | @@ -1008,14 +1006,9 @@ class TestEmailNotificationsWithFilters(TestCaseWithFactory): |
756 | def addNotificationRecipient(self, notification, person): |
757 | # Manually insert BugNotificationRecipient for |
758 | # construct_email_notifications to work. |
759 | - # Not sure why using SQLObject constructor doesn't work (it |
760 | - # tries to insert a row with only the ID which fails). |
761 | - Store.of(notification).execute(""" |
762 | - INSERT INTO BugNotificationRecipient |
763 | - (bug_notification, person, reason_header, reason_body) |
764 | - VALUES (%s, %s, %s, %s)""" % sqlvalues( |
765 | - notification, person, |
766 | - u'reason header', u'reason body')) |
767 | + BugNotificationRecipient( |
768 | + bug_notification=notification, person=person, |
769 | + reason_header='reason header', reason_body='reason body') |
770 | |
771 | def addNotification(self, person): |
772 | # Add a notification along with recipient data. |
773 | @@ -1176,8 +1169,8 @@ class TestEmailNotificationsWithFilters(TestCaseWithFactory): |
774 | def fetch_notifications(subscriber, bug): |
775 | return IStore(BugNotification).find( |
776 | BugNotification, |
777 | - BugNotification.id == BugNotificationRecipient.bug_notificationID, |
778 | - BugNotificationRecipient.personID == subscriber.id, |
779 | + BugNotification.id == BugNotificationRecipient.bug_notification_id, |
780 | + BugNotificationRecipient.person == subscriber, |
781 | BugNotification.bug == bug) |
782 | |
783 | |
784 | diff --git a/lib/lp/bugs/stories/bugs/xx-bugs.txt b/lib/lp/bugs/stories/bugs/xx-bugs.txt |
785 | index 05f2622..0dd58c7 100644 |
786 | --- a/lib/lp/bugs/stories/bugs/xx-bugs.txt |
787 | +++ b/lib/lp/bugs/stories/bugs/xx-bugs.txt |
788 | @@ -40,5 +40,5 @@ Bar. First, let's clear out the notification table: |
789 | |
790 | After the comment has been submitted, a notification is added: |
791 | |
792 | - >>> BugNotification.select().count() |
793 | + >>> IStore(BugNotification).find(BugNotification).count() |
794 | 1 |
795 | diff --git a/lib/lp/bugs/stories/webservice/xx-bug.txt b/lib/lp/bugs/stories/webservice/xx-bug.txt |
796 | index 119fb43..e36d172 100644 |
797 | --- a/lib/lp/bugs/stories/webservice/xx-bug.txt |
798 | +++ b/lib/lp/bugs/stories/webservice/xx-bug.txt |
799 | @@ -113,6 +113,7 @@ bugs. |
800 | |
801 | >>> from lp.bugs.interfaces.bug import IBugSet |
802 | >>> from lp.bugs.model.bugnotification import BugNotification |
803 | + >>> from lp.services.database.interfaces import IStore |
804 | >>> from lp.testing import ANONYMOUS, login, logout |
805 | >>> from zope.component import getUtility |
806 | |
807 | @@ -125,7 +126,8 @@ bugs. |
808 | ... activity.person.name)) |
809 | bug, added bug, salgado |
810 | |
811 | - >>> for notification in BugNotification.selectBy(bug=bug, orderBy='id'): |
812 | + >>> for notification in IStore(BugNotification).find( |
813 | + ... BugNotification, bug=bug).order_by(BugNotification.id): |
814 | ... print('%s, %s, %s' % ( |
815 | ... notification.message.owner.name, notification.is_comment, |
816 | ... notification.message.text_contents)) |
817 | diff --git a/lib/lp/bugs/subscribers/tests/test_bug.py b/lib/lp/bugs/subscribers/tests/test_bug.py |
818 | index 28130c1..19658d1 100644 |
819 | --- a/lib/lp/bugs/subscribers/tests/test_bug.py |
820 | +++ b/lib/lp/bugs/subscribers/tests/test_bug.py |
821 | @@ -61,9 +61,9 @@ class BugSubscriberTestCase(TestCaseWithFactory): |
822 | def getNotifiedPersons(self, include_all=False): |
823 | notified_persons = Store.of(self.bug).find( |
824 | Person, |
825 | - BugNotification.id == BugNotificationRecipient.bug_notificationID, |
826 | - BugNotificationRecipient.personID == Person.id, |
827 | - BugNotification.bugID == self.bug.id) |
828 | + BugNotification.id == BugNotificationRecipient.bug_notification_id, |
829 | + BugNotificationRecipient.person_id == Person.id, |
830 | + BugNotification.bug == self.bug) |
831 | if include_all: |
832 | return list(notified_persons) |
833 | else: |
834 | diff --git a/lib/lp/bugs/tests/bugs-emailinterface.txt b/lib/lp/bugs/tests/bugs-emailinterface.txt |
835 | index 2bc5460..ccb90bc 100644 |
836 | --- a/lib/lp/bugs/tests/bugs-emailinterface.txt |
837 | +++ b/lib/lp/bugs/tests/bugs-emailinterface.txt |
838 | @@ -90,8 +90,10 @@ bug got submitted correctly: |
839 | >>> from lp.services.mail import stub |
840 | >>> bugset = getUtility(IBugSet) |
841 | >>> from lp.bugs.model.bugnotification import BugNotification |
842 | + >>> from lp.services.database.interfaces import IStore |
843 | >>> def get_latest_added_bug(): |
844 | - ... latest_notification = BugNotification.selectFirst(orderBy='-id') |
845 | + ... latest_notification = IStore(BugNotification).find( |
846 | + ... BugNotification).order_by(BugNotification.id).last() |
847 | ... return latest_notification.bug |
848 | >>> bug = get_latest_added_bug() |
849 | |
850 | @@ -129,7 +131,8 @@ The owner of the bug was set to the submitter: |
851 | |
852 | A notification was added: |
853 | |
854 | - >>> bug_notification = BugNotification.selectFirst(orderBy='-id') |
855 | + >>> bug_notification = IStore(BugNotification).find( |
856 | + ... BugNotification).order_by(BugNotification.id).last() |
857 | >>> print(bug_notification.message.owner.displayname) |
858 | Foo Bar |
859 | |
860 | @@ -174,7 +177,8 @@ this: |
861 | |
862 | A notification was added: |
863 | |
864 | - >>> bug_notification = BugNotification.selectFirst(orderBy='-id') |
865 | + >>> bug_notification = IStore(BugNotification).find( |
866 | + ... BugNotification).order_by(BugNotification.id).last() |
867 | >>> print(bug_notification.message.owner.displayname) |
868 | Sample Person |
869 | |
870 | @@ -1084,7 +1088,8 @@ created: |
871 | |
872 | A notification was added: |
873 | |
874 | - >>> bug_notification = BugNotification.selectFirst(orderBy='-id') |
875 | + >>> bug_notification = IStore(BugNotification).find( |
876 | + ... BugNotification).order_by(BugNotification.id).last() |
877 | >>> print(bug_notification.message.text_contents) |
878 | ** Also affects: debian |
879 | ... |
880 | @@ -1660,7 +1665,8 @@ edited: |
881 | >>> print(linux_task.status.name) |
882 | CONFIRMED |
883 | |
884 | - >>> bug_notification = BugNotification.selectFirst(orderBy='-id') |
885 | + >>> bug_notification = IStore(BugNotification).find( |
886 | + ... BugNotification).order_by(BugNotification.id).last() |
887 | >>> print(bug_notification.bug.id) |
888 | 10 |
889 | >>> print(bug_notification.message.text_contents) |
890 | @@ -1686,8 +1692,9 @@ The user is a bug supervisors of the upstream product |
891 | mozilla-firefox (Ubuntu): New, assigned to no one |
892 | mozilla-firefox (Debian): Confirmed, assigned to no one |
893 | |
894 | - >>> pending_notifications = BugNotification.select( |
895 | - ... orderBy='-id', limit=2) |
896 | + >>> from storm.locals import Desc |
897 | + >>> pending_notifications = IStore(BugNotification).find( |
898 | + ... BugNotification).order_by(Desc(BugNotification.id))[:2] |
899 | >>> for bug_notification in pending_notifications: |
900 | ... print(bug_notification.bug.id) |
901 | ... print(bug_notification.message.text_contents) |
902 | @@ -1727,7 +1734,8 @@ The user is a package bug supervisor |
903 | mozilla-firefox (Ubuntu): Confirmed, assigned to Helge Kreutzmann |
904 | mozilla-firefox (Debian): Confirmed, assigned to no one |
905 | |
906 | - >>> pending_notifications = BugNotification.select(orderBy='-id', limit=2) |
907 | + >>> pending_notifications = IStore(BugNotification).find( |
908 | + ... BugNotification).order_by(Desc(BugNotification.id))[:2] |
909 | >>> for bug_notification in pending_notifications: |
910 | ... print(bug_notification.bug.id) |
911 | ... print(bug_notification.message.text_contents) |
912 | @@ -1758,7 +1766,8 @@ The user is a distribution member |
913 | mozilla-firefox (Ubuntu): New, assigned to Sample Person |
914 | mozilla-firefox (Debian): Confirmed, assigned to no one |
915 | |
916 | - >>> pending_notifications = BugNotification.select(orderBy='-id', limit=2) |
917 | + >>> pending_notifications = IStore(BugNotification).find( |
918 | + ... BugNotification).order_by(Desc(BugNotification.id))[:2] |
919 | >>> for bug_notification in pending_notifications: |
920 | ... print(bug_notification.bug.id) |
921 | ... print(bug_notification.message.text_contents) |
922 | @@ -2452,7 +2461,8 @@ An email may contain more than one attachment; all of them are stored. |
923 | |
924 | A bugnotification is sent for each attached file. |
925 | |
926 | - >>> bug_notifications = BugNotification.select(orderBy='-id', limit=3) |
927 | + >>> bug_notifications = IStore(BugNotification).find( |
928 | + ... BugNotification).order_by(Desc(BugNotification.id))[:3] |
929 | >>> for bug_notification in bug_notifications: |
930 | ... print('-------------------') |
931 | ... print(bug_notification.message.chunks[0].content) |
932 | diff --git a/lib/lp/bugs/tests/bugtarget-questiontarget.txt b/lib/lp/bugs/tests/bugtarget-questiontarget.txt |
933 | index cd2c7e0..2bf90ca 100644 |
934 | --- a/lib/lp/bugs/tests/bugtarget-questiontarget.txt |
935 | +++ b/lib/lp/bugs/tests/bugtarget-questiontarget.txt |
936 | @@ -128,8 +128,11 @@ question and that the bugtasks are Invalid. |
937 | >>> 'test@canonical.com' in recipients.getEmails() |
938 | True |
939 | |
940 | + >>> from storm.locals import Desc |
941 | >>> from lp.bugs.model.bugnotification import BugNotification |
942 | - >>> bug_notifications = BugNotification.select(orderBy='-id') |
943 | + >>> from lp.services.database.interfaces import IStore |
944 | + >>> bug_notifications = IStore(BugNotification).find( |
945 | + ... BugNotification).order_by(Desc(BugNotification.id)) |
946 | >>> for notification in bug_notifications: |
947 | ... print(notification.message.text_contents) |
948 | ** Converted to question: |
949 | diff --git a/lib/lp/bugs/tests/test_bugchanges.py b/lib/lp/bugs/tests/test_bugchanges.py |
950 | index 4f32051..48c74b0 100644 |
951 | --- a/lib/lp/bugs/tests/test_bugchanges.py |
952 | +++ b/lib/lp/bugs/tests/test_bugchanges.py |
953 | @@ -20,6 +20,7 @@ from lp.bugs.interfaces.bugtask import ( |
954 | from lp.bugs.interfaces.cve import ICveSet |
955 | from lp.bugs.model.bugnotification import BugNotification |
956 | from lp.bugs.scripts.bugnotification import construct_email_notifications |
957 | +from lp.services.database.interfaces import IStore |
958 | from lp.services.librarian.browser import ProxiedLibraryFileAlias |
959 | from lp.services.webapp.publisher import canonical_url |
960 | from lp.services.webapp.snapshot import notify_modified |
961 | @@ -80,8 +81,8 @@ class TestBugChanges(TestCaseWithFactory): |
962 | bug = self.bug |
963 | old_activities = set(bug.activity) |
964 | old_notification_ids = set( |
965 | - notification.id for notification in ( |
966 | - BugNotification.selectBy(bug=bug))) |
967 | + notification.id for notification in IStore(BugNotification).find( |
968 | + BugNotification, bug=bug)) |
969 | |
970 | if append: |
971 | self.old_activities.update(old_activities) |
972 | @@ -107,8 +108,8 @@ class TestBugChanges(TestCaseWithFactory): |
973 | def getNewNotifications(self, bug=None): |
974 | if bug is None: |
975 | bug = self.bug |
976 | - bug_notifications = BugNotification.selectBy( |
977 | - bug=bug, orderBy='id') |
978 | + bug_notifications = IStore(BugNotification).find( |
979 | + BugNotification, bug=bug).order_by(BugNotification.id) |
980 | new_notifications = [ |
981 | notification for notification in bug_notifications |
982 | if notification.id not in self.old_notification_ids] |
983 | @@ -1506,8 +1507,8 @@ class TestBugChanges(TestCaseWithFactory): |
984 | |
985 | # Ensure that only the people subscribed to the bug that |
986 | # gets marked as a duplicate are notified. |
987 | - master_notifications = BugNotification.selectBy( |
988 | - bug=self.bug, orderBy='id') |
989 | + master_notifications = IStore(BugNotification).find( |
990 | + BugNotification, bug=self.bug).order_by(BugNotification.id) |
991 | new_notifications = [ |
992 | notification for notification in master_notifications |
993 | if notification.id not in self.old_notification_ids] |
994 | diff --git a/lib/lp/bugs/tests/test_bugnotification.py b/lib/lp/bugs/tests/test_bugnotification.py |
995 | index b0ecfc3..6672082 100644 |
996 | --- a/lib/lp/bugs/tests/test_bugnotification.py |
997 | +++ b/lib/lp/bugs/tests/test_bugnotification.py |
998 | @@ -23,6 +23,7 @@ from lp.bugs.model.bugnotification import ( |
999 | ) |
1000 | from lp.bugs.model.bugsubscriptionfilter import BugSubscriptionFilterMute |
1001 | from lp.services.config import config |
1002 | +from lp.services.database.interfaces import IStore |
1003 | from lp.services.messages.interfaces.message import IMessageSet |
1004 | from lp.services.messages.model.message import MessageSet |
1005 | from lp.services.webapp.snapshot import notify_modified |
1006 | @@ -372,7 +373,8 @@ class TestNotificationsForDuplicates(TestCaseWithFactory): |
1007 | # bug, not to subscribers of the master bug. |
1008 | self.dupe_bug.newMessage( |
1009 | self.dupe_bug.owner, subject='subject', content='content') |
1010 | - latest_notification = BugNotification.selectFirst(orderBy='-id') |
1011 | + latest_notification = IStore(BugNotification).find( |
1012 | + BugNotification).order_by(BugNotification.id).last() |
1013 | recipients = set( |
1014 | recipient.person |
1015 | for recipient in latest_notification.recipients) |
1016 | @@ -383,7 +385,8 @@ class TestNotificationsForDuplicates(TestCaseWithFactory): |
1017 | with notify_modified( |
1018 | self.dupe_bug, ['description'], user=self.dupe_bug.owner): |
1019 | self.dupe_bug.description = 'A changed description' |
1020 | - latest_notification = BugNotification.selectFirst(orderBy='-id') |
1021 | + latest_notification = IStore(BugNotification).find( |
1022 | + BugNotification).order_by(BugNotification.id).last() |
1023 | recipients = set( |
1024 | recipient.person |
1025 | for recipient in latest_notification.recipients) |
1026 | @@ -397,7 +400,8 @@ class TestNotificationsForDuplicates(TestCaseWithFactory): |
1027 | # provided by the Bug.addChange mechanism. |
1028 | branch = self.factory.makeBranch(owner=self.dupe_bug.owner) |
1029 | self.dupe_bug.linkBranch(branch, self.dupe_bug.owner) |
1030 | - latest_notification = BugNotification.selectFirst(orderBy='-id') |
1031 | + latest_notification = IStore(BugNotification).find( |
1032 | + BugNotification).order_by(BugNotification.id).last() |
1033 | recipients = set( |
1034 | recipient.person |
1035 | for recipient in latest_notification.recipients) |
1036 | diff --git a/lib/lp/registry/doc/milestone.txt b/lib/lp/registry/doc/milestone.txt |
1037 | index 2ad094c..5e4b086 100644 |
1038 | --- a/lib/lp/registry/doc/milestone.txt |
1039 | +++ b/lib/lp/registry/doc/milestone.txt |
1040 | @@ -317,8 +317,7 @@ Target change notifications |
1041 | When we change the milestone for a bug task, subscribers to both the old |
1042 | milestone and the new one are notified. |
1043 | |
1044 | - >>> from lp.bugs.model.bugnotification import ( |
1045 | - ... BugNotification) |
1046 | + >>> from lp.bugs.model.bugnotification import BugNotification |
1047 | >>> from lp.bugs.interfaces.bug import IBugSet |
1048 | >>> from lp.registry.interfaces.person import IPersonSet |
1049 | >>> from lp.registry.interfaces.product import IProductSet |
1050 | @@ -353,7 +352,9 @@ change event. |
1051 | A new bug notification is created, and both Celso and David are in the |
1052 | list of recipients. |
1053 | |
1054 | - >>> notification = BugNotification.select("date_emailed IS NULL")[-1] |
1055 | + >>> from lp.services.database.interfaces import IStore |
1056 | + >>> notification = IStore(BugNotification).find( |
1057 | + ... BugNotification, date_emailed=None).last() |
1058 | >>> print notification.message.chunks[0].content |
1059 | ** Changed in: firefox |
1060 | Milestone: 1.0 => 2.0 |
1061 | diff --git a/lib/lp/scripts/tests/test_garbo.py b/lib/lp/scripts/tests/test_garbo.py |
1062 | index 14ba31f..1de59db 100644 |
1063 | --- a/lib/lp/scripts/tests/test_garbo.py |
1064 | +++ b/lib/lp/scripts/tests/test_garbo.py |
1065 | @@ -46,6 +46,7 @@ from zope.security.proxy import removeSecurityProxy |
1066 | |
1067 | from lp.answers.model.answercontact import AnswerContact |
1068 | from lp.app.enums import InformationType |
1069 | +from lp.bugs.interfaces.bug import IBugSet |
1070 | from lp.bugs.model.bugnotification import ( |
1071 | BugNotification, |
1072 | BugNotificationRecipient, |
1073 | @@ -109,6 +110,7 @@ from lp.services.identity.interfaces.emailaddress import EmailAddressStatus |
1074 | from lp.services.job.interfaces.job import JobStatus |
1075 | from lp.services.job.model.job import Job |
1076 | from lp.services.librarian.model import TimeLimitedToken |
1077 | +from lp.services.messages.interfaces.message import IMessageSet |
1078 | from lp.services.messages.model.message import Message |
1079 | from lp.services.openid.model.openidconsumer import OpenIDConsumerNonce |
1080 | from lp.services.scripts.tests import run_script |
1081 | @@ -790,14 +792,18 @@ class TestGarbo(FakeAdapterMixin, TestCaseWithFactory): |
1082 | def test_BugNotificationPruner(self): |
1083 | # Create some sample data |
1084 | switch_dbuser('testadmin') |
1085 | + bug = getUtility(IBugSet).get(1) |
1086 | + message = getUtility(IMessageSet).get( |
1087 | + 'foo@example.com-332342--1231')[0] |
1088 | + person = self.factory.makePerson() |
1089 | notification = BugNotification( |
1090 | - messageID=1, |
1091 | - bugID=1, |
1092 | + message=message, |
1093 | + bug=bug, |
1094 | is_comment=True, |
1095 | date_emailed=None) |
1096 | BugNotificationRecipient( |
1097 | bug_notification=notification, |
1098 | - personID=1, |
1099 | + person=person, |
1100 | reason_header='Whatever', |
1101 | reason_body='Whatever') |
1102 | # We don't create an entry exactly 30 days old to avoid |
1103 | @@ -806,12 +812,12 @@ class TestGarbo(FakeAdapterMixin, TestCaseWithFactory): |
1104 | message = Message(rfc822msgid=str(delta)) |
1105 | notification = BugNotification( |
1106 | message=message, |
1107 | - bugID=1, |
1108 | + bug=bug, |
1109 | is_comment=True, |
1110 | date_emailed=UTC_NOW + SQL("interval '%d days'" % delta)) |
1111 | BugNotificationRecipient( |
1112 | bug_notification=notification, |
1113 | - personID=1, |
1114 | + person=person, |
1115 | reason_header='Whatever', |
1116 | reason_body='Whatever') |
1117 | |
1118 | diff --git a/lib/lp/soyuz/doc/closing-bugs-from-changelogs.txt b/lib/lp/soyuz/doc/closing-bugs-from-changelogs.txt |
1119 | index d4c42cc..75f99ff 100644 |
1120 | --- a/lib/lp/soyuz/doc/closing-bugs-from-changelogs.txt |
1121 | +++ b/lib/lp/soyuz/doc/closing-bugs-from-changelogs.txt |
1122 | @@ -146,8 +146,10 @@ comment addition. The both notifications will be batched together into a |
1123 | single email later. |
1124 | |
1125 | >>> from lp.bugs.model.bugnotification import BugNotification |
1126 | - >>> notifications = BugNotification.select(orderBy='id') |
1127 | - >>> for notification in notifications[-2:]: |
1128 | + >>> from lp.services.database.interfaces import IStore |
1129 | + >>> notifications = IStore(BugNotification).find( |
1130 | + ... BugNotification).order_by(BugNotification.id) |
1131 | + >>> for notification in list(notifications)[-2:]: |
1132 | ... print("From %s:\n%s\n" % ( |
1133 | ... notification.message.owner.displayname, |
1134 | ... notification.message.text_contents)) |
1135 | @@ -178,7 +180,8 @@ packages are synced from Debian. |
1136 | |
1137 | >>> close_bugs_for_queue_item(queue_item) |
1138 | |
1139 | - >>> notifications = BugNotification.select(orderBy='id') |
1140 | + >>> notifications = IStore(BugNotification).find( |
1141 | + ... BugNotification).order_by(BugNotification.id) |
1142 | >>> new_notifications = notifications[number_of_old_notifications:] |
1143 | >>> [notification.message.text_contents |
1144 | ... for notification in new_notifications] |