2
# Author: Brian Murray <brian@canonical.com>
3
# Copyright (C) 2011 Canonical, Ltd.
10
from cgi import escape
11
from lpltk import LaunchpadService
14
def html_report(team_name, tasks, target_date):
15
datafile = open('%s-recent-triaged-bug-tasks.html' % team_name, 'w')
16
supported_releases = ['Dapper', 'Hardy', 'Lucid', 'Maverick', 'Natty',
18
importances = {'Critical': 1, 'High': 2, 'Medium': 3, 'Low': 4,
19
'Wishlist': 5, 'Undecided': 6}
20
statuses = {"Won't Fix": 1, 'New': 2, 'Incomplete': 3, 'Confirmed': 4,
21
'Triaged': 5, 'In Progress': 6, 'Fix Committed': 7, 'Fix Released': 8}
22
templatefile = open('template.html', 'r')
25
for line in templatefile:
26
if line.strip() == "<!-- *** Title Space *** -->":
27
datafile.write("Recently Triaged bug tasks for the %s team\n" % team_name)
28
elif line.strip() == "<!-- *** Header Space *** -->":
29
datafile.write("Recently Triaged bug tasks for the %s team\n" % team_name)
30
elif line.strip() == "<!-- *** Paragraph Space *** -->":
31
datafile.write("Triaged bug tasks about packages to which %s is subscribed. Some rows will be a different color, this indicates they are tagged as a regression. All of the column headers are sortable give them a click!" % team_name)
32
elif line.strip() == "<!-- *** Table Header Space *** -->":
33
table_header = "<th>#</th>" # bug number in this column
34
table_header += "<th>Summary</th>"
35
table_header += "<th>In</th>"
36
table_header += "<th>Importance</th>"
37
table_header += "<th>Status</th>"
38
table_header += "<th>Release</th>"
39
table_header += "<th>Assignee</th>"
40
table_header += "<th>Date Triaged</th>"
41
table_header += "<th>Regression</th>"
43
datafile.write(table_header)
44
elif line.strip() == "<!-- *** Table Body Space *** -->":
46
if task.date_triaged is None:
48
date_triaged = task.date_triaged
49
if date_triaged.date() < target_date.date():
51
if [tag for tag in task.bug.tags if 'regression-' in tag]:
52
# change the class to highlight for any bug that has a regression- tag in it
53
table_row = '<tr class="highlight">\n'
56
table_row += '<td id="bug_number">%s</td>\n' % task.bug.id
57
table_row += "<td><a href='http://launchpad.net/bugs/%s'>%s</a></td>\n" % (task.bug.id, escape(task.bug.title.encode('utf-8')))
58
table_row += '<td id="target">%s</td>\n' % task.bug_target_display_name.encode('utf-8')
59
importance = task.importance.encode('utf-8')
60
table_row += '<td id="importance"><span class="sortkey">%s</span>%s</td>\n' % ( importances[importance], importance )
61
status = task.status.encode('utf-8')
62
table_row += '<td id="status"><span class="sortkey">%s</span>%s</td>\n' % ( statuses[status], status )
64
table_row += '<td id="release">'
65
affected_releases = []
66
for release in supported_releases:
67
rtasks = [task.bug_target_display_name for task in task.related_tasks]
69
affected_releases.append('%s%s' % (release[0], release[0]))
71
table_row += ', '.join(affected_releases)
74
table_row += '</td>\n'
76
if task.assignee is not None:
77
assignee = task.assignee.display_name
79
table_row += '<td id="assignee">%s</td>\n' % task.assignee.lpperson.display_name.encode('utf-8')
80
except UnicodeDecodeError:
81
table_row += '<td id="assignee">%s</td>\n' % task.assignee.name
83
table_row += '<td id="assignee"></td>\n'
84
#table_row += "<td></td>"
85
if date_triaged is not None:
87
table_row += '<td id="date_triaged">%s</td>\n' % date_triaged[:10].encode('utf-8')
89
table_row += '<td id="date_triaged">%s</td>\n' % date_triaged.strftime('%Y-%m-%d')
91
table_row += '<td id="date_triaged"></td>\n'
92
items = [tag for tag in task.bug.tags if 'regression-' in tag]
94
table_row += '<td id="regression">'
96
table_row += "%s " % item.encode('utf-8')
97
table_row += '</td>\n'
99
table_row += '<td id="regression"></td>\n'
102
datafile.write(table_row)
103
# only count rows that show up on the report not hokey ones
104
counts['total'] = counts.setdefault('total', 0) + 1
105
elif line.strip() == "<!-- *** Last Paragraph Space *** -->":
107
datafile.write("A total of %s bug tasks have been triaged since %s.<br><br>" % (counts['total'], target_date.date()))
109
datafile.write("The %s team has no recently triaged bug tasks.<br><br>" % team_name)
110
datafile.write('<br>')
111
datafile.write('Is there a problem with this report? File a bug about the <a href="https://bugs.launchpad.net/ubuntu-qa-tools/+filebug">ubuntu-qa-tools.</a><br>')
112
datafile.write('<br>')
113
now = datetime.datetime.now()
114
datafile.write('Report generated at: %s<br>' % now.strftime('%Y-%m-%d %H:%M'))
119
if __name__ == '__main__':
120
lp = LaunchpadService(config={})
122
ubuntu = lp.distributions['ubuntu']
123
parser = optparse.OptionParser()
125
parser.add_option("--days", help="Filter on bugs changed within \
127
parser.add_option("--team", help="Filter on bugs with a bug supervisor \
129
parser.add_option("--html", help="Output to html", action="store_true")
131
(opt, args) = parser.parse_args()
133
team = lp.launchpad.people[opt.team]
134
today = datetime.datetime.utcnow()
135
target_date = today - datetime.timedelta(int(opt.days))
137
tasks = ubuntu.search_tasks(bug_supervisor=team,
139
order_by='-date_last_updated')
142
html_report(opt.team, tasks, target_date)
146
if task.date_triaged is None:
148
date_triaged = task.date_triaged.date()
149
if date_triaged > target_date.date():
150
print 'LP: #%s %s triaged on %s' % \
151
(task.bug.id, task.bug.title, date_triaged)