- Change from taking a filename to a url to a file.

- Lowercase all cclist accounts.
- When printing dry run output, encode to ascii with 'replace'.  This could
  also be worked around by setting:
      sys.stdout = codecs.getwriter('utf-8')(sys.stdout)
This commit is contained in:
Toshio Kuratomi 2008-04-25 11:17:32 -07:00
parent b452a00bd3
commit 1ba90e11c4

View file

@ -21,16 +21,12 @@
# #
import sys import sys
import os import urllib2
import errno
import website
import crypt
import getopt import getopt
import xmlrpclib import xmlrpclib
from email.Message import Message from email.Message import Message
import smtplib import smtplib
# Set this to the production bugzilla account when we're ready to go live # 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://bugdev.devel.redhat.com/bugzilla-cvs/xmlrpc.cgi'
#BZSERVER = 'https://bugzilla.redhat.com/xmlrpc.cgi' #BZSERVER = 'https://bugzilla.redhat.com/xmlrpc.cgi'
@ -38,7 +34,7 @@ BZSERVER = 'https://bugdev.devel.redhat.com/bugzilla-cvs/xmlrpc.cgi'
BZUSER='<%= bzAdminUser %>' BZUSER='<%= bzAdminUser %>'
BZPASS='<%= bzAdminPassword %>' BZPASS='<%= bzAdminPassword %>'
DRY_RUN = False DRY_RUN = True
class Bugzilla(object): class Bugzilla(object):
def __init__(self, bzServer, username, password): def __init__(self, bzServer, username, password):
@ -49,11 +45,11 @@ class Bugzilla(object):
self.server = xmlrpclib.Server(bzServer) self.server = xmlrpclib.Server(bzServer)
def add_edit_component(self, package, collection,owner, description, def add_edit_component(self, package, collection, owner, description,
qacontact=None, cclist=None): qacontact=None, cclist=None):
'''Add or updatea component to have the values specified. '''Add or updatea component to have the values specified.
''' '''
initialCCList = cclist or list() initialCCList = [p.lower() for p in cclist] or list()
# Lookup product # Lookup product
try: try:
@ -135,11 +131,14 @@ class Bugzilla(object):
data['product'] = collection data['product'] = collection
data['component'] = product[pkgKey]['component'] data['component'] = product[pkgKey]['component']
if DRY_RUN: if DRY_RUN:
for key in data:
if isinstance(data[key], basestring):
data[key] = data[key].encode('ascii', 'replace')
print '[EDITCOMP] Changing via editComponent(%s, %s, "xxxxx")' % ( print '[EDITCOMP] Changing via editComponent(%s, %s, "xxxxx")' % (
data, self.username) data, self.username)
print '[EDITCOMP] Former values: %s|%s|%s' % ( print '[EDITCOMP] Former values: %s|%s|%s' % (
product[pkgKey]['initialowner'], product[pkgKey]['initialowner'],
product[pkgKey]['description'], product[pkgKey]['description'].encode('ascii', 'replace'),
product[pkgKey]['initialqacontact']) product[pkgKey]['initialqacontact'])
else: else:
try: try:
@ -169,6 +168,9 @@ class Bugzilla(object):
data['initialcclist'] = initialCCList data['initialcclist'] = initialCCList
if DRY_RUN: if DRY_RUN:
for key in data:
if isinstance(data[key], basestring):
data[key] = data[key].encode('ascii', 'replace')
print '[ADDCOMP] Adding new component AddComponent:(%s, %s, "xxxxx")' % ( print '[ADDCOMP] Adding new component AddComponent:(%s, %s, "xxxxx")' % (
data, self.username) data, self.username)
else: else:
@ -180,24 +182,24 @@ class Bugzilla(object):
e.args = (data, e.faultCode, e.faultString) e.args = (data, e.faultCode, e.faultString)
raise raise
def parseOwnerFile(curfile, warnings): def parseOwnerFile(url, warnings):
pkgInfo = [] pkgInfo = []
ownerFile = file(curfile, 'r') ownerFile = urllib2.urlopen(url)
while line in ownerFile: for line in ownerFile:
line = line.strip() line = unicode(line, 'utf-8').strip()
if not line or line[0] == '#': if not line or line[0] == '#':
continue continue
pieces = line.split('|') pieces = line.split('|')
try: try:
product, component, summary, owner, qa = pieces[:5] product, component, summary, owner, qa = pieces[:5]
except: except:
warnings.append('%s: Invalid line %s' % (curfile, line)) warnings.append('%s: Invalid line %s' % (url, line))
owners = owner.split(',') owners = owner.split(',')
owner = owners[0] owner = owners[0]
cclist = owners[1:] or [] cclist = owners[1:] or []
if not owner: if not owner:
warnings.append('%s: No owner in line %s' % (curfile, line)) warnings.append('%s: No owner in line %s' % (url, line))
continue continue
if len(pieces) > 5 and pieces[5].strip(): if len(pieces) > 5 and pieces[5].strip():
@ -206,7 +208,7 @@ def parseOwnerFile(curfile, warnings):
if product != 'Fedora' and not product.startswith('Fedora '): if product != 'Fedora' and not product.startswith('Fedora '):
warnings.append('%s: Invalid product %s in line %s' % warnings.append('%s: Invalid product %s in line %s' %
(curfile, product, line)) (url, product, line))
continue continue
pkgInfo.append({'product': product, 'component': component, pkgInfo.append({'product': product, 'component': component,
'owner': owner, 'summary': summary, 'qa': qa, 'cclist': cclist}) 'owner': owner, 'summary': summary, 'qa': qa, 'cclist': cclist})
@ -230,7 +232,11 @@ def send_email(fromAddress, toAddress, subject, message):
if __name__ == '__main__': if __name__ == '__main__':
opts, args = getopt.getopt(sys.argv[1:], '', ('usage', 'help')) opts, args = getopt.getopt(sys.argv[1:], '', ('usage', 'help'))
if len(args) < 1 or ('--usage','') in opts or ('--help','') in opts: if len(args) < 1 or ('--usage','') in opts or ('--help','') in opts:
print """Usage: bz-make-components.py FILENAME...""" print """Usage: bz-make-components.py URL1 [URL2]...
This script takes URLs to files in owners.list format and makes changes in
bugzilla to reflect the ownership of bugzilla products that are listed there.
"""
sys.exit(1) sys.exit(1)
# Initialize connection to bugzilla # Initialize connection to bugzilla
@ -240,24 +246,18 @@ if __name__ == '__main__':
# Iterate through the files in the argument list. Grab the owner # Iterate through the files in the argument list. Grab the owner
# information from each one and construct bugzilla information from it. # information from each one and construct bugzilla information from it.
pkgData = [] pkgData = []
for curfile in args: for url in args:
if not os.path.exists(curfile): pkgData.extend(parseOwnerFile(url, warnings))
warnings.append('%s does not exist' % curfile)
continue
pkgData.extend(parseOwnerFile(curfile, warnings))
for pkgInfo in pkgData: for pkgInfo in pkgData:
try: try:
bugzilla.add_edit_component(pkgInfo['product'], bugzilla.add_edit_component(pkgInfo['component'],
pkgInfo['component'], pkgInfo['owner'], pkgInfo['summary'], pkgInfo['product'], pkgInfo['owner'],
pkgInfo['qa'], pkgInfo['cclist']) pkgInfo['summary'], pkgInfo['qa'],
pkgInfo['cclist'])
except ValueError, e: except ValueError, e:
# A username didn't have a bugzilla address # A username didn't have a bugzilla address
warnings.append(str(e.args)) warnings.append(str(e.args))
except DataChangedError, e:
# A Package or Collection was returned via xmlrpc but wasn't
# present when we tried to change it
warnings.append(str(e.args))
except xmlrpclib.ProtocolError, e: except xmlrpclib.ProtocolError, e:
# Unrecoverable and likely means that nothing is going to # Unrecoverable and likely means that nothing is going to
# succeed. # succeed.
@ -269,7 +269,7 @@ if __name__ == '__main__':
warnings.append(str(e.args)) warnings.append(str(e.args))
if warnings: if warnings:
# print '[DEBUG]', '\n'.join(warnings) print '[DEBUG]', '\n'.join(warnings)
send_email('accounts@fedoraproject.org', 'a.badger@gmail.com', send_email('accounts@fedoraproject.org', 'a.badger@gmail.com',
'Errors while syncing bugzilla with owners.list', 'Errors while syncing bugzilla with owners.list',
''' '''