616
627
if extra_data.private:
617
628
params.private = extra_data.private
619
# Apply any extra options given by privileged users.
620
if BugTask.userHasBugSupervisorPrivilegesContext(context, self.user):
621
if 'assignee' in data:
622
params.assignee = data['assignee']
624
params.status = data['status']
625
if 'importance' in data:
626
params.importance = data['importance']
627
if 'milestone' in data:
628
params.milestone = data['milestone']
630
# Apply any extra options given by a bug supervisor.
631
if IHasBugSupervisor.providedBy(context):
632
if self.user.inTeam(context.bug_supervisor):
633
if 'assignee' in data:
634
params.assignee = data['assignee']
636
params.status = data['status']
637
if 'importance' in data:
638
params.importance = data['importance']
639
if 'milestone' in data:
640
params.milestone = data['milestone']
630
642
self.added_bug = bug = context.createBug(params)
1307
1311
self.color = 'MochiKit.Color.Color["%sColor"]()' % color
1314
class BugTargetBugsView(BugTaskSearchListingView, FeedsMixin):
1315
"""View for the Bugs front page."""
1317
# We have a custom searchtext widget here so that we can set the
1318
# width of the search box properly.
1319
custom_widget('searchtext', NewLineToSpacesWidget, displayWidth=36)
1321
# Only include <link> tags for bug feeds when using this view.
1324
BugTargetLatestBugsFeedLink,
1327
# XXX: Bjorn Tillenius 2007-02-13:
1328
# These colors should be changed. It's the same colors that are used
1329
# to color statuses in buglistings using CSS, but there should be one
1330
# unique color for each status in the pie chart
1332
BugTaskStatus.NEW: '#993300',
1333
BugTaskStatus.INCOMPLETE: 'red',
1334
BugTaskStatus.CONFIRMED: 'orange',
1335
BugTaskStatus.TRIAGED: 'black',
1336
BugTaskStatus.INPROGRESS: 'blue',
1337
BugTaskStatus.FIXCOMMITTED: 'green',
1338
BugTaskStatus.FIXRELEASED: 'magenta',
1339
BugTaskStatus.INVALID: 'yellow',
1340
BugTaskStatus.UNKNOWN: 'purple',
1343
override_title_breadcrumbs = True
1347
"""The display label for the view."""
1348
return 'Bugs in %s' % self.context.title
1350
def initialize(self):
1351
super(BugTargetBugsView, self).initialize()
1352
bug_statuses_to_show = list(UNRESOLVED_BUGTASK_STATUSES)
1353
if IDistroSeries.providedBy(self.context):
1354
bug_statuses_to_show.append(BugTaskStatus.FIXRELEASED)
1355
expose_structural_subscription_data_to_js(
1356
self.context, self.request, self.user)
1359
def can_have_external_bugtracker(self):
1360
return (IProduct.providedBy(self.context)
1361
or IProductSeries.providedBy(self.context))
1364
def bug_tracking_usage(self):
1365
"""Whether the context tracks bugs in launchpad.
1367
:returns: ServiceUsage enum value
1369
service_usage = IServiceUsage(self.context)
1370
return service_usage.bug_tracking_usage
1373
def bugtracker(self):
1374
"""Description of the context's bugtracker.
1376
:returns: str which may contain HTML.
1378
if self.bug_tracking_usage == ServiceUsage.LAUNCHPAD:
1380
elif self.external_bugtracker:
1381
return BugTrackerFormatterAPI(self.external_bugtracker).link(None)
1383
return 'None specified'
1386
def hot_bugs_info(self):
1387
"""Return a dict of the 10 hottest tasks and a has_more_bugs flag."""
1388
has_more_bugs = False
1389
params = BugTaskSearchParams(
1390
orderby=['-heat', 'task'], omit_dupes=True,
1391
user=self.user, status=any(*UNRESOLVED_BUGTASK_STATUSES))
1392
# Use 4x as many tasks as bugs that are needed to improve performance.
1393
bugtasks = self.context.searchTasks(params)[:40]
1396
for task in bugtasks:
1397
# Use hot_bugs list to ensure a bug is only listed once.
1398
if task.bug not in hot_bugs:
1399
if len(hot_bugtasks) < 10:
1400
hot_bugtasks.append(task)
1401
hot_bugs.append(task.bug)
1403
has_more_bugs = True
1405
return {'has_more_bugs': has_more_bugs, 'bugtasks': hot_bugtasks}
1310
1408
class BugTargetBugTagsView(LaunchpadView):
1311
1409
"""Helper methods for rendering the bug tags portlet."""
1315
1413
# Use path_only here to reduce the size of the rendered page.
1316
1414
return "+bugs?field.tag=%s" % urllib.quote(tag)
1416
def _calculateFactor(self, tag, count, max_count, official_tags):
1417
bonus = 1.5 if tag in official_tags else 1
1418
return (count / max_count) + bonus
1319
1421
def tags_cloud_data(self):
1320
1422
"""The data for rendering a tags cloud"""
1321
1423
official_tags = self.context.official_bug_tags
1322
1424
tags = self.context.getUsedBugTagsWithOpenCounts(
1323
1425
self.user, 10, official_tags)
1426
max_count = float(max([1] + tags.values()))
1431
factor=self._calculateFactor(
1432
tag, count, max_count, official_tags),
1329
1433
url=self._getSearchURL(tag),
1331
1435
for (tag, count) in tags.iteritems()],
1332
key=itemgetter('count'), reverse=True)
1436
key=itemgetter('tag'))
1335
1439
def show_manage_tags_link(self):