fedora-accounts bz-make-components-pkgdb.py,NONE,1.1
Toshio Ernie Kuratomi (toshio)
fedora-extras-commits at redhat.com
Sat Jun 30 01:23:15 UTC 2007
Author: toshio
Update of /cvs/fedora/fedora-accounts
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv4554
Added Files:
bz-make-components-pkgdb.py
Log Message:
* bz-make-components-pkgdb.py: Initial version of a script to sync the package
database information out to bugzilla.
--- NEW FILE bz-make-components-pkgdb.py ---
#!/usr/bin/python -t
import sys, os, errno
import website, crypt
import getopt, re
import xmlrpclib
import simplejson
import urllib2
from fedora.accounts.fas import AccountSystem
# Set this to the production bugzilla account when we're ready to go live
BZSERVER = 'https://bugdev.devel.redhat.com/bugzilla-cvs/xmlrpc.cgi'
#BZSERVER = 'https://bugzilla.redhat.com/bugzilla/xmlrpc.cgi'
BZUSER='toshio at tiki-lounge.com'
BZPASS='tanuki7'
PKGDBSERVER = 'http://test3.fedora.phx.redhat.com/pkgdb-dev/acls/bugzilla?tg_format=json'
# Set this to False when we're ready to run it against the bz database
DRY_RUN = True
class DataChangedError(Exception):
'''Raised when data we are manipulating changes while we're modifying it.'''
pass
class Bugzilla(object):
GRANT_DIRECT = 0
GRANT_DERIVED = 1
GRANT_REGEXP = 2
def __init__(self, bzServer, username, password):
self.userCache = {}
self.productCache = {}
self.bzXmlRpcServer = bzServer
self.username = username
self.password = password
self.server = xmlrpclib.Server(bzServer)
# We still have to talk directly to the db for some things
self.bzdbh = website.get_dbh('bugs', 'bugs')
self.bzdbc = self.bzdbh.cursor()
self.bzdbh.commit()
def _get_bugzilla_email(self, username):
try:
user = self.userCache[username]
except KeyError:
user = {}
(person, groups) = self.fas.get_user_info(username)
user['email'] = person['bugzilla_email']
self.userCache[username] = user
return user['email']
try:
email = user['email']
except KeyError:
try:
(person, groups) = self.fas.get_user_info(username)
except fas.AuthError, e:
raise ValueError, 'Username %s was not found in fas' % username
email = person['bugzilla_email']
user['email'] = email
return email
def _get_bugzilla_user_id(self, username):
bzdbc = self.bzdbh.cursor()
try:
user = self.userCache[username]
except KeyError:
self._get_bugzilla_email(username)
user = self.userCache[username]
try:
bzid = user['bzid']
except KeyError:
bzdbc.execute("SELECT userid FROM profiles WHERE login_name = %s",
(user['email'],))
if bzdbc.rowcount:
bzid = bzdbc.fetchone()[0]
else:
raise ValueError , 'Username %s with email %s does not have a bugzilla account.' % (username, user['email'])
user['bzid'] = bzid
return bzid
def add_edit_component(self, package, collection, owner, description,
qacontact=None, cclist=None):
'''Add or update a component to have the values specified.
'''
# Lookup product
try:
product = self.productCache[collection]
except KeyError:
product = {}
components = self.server.bugzilla.getProdCompDetails(collection,
self.username, self.password)
# This ugly construction changes from the form:
# {'component': 'PackageName',
# 'initialowner': 'OwnerEmail',
# 'initialqacontact': 'QAContactEmail',
# 'description': 'One sentence summary'}
# to:
# product['PackageName'] = {'initialowner': 'OwnerEmail',
# 'initialqacontact': 'QAContactEmail',
# 'description': 'One sentenct summary'}
for record in map(lambda x: (x['component'], [z for z in x.items() if lambda y: y[0] != 'component']), components):
product[record[0]] = {}
product[record[0]].update(record[1])
self.productCache[collection] = product
if package in product:
# edit the package information
data = {}
# Grab bugzilla email for things changable via xmlrpc
owner = self._get_bugzilla_email(owner)
if qacontact:
qacontact = self._get_bugzilla_email(qacontact)
# Check for changes to the owner, qacontact, or description
if product[package]['initialowner'] != owner:
data['initialowner'] = owner
if product[package]['description'] == description:
data['description'] = description
if product[package]['initialqacontact'] != qacontact and (
qacontact or product[package]['initialqacontact']):
data['initialqacontact'] = qacontact
if data:
# Changes occurred. Submit a request to change via xmlrpc
data['product'] = collection
data['component'] = package
if DRY_RUN:
print 'Changing via editComponent(%s, %s, "xxxxx")' % (
data, self.username)
else:
self.server.bugzilla.editComponent(data, self.username,
self.password)
### FIXME: Check for changes to cclist
# We're going to wait on the xmlrpc interface returning cclist
# Update the cclist
# Get the component id
self.bzdbc.execute("select c.id" \
" from components as c, products as p" \
" where p.name = %s and c.name = %s" \
" and p.id = c.product_id", (collection, package))
if not self.bzdbc.rowcount:
raise DataChangedError, 'Package %s disappeared from collection %s during processing' % (package, collection)
pkgId = self.bzdbc.fetchone()[0]
# Turn all cclist members into bugzilla ids
bzCclist = []
for watcher in cclist:
bzCclist.append(self._get_bugzilla_user_id(watcher))
# Update the cclist in the database
if DRY_RUN:
print "update components set initialcclist = '%s'" \
" where id = '%s'" % (':'.join(map(str,bzCclist)),
pkgId)
else:
self.bzdbc.execute("update components set initialcclist = %s" \
" where id = %s", (':'.join(map(str,bzCclist)), pkgId))
self.bzdbh.commit()
else:
# Add component
# Get the product id
self.bzdbc.execute("select id from products where name = %s", collection)
if not self.bzdbc.rowcount:
raise DataChangedError, 'Collection %s disappeared from the database during processing' % (collection,)
collectionId = self.bzdbc.fetchone()[0]
# Retrieve bugzilla ids for all the fas usernames
ownerId = self._get_bugzilla_user_id(owner)
qacontactId = self._get_bugzilla_user_id(qacontact)
bzCclist = []
for watcher in cclist:
bzCclist.append(self._get_bugzilla_user_id(watcher))
# Add the component
if DRY_RUN:
print "insert into components (name, product_id, description," \
" initialowner, initialqacontact, initialcclist)" \
" values (%s, %s, %s, %s, %s, %s)" % (package,
collectionId, description, ownerId,
qacontactId, bzCclist)
else:
self.bzdbc.execute("insert into components" \
" (name, product_id, description," \
" initialowner, initialqacontact, initialcclist)" \
" values (%s, %s, %s, %s, %s, %s)" % (package,
collectionId, description, ownerId,
qacontactId, bzCclist))
self.bzdbh.commit()
if __name__ == '__main__':
opts, args = getopt.getopt(sys.argv[1:], '', ('usage', 'help'))
if len(args) > 0:
print """
Usage: bz-make-components.py
Sync package information from the package database to bugzilla.
"""
sys.exit(1)
# Initialize the connection to bugzilla
bugzilla = Bugzilla(BZSERVER, BZUSER, BZPASS)
# Non-fatal errors to alert people about
errors = []
# Get bugzilla information from the package database
ownerPage = urllib2.urlopen(PKGDBSERVER)
bugzillaData = simplejson.load(ownerPage)
ownerPage.close()
acls = bugzillaData['bugzillaAcls']
del bugzillaData
for product in acls.keys():
for pkg in acls[product]:
pkgInfo = acls[product][pkg]
### FIXME:
# Catch the exceptions and save information into email to send
print 'here we are'
print 'pkg:%s' % pkg
print 'product:%s' % product
print 'pkgInfo.owner:%s' % pkgInfo['owner']
print 'pkgInfo.summary:%s' % pkgInfo['summary']
print 'pkgInfo.qacontact:%s' % pkgInfo['qacontact']
print 'pkgInfo.cclist:%s' % pkgInfo['cclist']
sys.exit(1)
try:
bugzilla.add_edit_component(pkg, product, pkgInfo['owner'],
pkgInfo['summary'], pkgInfo['qacontact'],
pkgInfo['cclist'])
except ValueError, e:
# A username didn't have a bugzilla address
errors.append(e)
except DataChangedError, e:
# A Package or Collection was returned via xmlrpc but wasn't
# present when we tried to change it
errors.append(e)
except xmlrpclib.Error, e:
# An error occurred in the xmlrpc call. Shouldn't happen but
# we better se what it is
errors.append(e)
# Send notification of errors
if errors:
website.send_email('accounts at fedoraproject.org',
'toshio at fedoraproject.org',
'Errors while syncing bugzilla with the PackageDB',
'''
In order to make bugzilla components for Fedora-related programs, we need to have an existing bugzilla account for
the listed owner. You (%s) do not have a bugzilla account, but are listed as the owner for the following components:
%s
Please create a bugzilla account for %s immediately, because this amazingly stupid cron job will keep sending you an
e-mail every hour until you do :)
- The management
''' % ('\n'.join(str(errors)),))
sys.exit(0)
More information about the fedora-extras-commits
mailing list