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