Update to latest review-stats upstream code.
This commit is contained in:
parent
75c6d70bac
commit
dcb2f9b9d1
2 changed files with 89 additions and 75 deletions
|
@ -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)
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue