From 3172fcbd5c9e300091dd60b1f96dc2aeb5a5fdf9 Mon Sep 17 00:00:00 2001 From: "Owen W. Taylor" Date: Fri, 9 Sep 2011 18:31:30 -0400 Subject: Make components work with older bugzilla Use Bug.legal_values({ product_id: }) to find out legal component values in a way that works on older Bugzilla like the bugzilla.gnome.org 3.4. This requires finding out the product_id first, which is fast with new bugzilla, but requires a slow fallback on older bugzillas; we cache positive hits for product IDs in our cache. https://bugzilla.gnome.org/show_bug.cgi?id=654693 --- git-bz | 58 +++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 49 insertions(+), 9 deletions(-) diff --git a/git-bz b/git-bz index 6b2a52b..0c5a3e4 100755 --- a/git-bz +++ b/git-bz @@ -80,6 +80,7 @@ import tempfile import time import traceback import xmlrpclib +import urllib import urlparse from xml.etree.cElementTree import ElementTree import base64 @@ -927,6 +928,46 @@ class BugServer(object): return self._xmlrpc_proxy + def _product_id(self, product_name): + # This way works with newer bugzilla; older Bugzilla doesn't support names: + try: + response = self.get_xmlrpc_proxy().Product.get({ 'names': product_name, 'include_fields': ['id', 'name'] }) + products = response['products'] + if len(products) > 0: + return products[0]['id'] + except xmlrpclib.Fault, e: + pass + except xmlrpclib.ProtocolError, e: + pass + + # This should work with any bugzilla that supports xmlrpc, but will be slow + print >>sys.stderr, "Searching for product ID ...", + try: + response = self.get_xmlrpc_proxy().Product.get_accessible_products({}) + ids = response['ids'] + response = self.get_xmlrpc_proxy().Product.get_products({ 'ids': ids, 'include_fields': ['id', 'name']}) + for p in response['products']: + if p['name'] == product_name: + print >>sys.stderr, "found it" + return p['id'] + except xmlrpclib.Fault, e: + pass + except xmlrpclib.ProtocolError, e: + pass + + print >>sys.stderr, "failed" + return None + + def product_id(self, product_name): + key = 'product_id_' + urllib.quote(product_name) + try: + return cache.get(self.host, key) + except IndexError: + value = self._product_id(product_name) + if value != None: + cache.set(self.host, key, value) + return value + # Query the server for the legal values of the given field; returns an # array, or None if the query failed def _legal_values(self, field): @@ -2047,21 +2088,20 @@ def do_components(*args): if not product: die(" not specified and no default product is configured" + PRODUCT_COMPONENT_HELP) + product_id = server.product_id(product) + if product_id is None: + die("No such product " + product) + try: - response = server.get_xmlrpc_proxy().Product.get({ 'names': product }) + response = server.get_xmlrpc_proxy().Bug.legal_values({'product_id': product_id, 'field': 'component'}) + components = response['values'] + for component in components: + print component except xmlrpclib.Fault, e: die(e.faultString) except xmlrpclib.ProtocolError, e: die("Unable to retrieve components: %s" % e.errmsg) - products = response['products'] - if len(products) == 0: - die("No such product '%s' on %s." % (product, host)) - - product = response['products'][0] - for component in product['components']: - print "%s" % component['name'] - ################################################################################ if len(sys.argv) > 1: -- cgit v1.2.3