Merge lp:~wgrant/launchpad/descend-from-istructuralsubscriptiontarget into lp:launchpad

Proposed by William Grant
Status: Merged
Merged at revision: not available
Proposed branch: lp:~wgrant/launchpad/descend-from-istructuralsubscriptiontarget
Merge into: lp:launchpad
Diff against target: None lines
To merge this branch: bzr merge lp:~wgrant/launchpad/descend-from-istructuralsubscriptiontarget
Reviewer Review Type Date Requested Status
Curtis Hovey (community) code Approve
Review via email: mp+10636@code.launchpad.net
To post a comment you must log in.
Revision history for this message
William Grant (wgrant) wrote :

= Summary =

Structural subscriptions need to be exported through the webservice. Most of the manipulation methods live in IStructuralSubscriptionTarget, so that needs to be exported too. Because lazr.restful only exports one interface for each entry, ISST needs to be integrated into the primary interface of each class that currently implements() it.

== Proposed fix ==

Very simple: drop all implements(ISST) declarations from lp.registry.model.*, instead having I{Project,Product,ProductSeries,Distribution,DistroSeries,DistributionSourcePackage} descend from ISST.

== Pre-implementation notes ==

Nothing of note.

== Implementation details ==

There was a complication with IProject -- it was only the relevant interface which was not split into sub-interfaces by read permission requirements, so it had security declarations directly on IProject.

This conflicted with the existing per-attribute security declarations on IProject for ISST, so I moved all of IProject's attributes and methods to IProjectPublic, applied the security declarations to that instead, and then created an IProject descending from IProjectPublic and IStructuralSubscriptionTarget. This resolved the conflicts.

== Tests ==

There are many other affected tests, but this is the main one.

 $ bin/test -vvt structural-subscription-target.txt

== Demo and Q/A ==

There are no user-visible changes.

Revision history for this message
Curtis Hovey (sinzui) wrote :

This is a nice refactoring. This is good to land without additional changes.

review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/registry/configure.zcml'
2--- lib/lp/registry/configure.zcml 2009-08-21 10:11:44 +0000
3+++ lib/lp/registry/configure.zcml 2009-08-24 03:50:07 +0000
4@@ -267,14 +267,14 @@
5 <class
6 class="lp.registry.model.project.Project">
7 <allow
8- interface="lp.registry.interfaces.project.IProject"/>
9+ interface="lp.registry.interfaces.project.IProjectPublic"/>
10 <allow
11 interface="canonical.launchpad.interfaces.IFAQCollection"/>
12 <allow
13 interface="canonical.launchpad.interfaces.IQuestionCollection"/>
14 <require
15 permission="launchpad.Edit"
16- set_schema="lp.registry.interfaces.project.IProject"/>
17+ set_schema="lp.registry.interfaces.project.IProjectPublic"/>
18
19 <!-- IStructuralSubscriptionTarget -->
20
21
22=== modified file 'lib/lp/registry/interfaces/distribution.py'
23--- lib/lp/registry/interfaces/distribution.py 2009-08-20 07:15:35 +0000
24+++ lib/lp/registry/interfaces/distribution.py 2009-08-24 03:18:41 +0000
25@@ -34,6 +34,8 @@
26 from canonical.launchpad import _
27 from canonical.launchpad.fields import (
28 Description, PublicPersonChoice, Summary, Title)
29+from canonical.launchpad.interfaces.structuralsubscription import (
30+ IStructuralSubscriptionTarget)
31 from lp.app.interfaces.rootcontext import IRootContext
32 from lp.registry.interfaces.announcement import IMakesAnnouncements
33 from lp.bugs.interfaces.bugtarget import (
34@@ -530,7 +532,7 @@
35
36
37 class IDistribution(IDistributionEditRestricted, IDistributionPublic,
38- IRootContext):
39+ IRootContext, IStructuralSubscriptionTarget):
40 """An operating system distribution."""
41 export_as_webservice_entry()
42
43
44=== modified file 'lib/lp/registry/interfaces/distroseries.py'
45--- lib/lp/registry/interfaces/distroseries.py 2009-08-03 19:22:22 +0000
46+++ lib/lp/registry/interfaces/distroseries.py 2009-08-24 03:18:41 +0000
47@@ -25,6 +25,8 @@
48 from canonical.launchpad.fields import (
49 ContentNameField, Description, PublicPersonChoice, Summary, Title,
50 UniqueField)
51+from canonical.launchpad.interfaces.structuralsubscription import (
52+ IStructuralSubscriptionTarget)
53 from lp.bugs.interfaces.bugtarget import IBugTarget, IHasBugs
54 from lp.soyuz.interfaces.buildrecords import IHasBuildRecords
55 from lp.translations.interfaces.languagepack import ILanguagePack
56@@ -846,7 +848,8 @@
57 """
58
59
60-class IDistroSeries(IDistroSeriesEditRestricted, IDistroSeriesPublic):
61+class IDistroSeries(IDistroSeriesEditRestricted, IDistroSeriesPublic,
62+ IStructuralSubscriptionTarget):
63 """A series of an operating system distribution."""
64 export_as_webservice_entry()
65
66
67=== modified file 'lib/lp/registry/interfaces/milestone.py'
68--- lib/lp/registry/interfaces/milestone.py 2009-06-25 04:06:00 +0000
69+++ lib/lp/registry/interfaces/milestone.py 2009-08-24 03:18:41 +0000
70@@ -18,6 +18,8 @@
71 from zope.interface import Interface, Attribute
72 from zope.schema import Bool, Choice, Date, Int, TextLine
73
74+from canonical.launchpad.interfaces.structuralsubscription import (
75+ IStructuralSubscriptionTarget)
76 from lp.registry.interfaces.productrelease import IProductRelease
77 from lp.bugs.interfaces.bugtarget import IHasBugs
78 from lp.bugs.interfaces.bugtask import IBugTask
79@@ -66,7 +68,7 @@
80 return milestone
81
82
83-class IMilestone(IHasBugs):
84+class IMilestone(IHasBugs, IStructuralSubscriptionTarget):
85 """A milestone, or a targeting point for bugs and other
86 release-management items that need coordination.
87 """
88
89=== modified file 'lib/lp/registry/interfaces/product.py'
90--- lib/lp/registry/interfaces/product.py 2009-08-19 05:33:26 +0000
91+++ lib/lp/registry/interfaces/product.py 2009-08-24 03:18:41 +0000
92@@ -39,6 +39,8 @@
93 Description, IconImageUpload, LogoImageUpload, MugshotImageUpload,
94 ParticipatingPersonChoice, ProductBugTracker, ProductNameField,
95 PublicPersonChoice, Summary, Title, URIField)
96+from canonical.launchpad.interfaces.structuralsubscription import (
97+ IStructuralSubscriptionTarget)
98 from lp.app.interfaces.rootcontext import IRootContext
99 from lp.code.interfaces.branchvisibilitypolicy import (
100 IHasBranchVisibilityPolicy)
101@@ -702,7 +704,8 @@
102
103
104 class IProduct(IProductEditRestricted, IProductProjectReviewRestricted,
105- IProductDriverRestricted, IProductPublic, IRootContext):
106+ IProductDriverRestricted, IProductPublic, IRootContext,
107+ IStructuralSubscriptionTarget):
108 """A Product.
109
110 The Launchpad Registry describes the open source world as Projects and
111
112=== modified file 'lib/lp/registry/interfaces/productseries.py'
113--- lib/lp/registry/interfaces/productseries.py 2009-08-10 17:08:27 +0000
114+++ lib/lp/registry/interfaces/productseries.py 2009-08-24 03:18:41 +0000
115@@ -21,6 +21,8 @@
116 from canonical.launchpad.fields import (
117 ContentNameField, NoneableDescription, ParticipatingPersonChoice,
118 PublicPersonChoice, Title)
119+from canonical.launchpad.interfaces.structuralsubscription import (
120+ IStructuralSubscriptionTarget)
121 from lp.code.interfaces.branch import IBranch
122 from lp.bugs.interfaces.bugtarget import IBugTarget
123 from lp.registry.interfaces.distroseries import DistroSeriesStatus
124@@ -309,7 +311,8 @@
125 """Return basic timeline data useful for creating a diagram."""
126
127
128-class IProductSeries(IProductSeriesEditRestricted, IProductSeriesPublic):
129+class IProductSeries(IProductSeriesEditRestricted, IProductSeriesPublic,
130+ IStructuralSubscriptionTarget):
131 """A series of releases. For example '2.0' or '1.3' or 'dev'."""
132 export_as_webservice_entry('project_series')
133
134
135=== modified file 'lib/lp/registry/interfaces/project.py'
136--- lib/lp/registry/interfaces/project.py 2009-08-19 05:33:26 +0000
137+++ lib/lp/registry/interfaces/project.py 2009-08-24 03:59:31 +0000
138@@ -9,6 +9,7 @@
139
140 __all__ = [
141 'IProject',
142+ 'IProjectPublic',
143 'IProjectSeries',
144 'IProjectSet',
145 ]
146@@ -38,6 +39,8 @@
147 from lp.blueprints.interfaces.sprint import IHasSprints
148 from lp.translations.interfaces.translationgroup import (
149 IHasTranslationGroup)
150+from canonical.launchpad.interfaces.structuralsubscription import (
151+ IStructuralSubscriptionTarget)
152 from canonical.launchpad.validators.name import name_validator
153 from canonical.launchpad.fields import (
154 IconImageUpload, LogoImageUpload, MugshotImageUpload, PillarNameField)
155@@ -56,14 +59,13 @@
156 return IProject
157
158
159-class IProject(ICanGetMilestonesDirectly, IHasAppointedDriver, IHasBranches,
160- IHasBugs, IHasDrivers, IHasBranchVisibilityPolicy, IHasIcon,
161- IHasLogo, IHasMentoringOffers, IHasMergeProposals,
162- IHasMilestones, IHasMugshot, IHasOwner, IHasSpecifications,
163- IHasSprints, IHasTranslationGroup, IMakesAnnouncements,
164- IKarmaContext, IPillar, IRootContext):
165- """A Project."""
166- export_as_webservice_entry('project_group')
167+class IProjectPublic(
168+ ICanGetMilestonesDirectly, IHasAppointedDriver, IHasBranches, IHasBugs,
169+ IHasDrivers, IHasBranchVisibilityPolicy, IHasIcon, IHasLogo,
170+ IHasMentoringOffers, IHasMergeProposals, IHasMilestones, IHasMugshot,
171+ IHasOwner, IHasSpecifications, IHasSprints, IHasTranslationGroup,
172+ IMakesAnnouncements, IKarmaContext, IPillar, IRootContext):
173+ """Public IProject properties."""
174
175 id = Int(title=_('ID'), readonly=True)
176
177@@ -286,6 +288,12 @@
178 """Return a ProjectSeries object with name `series_name`."""
179
180
181+class IProject(IProjectPublic, IStructuralSubscriptionTarget):
182+ """A Project."""
183+
184+ export_as_webservice_entry('project_group')
185+
186+
187 # Interfaces for set
188
189 class IProjectSet(Interface):
190
191=== modified file 'lib/lp/registry/model/distribution.py'
192--- lib/lp/registry/model/distribution.py 2009-08-13 16:38:39 +0000
193+++ lib/lp/registry/model/distribution.py 2009-08-24 03:18:41 +0000
194@@ -100,8 +100,6 @@
195 from lp.blueprints.interfaces.specification import (
196 SpecificationDefinitionStatus, SpecificationFilter,
197 SpecificationImplementationStatus, SpecificationSort)
198-from canonical.launchpad.interfaces.structuralsubscription import (
199- IStructuralSubscriptionTarget)
200 from lp.translations.interfaces.translationgroup import (
201 TranslationPermission)
202 from canonical.launchpad.validators.name import sanitize_name, valid_name
203@@ -126,8 +124,7 @@
204 """A distribution of an operating system, e.g. Debian GNU/Linux."""
205 implements(
206 IDistribution, IFAQTarget, IHasBugSupervisor, IHasBuildRecords,
207- IHasIcon, IHasLogo, IHasMugshot, ILaunchpadUsage, IQuestionTarget,
208- IStructuralSubscriptionTarget)
209+ IHasIcon, IHasLogo, IHasMugshot, ILaunchpadUsage, IQuestionTarget)
210
211 _table = 'Distribution'
212 _defaultOrder = 'name'
213
214=== modified file 'lib/lp/registry/model/distributionsourcepackage.py'
215--- lib/lp/registry/model/distributionsourcepackage.py 2009-07-31 02:10:10 +0000
216+++ lib/lp/registry/model/distributionsourcepackage.py 2009-08-24 03:18:41 +0000
217@@ -19,8 +19,6 @@
218 from storm.locals import Int, Reference, Store, Storm, Unicode
219 from zope.interface import implements
220
221-from canonical.launchpad.interfaces.structuralsubscription import (
222- IStructuralSubscriptionTarget)
223 from lp.answers.interfaces.questiontarget import IQuestionTarget
224 from lp.registry.interfaces.product import IDistributionSourcePackage
225 from canonical.database.sqlbase import sqlvalues
226@@ -55,9 +53,7 @@
227 or current release, etc.
228 """
229
230- implements(
231- IDistributionSourcePackage, IQuestionTarget,
232- IStructuralSubscriptionTarget)
233+ implements(IDistributionSourcePackage, IQuestionTarget)
234
235 def __init__(self, distribution, sourcepackagename):
236 self.distribution = distribution
237
238=== modified file 'lib/lp/registry/model/distroseries.py'
239--- lib/lp/registry/model/distroseries.py 2009-08-03 13:00:37 +0000
240+++ lib/lp/registry/model/distroseries.py 2009-08-24 03:18:41 +0000
241@@ -112,8 +112,6 @@
242 from lp.blueprints.interfaces.specification import (
243 SpecificationFilter, SpecificationGoalStatus,
244 SpecificationImplementationStatus, SpecificationSort)
245-from canonical.launchpad.interfaces.structuralsubscription import (
246- IStructuralSubscriptionTarget)
247 from canonical.launchpad.mail import signed_message_from_string
248 from lp.registry.interfaces.person import validate_public_person
249 from canonical.launchpad.webapp.interfaces import (
250@@ -142,7 +140,7 @@
251 """A particular series of a distribution."""
252 implements(
253 ICanPublishPackages, IDistroSeries, IHasBuildRecords, IHasQueueItems,
254- IHasTranslationTemplates, IStructuralSubscriptionTarget)
255+ IHasTranslationTemplates)
256
257 _table = 'DistroSeries'
258 _defaultOrder = ['distribution', 'version']
259
260=== modified file 'lib/lp/registry/model/milestone.py'
261--- lib/lp/registry/model/milestone.py 2009-07-17 18:46:25 +0000
262+++ lib/lp/registry/model/milestone.py 2009-08-24 03:18:41 +0000
263@@ -35,8 +35,6 @@
264 from lp.bugs.interfaces.bugtarget import IHasBugs
265 from lp.registry.interfaces.milestone import (
266 IHasMilestones, IMilestone, IMilestoneSet, IProjectMilestone)
267-from canonical.launchpad.interfaces.structuralsubscription import (
268- IStructuralSubscriptionTarget)
269 from canonical.launchpad.webapp.interfaces import NotFoundError
270
271
272@@ -93,7 +91,7 @@
273
274
275 class Milestone(SQLBase, StructuralSubscriptionTargetMixin, HasBugsBase):
276- implements(IHasBugs, IMilestone, IStructuralSubscriptionTarget)
277+ implements(IHasBugs, IMilestone)
278
279 # XXX: Guilherme Salgado 2007-03-27 bug=40978:
280 # Milestones should be associated with productseries/distroseriess
281
282=== modified file 'lib/lp/registry/model/product.py'
283--- lib/lp/registry/model/product.py 2009-08-12 13:20:10 +0000
284+++ lib/lp/registry/model/product.py 2009-08-24 03:18:41 +0000
285@@ -88,8 +88,6 @@
286 from lp.registry.interfaces.pillar import IPillarNameSet
287 from lp.registry.interfaces.product import (
288 IProduct, IProductSet, License, LicenseStatus)
289-from canonical.launchpad.interfaces.structuralsubscription import (
290- IStructuralSubscriptionTarget)
291 from lp.blueprints.interfaces.specification import (
292 SpecificationDefinitionStatus, SpecificationFilter,
293 SpecificationImplementationStatus, SpecificationSort)
294@@ -175,8 +173,7 @@
295
296 implements(
297 IFAQTarget, IHasBugSupervisor, IHasIcon, IHasLogo,
298- IHasMugshot, ILaunchpadUsage, IProduct, IQuestionTarget,
299- IStructuralSubscriptionTarget)
300+ IHasMugshot, ILaunchpadUsage, IProduct, IQuestionTarget)
301
302 _table = 'Product'
303
304
305=== modified file 'lib/lp/registry/model/productseries.py'
306--- lib/lp/registry/model/productseries.py 2009-08-10 17:28:13 +0000
307+++ lib/lp/registry/model/productseries.py 2009-08-24 03:18:41 +0000
308@@ -59,8 +59,6 @@
309 SpecificationDefinitionStatus, SpecificationFilter,
310 SpecificationGoalStatus, SpecificationImplementationStatus,
311 SpecificationSort)
312-from canonical.launchpad.interfaces.structuralsubscription import (
313- IStructuralSubscriptionTarget)
314 from canonical.launchpad.webapp.interfaces import NotFoundError
315 from lp.registry.interfaces.productseries import (
316 IProductSeries, IProductSeriesSet)
317@@ -87,9 +85,7 @@
318 HasTranslationTemplatesMixin,
319 StructuralSubscriptionTargetMixin, SeriesMixin):
320 """A series of product releases."""
321- implements(
322- IProductSeries, IHasTranslationTemplates,
323- IStructuralSubscriptionTarget)
324+ implements(IProductSeries, IHasTranslationTemplates)
325
326 _table = 'ProductSeries'
327
328
329=== modified file 'lib/lp/registry/model/project.py'
330--- lib/lp/registry/model/project.py 2009-07-17 00:26:05 +0000
331+++ lib/lp/registry/model/project.py 2009-08-24 03:59:31 +0000
332@@ -30,8 +30,6 @@
333 SpecificationFilter, SpecificationImplementationStatus, SpecificationSort)
334 from lp.blueprints.interfaces.sprintspecification import (
335 SprintSpecificationStatus)
336-from canonical.launchpad.interfaces.structuralsubscription import (
337- IStructuralSubscriptionTarget)
338 from lp.translations.interfaces.translationgroup import (
339 TranslationPermission)
340 from canonical.launchpad.webapp.interfaces import NotFoundError
341@@ -78,8 +76,7 @@
342 """A Project"""
343
344 implements(IProject, IFAQCollection, IHasIcon, IHasLogo,
345- IHasMugshot, ISearchableByQuestionOwner,
346- IStructuralSubscriptionTarget)
347+ IHasMugshot, ISearchableByQuestionOwner)
348
349 _table = "Project"
350