Merge lp:~gmb/launchpad/team-subscription-opt-out into lp:launchpad/db-devel

Proposed by Graham Binns
Status: Merged
Merged at revision: 10390
Proposed branch: lp:~gmb/launchpad/team-subscription-opt-out
Merge into: lp:launchpad/db-devel
Diff against target: 225 lines (+100/-3)
7 files modified
database/schema/comments.sql (+6/-0)
database/schema/patch-2208-58-0.sql (+25/-0)
database/schema/security.cfg (+2/-0)
lib/lp/bugs/configure.zcml (+11/-0)
lib/lp/bugs/interfaces/bugsubscriptionfilter.py (+20/-1)
lib/lp/bugs/model/bugsubscriptionfilter.py (+33/-2)
lib/lp/registry/model/person.py (+3/-0)
To merge this branch: bzr merge lp:~gmb/launchpad/team-subscription-opt-out
Reviewer Review Type Date Requested Status
Stuart Bishop (community) db Approve
Gavin Panella (community) code Approve
Robert Collins db Pending
Review via email: mp+55779@code.launchpad.net

Commit message

[r=allenap,stub][ui=none][bug=751173][incr] A BugSubscriptionFilterMute table has been added to the database.

Description of the change

This branch adds a BugSubscriptionFilterMute table to the database and
its associated interface and model to the tree.

The idea behind BugSubscriptionFilterMute is that people should be able
to mute team subscriptions if they want to. The story being that:

 As a member of ~launchpad
 I want to be able to mute emails that I would receive because
 ~launchpad is structurally subscribed to a project
 So that I don't have to read bug mail in which I'm not interested.

To post a comment you must log in.
Revision history for this message
Gavin Panella (allenap) wrote :

All looks good, but perhaps there ought to be some tests for the basics, like adding to and removing from the store.

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

Some discussion on IRC. The following version is approved as patch-2208-58-0.sql:

-- Copyright 2011 Canonical Ltd. This software is licensed under the
-- GNU Affero General Public License version 3 (see the file LICENSE).

SET client_min_messages=ERROR;

-- A table to store subscription mutes in.

CREATE TABLE BugSubscriptionFilterMute (
    person integer REFERENCES Person(id)
        ON DELETE CASCADE NOT NULL,
    filter integer REFERENCES BugSubscriptionFilter(id)
        ON DELETE CASCADE NOT NULL,
    date_created timestamp without time zone
        DEFAULT timezone('UTC'::text, now()) NOT NULL,
    CONSTRAINT bugsubscriptionfiltermute_pkey PRIMARY KEY (person, filter)
);

-- We don't need an index on person, as the primary key index can be used
-- for those lookups. We have an index on just filter, as the bulk of our
-- lookups will be on filter.
CREATE INDEX bugsubscriptionfiltermute__filter__idx
    ON BugSubscriptionFilterMute(filter);

INSERT INTO LaunchpadDatabaseRevision VALUES (2208, 58, 0);

