def encoded_filename_test(): '''A test for the fix for bug #663674''' attachid = 502352 attachname = 'Karel Kl\xc3\xad\xc4\x8d memorial test file.txt' # in utf8 bz = Bugzilla(url='https://bugzilla.redhat.com/xmlrpc.cgi') att = bz.openattachment(attachid) assert att.name.encode("utf8") == attachname
def __init__(self, bug, user=None, password=None, cache=False, nobuild=False, other_BZ=None): """ Constructor. :arg bug, the bug number on bugzilla :kwarg user, the username with which to log in in bugzilla. :kwarg password, the password associated with this account. :kwarg cache, boolean specifying whether the spec and srpm should be re-downloaded or not. :kwarg nobuild, boolean specifying whether to build or not the package. :kwarg other_BZ, url of an eventual other bugzilla system. """ Helpers.__init__(self, cache, nobuild) self.bug_num = bug self.spec_url = None self.srpm_url = None self.spec_file = None self.srpm_file = None self.log = get_logger() if other_BZ: self.bugzilla = Bugzilla(url=other_BZ + '/xmlrpc.cgi') else: self.bugzilla = Bugzilla(url=BZ_URL) self.log.info("Trying bugzilla cookies for authentication") self.user = user self.bug = self.bugzilla.getbug(self.bug_num)
def __init__(self, email, widget_id=None): self.widget_id = widget_id bugzilla = Bugzilla(url="https://bugzilla.redhat.com/xmlrpc.cgi") # pylint: disable-msg=E1101 # :E1101: Bugzilla class monkey patches itself with methods like # query. self.bugs = bugzilla.query({"product": "Fedora", "email1": email, "emailassigned_to1": True})[:5]
def submit(self): today = datetime.now().strftime('%Y-%m-%d %H:%M') bugzilla = Bugzilla(url=settings.BUGZILLA_URL) bugzilla.login(user=settings.BUGZILLA_USERNAME, password=settings.BUGZILLA_PASSWORD) message = self.cleaned_data['message'] service = self.cleaned_data['service'].name summary = '[dashboard] {0} Issue with {1}'.format(today, service) description = ("[dashboard]\n" "Date: {0}\n" "Message: {1}\n".format(today, message)) bug = bugzilla.build_createbug(product=settings.BUGZILLA_PRODUCT, component=settings.BUGZILLA_COMPONENT, summary=summary, op_sys='All', platform='All', description=description, version='unspecified', ) result = bugzilla.createbug(bug) return result.id
def update_flag(self, id, flags_status): """ Updates the flags associated with a bug report. :param idlist: :param flags: :return: """ Bugzilla.update_flags(id, flags=flags_status)
def testURLQuery(self): # This is a bugzilla 5.0 instance, which supports URL queries now query_url = ("https://bugs.gentoo.org/buglist.cgi?" "component=[CS]&product=Doc%20Translations" "&query_format=advanced&resolution=FIXED") bz = Bugzilla(url=self.url, use_creds=False) ret = bz.query(bz.url_to_query(query_url)) self.assertTrue(len(ret) > 0)
def request(self, extra_fields={}): if not self._request: self._request = Bugzilla(url=None).url_to_query(self.url) self._request.update(extra_fields) self._request.update({ 'include_fields': Constants.INCLUDE_FIELDS, }) return self._request
def testURLQuery(self): # This is a bugzilla 5.0 instance, which supports URL queries now query_url = ("https://bugs.gentoo.org/buglist.cgi?" "component=[CS]&product=Doc%20Translations" "&query_format=advanced&resolution=FIXED") bz = Bugzilla(url=self.url, use_creds=False) ret = bz.query(bz.url_to_query(query_url)) assert len(ret) > 0
def _get_bugzilla_history(email, all_comments=False): """ Query the bugzilla for all bugs to which the provided email is either assigned or cc'ed. Then for each bug found, print the latest comment from this user (if any). :arg email, the email address used in the bugzilla and for which we are searching for activities. :arg all_comments, boolean to display all the comments made by this person on the bugzilla. """ from bugzilla import Bugzilla bzclient = Bugzilla(url='https://bugzilla.redhat.com/xmlrpc.cgi') log.debug('Querying bugzilla for email: {0}'.format(email)) print("Bugzilla activity") bugbz = bzclient.query({ 'emailtype1': 'substring', 'emailcc1': True, 'emailassigned_to1': True, 'query_format': 'advanced', 'order': 'Last Change', 'bug_status': ['ASSIGNED', 'NEW', 'NEEDINFO'], 'email1': email }) print(' {0} bugs assigned, cc or on which {1} commented'.format( len(bugbz), email)) # Retrieve the information about this user user = bzclient.getuser(email) bugbz.reverse() print('Last comment on the most recent ticket on bugzilla:') ids = [bug.bug_id for bug in bugbz] for bug in bzclient.getbugs(ids): log.debug(bug.bug_id) user_coms = [ com for com in bug.longdescs if com['creator_id'] == user.userid ] if user_coms: last_com = user_coms[-1] converted = datetime.datetime.strptime(last_com['time'].value, "%Y%m%dT%H:%M:%S") print( u' #{0} {1} {2}'.format( bug.bug_id, converted.strftime('%Y-%m-%d'), last_com['creator'] ) ) else: continue if not all_comments: break
def get_component_info(self, product, component, force_refresh=False): """ Get details for a single component. :param product: :param component: :param force_refresh: :return: """ Bugzilla.getcomponentdetails(product, component, force_refresh)
def attach_file(self, idlist, attachment, description, **kwargs): """ Attach a file to the given bug IDs. :param idlist: :param attachment: :param description: :param kwargs: :return: Returns the ID of the attachment. """ Bugzilla.attachfile(idlist, attachfile=attachment, description=description, **kwargs)
def testURLQuery(self): # This instance is old and doesn't support URL queries, we are # just verifying our extra error message report query_url = ("https://bugzilla.gnome.org/buglist.cgi?" "bug_status=RESOLVED&order=Importance&product=accerciser" "&query_format=advanced&resolution=NOTABUG") bz = Bugzilla(url=self.url, use_creds=False) try: bz.query(bz.url_to_query(query_url)) except BugzillaError as e: assert "derived from bugzilla" in str(e)
def get_security_bugs(): bz = Bugzilla(url='https://bugzilla.redhat.com/xmlrpc.cgi') query_data = { 'keywords': 'SecurityTracking', 'keywords_type': 'allwords', # 'component': 'cacti', # 'severity': 'high', 'status': VALID_STATUSES, } bugs = bz.query(query_data) return bugs
def __init__(self, _id, config): self._bug = None self.config = config self.id = _id self.url = config.get('bz_url') if "bugzilla.redhat.com" in self.url: self.bugzilla = RHBugzilla(url=self.url) else: self.bugzilla = Bugzilla(url=self.url)
def __init__(self, email, widget_id=None): self.widget_id = widget_id bugzilla = Bugzilla(url='https://bugzilla.redhat.com/xmlrpc.cgi') # pylint: disable-msg=E1101 # :E1101: Bugzilla class monkey patches itself with methods like # query. self.bugs = bugzilla.query({ 'product': 'Fedora', 'email1': email, 'emailassigned_to1': True })[:5]
class Query: def __init__(self, name, configuration): self.name = name self.reserved_keywords = ['documentation', 'url', 'extra', 'dfg'] self._request = None self.bz_query_url = None for prop in self.reserved_keywords: setattr(self, prop, None) for (prop, value) in configuration: if prop in self.reserved_keywords: if prop is 'url': self._check_url(prop) setattr(self, prop, value) def __str__(self): return '{}'.format(self._request) def request(self, extra_fields={}): if not self._request: self._request = Bugzilla(url=None).url_to_query(self.url) self._request.update(extra_fields) self._request.update({ 'include_fields': Constants.INCLUDE_FIELDS, }) return self._request @classmethod def from_bz(cls, bz, documentation="Search specific bzs"): # https://bugzilla.redhat.com/report.cgi?x_axis_field=target_release&y_axis_field=bug_status&z_axis_field=&no_redirect=1&query_format=report-table&short_desc_type=allwordssubstr&short_desc=&classification=Red+Hat&product=Red+Hat+OpenStack&bug_status=NEW&bug_status=ASSIGNED&bug_status=POST&bug_status=MODIFIED&bug_status=ON_DEV&bug_status=ON_QA&bug_status=VERIFIED&bug_status=RELEASE_PENDING&bug_status=CLOSED&longdesc_type=allwordssubstr&longdesc=&bug_file_loc_type=allwordssubstr&bug_file_loc=&status_whiteboard_type=allwordssubstr&status_whiteboard=&keywords_type=allwords&keywords=&deadlinefrom=&deadlineto=&bug_id=&bug_id_type=anyexact&votes=&votes_type=greaterthaneq&emailtype1=substring&email1=&emailtype2=substring&email2=&emailtype3=substring&email3=&chfieldvalue=&chfieldfrom=&chfieldto=Now&j_top=OR&f1=bug_id&o1=equals&v1=1451275&f2=bug_id&o2=equals&v2=1461531&f3=bug_id&o3=equals&v3=1472340&f4=bug_id&o4=equals&v4=1472343&f5=bug_id&o5=equals&v5=1472347&format=table&action=wrap # https://bugzilla.redhat.com/buglist.cgi?action=wrap&bug_status=NEW&bug_status=ASSIGNED&bug_status=POST&bug_status=MODIFIED&bug_status=ON_DEV&bug_status=ON_QA&bug_status=VERIFIED&bug_status=RELEASE_PENDING&bug_status=CLOSED&classification=Red%20Hat&f1=OP&f2=bug_id&f3=bug_id&f4=bug_id&f5=bug_id&f6=bug_id&f7=CP&j1=OR&list_id=7602378&o2=equals&o3=equals&o4=equals&o5=equals&o6=equals&product=Red%20Hat%20OpenStack&v2=1451275&v3=1461531&v4=1472340&v5=1472343&v6=1472347 bzs = [] if type(bz) is not list and type(bz) is not tuple: bzs = list([bz]) else: bzs = list(bz) query_str = 'https://bugzilla.redhat.com/buglist.cgi?action=wrap&bug_status=NEW&bug_status=ASSIGNED&bug_status=POST&bug_status=MODIFIED&bug_status=ON_DEV&bug_status=ON_QA&bug_status=VERIFIED&bug_status=RELEASE_PENDING&bug_status=CLOSED&f1=OP&f7=CP&j1=OR' cpt = 2 for bbz in bzs: query_str += "&f{0}=bug_id&o{0}=equals&v{0}={1}".format(cpt, bbz) cpt += 1 query = cls('id', [('url', query_str), ('documentation', documentation)]) setattr(query, 'bz_query_url', query_str) return query @staticmethod def _check_url(url): if not url.find('/buglist.cgi'): # TODO: make a class for exception. raise Exception("You must pass a buglist.cgi request, not {}".format(url))
def check_bugzilla(url): global bz if not url.startswith("https://bugzilla.novell.com"): return try: if bz == None: bz = Bugzilla(url="https://bugzilla.novell.com/xmlrpc.cgi", cookiefile=None) bug_id = url[url.find("id=")+3::] bug = bz._getbug(int(bug_id)) bug_desc = bug['short_desc'] except Exception as e: bug_desc = e print_item(4*" ", "(%s)" % bug_desc)
def _get_bz(url=pkgdb2client.BZ_URL, insecure=False): ''' Return a bugzilla object. ''' global BZCLIENT if not BZCLIENT or BZCLIENT.url != url: BZCLIENT = Bugzilla(url=url) BZCLIENT._sslverify = not insecure try: BZCLIENT.logged_in except xmlrpclib.Error: bz_login() return BZCLIENT
def _get_bz(url=RH_BZ_API, insecure=False): ''' Return a bugzilla object. ''' global BZCLIENT if not BZCLIENT: BZCLIENT = Bugzilla(url=url) elif BZCLIENT.url != url: BZCLIENT.url = url BZCLIENT._sslverify = not insecure try: BZCLIENT.logged_in except xmlrpclib.Error: bz_login() return BZCLIENT
def testVersion(self): # bugzilla.mozilla.org returns version values in YYYY-MM-DD # format, so just try to confirm that bz = Bugzilla("bugzilla.mozilla.org", use_creds=False) self.assertEquals(bz.__class__, Bugzilla) self.assertTrue(bz.bz_ver_major >= 2016) self.assertTrue(bz.bz_ver_minor in range(1, 13))
def _testBZVersion(self): bz = Bugzilla(self.url, use_creds=False) assert bz.__class__ == self.bzclass if tests.CLICONFIG.REDHAT_URL: return assert bz.bz_ver_major == self.bzversion[0] assert bz.bz_ver_minor == self.bzversion[1]
def _testBZVersion(self): bz = Bugzilla(self.url, use_creds=False) self.assertEquals(bz.__class__, self.bzclass) if tests.REDHAT_URL: print("BZ version=%s.%s" % (bz.bz_ver_major, bz.bz_ver_minor)) else: self.assertEquals(bz.bz_ver_major, self.bzversion[0]) self.assertEquals(bz.bz_ver_minor, self.bzversion[1])
def get_bugzilla(parse): print "INFO - Connecting to bugzilla" try: bzusername = parse.get("bugzilla", "username") bzpassword = parse.get("bugzilla", "password") bzrpcurl = parse.get("bugzilla", "rpcurl") return Bugzilla(url=bzrpcurl, user=bzusername, password=bzpassword) except Exception as details: print "Error - get bugzilla connection failed: %s" % details
def clicomm(self, argstr, expectexc=False, bz=None): comm = "bugzilla " + argstr if not bz: bz = Bugzilla(url=self.url, use_creds=False) if expectexc: self.assertRaises(Exception, tests.clicomm, comm, bz) else: return tests.clicomm(comm, bz)
def __init__(self, bug, user=None, password=None): """ Constructor. :arg bug, the bug number on bugzilla :kwarg user, the username with which to log in in bugzilla. :kwarg password, the password associated with this account. """ AbstractBug.__init__(self) self.check_options() self.bug_num = bug bz_url = os.path.join(Settings.current_bz_url, 'xmlrpc.cgi') self.bugzilla = Bugzilla(url=bz_url) self.log.info("Trying bugzilla cookies for authentication") self.user = user self.bug = self.bugzilla.getbug(self.bug_num) if Settings.login: self.login(Settings.user) if Settings.assign: self.assign_bug()
def create_case(self, **kwargs): """ Create initial bug. :param kwargs: product (str), component (str), summary (str), version (str), description (str) :return: Returns a new Bug object. """ return Bugzilla.createbug(**kwargs)
def __init__(self, bug, user=None, password=None, cache=False, nobuild=False): Helpers.__init__(self, cache, nobuild) self.bug_num = bug self.spec_url = None self.srpm_url = None self.spec_file = None self.srpm_file = None self.bugzilla = Bugzilla(url=BZ_URL) self.is_login = False if user and password: rc = self.bugzilla.login(user=user, password=password) if rc > 0: self.is_login = True self.user = user self.bug = self.bugzilla.getbug(self.bug_num) self.log = get_logger()
def __init__(self, bug, user=None, password=None): """ Constructor. :arg bug, the bug number on bugzilla :kwarg user, the username with which to log in in bugzilla. :kwarg password, the password associated with this account. be re-downloaded or not. """ Helpers.__init__(self) self.bug_num = bug self.spec_url = None self.srpm_url = None self.spec_file = None self.srpm_file = None self.log = get_logger() if Settings.other_bz: self.bugzilla = Bugzilla(url=Settings.other_bz + '/xmlrpc.cgi') else: self.bugzilla = Bugzilla(url=BZ_URL) self.log.info("Trying bugzilla cookies for authentication") self.user = user self.bug = self.bugzilla.getbug(self.bug_num)
def testVersion(self): # bugzilla.mozilla.org returns version values in YYYY-MM-DD # format, so just try to confirm that try: bz = Bugzilla("bugzilla.mozilla.org", use_creds=False) assert bz.__class__ == Bugzilla assert bz.bz_ver_major >= 2016 assert bz.bz_ver_minor in range(1, 13) except Exception as e: # travis environment throws SSL errors here # https://travis-ci.org/python-bugzilla/python-bugzilla/builds/304713566 if "EOF occurred" not in str(e): raise self.skipTest("travis environment SSL error hit: %s" % str(e))
def get_bugs(package_name): bugzilla_client = Bugzilla(url=URL, cookiefile=None, tokenfile=None) bugs = _open_bugs(bugzilla_client, package_name) blocker_bugs_results = blocker_bugs(bugs) results = { 'bugs': [], 'open_bugs': len(bugs), 'blocker_bugs': len(blocker_bugs_results), } # Generate the URL for the blocker bugs url_args = [ ('classification', 'Fedora'), ('query_format', 'advanced'), ('component', package_name), ] for product in PRODUCTS: url_args.append(('product', product)) for status in OPEN_BUG_STATUS: url_args.append(('bug_status', status)) results['open_bugs_url'] = "https://bugzilla.redhat.com/buglist.cgi?" + \ urllib.parse.urlencode(url_args) url_args += [ ('f1', 'blocked'), ('o1', 'anywordssubstr'), ('v1', ' '.join(map(str, blocker_bugs_results))), ] results['blocker_bugs_url'] = \ "https://bugzilla.redhat.com/buglist.cgi?" + \ urllib.parse.urlencode(url_args) for fb in bugs: bug_version = fb.version if isinstance(bug_version, (list, tuple)): bug_version = bug_version[0] results['bugs'].append({ 'id': fb.bug_id, 'status': fb.bug_status.title(), 'summary': fb.summary, 'release': '{} {}'.format(fb.product, bug_version), 'version_sort': _version_to_int(fb.version), 'status_sort': _status_to_index(fb.bug_status), }) return results
def selftest(data, user='', password=''): print "Using bugzilla at " + data['url'] bz = Bugzilla(url=data['url']) print "Bugzilla class: %s" % bz.__class__ if not bz.logged_in: if user and password: bz.login(user, password) if bz.logged_in: print "Logged in to bugzilla OK." else: print "Not logged in - create a .bugzillarc or provide user/password" # FIXME: only run some tests if .logged_in print "Reading product list" prod = bz.getproducts() prodlist = [p['name'] for p in prod] print "Products found: %s, %s, %s...(%i more)" % \ (prodlist[0],prodlist[1],prodlist[2],len(prodlist)-3) p = data['query']['product'] assert p in prodlist print "Getting component list for %s" % p comp = bz.getcomponents(p) print "%i components found" % len(comp) print "Reading public bug (#%i)" % data['public_bug'] print bz.getbugsimple(data['public_bug']) print print "Reading private bug (#%i)" % data['private_bug'] try: print bz.getbugsimple(data['private_bug']) except xmlrpclib.Fault, e: if 'NotPermitted' in e.faultString: print "Failed: Not authorized." else: print "Failed: Unknown XMLRPC error: %s" % e
def __init__(self,bug,user=None,password=None, cache=False, nobuild=False): Helpers.__init__(self,cache, nobuild) self.bug_num = bug self.spec_url = None self.srpm_url = None self.spec_file = None self.srpm_file = None self.bugzilla = Bugzilla(url=BZ_URL) self.is_login = False if user and password: rc = self.bugzilla.login(user=user, password=password) if rc > 0: self.is_login = True self.user = user self.bug = self.bugzilla.getbug(self.bug_num) self.log = get_logger()
def testFaults(self): # Test special error wrappers in bugzilla/_cli.py bzinstance = Bugzilla(self.url, use_creds=False) out = tests.clicomm("bugzilla query --field=IDONTEXIST=FOO", bzinstance, expectfail=True) assert "Server error:" in out out = tests.clicomm("bugzilla " "--bugzilla https://example.com/xmlrpc.cgi " "query --field=IDONTEXIST=FOO", None, expectfail=True) assert "Connection lost/failed" in out out = tests.clicomm("bugzilla " "--bugzilla https://expired.badssl.com/ " "query --bug_id 1234", None, expectfail=True) assert "trust the remote server" in out assert "--nosslverify" in out
def selftest(data,user='',password=''): print "Using bugzilla at " + data['url'] bz = Bugzilla(url=data['url']) print "Bugzilla class: %s" % bz.__class__ if not bz.logged_in: if user and password: bz.login(user,password) if bz.logged_in: print "Logged in to bugzilla OK." else: print "Not logged in - create a .bugzillarc or provide user/password" # FIXME: only run some tests if .logged_in print "Reading product list" prod = bz.getproducts() prodlist = [p['name'] for p in prod] print "Products found: %s, %s, %s...(%i more)" % \ (prodlist[0],prodlist[1],prodlist[2],len(prodlist)-3) p = data['query']['product'] assert p in prodlist print "Getting component list for %s" % p comp = bz.getcomponents(p) print "%i components found" % len(comp) print "Reading public bug (#%i)" % data['public_bug'] print bz.getbugsimple(data['public_bug']) print print "Reading private bug (#%i)" % data['private_bug'] try: print bz.getbugsimple(data['private_bug']) except xmlrpclib.Fault, e: if 'NotPermitted' in e.faultString: print "Failed: Not authorized." else: print "Failed: Unknown XMLRPC error: %s" % e
def get_bz(): # pragma: no cover '''Retrieve a connection to bugzilla :raises xmlrpclib.ProtocolError: If we're unable to contact bugzilla ''' global _BUGZILLA if _BUGZILLA: # pragma: no cover return _BUGZILLA # Get a connection to bugzilla bz_server = pkgdb2.APP.config['PKGDB2_BUGZILLA_URL'] if not bz_server: raise pkgdb2.lib.PkgdbException('No PKGDB2_BUGZILLA_URL configured') bz_url = bz_server + '/xmlrpc.cgi' bz_user = pkgdb2.APP.config['PKGDB2_BUGZILLA_USER'] bz_pass = pkgdb2.APP.config['PKGDB2_BUGZILLA_PASSWORD'] _BUGZILLA = Bugzilla(url=bz_url, user=bz_user, password=bz_pass, cookiefile=None, tokenfile=None) return _BUGZILLA
def _bugzilla(self): return Bugzilla(url=self._base_url, cookiefile=None, tokenfile=None)
def main(): parser = argparse.ArgumentParser(description='pull all bugs from a ' 'launchpad project') args = parser.parse_args() # launchpad = Launchpad.login_anonymously('OpenStack Infra Bugday', # 'production', # LPCACHEDIR) # project = launchpad.projects[LPPROJECT] bz = Bugzilla(url=BZURL) counter = 0 nova_status = "Unknown" f = open('bugs-refresh.json', 'w') f.write('{"date": "%s", "bugs": [' % datetime.datetime.now()) # for task in project.searchTasks(status=LPSTATUS, importance=LPIMPORTANCE, # omit_duplicates=True, # order_by='-importance'): bzq = bz.build_query(product=LPPROJECT, status=BZSTATUS) #bzq = bz.build_query(bug_id='1154635') bugs = bz.query(bzq) for task in bugs: #if counter == 300: # break # bug = launchpad.load(task.bug_link) # # nova_status = 'Unknown' # nova_owner = 'Unknown' # # for task in bug.bug_tasks: # if task.bug_target_name == LPPROJECT: # nova_status = task.status # nova_owner = task.assignee # break try: if counter != 0: bug_data = ',' else: bug_data = u"" title = task.summary.replace('"', "'") title = title.replace("\n", "") title = title.replace("\t", "") bug_data += ('{"index": %d, "id": %d, "importance": "%s", ' '"status": "%s", ' '"owner": "%s", ' '"title": "%s", ' '"link": "%s"' % ( counter, task.id, getBugPriority(task), getBugStatus(task), task.assigned_to, title, task.weburl)) except (TypeError, UnicodeEncodeError): # TODO: fix this print 'Error on bug %d', task.id counter += 1 continue age = delta(datetime.datetime.strptime("%s" % task.creation_time, "%Y%m%dT%H:%M:%S")) updated = delta(datetime.datetime.strptime("%s" % task.last_change_time, "%Y%m%dT%H:%M:%S")) stale = False if updated > 30 and age > 30: if task.status == 'ASSIGNED': stale = True bug_data += (',"age": %d, "update": %d, "stale": %d, ' '"never_touched": %d' % (age, updated, 1 if stale else 0, 1 if len(task.comments) == 1 else 0)) i = 0 bug_data += ( ',"projects": [') bug_data += '{"target": "%s", "status": "%s"}' % (task.target_release, task.status) bug_data += ('] ,"reviews": [') i = 0 for review in get_reviews_from_bug(task): review_status = get_review_status(review) if i != 0: bug_data += (",") i += 1 review_status = review_status.replace("\n", "") bug_data += ('{"review": ' '"%s/%s",' '"status": "%s"}' % (GERRIT_URL, review, review_status)) bug_data += (']}') try: if counter == 0: json.loads(bug_data) else: json.loads(bug_data[1:]) f.write(bug_data) except (ValueError, UnicodeEncodeError), e: print e, '[Bug: %s]' % task.id counter += 1
parser = argparse.ArgumentParser( description='check that a candlepin PR references the correct BZ') parser.add_argument('pr', help='the pr number to examine') args = parser.parse_args() # fetch pr pr = requests.get( 'https://api.github.com/repos/candlepin/candlepin/pulls/{pr}'.format( pr=args.pr), headers={ 'Authorization': 'token {}'.format(github_token) }).json() target = pr['base']['ref'] bz = Bugzilla(bugzilla_url, user=bugzilla_user, password=bugzilla_password) master_version = None def fetch_master_version(): global master_version if master_version: return master_version spec_file = requests.get( 'https://raw.githubusercontent.com/candlepin/candlepin/master/candlepin.spec.tmpl' ).text for line in spec_file.split('\n'): if line.startswith('Version:'): match = re.search('^Version: (\d+\.\d+)\.\d+$', line) version = match.group(1)
#!/usr/bin/env python from bugzilla import Bugzilla import xmlrpclib bz = Bugzilla(url='https://bugzilla.redhat.com/xmlrpc.cgi') if not bz.logged_in: bz.login('username','password') if bz.logged_in: print "Logged in to Bugzilla OK.\n" comps = bz.getcomponents('Red Hat Enterprise Linux 5') for comp in comps: print comp
class ReviewBug(Helpers): def __init__(self,bug,user=None,password=None, cache=False, nobuild=False): Helpers.__init__(self,cache, nobuild) self.bug_num = bug self.spec_url = None self.srpm_url = None self.spec_file = None self.srpm_file = None self.bugzilla = Bugzilla(url=BZ_URL) self.is_login = False if user and password: rc = self.bugzilla.login(user=user, password=password) if rc > 0: self.is_login = True self.user = user self.bug = self.bugzilla.getbug(self.bug_num) self.log = get_logger() def login(self, user, password): if self.bugzilla.login(user=user, password=password) > 0: self.is_login = True self.user = user else: self.is_login = False return self.is_login def find_urls(self): found = True if self.bug.longdescs: for c in self.bug.longdescs: body = c['body'] #self.log.debug(body) urls = re.findall('http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+~]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', body) if urls: for url in urls: if url.endswith(".spec"): self.spec_url = url elif url.endswith(".src.rpm"): self.srpm_url = url if not self.spec_url: self.log.info('not spec file URL found in bug #%s' % self.bug_num) found = False if not self.srpm_url: self.log.info('not SRPM file URL found in bug #%s' % self.bug_num) found = False return found def assign_bug(self): if self.is_login: self.bug.setstatus('ASSIGNED') self.bug.setassignee(assigned_to=self.user) self.bug.addcomment('I will review this package') flags = {'fedora-review' : '?'} self.bug.updateflags(flags) self.bug.addcc([self.user]) else: self.log.info("You need to login before assigning a bug") def add_comment(self,comment): if self.is_login: self.bug.addcomment(comment) else: self.log.info("You need to is_login before commenting on a bug") def add_comment_from_file(self,fname): fd = open(fname,"r") lines = fd.readlines() fd.close self.add_comment("".join(lines)) def download_files(self): if not self.cache: self.log.info('Downloading .spec and .srpm files') found = True if not self.spec_url or not self.srpm_url: found = self.find_urls() if found and self.spec_url and self.srpm_url: self.spec_file = self._get_file(self.spec_url) self.srpm_file = self._get_file(self.srpm_url) if self.spec_file and self.srpm_file: return True return False
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." url = "https://bugzilla.redhat.com/xmlrpc.cgi" query_dict = { "product": "Fedora", "component": "Package Review", "chfieldfrom": str(start), "field0-0-0": "flagtypes.name", "type0-0-0": "equals" } bz = Bugzilla(url=url, user=username, password=passwd) if verbose: print "Getting all package review bugs (be patient, this may take a while) ...." bug_list_query = {} flag = None if report == "new": flag = "new" bug_list_query = {"bug_status": "NEW"} elif report == "rev-com": flag = "fedora-review+" bug_list_query = {"value0-0-0": "fedora-review+"} elif report == "rev-incom": flag = "fedora-review?" bug_list_query = {"value0-0-0": "fedora-review?"}
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." url = "https://bugzilla.redhat.com/xmlrpc.cgi" query_dict = {"product": "Fedora", "component": "Package Review", "chfieldfrom": str(start), "field0-0-0": "flagtypes.name", "type0-0-0": "equals"} bz = Bugzilla(url=url, user=username, password=passwd, cookiefile=None, tokenfile=None) if verbose: print "Getting all package review bugs (be patient, this may take a while) ...." bug_list_query = {} flag = None if report == "new": flag = "new" bug_list_query = {"bug_status": "NEW"} elif report == "rev-com": flag = "fedora-review+" bug_list_query = {"value0-0-0": "fedora-review+"} elif report == "rev-incom": flag = "fedora-review?" bug_list_query = {"value0-0-0": "fedora-review?"}
if __name__ == "__main__": from bugzilla import Bugzilla print "Start work" test = Bugzilla("https://bugzilla.eng.vmware.com/xmlrpc.cgi") print test.get("1284089")
class BugzillaBackend(object): def __init__(self, _id, config): self._bug = None self.config = config self.id = _id self.url = config.get('bz_url') if "bugzilla.redhat.com" in self.url: self.bugzilla = RHBugzilla(url=self.url) else: self.bugzilla = Bugzilla(url=self.url) def ensure_login(func): def wrapper(self): user = self.config.get('user') password = self.config.get('password') if (user and password) and not self.bugzilla.logged_in: self.bugzilla.login(user, password) return func(self) return wrapper @property @ensure_login def bug(self): if not self._bug: self._bug = self.bugzilla.getbug(self.id) return self._bug @classmethod def on_take(cls, config, **kwargs): bugz = cls(kwargs.get("bug"), config) bug = bugz.bug.__dict__ if bug: with open('.bugzilla.json', 'wab') as f: f.write(dumps(bug, ensure_ascii=True, indent=4)) @classmethod def on_update(cls, config, **kwargs): def update_bug(bug): bugz = cls(bug, config) bug = bugz.bug.__dict__ if bug: with open('.bugzilla.json', 'wab') as f: f.write(dumps(bug, ensure_ascii=True, indent=4)) if kwargs.get("bug"): return update_bug(kwargs.get("bug")) for sub in os.listdir("./"): bugdir = os.path.join("./", sub) if not os.path.exists(os.path.join(bugdir, '.bugzilla.json')): continue update_bug(sub.lstrip(config.get("prefix", ""))) @classmethod def on_show(cls, config, **kwargs): if os.path.exists(".bugzilla.json"): with open(".bugzilla.json", "rb") as f: summary = loads(f.read()) print colored("Bug Title: ", 'green') + summary["summary"] print "\tStatus: %s" % summary["status"] print "\t%s comments" % len(summary["comments"]) # Check if conf.args has attr so we can reuse it for listing if hasattr(conf.args, "verbose") and conf.args.verbose: for idx, comment in enumerate(summary["comments"]): print colored("\tComment: %s" % (idx + 1), 'yellow') header = "\tAuthor: %s, Private: %s, Date %s" % (comment["author"], comment["is_private"], comment["time"]) print colored(header, 'yellow') print "\t%s" % comment["text"].replace("\n", "\n\t") print "\t" on_list = on_show
class BugzillaBug(AbstractBug): """ This class handles interaction with bugzilla using xmlrpc. """ def __init__(self, bug, user=None, password=None): """ Constructor. :arg bug, the bug number on bugzilla :kwarg user, the username with which to log in in bugzilla. :kwarg password, the password associated with this account. """ AbstractBug.__init__(self) self.check_options() self.bug_num = bug bz_url = os.path.join(Settings.current_bz_url, 'xmlrpc.cgi') self.bugzilla = Bugzilla(url=bz_url) self.log.info("Trying bugzilla cookies for authentication") self.user = user self.bug = self.bugzilla.getbug(self.bug_num) if Settings.login: self.login(Settings.user) if Settings.assign: self.assign_bug() def login(self, user, password=None): """ Handles the login of the user into bugzilla. Will ask for password on the commandline unless it's provided as argument. :arg user, the bugzilla username. :arg password, bugzilla password. """ if not user: raise SettingsError('--user required for --login') if not password: password=getpass.getpass() ret = self.bugzilla.login(user=user, password=password) if ret: self.log.info("You are logged in to bugzilla. " "Credential cookies cached for future.") else: raise SettingsError("Can't login (bad password?)") self.user = user return True def _find_urls(self): """ Reads the page on bugzilla, search for all urls and extract the last urls for the spec and the srpm. """ urls = [] if self.bug.longdescs: for cat in self.bug.longdescs: body = cat['body'] # workaround for bugzilla/xmlrpc bug. When comment # text is pure number it converts to number type (duh) if type(body) != str and type(body) != unicode: continue urls.extend(re.findall('(?:ht|f)tp[s]?://' '(?:[a-zA-Z]|[0-9]|[$-_@.&+~]|[!*\(\),]|' '(?:%[0-9a-fA-F~\.][0-9a-fA-F]))+', body)) return urls def find_spec_url(self): urls = self._find_urls() urls = filter(lambda u: '.spec' in u, urls) if len(urls) == 0: raise BugException ( 'No spec file URL found in bug #%s' % self.bug_num) url = urls[-1] self.spec_url = url def find_srpm_url(self): urls = self._find_urls() urls = filter(lambda u: '.src.rpm' in u, urls) if len(urls) == 0: raise BugException ( 'No srpm file URL found in bug #%s' % self.bug_num) url = urls[-1] self.srpm_url = url def get_location(self): return Settings.bug def get_dirname(self): ''' Return dirname to be used for this bug. ''' if self.get_name() != '?': return self.bug_num + '-' + self.get_name() else: return self.bug_num def check_options(self): AbstractBug.do_check_options(self, '--bug', ['prebuilt']) def assign_bug(self): """ Assign the bug to the reviewer. """ try: self.bug.setstatus('ASSIGNED') self.bug.setassignee(assigned_to=self.user) self.bug.addcomment('I will review this package') flags = {'fedora-review': '?'} self.bug.updateflags(flags) self.bug.addcc([self.user]) except xmlrpclib.Fault, e: self.handle_xmlrpc_err(e) self.log.error("Some parts of bug assignment " "failed. Please check manually") except ValueError, e: self.log.error("Invalid bugzilla values: %s" % e) self.log.error("Some parts of bug assignment " "failed. Please check manually")
import pprint as pprint_module pp = pprint_module.PrettyPrinter(indent=4) pprint = pp.pprint from optparse import OptionParser parser = OptionParser() parser.add_option("-u", "--username", dest="username", help="bugzilla username") (options, args) = parser.parse_args() from bugzilla import Bugzilla bz = Bugzilla(url="https://bugzilla.redhat.com/xmlrpc.cgi") qs = {'product': ['Fedora'], 'query_format': ['advanced'], 'bug_status': ['NEW'], 'emailreporter1': ['1'], 'emailtype1': ['exact'], 'email1': ['*****@*****.**']} qs = {'product': ['Fedora'], 'query_format': ['advanced'], 'bug_status': ['ASSIGNED'], 'emailreporter1': ['1'], 'emailtype1': ['exact'], 'email1': ['*****@*****.**']} bugs = bz.query(qs) pprint(bugs) username = options.username if not username: username = raw_input("Username: ") bz.login(user=username, password=getpass.getpass()) # :TODO: # Maybe all bugs could be changed somehow like this: #
class ReviewBug(Helpers): """ This class handles interaction with bugzilla. """ def __init__(self, bug, user=None, password=None): """ Constructor. :arg bug, the bug number on bugzilla :kwarg user, the username with which to log in in bugzilla. :kwarg password, the password associated with this account. be re-downloaded or not. """ Helpers.__init__(self) self.bug_num = bug self.spec_url = None self.srpm_url = None self.spec_file = None self.srpm_file = None self.log = get_logger() if Settings.other_bz: self.bugzilla = Bugzilla(url=Settings.other_bz + '/xmlrpc.cgi') else: self.bugzilla = Bugzilla(url=BZ_URL) self.log.info("Trying bugzilla cookies for authentication") self.user = user self.bug = self.bugzilla.getbug(self.bug_num) def login(self, user): """ Handles the login of the user into bugzilla. Will ask for password on the commandline :arg user, the bugzilla username. """ ret = self.bugzilla.login(user=user, password=getpass.getpass()) if ret > 0: self.log.info("You are logged in to bugzilla. " "Credential cookies cached for future.") self.user = user return True def find_urls(self): """ Reads the page on bugzilla, search for all urls and extract the last urls for the spec and the srpm. """ found = True if self.bug.longdescs: for cat in self.bug.longdescs: body = cat['body'] # workaround for bugzilla/xmlrpc bug. When comment # text is pure number it converts to number type (duh) if type(body) != str and type(body) != unicode: continue urls = re.findall('(?:ht|f)tp[s]?://(?:[a-zA-Z]|[0-9]|\ [$-_@.&+~]|[!*\(\),]|(?:%[0-9a-fA-F~\.][0-9a-fA-F]))+', body) if urls: for url in urls: if ".spec" in url: self.spec_url = url elif ".src.rpm" in url: self.srpm_url = url if not self.spec_url: self.log.info('no spec file URL found in bug #%s' % self.bug_num) found = False if not self.srpm_url: self.log.info('no SRPM file URL found in bug #%s' % self.bug_num) found = False return found def assign_bug(self): """ Assign the bug to the reviewer. """ try: self.bug.setstatus('ASSIGNED') self.bug.setassignee(assigned_to=self.user) self.bug.addcomment('I will review this package') flags = {'fedora-review': '?'} self.bug.updateflags(flags) self.bug.addcc([self.user]) except xmlrpclib.Fault, e: self.handle_xmlrpc_err(e) self.log.error("Some parts of bug assignment " "failed. Please check manually") except ValueError, e: self.log.error("Invalid bugzilla values: %s" % e) self.log.error("Some parts of bug assignment " "failed. Please check manually")
class BugzillaBackend(object): def __init__(self, _id, config): self._bug = None self.config = config self.id = _id self.url = config.get('bz_url') if "bugzilla.redhat.com" in self.url: self.bugzilla = RHBugzilla(url=self.url) else: self.bugzilla = Bugzilla(url=self.url) def ensure_login(func): def wrapper(self, *args, **kwargs): user = self.config.get('bz_user') password = self.config.get('bz_password') if (user and password) and not self.bugzilla.logged_in: self.bugzilla.login(user, password) return func(self, *args, **kwargs) return wrapper @property @ensure_login def bug(self): if not self._bug: self._bug = self.bugzilla.getbug(self.id) return self._bug @ensure_login def search(self, query): q = self.config.get("bz_query", {}).copy() q.update(query) for k, v in q.items(): if isinstance(v, basestring) and "," in v: q[k] = v.split(",") return self.bugzilla.query(q) @classmethod def on_search(cls, config, query, **kwargs): bugz = cls(None, config) results = bugz.search(query) headers = [ 'ID', 'Component', 'Status', 'Summary', 'Assignee'] table = prettytable.PrettyTable(headers, header=False, border=False) for rst in results: bug = rst.__dict__ table.add_row([ bug["id"], colored(bug["component"], "green"), colored(bug["status"], "red"), bug["summary"], bug["assigned_to"], ]) print table.get_string() @classmethod def on_take(cls, config, **kwargs): bugz = cls(kwargs.get("bug"), config) bug = bugz.bug.__dict__ if bug: with open('.bugzilla.json', 'wab') as f: f.write(dumps(bug, ensure_ascii=True, indent=4)) @classmethod def on_update(cls, config, **kwargs): def update_bug(bug): bugz = cls(bug, config) bug = bugz.bug.__dict__ if bug: with open('.bugzilla.json', 'wab') as f: f.write(dumps(bug, ensure_ascii=True, indent=4)) if kwargs.get("bug"): return update_bug(kwargs.get("bug")) for sub in os.listdir("./"): bugdir = os.path.join("./", sub) if not os.path.exists(os.path.join(bugdir, '.bugzilla.json')): continue update_bug(sub.lstrip(config.get("prefix", ""))) @classmethod def on_show(cls, config, **kwargs): if os.path.exists(".bugzilla.json"): with open(".bugzilla.json", "rb") as f: summary = loads(f.read()) print colored("Bug Title: ", 'green') + summary["summary"] print "\tStatus: %s" % summary["status"] print "\t%s comments" % len(summary["comments"]) # Check if conf.args has attr so we can reuse it for listing if hasattr(conf.args, "verbose") and conf.args.verbose: for idx, comment in enumerate(summary["comments"]): print colored("\tComment: %s" % (idx + 1), 'yellow') header = "\tAuthor: %s, Private: %s, Date %s" % \ (comment["author"], comment["is_private"], comment["time"]) print colored(header, 'yellow') print "\t%s" % comment["text"].replace("\n", "\n\t") print "\t" on_list = on_show
def update_case(self, bug_id, updates): """ :return: """ Bugzilla.update_bugs(ids=bug_id, updates=updates)