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
1=== modified file 'database/schema/comments.sql'
2--- database/schema/comments.sql 2011-03-29 10:17:46 +0000
3+++ database/schema/comments.sql 2011-04-04 12:32:01 +0000
4@@ -231,6 +231,12 @@
5 COMMENT ON COLUMN BugSubscriptionFilterTag.tag IS 'A bug tag.';
6 COMMENT 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.';
7
8+-- BugSubscriptionFilterMute
9+COMMENT ON TABLE BugSubscriptionFilterMute IS 'Mutes for subscription filters.';
10+COMMENT ON COLUMN BugSubscriptionFilterMute.person IS 'The person that muted their subscription to this filter.';
11+COMMENT ON COLUMN BugSubscriptionFilterMute.filter IS 'The subscription filter of this record';
12+COMMENT ON COLUMN BugSubscriptionFilterMute.date_created IS 'The date at which this mute was created.';
13+
14 -- BugTag
15 COMMENT ON TABLE BugTag IS 'Attaches simple text tags to a bug.';
16 COMMENT ON COLUMN BugTag.bug IS 'The bug the tags is attached to.';
17
18=== added file 'database/schema/patch-2208-58-0.sql'
19--- database/schema/patch-2208-58-0.sql 1970-01-01 00:00:00 +0000
20+++ database/schema/patch-2208-58-0.sql 2011-04-04 12:32:01 +0000
21@@ -0,0 +1,25 @@
22+-- Copyright 2011 Canonical Ltd. This software is licensed under the
23+-- GNU Affero General Public License version 3 (see the file LICENSE).
24+
25+SET client_min_messages=ERROR;
26+
27+-- A table to store subscription mutes in.
28+
29+CREATE TABLE BugSubscriptionFilterMute (
30+ person integer REFERENCES Person(id)
31+ ON DELETE CASCADE NOT NULL,
32+ filter integer REFERENCES BugSubscriptionFilter(id)
33+ ON DELETE CASCADE NOT NULL,
34+ date_created timestamp without time zone
35+ DEFAULT timezone('UTC'::text, now()) NOT NULL,
36+ CONSTRAINT bugsubscriptionfiltermute_pkey PRIMARY KEY (person, filter)
37+);
38+
39+-- We don't need an index on person, as the primary key index can be used
40+-- for those lookups. We have an index on just filter, as the bulk of our
41+-- lookups will be on filter.
42+CREATE INDEX bugsubscriptionfiltermute__filter__idx
43+ ON BugSubscriptionFilterMute(filter);
44+
45+INSERT INTO LaunchpadDatabaseRevision VALUES (2208, 58, 0);
46+
47
48=== modified file 'database/schema/security.cfg'
49--- database/schema/security.cfg 2011-04-01 14:46:21 +0000
50+++ database/schema/security.cfg 2011-04-04 12:32:01 +0000
51@@ -1107,6 +1107,7 @@
52 public.bugproductinfestation = SELECT, INSERT, UPDATE
53 public.bugsubscription = SELECT, INSERT, UPDATE, DELETE
54 public.bugsubscriptionfilter = SELECT, INSERT, UPDATE, DELETE
55+public.bugsubscriptionfiltermute = SELECT, INSERT, UPDATE, DELETE
56 public.bugsubscriptionfilterstatus = SELECT, INSERT, UPDATE, DELETE
57 public.bugsubscriptionfilterimportance = SELECT, INSERT, UPDATE, DELETE
58 public.bugsubscriptionfiltertag = SELECT, INSERT, UPDATE, DELETE
59@@ -1530,6 +1531,7 @@
60 public.bugnotificationrecipient = SELECT, INSERT, UPDATE
61 public.bugsubscription = SELECT, INSERT
62 public.bugsubscriptionfilter = SELECT, INSERT
63+public.bugsubscriptionfiltermute = SELECT, INSERT
64 public.bugsubscriptionfilterstatus = SELECT, INSERT
65 public.bugsubscriptionfilterimportance = SELECT, INSERT
66 public.bugsubscriptionfiltertag = SELECT, INSERT
67
68=== modified file 'lib/lp/bugs/configure.zcml'
69--- lib/lp/bugs/configure.zcml 2011-03-30 13:33:35 +0000
70+++ lib/lp/bugs/configure.zcml 2011-04-04 12:32:01 +0000
71@@ -642,6 +642,17 @@
72 set_schema=".interfaces.bugsubscriptionfilter.IBugSubscriptionFilterAttributes" />
73 </class>
74
75+ <!-- BugSubscriptionFilterMute -->
76+ <class
77+ class=".model.bugsubscriptionfilter.BugSubscriptionFilterMute">
78+ <allow
79+ interface=".interfaces.bugsubscriptionfilter.IBugSubscriptionFilterMute"/>
80+ <require
81+ permission="launchpad.Edit"
82+ set_schema=".interfaces.bugsubscriptionfilter.IBugSubscriptionFilterMute" />
83+ </class>
84+
85+
86 <!-- BugSubscriptionInfo -->
87
88 <class class=".model.bug.BugSubscriptionInfo">
89
90=== modified file 'lib/lp/bugs/interfaces/bugsubscriptionfilter.py'
91--- lib/lp/bugs/interfaces/bugsubscriptionfilter.py 2011-03-23 15:55:44 +0000
92+++ lib/lp/bugs/interfaces/bugsubscriptionfilter.py 2011-04-04 12:32:01 +0000
93@@ -6,6 +6,7 @@
94 __metaclass__ = type
95 __all__ = [
96 "IBugSubscriptionFilter",
97+ "IBugSubscriptionFilterMute",
98 ]
99
100
101@@ -19,6 +20,7 @@
102 from zope.schema import (
103 Bool,
104 Choice,
105+ Datetime,
106 FrozenSet,
107 Int,
108 Text,
109@@ -33,7 +35,10 @@
110 from lp.bugs.interfaces.structuralsubscription import (
111 IStructuralSubscription,
112 )
113-from lp.services.fields import SearchTag
114+from lp.services.fields import (
115+ PersonChoice,
116+ SearchTag,
117+ )
118
119
120 class IBugSubscriptionFilterAttributes(Interface):
121@@ -109,3 +114,17 @@
122 IBugSubscriptionFilterAttributes, IBugSubscriptionFilterMethods):
123 """A bug subscription filter."""
124 export_as_webservice_entry()
125+
126+
127+class IBugSubscriptionFilterMute(Interface):
128+ """A mute on an IBugSubscriptionFilter."""
129+
130+ person = PersonChoice(
131+ title=_('Person'), required=True, vocabulary='ValidPersonOrTeam',
132+ readonly=True, description=_("The person subscribed."))
133+ filter = Reference(
134+ IBugSubscriptionFilter, title=_("Subscription filter"),
135+ description=_("The subscription filter to be muted."))
136+ date_created = Datetime(
137+ title=_("The date on which the mute was created."), required=False,
138+ readonly=True)
139
140=== modified file 'lib/lp/bugs/model/bugsubscriptionfilter.py'
141--- lib/lp/bugs/model/bugsubscriptionfilter.py 2011-03-30 15:20:46 +0000
142+++ lib/lp/bugs/model/bugsubscriptionfilter.py 2011-04-04 12:32:01 +0000
143@@ -4,12 +4,18 @@
144 # pylint: disable-msg=E0611,W0212
145
146 __metaclass__ = type
147-__all__ = ['BugSubscriptionFilter']
148+__all__ = [
149+ 'BugSubscriptionFilter',
150+ 'BugSubscriptionFilterMute',
151+ ]
152+
153+import pytz
154
155 from itertools import chain
156
157 from storm.locals import (
158 Bool,
159+ DateTime,
160 Int,
161 Reference,
162 SQL,
163@@ -18,12 +24,16 @@
164 )
165 from zope.interface import implements
166
167+from canonical.database.constants import UTC_NOW
168 from canonical.database.enumcol import DBEnum
169 from canonical.database.sqlbase import sqlvalues
170 from canonical.launchpad import searchbuilder
171 from canonical.launchpad.interfaces.lpstorm import IStore
172 from lp.bugs.enum import BugNotificationLevel
173-from lp.bugs.interfaces.bugsubscriptionfilter import IBugSubscriptionFilter
174+from lp.bugs.interfaces.bugsubscriptionfilter import (
175+ IBugSubscriptionFilter,
176+ IBugSubscriptionFilterMute,
177+ )
178 from lp.bugs.interfaces.bugtask import (
179 BugTaskImportance,
180 BugTaskStatus,
181@@ -35,6 +45,7 @@
182 BugSubscriptionFilterStatus,
183 )
184 from lp.bugs.model.bugsubscriptionfiltertag import BugSubscriptionFilterTag
185+from lp.registry.interfaces.person import validate_person
186 from lp.services.database.stormbase import StormBase
187
188
189@@ -237,3 +248,23 @@
190 # There are no other filters. We can delete the parent
191 # subscription.
192 self.structural_subscription.delete()
193+
194+
195+class BugSubscriptionFilterMute(StormBase):
196+ """A filter to specialize a *structural* subscription."""
197+
198+ implements(IBugSubscriptionFilterMute)
199+
200+ __storm_table__ = "BugSubscriptionFilterMute"
201+
202+ person_id = Int("person", allow_none=False, validator=validate_person)
203+ person = Reference(person_id, "Person.id")
204+
205+ filter_id = Int("filter", allow_none=False)
206+ filter = Reference(filter_id, "StructuralSubscription.id")
207+
208+ __storm_primary__ = 'person_id', 'filter_id'
209+
210+ date_created = DateTime(
211+ "date_created", allow_none=False, default=UTC_NOW,
212+ tzinfo=pytz.UTC)
213
214=== modified file 'lib/lp/registry/model/person.py'
215--- lib/lp/registry/model/person.py 2011-03-31 19:10:35 +0000
216+++ lib/lp/registry/model/person.py 2011-04-04 12:32:01 +0000
217@@ -3965,6 +3965,9 @@
218 self._mergeBugNotificationRecipient(cur, from_id, to_id)
219 skip.append(('bugnotificationrecipient', 'person'))
220
221+ # We ignore BugSubscriptionFilterMutes.
222+ skip.append(('bugsubscriptionfiltermute', 'person'))
223+
224 self._mergePackageBugSupervisor(cur, from_id, to_id)
225 skip.append(('packagebugsupervisor', 'bug_supervisor'))
226

Subscribers

People subscribed via source and target branches

to status/vote changes: