1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
|
#!/usr/bin/env python
"""
A script to help triage Launchpad bugs.
"""
from optparse import OptionParser
import sys
from launchpadlib.launchpad import Launchpad, uris
def get_suggested_importance(result):
scale = {
(1, 6): u'Low',
(7, 11): u'High',
}
for index in scale:
if index[0] <= result <= index[1]:
return scale[index]
questions = {
1: {
'Can this bug be confirmed? [yes, no, neither]':
{'yes': 1, 'no': -1, 'neither': 0},
},
2: {
'Is this bug new? [yes, no]':
{'yes': 1, 'no': 0},
},
3: {
'Is the area in scope for the next 6 months? [yes, no, neither]':
{'yes': 1, 'no': -1, 'neither': 0},
},
4: {
'How likely is a quick/easy fix? [very, somewhat, unsure, not]':
{'very': 2, 'somewhat': 1, 'unsure': 0, 'not': -1},
},
5: {
'How many people does this affect? [everyone, many, some, none]':
{'everyone': 2, 'many': 1, 'some': 0, 'none': -1},
},
6: {
'Are their workarounds? [always, sometimes, never]':
{'always': -1, 'sometimes': 0, 'never': 1},
},
7: {
'Is this an OOPS/Timeout? [yes, no]':
{'yes': 1, 'no': 0},
},
8: {
'How prominent is the affected feature? [very, somewhat, not]':
{'very': 2, 'somewhat': 1, 'not': 0}
},
}
def rank_bug():
total = 0
keys = questions.keys()
keys.sort()
for question_num in keys:
question = questions[question_num]
answer = raw_input('%s ' % question.keys()[0])
val = question.values()[0][answer]
print 'Adding %d to count' % val
total += val
return total
def main(argv=None):
if argv is None:
argv = sys.argv
usage = """%s: [PROJECT]\n%s""" % (argv[0], __doc__)
parser = OptionParser(usage=usage)
parser.add_option(
'-s', '--system', default='edge', dest='lpsystem',
help=(
"The Launchpad system to use. Must be one of %s. "
"Defaults to 'edge'." % sorted(uris.service_roots.keys())))
parser.add_option(
'-b', '--bug', dest='lpbug', metavar='BUG_ID', type='int',
help='Triage a single bug instead of all open bugs.')
parser.add_option(
'-t', '--tag', dest='tag', metavar='TAG',
help='Triage bugs with this tag.')
options, args = parser.parse_args(args=argv)
if len(args) != 2:
parser.error('A project name must be supplied.')
if options.lpbug and options.tag:
parser.error('You can only specify either a bug ID or a tag.')
project = args[1]
launchpad = Launchpad.login_with('lpmedic', options.lpsystem)
lp_project = launchpad.projects[project]
if options.lpbug:
new_bugs = [launchpad.bugs[options.lpbug]]
elif options.tag:
new_bugs = lp_project.searchTasks(
tags=options.tag, order_by='-datecreated')
else:
new_bugs = lp_project.searchTasks(
status='New', order_by='-datecreated')
for item in new_bugs:
# XXX: deryck
# The logic should be refactored to not assume
# this is a bugtask, but to get single bugs working,
# work from the correct bugtask on a bug.
if hasattr(item, 'bug'):
task = item
else:
task = [
bt for bt in item.bug_tasks
if bt.bug_target_name == project][0]
print 'Title: %s' % task.bug.title
print 'Status: %s, Importance: %s' % (
task.status, task.importance)
if task.assignee:
assignee = task.assignee.display_name
else:
assignee = task.assignee
print 'Assignee: %s, Milestone: %s' % (assignee, task.milestone)
print '%d affected users' % task.bug.users_affected_count
print 'Reported by %s (%s) on %s:' % (
task.bug.owner.display_name, task.bug.owner.name,
task.bug.date_created)
print 'Description:\n%s' % task.bug.description
if task.bug.messages.total_size > 1:
print 'Comments:'
for message in task.bug.messages:
if message.content != task.bug.description:
print '---------------------------------------------'
print '%s (%s) wrote on %s' % (
message.owner.display_name, message.owner.name,
message.date_created)
print message.content
print 'Bug link: https://bugs.launchpad.net/bugs/%s/' % task.bug.id
print
do_bug = raw_input('Triage this bug? [Y/n] ')
if do_bug.lower() == 'y' or do_bug == '':
print
rank = rank_bug()
print 'This bug has been ranked at: %d' % rank
suggested_importance = get_suggested_importance(rank)
if suggested_importance is not None:
do_importance = raw_input(
'Set this bug to %s? [y/N] ' % suggested_importance)
if do_importance.lower() == 'y':
if task.status != u'Triaged':
task.status = u'Triaged'
task.importance = suggested_importance
task.lp_save()
print 'Set bug %d to (Triaged, %s)' % (
task.bug.id, suggested_importance)
go_again = raw_input('Continue triaging bugs? [Y/n] ')
if go_again == '' or go_again.lower() == 'y':
continue
else:
print 'Thanks for doing some bug triage!'
return 0
else:
continue
else:
print 'Unable to rank importance for bug %s.' % task.bug.id
else:
print
continue
print 'Thanks for doing some bug triage bugs!'
return 0
if __name__ == '__main__':
try:
sys.exit(main())
except KeyboardInterrupt:
print
print 'Thanks for doing some bug triage!'
|