120
122
from zope.traversing.browser import absoluteURL
121
123
from zope.traversing.interfaces import IPathAdapter
125
from canonical.config import config
126
from canonical.launchpad import (
130
from canonical.launchpad.browser.feeds import (
131
BugTargetLatestBugsFeedLink,
134
from canonical.launchpad.interfaces.launchpad import IHasExternalBugTracker
135
from canonical.launchpad.mailnotification import get_unified_diff
136
from canonical.launchpad.searchbuilder import (
141
from canonical.launchpad.webapp import (
143
enabled_with_permission,
152
from canonical.launchpad.webapp.authorization import (
154
precache_permission_for_objects,
156
from canonical.launchpad.webapp.batching import TableBatchNavigator
157
from canonical.launchpad.webapp.breadcrumb import Breadcrumb
158
from canonical.launchpad.webapp.interfaces import ILaunchBag
159
from canonical.launchpad.webapp.menu import structured
160
from canonical.lazr.interfaces import IObjectPrivacy
124
161
from lp.answers.interfaces.questiontarget import IQuestionTarget
125
162
from lp.app.browser.launchpad import iter_view_registrations
126
163
from lp.app.browser.launchpadform import (
244
278
from lp.registry.interfaces.sourcepackage import ISourcePackage
245
279
from lp.registry.model.personroles import PersonRoles
246
280
from lp.registry.vocabularies import MilestoneVocabulary
247
from lp.services.config import config
248
281
from lp.services.features import getFeatureFlag
249
from lp.services.feeds.browser import (
250
BugTargetLatestBugsFeedLink,
253
282
from lp.services.fields import PersonChoice
254
from lp.services.helpers import shortlist
255
from lp.services.mail.notification import get_unified_diff
256
from lp.services.privacy.interfaces import IObjectPrivacy
257
283
from lp.services.propertycache import (
259
285
get_property_cache,
261
from lp.services.searchbuilder import (
266
287
from lp.services.utils import obfuscate_structure
267
from lp.services.webapp import (
269
enabled_with_permission,
278
from lp.services.webapp.authorization import (
280
precache_permission_for_objects,
282
from lp.services.webapp.batching import TableBatchNavigator
283
from lp.services.webapp.breadcrumb import Breadcrumb
284
from lp.services.webapp.interfaces import ILaunchBag
285
from lp.services.webapp.menu import structured
288
289
vocabulary_registry = getVocabularyRegistry()
558
559
# Security proxy this object on the way out.
559
560
return getUtility(IBugTaskSet).get(bugtask.id)
561
# If we've come this far, there's no task for the requested context.
562
# If we are attempting to navigate past the non-existent bugtask,
563
# we raise NotFound error. eg +delete or +edit etc.
564
# Otherwise we are simply navigating to a non-existent task and so we
565
# redirect to one that exists.
566
travseral_stack = self.request.getTraversalStack()
567
if len(travseral_stack) > 0:
562
# If we've come this far, there's no task for the requested
563
# context. Redirect to one that exists.
569
564
return self.redirectSubTree(canonical_url(bug.default_bugtask))
2502
2490
# All sort orders supported by BugTaskSet.search() and a title for
2505
('importance', 'Importance', 'desc'),
2506
('status', 'Status', 'asc'),
2507
('id', 'Number', 'desc'),
2508
('title', 'Title', 'asc'),
2509
('targetname', 'Package/Project/Series name', 'asc'),
2510
('milestone_name', 'Milestone', 'asc'),
2511
('date_last_updated', 'Date last updated', 'desc'),
2512
('assignee', 'Assignee', 'asc'),
2513
('reporter', 'Reporter', 'asc'),
2514
('datecreated', 'Age', 'desc'),
2515
('tag', 'Tags', 'asc'),
2516
('heat', 'Heat', 'desc'),
2517
('date_closed', 'Date closed', 'desc'),
2518
('dateassigned', 'Date when the bug task was assigned', 'desc'),
2519
('number_of_duplicates', 'Number of duplicates', 'desc'),
2520
('latest_patch_uploaded', 'Date latest patch uploaded', 'desc'),
2521
('message_count', 'Number of comments', 'desc'),
2522
('milestone', 'Milestone ID', 'desc'),
2523
('specification', 'Linked blueprint', 'asc'),
2524
('task', 'Bug task ID', 'desc'),
2525
('users_affected_count', 'Number of affected users', 'desc'),
2493
('importance', 'Importance'),
2494
('status', 'Status'),
2495
('id', 'Bug number'),
2496
('title', 'Bug title'),
2497
('targetname', 'Package/Project/Series name'),
2498
('milestone_name', 'Milestone'),
2499
('date_last_updated', 'Date bug last updated'),
2500
('assignee', 'Assignee'),
2501
('reporter', 'Reporter'),
2502
('datecreated', 'Bug age'),
2503
('tag', 'Bug Tags'),
2504
('heat', 'Bug heat'),
2505
('date_closed', 'Date bug closed'),
2506
('dateassigned', 'Date when the bug task was assigned'),
2507
('number_of_duplicates', 'Number of duplicates'),
2508
('latest_patch_uploaded', 'Date latest patch uploaded'),
2509
('message_count', 'Number of comments'),
2510
('milestone', 'Milestone ID'),
2511
('specification', 'Linked blueprint'),
2512
('task', 'Bug task ID'),
2513
('users_affected_count', 'Number of affected users'),
3021
3007
the search criteria taken from the request. Params in
3022
3008
`extra_params` take precedence over request params.
3024
if self._batch_navigator is None:
3025
unbatchedTasks = self.searchUnbatched(
3026
searchtext, context, extra_params)
3027
self._batch_navigator = self._getBatchNavigator(unbatchedTasks)
3028
return self._batch_navigator
3010
unbatchedTasks = self.searchUnbatched(
3011
searchtext, context, extra_params)
3012
return self._getBatchNavigator(unbatchedTasks)
3030
3014
def searchUnbatched(self, searchtext=None, context=None,
3031
3015
extra_params=None, prejoins=[]):