Merge lp:~gary/launchpad/bug164196-3 into lp:launchpad/db-devel

Proposed by Gary Poster
Status: Merged
Approved by: Gary Poster
Approved revision: no longer in the source branch.
Merged at revision: 10215
Proposed branch: lp:~gary/launchpad/bug164196-3
Merge into: lp:launchpad/db-devel
Prerequisite: lp:~gary/launchpad/bug164196-2
Diff against target: 519 lines (+140/-30)
13 files modified
cronscripts/send-bug-notifications.py (+8/-1)
database/schema/comments.sql (+1/-0)
database/schema/patch-2208-45-0.sql (+12/-0)
lib/lp/bugs/doc/bugnotification-sending.txt (+61/-19)
lib/lp/bugs/doc/bugnotification-threading.txt (+3/-3)
lib/lp/bugs/enum.py (+27/-0)
lib/lp/bugs/interfaces/bugnotification.py (+9/-0)
lib/lp/bugs/mail/tests/test_bug_task_assignment.py (+2/-2)
lib/lp/bugs/mail/tests/test_bug_task_modification.py (+1/-1)
lib/lp/bugs/model/bugnotification.py (+6/-0)
lib/lp/bugs/scripts/bugnotification.py (+4/-1)
lib/lp/bugs/scripts/tests/test_bugnotification.py (+4/-2)
lib/lp/bugs/tests/test_bugchanges.py (+2/-1)
To merge this branch: bzr merge lp:~gary/launchpad/bug164196-3
Reviewer Review Type Date Requested Status
Robert Collins (community) Approve
Stuart Bishop (community) db Approve
Aaron Bentley (community) Approve
Review via email: mp+49980@code.launchpad.net

Commit message

[r=abentley,stub][bug=164196] makes sure that the omitted notification objects left over from duplicate actions are marked as processed so that they are not perpetually considered for subsequent notification cronscript runs.

Description of the change

This is the last of three branches that address bug 164196, and one of two that have a database patch. The other two are lp:~gary/launchpad/bug164196-1 and lp:~gary/launchpad/bug164196-3. My pre-implementation call for these changes was with Graham Binns.

This branch makes sure that the omitted notification objects left over from actions in the previous branch are marked as processed so that they are not perpetually considered for subsequent notification cronscript runs. It also marks these omitted notification objects with a flag in case we want to analyze them for debugging later, if we get a report of something gone wrong in this regard.

The database changes simply add the flag as described above.

The code in lib/lp/bugs/scripts/bugnotification.py now includes the omitted notifications so that the cronscript can mark them. This required small changes to a number of tests.

lib/lp/bugs/doc/bugnotification-sending.txt had the test for the cronscript and were a natural place for a smoketest of this behavior.

Thank you

Gary

To post a comment you must log in.
Revision history for this message
Aaron Bentley (abentley) wrote :

Per our IRC discussion, I recommend providing a status enum, rather than just is_omitted. The values could include PENDING, SENT, SKIPPED.

I believe ResultSets support slicing, so it might be clearer in the doctest to get a ResultSet and then slice it.

However, the branch as it stands is a worthwhile improvement, so I'll approve it.

review: Approve
Revision history for this message
Gary Poster (gary) wrote :

I have followed both of Aaron's suggestions, because I agreed that they were nicer. If Stuart prefers a bool after all (presumably because of space reasons), I can revert that bit pretty easily.

Thank you

Revision history for this message
Stuart Bishop (stub) wrote :

patch-2208-45-0.sql

Please add the following statement after the ALTER TABLE (all rows are going to be rewritten, so we want to repack the table):

CLUSTER BugNotification USING bugnotification__date_emailed__idx

Bug notification is regularly trimmed, so there are not too many rows to deal with - should be fast enough for a db patch.

I prefer status rather than the boolean too.