review: Approve (db)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'database/schema/comments.sql'
--- database/schema/comments.sql 2011-03-29 10:17:46 +0000
+++ database/schema/comments.sql 2011-04-04 12:32:01 +0000
@@ -231,6 +231,12 @@
231COMMENT ON COLUMN BugSubscriptionFilterTag.tag IS 'A bug tag.';231COMMENT ON COLUMN BugSubscriptionFilterTag.tag IS 'A bug tag.';
232COMMENT ON COLUMN BugSubscriptionFilterTag.include IS 'If True, send only messages for bugs having this tag, else send only messages for bugs which do not have this tag.';232COMMENT ON COLUMN BugSubscriptionFilterTag.include IS 'If True, send only messages for bugs having this tag, else send only messages for bugs which do not have this tag.';
233233
234-- BugSubscriptionFilterMute
235COMMENT ON TABLE BugSubscriptionFilterMute IS 'Mutes for subscription filters.';
236COMMENT ON COLUMN BugSubscriptionFilterMute.person IS 'The person that muted their subscription to this filter.';
237COMMENT ON COLUMN BugSubscriptionFilterMute.filter IS 'The subscription filter of this record';
238COMMENT ON COLUMN BugSubscriptionFilterMute.date_created IS 'The date at which this mute was created.';
239
234-- BugTag240-- BugTag
235COMMENT ON TABLE BugTag IS 'Attaches simple text tags to a bug.';241COMMENT ON TABLE BugTag IS 'Attaches simple text tags to a bug.';
236COMMENT ON COLUMN BugTag.bug IS 'The bug the tags is attached to.';242COMMENT ON COLUMN BugTag.bug IS 'The bug the tags is attached to.';
237243
=== added file 'database/schema/patch-2208-58-0.sql'
--- database/schema/patch-2208-58-0.sql 1970-01-01 00:00:00 +0000
+++ database/schema/patch-2208-58-0.sql 2011-04-04 12:32:01 +0000
@@ -0,0 +1,25 @@
1-- Copyright 2011 Canonical Ltd. This software is licensed under the
2-- GNU Affero General Public License version 3 (see the file LICENSE).
3
4SET client_min_messages=ERROR;
5
6-- A table to store subscription mutes in.
7
8CREATE TABLE BugSubscriptionFilterMute (
9 person integer REFERENCES Person(id)
10 ON DELETE CASCADE NOT NULL,
11 filter integer REFERENCES BugSubscriptionFilter(id)
12 ON DELETE CASCADE NOT NULL,
13 date_created timestamp without time zone
14 DEFAULT timezone('UTC'::text, now()) NOT NULL,
15 CONSTRAINT bugsubscriptionfiltermute_pkey PRIMARY KEY (person, filter)
16);
17
18-- We don't need an index on person, as the primary key index can be used
19-- for those lookups. We have an index on just filter, as the bulk of our
20-- lookups will be on filter.
21CREATE INDEX bugsubscriptionfiltermute__filter__idx
22 ON BugSubscriptionFilterMute(filter);
23
24INSERT INTO LaunchpadDatabaseRevision VALUES (2208, 58, 0);
25
026
=== modified file 'database/schema/security.cfg'
--- database/schema/security.cfg 2011-04-01 14:46:21 +0000
+++ database/schema/security.cfg 2011-04-04 12:32:01 +0000
@@ -1107,6 +1107,7 @@
1107public.bugproductinfestation = SELECT, INSERT, UPDATE1107public.bugproductinfestation = SELECT, INSERT, UPDATE
1108public.bugsubscription = SELECT, INSERT, UPDATE, DELETE1108public.bugsubscription = SELECT, INSERT, UPDATE, DELETE
1109public.bugsubscriptionfilter = SELECT, INSERT, UPDATE, DELETE1109public.bugsubscriptionfilter = SELECT, INSERT, UPDATE, DELETE
1110public.bugsubscriptionfiltermute = SELECT, INSERT, UPDATE, DELETE
1110public.bugsubscriptionfilterstatus = SELECT, INSERT, UPDATE, DELETE1111public.bugsubscriptionfilterstatus = SELECT, INSERT, UPDATE, DELETE
1111public.bugsubscriptionfilterimportance = SELECT, INSERT, UPDATE, DELETE1112public.bugsubscriptionfilterimportance = SELECT, INSERT, UPDATE, DELETE
1112public.bugsubscriptionfiltertag = SELECT, INSERT, UPDATE, DELETE1113public.bugsubscriptionfiltertag = SELECT, INSERT, UPDATE, DELETE
@@ -1530,6 +1531,7 @@
1530public.bugnotificationrecipient = SELECT, INSERT, UPDATE1531public.bugnotificationrecipient = SELECT, INSERT, UPDATE
1531public.bugsubscription = SELECT, INSERT1532public.bugsubscription = SELECT, INSERT
1532public.bugsubscriptionfilter = SELECT, INSERT1533public.bugsubscriptionfilter = SELECT, INSERT
1534public.bugsubscriptionfiltermute = SELECT, INSERT
1533public.bugsubscriptionfilterstatus = SELECT, INSERT1535public.bugsubscriptionfilterstatus = SELECT, INSERT
1534public.bugsubscriptionfilterimportance = SELECT, INSERT1536public.bugsubscriptionfilterimportance = SELECT, INSERT
1535public.bugsubscriptionfiltertag = SELECT, INSERT1537public.bugsubscriptionfiltertag = SELECT, INSERT
15361538
=== modified file 'lib/lp/bugs/configure.zcml'
--- lib/lp/bugs/configure.zcml 2011-03-30 13:33:35 +0000
+++ lib/lp/bugs/configure.zcml 2011-04-04 12:32:01 +0000
@@ -642,6 +642,17 @@
642 set_schema=".interfaces.bugsubscriptionfilter.IBugSubscriptionFilterAttributes" />642 set_schema=".interfaces.bugsubscriptionfilter.IBugSubscriptionFilterAttributes" />
643 </class>643 </class>
644644
645 <!-- BugSubscriptionFilterMute -->
646 <class
647 class=".model.bugsubscriptionfilter.BugSubscriptionFilterMute">
648 <allow
649 interface=".interfaces.bugsubscriptionfilter.IBugSubscriptionFilterMute"/>
650 <require
651 permission="launchpad.Edit"
652 set_schema=".interfaces.bugsubscriptionfilter.IBugSubscriptionFilterMute" />
653 </class>
654
655
645 <!-- BugSubscriptionInfo -->656 <!-- BugSubscriptionInfo -->
646657
647 <class class=".model.bug.BugSubscriptionInfo">658 <class class=".model.bug.BugSubscriptionInfo">
648659
=== modified file 'lib/lp/bugs/interfaces/bugsubscriptionfilter.py'
--- lib/lp/bugs/interfaces/bugsubscriptionfilter.py 2011-03-23 15:55:44 +0000
+++ lib/lp/bugs/interfaces/bugsubscriptionfilter.py 2011-04-04 12:32:01 +0000
@@ -6,6 +6,7 @@
6__metaclass__ = type6__metaclass__ = type
7__all__ = [7__all__ = [
8 "IBugSubscriptionFilter",8 "IBugSubscriptionFilter",
9 "IBugSubscriptionFilterMute",
9 ]10 ]
1011
1112
@@ -19,6 +20,7 @@
19from zope.schema import (20from zope.schema import (
20 Bool,21 Bool,
21 Choice,22 Choice,
23 Datetime,
22 FrozenSet,24 FrozenSet,
23 Int,25 Int,
24 Text,26 Text,
@@ -33,7 +35,10 @@
33from lp.bugs.interfaces.structuralsubscription import (35from lp.bugs.interfaces.structuralsubscription import (
34 IStructuralSubscription,36 IStructuralSubscription,
35 )37 )
36from lp.services.fields import SearchTag38from lp.services.fields import (
39 PersonChoice,
40 SearchTag,
41 )
3742
3843
39class IBugSubscriptionFilterAttributes(Interface):44class IBugSubscriptionFilterAttributes(Interface):
@@ -109,3 +114,17 @@
109 IBugSubscriptionFilterAttributes, IBugSubscriptionFilterMethods):114 IBugSubscriptionFilterAttributes, IBugSubscriptionFilterMethods):
110 """A bug subscription filter."""115 """A bug subscription filter."""
111 export_as_webservice_entry()116 export_as_webservice_entry()
117
118
119class IBugSubscriptionFilterMute(Interface):
120 """A mute on an IBugSubscriptionFilter."""
121
122 person = PersonChoice(
123 title=_('Person'), required=True, vocabulary='ValidPersonOrTeam',
124 readonly=True, description=_("The person subscribed."))
125 filter = Reference(
126 IBugSubscriptionFilter, title=_("Subscription filter"),
127 description=_("The subscription filter to be muted."))
128 date_created = Datetime(
129 title=_("The date on which the mute was created."), required=False,
130 readonly=True)
112131
=== modified file 'lib/lp/bugs/model/bugsubscriptionfilter.py'
--- lib/lp/bugs/model/bugsubscriptionfilter.py 2011-03-30 15:20:46 +0000
+++ lib/lp/bugs/model/bugsubscriptionfilter.py 2011-04-04 12:32:01 +0000
@@ -4,12 +4,18 @@
4# pylint: disable-msg=E0611,W02124# pylint: disable-msg=E0611,W0212
55
6__metaclass__ = type6__metaclass__ = type
7__all__ = ['BugSubscriptionFilter']7__all__ = [
8 'BugSubscriptionFilter',
9 'BugSubscriptionFilterMute',
10 ]
11
12import pytz
813
9from itertools import chain14from itertools import chain
1015
11from storm.locals import (16from storm.locals import (
12 Bool,17 Bool,
18 DateTime,
13 Int,19 Int,
14 Reference,20 Reference,
15 SQL,21 SQL,
@@ -18,12 +24,16 @@
18 )24 )
19from zope.interface import implements25from zope.interface import implements
2026
27from canonical.database.constants import UTC_NOW
21from canonical.database.enumcol import DBEnum28from canonical.database.enumcol import DBEnum
22from canonical.database.sqlbase import sqlvalues29from canonical.database.sqlbase import sqlvalues
23from canonical.launchpad import searchbuilder30from canonical.launchpad import searchbuilder
24from canonical.launchpad.interfaces.lpstorm import IStore31from canonical.launchpad.interfaces.lpstorm import IStore
25from lp.bugs.enum import BugNotificationLevel32from lp.bugs.enum import BugNotificationLevel
26from lp.bugs.interfaces.bugsubscriptionfilter import IBugSubscriptionFilter33from lp.bugs.interfaces.bugsubscriptionfilter import (
34 IBugSubscriptionFilter,
35 IBugSubscriptionFilterMute,
36 )
27from lp.bugs.interfaces.bugtask import (37from lp.bugs.interfaces.bugtask import (
28 BugTaskImportance,38 BugTaskImportance,
29 BugTaskStatus,39 BugTaskStatus,
@@ -35,6 +45,7 @@
35 BugSubscriptionFilterStatus,45 BugSubscriptionFilterStatus,
36 )46 )
37from lp.bugs.model.bugsubscriptionfiltertag import BugSubscriptionFilterTag47from lp.bugs.model.bugsubscriptionfiltertag import BugSubscriptionFilterTag
48from lp.registry.interfaces.person import validate_person
38from lp.services.database.stormbase import StormBase49from lp.services.database.stormbase import StormBase
3950
4051
@@ -237,3 +248,23 @@
237 # There are no other filters. We can delete the parent248 # There are no other filters. We can delete the parent
238 # subscription.249 # subscription.
239 self.structural_subscription.delete()250 self.structural_subscription.delete()
251
252
253class BugSubscriptionFilterMute(StormBase):
254 """A filter to specialize a *structural* subscription."""
255
256 implements(IBugSubscriptionFilterMute)
257
258 __storm_table__ = "BugSubscriptionFilterMute"
259
260 person_id = Int("person", allow_none=False, validator=validate_person)
261 person = Reference(person_id, "Person.id")
262
263 filter_id = Int("filter", allow_none=False)
264 filter = Reference(filter_id, "StructuralSubscription.id")
265
266 __storm_primary__ = 'person_id', 'filter_id'
267
268 date_created = DateTime(
269 "date_created", allow_none=False, default=UTC_NOW,
270 tzinfo=pytz.UTC)
240271
=== modified file 'lib/lp/registry/model/person.py'
--- lib/lp/registry/model/person.py 2011-03-31 19:10:35 +0000
+++ lib/lp/registry/model/person.py 2011-04-04 12:32:01 +0000
@@ -3965,6 +3965,9 @@
3965 self._mergeBugNotificationRecipient(cur, from_id, to_id)3965 self._mergeBugNotificationRecipient(cur, from_id, to_id)
3966 skip.append(('bugnotificationrecipient', 'person'))3966 skip.append(('bugnotificationrecipient', 'person'))
39673967
3968 # We ignore BugSubscriptionFilterMutes.
3969 skip.append(('bugsubscriptionfiltermute', 'person'))
3970
3968 self._mergePackageBugSupervisor(cur, from_id, to_id)3971 self._mergePackageBugSupervisor(cur, from_id, to_id)
3969 skip.append(('packagebugsupervisor', 'bug_supervisor'))3972 skip.append(('packagebugsupervisor', 'bug_supervisor'))
39703973

Subscribers

People subscribed via source and target branches

to status/vote changes: