Update to latest review-stats upstream code.

This commit is contained in:
Jason ティビツ 2015-08-21 17:55:40 +00:00
parent 75c6d70bac
commit dcb2f9b9d1
2 changed files with 89 additions and 75 deletions

View file

@ -1,17 +1,4 @@
#!/usr/bin/python -t #!/usr/bin/python -t
VERSION = "4.0"
# $Id: review-stats.py,v 1.12 2010/01/15 05:14:10 tibbs Exp $
# Note: This script presently lives in internal git and external cvs. External
# cvs is:
# http://cvs.fedoraproject.org/viewvc/status-report-scripts/review-stats.py?root=fedora
# or check it out with
# CVSROOT=:pserver:anonymous@cvs.fedoraproject.org:/cvs/fedora cvs co status-report-scripts
#
# Internal is in the puppet configs repository on puppet1. It needs to be
# there so that puppet can distribute to the servers. I recommend doing the
# work in the public cvs first, then copying to puppet's git after.
import bugzilla import bugzilla
import datetime import datetime
import glob import glob
@ -28,18 +15,20 @@ from genshi.template import TemplateLoader
from optparse import OptionParser from optparse import OptionParser
from validate import Validator from validate import Validator
VERSION = "4.1"
# Red Hat's bugzilla # Red Hat's bugzilla
url = 'https://bugzilla.redhat.com/xmlrpc.cgi' url = 'https://bugzilla.redhat.com/xmlrpc.cgi'
# Some magic bug numbers # Some magic bug numbers
ACCEPT = 163779 ACCEPT = 163779
BUNDLED = 658489 BUNDLED = 658489
FEATURE = 654686 FEATURE = 654686
GUIDELINES = 197974 GUIDELINES = 197974
LEGAL = 182235 LEGAL = 182235
NEEDSPONSOR = 177841 NEEDSPONSOR = 177841
SCITECH = 505154 SCITECH = 505154
SECLAB = 563471 SECLAB = 563471
# These will show up in a query but aren't actual review tickets # These will show up in a query but aren't actual review tickets
trackers = set([ACCEPT, BUNDLED, FEATURE, NEEDSPONSOR, GUIDELINES, SCITECH, SECLAB]) trackers = set([ACCEPT, BUNDLED, FEATURE, NEEDSPONSOR, GUIDELINES, SCITECH, SECLAB])
@ -49,7 +38,7 @@ maxpackages = 5
# So the bugzilla module has some way to complain # So the bugzilla module has some way to complain
logging.basicConfig() logging.basicConfig()
#logging.basicConfig(level=logging.DEBUG)
def parse_commandline(): def parse_commandline():
usage = "usage: %prog [options] -c <bugzilla_config> -d <dest_dir> -t <template_dir>" usage = "usage: %prog [options] -c <bugzilla_config> -d <dest_dir> -t <template_dir>"
@ -66,7 +55,6 @@ def parse_commandline():
help="run verbosely") help="run verbosely")
(options, args) = parser.parse_args() (options, args) = parser.parse_args()
tst = str(options.dirname)
if str(options.dirname) == 'None': if str(options.dirname) == 'None':
parser.error("Please specify destination directory") parser.error("Please specify destination directory")
if not os.path.isdir(options.dirname): if not os.path.isdir(options.dirname):
@ -79,6 +67,7 @@ def parse_commandline():
return options return options
def parse_config(file): def parse_config(file):
v = Validator() v = Validator()
@ -95,14 +84,14 @@ def parse_config(file):
for entry in flatten_errors(cfg, res): for entry in flatten_errors(cfg, res):
section_list, key, error = entry section_list, key, error = entry
section_list.append(key) section_list.append(key)
section_string = ','.join(section_list) if not error:
if error == False:
error = 'Missing value or section.' error = 'Missing value or section.'
print ','.join(section_list), '=', error print(','.join(section_list), '=', error)
sys.exit(1) sys.exit(1)
return cfg['global'] return cfg['global']
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"
@ -110,20 +99,24 @@ def nobody(str):
return "(Nobody)" return "(Nobody)"
return str return str
def nosec(str): 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_date(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] return t[0:4] + '-' + t[4:6] + '-' + t[6:8]
def human_time(t): def human_time(t):
'''Turn an ISO date into something more human-friendly, with time.''' '''Turn an ISO date into something more human-friendly, with time.'''
t = str(t) 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'):
if isinstance(object, basestring): if isinstance(object, basestring):
if isinstance(object, str): if isinstance(object, str):
@ -132,6 +125,7 @@ def to_unicode(object, encoding='utf8', errors='replace'):
return object return object
return u'' return u''
def reporter(bug): def reporter(bug):
'''Extract the reporter from a bug, replacing an empty value with "(none)". '''Extract the reporter from a bug, replacing an empty value with "(none)".
Yes, bugzilla will return a blank reporter for some reason.''' Yes, bugzilla will return a blank reporter for some reason.'''
@ -139,28 +133,29 @@ def reporter(bug):
return "(none)" return "(none)"
return bug.reporter return bug.reporter
def yrmonth(d): def yrmonth(d):
'''Turn a bugzilla date into Month YYYY string.''' '''Turn a bugzilla date into Month YYYY string.'''
m = ['January', 'February', 'March', 'April', 'May', 'June', 'July', m = ['January', 'February', 'March', 'April', 'May', 'June', 'July',
'August', 'September', 'October', 'November', 'December'] 'August', 'September', 'October', 'November', 'December']
#year = str.split('-')[0]
#month = int(str.split('-')[1])-1
str = d.value str = d.value
year = str[0:4] year = str[0:4]
month = int(str[4:6])-1 month = int(str[4:6]) - 1
return m[month] + ' ' + year return m[month] + ' ' + year
def dbprint(str): def dbprint(str):
'''Print string if verbosity is turned on.''' '''Print string if verbosity is turned on.'''
if verbose: if verbose:
print(str) print(str)
def seq_max_split(seq, max_entries): def seq_max_split(seq, max_entries):
""" Given a seq, split into a list of lists of length max_entries each. """ """ Given a seq, split into a list of lists of length max_entries each. """
ret = [] ret = []
num = len(seq) num = len(seq)
seq = list(seq) # Trying to use a set/etc. here is bad seq = list(seq) # Trying to use a set/etc. here is bad
beg = 0 beg = 0
while num > max_entries: while num > max_entries:
end = beg + max_entries end = beg + max_entries
@ -170,20 +165,18 @@ def seq_max_split(seq, max_entries):
ret.append(seq[beg:]) ret.append(seq[beg:])
return ret return ret
def run_query(bz): def run_query(bz):
querydata = {} querydata = {}
bugdata = {} bugdata = {}
interesting = {}
alldeps = set([]) alldeps = set([])
closeddeps = set([]) closeddeps = set([])
needinfo = set([])
usermap = {} 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['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']
@ -197,7 +190,7 @@ def run_query(bz):
dbprint("Running main query.") dbprint("Running main query.")
t = time.time() t = time.time()
bugs = filter(lambda b: b.id not in trackers, bz.query(querydata)) bugs = filter(lambda b: b.id not in trackers, bz.query(querydata))
dbprint("Done, took {0:.2f}.".format(time.time()-t)) dbprint("Done, took {0:.2f}.".format(time.time() - t))
for bug in bugs: for bug in bugs:
bugdata[bug.id] = {} bugdata[bug.id] = {}
@ -219,20 +212,21 @@ def run_query(bz):
# Find which of the dependencies are closed # Find which of the dependencies are closed
dbprint("Looking up {0} bug deps.".format(len(alldeps))) dbprint("Looking up {0} bug deps.".format(len(alldeps)))
t=time.time() t = time.time()
for bug in filter(None, bz.query(bz.build_query(bug_id=list(alldeps), status=["CLOSED"]))): for bug in filter(None, bz.query(bz.build_query(bug_id=list(alldeps), status=["CLOSED"]))):
closeddeps.add(bug.id) closeddeps.add(bug.id)
dbprint("Done; took {0:.2f}.".format(time.time()-t)) dbprint("Done; took {0:.2f}.".format(time.time() - t))
# Hide tickets blocked by other bugs or those with various blockers and # Hide tickets blocked by other bugs or those with various blockers and
# statuses. # 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)
if bug.bug_status != 'CLOSED': if bug.bug_status != 'CLOSED':
if wb.find('notready') >= 0: if wb.find('notready') >= 0:
bugdata[bug.id]['hidden'].append('notready') bugdata[bug.id]['hidden'].append('notready')
if wb.find('buildfails') >= 0: if wb.find('buildfails') >= 0:
bugdata[bug.id]['hidden'].append('buildfails') bugdata[bug.id]['hidden'].append('buildfails')
if wb.find('stalledsubmitter') >= 0: if wb.find('stalledsubmitter') >= 0:
bugdata[bug.id]['hidden'].append('stalled') bugdata[bug.id]['hidden'].append('stalled')
@ -265,13 +259,13 @@ def run_query(bz):
# Now we need to look up the names of the users # Now we need to look up the names of the users
for i in bugs: for i in bugs:
if select_needsponsor(i, bugdata[i.id]): if select_needsponsor(i, bugdata[i.id]):
usermap[i.reporter] = '' usermap[i.reporter] = ''
dbprint("Looking up {0} user names.".format(len(usermap))) dbprint("Looking up {0} user names.".format(len(usermap)))
t=time.time() t = time.time()
for i in bz._proxy.User.get({'names': usermap.keys()})['users']: for i in bz._proxy.User.get({'names': usermap.keys()})['users']:
usermap[i['name']] = i['real_name'] usermap[i['name']] = i['real_name']
dbprint("Done; took {0:.2f}.".format(time.time()-t)) dbprint("Done; took {0:.2f}.".format(time.time() - t))
# 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'
@ -280,9 +274,9 @@ def run_query(bz):
querydata['v1'] = 'fedora-review' + i querydata['v1'] = 'fedora-review' + i
dbprint("Looking up tickets with flag {0}.".format(i)) dbprint("Looking up tickets with flag {0}.".format(i))
t=time.time() t = time.time()
b1 = bz.query(querydata) b1 = bz.query(querydata)
dbprint("Done; took {0:.2f}.".format(time.time()-t)) dbprint("Done; took {0:.2f}.".format(time.time() - t))
for bug in b1: for bug in b1:
bugdata[bug.id] = {} bugdata[bug.id] = {}
@ -297,7 +291,7 @@ def run_query(bz):
return [bugs, bugdata, usermap] return [bugs, bugdata, usermap]
# Need to generate reports: # Need to generate reports:
# "Accepted" and closed # "Accepted" and closed
# "Accepted" but still open # "Accepted" but still open
# "Accepted" means either fedora-review+ or blocking FE-ACCEPT # "Accepted" means either fedora-review+ or blocking FE-ACCEPT
# fedora-review- and closed # fedora-review- and closed
@ -307,6 +301,7 @@ def run_query(bz):
# Tickets awaiting review but which were hidden for some reason # Tickets awaiting review but which were hidden for some reason
# That should be all tickets in the Package Review component # That should be all tickets in the Package Review component
def write_html(loader, template, data, dir, fname): def write_html(loader, template, data, dir, fname):
'''Load and render the given template with the given data to the given '''Load and render the given template with the given data to the given
filename in the specified directory.''' filename in the specified directory.'''
@ -316,19 +311,25 @@ def write_html(loader, template, data, dir, fname):
path = os.path.join(dir, fname) path = os.path.join(dir, fname)
try: try:
f = open(path, "w") f = open(path, "w")
except IOError, (err, strerr): except:
print 'ERROR: %s: %s' % (strerr, path) print("Error opening %s" % (path))
sys.exit(1) sys.exit(1)
f.write(output.render()) for line in output.render().splitlines():
try:
f.write(line.encode('utf8'))
except UnicodeError as e:
print(e.encoding, e.reason, e.object)
f.close() f.close()
# Selection functions (should all be predicates) # Selection functions (should all be predicates)
def select_hidden(bug, bugd): def select_hidden(bug, bugd):
if len(bugd['hidden']) > 0: if len(bugd['hidden']) > 0:
return 1 return 1
return 0 return 0
def select_merge(bug, bugd): def select_merge(bug, bugd):
if (bugd['reviewflag'] == ' ' if (bugd['reviewflag'] == ' '
and bug.bug_status != 'CLOSED' and bug.bug_status != 'CLOSED'
@ -336,6 +337,7 @@ def select_merge(bug, bugd):
return 1 return 1
return 0 return 0
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'] == ' '
@ -351,11 +353,13 @@ def select_needsponsor(bug, bugd):
return 1 return 1
return 0 return 0
def select_review(bug, bugd): def select_review(bug, bugd):
if bugd['reviewflag'] == '?': if bugd['reviewflag'] == '?':
return 1 return 1
return 0 return 0
def select_trivial(bug, bugd): def select_trivial(bug, bugd):
if (bugd['reviewflag'] == ' ' if (bugd['reviewflag'] == ' '
and bug.bug_status != 'CLOSED' and bug.bug_status != 'CLOSED'
@ -363,6 +367,7 @@ def select_trivial(bug, bugd):
return 1 return 1
return 0 return 0
def select_epel(bug, bugd): def select_epel(bug, bugd):
'''If someone assigns themself to a ticket, it's theirs regardless of '''If someone assigns themself to a ticket, it's theirs regardless of
whether they set the flag properly or not.''' whether they set the flag properly or not.'''
@ -375,6 +380,7 @@ def select_epel(bug, bugd):
return 1 return 1
return 0 return 0
def select_new(bug, bugd): def select_new(bug, bugd):
'''If someone assigns themself to a ticket, it's theirs regardless of '''If someone assigns themself to a ticket, it's theirs regardless of
whether they set the flag properly or not.''' whether they set the flag properly or not.'''
@ -387,10 +393,12 @@ def select_new(bug, bugd):
return 1 return 1
return 0 return 0
def rowclass_plain(count): def rowclass_plain(count):
rowclass = 'bz_row_even'
if count % 2 == 1: if count % 2 == 1:
rowclass = 'bz_row_odd' return 'bz_row_odd'
return 'bz_row_even'
# Yes, the even/odd classes look backwards, but it looks better this way # Yes, the even/odd classes look backwards, but it looks better this way
def rowclass_with_sponsor(bug, count): def rowclass_with_sponsor(bug, count):
@ -403,6 +411,7 @@ def rowclass_with_sponsor(bug, count):
rowclass = 'bz_row_even' rowclass = 'bz_row_even'
return rowclass return rowclass
# The data from a standard row in a bug list # The data from a standard row in a bug list
def std_row(bug, rowclass): def std_row(bug, rowclass):
alias = '' alias = ''
@ -418,6 +427,7 @@ def std_row(bug, rowclass):
'summary': to_unicode(bug.short_desc), 'summary': to_unicode(bug.short_desc),
} }
def hidden_reason(reasons): def hidden_reason(reasons):
r = '' r = ''
if 'buildfails' in reasons: if 'buildfails' in reasons:
@ -437,24 +447,25 @@ def hidden_reason(reasons):
return r return r
# Report generators # Report generators
def report_hidden(bugs, bugdata, loader, tmpdir, subs): def report_hidden(bugs, bugdata, loader, tmpdir, subs):
data = deepcopy(subs) data = deepcopy(subs)
data['description'] = 'This page lists all review tickets are hidden from the main review queues' data['description'] = 'This page lists all review tickets are hidden from the main review queues'
data['title'] = 'Hidden reviews' data['title'] = 'Hidden reviews'
curmonth = ''
for i in bugs: for i in bugs:
if select_hidden(i, bugdata[i.id]): if select_hidden(i, bugdata[i.id]):
rowclass = rowclass_with_sponsor(bugdata[i.id], data['count']) rowclass = rowclass_with_sponsor(bugdata[i.id], data['count'])
data['bugs'].append(std_row(i, rowclass)) data['bugs'].append(std_row(i, rowclass))
data['bugs'][-1]['reason'] = hidden_reason(bugdata[i.id]['hidden']) data['bugs'][-1]['reason'] = hidden_reason(bugdata[i.id]['hidden'])
data['count'] +=1 data['count'] += 1
write_html(loader, 'hidden.html', data, tmpdir, 'HIDDEN.html') write_html(loader, 'hidden.html', data, tmpdir, 'HIDDEN.html')
return data['count'] return data['count']
def report_review(bugs, bugdata, loader, tmpdir, subs): def report_review(bugs, bugdata, loader, tmpdir, subs):
data = deepcopy(subs) data = deepcopy(subs)
data['description'] = 'This page lists tickets currently under review' data['description'] = 'This page lists tickets currently under review'
@ -464,12 +475,13 @@ def report_review(bugs, bugdata, loader, tmpdir, subs):
if select_review(i, bugdata[i.id]): if select_review(i, bugdata[i.id]):
rowclass = rowclass_plain(data['count']) rowclass = rowclass_plain(data['count'])
data['bugs'].append(std_row(i, rowclass)) data['bugs'].append(std_row(i, rowclass))
data['count'] +=1 data['count'] += 1
write_html(loader, 'plain.html', data, tmpdir, 'REVIEW.html') write_html(loader, 'plain.html', data, tmpdir, 'REVIEW.html')
return data['count'] return data['count']
def report_trivial(bugs, bugdata, loader, tmpdir, subs): def report_trivial(bugs, bugdata, loader, tmpdir, subs):
data = deepcopy(subs) data = deepcopy(subs)
data['description'] = 'This page lists review tickets marked as trivial' data['description'] = 'This page lists review tickets marked as trivial'
@ -479,12 +491,13 @@ def report_trivial(bugs, bugdata, loader, tmpdir, subs):
if select_trivial(i, bugdata[i.id]): if select_trivial(i, bugdata[i.id]):
rowclass = rowclass_plain(data['count']) rowclass = rowclass_plain(data['count'])
data['bugs'].append(std_row(i, rowclass)) data['bugs'].append(std_row(i, rowclass))
data['count'] +=1 data['count'] += 1
write_html(loader, 'plain.html', data, tmpdir, 'TRIVIAL.html') write_html(loader, 'plain.html', data, tmpdir, 'TRIVIAL.html')
return data['count'] return data['count']
def report_merge(bugs, bugdata, loader, tmpdir, subs): def report_merge(bugs, bugdata, loader, tmpdir, subs):
data = deepcopy(subs) data = deepcopy(subs)
data['description'] = 'This page lists all merge review tickets which need reviewers' data['description'] = 'This page lists all merge review tickets which need reviewers'
@ -494,12 +507,13 @@ def report_merge(bugs, bugdata, loader, tmpdir, subs):
if select_merge(i, bugdata[i.id]): if select_merge(i, bugdata[i.id]):
rowclass = rowclass_plain(data['count']) rowclass = rowclass_plain(data['count'])
data['bugs'].append(std_row(i, rowclass)) data['bugs'].append(std_row(i, rowclass))
data['count'] +=1 data['count'] += 1
write_html(loader, 'plain.html', data, tmpdir, 'MERGE.html') write_html(loader, 'plain.html', data, tmpdir, 'MERGE.html')
return data['count'] return data['count']
def report_needsponsor(bugs, bugdata, loader, usermap, tmpdir, subs): def report_needsponsor(bugs, bugdata, loader, usermap, tmpdir, subs):
data = deepcopy(subs) data = deepcopy(subs)
data['description'] = 'This page lists all new NEEDSPONSOR tickets (those without the fedora-review flag set).' data['description'] = 'This page lists all new NEEDSPONSOR tickets (those without the fedora-review flag set).'
@ -525,7 +539,7 @@ def report_needsponsor(bugs, bugdata, loader, usermap, tmpdir, subs):
for i in selected: for i in selected:
rowclass = rowclass_plain(data['count']) rowclass = rowclass_plain(data['count'])
r = i.reporter; r = i.reporter
if curreporter != r: if curreporter != r:
if (r in usermap and len(usermap[r])): if (r in usermap and len(usermap[r])):
@ -537,16 +551,18 @@ def report_needsponsor(bugs, bugdata, loader, usermap, tmpdir, subs):
curcount = 0 curcount = 0
data['packagers'][-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, 'needsponsor.html', data, tmpdir, 'NEEDSPONSOR.html') write_html(loader, 'needsponsor.html', data, tmpdir, 'NEEDSPONSOR.html')
return data['count'] return data['count']
def report_epel(bugs, bugdata, loader, tmpdir, subs): def report_epel(bugs, bugdata, loader, tmpdir, subs):
data = deepcopy(subs) data = deepcopy(subs)
data['description'] = 'This page lists new, reviewable EPEL package review tickets. Tickets colored green require a sponsor.' data['description'] = ('This page lists new, reviewable EPEL package review tickets.'
' Tickets colored green require a sponsor.')
data['title'] = 'New EPEL package review tickets' data['title'] = 'New EPEL package review tickets'
curmonth = '' curmonth = ''
@ -563,8 +579,8 @@ def report_epel(bugs, bugdata, loader, tmpdir, subs):
rowclass = rowclass_with_sponsor(bugdata[i.id], curcount) rowclass = rowclass_with_sponsor(bugdata[i.id], curcount)
data['months'][-1]['bugs'].append(std_row(i, rowclass)) data['months'][-1]['bugs'].append(std_row(i, rowclass))
data['count'] +=1 data['count'] += 1
curcount +=1 curcount += 1
if curcount > 0: if curcount > 0:
data['months'][-1]['month'] += (" (%d)" % curcount) data['months'][-1]['month'] += (" (%d)" % curcount)
@ -573,9 +589,11 @@ def report_epel(bugs, bugdata, loader, tmpdir, subs):
return data['count'] return data['count']
def report_new(bugs, bugdata, loader, tmpdir, subs): def report_new(bugs, bugdata, loader, tmpdir, subs):
data = deepcopy(subs) data = deepcopy(subs)
data['description'] = 'This page lists new, reviewable Fedora package review tickets (excluding merge reviews). Tickets colored green require a sponsor.' data['description'] = ('This page lists new, reviewable Fedora package review tickets (excluding merge reviews).'
' Tickets colored green require a sponsor.')
data['title'] = 'New package review tickets' data['title'] = 'New package review tickets'
curmonth = '' curmonth = ''
@ -592,8 +610,8 @@ def report_new(bugs, bugdata, loader, tmpdir, subs):
rowclass = rowclass_with_sponsor(bugdata[i.id], curcount) rowclass = rowclass_with_sponsor(bugdata[i.id], curcount)
data['months'][-1]['bugs'].append(std_row(i, rowclass)) data['months'][-1]['bugs'].append(std_row(i, rowclass))
data['count'] +=1 data['count'] += 1
curcount +=1 curcount += 1
if curcount > 0: if curcount > 0:
data['months'][-1]['month'] += (" (%d)" % curcount) data['months'][-1]['month'] += (" (%d)" % curcount)
@ -627,19 +645,17 @@ if __name__ == '__main__':
'count': 0, 'count': 0,
'months': [], 'months': [],
'packagers': [], '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}
t = time.time() t = time.time()
subs['new'] = report_new(**args) subs['new'] = report_new(**args)
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['needsponsor'] = report_needsponsor(usermap=usermap, **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)
# data['accepted_open'] = report_accepted_open(bugs, bugdata, loader, tmpdir) # data['accepted_open'] = report_accepted_open(bugs, bugdata, loader, tmpdir)
# data['rejected_closed'] = report_rejected_closed(bugs, bugdata, loader, tmpdir) # data['rejected_closed'] = report_rejected_closed(bugs, bugdata, loader, tmpdir)

View file

@ -38,13 +38,11 @@ available:
<tr><td style="white-space: nowrap"><a href="TRIVIAL.html">Trivial tickets</a> ($trivial)</td> <tr><td style="white-space: nowrap"><a href="TRIVIAL.html">Trivial tickets</a> ($trivial)</td>
<td>All review tickets marked as trivial. New reviewers should look here for simple packages to review.</td></tr> <td>All review tickets marked as trivial. New reviewers should look here for simple packages to review.</td></tr>
<tr><td style="white-space: nowrap"><a href="NEW.html">New tickets</a> ($new)</td> <tr><td style="white-space: nowrap"><a href="NEW.html">New tickets</a> ($new)</td>
<td>All non-merge review tickets without an assigned reviewer, sorted by submission date. Tickets colored green require a sponsor.</td></tr> <td>All review tickets without an assigned reviewer, sorted by submission date. Tickets colored green require a sponsor.</td></tr>
<tr><td style="white-space: nowrap"><a href="EPEL.html">New EPEL tickets</a> ($epel)</td> <tr><td style="white-space: nowrap"><a href="EPEL.html">New EPEL tickets</a> ($epel)</td>
<td>All EPEL review tickets without an assigned reviewer, sorted by submission date. Tickets colored green require a sponsor.</td></tr> <td>All EPEL review tickets without an assigned reviewer, sorted by submission date. Tickets colored green require a sponsor.</td></tr>
<tr><td style="white-space: nowrap"><a href="NEEDSPONSOR.html">Needsponsor tickets</a> ($needsponsor)</td> <tr><td style="white-space: nowrap"><a href="NEEDSPONSOR.html">Needsponsor tickets</a> ($needsponsor)</td>
<td>All review tickets where a sponsor is required, sorted by reporter. Please see <a href="https://fedoraproject.org/wiki/How_to_get_sponsored_into_the_packager_group#Sponsorship_model">this page</a> for more information on sponsorship.</td></tr> <td>All review tickets where a sponsor is required, sorted by reporter. Please see <a href="https://fedoraproject.org/wiki/How_to_get_sponsored_into_the_packager_group#Sponsorship_model">this page</a> for more information on sponsorship.</td></tr>
<tr><td style="white-space: nowrap"><a href="MERGE.html">Merge review tickets</a> ($merge)</td>
<td>All merge review tickets. Please see <a href="https://fedoraproject.org/wiki/Merge_Reviews">this page</a> for more information on merge reviews.</td></tr>
<tr><td style="white-space: nowrap"><a href="HIDDEN.html">Hidden tickets</a> ($hidden)</td> <tr><td style="white-space: nowrap"><a href="HIDDEN.html">Hidden tickets</a> ($hidden)</td>
<td>Tickets which have been hidden for some reason. These tickets either depend on other review tickets which have not yet been closed, or are unreviewable for some reason. See <a href="https://fedoraproject.org/wiki/Package_Review_Process#Special_blocker_tickets">this page</a> for more information on the various states a review ticket can have.</td></tr> <td>Tickets which have been hidden for some reason. These tickets either depend on other review tickets which have not yet been closed, or are unreviewable for some reason. See <a href="https://fedoraproject.org/wiki/Package_Review_Process#Special_blocker_tickets">this page</a> for more information on the various states a review ticket can have.</td></tr>
<tr><td style="white-space: nowrap"><a href="REVIEW.html">Tickets under review</a> ($review)</td> <tr><td style="white-space: nowrap"><a href="REVIEW.html">Tickets under review</a> ($review)</td>