#!/usr/bin/python
# vim: fileencoding=utf8 foldmethod=marker
#{{{ License header: GPLv2+
# This file is part of cnucnu.
#
# Cnucnu 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 2 of the License, or
# (at your option) any later version.
#
# Cnucnu 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 cnucnu. If not, see .
#}}}
from bugzilla import Bugzilla
from config import Config
from helper import filter_dict
from helper import pprint
from cvs import CVS
class BugzillaReporter(object):
base_query = {'query_format': ['advanced'], 'emailreporter1': ['1'], 'emailtype1': ['exact']}
bug_status_open = ['NEW', 'ASSIGNED', 'MODIFIED', 'ON_DEV', 'ON_QA', 'VERIFIED', 'FAILS_QA', 'RELEASE_PENDING', 'POST']
bug_status_closed = ['CLOSED']
new_bug = { 'status': 'NEW',
# Using ASSIGNED returns an exception:
#
# if the account is in editbugs, fedora_bugs, fedora_contrib, setpriority
# if not, then it is silently ignored
# 'status': 'ASSIGNED',
}
def __init__(self, config):
rpc_conf = filter_dict(config, ["url", "user", "password"])
bz = Bugzilla(**rpc_conf)
self.bz = bz
if "password" in rpc_conf and rpc_conf["password"]:
self.bz.login()
self.config = config
self.base_query['product'] = config['product']
self.base_query['email1'] = config['user']
self.new_bug['product'] = config['product']
if "keywords" in config:
self.new_bug['keywords'] = config['keywords']
self.new_bug['version'] = config['version']
self.bugzilla_username = config['user']
self.cvs = CVS()
def bug_url(self, bug):
if isinstance(bug, str):
bug_id = bug
else:
bug_id = bug.bug_id
return "%s%s" % (self.config['bug url prefix'], bug_id)
def report_outdated(self, package, dry_run=True):
if package.upstream_newer:
if self.cvs.has_upstream_version(package):
print "Upstream Version found in CVS, skipping bug report: %(name)s U:%(latest_upstream)s R:%(repo_version)s" % package
return False
matching_bugs = self.get_bug(package)
# TODO: warning in case of more than one matching bug, then something is wrong
if not matching_bugs:
open = self.get_open(package)
if not open:
bug = {'component': package.name,
'summary': self.config["summary template"] % package,
'description': self.config["description template"] % package
}
bug.update(self.new_bug)
if not dry_run:
new_bug = self.bz.createbug(**bug)
status = self.config['bug status']
if status != "NEW":
change_status = self.bz._proxy.bugzilla.changeStatus(new_bug.bug_id, status, self.config['user'], "", "", False, False, 1)
print "status changed", change_status
print self.bug_url(new_bug)
else:
pprint(bug)
else:
open_bug = open[0]
summary = open_bug.summary
# summary should be '- '
# To extract the version get everything before the first space
# with split and then remove the name and '-' via slicing
bug_version = summary.split(" ")[0][len(package.name)+1:]
if bug_version != package.latest_upstream:
update = {'short_desc': self.config["summary template"] % package,
'comment': self.config["description template"] % package
}
print repr(update)
res = self.bz._update_bugs(open_bug.bug_id, update)
print res
return res
else:
for bug in matching_bugs:
print "bug already filed:%s %s" % (self.bug_url(bug), bug.bug_status)
def get_bug(self, package):
q = {'component': [package.name],
'bug_status': self.bug_status_open + self.bug_status_closed,
'short_desc': ['%(name)s-%(latest_upstream)s' % package],
'short_desc_type': ['substring']
}
q.update(self.base_query)
bugs = self.bz.query(q)
return bugs
def get_open(self, package):
q = {'component': [package.name],
'bug_status': self.bug_status_open
}
q.update(self.base_query)
return self.bz.query(q)