12293.1.11
by Curtis Hovey
Updated copyright. |
1 |
# Copyright 2009-2011 Canonical Ltd. This software is licensed under the
|
8687.15.15
by Karl Fogel
Add the copyright header block to files under lib/lp/bugs/. |
2 |
# GNU Affero General Public License version 3 (see the file LICENSE).
|
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
3 |
|
4 |
__metaclass__ = type |
|
5 |
||
13453.5.1
by Steve Kowalik
First shot at getting *anything* to use the DSP vocab. |
6 |
__all__ = [ |
7 |
'BugAlsoAffectsProductMetaView', |
|
8 |
'BugAlsoAffectsDistroMetaView', |
|
9 |
'BugAlsoAffectsProductWithProductCreationView'
|
|
10 |
]
|
|
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
11 |
|
12 |
import cgi |
|
4681.1.28
by Guilherme Salgado
Move some common things to AlsoAffectsStep add some docstrings and remove some dead code. |
13 |
from textwrap import dedent |
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
14 |
|
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
15 |
from lazr.enum import ( |
16 |
EnumeratedType, |
|
17 |
Item, |
|
18 |
)
|
|
19 |
from lazr.lifecycle.event import ObjectCreatedEvent |
|
20 |
from z3c.ptcompat import ViewPageTemplateFile |
|
7915.1.2
by Barry Warsaw
pick lint |
21 |
from zope.app.form.browser import DropdownWidget |
13506.4.2
by William Grant
Replace valid_upstreamtask with validate_target everywhere. |
22 |
from zope.app.form.interfaces import MissingInputError |
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
23 |
from zope.component import getUtility |
24 |
from zope.event import notify |
|
5127.4.1
by Guilherme Salgado
Allos users to Register a product while adding an upstream task |
25 |
from zope.formlib import form |
26 |
from zope.schema import Choice |
|
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
27 |
from zope.schema.vocabulary import ( |
28 |
SimpleTerm, |
|
29 |
SimpleVocabulary, |
|
30 |
)
|
|
7876.3.6
by Francis J. Lacoste
Used ISQLObject from lazr.lifecycle |
31 |
|
14600.1.12
by Curtis Hovey
Move i18n to lp. |
32 |
from lp import _ |
11929.9.1
by Tim Penhey
Move launchpadform into lp.app.browser. |
33 |
from lp.app.browser.launchpadform import ( |
34 |
action, |
|
35 |
custom_widget, |
|
36 |
LaunchpadFormView, |
|
37 |
)
|
|
14550.1.1
by Steve Kowalik
Run format-imports over lib/lp and lib/canonical/launchpad |
38 |
from lp.app.browser.multistep import ( |
39 |
MultiStepView, |
|
40 |
StepView, |
|
41 |
)
|
|
11411.7.1
by j.c.sackett
Fixed majority of official_malone calls in code-space. Still need to fix templates. |
42 |
from lp.app.enums import ServiceUsage |
13130.1.12
by Curtis Hovey
Sorted imports. |
43 |
from lp.app.interfaces.launchpad import ILaunchpadCelebrities |
12442.2.9
by j.c.sackett
Ran import reformatter per review. |
44 |
from lp.app.validators.email import email_validator |
12293.1.10
by Curtis Hovey
Formatted imports. |
45 |
from lp.app.widgets.itemswidgets import LaunchpadRadioWidget |
46 |
from lp.app.widgets.popup import SearchForUpstreamPopupWidget |
|
47 |
from lp.app.widgets.textwidgets import StrippedTextWidget |
|
12164.3.5
by Gavin Panella
Move lib/canonical/widgets/bugtask.py to lib/lp/bugs/browser/widgets/bugtask.py and adjust all imports, fix lint, etc. |
48 |
from lp.bugs.browser.widgets.bugtask import ( |
49 |
BugTaskAlsoAffectsSourcePackageNameWidget, |
|
50 |
)
|
|
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
51 |
from lp.bugs.interfaces.bug import IBug |
52 |
from lp.bugs.interfaces.bugtask import ( |
|
53 |
BugTaskImportance, |
|
54 |
BugTaskStatus, |
|
55 |
IAddBugTaskForm, |
|
56 |
IAddBugTaskWithProductCreationForm, |
|
13506.4.2
by William Grant
Replace valid_upstreamtask with validate_target everywhere. |
57 |
IllegalTarget, |
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
58 |
valid_remote_bug_url, |
59 |
)
|
|
60 |
from lp.bugs.interfaces.bugtracker import ( |
|
61 |
BugTrackerType, |
|
62 |
IBugTrackerSet, |
|
63 |
)
|
|
64 |
from lp.bugs.interfaces.bugwatch import ( |
|
65 |
IBugWatchSet, |
|
66 |
NoBugTrackerFound, |
|
67 |
UnrecognizedBugTrackerURL, |
|
68 |
)
|
|
13506.4.7
by William Grant
Turn validate_new_distrotask into validate_new_target and move it into lp.bugs. |
69 |
from lp.bugs.model.bugtask import ( |
70 |
validate_new_target, |
|
71 |
validate_target, |
|
72 |
)
|
|
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
73 |
from lp.registry.interfaces.distributionsourcepackage import ( |
74 |
IDistributionSourcePackage, |
|
75 |
)
|
|
76 |
from lp.registry.interfaces.packaging import ( |
|
77 |
IPackagingUtil, |
|
78 |
PackagingType, |
|
79 |
)
|
|
80 |
from lp.registry.interfaces.product import ( |
|
81 |
IProductSet, |
|
82 |
License, |
|
83 |
)
|
|
13453.5.1
by Steve Kowalik
First shot at getting *anything* to use the DSP vocab. |
84 |
from lp.services.features import getFeatureFlag |
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
85 |
from lp.services.fields import StrippedTextLine |
11382.6.34
by Gavin Panella
Reformat imports in all files touched so far. |
86 |
from lp.services.propertycache import cachedproperty |
14612.2.1
by William Grant
format-imports on lib/. So many imports. |
87 |
from lp.services.webapp import canonical_url |
88 |
from lp.services.webapp.interfaces import ILaunchBag |
|
89 |
from lp.services.webapp.menu import structured |
|
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
90 |
|
91 |
||
7915.1.1
by Barry Warsaw
Refactoring multistep pages for re-use. |
92 |
class BugAlsoAffectsProductMetaView(MultiStepView): |
9322.10.7
by Guilherme Salgado
A couple more fixes/hacks |
93 |
page_title = 'Record as affecting another project' |
94 |
||
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
95 |
@property
|
7915.5.1
by Barry Warsaw
Responding to Aaron's review: |
96 |
def first_step(self): |
4681.1.27
by Guilherme Salgado
Drop AlsoAffects prefix from bugalsoaffects.py views |
97 |
return ChooseProductStep |
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
98 |
|
7915.1.1
by Barry Warsaw
Refactoring multistep pages for re-use. |
99 |
|
100 |
class BugAlsoAffectsDistroMetaView(MultiStepView): |
|
9322.10.7
by Guilherme Salgado
A couple more fixes/hacks |
101 |
page_title = 'Record as affecting another distribution/package' |
102 |
||
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
103 |
@property
|
7915.5.1
by Barry Warsaw
Responding to Aaron's review: |
104 |
def first_step(self): |
4681.1.27
by Guilherme Salgado
Drop AlsoAffects prefix from bugalsoaffects.py views |
105 |
return DistroBugTaskCreationStep |
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
106 |
|
107 |
||
7915.1.1
by Barry Warsaw
Refactoring multistep pages for re-use. |
108 |
class AlsoAffectsStep(StepView): |
4681.1.28
by Guilherme Salgado
Move some common things to AlsoAffectsStep add some docstrings and remove some dead code. |
109 |
__launchpad_facetname__ = 'bugs' |
110 |
schema = IAddBugTaskForm |
|
7162.7.4
by Gavin Panella
Add the cancel link. |
111 |
|
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
112 |
|
11110.4.14
by Curtis Hovey
Removed lint, Extract common code for DRY code. |
113 |
class LinkPackgingMixin: |
114 |
||
115 |
@property
|
|
116 |
def can_link_package(self): |
|
117 |
bugtask = self.context |
|
118 |
is_package_bugtask = IDistributionSourcePackage.providedBy( |
|
119 |
bugtask.target) |
|
120 |
return is_package_bugtask and bugtask.target.upstream_product is None |
|
121 |
||
122 |
||
123 |
class ChooseProductStep(LinkPackgingMixin, AlsoAffectsStep): |
|
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
124 |
"""View for choosing a product that is affected by a given bug."""
|
125 |
||
126 |
template = ViewPageTemplateFile( |
|
127 |
'../templates/bugtask-choose-affected-product.pt') |
|
128 |
||
8879.5.2
by Edwin Grubbs
Updated SearchForUpstreamPopupWidget. |
129 |
custom_widget('product', SearchForUpstreamPopupWidget) |
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
130 |
label = u"Record as affecting another project" |
131 |
step_name = "choose_product" |
|
132 |
||
11110.4.12
by Curtis Hovey
Do not include the add_packaging field when the source package is already |
133 |
@property
|
134 |
def _field_names(self): |
|
135 |
"""The fields needed to choose an existing project."""
|
|
136 |
names = ['product'] |
|
11110.4.13
by Curtis Hovey
Do not access widgets/add_packaging if packaging links cannot be created. |
137 |
if self.can_link_package: |
11110.4.12
by Curtis Hovey
Do not include the add_packaging field when the source package is already |
138 |
names.append('add_packaging') |
139 |
return names |
|
140 |
||
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
141 |
def initialize(self): |
4681.1.27
by Guilherme Salgado
Drop AlsoAffects prefix from bugalsoaffects.py views |
142 |
super(ChooseProductStep, self).initialize() |
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
143 |
if (self.widgets['product'].hasInput() or |
4681.1.28
by Guilherme Salgado
Move some common things to AlsoAffectsStep add some docstrings and remove some dead code. |
144 |
not IDistributionSourcePackage.providedBy(self.context.target)): |
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
145 |
return
|
146 |
||
147 |
self.maybeAddNotificationOrTeleport() |
|
148 |
||
149 |
def maybeAddNotificationOrTeleport(self): |
|
150 |
"""If we can't infer the upstream and the target distribution has a
|
|
151 |
currentseries we add a notification message telling the user the
|
|
152 |
package could be linked to an upstream to avoid this extra step.
|
|
153 |
||
154 |
On the other hand, if the upstream can be infered and there's no task
|
|
155 |
for it yet, we teleport the user straight to the next step.
|
|
156 |
"""
|
|
157 |
bugtask = self.context |
|
7672.1.2
by Graham Binns
Added a test for DSP.upstream_product. |
158 |
upstream = bugtask.target.upstream_product |
4681.1.28
by Guilherme Salgado
Move some common things to AlsoAffectsStep add some docstrings and remove some dead code. |
159 |
if upstream is not None: |
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
160 |
try: |
13506.4.2
by William Grant
Replace valid_upstreamtask with validate_target everywhere. |
161 |
validate_target(bugtask.bug, upstream) |
162 |
except IllegalTarget: |
|
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
163 |
# There is already a task for the upstream.
|
164 |
pass
|
|
165 |
else: |
|
166 |
# We can infer the upstream and there's no bugtask for it,
|
|
167 |
# so we can go straight to the page asking for the remote
|
|
168 |
# bug URL.
|
|
5127.4.1
by Guilherme Salgado
Allos users to Register a product while adding an upstream task |
169 |
self.request.form['field.product'] = upstream.name |
11110.4.8
by Curtis Hovey
Create a packaging link when the user checks add_packaging. |
170 |
self.request.form['field.add_packaging'] = 'off' |
7915.1.1
by Barry Warsaw
Refactoring multistep pages for re-use. |
171 |
self.next_step = ProductBugTaskCreationStep |
4681.1.28
by Guilherme Salgado
Move some common things to AlsoAffectsStep add some docstrings and remove some dead code. |
172 |
return
|
173 |
||
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
174 |
def validateStep(self, data): |
175 |
if data.get('product'): |
|
176 |
try: |
|
13506.4.2
by William Grant
Replace valid_upstreamtask with validate_target everywhere. |
177 |
validate_target(self.context.bug, data.get('product')) |
178 |
except IllegalTarget as e: |
|
179 |
self.setFieldError('product', e[0]) |
|
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
180 |
return
|
181 |
||
182 |
entered_product = self.request.form.get(self.widgets['product'].name) |
|
183 |
if not entered_product: |
|
184 |
return
|
|
185 |
||
186 |
# The user has entered a product name but we couldn't find it.
|
|
5127.4.5
by Guilherme Salgado
Some cleanups |
187 |
# Tell the user to search for it using the popup widget as it'll allow
|
188 |
# the user to register a new product if the one he is looking for is
|
|
189 |
# not yet registered.
|
|
8879.5.8
by Edwin Grubbs
Made the bug-also-affects error message handle js and non-js browsers. |
190 |
widget_link_id = self.widgets['product'].show_widget_id |
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
191 |
self.setFieldError( |
192 |
'product', |
|
8879.5.8
by Edwin Grubbs
Made the bug-also-affects error message handle js and non-js browsers. |
193 |
structured(""" |
11110.4.8
by Curtis Hovey
Create a packaging link when the user checks add_packaging. |
194 |
There is no project in Launchpad named "%s". Please |
8879.5.8
by Edwin Grubbs
Made the bug-also-affects error message handle js and non-js browsers. |
195 |
<a href="/projects"
|
11666.5.38
by Deryck Hodge
Convert all YUI instances to use LPS object. Also, make sure |
196 |
onclick="LPS.use('event').Event.simulate(
|
8879.5.8
by Edwin Grubbs
Made the bug-also-affects error message handle js and non-js browsers. |
197 |
document.getElementById('%s'), 'click'); |
198 |
return false;"
|
|
199 |
>search for it</a> as it may be
|
|
200 |
registered with a different name.""", |
|
201 |
entered_product, widget_link_id)) |
|
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
202 |
|
5127.4.1
by Guilherme Salgado
Allos users to Register a product while adding an upstream task |
203 |
def main_action(self, data): |
7915.1.6
by Barry Warsaw
Respond to reviewer comments. |
204 |
"""Perform the 'Continue' action."""
|
205 |
# Inject the selected product into the form and set the next_step to
|
|
206 |
# be used by our multistep controller.
|
|
5127.4.1
by Guilherme Salgado
Allos users to Register a product while adding an upstream task |
207 |
self.request.form['field.product'] = data['product'].name |
11110.4.12
by Curtis Hovey
Do not include the add_packaging field when the source package is already |
208 |
if data.get('add_packaging', False): |
11110.4.8
by Curtis Hovey
Create a packaging link when the user checks add_packaging. |
209 |
self.request.form['field.add_packaging'] = 'on' |
210 |
else: |
|
211 |
self.request.form['field.add_packaging'] = 'off' |
|
7915.1.1
by Barry Warsaw
Refactoring multistep pages for re-use. |
212 |
self.next_step = ProductBugTaskCreationStep |
4681.1.27
by Guilherme Salgado
Drop AlsoAffects prefix from bugalsoaffects.py views |
213 |
|
214 |
||
215 |
class BugTaskCreationStep(AlsoAffectsStep): |
|
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
216 |
"""The bug task creation step of the AlsoAffects workflow.
|
217 |
||
218 |
In this view the user specifies the URL for the remote bug and we create
|
|
219 |
the new bugtask/bugwatch.
|
|
5906.1.1
by Gavin Panella
Initial forwarding-to-email-address UI changes. |
220 |
|
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
221 |
If the bugtracker in the given URL is not registered in Launchpad, we
|
222 |
delegate its creation to another view. This other view should then
|
|
223 |
delegate the bug task creation to this one once the bugtracker is
|
|
224 |
registered.
|
|
225 |
"""
|
|
226 |
||
5127.4.1
by Guilherme Salgado
Allos users to Register a product while adding an upstream task |
227 |
custom_widget('bug_url', StrippedTextWidget, displayWidth=62) |
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
228 |
|
7267.3.1
by Bjorn Tillenius
Focus the URL field on +choose-affected-product so that pasting via the keyboard works. |
229 |
initial_focus_widget = 'bug_url' |
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
230 |
step_name = 'specify_remote_bug_url' |
231 |
target_field_names = () |
|
232 |
||
5127.4.1
by Guilherme Salgado
Allos users to Register a product while adding an upstream task |
233 |
# This is necessary so that other views which dispatch work to this one
|
234 |
# have access to the newly created task.
|
|
235 |
task_added = None |
|
236 |
||
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
237 |
def __init__(self, context, request): |
4681.1.27
by Guilherme Salgado
Drop AlsoAffects prefix from bugalsoaffects.py views |
238 |
super(BugTaskCreationStep, self).__init__(context, request) |
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
239 |
self.notifications = [] |
4681.1.30
by Guilherme Salgado
Add a field_names property to AlsoAffectsStep which always include the 'visited_steps' field so that subclasses don't have to include it in their field_names |
240 |
self._field_names = ['bug_url'] + list(self.target_field_names) |
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
241 |
|
242 |
def setUpWidgets(self): |
|
4681.1.27
by Guilherme Salgado
Drop AlsoAffects prefix from bugalsoaffects.py views |
243 |
super(BugTaskCreationStep, self).setUpWidgets() |
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
244 |
self.target_widgets = [ |
245 |
self.widgets[field_name] |
|
246 |
for field_name in self.field_names |
|
247 |
if field_name in self.target_field_names] |
|
248 |
self.bugwatch_widgets = [self.widgets['bug_url']] |
|
249 |
||
250 |
def getTarget(self, data=None): |
|
251 |
"""Return the fix target.
|
|
252 |
||
253 |
If data is given extract the target from there. Otherwise extract it
|
|
254 |
from this view's widgets.
|
|
255 |
"""
|
|
256 |
raise NotImplementedError() |
|
257 |
||
5127.4.1
by Guilherme Salgado
Allos users to Register a product while adding an upstream task |
258 |
def main_action(self, data): |
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
259 |
"""Create the new bug task.
|
260 |
||
261 |
If a remote bug URL is given and there's no bug watch registered with
|
|
262 |
that URL we create a bug watch and link it to the newly created bug
|
|
263 |
task.
|
|
264 |
"""
|
|
5127.4.1
by Guilherme Salgado
Allos users to Register a product while adding an upstream task |
265 |
bug_url = data.get('bug_url', '') |
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
266 |
target = self.getTarget(data) |
267 |
||
268 |
extracted_bug = None |
|
269 |
extracted_bugtracker = None |
|
270 |
if bug_url: |
|
271 |
try: |
|
272 |
extracted_bugtracker, extracted_bug = getUtility( |
|
273 |
IBugWatchSet).extractBugTrackerAndBug(bug_url) |
|
274 |
except NoBugTrackerFound: |
|
275 |
# Delegate to another view which will ask the user if (s)he
|
|
276 |
# wants to create the bugtracker now.
|
|
11110.4.10
by Curtis Hovey
Fixed checks for product bugtask creation scenario...they were entering into |
277 |
if 'product' in self.target_field_names: |
7915.1.1
by Barry Warsaw
Refactoring multistep pages for re-use. |
278 |
self.next_step = UpstreamBugTrackerCreationStep |
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
279 |
else: |
280 |
assert 'distribution' in self.target_field_names |
|
7915.1.1
by Barry Warsaw
Refactoring multistep pages for re-use. |
281 |
self.next_step = DistroBugTrackerCreationStep |
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
282 |
return
|
283 |
||
7996.1.7
by Bjorn Tillenius
Don't use create task in browser/bugalsoaffects.py |
284 |
if data.get('product') is not None: |
7996.1.12
by Bjorn Tillenius
Fix test failures. |
285 |
task_target = data['product'] |
7996.1.8
by Bjorn Tillenius
Fix typo. |
286 |
else: |
7996.1.12
by Bjorn Tillenius
Fix test failures. |
287 |
task_target = data['distribution'] |
7996.1.7
by Bjorn Tillenius
Don't use create task in browser/bugalsoaffects.py |
288 |
if data.get('sourcepackagename') is not None: |
14400.2.23
by Curtis Hovey
Use an alternate schema instead of setUpFields to switch from spn to dsp. |
289 |
spn_or_dsp = data['sourcepackagename'] |
14400.2.27
by Curtis Hovey
Fix unbound variable error reported by tests. |
290 |
if IDistributionSourcePackage.providedBy(spn_or_dsp): |
291 |
task_target = spn_or_dsp |
|
292 |
else: |
|
293 |
task_target = task_target.getSourcePackage(spn_or_dsp) |
|
7996.1.7
by Bjorn Tillenius
Don't use create task in browser/bugalsoaffects.py |
294 |
self.task_added = self.context.bug.addTask( |
7996.1.12
by Bjorn Tillenius
Fix test failures. |
295 |
getUtility(ILaunchBag).user, task_target) |
5127.4.1
by Guilherme Salgado
Allos users to Register a product while adding an upstream task |
296 |
task_added = self.task_added |
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
297 |
|
5906.1.1
by Gavin Panella
Initial forwarding-to-email-address UI changes. |
298 |
if extracted_bug is not None: |
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
299 |
assert extracted_bugtracker is not None, ( |
300 |
"validate() should have ensured that bugtracker is not None.") |
|
4982.1.3
by Bjorn Tillenius
clean up implementation. |
301 |
# Display a notification, if another bug is already linked
|
302 |
# to the same external bug.
|
|
303 |
other_bugs_already_watching = [ |
|
304 |
bug for bug in extracted_bugtracker.getBugsWatching( |
|
305 |
extracted_bug) |
|
306 |
if bug != self.context.bug] |
|
307 |
# Simply add one notification per bug to simplify the
|
|
308 |
# implementation; most of the time it will be only one bug.
|
|
309 |
for other_bug in other_bugs_already_watching: |
|
5594.1.11
by Maris Fogels
Beautified the addNotification(structured(...)) construct. |
310 |
self.request.response.addInfoNotification( |
311 |
structured( |
|
4982.1.5
by Bjorn Tillenius
change the notification message. |
312 |
'<a href="%(bug_url)s">Bug #%(bug_id)s</a> also links' |
313 |
' to the added bug watch'
|
|
314 |
' (%(bugtracker_name)s #%(remote_bug)s).', |
|
5594.1.23
by Maris Fogels
Fixed an issue with the structured() constructor, which only takes string, receiving an integer. |
315 |
bug_url=canonical_url(other_bug), |
316 |
bug_id=str(other_bug.id), |
|
4982.1.5
by Bjorn Tillenius
change the notification message. |
317 |
bugtracker_name=extracted_bugtracker.name, |
5594.1.9
by Maris Fogels
Fixed all of the calls to addInfoNotification() that contain HTML so that they use the structured() class. Also fixed a number of broken uses of the _() translation function. |
318 |
remote_bug=extracted_bug)) |
4982.1.3
by Bjorn Tillenius
clean up implementation. |
319 |
|
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
320 |
# Make sure that we don't add duplicate bug watches.
|
4681.1.28
by Guilherme Salgado
Move some common things to AlsoAffectsStep add some docstrings and remove some dead code. |
321 |
bug_watch = task_added.bug.getBugWatch( |
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
322 |
extracted_bugtracker, extracted_bug) |
323 |
if bug_watch is None: |
|
4681.1.28
by Guilherme Salgado
Move some common things to AlsoAffectsStep add some docstrings and remove some dead code. |
324 |
bug_watch = task_added.bug.addWatch( |
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
325 |
extracted_bugtracker, extracted_bug, self.user) |
11411.7.1
by j.c.sackett
Fixed majority of official_malone calls in code-space. Still need to fix templates. |
326 |
if target.bug_tracking_usage != ServiceUsage.LAUNCHPAD: |
4681.1.28
by Guilherme Salgado
Move some common things to AlsoAffectsStep add some docstrings and remove some dead code. |
327 |
task_added.bugwatch = bug_watch |
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
328 |
|
11411.7.28
by j.c.sackett
Lint fixes. |
329 |
if (target.bug_tracking_usage != ServiceUsage.LAUNCHPAD |
11411.7.1
by j.c.sackett
Fixed majority of official_malone calls in code-space. Still need to fix templates. |
330 |
and task_added.bugwatch is not None |
5906.1.1
by Gavin Panella
Initial forwarding-to-email-address UI changes. |
331 |
and (task_added.bugwatch.bugtracker.bugtrackertype != |
332 |
BugTrackerType.EMAILADDRESS)): |
|
333 |
# A remote bug task gets its status from a bug watch, so
|
|
334 |
# we want its status/importance to be UNKNOWN when
|
|
335 |
# created. Status updates cannot be fetched from Email
|
|
336 |
# Address bug trackers, and we expect the status and
|
|
337 |
# importance to be updated manually, so we do not reset
|
|
338 |
# the status and importance here.
|
|
6602.5.15
by Tom Berger
when resetting a bugtask to use a bugwatch, use the bug importer |
339 |
bug_importer = getUtility(ILaunchpadCelebrities).bug_importer |
340 |
task_added.transitionToStatus( |
|
341 |
BugTaskStatus.UNKNOWN, bug_importer) |
|
6602.5.5
by Tom Berger
fix some lint errors |
342 |
task_added.transitionToImportance( |
6602.5.15
by Tom Berger
when resetting a bugtask to use a bugwatch, use the bug importer |
343 |
BugTaskImportance.UNKNOWN, bug_importer) |
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
344 |
|
7876.3.6
by Francis J. Lacoste
Used ISQLObject from lazr.lifecycle |
345 |
notify(ObjectCreatedEvent(task_added)) |
4681.1.28
by Guilherme Salgado
Move some common things to AlsoAffectsStep add some docstrings and remove some dead code. |
346 |
self.next_url = canonical_url(task_added) |
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
347 |
|
348 |
||
14400.2.23
by Curtis Hovey
Use an alternate schema instead of setUpFields to switch from spn to dsp. |
349 |
class IAddDistroBugTaskForm(IAddBugTaskForm): |
350 |
||
351 |
sourcepackagename = Choice( |
|
352 |
title=_("Source Package Name"), required=False, |
|
353 |
description=_("The source package in which the bug occurs. " |
|
354 |
"Leave blank if you are not sure."), |
|
355 |
vocabulary='DistributionSourcePackage') |
|
356 |
||
357 |
||
4681.1.27
by Guilherme Salgado
Drop AlsoAffects prefix from bugalsoaffects.py views |
358 |
class DistroBugTaskCreationStep(BugTaskCreationStep): |
359 |
"""Specialized BugTaskCreationStep for reporting a bug in a distribution.
|
|
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
360 |
"""
|
361 |
||
14400.2.23
by Curtis Hovey
Use an alternate schema instead of setUpFields to switch from spn to dsp. |
362 |
@property
|
363 |
def schema(self): |
|
364 |
if bool(getFeatureFlag('disclosure.dsp_picker.enabled')): |
|
365 |
return IAddDistroBugTaskForm |
|
366 |
else: |
|
367 |
return IAddBugTaskForm |
|
368 |
||
6325.1.1
by Bjorn Tillenius
prevent non-published packages from being targeted on +distrotask. |
369 |
custom_widget( |
370 |
'sourcepackagename', BugTaskAlsoAffectsSourcePackageNameWidget) |
|
371 |
||
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
372 |
template = ViewPageTemplateFile('../templates/bugtask-requestfix.pt') |
373 |
||
374 |
label = "Also affects distribution/package" |
|
375 |
target_field_names = ('distribution', 'sourcepackagename') |
|
376 |
||
5398.1.1
by Graham Binns
The default value of the distro field for the +distrotask form is now Ubuntu> |
377 |
@property
|
378 |
def initial_values(self): |
|
5398.1.2
by Graham Binns
Added a docstring to DistroBugTaskCreationStep.initial_values. |
379 |
"""Return the initial values for the view's fields."""
|
5398.1.1
by Graham Binns
The default value of the distro field for the +distrotask form is now Ubuntu> |
380 |
return {'distribution': getUtility(ILaunchpadCelebrities).ubuntu} |
381 |
||
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
382 |
def getTarget(self, data=None): |
383 |
if data is not None: |
|
384 |
return data.get('distribution') |
|
385 |
else: |
|
386 |
return self.widgets['distribution'].getInputValue() |
|
387 |
||
6105.8.2
by Gavin Panella
Remove the confirmation step. |
388 |
def main_action(self, data): |
389 |
"""Create the new bug task, confirming if necessary."""
|
|
390 |
bug_url = data.get('bug_url', '') |
|
391 |
target = self.getTarget(data) |
|
392 |
||
393 |
if (not bug_url and |
|
394 |
not self.request.get('ignore_missing_remote_bug') and |
|
11411.7.20
by j.c.sackett
Fixed yet more bad references missed in the initial pass. |
395 |
target.bug_tracking_usage != ServiceUsage.LAUNCHPAD): |
6105.8.2
by Gavin Panella
Remove the confirmation step. |
396 |
# We have no URL for the remote bug and the target does not use
|
397 |
# Launchpad for bug tracking, so we warn the user this is not
|
|
398 |
# optimal and ask for his confirmation.
|
|
399 |
||
400 |
# Add a hidden field to fool LaunchpadFormView into thinking we
|
|
401 |
# submitted the action it expected when in fact we're submiting
|
|
402 |
# something else to indicate the user has confirmed.
|
|
403 |
confirm_button = ( |
|
404 |
'<input type="hidden" name="%s" value="1" />' |
|
405 |
'<input style="font-size: smaller" type="submit"'
|
|
406 |
' value="Add Anyway" name="ignore_missing_remote_bug" />'
|
|
407 |
% self.continue_action.__name__) |
|
408 |
self.notifications.append(_(dedent(""" |
|
409 |
%s doesn't use Launchpad as its bug tracker. Without a bug |
|
410 |
URL to watch, the %s status will not update automatically. |
|
411 |
%s""" % (cgi.escape(target.displayname), |
|
412 |
cgi.escape(target.displayname), |
|
413 |
confirm_button)))) |
|
414 |
return None |
|
415 |
# Create the task.
|
|
416 |
return super(DistroBugTaskCreationStep, self).main_action(data) |
|
417 |
||
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
418 |
def validateStep(self, data): |
4681.1.28
by Guilherme Salgado
Move some common things to AlsoAffectsStep add some docstrings and remove some dead code. |
419 |
"""Check that
|
420 |
||
421 |
1. there's no bug_url if the target uses malone;
|
|
422 |
2. there is a package with the given name;
|
|
423 |
3. it's possible to create a new task for the given package/distro.
|
|
424 |
"""
|
|
425 |
target = self.getTarget(data) |
|
426 |
bug_url = data.get('bug_url') |
|
11411.7.1
by j.c.sackett
Fixed majority of official_malone calls in code-space. Still need to fix templates. |
427 |
if bug_url and target.bug_tracking_usage == ServiceUsage.LAUNCHPAD: |
4681.1.28
by Guilherme Salgado
Move some common things to AlsoAffectsStep add some docstrings and remove some dead code. |
428 |
self.addError( |
429 |
"Bug watches can not be added for %s, as it uses Launchpad" |
|
430 |
" as its official bug tracker. Alternatives are to add a"
|
|
431 |
" watch for another project, or a comment containing a"
|
|
5653.2.1
by Maris Fogels
Changed occurrances of addError() so that the conform to the new API. Fixed a number of broken msgids. |
432 |
" URL to the related bug report." % target.displayname) |
4681.1.28
by Guilherme Salgado
Move some common things to AlsoAffectsStep add some docstrings and remove some dead code. |
433 |
|
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
434 |
distribution = data.get('distribution') |
435 |
sourcepackagename = data.get('sourcepackagename') |
|
436 |
entered_package = self.request.form.get( |
|
437 |
self.widgets['sourcepackagename'].name) |
|
438 |
if sourcepackagename is None and entered_package: |
|
439 |
# The entered package doesn't exist.
|
|
13169.1.2
by Steve Kowalik
Use structured properly, and slightly re-flow. |
440 |
if distribution.has_published_binaries: |
441 |
binary_tracking = '' |
|
442 |
else: |
|
13169.1.1
by Steve Kowalik
* Stop instructing users to file a bug if they can't find a package, and tell |
443 |
binary_tracking = structured( |
444 |
' Launchpad does not track binary package names '
|
|
13169.1.2
by Steve Kowalik
Use structured properly, and slightly re-flow. |
445 |
'in %s.', distribution.displayname) |
13169.1.1
by Steve Kowalik
* Stop instructing users to file a bug if they can't find a package, and tell |
446 |
error = structured( |
447 |
'There is no package in %s named "%s".%s', |
|
448 |
distribution.displayname, entered_package, |
|
449 |
binary_tracking) |
|
450 |
self.setFieldError('sourcepackagename', error) |
|
14400.2.23
by Curtis Hovey
Use an alternate schema instead of setUpFields to switch from spn to dsp. |
451 |
elif not IDistributionSourcePackage.providedBy(sourcepackagename): |
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
452 |
try: |
13506.4.7
by William Grant
Turn validate_new_distrotask into validate_new_target and move it into lp.bugs. |
453 |
target = distribution |
454 |
if sourcepackagename: |
|
455 |
target = target.getSourcePackage(sourcepackagename) |
|
456 |
validate_new_target(self.context.bug, target) |
|
13506.4.8
by William Grant
validate_new_target now raises IllegalTarget instead of LaunchpadValidationError. |
457 |
except IllegalTarget as e: |
14174.2.9
by Ian Booth
Add doc test |
458 |
if sourcepackagename: |
459 |
self.setFieldError('sourcepackagename', e[0]) |
|
460 |
else: |
|
461 |
self.setFieldError('distribution', e[0]) |
|
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
462 |
|
4681.1.27
by Guilherme Salgado
Drop AlsoAffects prefix from bugalsoaffects.py views |
463 |
super(DistroBugTaskCreationStep, self).validateStep(data) |
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
464 |
|
465 |
def render(self): |
|
466 |
for bugtask in IBug(self.context).bugtasks: |
|
467 |
if (IDistributionSourcePackage.providedBy(bugtask.target) and |
|
468 |
(not self.widgets['sourcepackagename'].hasInput())): |
|
469 |
self.widgets['sourcepackagename'].setRenderedValue( |
|
470 |
bugtask.sourcepackagename) |
|
471 |
break
|
|
4681.1.27
by Guilherme Salgado
Drop AlsoAffects prefix from bugalsoaffects.py views |
472 |
return super(DistroBugTaskCreationStep, self).render() |
473 |
||
474 |
||
5906.1.4
by Gavin Panella
Move form definitions to the browser package. |
475 |
class LinkUpstreamHowOptions(EnumeratedType): |
476 |
LINK_UPSTREAM = Item( |
|
477 |
"""I have the URL for the upstream bug:
|
|
478 |
||
479 |
Enter the URL in the upstream bug tracker. If it's in a
|
|
480 |
supported upstream bug tracker, Launchpad can download the
|
|
481 |
status and display it in the bug report.
|
|
482 |
""") |
|
483 |
||
484 |
# XXX: GavinPanella 2008-02-13 bug=201793: This will be uncommented in
|
|
485 |
# a later branch.
|
|
486 |
#
|
|
487 |
# EMAIL_UPSTREAM = Item(
|
|
488 |
# """I would like to email an upstream bug contact.
|
|
489 |
#
|
|
490 |
# Launchpad will prepare an example email containing all the
|
|
491 |
# pertinent details. You can send it from Launchpad or from your
|
|
492 |
# own mail software. If you send it from Launchpad, it'll save
|
|
493 |
# the message id and - in the future - will use it to try and
|
|
494 |
# follow the resulting conversation, provided it happens on a
|
|
495 |
# public mailing list.
|
|
496 |
# """)
|
|
497 |
||
498 |
EMAIL_UPSTREAM_DONE = Item( |
|
499 |
"""I have already emailed an upstream bug contact:
|
|
500 |
||
501 |
Launchpad will record that.
|
|
502 |
""") |
|
503 |
||
504 |
# XXX: GavinPanella 2008-02-13 bug=201793: This additional description
|
|
505 |
# for EMAIL_UPSTREAM_DONE should be appended when EMAIL_UPSTREAM is
|
|
506 |
# made available.
|
|
507 |
#
|
|
508 |
# "Next time, try using Launchpad to send the message upstream
|
|
509 |
# too. That way it may be able to follow the conversation that
|
|
510 |
# results from your bug report. This is especially true for public
|
|
511 |
# mailing lists."
|
|
512 |
||
513 |
UNLINKED_UPSTREAM = Item( |
|
514 |
"""I just want to register that it is upstream right now; \
|
|
515 |
I don't have any way to link it.
|
|
516 |
||
517 |
Launchpad will record that.
|
|
518 |
""") |
|
519 |
||
520 |
||
521 |
class IAddBugTaskWithUpstreamLinkForm(IAddBugTaskForm): |
|
522 |
"""Form for adding an upstream bugtask with linking options.
|
|
523 |
||
524 |
The choices in link_upstream_how correspond to zero or one of the
|
|
525 |
text fields. For example, if link_upstream_how is LINK_UPSTREAM
|
|
526 |
then bug_url is the relevant field, and the other text fields,
|
|
527 |
like upstream_email_address_done, can be ignored.
|
|
528 |
||
529 |
That also explains why none of the text fields are required. That
|
|
530 |
check is left to the view, in part so that better error messages
|
|
531 |
can be provided.
|
|
532 |
"""
|
|
7403.4.5
by Edwin Grubbs
Fixed different paths through ProductBugTaskCreationStep views. |
533 |
# link_upstream_how must have required=False, since
|
534 |
# ProductBugTaskCreationStep doesn't always display a form input for it.
|
|
5906.1.4
by Gavin Panella
Move form definitions to the browser package. |
535 |
link_upstream_how = Choice( |
7403.4.5
by Edwin Grubbs
Fixed different paths through ProductBugTaskCreationStep views. |
536 |
title=_('How'), required=False, |
5906.1.4
by Gavin Panella
Move form definitions to the browser package. |
537 |
vocabulary=LinkUpstreamHowOptions, |
538 |
default=LinkUpstreamHowOptions.LINK_UPSTREAM, |
|
539 |
description=_("How to link to an upstream bug.")) |
|
540 |
bug_url = StrippedTextLine( |
|
541 |
title=_('Bug URL'), required=False, constraint=valid_remote_bug_url, |
|
542 |
description=_("The URL of this bug in the remote bug tracker.")) |
|
543 |
upstream_email_address_done = StrippedTextLine( |
|
544 |
title=_('Email Address'), required=False, constraint=email_validator, |
|
545 |
description=_("The upstream email address that this bug has been " |
|
546 |
"forwarded to.")) |
|
547 |
||
548 |
||
4681.1.27
by Guilherme Salgado
Drop AlsoAffects prefix from bugalsoaffects.py views |
549 |
class ProductBugTaskCreationStep(BugTaskCreationStep): |
550 |
"""Specialized BugTaskCreationStep for reporting a bug in an upstream."""
|
|
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
551 |
|
552 |
template = ViewPageTemplateFile( |
|
553 |
'../templates/bugtask-requestfix-upstream.pt') |
|
554 |
||
555 |
label = "Confirm project" |
|
11110.4.8
by Curtis Hovey
Create a packaging link when the user checks add_packaging. |
556 |
target_field_names = ('product', 'add_packaging') |
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
557 |
main_action_label = u'Add to Bug Report' |
5906.1.1
by Gavin Panella
Initial forwarding-to-email-address UI changes. |
558 |
schema = IAddBugTaskWithUpstreamLinkForm |
559 |
||
7403.4.5
by Edwin Grubbs
Fixed different paths through ProductBugTaskCreationStep views. |
560 |
custom_widget('link_upstream_how', LaunchpadRadioWidget, |
561 |
_displayItemForMissingValue=False) |
|
5906.1.1
by Gavin Panella
Initial forwarding-to-email-address UI changes. |
562 |
custom_widget('bug_url', StrippedTextWidget, displayWidth=42) |
563 |
custom_widget('upstream_email_address_done', |
|
564 |
StrippedTextWidget, displayWidth=42) |
|
565 |
||
566 |
@property
|
|
567 |
def field_names(self): |
|
568 |
return ['link_upstream_how', 'upstream_email_address_done'] + ( |
|
569 |
super(ProductBugTaskCreationStep, self).field_names) |
|
570 |
||
571 |
def validate_widgets(self, data, names=None): |
|
5906.1.3
by Gavin Panella
Changes as requested by bac in review. |
572 |
# The form is essentially just a radio group, with zero or one
|
573 |
# related text widgets per choice. The text widget should be
|
|
574 |
# validated when its corresponding radio button has been
|
|
575 |
# selected, otherwise we should do no validation because we
|
|
576 |
# don't want to issue errors for widgets that we and the user
|
|
577 |
# are not interested in.
|
|
578 |
||
579 |
# Collect all the widget names.
|
|
5906.1.1
by Gavin Panella
Initial forwarding-to-email-address UI changes. |
580 |
if names is None: |
581 |
names = set() |
|
582 |
else: |
|
583 |
names = set(names) |
|
584 |
names.update(widget.context.__name__ for widget in self.widgets) |
|
585 |
||
5906.1.3
by Gavin Panella
Changes as requested by bac in review. |
586 |
# A mapping from radio buttons to their related text widgets.
|
5906.1.1
by Gavin Panella
Initial forwarding-to-email-address UI changes. |
587 |
link_upstream_options = { |
588 |
LinkUpstreamHowOptions.LINK_UPSTREAM: |
|
589 |
'bug_url', |
|
590 |
LinkUpstreamHowOptions.EMAIL_UPSTREAM_DONE: |
|
11110.4.8
by Curtis Hovey
Create a packaging link when the user checks add_packaging. |
591 |
'upstream_email_address_done'} |
5906.1.1
by Gavin Panella
Initial forwarding-to-email-address UI changes. |
592 |
|
5906.1.3
by Gavin Panella
Changes as requested by bac in review. |
593 |
# Examine the radio group if it has valid input.
|
5906.1.1
by Gavin Panella
Initial forwarding-to-email-address UI changes. |
594 |
link_upstream_how = self.widgets['link_upstream_how'] |
595 |
if link_upstream_how.hasValidInput(): |
|
596 |
link_upstream_how = link_upstream_how.getInputValue() |
|
597 |
||
5906.1.3
by Gavin Panella
Changes as requested by bac in review. |
598 |
# Don't request validation for text widgets that are not
|
599 |
# related to the current radio selection.
|
|
600 |
for option, name in link_upstream_options.iteritems(): |
|
5906.1.1
by Gavin Panella
Initial forwarding-to-email-address UI changes. |
601 |
if link_upstream_how != option: |
602 |
names.discard(name) |
|
603 |
elif self.widgets[name].hasValidInput(): |
|
5906.1.3
by Gavin Panella
Changes as requested by bac in review. |
604 |
# Check that input has been provided because the
|
605 |
# fields in the schema are set to required=False
|
|
606 |
# to make the radio+text-widget mechanism work.
|
|
5906.1.1
by Gavin Panella
Initial forwarding-to-email-address UI changes. |
607 |
if not self.widgets[name].getInputValue(): |
608 |
self.setFieldError( |
|
609 |
name, 'Required input is missing.') |
|
610 |
||
611 |
else: |
|
612 |
# Don't validate these widgets when we don't yet know how
|
|
613 |
# we intend to link upstream.
|
|
614 |
names.difference_update(link_upstream_options.itervalues()) |
|
615 |
||
616 |
return super(ProductBugTaskCreationStep, |
|
617 |
self).validate_widgets(data, names) |
|
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
618 |
|
619 |
def getTarget(self, data=None): |
|
620 |
if data is not None: |
|
621 |
return data.get('product') |
|
622 |
else: |
|
623 |
return self.widgets['product'].getInputValue() |
|
624 |
||
5906.1.1
by Gavin Panella
Initial forwarding-to-email-address UI changes. |
625 |
@cachedproperty
|
626 |
def link_upstream_how_items(self): |
|
627 |
"""Manually create and pick apart a radio widget.
|
|
628 |
||
5906.1.3
by Gavin Panella
Changes as requested by bac in review. |
629 |
On its own, `LaunchpadRadioWidget` does not render quite how
|
630 |
we need it, because we're interspersing related text
|
|
631 |
widgets. We need to dig down a bit and place the individually
|
|
632 |
rendered radio buttons into our custom layout.
|
|
5906.1.1
by Gavin Panella
Initial forwarding-to-email-address UI changes. |
633 |
"""
|
634 |
widget = self.widgets['link_upstream_how'] |
|
635 |
try: |
|
636 |
current_value = widget.getInputValue() |
|
637 |
except MissingInputError: |
|
638 |
current_value = LinkUpstreamHowOptions.LINK_UPSTREAM |
|
639 |
items = widget.renderItems(current_value) |
|
7403.4.1
by Edwin Grubbs
Removed LaunchpadRadioWidget.renderItemsWithValues() and updated affected views. |
640 |
|
641 |
# The items list is returned in the same order as the
|
|
7403.4.5
by Edwin Grubbs
Fixed different paths through ProductBugTaskCreationStep views. |
642 |
# widget.vocabulary enumerator. It is important that
|
643 |
# link_upstream_how has _displayItemForMissingValue=False
|
|
7403.4.1
by Edwin Grubbs
Removed LaunchpadRadioWidget.renderItemsWithValues() and updated affected views. |
644 |
# so that renderItems() doesn't return an extra radio button which
|
7403.4.5
by Edwin Grubbs
Fixed different paths through ProductBugTaskCreationStep views. |
645 |
# prevents it from matching widget.vocabulary's ordering.
|
646 |
return dict((entry.token, items[i]) |
|
647 |
for i, entry in enumerate(widget.vocabulary)) |
|
5906.1.1
by Gavin Panella
Initial forwarding-to-email-address UI changes. |
648 |
|
649 |
def main_action(self, data): |
|
650 |
link_upstream_how = data.get('link_upstream_how') |
|
651 |
||
5906.1.3
by Gavin Panella
Changes as requested by bac in review. |
652 |
if link_upstream_how == LinkUpstreamHowOptions.UNLINKED_UPSTREAM: |
5906.1.1
by Gavin Panella
Initial forwarding-to-email-address UI changes. |
653 |
# Erase bug_url because we don't want to create a bug
|
654 |
# watch against a specific URL.
|
|
655 |
if 'bug_url' in data: |
|
656 |
del data['bug_url'] |
|
657 |
elif link_upstream_how == LinkUpstreamHowOptions.EMAIL_UPSTREAM_DONE: |
|
658 |
# Ensure there's a bug tracker for this email address.
|
|
659 |
bug_url = 'mailto:' + data['upstream_email_address_done'] |
|
10734.1.8
by Edwin Grubbs
Fixed lint errors. |
660 |
getUtility(IBugTrackerSet).ensureBugTracker( |
5906.1.1
by Gavin Panella
Initial forwarding-to-email-address UI changes. |
661 |
bug_url, self.user, BugTrackerType.EMAILADDRESS) |
662 |
data['bug_url'] = bug_url |
|
11110.4.10
by Curtis Hovey
Fixed checks for product bugtask creation scenario...they were entering into |
663 |
if data.get('add_packaging', False): |
11110.4.8
by Curtis Hovey
Create a packaging link when the user checks add_packaging. |
664 |
# Create a packaging link so that Launchpad will suggest the
|
665 |
# upstream project to the user.
|
|
14617.1.1
by Steve Kowalik
Only add packaging if distribution.currentseries is not None. |
666 |
series = self.context.target.distribution.currentseries |
667 |
if series: |
|
668 |
getUtility(IPackagingUtil).createPackaging( |
|
669 |
productseries=data['product'].development_focus, |
|
670 |
sourcepackagename=self.context.target.sourcepackagename, |
|
671 |
distroseries=series, packaging=PackagingType.PRIME, |
|
672 |
owner=self.user) |
|
5906.1.1
by Gavin Panella
Initial forwarding-to-email-address UI changes. |
673 |
return super(ProductBugTaskCreationStep, self).main_action(data) |
674 |
||
7849.6.1
by Graham Binns
Moved upstream_bugtracker_links from Product DB class into view. |
675 |
@property
|
676 |
def upstream_bugtracker_links(self): |
|
7849.6.2
by Graham Binns
Completed the move of upstream_bugtracker_links from Product to ProductBugTaskCreationStep. |
677 |
"""Return the upstream bugtracker links for the current target.
|
7849.6.1
by Graham Binns
Moved upstream_bugtracker_links from Product DB class into view. |
678 |
|
7849.6.5
by Graham Binns
Removed unneccessary check for the bug target being a product. We know that it's a product because it's in the +choose-affected-PRODUCT view, which makes it kinda obvious. |
679 |
:return: The bug tracker links for the target, as returned by
|
680 |
BugTracker.getBugFilingAndSearchLinks(). If product.bugtracker
|
|
681 |
is None, return None.
|
|
7849.6.1
by Graham Binns
Moved upstream_bugtracker_links from Product DB class into view. |
682 |
"""
|
7849.6.2
by Graham Binns
Completed the move of upstream_bugtracker_links from Product to ProductBugTaskCreationStep. |
683 |
target = self.getTarget() |
684 |
||
685 |
if not target.bugtracker: |
|
7849.6.1
by Graham Binns
Moved upstream_bugtracker_links from Product DB class into view. |
686 |
return None |
13405.7.1
by Bryce Harrington
Refactor else clause away. |
687 |
|
688 |
bug = self.context.bug |
|
689 |
title = bug.title |
|
690 |
description = u"Originally reported at:\n %s\n\n%s" % ( |
|
691 |
canonical_url(bug), bug.description) |
|
692 |
return target.bugtracker.getBugFilingAndSearchLinks( |
|
693 |
target.remote_product, title, description) |
|
7849.6.1
by Graham Binns
Moved upstream_bugtracker_links from Product DB class into view. |
694 |
|
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
695 |
|
4681.1.27
by Guilherme Salgado
Drop AlsoAffects prefix from bugalsoaffects.py views |
696 |
class BugTrackerCreationStep(AlsoAffectsStep): |
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
697 |
"""View for creating a bugtracker from the given URL.
|
698 |
||
699 |
This view will ask the user if he really wants to register the new bug
|
|
700 |
tracker, perform the registration and then delegate to one of
|
|
4681.1.27
by Guilherme Salgado
Drop AlsoAffects prefix from bugalsoaffects.py views |
701 |
BugTaskCreationStep's subclasses.
|
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
702 |
"""
|
703 |
||
5127.4.1
by Guilherme Salgado
Allos users to Register a product while adding an upstream task |
704 |
custom_widget('bug_url', StrippedTextWidget, displayWidth=62) |
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
705 |
step_name = "bugtracker_creation" |
706 |
main_action_label = u'Register Bug Tracker and Add to Bug Report' |
|
7915.1.1
by Barry Warsaw
Refactoring multistep pages for re-use. |
707 |
_next_step = None |
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
708 |
|
5127.4.1
by Guilherme Salgado
Allos users to Register a product while adding an upstream task |
709 |
def main_action(self, data): |
7915.1.1
by Barry Warsaw
Refactoring multistep pages for re-use. |
710 |
assert self._next_step is not None, ( |
711 |
"_next_step must be specified in subclasses.") |
|
4681.1.28
by Guilherme Salgado
Move some common things to AlsoAffectsStep add some docstrings and remove some dead code. |
712 |
bug_url = data.get('bug_url').strip() |
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
713 |
try: |
714 |
getUtility(IBugWatchSet).extractBugTrackerAndBug(bug_url) |
|
715 |
except NoBugTrackerFound, error: |
|
716 |
getUtility(IBugTrackerSet).ensureBugTracker( |
|
717 |
error.base_url, self.user, error.bugtracker_type) |
|
7915.1.1
by Barry Warsaw
Refactoring multistep pages for re-use. |
718 |
self.next_step = self._next_step |
4681.1.27
by Guilherme Salgado
Drop AlsoAffects prefix from bugalsoaffects.py views |
719 |
|
720 |
||
721 |
class DistroBugTrackerCreationStep(BugTrackerCreationStep): |
|
722 |
||
7915.1.1
by Barry Warsaw
Refactoring multistep pages for re-use. |
723 |
_next_step = DistroBugTaskCreationStep |
4681.1.30
by Guilherme Salgado
Add a field_names property to AlsoAffectsStep which always include the 'visited_steps' field so that subclasses don't have to include it in their field_names |
724 |
_field_names = ['distribution', 'sourcepackagename', 'bug_url'] |
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
725 |
custom_widget('distribution', DropdownWidget, visible=False) |
726 |
custom_widget('sourcepackagename', DropdownWidget, visible=False) |
|
727 |
label = "Also affects distribution/package" |
|
728 |
template = ViewPageTemplateFile( |
|
729 |
'../templates/bugtask-confirm-bugtracker-creation.pt') |
|
730 |
||
4681.1.27
by Guilherme Salgado
Drop AlsoAffects prefix from bugalsoaffects.py views |
731 |
|
732 |
class UpstreamBugTrackerCreationStep(BugTrackerCreationStep): |
|
733 |
||
6105.8.2
by Gavin Panella
Remove the confirmation step. |
734 |
schema = IAddBugTaskWithUpstreamLinkForm |
7915.1.1
by Barry Warsaw
Refactoring multistep pages for re-use. |
735 |
_next_step = ProductBugTaskCreationStep |
6105.8.3
by Gavin Panella
Don't need the email address to be copied because we won't end up here if an email address has been entered. |
736 |
_field_names = ['product', 'bug_url', 'link_upstream_how'] |
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
737 |
custom_widget('product', DropdownWidget, visible=False) |
6105.8.2
by Gavin Panella
Remove the confirmation step. |
738 |
custom_widget('link_upstream_how', |
739 |
LaunchpadRadioWidget, visible=False) |
|
4681.1.26
by Guilherme Salgado
Split all views related to the bug-also-affects workflow into a separate file (bugalsoaffects.py) |
740 |
label = "Confirm project" |
741 |
template = ViewPageTemplateFile( |
|
742 |
'../templates/bugtask-confirm-bugtracker-creation.pt') |
|
743 |
||
5127.4.1
by Guilherme Salgado
Allos users to Register a product while adding an upstream task |
744 |
|
11110.4.14
by Curtis Hovey
Removed lint, Extract common code for DRY code. |
745 |
class BugAlsoAffectsProductWithProductCreationView(LinkPackgingMixin, |
746 |
LaunchpadFormView): |
|
5127.4.1
by Guilherme Salgado
Allos users to Register a product while adding an upstream task |
747 |
"""Register a product and indicate this bug affects it.
|
748 |
||
749 |
If there's no bugtracker with the given URL registered in Launchpad, then
|
|
750 |
a new bugtracker is created as well.
|
|
751 |
"""
|
|
752 |
||
753 |
label = "Register project affected by this bug" |
|
754 |
schema = IAddBugTaskWithProductCreationForm |
|
755 |
custom_widget('bug_url', StrippedTextWidget, displayWidth=62) |
|
756 |
custom_widget('existing_product', LaunchpadRadioWidget) |
|
757 |
existing_products = None |
|
758 |
MAX_PRODUCTS_TO_DISPLAY = 10 |
|
8781.2.3
by Brad Crittenden
Change +affects-new-product to assign the new product to the regsitry admins and set the license to DONT_KNOW |
759 |
licenses = [License.DONT_KNOW] |
5127.4.1
by Guilherme Salgado
Allos users to Register a product while adding an upstream task |
760 |
|
11110.4.12
by Curtis Hovey
Do not include the add_packaging field when the source package is already |
761 |
@property
|
762 |
def field_names(self): |
|
763 |
"""The fields needed to choose an existing project."""
|
|
764 |
names = ['bug_url', 'displayname', 'name', 'summary'] |
|
11110.4.13
by Curtis Hovey
Do not access widgets/add_packaging if packaging links cannot be created. |
765 |
if self.can_link_package: |
11110.4.12
by Curtis Hovey
Do not include the add_packaging field when the source package is already |
766 |
names.append('add_packaging') |
767 |
return names |
|
768 |
||
5127.4.9
by Guilherme Salgado
Bunch of changes suggested by Francis |
769 |
def _loadProductsUsingBugTracker(self): |
5127.4.5
by Guilherme Salgado
Some cleanups |
770 |
"""Find products using the bugtracker wich runs on the given URL.
|
771 |
||
772 |
These products are stored in self.existing_products.
|
|
773 |
||
774 |
If there are too many products using that bugtracker then we'll store
|
|
775 |
only the first ones that somehow match the name given.
|
|
5127.4.1
by Guilherme Salgado
Allos users to Register a product while adding an upstream task |
776 |
"""
|
777 |
bug_url = self.request.form.get('field.bug_url') |
|
778 |
if not bug_url: |
|
5127.4.5
by Guilherme Salgado
Some cleanups |
779 |
return
|
5127.4.1
by Guilherme Salgado
Allos users to Register a product while adding an upstream task |
780 |
|
781 |
bugwatch_set = getUtility(IBugWatchSet) |
|
782 |
try: |
|
783 |
bugtracker, bug = bugwatch_set.extractBugTrackerAndBug(bug_url) |
|
5127.4.9
by Guilherme Salgado
Bunch of changes suggested by Francis |
784 |
except (NoBugTrackerFound, UnrecognizedBugTrackerURL): |
5127.4.1
by Guilherme Salgado
Allos users to Register a product while adding an upstream task |
785 |
# There's no bugtracker registered with the given URL, so we
|
786 |
# don't need to worry about finding products using it.
|
|
5127.4.9
by Guilherme Salgado
Bunch of changes suggested by Francis |
787 |
return
|
5127.4.5
by Guilherme Salgado
Some cleanups |
788 |
|
5127.4.1
by Guilherme Salgado
Allos users to Register a product while adding an upstream task |
789 |
count = bugtracker.products.count() |
790 |
if count > 0 and count <= self.MAX_PRODUCTS_TO_DISPLAY: |
|
5127.4.9
by Guilherme Salgado
Bunch of changes suggested by Francis |
791 |
self.existing_products = list(bugtracker.products) |
5127.4.1
by Guilherme Salgado
Allos users to Register a product while adding an upstream task |
792 |
elif count > self.MAX_PRODUCTS_TO_DISPLAY: |
5127.4.9
by Guilherme Salgado
Bunch of changes suggested by Francis |
793 |
# Use a local import as we don't want removeSecurityProxy used
|
794 |
# anywhere else.
|
|
795 |
from zope.security.proxy import removeSecurityProxy |
|
12641.1.3
by Robert Collins
Add back in a SQLObject version of ProductSet.search because migration cascades, oh my yes it does. |
796 |
name_matches = removeSecurityProxy( |
797 |
getUtility(IProductSet).search_sqlobject( |
|
798 |
self.request.form.get('field.name'))) |
|
799 |
products = bugtracker.products.intersect(name_matches) |
|
5127.4.9
by Guilherme Salgado
Bunch of changes suggested by Francis |
800 |
self.existing_products = list( |
801 |
products[:self.MAX_PRODUCTS_TO_DISPLAY]) |
|
5127.4.1
by Guilherme Salgado
Allos users to Register a product while adding an upstream task |
802 |
else: |
803 |
# The bugtracker is registered in Launchpad but there are no
|
|
804 |
# products using it at the moment.
|
|
805 |
pass
|
|
806 |
||
807 |
def setUpFields(self): |
|
5127.4.5
by Guilherme Salgado
Some cleanups |
808 |
"""Setup an extra field with all products using the given bugtracker.
|
809 |
||
810 |
This extra field is setup only if there is one or more products using
|
|
811 |
that bugtracker.
|
|
812 |
"""
|
|
5292.1.2
by Guilherme Salgado
Fix a couple things spotted by Tom Berger |
813 |
super( |
814 |
BugAlsoAffectsProductWithProductCreationView, self).setUpFields() |
|
5127.4.9
by Guilherme Salgado
Bunch of changes suggested by Francis |
815 |
self._loadProductsUsingBugTracker() |
816 |
if self.existing_products is None or len(self.existing_products) < 1: |
|
5127.4.1
by Guilherme Salgado
Allos users to Register a product while adding an upstream task |
817 |
# No need to setup any extra fields.
|
818 |
return
|
|
819 |
||
820 |
terms = [] |
|
5127.4.5
by Guilherme Salgado
Some cleanups |
821 |
for product in self.existing_products: |
5127.4.1
by Guilherme Salgado
Allos users to Register a product while adding an upstream task |
822 |
terms.append(SimpleTerm(product, product.name, product.title)) |
823 |
existing_product = form.FormField( |
|
824 |
Choice(__name__='existing_product', |
|
825 |
title=_("Existing project"), required=True, |
|
7076.5.2
by Gary Poster
initial cut at changing files to take into account new behavior. four tests do not pass. |
826 |
vocabulary=SimpleVocabulary(terms))) |
5127.4.1
by Guilherme Salgado
Allos users to Register a product while adding an upstream task |
827 |
self.form_fields += form.Fields(existing_product) |
828 |
if 'field.existing_product' not in self.request.form: |
|
829 |
# This is the first time the form is being submitted, so the
|
|
830 |
# request doesn't contain a value for the existing_product
|
|
831 |
# widget and thus we'll end up rendering an error message around
|
|
832 |
# said widget unless we sneak a value for it in our request.
|
|
833 |
self.request.form['field.existing_product'] = terms[0].token |
|
834 |
||
835 |
def validate_existing_product(self, action, data): |
|
5127.4.5
by Guilherme Salgado
Some cleanups |
836 |
"""Check if the chosen project is not already affected by this bug."""
|
5127.4.4
by Guilherme Salgado
Fix the custom validation for the use-existing-project action |
837 |
self._validate(action, data) |
5127.4.1
by Guilherme Salgado
Allos users to Register a product while adding an upstream task |
838 |
project = data.get('existing_product') |
839 |
try: |
|
13506.4.2
by William Grant
Replace valid_upstreamtask with validate_target everywhere. |
840 |
validate_target(self.context.bug, project) |
841 |
except IllegalTarget as e: |
|
842 |
self.setFieldError('existing_product', e[0]) |
|
5127.4.1
by Guilherme Salgado
Allos users to Register a product while adding an upstream task |
843 |
|
844 |
@action('Use Existing Project', name='use_existing_product', |
|
845 |
validator=validate_existing_product) |
|
846 |
def use_existing_product_action(self, action, data): |
|
5127.4.5
by Guilherme Salgado
Some cleanups |
847 |
"""Record the chosen project as being affected by this bug.
|
848 |
||
849 |
Also creates a bugwatch for the given remote bug.
|
|
850 |
"""
|
|
5127.4.1
by Guilherme Salgado
Allos users to Register a product while adding an upstream task |
851 |
data['product'] = data['existing_product'] |
852 |
self._createBugTaskAndWatch(data) |
|
853 |
||
854 |
@action('Continue', name='continue') |
|
855 |
def continue_action(self, action, data): |
|
856 |
"""Create a new product and a bugtask for this bug on that product.
|
|
857 |
||
858 |
If the URL of the remote bug given is of a bugtracker used by any
|
|
859 |
other products registered in Launchpad, then we show these products to
|
|
860 |
the user and ask if he doesn't want to create the task in one of them.
|
|
861 |
"""
|
|
862 |
if self.existing_products and not self.request.form.get('create_new'): |
|
863 |
# Present the projects using that bugtracker to the user as
|
|
864 |
# possible options to report the bug on. If there are too many
|
|
865 |
# projects using that bugtracker then show only the ones that
|
|
866 |
# match the text entered as the project's name
|
|
867 |
return
|
|
8781.2.3
by Brad Crittenden
Change +affects-new-product to assign the new product to the regsitry admins and set the license to DONT_KNOW |
868 |
# Products created through this view have DONT_KNOW licensing.
|
5127.4.1
by Guilherme Salgado
Allos users to Register a product while adding an upstream task |
869 |
product = getUtility(IProductSet).createProduct( |
8781.2.3
by Brad Crittenden
Change +affects-new-product to assign the new product to the regsitry admins and set the license to DONT_KNOW |
870 |
owner=self.user, |
871 |
name=data['name'], |
|
872 |
displayname=data['displayname'], title=data['displayname'], |
|
873 |
summary=data['summary'], licenses=self.licenses, |
|
11110.4.8
by Curtis Hovey
Create a packaging link when the user checks add_packaging. |
874 |
registrant=self.user) |
5127.4.1
by Guilherme Salgado
Allos users to Register a product while adding an upstream task |
875 |
data['product'] = product |
5292.1.1
by Guilherme Salgado
Fix the bug |
876 |
self._createBugTaskAndWatch(data, set_bugtracker=True) |
8781.2.3
by Brad Crittenden
Change +affects-new-product to assign the new product to the regsitry admins and set the license to DONT_KNOW |
877 |
# Now that the product is configured set the owner to be the registry
|
878 |
# experts team.
|
|
879 |
product.owner = getUtility(ILaunchpadCelebrities).registry_experts |
|
5127.4.1
by Guilherme Salgado
Allos users to Register a product while adding an upstream task |
880 |
|
5292.1.1
by Guilherme Salgado
Fix the bug |
881 |
def _createBugTaskAndWatch(self, data, set_bugtracker=False): |
5127.4.1
by Guilherme Salgado
Allos users to Register a product while adding an upstream task |
882 |
"""Create a bugtask and bugwatch on the chosen product.
|
883 |
||
5292.1.1
by Guilherme Salgado
Fix the bug |
884 |
If set_bugtracker is True then the bugtracker of the newly created
|
885 |
watch is set as the product's bugtracker.
|
|
886 |
||
5127.4.1
by Guilherme Salgado
Allos users to Register a product while adding an upstream task |
887 |
This is done by manually calling the main_action() method of
|
888 |
UpstreamBugTrackerCreationStep and ProductBugTaskCreationStep.
|
|
889 |
||
890 |
This method also sets self.next_url to the URL of the newly added
|
|
891 |
bugtask.
|
|
892 |
"""
|
|
6916.1.1
by Curtis Hovey
Fixed comment formats to fidn missing persons, dates, and some bugs. |
893 |
# XXX: Guilherme Salgado, 2007-11-20: This relies on the fact that
|
894 |
# these actions work using only the form data and the context.
|
|
895 |
# (They don't require any side-effects done during initialize().)
|
|
896 |
# They should probably be extracted outside of the view to
|
|
897 |
# make that explicit.
|
|
5127.4.1
by Guilherme Salgado
Allos users to Register a product while adding an upstream task |
898 |
view = UpstreamBugTrackerCreationStep(self.context, self.request) |
899 |
view.main_action(data) |
|
900 |
||
901 |
view = ProductBugTaskCreationStep(self.context, self.request) |
|
902 |
view.main_action(data) |
|
903 |
||
5292.1.1
by Guilherme Salgado
Fix the bug |
904 |
if set_bugtracker: |
905 |
data['product'].bugtracker = view.task_added.bugwatch.bugtracker |
|
5127.4.1
by Guilherme Salgado
Allos users to Register a product while adding an upstream task |
906 |
self.next_url = canonical_url(view.task_added) |