review: Approve (db)
Revision history for this message
Robert Collins (lifeless) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'cronscripts/send-bug-notifications.py'
--- cronscripts/send-bug-notifications.py 2010-11-08 12:52:43 +0000
+++ cronscripts/send-bug-notifications.py 2011-02-17 17:43:44 +0000
@@ -20,6 +20,7 @@
20from canonical.config import config20from canonical.config import config
21from canonical.database.constants import UTC_NOW21from canonical.database.constants import UTC_NOW
22from canonical.launchpad.mail import sendmail22from canonical.launchpad.mail import sendmail
23from lp.bugs.enum import BugNotificationStatus
23from lp.bugs.interfaces.bugnotification import IBugNotificationSet24from lp.bugs.interfaces.bugnotification import IBugNotificationSet
24from lp.bugs.scripts.bugnotification import get_email_notifications25from lp.bugs.scripts.bugnotification import get_email_notifications
25from lp.services.scripts.base import LaunchpadCronScript26from lp.services.scripts.base import LaunchpadCronScript
@@ -30,7 +31,9 @@
30 notifications_sent = False31 notifications_sent = False
31 pending_notifications = get_email_notifications(getUtility(32 pending_notifications = get_email_notifications(getUtility(
32 IBugNotificationSet).getNotificationsToSend())33 IBugNotificationSet).getNotificationsToSend())
33 for bug_notifications, messages in pending_notifications:34 for (bug_notifications,
35 omitted_notifications,
36 messages) in pending_notifications:
34 for message in messages:37 for message in messages:
35 self.logger.info("Notifying %s about bug %d." % (38 self.logger.info("Notifying %s about bug %d." % (
36 message['To'], bug_notifications[0].bug.id))39 message['To'], bug_notifications[0].bug.id))
@@ -38,6 +41,10 @@
38 self.logger.debug(message.as_string())41 self.logger.debug(message.as_string())
39 for notification in bug_notifications:42 for notification in bug_notifications:
40 notification.date_emailed = UTC_NOW43 notification.date_emailed = UTC_NOW
44 notification.status = BugNotificationStatus.SENT
45 for notification in omitted_notifications:
46 notification.date_emailed = UTC_NOW
47 notification.status = BugNotificationStatus.OMITTED
41 notifications_sent = True48 notifications_sent = True
42 # Commit after each batch of email sent, so that we won't49 # Commit after each batch of email sent, so that we won't
43 # re-mail the notifications in case of something going wrong50 # re-mail the notifications in case of something going wrong
4451
=== modified file 'database/schema/comments.sql'
--- database/schema/comments.sql 2011-02-17 17:43:43 +0000
+++ database/schema/comments.sql 2011-02-17 17:43:44 +0000
@@ -281,6 +281,7 @@
281COMMENT ON COLUMN BugNotification.is_comment IS 'Is the change a comment addition.';281COMMENT ON COLUMN BugNotification.is_comment IS 'Is the change a comment addition.';
282COMMENT ON COLUMN BugNotification.date_emailed IS 'When this notification was emailed to the bug subscribers.';282COMMENT ON COLUMN BugNotification.date_emailed IS 'When this notification was emailed to the bug subscribers.';
283COMMENT ON COLUMN BugNotification.activity IS 'The BugActivity record corresponding to this notification, if any.';283COMMENT ON COLUMN BugNotification.activity IS 'The BugActivity record corresponding to this notification, if any.';
284COMMENT ON COLUMN BugNotification.status IS 'The status of this bug notification: pending, omitted, or sent.';
284285
285286
286-- BugNotificationAttachment287-- BugNotificationAttachment
287288
=== added file 'database/schema/patch-2208-45-0.sql'
--- database/schema/patch-2208-45-0.sql 1970-01-01 00:00:00 +0000
+++ database/schema/patch-2208-45-0.sql 2011-02-17 17:43:44 +0000
@@ -0,0 +1,12 @@
1-- Copyright 2011 Canonical Ltd. This software is licensed under the
2-- GNU Affero General Public License version 3 (see the file LICENSE).
3SET client_min_messages=ERROR;
4
5-- The default value for status can be found in the
6-- BugNotificationStatus DBEnum in lib/lp/bugs/enum.py.
7ALTER TABLE BugNotification
8 ADD COLUMN status INTEGER NOT NULL DEFAULT 10;
9
10CLUSTER BugNotification USING bugnotification__date_emailed__idx;
11
12INSERT INTO LaunchpadDatabaseRevision VALUES (2208, 45, 0);
013
=== modified file 'lib/lp/bugs/doc/bugnotification-sending.txt'
--- lib/lp/bugs/doc/bugnotification-sending.txt 2011-02-17 17:43:43 +0000
+++ lib/lp/bugs/doc/bugnotification-sending.txt 2011-02-17 17:43:44 +0000
@@ -63,7 +63,7 @@
63 >>> from lp.bugs.scripts.bugnotification import (63 >>> from lp.bugs.scripts.bugnotification import (
64 ... get_email_notifications)64 ... get_email_notifications)
65 >>> email_notifications = get_email_notifications(notifications)65 >>> email_notifications = get_email_notifications(notifications)
66 >>> for bug_notifications, messages in email_notifications:66 >>> for bug_notifications, omitted, messages in email_notifications:
67 ... for message in messages:67 ... for message in messages:
68 ... print_notification(message)68 ... print_notification(message)
69 To: foo.bar@canonical.com69 To: foo.bar@canonical.com
@@ -176,7 +176,7 @@
176 >>> pending_notifications = getUtility(176 >>> pending_notifications = getUtility(
177 ... IBugNotificationSet).getNotificationsToSend()177 ... IBugNotificationSet).getNotificationsToSend()
178 >>> email_notifications = get_email_notifications(pending_notifications)178 >>> email_notifications = get_email_notifications(pending_notifications)
179 >>> for bug_notifications, messages in email_notifications:179 >>> for bug_notifications, omitted, messages in email_notifications:
180 ... for message in messages:180 ... for message in messages:
181 ... print_notification(message)181 ... print_notification(message)
182 To: foo.bar@canonical.com182 To: foo.bar@canonical.com
@@ -222,7 +222,7 @@
222 2222 2
223223
224 >>> email_notifications = get_email_notifications(pending_notifications)224 >>> email_notifications = get_email_notifications(pending_notifications)
225 >>> for bug_notifications, messages in email_notifications:225 >>> for bug_notifications, omitted, messages in email_notifications:
226 ... for message in messages:226 ... for message in messages:
227 ... print_notification(message)227 ... print_notification(message)
228 To: foo.bar@canonical.com228 To: foo.bar@canonical.com
@@ -275,7 +275,7 @@
275in the order they were added:275in the order they were added:
276276
277 >>> email_notifications = get_email_notifications(pending_notifications)277 >>> email_notifications = get_email_notifications(pending_notifications)
278 >>> for bug_notifications, messages in email_notifications:278 >>> for bug_notifications, omitted, messages in email_notifications:
279 ... for message in messages:279 ... for message in messages:
280 ... print_notification(message)280 ... print_notification(message)
281 To: foo.bar@canonical.com281 To: foo.bar@canonical.com
@@ -371,7 +371,7 @@
371 1371 1
372372
373 >>> email_notifications = get_email_notifications(pending_notifications)373 >>> email_notifications = get_email_notifications(pending_notifications)
374 >>> for bug_notifications, messages in email_notifications:374 >>> for bug_notifications, omitted, messages in email_notifications:
375 ... for message in messages:375 ... for message in messages:
376 ... print message['To']376 ... print message['To']
377 foo.bar@canonical.com377 foo.bar@canonical.com
@@ -414,7 +414,7 @@
414 >>> len(notifications)414 >>> len(notifications)
415 1415 1
416416
417 >>> for bug_notifications, messages in (417 >>> for bug_notifications, omitted, messages in (
418 ... get_email_notifications(notifications)):418 ... get_email_notifications(notifications)):
419 ... for message in messages:419 ... for message in messages:
420 ... print_notification(message)420 ... print_notification(message)
@@ -485,7 +485,7 @@
485 >>> notifications = (485 >>> notifications = (
486 ... getUtility(IBugNotificationSet).getNotificationsToSend())486 ... getUtility(IBugNotificationSet).getNotificationsToSend())
487 >>> email_notifications = get_email_notifications(notifications)487 >>> email_notifications = get_email_notifications(notifications)
488 >>> for bug_notifications, messages in email_notifications:488 >>> for bug_notifications, omitted, messages in email_notifications:
489 ... for message in messages:489 ... for message in messages:
490 ... print_notification(message)490 ... print_notification(message)
491 To: support@ubuntu.com491 To: support@ubuntu.com
@@ -509,7 +509,7 @@
509 >>> notifications = (509 >>> notifications = (
510 ... getUtility(IBugNotificationSet).getNotificationsToSend())510 ... getUtility(IBugNotificationSet).getNotificationsToSend())
511 >>> email_notifications = get_email_notifications(notifications)511 >>> email_notifications = get_email_notifications(notifications)
512 >>> for bug_notifications, messages in email_notifications:512 >>> for bug_notifications, omitted, messages in email_notifications:
513 ... for message in messages:513 ... for message in messages:
514 ... print_notification(message)514 ... print_notification(message)
515 To: support@ubuntu.com515 To: support@ubuntu.com
@@ -556,11 +556,19 @@
556 ... BugTitleChange(556 ... BugTitleChange(
557 ... ten_minutes_ago, sample_person, "title",557 ... ten_minutes_ago, sample_person, "title",
558 ... "Old summary", "New summary"))558 ... "Old summary", "New summary"))
559 >>> bug_two.addChange(
560 ... BugVisibilityChange(
561 ... ten_minutes_ago, sample_person, "title",
562 ... False, True))
563 >>> bug_two.addChange(
564 ... BugVisibilityChange(
565 ... ten_minutes_ago, sample_person, "title",
566 ... True, False))
559567
560 >>> notifications = getUtility(568 >>> notifications = getUtility(
561 ... IBugNotificationSet).getNotificationsToSend()569 ... IBugNotificationSet).getNotificationsToSend()
562 >>> len(notifications)570 >>> len(notifications)
563 6571 8
564572
565We need to commit the transaction so that the cronscript will see the573We need to commit the transaction so that the cronscript will see the
566notifications.574notifications.
@@ -648,7 +656,41 @@
648 INFO Notifying test@canonical.com about bug 1.656 INFO Notifying test@canonical.com about bug 1.
649 ...657 ...
650658
651 >>> flush_notifications()659Note that the message omitted the undone visibility change.
660
661The cronscript has to be sure to mark all notifications, omitted and
662otherwise, as sent. It also marks the omitted notifications with a status,
663so if there are any problems we can identify which notifications were omitted
664during analysis. We'll commit a transaction to synchronize the database,
665and then look at the notifications available.
666
667 >>> transaction.commit()
668
669 >>> notifications = getUtility(
670 ... IBugNotificationSet).getNotificationsToSend()
671 >>> len(notifications)
672 0
673
674They have all been marked as sent, including the omitted ones. Let's look
675more carefully at the notifications just to see that the status has
676been set properly.
677
678 >>> from lp.bugs.model.bugnotification import BugNotification
679 >>> from lp.bugs.enum import BugNotificationStatus
680 >>> for notification in BugNotification.select(orderBy='id')[-8:]:
681 ... if notification.is_comment:
682 ... identifier = 'comment'
683 ... else:
684 ... identifier = notification.activity.whatchanged
685 ... print identifier, notification.status.title
686 comment Sent
687 summary Sent
688 comment Sent
689 summary Sent
690 comment Sent
691 summary Sent
692 visibility Omitted
693 visibility Omitted
652694
653695
654The X-Launchpad-Bug header696The X-Launchpad-Bug header
@@ -673,7 +715,7 @@
673X-Launchpad-Bug headers were added:715X-Launchpad-Bug headers were added:
674716
675 >>> email_notifications = get_email_notifications(notifications)717 >>> email_notifications = get_email_notifications(notifications)
676 >>> for bug_notifications, messages in email_notifications:718 >>> for bug_notifications, omitted, messages in email_notifications:
677 ... for message in messages:719 ... for message in messages:
678 ... sorted(message.get_all('X-Launchpad-Bug'))720 ... sorted(message.get_all('X-Launchpad-Bug'))
679 [u'distribution=debian; distroseries=sarge;... milestone=3.1;...',721 [u'distribution=debian; distroseries=sarge;... milestone=3.1;...',
@@ -707,7 +749,7 @@
707749
708 >>> def get_email_messages(notifications):750 >>> def get_email_messages(notifications):
709 ... messages = (message751 ... messages = (message
710 ... for bug_notifications, messages in752 ... for bug_notifications, omitted, messages in
711 ... get_email_notifications(notifications)753 ... get_email_notifications(notifications)
712 ... for message in messages)754 ... for message in messages)
713 ... return sorted(messages, key=lambda message: message['To'])755 ... return sorted(messages, key=lambda message: message['To'])
@@ -963,7 +1005,7 @@
9631005
964 >>> from itertools import chain1006 >>> from itertools import chain
965 >>> collated_messages = collate_messages_by_recipient(1007 >>> collated_messages = collate_messages_by_recipient(
966 ... chain(*(messages for bug_notifications, messages in1008 ... chain(*(messages for bug_notifications, omitted, messages in
967 ... get_email_notifications(notifications))))1009 ... get_email_notifications(notifications))))
9681010
969We can see that Concise Person doesn't receive verbose notifications:1011We can see that Concise Person doesn't receive verbose notifications:
@@ -1151,7 +1193,7 @@
1151 >>> pending_notifications = getUtility(1193 >>> pending_notifications = getUtility(
1152 ... IBugNotificationSet).getNotificationsToSend()1194 ... IBugNotificationSet).getNotificationsToSend()
1153 >>> email_notifications = get_email_notifications(pending_notifications)1195 >>> email_notifications = get_email_notifications(pending_notifications)
1154 >>> for bug_notifications, messages in email_notifications:1196 >>> for bug_notifications, omitted, messages in email_notifications:
1155 ... for message in messages:1197 ... for message in messages:
1156 ... print_notification(message)1198 ... print_notification(message)
1157 To: foo.bar@canonical.com1199 To: foo.bar@canonical.com
@@ -1212,7 +1254,7 @@
1212 >>> pending_notifications = getUtility(1254 >>> pending_notifications = getUtility(
1213 ... IBugNotificationSet).getNotificationsToSend()1255 ... IBugNotificationSet).getNotificationsToSend()
1214 >>> email_notifications = get_email_notifications(pending_notifications)1256 >>> email_notifications = get_email_notifications(pending_notifications)
1215 >>> for bug_notifications, messages in email_notifications:1257 >>> for bug_notifications, omitted, messages in email_notifications:
1216 ... for message in messages:1258 ... for message in messages:
1217 ... print_notification(message)1259 ... print_notification(message)
1218 To: foo.bar@canonical.com1260 To: foo.bar@canonical.com
@@ -1271,7 +1313,7 @@
1271 >>> pending_notifications = getUtility(1313 >>> pending_notifications = getUtility(
1272 ... IBugNotificationSet).getNotificationsToSend()1314 ... IBugNotificationSet).getNotificationsToSend()
1273 >>> email_notifications = get_email_notifications(pending_notifications)1315 >>> email_notifications = get_email_notifications(pending_notifications)
1274 >>> for bug_notifications, messages in email_notifications:1316 >>> for bug_notifications, omitted, messages in email_notifications:
1275 ... for message in messages:1317 ... for message in messages:
1276 ... print_notification(message)1318 ... print_notification(message)
1277 To: foo.bar@canonical.com1319 To: foo.bar@canonical.com
@@ -1322,7 +1364,7 @@
1322 >>> pending_notifications = getUtility(1364 >>> pending_notifications = getUtility(
1323 ... IBugNotificationSet).getNotificationsToSend()1365 ... IBugNotificationSet).getNotificationsToSend()
1324 >>> email_notifications = get_email_notifications(pending_notifications)1366 >>> email_notifications = get_email_notifications(pending_notifications)
1325 >>> for bug_notifications, messages in email_notifications:1367 >>> for bug_notifications, omitted, messages in email_notifications:
1326 ... for message in messages:1368 ... for message in messages:
1327 ... print_notification(message)1369 ... print_notification(message)
1328 To: foo.bar@canonical.com1370 To: foo.bar@canonical.com
@@ -1386,7 +1428,7 @@
1386 >>> pending_notifications = getUtility(1428 >>> pending_notifications = getUtility(
1387 ... IBugNotificationSet).getNotificationsToSend()1429 ... IBugNotificationSet).getNotificationsToSend()
1388 >>> email_notifications = get_email_notifications(pending_notifications)1430 >>> email_notifications = get_email_notifications(pending_notifications)
1389 >>> for bug_notifications, messages in email_notifications:1431 >>> for bug_notifications, omitted, messages in email_notifications:
1390 ... for message in messages:1432 ... for message in messages:
1391 ... print_notification(message)1433 ... print_notification(message)
1392 To: foo.bar@canonical.com1434 To: foo.bar@canonical.com
@@ -1448,7 +1490,7 @@
1448 >>> pending_notifications = getUtility(1490 >>> pending_notifications = getUtility(
1449 ... IBugNotificationSet).getNotificationsToSend()1491 ... IBugNotificationSet).getNotificationsToSend()
1450 >>> email_notifications = get_email_notifications(pending_notifications)1492 >>> email_notifications = get_email_notifications(pending_notifications)
1451 >>> for bug_notifications, messages in email_notifications:1493 >>> for bug_notifications, omitted, messages in email_notifications:
1452 ... for message in messages:1494 ... for message in messages:
1453 ... print_notification(message)1495 ... print_notification(message)
1454 To: foo.bar@canonical.com1496 To: foo.bar@canonical.com
14551497
=== modified file 'lib/lp/bugs/doc/bugnotification-threading.txt'
--- lib/lp/bugs/doc/bugnotification-threading.txt 2011-02-02 17:33:21 +0000
+++ lib/lp/bugs/doc/bugnotification-threading.txt 2011-02-17 17:43:44 +0000
@@ -35,7 +35,7 @@
35 >>> notifications = getUtility(35 >>> notifications = getUtility(
36 ... IBugNotificationSet).getNotificationsToSend()36 ... IBugNotificationSet).getNotificationsToSend()
3737
38 >>> messages = [emails for dummy, emails in38 >>> messages = [emails for notifications, omitted, emails in
39 ... get_email_notifications(notifications)]39 ... get_email_notifications(notifications)]
40 >>> len(messages)40 >>> len(messages)
41 141 1
@@ -73,7 +73,7 @@
73 ... True, False))73 ... True, False))
74 >>> notifications = getUtility(74 >>> notifications = getUtility(
75 ... IBugNotificationSet).getNotificationsToSend()75 ... IBugNotificationSet).getNotificationsToSend()
76 >>> messages = [emails for dummy, emails in76 >>> messages = [emails for notifications, omitted, emails in
77 ... get_email_notifications(notifications)]77 ... get_email_notifications(notifications)]
78 >>> len(messages)78 >>> len(messages)
79 179 1
@@ -106,7 +106,7 @@
106106
107 >>> notifications = getUtility(107 >>> notifications = getUtility(
108 ... IBugNotificationSet).getNotificationsToSend()108 ... IBugNotificationSet).getNotificationsToSend()
109 >>> messages = [emails for dummy, emails in109 >>> messages = [emails for notifications, omitted, emails in
110 ... get_email_notifications(notifications)]110 ... get_email_notifications(notifications)]
111 >>> len(messages)111 >>> len(messages)
112 1112 1
113113
=== modified file 'lib/lp/bugs/enum.py'
--- lib/lp/bugs/enum.py 2011-02-01 17:52:45 +0000
+++ lib/lp/bugs/enum.py 2011-02-17 17:43:44 +0000
@@ -6,6 +6,7 @@
6__metaclass__ = type6__metaclass__ = type
7__all__ = [7__all__ = [
8 'BugNotificationLevel',8 'BugNotificationLevel',
9 'BugNotificationStatus',
9 ]10 ]
1011
11from lazr.enum import (12from lazr.enum import (
@@ -47,3 +48,29 @@
47 notifications about new events in the bugs's discussion, like new48 notifications about new events in the bugs's discussion, like new
48 comments.49 comments.
49 """)50 """)
51
52
53class BugNotificationStatus(DBEnumeratedType):
54 """The status of a bug notification.
55
56 A notification may be pending, sent, or omitted."""
57
58 PENDING = DBItem(10, """
59 Pending
60
61 The notification has not yet been sent.
62 """)
63
64 OMITTED = DBItem(20, """
65 Omitted
66
67 The system considered sending the notification, but omitted it.
68 This is generally because the action reported by the notification
69 was immediately undone.
70 """)
71
72 SENT = DBItem(30, """
73 Sent
74
75 The notification has been sent.
76 """)
5077
=== modified file 'lib/lp/bugs/interfaces/bugnotification.py'
--- lib/lp/bugs/interfaces/bugnotification.py 2011-02-17 17:43:43 +0000
+++ lib/lp/bugs/interfaces/bugnotification.py 2011-02-17 17:43:44 +0000
@@ -18,11 +18,13 @@
18 )18 )
19from zope.schema import (19from zope.schema import (
20 Bool,20 Bool,
21 Choice,
21 Datetime,22 Datetime,
22 TextLine,23 TextLine,
23 )24 )
2425
25from canonical.launchpad import _26from canonical.launchpad import _
27from lp.bugs.enum import BugNotificationStatus
26from lp.registry.interfaces.role import IHasOwner28from lp.registry.interfaces.role import IHasOwner
27from lp.services.fields import BugField29from lp.services.fields import BugField
2830
@@ -51,6 +53,13 @@
51 required=False)53 required=False)
52 recipients = Attribute(54 recipients = Attribute(
53 "The people to which this notification should be sent.")55 "The people to which this notification should be sent.")
56 status = Choice(
57 title=_("Status"), required=True,
58 vocabulary=BugNotificationStatus,
59 default=BugNotificationStatus.PENDING,
60 description=_(
61 "The status of this bug notification."),
62 )
5463
5564
56class IBugNotificationSet(Interface):65class IBugNotificationSet(Interface):
5766
=== modified file 'lib/lp/bugs/mail/tests/test_bug_task_assignment.py'
--- lib/lp/bugs/mail/tests/test_bug_task_assignment.py 2010-12-21 19:11:49 +0000
+++ lib/lp/bugs/mail/tests/test_bug_task_assignment.py 2011-02-17 17:43:44 +0000
@@ -90,7 +90,7 @@
90 self.bug_task, self.bug_task_before_modification,90 self.bug_task, self.bug_task_before_modification,
91 ['assignee'], user=self.user))91 ['assignee'], user=self.user))
92 latest_notification = BugNotification.selectFirst(orderBy='-id')92 latest_notification = BugNotification.selectFirst(orderBy='-id')
93 notifications, messages = construct_email_notifications(93 notifications, omitted, messages = construct_email_notifications(
94 [latest_notification])94 [latest_notification])
95 self.assertEqual(len(notifications), 1,95 self.assertEqual(len(notifications), 1,
96 'email notication not created')96 'email notication not created')
@@ -107,7 +107,7 @@
107 self.bug_task, self.bug_task_before_modification,107 self.bug_task, self.bug_task_before_modification,
108 ['assignee'], user=self.user))108 ['assignee'], user=self.user))
109 latest_notification = BugNotification.selectFirst(orderBy='-id')109 latest_notification = BugNotification.selectFirst(orderBy='-id')
110 notifications, messages = construct_email_notifications(110 notifications, omitted, messages = construct_email_notifications(
111 [latest_notification])111 [latest_notification])
112 self.assertEqual(len(notifications), 1,112 self.assertEqual(len(notifications), 1,
113 'email notification not created')113 'email notification not created')
114114
=== modified file 'lib/lp/bugs/mail/tests/test_bug_task_modification.py'
--- lib/lp/bugs/mail/tests/test_bug_task_modification.py 2010-10-04 19:50:45 +0000
+++ lib/lp/bugs/mail/tests/test_bug_task_modification.py 2011-02-17 17:43:44 +0000
@@ -44,7 +44,7 @@
44 ['status'], user=self.user))44 ['status'], user=self.user))
45 transaction.commit()45 transaction.commit()
46 latest_notification = BugNotification.selectFirst(orderBy='-id')46 latest_notification = BugNotification.selectFirst(orderBy='-id')
47 notifications, messages = construct_email_notifications(47 notifications, omitted, messages = construct_email_notifications(
48 [latest_notification])48 [latest_notification])
49 self.assertEqual(len(notifications), 1,49 self.assertEqual(len(notifications), 1,
50 'email notification not created')50 'email notification not created')
5151
=== modified file 'lib/lp/bugs/model/bugnotification.py'
--- lib/lp/bugs/model/bugnotification.py 2011-02-17 17:43:43 +0000
+++ lib/lp/bugs/model/bugnotification.py 2011-02-17 17:43:44 +0000
@@ -28,10 +28,12 @@
2828
29from canonical.config import config29from canonical.config import config
30from canonical.database.datetimecol import UtcDateTimeCol30from canonical.database.datetimecol import UtcDateTimeCol
31from canonical.database.enumcol import EnumCol
31from canonical.database.sqlbase import (32from canonical.database.sqlbase import (
32 SQLBase,33 SQLBase,
33 sqlvalues,34 sqlvalues,
34 )35 )
36from lp.bugs.enum import BugNotificationStatus
35from lp.bugs.interfaces.bugnotification import (37from lp.bugs.interfaces.bugnotification import (
36 IBugNotification,38 IBugNotification,
37 IBugNotificationRecipient,39 IBugNotificationRecipient,
@@ -49,6 +51,10 @@
49 bug = ForeignKey(dbName='bug', notNull=True, foreignKey='Bug')51 bug = ForeignKey(dbName='bug', notNull=True, foreignKey='Bug')
50 is_comment = BoolCol(notNull=True)52 is_comment = BoolCol(notNull=True)
51 date_emailed = UtcDateTimeCol(notNull=False)53 date_emailed = UtcDateTimeCol(notNull=False)
54 status = EnumCol(
55 dbName='status',
56 schema=BugNotificationStatus, default=BugNotificationStatus.PENDING,
57 notNull=True)
5258
53 @property59 @property
54 def recipients(self):60 def recipients(self):
5561
=== modified file 'lib/lp/bugs/scripts/bugnotification.py'
--- lib/lp/bugs/scripts/bugnotification.py 2011-02-17 17:43:43 +0000
+++ lib/lp/bugs/scripts/bugnotification.py 2011-02-17 17:43:44 +0000
@@ -97,6 +97,7 @@
9797
98 recipients = {}98 recipients = {}
99 filtered_notifications = []99 filtered_notifications = []
100 omitted_notifications = []
100 for notification in bug_notifications:101 for notification in bug_notifications:
101 key = get_activity_key(notification)102 key = get_activity_key(notification)
102 if (notification.is_comment or103 if (notification.is_comment or
@@ -111,6 +112,8 @@
111 email_people.remove(actor)112 email_people.remove(actor)
112 for email_person in email_people:113 for email_person in email_people:
113 recipients[email_person] = recipient114 recipients[email_person] = recipient
115 else:
116 omitted_notifications.append(notification)
114117
115 if bug.duplicateof is not None:118 if bug.duplicateof is not None:
116 text_notifications.append(119 text_notifications.append(
@@ -203,7 +206,7 @@
203 rationale, references, msgid)206 rationale, references, msgid)
204 messages.append(msg)207 messages.append(msg)
205208
206 return filtered_notifications, messages209 return filtered_notifications, omitted_notifications, messages
207210
208211
209def notification_comment_batches(notifications):212def notification_comment_batches(notifications):
210213
=== modified file 'lib/lp/bugs/scripts/tests/test_bugnotification.py'
--- lib/lp/bugs/scripts/tests/test_bugnotification.py 2011-02-17 17:43:43 +0000
+++ lib/lp/bugs/scripts/tests/test_bugnotification.py 2011-02-17 17:43:44 +0000
@@ -248,7 +248,7 @@
248 email_notifications = get_email_notifications(notifications_to_send)248 email_notifications = get_email_notifications(notifications_to_send)
249 to_addresses = set()249 to_addresses = set()
250 sent_notifications = []250 sent_notifications = []
251 for notifications, messages in email_notifications:251 for notifications, omitted, messages in email_notifications:
252 for message in messages:252 for message in messages:
253 to_addresses.add(message['to'])253 to_addresses.add(message['to'])
254 recipients = {}254 recipients = {}
@@ -572,7 +572,9 @@
572 def get_messages(self):572 def get_messages(self):
573 notifications = self.notification_set.getNotificationsToSend()573 notifications = self.notification_set.getNotificationsToSend()
574 email_notifications = get_email_notifications(notifications)574 email_notifications = get_email_notifications(notifications)
575 for bug_notifications, messages in email_notifications:575 for (bug_notifications,
576 omitted_notifications,
577 messages) in email_notifications:
576 for message in messages:578 for message in messages:
577 yield message, message.get_payload(decode=True)579 yield message, message.get_payload(decode=True)
578580
579581
=== modified file 'lib/lp/bugs/tests/test_bugchanges.py'
--- lib/lp/bugs/tests/test_bugchanges.py 2011-02-17 17:43:43 +0000
+++ lib/lp/bugs/tests/test_bugchanges.py 2011-02-17 17:43:44 +0000
@@ -183,7 +183,8 @@
183183
184 def assertRecipients(self, expected_recipients):184 def assertRecipients(self, expected_recipients):
185 notifications = self.getNewNotifications()185 notifications = self.getNewNotifications()
186 notifications, messages = construct_email_notifications(notifications)186 notifications, omitted, messages = construct_email_notifications(
187 notifications)
187 recipients = set(message['to'] for message in messages)188 recipients = set(message['to'] for message in messages)
188189
189 self.assertEqual(190 self.assertEqual(

Subscribers

People subscribed via source and target branches

to status/vote changes: