12293.1.11
by Curtis Hovey
Updated copyright. |
1 |
# Copyright 2009-2011 Canonical Ltd. This software is licensed under the
|
8687.15.17
by Karl Fogel
Add the copyright header block to the rest of the files under lib/lp/. |
2 |
# GNU Affero General Public License version 3 (see the file LICENSE).
|
3 |
||
8566.2.4
by Curtis Hovey
Fixed indentation to quiet lint. Added missing docstrings. |
4 |
"""View classes for `IProductSeries`."""
|
2068
by Canonical.com Patch Queue Manager
[r=SteveA/trivial] import fascism, kill translationeffort, kill sshkey browser code, add __all__s to interfaces, other cleanings-up |
5 |
|
6 |
__metaclass__ = type |
|
7 |
||
5481.2.6
by Tim Penhey
Fixes following review |
8 |
__all__ = [ |
9 |
'get_series_branch_error', |
|
9209.4.5
by Guilherme Salgado
Update all existing breadcrumb adapters to use Breadcrumb rather than BreadcrumbBuilder. Also rename them all |
10 |
'ProductSeriesBreadcrumb', |
5481.2.6
by Tim Penhey
Fixes following review |
11 |
'ProductSeriesBugsMenu', |
8255.11.2
by Curtis Hovey
Product series owners and drivers can delete mis-created series. |
12 |
'ProductSeriesDeleteView', |
11320.1.1
by Edwin Grubbs
Converted productseries detailed-display from a macro to its own template. |
13 |
'ProductSeriesDetailedDisplayView', |
5481.2.6
by Tim Penhey
Fixes following review |
14 |
'ProductSeriesEditView', |
15 |
'ProductSeriesFacets', |
|
16 |
'ProductSeriesFileBugRedirect', |
|
7675.662.1
by Brad Crittenden
Correct ProductInvolvedMenu to reference the product not the product series. |
17 |
'ProductSeriesInvolvedMenu', |
10648.1.7
by Curtis Hovey
Removed the provideAdapter call from pillar and moved the Product and ProductSeries |
18 |
'ProductSeriesInvolvementView', |
5481.2.6
by Tim Penhey
Fixes following review |
19 |
'ProductSeriesLinkBranchView', |
20 |
'ProductSeriesLinkBranchFromCodeView', |
|
21 |
'ProductSeriesNavigation', |
|
22 |
'ProductSeriesOverviewMenu', |
|
7709.3.2
by Curtis Hovey
Deleting a release now deletes the files attached to a release too. Updated the |
23 |
'ProductSeriesOverviewNavigationMenu', |
5481.2.6
by Tim Penhey
Fixes following review |
24 |
'ProductSeriesRdfView', |
25 |
'ProductSeriesReviewView', |
|
10456.2.1
by Brad Crittenden
checkpoint |
26 |
'ProductSeriesSetBranchView', |
5481.2.6
by Tim Penhey
Fixes following review |
27 |
'ProductSeriesSpecificationsMenu', |
9081.2.8
by Curtis Hovey
Updated the productseries ubuntu packaging page to UI 3.0. |
28 |
'ProductSeriesUbuntuPackagingView', |
5481.2.6
by Tim Penhey
Fixes following review |
29 |
'ProductSeriesView', |
30 |
]
|
|
615
by Canonical.com Patch Queue Manager
productseries now core-complete for add, view, edit |
31 |
|
3691.125.12
by James Henstridge
check the (series,branch) constraint when updating a series branch |
32 |
import cgi |
8805.7.3
by Edwin Grubbs
Optimized specification_status_counts. |
33 |
from operator import attrgetter |
7675.85.2
by Jonathan Lange
Undo revision generated by step 2 of process. |
34 |
|
35 |
from bzrlib.revision import NULL_REVISION |
|
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
36 |
from lazr.restful.interface import ( |
37 |
copy_field, |
|
38 |
use_template, |
|
39 |
)
|
|
40 |
from z3c.ptcompat import ViewPageTemplateFile |
|
41 |
from zope.app.form.browser import ( |
|
42 |
TextAreaWidget, |
|
43 |
TextWidget, |
|
44 |
)
|
|
1648
by Canonical.com Patch Queue Manager
land marks NukeSourceSource patch |
45 |
from zope.component import getUtility |
10023.3.4
by Curtis Hovey
Revise the Ubuntu packaging view to allow the user to select any ubuntu series. |
46 |
from zope.formlib import form |
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
47 |
from zope.interface import ( |
48 |
implements, |
|
49 |
Interface, |
|
50 |
)
|
|
10023.3.4
by Curtis Hovey
Revise the Ubuntu packaging view to allow the user to select any ubuntu series. |
51 |
from zope.schema import Choice |
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
52 |
from zope.schema.vocabulary import ( |
53 |
SimpleTerm, |
|
54 |
SimpleVocabulary, |
|
55 |
)
|
|
1102
by Canonical.com Patch Queue Manager
Lucille had some XXXs which should have been NOTEs |
56 |
|
14600.1.12
by Curtis Hovey
Move i18n to lp. |
57 |
from lp import _ |
14593.2.14
by Curtis Hovey
Extracted language helpers to lp.services.worlddata.helpers. |
58 |
from lp.services.worlddata.helpers import browser_languages |
14600.2.2
by Curtis Hovey
Moved webapp to lp.services. |
59 |
from lp.services.webapp import ( |
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
60 |
ApplicationMenu, |
61 |
canonical_url, |
|
62 |
enabled_with_permission, |
|
63 |
LaunchpadView, |
|
64 |
Link, |
|
65 |
Navigation, |
|
66 |
NavigationMenu, |
|
67 |
StandardLaunchpadFacets, |
|
68 |
stepthrough, |
|
69 |
stepto, |
|
70 |
)
|
|
14600.2.2
by Curtis Hovey
Moved webapp to lp.services. |
71 |
from lp.services.webapp.authorization import check_permission |
72 |
from lp.services.webapp.batching import BatchNavigator |
|
73 |
from lp.services.webapp.breadcrumb import Breadcrumb |
|
74 |
from lp.services.webapp.menu import structured |
|
11929.9.1
by Tim Penhey
Move launchpadform into lp.app.browser. |
75 |
from lp.app.browser.launchpadform import ( |
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
76 |
action, |
77 |
custom_widget, |
|
78 |
LaunchpadEditFormView, |
|
79 |
LaunchpadFormView, |
|
11929.11.14
by Tim Penhey
Move the method to render a part of the widget into the launchpadform module. |
80 |
render_radio_widget_part, |
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
81 |
ReturnToReferrerMixin, |
82 |
)
|
|
11626.3.2
by Curtis Hovey
Move tales gto lp.app. |
83 |
from lp.app.browser.tales import MenuAPI |
11452.1.6
by j.c.sackett
Converted productseries views and updated tests. |
84 |
from lp.app.enums import ServiceUsage |
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
85 |
from lp.app.errors import ( |
86 |
NotFoundError, |
|
87 |
UnexpectedFormData, |
|
88 |
)
|
|
13130.1.12
by Curtis Hovey
Sorted imports. |
89 |
from lp.app.interfaces.launchpad import ILaunchpadCelebrities |
12293.1.10
by Curtis Hovey
Formatted imports. |
90 |
from lp.app.widgets.itemswidgets import LaunchpadRadioWidget |
91 |
from lp.app.widgets.textwidgets import StrippedTextWidget |
|
9559.1.2
by Henning Eggers
Converted hasspecifications-specs.pt to 3.0 layout. Refactored all specification menus into a Mixin. Fixed specfications vhost breadcrumb. Fixed some labels and page_titles. |
92 |
from lp.blueprints.browser.specificationtarget import ( |
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
93 |
HasSpecificationsMenuMixin, |
94 |
)
|
|
11824.1.5
by Tim Penhey
Fix imports for SpecificationImplementationStatus. |
95 |
from lp.blueprints.enums import SpecificationImplementationStatus |
96 |
from lp.blueprints.interfaces.specification import ISpecificationSet |
|
8523.3.1
by Gavin Panella
Bugs tree reorg after automated migration. |
97 |
from lp.bugs.browser.bugtask import BugTargetTraversalMixin |
13130.1.12
by Curtis Hovey
Sorted imports. |
98 |
from lp.bugs.browser.structuralsubscription import ( |
99 |
expose_structural_subscription_data_to_js, |
|
100 |
StructuralSubscriptionMenuMixin, |
|
101 |
StructuralSubscriptionTargetTraversalMixin, |
|
102 |
)
|
|
14157.3.1
by Jeroen Vermeulen
Lint. |
103 |
from lp.bugs.interfaces.bugtask import IBugTaskSet |
10456.2.13
by Brad Crittenden
Added browser support for other +setbranch options |
104 |
from lp.code.browser.branch import BranchNameValidationMixin |
10456.2.1
by Brad Crittenden
checkpoint |
105 |
from lp.code.browser.branchref import BranchRef |
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
106 |
from lp.code.enums import ( |
107 |
BranchType, |
|
108 |
RevisionControlSystems, |
|
109 |
)
|
|
110 |
from lp.code.errors import ( |
|
111 |
BranchCreationForbidden, |
|
112 |
BranchExists, |
|
113 |
)
|
|
11270.2.3
by Tim Penhey
Fix more imports. |
114 |
from lp.code.interfaces.branch import IBranch |
8777.6.2
by Danilo Šegan
Move productseries translation views out of registry and into translations. |
115 |
from lp.code.interfaces.branchjob import IRosettaUploadJobSource |
10456.2.13
by Brad Crittenden
Added browser support for other +setbranch options |
116 |
from lp.code.interfaces.branchtarget import IBranchTarget |
10456.2.34
by Brad Crittenden
Fix lint and merge issues. |
117 |
from lp.code.interfaces.codeimport import ( |
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
118 |
ICodeImport, |
119 |
ICodeImportSet, |
|
120 |
)
|
|
121 |
from lp.registry.browser import ( |
|
12688.1.5
by Brad Crittenden
Fixed issues from review. Created add_subscribe_link. |
122 |
add_subscribe_link, |
11594.3.3
by Curtis Hovey
Removed duplicate an unused code. |
123 |
BaseRdfView, |
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
124 |
MilestoneOverlayMixin, |
125 |
RegistryDeleteViewMixin, |
|
126 |
StatusCount, |
|
127 |
)
|
|
128 |
from lp.registry.browser.pillar import ( |
|
129 |
InvolvedMenu, |
|
130 |
PillarView, |
|
131 |
)
|
|
10193.2.1
by Edwin Grubbs
Removed PackagingAddView. |
132 |
from lp.registry.interfaces.packaging import ( |
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
133 |
IPackaging, |
134 |
IPackagingUtil, |
|
135 |
)
|
|
136 |
from lp.registry.interfaces.productseries import IProductSeries |
|
137 |
from lp.registry.interfaces.series import SeriesStatus |
|
138 |
from lp.services.fields import URIField |
|
11382.6.34
by Gavin Panella
Reformat imports in all files touched so far. |
139 |
from lp.services.propertycache import cachedproperty |
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
140 |
from lp.services.worlddata.interfaces.country import ICountry |
141 |
from lp.services.worlddata.interfaces.language import ILanguageSet |
|
8751.1.1
by Danilo Šegan
Store migration changes so far. |
142 |
from lp.translations.interfaces.potemplate import IPOTemplateSet |
143 |
from lp.translations.interfaces.productserieslanguage import ( |
|
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
144 |
IProductSeriesLanguageSet, |
145 |
)
|
|
10456.2.1
by Brad Crittenden
checkpoint |
146 |
|
9963.2.1
by Curtis Hovey
Do not allow users to delete series that are linked to packages. |
147 |
|
3691.154.7
by David Allouche
improve error message for cvs/svn details in +source |
148 |
def quote(text): |
9963.2.4
by Curtis Hovey
Changes per review. |
149 |
"""Escape and quote text."""
|
3691.154.7
by David Allouche
improve error message for cvs/svn details in +source |
150 |
return cgi.escape(text, quote=True) |
151 |
||
152 |
||
9206.2.1
by William Grant
Add a URL and traversal mixin for IStructuralSubscription. Mix it into all targets. |
153 |
class ProductSeriesNavigation(Navigation, BugTargetTraversalMixin, |
9206.1.5
by William Grant
Style fixes. |
154 |
StructuralSubscriptionTargetTraversalMixin): |
8566.2.4
by Curtis Hovey
Fixed indentation to quiet lint. Added missing docstrings. |
155 |
"""A class to navigate `IProductSeries` URLs."""
|
2630
by Canonical.com Patch Queue Manager
[trivial] lots of tidying up. converting all database classes to use NotFoundError consistently, and to import it from launchpad.interfaces in preparation for the move to a new zope3. Also, introduced a NameNotAvailable error. removed browser:traverse rdirective. commented out shipit test that fails sometimes. |
156 |
usedfor = IProductSeries |
157 |
||
3691.160.1
by James Henstridge
Add support for Bazaar branch references to branch, product and product series pages |
158 |
@stepto('.bzr') |
159 |
def dotbzr(self): |
|
8566.2.4
by Curtis Hovey
Fixed indentation to quiet lint. Added missing docstrings. |
160 |
"""Return the series branch."""
|
7675.85.2
by Jonathan Lange
Undo revision generated by step 2 of process. |
161 |
if self.context.branch: |
162 |
return BranchRef(self.context.branch) |
|
3691.160.1
by James Henstridge
Add support for Bazaar branch references to branch, product and product series pages |
163 |
else: |
164 |
return None |
|
165 |
||
2630
by Canonical.com Patch Queue Manager
[trivial] lots of tidying up. converting all database classes to use NotFoundError consistently, and to import it from launchpad.interfaces in preparation for the move to a new zope3. Also, introduced a NameNotAvailable error. removed browser:traverse rdirective. commented out shipit test that fails sometimes. |
166 |
@stepto('+pots') |
167 |
def pots(self): |
|
8566.2.4
by Curtis Hovey
Fixed indentation to quiet lint. Added missing docstrings. |
168 |
"""Return the series templates."""
|
2630
by Canonical.com Patch Queue Manager
[trivial] lots of tidying up. converting all database classes to use NotFoundError consistently, and to import it from launchpad.interfaces in preparation for the move to a new zope3. Also, introduced a NameNotAvailable error. removed browser:traverse rdirective. commented out shipit test that fails sometimes. |
169 |
potemplateset = getUtility(IPOTemplateSet) |
170 |
return potemplateset.getSubset(productseries=self.context) |
|
171 |
||
8485.7.1
by Danilo Šegan
Merge with productserieslanguage page implementation. |
172 |
@stepthrough('+lang') |
173 |
def traverse_lang(self, langcode): |
|
174 |
"""Retrieve the ProductSeriesLanguage or a dummy if it is None."""
|
|
8485.7.10
by Danilo Šegan
A bunch of fixes after review from jtv. |
175 |
# We do not want users to see the 'en' pofile because
|
8485.7.1
by Danilo Šegan
Merge with productserieslanguage page implementation. |
176 |
# we store the messages we want to translate as English.
|
177 |
if langcode == 'en': |
|
178 |
raise NotFoundError(langcode) |
|
179 |
||
180 |
langset = getUtility(ILanguageSet) |
|
181 |
try: |
|
182 |
lang = langset[langcode] |
|
183 |
except IndexError: |
|
184 |
# Unknown language code.
|
|
185 |
raise NotFoundError |
|
186 |
psl_set = getUtility(IProductSeriesLanguageSet) |
|
8485.7.10
by Danilo Šegan
A bunch of fixes after review from jtv. |
187 |
psl = psl_set.getProductSeriesLanguage(self.context, lang) |
8485.7.1
by Danilo Šegan
Merge with productserieslanguage page implementation. |
188 |
|
189 |
return psl |
|
190 |
||
2630
by Canonical.com Patch Queue Manager
[trivial] lots of tidying up. converting all database classes to use NotFoundError consistently, and to import it from launchpad.interfaces in preparation for the move to a new zope3. Also, introduced a NameNotAvailable error. removed browser:traverse rdirective. commented out shipit test that fails sometimes. |
191 |
def traverse(self, name): |
8566.2.4
by Curtis Hovey
Fixed indentation to quiet lint. Added missing docstrings. |
192 |
"""See `INavigation`."""
|
13045.8.4
by Curtis Hovey
Reverted unneeded change because the change needed to be lower. |
193 |
return self.context.getRelease(name) |
2630
by Canonical.com Patch Queue Manager
[trivial] lots of tidying up. converting all database classes to use NotFoundError consistently, and to import it from launchpad.interfaces in preparation for the move to a new zope3. Also, introduced a NameNotAvailable error. removed browser:traverse rdirective. commented out shipit test that fails sometimes. |
194 |
|
195 |
||
9209.4.5
by Guilherme Salgado
Update all existing breadcrumb adapters to use Breadcrumb rather than BreadcrumbBuilder. Also rename them all |
196 |
class ProductSeriesBreadcrumb(Breadcrumb): |
6767.6.26
by Maris Fogels
Rework based on reviewer feedback. |
197 |
"""Builds a breadcrumb for an `IProductSeries`."""
|
9963.2.1
by Curtis Hovey
Do not allow users to delete series that are linked to packages. |
198 |
|
6767.6.6
by Maris Fogels
Migrated the ProductSeries breadcrumb to the new system interface. |
199 |
@property
|
200 |
def text(self): |
|
9209.4.5
by Guilherme Salgado
Update all existing breadcrumb adapters to use Breadcrumb rather than BreadcrumbBuilder. Also rename them all |
201 |
"""See `IBreadcrumb`."""
|
6767.6.6
by Maris Fogels
Migrated the ProductSeries breadcrumb to the new system interface. |
202 |
return 'Series ' + self.context.name |
203 |
||
204 |
||
3203.1.3
by Mark Shuttleworth
Substantial cleanup of spec listings and spec targeting |
205 |
class ProductSeriesFacets(StandardLaunchpadFacets): |
8566.2.4
by Curtis Hovey
Fixed indentation to quiet lint. Added missing docstrings. |
206 |
"""A class that provides the series facets."""
|
3203.1.3
by Mark Shuttleworth
Substantial cleanup of spec listings and spec targeting |
207 |
usedfor = IProductSeries |
5481.2.6
by Tim Penhey
Fixes following review |
208 |
enable_only = [ |
209 |
'overview', 'branches', 'bugs', 'specifications', 'translations'] |
|
210 |
||
211 |
def branches(self): |
|
8566.2.4
by Curtis Hovey
Fixed indentation to quiet lint. Added missing docstrings. |
212 |
"""Return a link to view the branches related to this series."""
|
5481.2.6
by Tim Penhey
Fixes following review |
213 |
# Override to go to the branches for the product.
|
10842.1.1
by Paul Hummer
Changed 'Branches' to 'Code' and prepping to run tests |
214 |
text = 'Code' |
5481.2.6
by Tim Penhey
Fixes following review |
215 |
summary = 'View related branches of code' |
216 |
link = canonical_url(self.context.product, rootsite='code') |
|
217 |
return Link(link, text, summary=summary) |
|
3203.1.3
by Mark Shuttleworth
Substantial cleanup of spec listings and spec targeting |
218 |
|
219 |
||
10648.1.4
by Curtis Hovey
Commit was appears to be sane code. Navigation links are broken and this looks like |
220 |
class IProductSeriesInvolved(Interface): |
221 |
"""A marker interface for getting involved."""
|
|
222 |
||
223 |
||
224 |
class ProductSeriesInvolvedMenu(InvolvedMenu): |
|
225 |
"""The get involved menu."""
|
|
226 |
usedfor = IProductSeriesInvolved |
|
227 |
links = [ |
|
228 |
'report_bug', 'help_translate', 'submit_code', 'register_blueprint'] |
|
229 |
||
7675.662.1
by Brad Crittenden
Correct ProductInvolvedMenu to reference the product not the product series. |
230 |
@property
|
231 |
def view(self): |
|
232 |
return self.context |
|
233 |
||
234 |
@property
|
|
235 |
def pillar(self): |
|
236 |
return self.view.context.product |
|
237 |
||
10648.1.4
by Curtis Hovey
Commit was appears to be sane code. Navigation links are broken and this looks like |
238 |
def submit_code(self): |
10648.1.5
by Curtis Hovey
Switch to ZCML adapter registration to avoid multiple registrations from python |
239 |
target = canonical_url( |
7675.662.1
by Brad Crittenden
Correct ProductInvolvedMenu to reference the product not the product series. |
240 |
self.pillar, view_name='+addbranch', rootsite='code') |
11452.1.6
by j.c.sackett
Converted productseries views and updated tests. |
241 |
enabled = self.view.codehosting_usage == ServiceUsage.LAUNCHPAD |
10648.1.4
by Curtis Hovey
Commit was appears to be sane code. Navigation links are broken and this looks like |
242 |
return Link( |
10648.1.5
by Curtis Hovey
Switch to ZCML adapter registration to avoid multiple registrations from python |
243 |
target, 'Submit code', icon='code', enabled=enabled) |
10648.1.4
by Curtis Hovey
Commit was appears to be sane code. Navigation links are broken and this looks like |
244 |
|
245 |
||
10648.1.7
by Curtis Hovey
Removed the provideAdapter call from pillar and moved the Product and ProductSeries |
246 |
class ProductSeriesInvolvementView(PillarView): |
247 |
"""Encourage configuration of involvement links for project series."""
|
|
248 |
||
10648.1.4
by Curtis Hovey
Commit was appears to be sane code. Navigation links are broken and this looks like |
249 |
implements(IProductSeriesInvolved) |
10648.1.7
by Curtis Hovey
Removed the provideAdapter call from pillar and moved the Product and ProductSeries |
250 |
has_involvement = True |
251 |
visible_disabled_link_names = ['submit_code'] |
|
252 |
||
253 |
def __init__(self, context, request): |
|
254 |
super(ProductSeriesInvolvementView, self).__init__(context, request) |
|
11483.3.2
by j.c.sackett
Update callsites for official_answers |
255 |
self.answers_usage = ServiceUsage.NOT_APPLICABLE |
11452.1.6
by j.c.sackett
Converted productseries views and updated tests. |
256 |
if self.context.branch is not None: |
257 |
self.codehosting_usage = ServiceUsage.LAUNCHPAD |
|
258 |
else: |
|
259 |
self.codehosting_usage = ServiceUsage.UNKNOWN |
|
10648.1.7
by Curtis Hovey
Removed the provideAdapter call from pillar and moved the Product and ProductSeries |
260 |
|
261 |
@property
|
|
262 |
def configuration_links(self): |
|
263 |
"""The enabled involvement links."""
|
|
264 |
series_menu = MenuAPI(self.context).overview |
|
265 |
set_branch = series_menu['set_branch'] |
|
266 |
set_branch.text = 'Configure series branch' |
|
11452.1.6
by j.c.sackett
Converted productseries views and updated tests. |
267 |
if self.codehosting_usage == ServiceUsage.LAUNCHPAD: |
268 |
configured = True |
|
269 |
else: |
|
270 |
configured = False |
|
11452.1.3
by j.c.sackett
Reverted some changes and added some comments. |
271 |
return [dict(link=set_branch, |
11452.1.6
by j.c.sackett
Converted productseries views and updated tests. |
272 |
configured=configured)] |
11452.1.3
by j.c.sackett
Reverted some changes and added some comments. |
273 |
|
10648.1.4
by Curtis Hovey
Commit was appears to be sane code. Navigation links are broken and this looks like |
274 |
|
9660.4.1
by Tom Berger
Use a different icon and text for the strucutal subscription menu link depensing on whether the user is already subscribed. |
275 |
class ProductSeriesOverviewMenu( |
276 |
ApplicationMenu, StructuralSubscriptionMenuMixin): |
|
8566.2.4
by Curtis Hovey
Fixed indentation to quiet lint. Added missing docstrings. |
277 |
"""The overview menu."""
|
3203.1.3
by Mark Shuttleworth
Substantial cleanup of spec listings and spec targeting |
278 |
usedfor = IProductSeries |
279 |
facet = 'overview' |
|
12393.30.9
by Brad Crittenden
Support for product series. Some tests failing for unknown reasons. |
280 |
|
281 |
@cachedproperty
|
|
282 |
def links(self): |
|
283 |
links = [ |
|
284 |
'configure_bugtracker', |
|
285 |
'create_milestone', |
|
286 |
'create_release', |
|
287 |
'delete', |
|
288 |
'driver', |
|
289 |
'edit', |
|
290 |
'link_branch', |
|
291 |
'rdf', |
|
292 |
'set_branch', |
|
293 |
]
|
|
12688.1.5
by Brad Crittenden
Fixed issues from review. Created add_subscribe_link. |
294 |
add_subscribe_link(links) |
12393.30.9
by Brad Crittenden
Support for product series. Some tests failing for unknown reasons. |
295 |
links.append('ubuntupkg') |
296 |
return links |
|
2548
by Canonical.com Patch Queue Manager
r=bjornt, plus some [trivial], lots of menus work, special error page for request timeouts. |
297 |
|
3691.169.5
by James Henstridge
Allow entering Bazaar branch details on +source form, add sourceadmin buttons |
298 |
@enabled_with_permission('launchpad.Edit') |
11462.2.12
by Edwin Grubbs
Made changes for UI reviews. |
299 |
def configure_bugtracker(self): |
300 |
text = 'Configure bug tracker' |
|
301 |
summary = 'Specify where bugs are tracked for this project' |
|
302 |
return Link( |
|
11462.2.13
by Edwin Grubbs
Fixed tests. |
303 |
canonical_url(self.context.product, |
304 |
view_name='+configure-bugtracker'), |
|
11462.2.12
by Edwin Grubbs
Made changes for UI reviews. |
305 |
text, summary, icon='edit') |
306 |
||
307 |
@enabled_with_permission('launchpad.Edit') |
|
2548
by Canonical.com Patch Queue Manager
r=bjornt, plus some [trivial], lots of menus work, special error page for request timeouts. |
308 |
def edit(self): |
8566.2.4
by Curtis Hovey
Fixed indentation to quiet lint. Added missing docstrings. |
309 |
"""Return a link to edit this series."""
|
3847.2.15
by Mark Shuttleworth
Consistency in menu text and capitalisation |
310 |
text = 'Change details' |
8445.2.1
by Curtis Hovey
First draft of the series page. |
311 |
summary = 'Edit this series' |
312 |
return Link('+edit', text, summary, icon='edit') |
|
2548
by Canonical.com Patch Queue Manager
r=bjornt, plus some [trivial], lots of menus work, special error page for request timeouts. |
313 |
|
3691.169.5
by James Henstridge
Allow entering Bazaar branch details on +source form, add sourceadmin buttons |
314 |
@enabled_with_permission('launchpad.Edit') |
8255.11.2
by Curtis Hovey
Product series owners and drivers can delete mis-created series. |
315 |
def delete(self): |
8566.2.4
by Curtis Hovey
Fixed indentation to quiet lint. Added missing docstrings. |
316 |
"""Return a link to delete this series."""
|
8255.11.2
by Curtis Hovey
Product series owners and drivers can delete mis-created series. |
317 |
text = 'Delete series' |
318 |
summary = "Delete this series and all it's dependent items." |
|
319 |
return Link('+delete', text, summary, icon='trash-icon') |
|
320 |
||
321 |
@enabled_with_permission('launchpad.Edit') |
|
3348.1.21
by Mark Shuttleworth
Enable setting and proper use of the "drivers" details. |
322 |
def driver(self): |
8566.2.4
by Curtis Hovey
Fixed indentation to quiet lint. Added missing docstrings. |
323 |
"""Return a link to set the release manager."""
|
8566.2.1
by Curtis Hovey
Use the term 'Release manager' to distinguish the series driver from the project drivers. |
324 |
text = 'Appoint release manager' |
3348.1.21
by Mark Shuttleworth
Enable setting and proper use of the "drivers" details. |
325 |
summary = 'Someone with permission to set goals this series' |
326 |
return Link('+driver', text, summary, icon='edit') |
|
327 |
||
5481.2.2
by Tim Penhey
Added a new page just to set the bazaar branch. |
328 |
@enabled_with_permission('launchpad.Edit') |
329 |
def link_branch(self): |
|
8566.2.4
by Curtis Hovey
Fixed indentation to quiet lint. Added missing docstrings. |
330 |
"""Return a link to set the bazaar branch for this series."""
|
8445.2.9
by Curtis Hovey
series +linkbranch link text changes Link to branch => Change branch when |
331 |
if self.context.branch is None: |
332 |
text = 'Link to branch' |
|
8615.11.3
by Curtis Hovey
Change branch now uses an edit icon. |
333 |
icon = 'add' |
9691.3.5
by Tim Penhey
New story for setting the development focus branch. |
334 |
summary = 'Set the branch for this series' |
8445.2.9
by Curtis Hovey
series +linkbranch link text changes Link to branch => Change branch when |
335 |
else: |
336 |
text = "Change branch" |
|
8615.11.3
by Curtis Hovey
Change branch now uses an edit icon. |
337 |
icon = 'edit' |
9691.3.5
by Tim Penhey
New story for setting the development focus branch. |
338 |
summary = 'Change the branch for this series' |
8615.11.3
by Curtis Hovey
Change branch now uses an edit icon. |
339 |
return Link('+linkbranch', text, summary, icon=icon) |
5481.2.2
by Tim Penhey
Added a new page just to set the bazaar branch. |
340 |
|
10469.1.21
by Edwin Grubbs
Make involvement portlet use +setbranch instead of +linkbranch. |
341 |
@enabled_with_permission('launchpad.Edit') |
342 |
def set_branch(self): |
|
343 |
"""Return a link to set the bazaar branch for this series."""
|
|
344 |
# Once +setbranch has been beta tested thoroughly, it should
|
|
345 |
# replace the +linkbranch page.
|
|
346 |
if self.context.branch is None: |
|
347 |
text = 'Link to branch' |
|
348 |
icon = 'add' |
|
349 |
summary = 'Set the branch for this series' |
|
350 |
else: |
|
351 |
text = "Change branch" |
|
352 |
icon = 'edit' |
|
353 |
summary = 'Change the branch for this series' |
|
354 |
return Link('+setbranch', text, summary, icon=icon) |
|
355 |
||
10248.2.5
by Jamal Fanaian
Fixed security problem in test xx-product-package-pages with ubuntupkg thanks to help from bac |
356 |
@enabled_with_permission('launchpad.AnyPerson') |
2548
by Canonical.com Patch Queue Manager
r=bjornt, plus some [trivial], lots of menus work, special error page for request timeouts. |
357 |
def ubuntupkg(self): |
8566.2.4
by Curtis Hovey
Fixed indentation to quiet lint. Added missing docstrings. |
358 |
"""Return a link to link this series to an ubuntu sourcepackage."""
|
3847.2.15
by Mark Shuttleworth
Consistency in menu text and capitalisation |
359 |
text = 'Link to Ubuntu package' |
8445.2.1
by Curtis Hovey
First draft of the series page. |
360 |
return Link('+ubuntupkg', text, icon='add') |
2548
by Canonical.com Patch Queue Manager
r=bjornt, plus some [trivial], lots of menus work, special error page for request timeouts. |
361 |
|
3472.2.1
by Mark Shuttleworth
Hang milestones mostly off series. |
362 |
@enabled_with_permission('launchpad.Edit') |
7675.118.1
by Edwin Grubbs
Working form for creating a product release off of the series. |
363 |
def create_milestone(self): |
8566.2.4
by Curtis Hovey
Fixed indentation to quiet lint. Added missing docstrings. |
364 |
"""Return a link to create a milestone."""
|
7675.118.1
by Edwin Grubbs
Working form for creating a product release off of the series. |
365 |
text = 'Create milestone' |
3472.2.1
by Mark Shuttleworth
Hang milestones mostly off series. |
366 |
summary = 'Register a new milestone for this series' |
367 |
return Link('+addmilestone', text, summary, icon='add') |
|
368 |
||
7675.118.1
by Edwin Grubbs
Working form for creating a product release off of the series. |
369 |
@enabled_with_permission('launchpad.Edit') |
370 |
def create_release(self): |
|
8566.2.4
by Curtis Hovey
Fixed indentation to quiet lint. Added missing docstrings. |
371 |
"""Return a link to create a release."""
|
7675.118.1
by Edwin Grubbs
Working form for creating a product release off of the series. |
372 |
text = 'Create release' |
373 |
return Link('+addrelease', text, icon='add') |
|
374 |
||
3348.1.25
by Mark Shuttleworth
Test fixes and productseries page cleanup. |
375 |
def rdf(self): |
8566.2.4
by Curtis Hovey
Fixed indentation to quiet lint. Added missing docstrings. |
376 |
"""Return a link to download the series RDF data."""
|
3847.2.15
by Mark Shuttleworth
Consistency in menu text and capitalisation |
377 |
text = 'Download RDF metadata' |
2548
by Canonical.com Patch Queue Manager
r=bjornt, plus some [trivial], lots of menus work, special error page for request timeouts. |
378 |
return Link('+rdf', text, icon='download') |
379 |
||
9660.4.1
by Tom Berger
Use a different icon and text for the strucutal subscription menu link depensing on whether the user is already subscribed. |
380 |
|
381 |
class ProductSeriesBugsMenu(ApplicationMenu, StructuralSubscriptionMenuMixin): |
|
8566.2.4
by Curtis Hovey
Fixed indentation to quiet lint. Added missing docstrings. |
382 |
"""The bugs menu."""
|
4310.1.21
by Bjorn Tillenius
add a +nominations page for a product series. |
383 |
usedfor = IProductSeries |
384 |
facet = 'bugs' |
|
12393.30.9
by Brad Crittenden
Support for product series. Some tests failing for unknown reasons. |
385 |
|
386 |
@cachedproperty
|
|
387 |
def links(self): |
|
388 |
links = ['new', 'nominations'] |
|
12688.1.5
by Brad Crittenden
Fixed issues from review. Created add_subscribe_link. |
389 |
add_subscribe_link(links) |
12393.30.9
by Brad Crittenden
Support for product series. Some tests failing for unknown reasons. |
390 |
return links |
4310.1.21
by Bjorn Tillenius
add a +nominations page for a product series. |
391 |
|
392 |
def new(self): |
|
8566.2.4
by Curtis Hovey
Fixed indentation to quiet lint. Added missing docstrings. |
393 |
"""Return a link to report a bug in this series."""
|
4310.1.21
by Bjorn Tillenius
add a +nominations page for a product series. |
394 |
return Link('+filebug', 'Report a bug', icon='add') |
395 |
||
396 |
def nominations(self): |
|
8566.2.4
by Curtis Hovey
Fixed indentation to quiet lint. Added missing docstrings. |
397 |
"""Return a link to review bugs nominated for this series."""
|
4310.1.21
by Bjorn Tillenius
add a +nominations page for a product series. |
398 |
return Link('+nominations', 'Review nominations', icon='bug') |
399 |
||
400 |
||
9559.1.2
by Henning Eggers
Converted hasspecifications-specs.pt to 3.0 layout. Refactored all specification menus into a Mixin. Fixed specfications vhost breadcrumb. Fixed some labels and page_titles. |
401 |
class ProductSeriesSpecificationsMenu(NavigationMenu, |
402 |
HasSpecificationsMenuMixin): |
|
3203.1.17
by Steve Alexander
Various improvements and cleanups from code review. |
403 |
"""Specs menu for ProductSeries.
|
404 |
||
405 |
This menu needs to keep track of whether we are showing all the
|
|
3203.1.6
by Mark Shuttleworth
Improve the Specifications menu for ProductSeries and DistroRelease |
406 |
specs, or just those that are approved/declined/proposed. It should
|
407 |
allow you to change the set your are showing while keeping the basic
|
|
408 |
view intact.
|
|
409 |
"""
|
|
3203.1.3
by Mark Shuttleworth
Substantial cleanup of spec listings and spec targeting |
410 |
|
411 |
usedfor = IProductSeries |
|
412 |
facet = 'specifications' |
|
9838.2.19
by Curtis Hovey
Added register a meeting link to hasspecifications pillars and series. |
413 |
links = [ |
414 |
'listall', 'assignments', 'setgoals', 'listdeclined', |
|
415 |
'new', 'register_sprint'] |
|
4621.2.63
by Jonathan Knowles
Adds the textual "Register a blueprint" link to blueprint listing pages for product series. |
416 |
|
3203.1.3
by Mark Shuttleworth
Substantial cleanup of spec listings and spec targeting |
417 |
|
7709.3.2
by Curtis Hovey
Deleting a release now deletes the files attached to a release too. Updated the |
418 |
class ProductSeriesOverviewNavigationMenu(NavigationMenu): |
419 |
"""Overview navigation menus for `IProductSeries` objects."""
|
|
420 |
# Suppress the ProductOverviewNavigationMenu from showing on series,
|
|
421 |
# release, and milestone pages.
|
|
422 |
usedfor = IProductSeries |
|
423 |
facet = 'overview' |
|
424 |
links = () |
|
425 |
||
426 |
||
3691.125.14
by James Henstridge
fixes suggested by Bjorn in review |
427 |
def get_series_branch_error(product, branch): |
428 |
"""Check if the given branch is suitable for the given product.
|
|
3691.125.12
by James Henstridge
check the (series,branch) constraint when updating a series branch |
429 |
|
430 |
Returns an HTML error message on error, and None otherwise.
|
|
431 |
"""
|
|
432 |
if branch.product != product: |
|
5653.2.6
by Maris Fogels
Fixed a number of broken pagetests. |
433 |
return structured( |
434 |
'<a href="%s">%s</a> is not a branch of <a href="%s">%s</a>.', |
|
435 |
canonical_url(branch), |
|
436 |
branch.unique_name, |
|
437 |
canonical_url(product), |
|
438 |
product.displayname) |
|
3691.125.12
by James Henstridge
check the (series,branch) constraint when updating a series branch |
439 |
return None |
440 |
||
2344
by Canonical.com Patch Queue Manager
[not r=kiko] specification tracker |
441 |
|
8777.6.2
by Danilo Šegan
Move productseries translation views out of registry and into translations. |
442 |
class ProductSeriesView(LaunchpadView, MilestoneOverlayMixin): |
8566.2.4
by Curtis Hovey
Fixed indentation to quiet lint. Added missing docstrings. |
443 |
"""A view to show a series with translations."""
|
9731.2.1
by Curtis Hovey
Extracted +ubuntupkg code to its own view. |
444 |
|
12393.30.9
by Brad Crittenden
Support for product series. Some tests failing for unknown reasons. |
445 |
def initialize(self): |
12393.30.17
by Brad Crittenden
Merge from yellow + use expose_structural_subscription_data_to_js instead of new JSMixin |
446 |
super(ProductSeriesView, self).initialize() |
12393.30.9
by Brad Crittenden
Support for product series. Some tests failing for unknown reasons. |
447 |
expose_structural_subscription_data_to_js( |
448 |
self.context, self.request, self.user) |
|
449 |
||
9731.2.1
by Curtis Hovey
Extracted +ubuntupkg code to its own view. |
450 |
@property
|
451 |
def page_title(self): |
|
452 |
"""Return the HTML page title."""
|
|
453 |
return self.context.title |
|
454 |
||
455 |
def requestCountry(self): |
|
456 |
"""The country associated with the IP of the request."""
|
|
457 |
return ICountry(self.request, None) |
|
458 |
||
459 |
def browserLanguages(self): |
|
460 |
"""The languages the user's browser requested."""
|
|
14593.2.14
by Curtis Hovey
Extracted language helpers to lp.services.worlddata.helpers. |
461 |
return browser_languages(self.request) |
9731.2.1
by Curtis Hovey
Extracted +ubuntupkg code to its own view. |
462 |
|
463 |
@property
|
|
464 |
def request_import_link(self): |
|
465 |
"""A link to the page for requesting a new code import."""
|
|
11318.8.19
by Tim Penhey
Being explicit about code. |
466 |
return canonical_url( |
467 |
self.context.product, view_name='+new-import', rootsite='code') |
|
9731.2.1
by Curtis Hovey
Extracted +ubuntupkg code to its own view. |
468 |
|
469 |
@property
|
|
470 |
def user_branch_visible(self): |
|
471 |
"""Can the logged in user see the user branch."""
|
|
472 |
branch = self.context.branch |
|
473 |
return (branch is not None and |
|
474 |
check_permission('launchpad.View', branch)) |
|
475 |
||
476 |
@property
|
|
477 |
def is_obsolete(self): |
|
9742.7.7
by Edwin Grubbs
Fixed docstrings. |
478 |
"""Return True if the series is OBSOLETE.
|
9731.2.1
by Curtis Hovey
Extracted +ubuntupkg code to its own view. |
479 |
|
480 |
Obsolete series do not need to display as much information as other
|
|
481 |
series. Accessing private bugs is an expensive operation and showing
|
|
482 |
them for obsolete series can be a problem if many series are being
|
|
483 |
displayed.
|
|
484 |
"""
|
|
10054.26.1
by Adi Roiban
Refactor DistroSeriesStatus to SeriesStatus; Don't prompt for setting up translations for obsolete product series. |
485 |
return self.context.status == SeriesStatus.OBSOLETE |
9731.2.1
by Curtis Hovey
Extracted +ubuntupkg code to its own view. |
486 |
|
487 |
@cachedproperty
|
|
488 |
def bugtask_status_counts(self): |
|
489 |
"""A list StatusCounts summarising the targeted bugtasks."""
|
|
490 |
bugtaskset = getUtility(IBugTaskSet) |
|
14124.2.12
by Gavin Panella
Update the ProductSeries:+status view to reflect the new behaviour of getStatusCountsForProductSeries(). |
491 |
status_counts = bugtaskset.getStatusCountsForProductSeries( |
9731.2.1
by Curtis Hovey
Extracted +ubuntupkg code to its own view. |
492 |
self.user, self.context) |
14124.2.12
by Gavin Panella
Update the ProductSeries:+status view to reflect the new behaviour of getStatusCountsForProductSeries(). |
493 |
# We sort by value before sortkey because the statuses returned can be
|
494 |
# from different (though related) enums.
|
|
495 |
statuses = sorted(status_counts, key=attrgetter('value', 'sortkey')) |
|
496 |
return [ |
|
497 |
StatusCount(status, status_counts[status]) |
|
498 |
for status in statuses] |
|
9731.2.1
by Curtis Hovey
Extracted +ubuntupkg code to its own view. |
499 |
|
500 |
@cachedproperty
|
|
501 |
def specification_status_counts(self): |
|
502 |
"""A list StatusCounts summarising the targeted specification."""
|
|
503 |
specification_set = getUtility(ISpecificationSet) |
|
504 |
status_id_counts = specification_set.getStatusCountsForProductSeries( |
|
505 |
self.context) |
|
506 |
SpecStatus = SpecificationImplementationStatus |
|
507 |
status_counts = dict([(SpecStatus.items[status_id], count) |
|
508 |
for status_id, count in status_id_counts]) |
|
509 |
return [StatusCount(status, status_counts[status]) |
|
510 |
for status in sorted(status_counts, |
|
511 |
key=attrgetter('sortkey'))] |
|
512 |
||
7675.803.1
by Edwin Grubbs
Batch milestones. |
513 |
@cachedproperty
|
9731.2.1
by Curtis Hovey
Extracted +ubuntupkg code to its own view. |
514 |
def latest_release_with_download_files(self): |
515 |
for release in self.context.releases: |
|
516 |
if len(list(release.files)) > 0: |
|
517 |
return release |
|
518 |
return None |
|
519 |
||
7675.803.1
by Edwin Grubbs
Batch milestones. |
520 |
@cachedproperty
|
521 |
def milestone_batch_navigator(self): |
|
522 |
return BatchNavigator(self.context.all_milestones, self.request) |
|
523 |
||
9731.2.1
by Curtis Hovey
Extracted +ubuntupkg code to its own view. |
524 |
|
11320.1.1
by Edwin Grubbs
Converted productseries detailed-display from a macro to its own template. |
525 |
class ProductSeriesDetailedDisplayView(ProductSeriesView): |
526 |
||
527 |
@cachedproperty
|
|
528 |
def latest_milestones(self): |
|
11320.1.6
by Edwin Grubbs
Addressed review comments. Fixed _milestone_order. |
529 |
# Convert to list to avoid the query being run multiple times.
|
530 |
return list(self.context.milestones[:12]) |
|
11320.1.1
by Edwin Grubbs
Converted productseries detailed-display from a macro to its own template. |
531 |
|
532 |
@cachedproperty
|
|
533 |
def latest_releases(self): |
|
11320.1.6
by Edwin Grubbs
Addressed review comments. Fixed _milestone_order. |
534 |
# Convert to list to avoid the query being run multiple times.
|
535 |
return list(self.context.releases[:12]) |
|
11320.1.1
by Edwin Grubbs
Converted productseries detailed-display from a macro to its own template. |
536 |
|
537 |
||
10193.2.1
by Edwin Grubbs
Removed PackagingAddView. |
538 |
class ProductSeriesUbuntuPackagingView(LaunchpadFormView): |
9731.2.4
by Curtis Hovey
Refactored the ProductSeriesUbuntuPackagingView to decend from PackagingAddView. |
539 |
|
10193.2.1
by Edwin Grubbs
Removed PackagingAddView. |
540 |
schema = IPackaging |
10023.3.4
by Curtis Hovey
Revise the Ubuntu packaging view to allow the user to select any ubuntu series. |
541 |
field_names = ['sourcepackagename', 'distroseries'] |
9731.2.4
by Curtis Hovey
Refactored the ProductSeriesUbuntuPackagingView to decend from PackagingAddView. |
542 |
page_title = 'Ubuntu source packaging' |
543 |
label = page_title |
|
544 |
||
545 |
def __init__(self, context, request): |
|
9742.7.7
by Edwin Grubbs
Fixed docstrings. |
546 |
"""Set the static packaging information for this series."""
|
9731.2.4
by Curtis Hovey
Refactored the ProductSeriesUbuntuPackagingView to decend from PackagingAddView. |
547 |
super(ProductSeriesUbuntuPackagingView, self).__init__( |
548 |
context, request) |
|
10023.3.4
by Curtis Hovey
Revise the Ubuntu packaging view to allow the user to select any ubuntu series. |
549 |
self._ubuntu = getUtility(ILaunchpadCelebrities).ubuntu |
550 |
self._ubuntu_series = self._ubuntu.currentseries |
|
9710.5.12
by Curtis Hovey
Reverted 9721: |
551 |
try: |
9731.2.4
by Curtis Hovey
Refactored the ProductSeriesUbuntuPackagingView to decend from PackagingAddView. |
552 |
package = self.context.getPackage(self._ubuntu_series) |
553 |
self.default_sourcepackagename = package.sourcepackagename |
|
9710.5.12
by Curtis Hovey
Reverted 9721: |
554 |
except NotFoundError: |
9731.2.4
by Curtis Hovey
Refactored the ProductSeriesUbuntuPackagingView to decend from PackagingAddView. |
555 |
# The package has never been set.
|
556 |
self.default_sourcepackagename = None |
|
557 |
||
10193.2.1
by Edwin Grubbs
Removed PackagingAddView. |
558 |
@property
|
559 |
def next_url(self): |
|
560 |
"""See `LaunchpadFormView`."""
|
|
561 |
return canonical_url(self.context) |
|
562 |
||
563 |
cancel_url = next_url |
|
564 |
||
10023.3.4
by Curtis Hovey
Revise the Ubuntu packaging view to allow the user to select any ubuntu series. |
565 |
def setUpFields(self): |
566 |
"""See `LaunchpadFormView`.
|
|
567 |
||
568 |
The packaging is restricted to ubuntu series and the default value
|
|
569 |
is the current development series.
|
|
570 |
"""
|
|
10023.3.12
by Curtis Hovey
Fixed super() call to ensure the class works if the super class adds a setUpFields(). |
571 |
super(ProductSeriesUbuntuPackagingView, self).setUpFields() |
10023.3.4
by Curtis Hovey
Revise the Ubuntu packaging view to allow the user to select any ubuntu series. |
572 |
series_vocabulary = SimpleVocabulary( |
573 |
[SimpleTerm(series, series.name, series.named_version) |
|
574 |
for series in self._ubuntu.series]) |
|
575 |
choice = Choice(__name__='distroseries', |
|
576 |
title=_('Series'), |
|
577 |
default=self._ubuntu_series, |
|
578 |
vocabulary=series_vocabulary, |
|
579 |
description=_( |
|
10023.3.14
by Curtis Hovey
Updated text per review. |
580 |
"Series where this package is published. The current series "
|
581 |
"is most important to the Ubuntu community."), |
|
10023.3.4
by Curtis Hovey
Revise the Ubuntu packaging view to allow the user to select any ubuntu series. |
582 |
required=True) |
583 |
field = form.Fields(choice, render_context=self.render_context) |
|
584 |
self.form_fields = self.form_fields.omit(choice.__name__) + field |
|
585 |
||
10722.2.3
by Curtis Hovey
Use initial_values instead of setUpWidgets(). |
586 |
@property
|
587 |
def initial_values(self): |
|
588 |
"""See `LaunchpadFormView`."""
|
|
9731.2.4
by Curtis Hovey
Refactored the ProductSeriesUbuntuPackagingView to decend from PackagingAddView. |
589 |
if self.default_sourcepackagename is not None: |
10722.2.3
by Curtis Hovey
Use initial_values instead of setUpWidgets(). |
590 |
return {'sourcepackagename': self.default_sourcepackagename} |
591 |
else: |
|
592 |
return {} |
|
9731.2.4
by Curtis Hovey
Refactored the ProductSeriesUbuntuPackagingView to decend from PackagingAddView. |
593 |
|
594 |
@property
|
|
595 |
def default_distroseries(self): |
|
596 |
"""The current Ubuntu distroseries"""
|
|
597 |
return self._ubuntu_series |
|
598 |
||
599 |
@property
|
|
600 |
def ubuntu_history(self): |
|
601 |
return self.context.getPackagingInDistribution( |
|
602 |
self.default_distroseries.distribution) |
|
603 |
||
10722.2.2
by Curtis Hovey
Added a method to replace duplicate code. |
604 |
def _getSubmittedSeries(self, data): |
605 |
"""Return the submitted or default series."""
|
|
606 |
return data.get('distroseries', self.default_distroseries) |
|
607 |
||
9731.2.4
by Curtis Hovey
Refactored the ProductSeriesUbuntuPackagingView to decend from PackagingAddView. |
608 |
def validate(self, data): |
10193.2.1
by Edwin Grubbs
Removed PackagingAddView. |
609 |
productseries = self.context |
9731.2.4
by Curtis Hovey
Refactored the ProductSeriesUbuntuPackagingView to decend from PackagingAddView. |
610 |
sourcepackagename = data.get('sourcepackagename', None) |
10722.2.2
by Curtis Hovey
Added a method to replace duplicate code. |
611 |
distroseries = self._getSubmittedSeries(data) |
10193.2.1
by Edwin Grubbs
Removed PackagingAddView. |
612 |
|
11099.2.1
by Edwin Grubbs
Fix unique constraint error due to validate() not catching some errors. |
613 |
packaging_util = getUtility(IPackagingUtil) |
614 |
if packaging_util.packagingEntryExists( |
|
615 |
productseries=productseries, |
|
616 |
sourcepackagename=sourcepackagename, |
|
617 |
distroseries=distroseries): |
|
618 |
# The package already exists. Don't display an error. The
|
|
619 |
# action method will let this go by.
|
|
9731.2.4
by Curtis Hovey
Refactored the ProductSeriesUbuntuPackagingView to decend from PackagingAddView. |
620 |
return
|
10193.2.1
by Edwin Grubbs
Removed PackagingAddView. |
621 |
|
10561.1.1
by Edwin Grubbs
Added restriction in IProductSeries.setPackaging(). |
622 |
# Do not allow users to create links to unpublished Ubuntu packages.
|
11099.2.1
by Edwin Grubbs
Fix unique constraint error due to validate() not catching some errors. |
623 |
if (sourcepackagename is not None |
624 |
and distroseries.distribution.full_functionality): |
|
10193.2.1
by Edwin Grubbs
Removed PackagingAddView. |
625 |
source_package = distroseries.getSourcePackage(sourcepackagename) |
626 |
if source_package.currentrelease is None: |
|
627 |
message = ("The source package is not published in %s." % |
|
628 |
distroseries.displayname) |
|
629 |
self.setFieldError('sourcepackagename', message) |
|
11099.2.1
by Edwin Grubbs
Fix unique constraint error due to validate() not catching some errors. |
630 |
|
10193.2.1
by Edwin Grubbs
Removed PackagingAddView. |
631 |
if packaging_util.packagingEntryExists( |
632 |
sourcepackagename=sourcepackagename, |
|
633 |
distroseries=distroseries): |
|
634 |
# The series package conflicts with another series.
|
|
635 |
sourcepackage = distroseries.getSourcePackage( |
|
636 |
sourcepackagename.name) |
|
637 |
message = structured( |
|
638 |
'The <a href="%s">%s</a> package in %s is already linked to ' |
|
639 |
'another series.' % |
|
640 |
(canonical_url(sourcepackage), |
|
641 |
sourcepackagename.name, |
|
642 |
distroseries.displayname)) |
|
643 |
self.setFieldError('sourcepackagename', message) |
|
644 |
||
9731.2.4
by Curtis Hovey
Refactored the ProductSeriesUbuntuPackagingView to decend from PackagingAddView. |
645 |
@action('Update', name='continue') |
646 |
def continue_action(self, action, data): |
|
9710.5.12
by Curtis Hovey
Reverted 9721: |
647 |
# set the packaging record for this productseries in the current
|
648 |
# ubuntu series. if none exists, one will be created
|
|
10722.2.2
by Curtis Hovey
Added a method to replace duplicate code. |
649 |
distroseries = self._getSubmittedSeries(data) |
9731.2.4
by Curtis Hovey
Refactored the ProductSeriesUbuntuPackagingView to decend from PackagingAddView. |
650 |
sourcepackagename = data['sourcepackagename'] |
10722.2.1
by Curtis Hovey
Updated +ubuntupkg view to used the submitted distroseries. |
651 |
if getUtility(IPackagingUtil).packagingEntryExists( |
652 |
sourcepackagename, distroseries, productseries=self.context): |
|
9731.2.4
by Curtis Hovey
Refactored the ProductSeriesUbuntuPackagingView to decend from PackagingAddView. |
653 |
# There is no change.
|
654 |
return
|
|
655 |
self.context.setPackaging( |
|
10722.2.1
by Curtis Hovey
Updated +ubuntupkg view to used the submitted distroseries. |
656 |
distroseries, sourcepackagename, self.user) |
9710.5.12
by Curtis Hovey
Reverted 9721: |
657 |
|
9081.2.8
by Curtis Hovey
Updated the productseries ubuntu packaging page to UI 3.0. |
658 |
|
3691.125.6
by James Henstridge
add UI for setting the branch for a product series |
659 |
class ProductSeriesEditView(LaunchpadEditFormView): |
8566.2.4
by Curtis Hovey
Fixed indentation to quiet lint. Added missing docstrings. |
660 |
"""A View to edit the attributes of a series."""
|
3691.125.6
by James Henstridge
add UI for setting the branch for a product series |
661 |
schema = IProductSeries |
6414.2.3
by Guilherme Salgado
UI for changing a product series' status and displaying it. |
662 |
field_names = [ |
7675.85.2
by Jonathan Lange
Undo revision generated by step 2 of process. |
663 |
'name', 'summary', 'status', 'branch', 'releasefileglob'] |
3691.125.6
by James Henstridge
add UI for setting the branch for a product series |
664 |
custom_widget('summary', TextAreaWidget, height=7, width=62) |
3691.169.13
by James Henstridge
move the releaseroot/releasefileglob entries to the edit product form |
665 |
custom_widget('releasefileglob', StrippedTextWidget, displayWidth=40) |
3691.125.6
by James Henstridge
add UI for setting the branch for a product series |
666 |
|
9081.2.2
by Curtis Hovey
Update the productseries edit page to UI 3.0 |
667 |
@property
|
668 |
def label(self): |
|
669 |
"""The form label."""
|
|
9081.2.10
by Curtis Hovey
Fixed series page title that was broken in a previous commit. |
670 |
return 'Edit %s %s series' % ( |
9081.2.2
by Curtis Hovey
Update the productseries edit page to UI 3.0 |
671 |
self.context.product.displayname, self.context.name) |
672 |
||
673 |
@property
|
|
674 |
def page_title(self): |
|
675 |
"""The page title."""
|
|
676 |
return self.label |
|
677 |
||
3691.125.7
by James Henstridge
allow setting the series branch when creating a product series, and validate that the branch comes from the same product |
678 |
def validate(self, data): |
8566.2.4
by Curtis Hovey
Fixed indentation to quiet lint. Added missing docstrings. |
679 |
"""See `LaunchpadFormView`."""
|
7675.85.2
by Jonathan Lange
Undo revision generated by step 2 of process. |
680 |
branch = data.get('branch') |
3691.125.12
by James Henstridge
check the (series,branch) constraint when updating a series branch |
681 |
if branch is not None: |
3691.125.14
by James Henstridge
fixes suggested by Bjorn in review |
682 |
message = get_series_branch_error(self.context.product, branch) |
3691.125.12
by James Henstridge
check the (series,branch) constraint when updating a series branch |
683 |
if message: |
7675.85.2
by Jonathan Lange
Undo revision generated by step 2 of process. |
684 |
self.setFieldError('branch', message) |
3691.125.7
by James Henstridge
allow setting the series branch when creating a product series, and validate that the branch comes from the same product |
685 |
|
3691.125.6
by James Henstridge
add UI for setting the branch for a product series |
686 |
@action(_('Change'), name='change') |
687 |
def change_action(self, action, data): |
|
8566.2.4
by Curtis Hovey
Fixed indentation to quiet lint. Added missing docstrings. |
688 |
"""Update the series."""
|
3691.125.6
by James Henstridge
add UI for setting the branch for a product series |
689 |
self.updateContextFromData(data) |
690 |
||
691 |
@property
|
|
692 |
def next_url(self): |
|
8566.2.4
by Curtis Hovey
Fixed indentation to quiet lint. Added missing docstrings. |
693 |
"""See `LaunchpadFormView`."""
|
3691.125.6
by James Henstridge
add UI for setting the branch for a product series |
694 |
return canonical_url(self.context) |
695 |
||
9081.2.2
by Curtis Hovey
Update the productseries edit page to UI 3.0 |
696 |
@property
|
697 |
def cancel_url(self): |
|
698 |
"""See `LaunchpadFormView`."""
|
|
699 |
return canonical_url(self.context) |
|
700 |
||
3691.125.6
by James Henstridge
add UI for setting the branch for a product series |
701 |
|
8255.11.2
by Curtis Hovey
Product series owners and drivers can delete mis-created series. |
702 |
class ProductSeriesDeleteView(RegistryDeleteViewMixin, LaunchpadEditFormView): |
703 |
"""A view to remove a productseries from a product."""
|
|
704 |
schema = IProductSeries |
|
705 |
field_names = [] |
|
706 |
||
707 |
@property
|
|
708 |
def label(self): |
|
709 |
"""The form label."""
|
|
9081.2.10
by Curtis Hovey
Fixed series page title that was broken in a previous commit. |
710 |
return 'Delete %s %s series' % ( |
8255.11.2
by Curtis Hovey
Product series owners and drivers can delete mis-created series. |
711 |
self.context.product.displayname, self.context.name) |
712 |
||
9081.2.1
by Curtis Hovey
Updated productseries delete to ui 3.0. |
713 |
@property
|
714 |
def page_title(self): |
|
715 |
"""The page title."""
|
|
716 |
return self.label |
|
717 |
||
8255.11.2
by Curtis Hovey
Product series owners and drivers can delete mis-created series. |
718 |
@cachedproperty
|
719 |
def milestones(self): |
|
720 |
"""A list of all the series `IMilestone`s."""
|
|
721 |
return self.context.all_milestones |
|
722 |
||
723 |
@cachedproperty
|
|
724 |
def bugtasks(self): |
|
725 |
"""A list of all `IBugTask`s targeted to this series."""
|
|
9571.1.5
by Curtis Hovey
Optimised code to keep it DRY. |
726 |
all_bugtasks = self._getBugtasks(self.context) |
8255.11.2
by Curtis Hovey
Product series owners and drivers can delete mis-created series. |
727 |
for milestone in self.milestones: |
728 |
all_bugtasks.extend(self._getBugtasks(milestone)) |
|
729 |
return all_bugtasks |
|
730 |
||
731 |
@cachedproperty
|
|
732 |
def specifications(self): |
|
733 |
"""A list of all `ISpecification`s targeted to this series."""
|
|
9571.1.5
by Curtis Hovey
Optimised code to keep it DRY. |
734 |
all_specifications = self._getSpecifications(self.context) |
8255.11.2
by Curtis Hovey
Product series owners and drivers can delete mis-created series. |
735 |
for milestone in self.milestones: |
736 |
all_specifications.extend(self._getSpecifications(milestone)) |
|
737 |
return all_specifications |
|
738 |
||
739 |
@cachedproperty
|
|
740 |
def has_bugtasks_and_specifications(self): |
|
741 |
"""Does the series have any targeted bugtasks or specifications."""
|
|
742 |
return len(self.bugtasks) > 0 or len(self.specifications) > 0 |
|
743 |
||
9571.1.6
by Curtis Hovey
Updated the UI to have consistent list indentation. Add a rule to show which branch will be unlinked if the series is deleted. |
744 |
@property
|
745 |
def has_linked_branch(self): |
|
746 |
"""Is the series linked to a branch."""
|
|
747 |
return self.context.branch is not None |
|
748 |
||
8255.11.2
by Curtis Hovey
Product series owners and drivers can delete mis-created series. |
749 |
@cachedproperty
|
750 |
def product_release_files(self): |
|
751 |
"""A list of all `IProductReleaseFile`s that belong to this series."""
|
|
752 |
all_files = [] |
|
753 |
for milestone in self.milestones: |
|
754 |
all_files.extend(self._getProductReleaseFiles(milestone)) |
|
755 |
return all_files |
|
756 |
||
9963.2.2
by Curtis Hovey
Do not delete a series if it has translations. |
757 |
@cachedproperty
|
9963.2.1
by Curtis Hovey
Do not allow users to delete series that are linked to packages. |
758 |
def has_linked_packages(self): |
759 |
"""Is the series linked to source packages."""
|
|
760 |
return self.context.packagings.count() > 0 |
|
761 |
||
9963.2.2
by Curtis Hovey
Do not delete a series if it has translations. |
762 |
@cachedproperty
|
9963.2.1
by Curtis Hovey
Do not allow users to delete series that are linked to packages. |
763 |
def linked_packages_message(self): |
764 |
url = canonical_url(self.context.product, view_name="+packages") |
|
765 |
return ( |
|
766 |
"You cannot delete a series that is linked to packages in "
|
|
767 |
"distributions. You can remove the links from the "
|
|
768 |
'<a href="%s">project packaging</a> page.' % url) |
|
769 |
||
770 |
development_focus_message = _( |
|
771 |
"You cannot delete a series that is the focus of "
|
|
772 |
"development. Make another series the focus of development "
|
|
773 |
"before deleting this one.") |
|
774 |
||
8255.11.2
by Curtis Hovey
Product series owners and drivers can delete mis-created series. |
775 |
@cachedproperty
|
9963.2.2
by Curtis Hovey
Do not delete a series if it has translations. |
776 |
def has_translations(self): |
777 |
"""Does the series have translations?"""
|
|
778 |
return self.context.potemplate_count > 0 |
|
779 |
||
780 |
translations_message = ( |
|
781 |
"This series cannot be deleted because it has translations.") |
|
782 |
||
783 |
@cachedproperty
|
|
8255.11.2
by Curtis Hovey
Product series owners and drivers can delete mis-created series. |
784 |
def can_delete(self): |
785 |
"""Can this series be delete."""
|
|
9963.2.1
by Curtis Hovey
Do not allow users to delete series that are linked to packages. |
786 |
return not ( |
9963.2.2
by Curtis Hovey
Do not delete a series if it has translations. |
787 |
self.context.is_development_focus |
788 |
or self.has_linked_packages or self.has_translations) |
|
8255.11.2
by Curtis Hovey
Product series owners and drivers can delete mis-created series. |
789 |
|
790 |
def canDeleteAction(self, action): |
|
791 |
"""Is the delete action available."""
|
|
9963.2.1
by Curtis Hovey
Do not allow users to delete series that are linked to packages. |
792 |
if self.context.is_development_focus: |
793 |
self.addError(self.development_focus_message) |
|
9963.2.4
by Curtis Hovey
Changes per review. |
794 |
if self.has_linked_packages: |
9963.2.1
by Curtis Hovey
Do not allow users to delete series that are linked to packages. |
795 |
self.addError(structured(self.linked_packages_message)) |
9963.2.4
by Curtis Hovey
Changes per review. |
796 |
if self.has_translations: |
9963.2.2
by Curtis Hovey
Do not delete a series if it has translations. |
797 |
self.addError(self.translations_message) |
8255.11.2
by Curtis Hovey
Product series owners and drivers can delete mis-created series. |
798 |
return self.can_delete |
799 |
||
800 |
@action('Delete this Series', name='delete', condition=canDeleteAction) |
|
801 |
def delete_action(self, action, data): |
|
802 |
"""Detach and delete associated objects and remove the series."""
|
|
803 |
product = self.context.product |
|
804 |
name = self.context.name |
|
8255.11.4
by Curtis Hovey
Changes per review. Moved the delete productseries rule to the RegistryDeleteMixin. Added support for BeautifulSoup PageElements as content to find_tag_by_id(). Added has_available_actions to LaunchpadFormView and made the 'or' before the cancel link conditional upon it. |
805 |
self._deleteProductSeries(self.context) |
8255.11.2
by Curtis Hovey
Product series owners and drivers can delete mis-created series. |
806 |
self.request.response.addInfoNotification( |
807 |
"Series %s deleted." % name) |
|
808 |
self.next_url = canonical_url(product) |
|
809 |
||
810 |
||
10456.2.11
by Brad Crittenden
Added more browser functionality for +setbranch |
811 |
LINK_LP_BZR = 'link-lp-bzr' |
812 |
CREATE_NEW = 'create-new' |
|
813 |
IMPORT_EXTERNAL = 'import-external' |
|
814 |
||
815 |
||
10456.2.17
by Brad Crittenden
Made branch type vocabulary a constant |
816 |
BRANCH_TYPE_VOCABULARY = SimpleVocabulary(( |
817 |
SimpleTerm(LINK_LP_BZR, LINK_LP_BZR, |
|
818 |
_("Link to a Bazaar branch already on Launchpad")), |
|
819 |
SimpleTerm(CREATE_NEW, CREATE_NEW, |
|
820 |
_("Create a new, empty branch in Launchpad and " |
|
821 |
"link to this series")), |
|
822 |
SimpleTerm(IMPORT_EXTERNAL, IMPORT_EXTERNAL, |
|
823 |
_("Import a branch hosted somewhere else")), |
|
824 |
))
|
|
10456.2.1
by Brad Crittenden
checkpoint |
825 |
|
826 |
||
827 |
class SetBranchForm(Interface): |
|
828 |
"""The fields presented on the form for setting a branch."""
|
|
829 |
||
830 |
use_template( |
|
831 |
ICodeImport, |
|
832 |
['cvs_module']) |
|
833 |
||
834 |
rcs_type = Choice(title=_("Type of RCS"), |
|
13756.4.1
by Jelmer Vernooij
Re-import bzr code imports. |
835 |
required=False, vocabulary=RevisionControlSystems, |
10456.2.1
by Brad Crittenden
checkpoint |
836 |
description=_( |
837 |
"The version control system to import from. ")) |
|
838 |
||
839 |
repo_url = URIField( |
|
10456.2.13
by Brad Crittenden
Added browser support for other +setbranch options |
840 |
title=_("Branch URL"), required=True, |
10456.2.1
by Brad Crittenden
checkpoint |
841 |
description=_("The URL of the branch."), |
10456.2.16
by Brad Crittenden
Fixed form validation errors and added tests. |
842 |
allowed_schemes=["http", "https"], |
10456.2.1
by Brad Crittenden
checkpoint |
843 |
allow_userinfo=False, |
844 |
allow_port=True, |
|
845 |
allow_query=False, |
|
846 |
allow_fragment=False, |
|
847 |
trailing_slash=False) |
|
848 |
||
849 |
branch_location = copy_field( |
|
850 |
IProductSeries['branch'], |
|
851 |
__name__='branch_location', |
|
10456.2.8
by Brad Crittenden
Added branch name and owner fields to the interface and template. |
852 |
title=_('Branch'), |
10456.2.1
by Brad Crittenden
checkpoint |
853 |
description=_( |
854 |
"The Bazaar branch for this series in Launchpad, "
|
|
855 |
"if one exists."), |
|
856 |
)
|
|
857 |
||
858 |
branch_type = Choice( |
|
859 |
title=_('Import type'), |
|
10456.2.17
by Brad Crittenden
Made branch type vocabulary a constant |
860 |
vocabulary=BRANCH_TYPE_VOCABULARY, |
10456.2.1
by Brad Crittenden
checkpoint |
861 |
description=_("The type of import"), |
862 |
required=True) |
|
863 |
||
10456.2.8
by Brad Crittenden
Added branch name and owner fields to the interface and template. |
864 |
branch_name = copy_field( |
865 |
IBranch['name'], |
|
866 |
__name__='branch_name', |
|
867 |
title=_('Branch name'), |
|
868 |
description=_(''), |
|
10456.2.13
by Brad Crittenden
Added browser support for other +setbranch options |
869 |
required=True, |
10456.2.8
by Brad Crittenden
Added branch name and owner fields to the interface and template. |
870 |
)
|
871 |
||
872 |
branch_owner = copy_field( |
|
873 |
IBranch['owner'], |
|
874 |
__name__='branch_owner', |
|
875 |
title=_('Branch owner'), |
|
876 |
description=_(''), |
|
10456.2.13
by Brad Crittenden
Added browser support for other +setbranch options |
877 |
required=True, |
10456.2.8
by Brad Crittenden
Added branch name and owner fields to the interface and template. |
878 |
)
|
879 |
||
10456.2.1
by Brad Crittenden
checkpoint |
880 |
|
10469.1.21
by Edwin Grubbs
Make involvement portlet use +setbranch instead of +linkbranch. |
881 |
class ProductSeriesSetBranchView(ReturnToReferrerMixin, LaunchpadFormView, |
882 |
ProductSeriesView, |
|
10456.2.13
by Brad Crittenden
Added browser support for other +setbranch options |
883 |
BranchNameValidationMixin): |
10456.2.1
by Brad Crittenden
checkpoint |
884 |
"""The view to set a branch for the ProductSeries."""
|
885 |
||
886 |
schema = SetBranchForm |
|
887 |
# Set for_input to True to ensure fields marked read-only will be editable
|
|
888 |
# upon creation.
|
|
889 |
for_input = True |
|
890 |
||
891 |
custom_widget('rcs_type', LaunchpadRadioWidget) |
|
892 |
custom_widget('branch_type', LaunchpadRadioWidget) |
|
893 |
||
10667.3.8
by Brad Crittenden
Create mechanism to override next_url when there are errors. |
894 |
errors_in_action = False |
895 |
||
896 |
@property
|
|
10714.1.3
by Brad Crittenden
Updated the way initial_values are handled to make more sense. |
897 |
def initial_values(self): |
898 |
return dict( |
|
13756.4.1
by Jelmer Vernooij
Re-import bzr code imports. |
899 |
rcs_type=RevisionControlSystems.BZR, |
10714.1.3
by Brad Crittenden
Updated the way initial_values are handled to make more sense. |
900 |
branch_type=LINK_LP_BZR, |
901 |
branch_location=self.context.branch) |
|
902 |
||
903 |
@property
|
|
10667.3.8
by Brad Crittenden
Create mechanism to override next_url when there are errors. |
904 |
def next_url(self): |
905 |
"""Return the next_url.
|
|
906 |
||
907 |
Use the value from `ReturnToReferrerMixin` or None if there
|
|
908 |
are errors.
|
|
909 |
"""
|
|
910 |
if self.errors_in_action: |
|
911 |
return None |
|
912 |
return super(ProductSeriesSetBranchView, self).next_url |
|
913 |
||
10456.2.18
by Brad Crittenden
Change widget generation based on review |
914 |
def setUpWidgets(self): |
10456.2.29
by Brad Crittenden
Cleaned up render method. Other changes from review. |
915 |
"""See `LaunchpadFormView`."""
|
10456.2.18
by Brad Crittenden
Change widget generation based on review |
916 |
super(ProductSeriesSetBranchView, self).setUpWidgets() |
917 |
widget = self.widgets['rcs_type'] |
|
918 |
vocab = widget.vocabulary |
|
10456.2.29
by Brad Crittenden
Cleaned up render method. Other changes from review. |
919 |
current_value = widget._getFormValue() |
11929.11.14
by Tim Penhey
Move the method to render a part of the widget into the launchpadform module. |
920 |
self.rcs_type_cvs = render_radio_widget_part( |
921 |
widget, vocab.CVS, current_value, 'CVS') |
|
922 |
self.rcs_type_svn = render_radio_widget_part( |
|
923 |
widget, vocab.BZR_SVN, current_value, 'SVN') |
|
924 |
self.rcs_type_git = render_radio_widget_part( |
|
925 |
widget, vocab.GIT, current_value) |
|
926 |
self.rcs_type_hg = render_radio_widget_part( |
|
927 |
widget, vocab.HG, current_value) |
|
928 |
self.rcs_type_bzr = render_radio_widget_part( |
|
929 |
widget, vocab.BZR, current_value) |
|
10456.2.18
by Brad Crittenden
Change widget generation based on review |
930 |
self.rcs_type_emptymarker = widget._emptyMarker() |
931 |
||
932 |
widget = self.widgets['branch_type'] |
|
933 |
current_value = widget._getFormValue() |
|
934 |
vocab = widget.vocabulary |
|
935 |
||
936 |
(self.branch_type_link, |
|
937 |
self.branch_type_create, |
|
938 |
self.branch_type_import) = [ |
|
11929.11.14
by Tim Penhey
Move the method to render a part of the widget into the launchpadform module. |
939 |
render_radio_widget_part(widget, value, current_value) |
10456.2.18
by Brad Crittenden
Change widget generation based on review |
940 |
for value in (LINK_LP_BZR, CREATE_NEW, IMPORT_EXTERNAL)] |
941 |
||
10456.2.16
by Brad Crittenden
Fixed form validation errors and added tests. |
942 |
def _validateLinkLpBzr(self, data): |
10456.2.12
by Brad Crittenden
Added more tests and functionality to ProductSeriesSetBranchView |
943 |
"""Validate data for link-lp-bzr case."""
|
944 |
if 'branch_location' not in data: |
|
945 |
self.setFieldError( |
|
946 |
'branch_location', |
|
947 |
'The branch location must be set.') |
|
948 |
||
10456.2.16
by Brad Crittenden
Fixed form validation errors and added tests. |
949 |
def _validateCreateNew(self, data): |
10456.2.12
by Brad Crittenden
Added more tests and functionality to ProductSeriesSetBranchView |
950 |
"""Validate data for create new case."""
|
10456.2.16
by Brad Crittenden
Fixed form validation errors and added tests. |
951 |
self._validateBranch(data) |
10456.2.12
by Brad Crittenden
Added more tests and functionality to ProductSeriesSetBranchView |
952 |
|
10456.2.21
by Brad Crittenden
Give widget errors high priority |
953 |
def _validateImportExternal(self, data): |
10456.2.12
by Brad Crittenden
Added more tests and functionality to ProductSeriesSetBranchView |
954 |
"""Validate data for import external case."""
|
10456.2.11
by Brad Crittenden
Added more browser functionality for +setbranch |
955 |
rcs_type = data.get('rcs_type') |
956 |
repo_url = data.get('repo_url') |
|
10456.2.16
by Brad Crittenden
Fixed form validation errors and added tests. |
957 |
|
958 |
if repo_url is None: |
|
959 |
self.setFieldError('repo_url', |
|
960 |
'You must set the external repository URL.') |
|
10456.2.22
by Brad Crittenden
Do not allow duplicate code imports for the same URL |
961 |
else: |
962 |
# Ensure this URL has not been imported before.
|
|
963 |
code_import = getUtility(ICodeImportSet).getByURL(repo_url) |
|
964 |
if code_import is not None: |
|
965 |
self.setFieldError( |
|
966 |
'repo_url', |
|
967 |
structured(""" |
|
968 |
This foreign branch URL is already specified for
|
|
969 |
the imported branch <a href="%s">%s</a>.""", |
|
970 |
canonical_url(code_import.branch), |
|
971 |
code_import.branch.unique_name)) |
|
10456.2.16
by Brad Crittenden
Fixed form validation errors and added tests. |
972 |
|
10456.2.12
by Brad Crittenden
Added more tests and functionality to ProductSeriesSetBranchView |
973 |
# RCS type is mandatory.
|
974 |
# This condition should never happen since an initial value is set.
|
|
975 |
if rcs_type is None: |
|
976 |
# The error shows but does not identify the widget.
|
|
977 |
self.setFieldError( |
|
978 |
'rcs_type', |
|
979 |
'You must specify the type of RCS for the remote host.') |
|
13756.4.1
by Jelmer Vernooij
Re-import bzr code imports. |
980 |
elif rcs_type == RevisionControlSystems.CVS: |
10456.2.16
by Brad Crittenden
Fixed form validation errors and added tests. |
981 |
if 'cvs_module' not in data: |
982 |
self.setFieldError( |
|
983 |
'cvs_module', |
|
984 |
'The CVS module must be set.') |
|
985 |
self._validateBranch(data) |
|
10456.2.12
by Brad Crittenden
Added more tests and functionality to ProductSeriesSetBranchView |
986 |
|
10456.2.16
by Brad Crittenden
Fixed form validation errors and added tests. |
987 |
def _validateBranch(self, data): |
10456.2.12
by Brad Crittenden
Added more tests and functionality to ProductSeriesSetBranchView |
988 |
"""Validate that branch name and owner are set."""
|
989 |
if 'branch_name' not in data: |
|
990 |
self.setFieldError( |
|
991 |
'branch_name', |
|
992 |
'The branch name must be set.') |
|
993 |
if 'branch_owner' not in data: |
|
994 |
self.setFieldError( |
|
995 |
'branch_owner', |
|
996 |
'The branch owner must be set.') |
|
997 |
||
10456.2.16
by Brad Crittenden
Fixed form validation errors and added tests. |
998 |
def _setRequired(self, names, value): |
10456.2.13
by Brad Crittenden
Added browser support for other +setbranch options |
999 |
"""Mark the widget field as optional."""
|
1000 |
for name in names: |
|
1001 |
widget = self.widgets[name] |
|
1002 |
# The 'required' property on the widget context is set to False.
|
|
1003 |
# The widget also has a 'required' property but it isn't used
|
|
1004 |
# during validation.
|
|
10456.2.16
by Brad Crittenden
Fixed form validation errors and added tests. |
1005 |
widget.context.required = value |
1006 |
||
1007 |
def _validSchemes(self, rcs_type): |
|
1008 |
"""Return the valid schemes for the repository URL."""
|
|
1009 |
schemes = set(['http', 'https']) |
|
1010 |
# Extend the allowed schemes for the repository URL based on
|
|
1011 |
# rcs_type.
|
|
1012 |
extra_schemes = { |
|
13756.4.1
by Jelmer Vernooij
Re-import bzr code imports. |
1013 |
RevisionControlSystems.BZR_SVN: ['svn'], |
1014 |
RevisionControlSystems.GIT: ['git'], |
|
1015 |
RevisionControlSystems.BZR: ['bzr'], |
|
10456.2.16
by Brad Crittenden
Fixed form validation errors and added tests. |
1016 |
}
|
1017 |
schemes.update(extra_schemes.get(rcs_type, [])) |
|
1018 |
return schemes |
|
10456.2.13
by Brad Crittenden
Added browser support for other +setbranch options |
1019 |
|
1020 |
def validate_widgets(self, data, names=None): |
|
1021 |
"""See `LaunchpadFormView`."""
|
|
1022 |
names = ['branch_type', 'rcs_type'] |
|
1023 |
super(ProductSeriesSetBranchView, self).validate_widgets(data, names) |
|
1024 |
branch_type = data.get('branch_type') |
|
1025 |
if branch_type == LINK_LP_BZR: |
|
1026 |
# Mark other widgets as non-required.
|
|
10456.2.16
by Brad Crittenden
Fixed form validation errors and added tests. |
1027 |
self._setRequired(['rcs_type', 'repo_url', 'cvs_module', |
1028 |
'branch_name', 'branch_owner'], False) |
|
10456.2.13
by Brad Crittenden
Added browser support for other +setbranch options |
1029 |
elif branch_type == CREATE_NEW: |
10456.2.25
by Brad Crittenden
Make repo_url optional for creating a new branch. Set the registrant properly for an import |
1030 |
self._setRequired( |
1031 |
['branch_location', 'repo_url', 'rcs_type', 'cvs_module'], |
|
1032 |
False) |
|
10456.2.13
by Brad Crittenden
Added browser support for other +setbranch options |
1033 |
elif branch_type == IMPORT_EXTERNAL: |
1034 |
rcs_type = data.get('rcs_type') |
|
10456.2.16
by Brad Crittenden
Fixed form validation errors and added tests. |
1035 |
|
1036 |
# Set the valid schemes based on rcs_type.
|
|
1037 |
self.widgets['repo_url'].field.allowed_schemes = ( |
|
1038 |
self._validSchemes(rcs_type)) |
|
1039 |
# The branch location is not required for validation.
|
|
1040 |
self._setRequired(['branch_location'], False) |
|
1041 |
# The cvs_module is required if it is a CVS import.
|
|
13756.4.1
by Jelmer Vernooij
Re-import bzr code imports. |
1042 |
if rcs_type == RevisionControlSystems.CVS: |
10456.2.16
by Brad Crittenden
Fixed form validation errors and added tests. |
1043 |
self._setRequired(['cvs_module'], True) |
10456.2.13
by Brad Crittenden
Added browser support for other +setbranch options |
1044 |
else: |
1045 |
raise AssertionError("Unknown branch type %s" % branch_type) |
|
1046 |
# Perform full validation now.
|
|
1047 |
super(ProductSeriesSetBranchView, self).validate_widgets(data) |
|
1048 |
||
10456.2.12
by Brad Crittenden
Added more tests and functionality to ProductSeriesSetBranchView |
1049 |
def validate(self, data): |
1050 |
"""See `LaunchpadFormView`."""
|
|
10456.2.21
by Brad Crittenden
Give widget errors high priority |
1051 |
# If widget validation returned errors then there is no need to
|
1052 |
# continue as we'd likely just override the errors reported there.
|
|
1053 |
if len(self.errors) > 0: |
|
1054 |
return
|
|
10456.2.11
by Brad Crittenden
Added more browser functionality for +setbranch |
1055 |
branch_type = data['branch_type'] |
1056 |
if branch_type == IMPORT_EXTERNAL: |
|
10456.2.21
by Brad Crittenden
Give widget errors high priority |
1057 |
self._validateImportExternal(data) |
10456.2.11
by Brad Crittenden
Added more browser functionality for +setbranch |
1058 |
elif branch_type == LINK_LP_BZR: |
10456.2.16
by Brad Crittenden
Fixed form validation errors and added tests. |
1059 |
self._validateLinkLpBzr(data) |
10456.2.12
by Brad Crittenden
Added more tests and functionality to ProductSeriesSetBranchView |
1060 |
elif branch_type == CREATE_NEW: |
10456.2.16
by Brad Crittenden
Fixed form validation errors and added tests. |
1061 |
self._validateCreateNew(data) |
10456.2.12
by Brad Crittenden
Added more tests and functionality to ProductSeriesSetBranchView |
1062 |
else: |
1063 |
raise AssertionError("Unknown branch type %s" % branch_type) |
|
10456.2.3
by Brad Crittenden
Working JS interface. No backend support. |
1064 |
|
10456.2.13
by Brad Crittenden
Added browser support for other +setbranch options |
1065 |
@property
|
1066 |
def target(self): |
|
1067 |
"""The branch target for the context."""
|
|
10648.1.9
by Curtis Hovey
Move ProductSeries branch_add menu link to Product to avoid crafting links. |
1068 |
return IBranchTarget(self.context.product) |
10456.2.13
by Brad Crittenden
Added browser support for other +setbranch options |
1069 |
|
10456.2.3
by Brad Crittenden
Working JS interface. No backend support. |
1070 |
@action(_('Update'), name='update') |
1071 |
def update_action(self, action, data): |
|
1072 |
branch_type = data.get('branch_type') |
|
10456.2.11
by Brad Crittenden
Added more browser functionality for +setbranch |
1073 |
if branch_type == LINK_LP_BZR: |
10456.2.3
by Brad Crittenden
Working JS interface. No backend support. |
1074 |
branch_location = data.get('branch_location') |
10456.2.12
by Brad Crittenden
Added more tests and functionality to ProductSeriesSetBranchView |
1075 |
if branch_location != self.context.branch: |
1076 |
self.context.branch = branch_location |
|
1077 |
# Request an initial upload of translation files.
|
|
1078 |
getUtility(IRosettaUploadJobSource).create( |
|
1079 |
self.context.branch, NULL_REVISION) |
|
10456.2.3
by Brad Crittenden
Working JS interface. No backend support. |
1080 |
else: |
10456.2.12
by Brad Crittenden
Added more tests and functionality to ProductSeriesSetBranchView |
1081 |
self.context.branch = branch_location |
1082 |
self.request.response.addInfoNotification( |
|
1083 |
'Series code location updated.') |
|
10456.2.3
by Brad Crittenden
Working JS interface. No backend support. |
1084 |
else: |
10456.2.11
by Brad Crittenden
Added more browser functionality for +setbranch |
1085 |
branch_name = data.get('branch_name') |
1086 |
branch_owner = data.get('branch_owner') |
|
10456.2.16
by Brad Crittenden
Fixed form validation errors and added tests. |
1087 |
|
1088 |
# Create a new branch.
|
|
10456.2.11
by Brad Crittenden
Added more browser functionality for +setbranch |
1089 |
if branch_type == CREATE_NEW: |
13756.5.1
by Jelmer Vernooij
Reimport bzr code import support UI patch. |
1090 |
branch = self._createBzrBranch(branch_name, branch_owner) |
10456.2.16
by Brad Crittenden
Fixed form validation errors and added tests. |
1091 |
if branch is not None: |
1092 |
self.context.branch = branch |
|
1093 |
self.request.response.addInfoNotification( |
|
1094 |
'New branch created and linked to the series.') |
|
1095 |
||
1096 |
# Import or mirror an external branch.
|
|
10456.2.11
by Brad Crittenden
Added more browser functionality for +setbranch |
1097 |
elif branch_type == IMPORT_EXTERNAL: |
10456.2.13
by Brad Crittenden
Added browser support for other +setbranch options |
1098 |
# Either create an externally hosted bzr branch
|
1099 |
# (a.k.a. 'mirrored') or create a new code import.
|
|
1100 |
rcs_type = data.get('rcs_type') |
|
13756.5.1
by Jelmer Vernooij
Reimport bzr code import support UI patch. |
1101 |
# We need to create an import request.
|
1102 |
if rcs_type == RevisionControlSystems.CVS: |
|
1103 |
cvs_root = data.get('repo_url') |
|
1104 |
cvs_module = data.get('cvs_module') |
|
1105 |
url = None |
|
10456.2.13
by Brad Crittenden
Added browser support for other +setbranch options |
1106 |
else: |
13756.5.1
by Jelmer Vernooij
Reimport bzr code import support UI patch. |
1107 |
cvs_root = None |
1108 |
cvs_module = None |
|
1109 |
url = data.get('repo_url') |
|
1110 |
rcs_item = RevisionControlSystems.items[rcs_type.name] |
|
1111 |
try: |
|
1112 |
code_import = getUtility(ICodeImportSet).new( |
|
1113 |
registrant=branch_owner, |
|
1114 |
target=IBranchTarget(self.context.product), |
|
1115 |
branch_name=branch_name, |
|
1116 |
rcs_type=rcs_item, |
|
1117 |
url=url, |
|
1118 |
cvs_root=cvs_root, |
|
1119 |
cvs_module=cvs_module) |
|
1120 |
except BranchExists, e: |
|
1121 |
self._setBranchExists(e.existing_branch, |
|
1122 |
'branch_name') |
|
1123 |
self.errors_in_action = True |
|
1124 |
# Abort transaction. This is normally handled
|
|
1125 |
# by LaunchpadFormView, but we are already in
|
|
1126 |
# the success handler.
|
|
1127 |
self._abort() |
|
1128 |
return
|
|
1129 |
self.context.branch = code_import.branch |
|
1130 |
self.request.response.addInfoNotification( |
|
1131 |
'Code import created and branch linked to the '
|
|
1132 |
'series.') |
|
10456.2.11
by Brad Crittenden
Added more browser functionality for +setbranch |
1133 |
else: |
1134 |
raise UnexpectedFormData(branch_type) |
|
10456.2.3
by Brad Crittenden
Working JS interface. No backend support. |
1135 |
|
13756.5.1
by Jelmer Vernooij
Reimport bzr code import support UI patch. |
1136 |
def _createBzrBranch(self, branch_name, branch_owner, repo_url=None): |
13756.5.14
by Jelmer Vernooij
Work on fixing code import UI. |
1137 |
"""Create a new hosted Bazaar branch.
|
10456.2.16
by Brad Crittenden
Fixed form validation errors and added tests. |
1138 |
|
1139 |
Return the branch on success or None.
|
|
1140 |
"""
|
|
1141 |
branch = None |
|
10456.2.13
by Brad Crittenden
Added browser support for other +setbranch options |
1142 |
try: |
1143 |
namespace = self.target.getNamespace(branch_owner) |
|
13756.5.1
by Jelmer Vernooij
Reimport bzr code import support UI patch. |
1144 |
branch = namespace.createBranch(branch_type=BranchType.HOSTED, |
10456.2.13
by Brad Crittenden
Added browser support for other +setbranch options |
1145 |
name=branch_name, |
10456.2.16
by Brad Crittenden
Fixed form validation errors and added tests. |
1146 |
registrant=self.user, |
1147 |
url=repo_url) |
|
10456.2.13
by Brad Crittenden
Added browser support for other +setbranch options |
1148 |
except BranchCreationForbidden: |
1149 |
self.addError( |
|
1150 |
"You are not allowed to create branches in %s." % |
|
1151 |
self.context.displayname) |
|
1152 |
except BranchExists, e: |
|
1153 |
self._setBranchExists(e.existing_branch, 'branch_name') |
|
10820.1.1
by Edwin Grubbs
Fixed error messages. Enable submit code link for product series once a branch has been set for the series. |
1154 |
if branch is None: |
1155 |
self.errors_in_action = True |
|
1156 |
# Abort transaction. This is normally handled by
|
|
1157 |
# LaunchpadFormView, but we are already in the success handler.
|
|
1158 |
self._abort() |
|
10456.2.16
by Brad Crittenden
Fixed form validation errors and added tests. |
1159 |
return branch |
10456.2.13
by Brad Crittenden
Added browser support for other +setbranch options |
1160 |
|
10456.2.1
by Brad Crittenden
checkpoint |
1161 |
|
10469.1.13
by Edwin Grubbs
Handled reviewer comments. |
1162 |
class ProductSeriesLinkBranchView(ReturnToReferrerMixin, |
10469.1.20
by Edwin Grubbs
Merged in ~bac/launchpad/bug-524302 |
1163 |
ProductSeriesView, |
10469.1.13
by Edwin Grubbs
Handled reviewer comments. |
1164 |
LaunchpadEditFormView): |
5481.2.2
by Tim Penhey
Added a new page just to set the bazaar branch. |
1165 |
"""View to set the bazaar branch for a product series."""
|
1166 |
||
1167 |
schema = IProductSeries |
|
7675.85.2
by Jonathan Lange
Undo revision generated by step 2 of process. |
1168 |
field_names = ['branch'] |
5481.2.2
by Tim Penhey
Added a new page just to set the bazaar branch. |
1169 |
|
1170 |
@property
|
|
9081.2.6
by Curtis Hovey
Updated the product linkbranch page to UI 3.0. |
1171 |
def label(self): |
1172 |
"""The form label."""
|
|
9081.2.10
by Curtis Hovey
Fixed series page title that was broken in a previous commit. |
1173 |
return 'Link an existing branch to %s %s series' % ( |
9081.2.6
by Curtis Hovey
Updated the product linkbranch page to UI 3.0. |
1174 |
self.context.product.displayname, self.context.name) |
1175 |
||
1176 |
@property
|
|
1177 |
def page_title(self): |
|
1178 |
"""The page title."""
|
|
1179 |
return self.label |
|
1180 |
||
7675.85.2
by Jonathan Lange
Undo revision generated by step 2 of process. |
1181 |
@action(_('Update'), name='update') |
5481.2.2
by Tim Penhey
Added a new page just to set the bazaar branch. |
1182 |
def update_action(self, action, data): |
8566.2.4
by Curtis Hovey
Fixed indentation to quiet lint. Added missing docstrings. |
1183 |
"""Update the branch attribute."""
|
7675.85.2
by Jonathan Lange
Undo revision generated by step 2 of process. |
1184 |
if data['branch'] != self.context.branch: |
1185 |
self.updateContextFromData(data) |
|
1186 |
# Request an initial upload of translation files.
|
|
1187 |
getUtility(IRosettaUploadJobSource).create( |
|
1188 |
self.context.branch, NULL_REVISION) |
|
1189 |
else: |
|
1190 |
self.updateContextFromData(data) |
|
5481.2.2
by Tim Penhey
Added a new page just to set the bazaar branch. |
1191 |
self.request.response.addInfoNotification( |
1192 |
'Series code location updated.') |
|
1193 |
||
1194 |
||
5481.2.6
by Tim Penhey
Fixes following review |
1195 |
class ProductSeriesLinkBranchFromCodeView(ProductSeriesLinkBranchView): |
1196 |
"""Set the branch link from the code overview page."""
|
|
1197 |
||
1198 |
@property
|
|
1199 |
def next_url(self): |
|
1200 |
"""Take the user back to the code overview page."""
|
|
1201 |
return canonical_url(self.context.product, rootsite="code") |
|
1202 |
||
1203 |
||
7182.6.3
by Guilherme Salgado
Convert ProductSeriesReviewView into a LFV |
1204 |
class ProductSeriesReviewView(LaunchpadEditFormView): |
8566.2.4
by Curtis Hovey
Fixed indentation to quiet lint. Added missing docstrings. |
1205 |
"""A view to review and change the series `IProduct` and name."""
|
7182.6.3
by Guilherme Salgado
Convert ProductSeriesReviewView into a LFV |
1206 |
schema = IProductSeries |
1207 |
field_names = ['product', 'name'] |
|
1208 |
custom_widget('name', TextWidget, width=20) |
|
1209 |
||
9081.2.5
by Curtis Hovey
Updated the product review page to UI 3.0. |
1210 |
@property
|
1211 |
def label(self): |
|
1212 |
"""The form label."""
|
|
9081.2.10
by Curtis Hovey
Fixed series page title that was broken in a previous commit. |
1213 |
return 'Administer %s %s series' % ( |
9081.2.5
by Curtis Hovey
Updated the product review page to UI 3.0. |
1214 |
self.context.product.displayname, self.context.name) |
1215 |
||
1216 |
@property
|
|
1217 |
def page_title(self): |
|
1218 |
"""The page title."""
|
|
1219 |
return self.label |
|
1220 |
||
1221 |
@property
|
|
1222 |
def cancel_url(self): |
|
1223 |
"""See `LaunchpadFormView`."""
|
|
1224 |
return canonical_url(self.context) |
|
1225 |
||
7182.6.3
by Guilherme Salgado
Convert ProductSeriesReviewView into a LFV |
1226 |
@action(_('Change'), name='change') |
1227 |
def change_action(self, action, data): |
|
8566.2.4
by Curtis Hovey
Fixed indentation to quiet lint. Added missing docstrings. |
1228 |
"""Update the series."""
|
7182.6.3
by Guilherme Salgado
Convert ProductSeriesReviewView into a LFV |
1229 |
self.updateContextFromData(data) |
3203.1.17
by Steve Alexander
Various improvements and cleanups from code review. |
1230 |
self.request.response.addInfoNotification( |
1231 |
_('This Series has been changed')) |
|
7182.6.3
by Guilherme Salgado
Convert ProductSeriesReviewView into a LFV |
1232 |
self.next_url = canonical_url(self.context) |
3203.1.3
by Mark Shuttleworth
Substantial cleanup of spec listings and spec targeting |
1233 |
|
1234 |
||
11594.3.3
by Curtis Hovey
Removed duplicate an unused code. |
1235 |
class ProductSeriesRdfView(BaseRdfView): |
2005
by Canonical.com Patch Queue Manager
[r=spiv] HatcheryRDFPublishing |
1236 |
"""A view that sets its mime-type to application/rdf+xml"""
|
2276
by Canonical.com Patch Queue Manager
r=jamesh Fix Bug 1603: RDF fails when a name has unicode chars |
1237 |
|
1238 |
template = ViewPageTemplateFile( |
|
1239 |
'../templates/productseries-rdf.pt') |
|
1240 |
||
11594.3.3
by Curtis Hovey
Removed duplicate an unused code. |
1241 |
@property
|
1242 |
def filename(self): |
|
1243 |
return '%s-%s' % (self.context.product.name, self.context.name) |
|
2005
by Canonical.com Patch Queue Manager
[r=spiv] HatcheryRDFPublishing |
1244 |
|
1245 |
||
4092.3.1
by Bjorn Tillenius
redirect a series' +filebug to it's product's one. |
1246 |
class ProductSeriesFileBugRedirect(LaunchpadView): |
1247 |
"""Redirect to the product's +filebug page."""
|
|
1248 |
||
1249 |
def initialize(self): |
|
8566.2.4
by Curtis Hovey
Fixed indentation to quiet lint. Added missing docstrings. |
1250 |
"""See `LaunchpadFormView`."""
|
4092.3.1
by Bjorn Tillenius
redirect a series' +filebug to it's product's one. |
1251 |
filebug_url = "%s/+filebug" % canonical_url(self.context.product) |
1252 |
self.request.response.redirect(filebug_url) |