- 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:
parent
b452a00bd3
commit
1ba90e11c4
1 changed files with 30 additions and 30 deletions
|
@ -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',
|
||||||
'''
|
'''
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue