Revamp needsponsor report.
Now includes names or addresses if names not set. Includes submission date of oldest ticket. Names are clickable to find all review commentary.
This commit is contained in:
parent
8789303caf
commit
66eaae6702
2 changed files with 165 additions and 24 deletions
|
@ -99,7 +99,8 @@ def parse_config(file):
|
||||||
|
|
||||||
def nobody(str):
|
def nobody(str):
|
||||||
'''Shorten the long "nobody's working on it" string.'''
|
'''Shorten the long "nobody's working on it" string.'''
|
||||||
if str == "Nobody's working on this, feel free to take it":
|
if (str == "Nobody's working on this, feel free to take it"
|
||||||
|
or str == "nobody@fedoraproject.org"):
|
||||||
return "(Nobody)"
|
return "(Nobody)"
|
||||||
return str
|
return str
|
||||||
|
|
||||||
|
@ -107,9 +108,14 @@ def nosec(str):
|
||||||
'''Remove the seconds from an hh:mm:ss format string.'''
|
'''Remove the seconds from an hh:mm:ss format string.'''
|
||||||
return str[0:str.rfind(':')]
|
return str[0:str.rfind(':')]
|
||||||
|
|
||||||
def human_time(t):
|
def human_date(t):
|
||||||
'''Turn an ISO date into something more human-friendly.'''
|
'''Turn an ISO date into something more human-friendly.'''
|
||||||
t = str(t)
|
t = str(t)
|
||||||
|
return t[0:4] + '-' + t[4:6] + '-' + t[6:8]
|
||||||
|
|
||||||
|
def human_time(t):
|
||||||
|
'''Turn an ISO date into something more human-friendly, with time.'''
|
||||||
|
t = str(t)
|
||||||
return t[0:4] + '-' + t[4:6] + '-' + t[6:8] + ' ' + t[9:]
|
return t[0:4] + '-' + t[4:6] + '-' + t[6:8] + ' ' + t[9:]
|
||||||
|
|
||||||
def to_unicode(object, encoding='utf8', errors='replace'):
|
def to_unicode(object, encoding='utf8', errors='replace'):
|
||||||
|
@ -156,20 +162,23 @@ def seq_max_split(seq, max_entries):
|
||||||
def run_query(bz):
|
def run_query(bz):
|
||||||
querydata = {}
|
querydata = {}
|
||||||
bugdata = {}
|
bugdata = {}
|
||||||
|
interesting = {}
|
||||||
alldeps = set([])
|
alldeps = set([])
|
||||||
closeddeps = set([])
|
closeddeps = set([])
|
||||||
|
needinfo = set([])
|
||||||
|
usermap = {}
|
||||||
|
|
||||||
querydata['include_fields'] = ['id', 'creation_time', 'last_change_time', 'bug_severity',
|
querydata['include_fields'] = ['id', 'creation_time', 'last_change_time', 'bug_severity',
|
||||||
'alias', 'assigned_to', 'product', 'creator', 'creator_id', 'status', 'resolution',
|
'alias', 'assigned_to', 'product', 'creator', 'creator_id', 'status', 'resolution',
|
||||||
'component', 'blocks', 'depends_on', 'summary',
|
'component', 'blocks', 'depends_on', 'summary',
|
||||||
'whiteboard', 'flags']
|
'whiteboard', 'flags']
|
||||||
querydata['extra_values'] = []
|
#querydata['extra_values'] = []
|
||||||
querydata['bug_status'] = ['NEW', 'ASSIGNED', 'MODIFIED']
|
querydata['bug_status'] = ['NEW', 'ASSIGNED', 'MODIFIED']
|
||||||
querydata['product'] = ['Fedora', 'Fedora EPEL']
|
querydata['product'] = ['Fedora', 'Fedora EPEL']
|
||||||
querydata['component'] = ['Package Review']
|
querydata['component'] = ['Package Review']
|
||||||
querydata['query_format'] = 'advanced'
|
querydata['query_format'] = 'advanced'
|
||||||
|
|
||||||
# Look up tickets with no flag set
|
# Look up tickets with no fedora-review flag set
|
||||||
querydata['f1'] = 'flagtypes.name'
|
querydata['f1'] = 'flagtypes.name'
|
||||||
querydata['o1'] = 'notregexp'
|
querydata['o1'] = 'notregexp'
|
||||||
querydata['v1'] = 'fedora-review[-+?]'
|
querydata['v1'] = 'fedora-review[-+?]'
|
||||||
|
@ -178,21 +187,40 @@ def run_query(bz):
|
||||||
for bug in bugs:
|
for bug in bugs:
|
||||||
bugdata[bug.id] = {}
|
bugdata[bug.id] = {}
|
||||||
bugdata[bug.id]['hidden'] = 0
|
bugdata[bug.id]['hidden'] = 0
|
||||||
|
bugdata[bug.id]['needinfo'] = 0
|
||||||
bugdata[bug.id]['blocks'] = bug.blocks
|
bugdata[bug.id]['blocks'] = bug.blocks
|
||||||
bugdata[bug.id]['depends'] = bug.depends_on
|
bugdata[bug.id]['depends'] = bug.depends_on
|
||||||
bugdata[bug.id]['reviewflag'] = ' '
|
bugdata[bug.id]['reviewflag'] = ' '
|
||||||
|
|
||||||
# Keep track of dependencies in unflagged tickets
|
# Keep track of "interesting" bugs for which we'll need to do complete
|
||||||
|
# lookups. We want anything with
|
||||||
if bug.depends_on:
|
if bug.depends_on:
|
||||||
alldeps.update(bug.depends_on)
|
alldeps.update(bug.depends_on)
|
||||||
|
|
||||||
# Get the status of each dependency
|
if bug.flags.find('needinfo?') >= 0:
|
||||||
for i in seq_max_split(alldeps, 500):
|
needinfo.add(bug.id)
|
||||||
for bug in bz.getbugssimple(i):
|
|
||||||
if bug.status == 'CLOSED':
|
|
||||||
closeddeps.add(bug.id)
|
|
||||||
|
|
||||||
# Some special processing for those unflagged tickets
|
# Get the status of each "interesting" bug
|
||||||
|
for i in seq_max_split(alldeps.union(needinfo), 500):
|
||||||
|
for bug in filter(None, bz._proxy.Bug.get_bugs({'ids':i, 'permissive': 1, 'extra_fields': ['flags']})['bugs']):
|
||||||
|
interesting[bug['id']] = bug
|
||||||
|
|
||||||
|
# Note the dependencies which are closed
|
||||||
|
for i in alldeps:
|
||||||
|
if interesting[i]['status'] == 'CLOSED':
|
||||||
|
closeddeps.add(i)
|
||||||
|
|
||||||
|
# Note the ones flagged needinfo->reporter
|
||||||
|
for i in needinfo:
|
||||||
|
for j in interesting[i]['flags']:
|
||||||
|
if (j['name'] == 'needinfo'
|
||||||
|
and j['status'] == '?'
|
||||||
|
and j['requestee'] == interesting[i]['creator']):
|
||||||
|
bugdata[i]['needinfo'] = 1
|
||||||
|
bugdata[i]['hidden'] = 1
|
||||||
|
|
||||||
|
# Hide tickets blocked by other bugs or whose with various blockers and
|
||||||
|
# statuses.
|
||||||
def opendep(id): return id not in closeddeps
|
def opendep(id): return id not in closeddeps
|
||||||
for bug in bugs:
|
for bug in bugs:
|
||||||
wb = string.lower(bug.whiteboard)
|
wb = string.lower(bug.whiteboard)
|
||||||
|
@ -206,6 +234,14 @@ def run_query(bz):
|
||||||
or filter(opendep, bugdata[bug.id]['depends']))):
|
or filter(opendep, bugdata[bug.id]['depends']))):
|
||||||
bugdata[bug.id]['hidden'] = 1
|
bugdata[bug.id]['hidden'] = 1
|
||||||
|
|
||||||
|
# Now we need to look up the names of the users
|
||||||
|
for i in bugs:
|
||||||
|
if select_needsponsor(i, bugdata[i.id]):
|
||||||
|
usermap[i.reporter] = ''
|
||||||
|
|
||||||
|
for i in bz._proxy.User.get({'names': usermap.keys()})['users']:
|
||||||
|
usermap[i['name']] = i['real_name']
|
||||||
|
|
||||||
# Now process the other three flags; not much special processing for them
|
# Now process the other three flags; not much special processing for them
|
||||||
querydata['o1'] = 'equals'
|
querydata['o1'] = 'equals'
|
||||||
# for i in ['-', '+', '?']:
|
# for i in ['-', '+', '?']:
|
||||||
|
@ -222,7 +258,7 @@ def run_query(bz):
|
||||||
|
|
||||||
bugs.sort(key=operator.attrgetter('id'))
|
bugs.sort(key=operator.attrgetter('id'))
|
||||||
|
|
||||||
return [bugs, bugdata]
|
return [bugs, bugdata, usermap]
|
||||||
|
|
||||||
# Need to generate reports:
|
# Need to generate reports:
|
||||||
# "Accepted" and closed
|
# "Accepted" and closed
|
||||||
|
@ -267,6 +303,7 @@ def select_merge(bug, bugd):
|
||||||
def select_needsponsor(bug, bugd):
|
def select_needsponsor(bug, bugd):
|
||||||
wb = string.lower(bug.whiteboard)
|
wb = string.lower(bug.whiteboard)
|
||||||
if (bugd['reviewflag'] == ' '
|
if (bugd['reviewflag'] == ' '
|
||||||
|
and bugd['needinfo'] == 0
|
||||||
and NEEDSPONSOR in bugd['blocks']
|
and NEEDSPONSOR in bugd['blocks']
|
||||||
and LEGAL not in bugd['blocks']
|
and LEGAL not in bugd['blocks']
|
||||||
and bug.bug_status != 'CLOSED'
|
and bug.bug_status != 'CLOSED'
|
||||||
|
@ -403,13 +440,13 @@ def report_merge(bugs, bugdata, loader, tmpdir, subs):
|
||||||
|
|
||||||
return data['count']
|
return data['count']
|
||||||
|
|
||||||
def report_needsponsor(bugs, bugdata, loader, tmpdir, subs):
|
def report_needsponsor(bugs, bugdata, loader, usermap, tmpdir, subs):
|
||||||
# Note that this abuses the "month" view to group by reporter instead of month.
|
|
||||||
data = deepcopy(subs)
|
data = deepcopy(subs)
|
||||||
data['description'] = 'This page lists all new NEEDSPONSOR tickets (those without the fedora-revlew flag set)'
|
data['description'] = 'This page lists all new NEEDSPONSOR tickets (those without the fedora-revlew flag set).'
|
||||||
data['title'] = 'NEEDSPONSOR tickets'
|
data['title'] = 'NEEDSPONSOR tickets'
|
||||||
curreporter = ''
|
curreporter = ''
|
||||||
curcount = 0
|
curcount = 0
|
||||||
|
oldest = {}
|
||||||
selected = []
|
selected = []
|
||||||
|
|
||||||
for i in bugs:
|
for i in bugs:
|
||||||
|
@ -417,19 +454,31 @@ def report_needsponsor(bugs, bugdata, loader, tmpdir, subs):
|
||||||
selected.append(i)
|
selected.append(i)
|
||||||
selected.sort(key=reporter)
|
selected.sort(key=reporter)
|
||||||
|
|
||||||
|
# Determine the oldest reported bug
|
||||||
|
for i in selected:
|
||||||
|
if i.reporter not in oldest:
|
||||||
|
oldest[i.reporter] = i.creation_time
|
||||||
|
elif i.creation_time < oldest[i.reporter]:
|
||||||
|
oldest[i.reporter] = i.creation_time
|
||||||
|
|
||||||
for i in selected:
|
for i in selected:
|
||||||
rowclass = rowclass_plain(data['count'])
|
rowclass = rowclass_plain(data['count'])
|
||||||
|
r = i.reporter;
|
||||||
|
|
||||||
if curreporter != reporter(i):
|
if curreporter != r:
|
||||||
data['months'].append({'month': reporter(i), 'bugs': []})
|
if (r in usermap and len(usermap[r])):
|
||||||
curreporter = reporter(i)
|
name = usermap[r]
|
||||||
|
else:
|
||||||
|
name = r
|
||||||
|
data['packagers'].append({'email': r, 'name': name, 'oldest': human_date(oldest[r]), 'bugs': []})
|
||||||
|
curreporter = r
|
||||||
curcount = 0
|
curcount = 0
|
||||||
|
|
||||||
data['months'][-1]['bugs'].append(std_row(i, rowclass))
|
data['packagers'][-1]['bugs'].append(std_row(i, rowclass))
|
||||||
data['count'] +=1
|
data['count'] +=1
|
||||||
curcount +=1
|
curcount +=1
|
||||||
|
|
||||||
write_html(loader, 'bymonth.html', data, tmpdir, 'NEEDSPONSOR.html')
|
write_html(loader, 'needsponsor.html', data, tmpdir, 'NEEDSPONSOR.html')
|
||||||
|
|
||||||
return data['count']
|
return data['count']
|
||||||
|
|
||||||
|
@ -494,10 +543,10 @@ def report_new(bugs, bugdata, loader, tmpdir, subs):
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
options = parse_commandline()
|
options = parse_commandline()
|
||||||
config = parse_config(options.configfile)
|
config = parse_config(options.configfile)
|
||||||
#bz = bugzilla.Bugzilla(url=config['url'], cookiefile=None, user=config['username'], password=config['password'])
|
bz = bugzilla.RHBugzilla(url=config['url'], cookiefile=None, user=config['username'], password=config['password'])
|
||||||
bz = bugzilla.Bugzilla(url=config['url'], cookiefile=None)
|
#bz = bugzilla.RHBugzilla(url=config['url'], cookiefile=None)
|
||||||
t = time.time()
|
t = time.time()
|
||||||
(bugs, bugdata) = run_query(bz)
|
(bugs, bugdata, usermap) = run_query(bz)
|
||||||
querytime = time.time() - t
|
querytime = time.time() - t
|
||||||
|
|
||||||
# Don't bother running this stuff until the query completes, since it fails
|
# Don't bother running this stuff until the query completes, since it fails
|
||||||
|
@ -512,6 +561,7 @@ if __name__ == '__main__':
|
||||||
'version': VERSION,
|
'version': VERSION,
|
||||||
'count': 0,
|
'count': 0,
|
||||||
'months': [],
|
'months': [],
|
||||||
|
'packagers': [],
|
||||||
'bugs': [],
|
'bugs': [],
|
||||||
}
|
}
|
||||||
args = {'bugs':bugs, 'bugdata':bugdata, 'loader':loader, 'tmpdir':tmpdir, 'subs':subs}
|
args = {'bugs':bugs, 'bugdata':bugdata, 'loader':loader, 'tmpdir':tmpdir, 'subs':subs}
|
||||||
|
@ -522,7 +572,7 @@ if __name__ == '__main__':
|
||||||
subs['epel'] = report_epel(**args)
|
subs['epel'] = report_epel(**args)
|
||||||
subs['hidden'] = report_hidden(**args)
|
subs['hidden'] = report_hidden(**args)
|
||||||
subs['merge'] = report_merge(**args)
|
subs['merge'] = report_merge(**args)
|
||||||
subs['needsponsor'] = report_needsponsor(**args)
|
subs['needsponsor'] = report_needsponsor(usermap=usermap, **args)
|
||||||
subs['review'] = report_review(**args)
|
subs['review'] = report_review(**args)
|
||||||
subs['trivial'] = report_trivial(**args)
|
subs['trivial'] = report_trivial(**args)
|
||||||
# data['accepted_closed'] = report_accepted_closed(bugs, bugdata, loader, tmpdir)
|
# data['accepted_closed'] = report_accepted_closed(bugs, bugdata, loader, tmpdir)
|
||||||
|
|
91
scripts/review-stats/review-templates/needsponsor.html
Normal file
91
scripts/review-stats/review-templates/needsponsor.html
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
<!DOCTYPE html
|
||||||
|
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||||
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||||
|
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||||
|
xmlns:py="http://genshi.edgewall.org/"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||||
|
<head>
|
||||||
|
<META http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||||
|
<base href="https://bugzilla.redhat.com/bugzilla/"/>
|
||||||
|
<title>$title</title>
|
||||||
|
<style type="text/css" media="screen">
|
||||||
|
.bz_state_NEEDSPONSOR {background-color: #AAFFAA}
|
||||||
|
.bz_state_FEATURE {background-color: #FFAAAA}
|
||||||
|
.bz_row_even {background-color: #FFFFFF}
|
||||||
|
.bz_row_odd {background-color: #EEEEEE}
|
||||||
|
|
||||||
|
#content
|
||||||
|
{
|
||||||
|
margin-left: 0ex!important;
|
||||||
|
}
|
||||||
|
|
||||||
|
td, th
|
||||||
|
{
|
||||||
|
border: none!important;
|
||||||
|
padding: 0.5ex 2ex!important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<link rel="stylesheet" type="text/css" media="all"
|
||||||
|
href="http://fedoraproject.org/static/css/fedora.css" />
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="wrapper">
|
||||||
|
<div id="head">
|
||||||
|
<h1><a href="http://fedoraproject.org/index.html">Fedora</a></h1>
|
||||||
|
</div>
|
||||||
|
<div id="content">
|
||||||
|
<h2>$description</h2>
|
||||||
|
Click the name to find all comments made in any review tickets.<br/>
|
||||||
|
In parentheses is the date their oldest submission was made.<br/>
|
||||||
|
Last Update: $update (v$version)<br/>
|
||||||
|
There are $count tickets in this category<br/>
|
||||||
|
|
||||||
|
<table class="buglist" cellspacing="0" cellpadding="4" width="100%">
|
||||||
|
<thead>
|
||||||
|
<tr align="left">
|
||||||
|
<th>ID</th>
|
||||||
|
<th>Alias</th>
|
||||||
|
<th>Last Change</th>
|
||||||
|
<th>Summary</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<py:for each="packager in packagers">
|
||||||
|
<tr><td colspan="5"><b>
|
||||||
|
<a href="buglist.cgi?emaillongdesc1=1&emailtype1=substring&component=Package%20Review&query_format=advanced&email1=${packager['email']}">${packager['name']}</a> (${packager['oldest']})
|
||||||
|
</b></td></tr>
|
||||||
|
<py:for each="bug in packager['bugs']">
|
||||||
|
<tr class="${bug['class']}">
|
||||||
|
<td>
|
||||||
|
<a href="show_bug.cgi?id=${bug['id']}">${bug['id']}</a>
|
||||||
|
</td>
|
||||||
|
<td>${bug['alias']} </td>
|
||||||
|
<td>${bug['lastchange']}</td>
|
||||||
|
<td>${bug['summary']}</td>
|
||||||
|
</tr>
|
||||||
|
</py:for>
|
||||||
|
</py:for>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="bottom">
|
||||||
|
<div id="footer">
|
||||||
|
<p class="copy">
|
||||||
|
© 2012 Red Hat, Inc. and others.
|
||||||
|
Currently maintained by Jason Tibbitts; please send comments or questions to him or file tickets on <a href="https://fedorahosted.org/fedora-infrastructure/">the infrastructure trac</a>.
|
||||||
|
</p>
|
||||||
|
<p class="disclaimer">
|
||||||
|
The Fedora Project is maintained and driven by the community and sponsored by Red Hat. This is a community maintained site. Red Hat is not responsible for content.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li class="first"><a href="http://fedoraproject.org/wiki/Legal:Main">Legal</a></li>
|
||||||
|
<li><a href="http://fedoraproject.org/wiki/Legal:Trademark_guidelines">Trademark Guidelines</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Add table
Add a link
Reference in a new issue