status-report-scripts bugzillaReport.py,NONE,1.1
Rakesh Pandit
rakesh at fedoraproject.org
Tue Nov 11 23:40:49 UTC 2008
Author: rakesh
Update of /cvs/fedora/status-report-scripts
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv15129
Added Files:
bugzillaReport.py
Log Message:
script to generate reports for reviews, new packages against reviewer or
reporter based on time span supplied.
--- NEW FILE bugzillaReport.py ---
#!/usr/bin/env python
#
# Copyright 2008 Rakesh Pandit <rakesh at fedoraproject.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with translate; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
import sys
import time
# For debugging pickly result dictionary to file as soon as things break
# Need to remove it later, once script is stable
import pickle
import datetime
import xmlrpclib
from optparse import OptionParser
from bugzilla import Bugzilla
from ConfigParser import ConfigParser
def checkdateInBetween(date, start_date, end_date):
""" """
date_string = date.__str__()
date = datetime.datetime(*(time.strptime(date_string, "%Y%m%dT%H:%M:%S")[0:5]))
if date >= start_date and date < end_date:
return True
return False
def getDateTime(date_string):
""" """
try:
return datetime.datetime(*time.strptime(date_string, "%d/%m/%Y")[0:5])
except ValueError:
print "Error: Date string", date_string, "is wrong. Please check."
exit(1)
def getBugReviewCompleteInfo(bugzilla, bug_id, start_date, end_date):
""" """
result = {}
history = bugzilla._proxy.Bug.get_history({'ids':[bug_id]})
dict_changes = history['bugs'][0][str(bug_id)]
for record in dict_changes:
when = record['when']
who = record['who']
# single record can have many changes also
for each_change in record['changes']:
added = each_change['added']
if added == 'fedora-review+':
result['check'] = True
result['date'] = checkdateInBetween(when, start_date, end_date)
result['who'] = who
return result
result['check'] = False
result['date'] = False
result['who'] = False
return result
def getBugReviewInCompleteInfo(bugzilla, bug_id, start_date, end_date):
""" """
result = {}
history = bugzilla._proxy.Bug.get_history({'ids':[bug_id]})
dict_changes = history['bugs'][0][str(bug_id)]
for record in dict_changes:
when = record['when']
who = record['who']
# single record can have many changes also
for each_change in record['changes']:
added = each_change['added']
if added == 'fedora-review?':
result['check'] = True
result['date'] = checkdateInBetween(when, start_date, end_date)
result['who'] = who
# Check if it already reviewed
return_date = getBugReviewCompleteInfo(bugzilla, bug_id, start_date, end_date)
if return_date['check']:
result['check'] = False
result['date'] = False
result['who'] = False
return result
result['check'] = False
result['date'] = False
result['who'] = False
return result
def getBugNewInfo(bugzilla, bug_id, start_date, end_date):
""" """
result = {}
bug_info = bugzilla._proxy.Bug.get({'ids':[bug_id]})
result['who'] = bug_info['bugs'][0]['internals']['reporter']
when = bug_info['bugs'][0]['creation_time']
result['date'] = checkdateInBetween(when, start_date, end_date)
result['check'] = True
return result
def getBugNewCompleteInfo(bugzilla, bug_id, start_date, end_date):
""" """
result = getBugReviewCompleteInfo(bugzilla, bug_id, start_date, end_date)
bug_info = bugzilla._proxy.Bug.get({'ids':[bug_id]})
result['who'] = bug_info['bugs'][0]['internals']['reporter']
return result
def getBugNewInCompleteInfo(bugzilla, bug_id, start_date, end_date):
""" """
result = getBugReviewInCompleteInfo(bugzilla, bug_id, start_date, end_date)
bug_info = bugzilla._proxy.Bug.get({'ids':[bug_id]})
result['who'] = bug_info['bugs'][0]['internals']['reporter']
return result
def getReportDict(bz, report, bug_list, start, end):
""" """
result = {}
try:
try:
if verbose:
print "Computing data for completed reviews against reviewers."
number = 1
total_number = len(bug_list)
for bug in bug_list:
if verbose:
print "Getting bug number:", number," report <bug #", bug.bug_id, "> -", round((float(number)*100.0/float(total_number)), 3), " %"
number = number + 1
report_data = []
if report == "rev-com":
return_data = getBugReviewCompleteInfo(bz, bug.bug_id, start, end)
elif report == "rev-incom":
return_data = getBugReviewInCompleteInfo(bz, bug.bug_id, start, end)
elif report == "new":
return_data = getBugNewInfo(bz, bug.bug_id, start, end)
elif report == "new-com":
return_data = getBugNewCompleteInfo(bz, bug.bug_id, start, end)
elif report == "new-incom":
return_data = getBugNewInCompleteInfo(bz, bug.bug_id, start, end)
if return_data['date'] and return_data['check']:
if (result.has_key(return_data['who'])):
result[return_data['who']] = result[return_data['who']] + 1
else:
result[return_data['who']] = 1
else:
continue
print "Results in a dictionary:"
return result
except KeyboardInterrupt:
print
print "Interrupting ...."
if len(result.keys()) == 0:
print "No computation done.. Exiting."
exit(0)
print "Results till now in a dictionary:"
return result
except:
print
print "Unexpected error:", sys.exc_info()[0]
print "Results till now in a dictionary:"
return result
usage = "usage: %prog [options]"
parser = OptionParser(usage=usage)
# Verbose progress
parser.add_option("-v", action="store_true", dest="verbose", default=False, \
help="Make a lot of noise [false by default]")
# Report
parser.add_option("-r", "--report", action="store", dest="report", default=False, \
help="Values can be - 'rev-com' - Review complete (against reviewer), 'rev-incom' - Review incomplete - (against reviewer), \
'new' - New packages - (against reporter), 'new-com' - New complete packages - (against reporter), 'new-incom' - New incomplete packages - (against reporter)")
# Bugzilla username
parser.add_option("-u", "--username", action="store", dest="username", \
help="Username for Bugzilla authentication.")
# Bugzilla password
parser.add_option("-p", "--password", action="store", dest="password", \
help="Password for Bugzilla authentication.")
# Start date
parser.add_option("-s", "--start", action="store", dest="start_date", \
help="Start date for report.")
# End date
parser.add_option("-e", "--end", action="store", dest="end_date", \
help="End date for report generation.")
options = {}
args = []
(options, args) = parser.parse_args()
username = options.username
password = options.password
verbose = options.verbose
report = options.report
if not report or (report not in ['rev-com', 'rev-incom', 'new', 'new-com', 'new-incom']):
print "Check ./bugzillaReport -h or --help for details."
print "Error: Either wrong report arg value or not supplied."
print "Values can be: 'rev-com', 'rev-incom', 'new', 'new-com' or 'new-incom'"
exit(1)
if not options.start_date and options.end_date:
print "Error: No start date specified."
exit(1)
# Decide on timespan for report
if options.start_date and not options.end_date:
start = getDateTime(options.start_date)
end = datetime.datetime.now()
difference = end - start
print "Report for ", difference.days, " days."
elif not options.start_date and not options.end_date:
end = datetime.datetime.now()
# Default: 1 week timespan
interval = datetime.timedelta(seconds=0, minutes=0, hours=0, days=7)
start = end - interval
print "Report for ", interval.days, " days."
elif options.start_date and options.end_date:
start = getDateTime(options.start_date)
end = getDateTime(options.end_date)
difference = end - start
print "Report for ", difference.days, " days."
# Find bugzilla username and password
if not (username and password):
try:
conf_file = open('bugzilla.config')
except IOError:
print "Neither username and password supplied"
print "nor conf file for bugzilla username and password."
print "Make a conf file if you want with name 'bugzilla.config'"
print ", with following contents:"
print "[Details]"
print "username=<your_bugzilla_username"
print "password=<your_bugzilla_password>"
exit(1)
# Using config file
cf = ConfigParser()
try:
cf.readfp(conf_file)
except NameError:
print "Neither username and password supplied"
print "nor conf file for bugzilla username and password."
print ", with following contents:"
print "[Details]"
print "username=<your_bugzilla_username"
print "password=<your_bugzilla_password>"
exit(1)
username = cf.get("Details",'username')
password = cf.get("Details",'password')
# Get bug list
bug_list = []
url = 'https://bugzilla.redhat.com/xmlrpc.cgi'
query_dict = {'product':'Fedora',
'component':'Package Review'}
bz = Bugzilla(url=url, username=username, password=password)
if verbose:
print "Quering. Getting all package review bugs (be patient, it may take too long) ...."
bug_list = bz.query(query_dict)
if verbose:
print "Total number of Package Reviews:", len(bug_list)
result = {}
# Result will have name as keys and number of bugs as value.
result = getReportDict(bz, report, bug_list, start, end)
print result
print "Calculated results are in file output.txt"
# pickle to a file for debugging, need to reomve it later
# once script is stable
file_pickle = open("pickle.pck", "w")
pickle.dump(result, file_pickle)
list_of_names = result.keys()
list_of_names.sort()
file = open('output.txt', 'w')
for i in range(0, list_of_names.__len__()):
file.write(list_of_names[i].encode('utf-8') + " - " + str(result[list_of_names[i]]))
file.write('\n')
file.close()
# File ends here
More information about the fedora-extras-commits
mailing list