1 #! /usr/bin/python 2 # 3 # CDDL HEADER START 4 # 5 # The contents of this file are subject to the terms of the 6 # Common Development and Distribution License (the "License"). 7 # You may not use this file except in compliance with the License. 8 # 9 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 # or http://www.opensolaris.org/os/licensing. 11 # See the License for the specific language governing permissions 12 # and limitations under the License. 13 # 14 # When distributing Covered Code, include this CDDL HEADER in each 15 # file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 # If applicable, add the following below this CDDL HEADER, with the 17 # fields enclosed by brackets "[]" replaced with your own identifying 18 # information: Portions Copyright [yyyy] [name of copyright owner] 19 # 20 # CDDL HEADER END 21 # 22 23 # 24 # Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. 25 # 26 27 # Copyright 2010, Richard Lowe 28 29 # 30 # Various database lookup classes/methods, i.e.: 31 # * monaco 32 # * bugs.opensolaris.org (b.o.o.) 33 # * redmine (illumos.org) 34 # 35 36 import htmllib 37 import re 38 import urllib 39 import urllib2 40 41 try: # Python >= 2.5 42 from xml.etree import ElementTree 43 except ImportError: 44 from elementtree import ElementTree 45 46 class NonExistentBug(Exception): 47 def __str__(self): 48 return "Bug %s does not exist" % (Exception.__str__(self)) 49 50 class BugDBException(Exception): 51 def __str__(self): 52 return "Unknown bug database: %s" % (Exception.__str__(self)) 53 54 class BugDB(object): 55 """Lookup change requests. 56 57 Usage: 58 bdb = BugDB() 59 r = bdb.lookup("6455550") 60 print r["6455550"]["synopsis"] 61 r = bdb.lookup(["6455550", "6505625"]) 62 print r["6505625"]["synopsis"] 63 """ 64 65 VALID_DBS = ["illumos"] 66 67 def __init__(self, priority = ["illumos"]): 68 """Create a BugDB object. 69 70 Keyword argument: 71 priority: use bug databases in this order 72 """ 73 for database in priority: 74 if database not in self.VALID_DBS: 75 raise BugDBException, database 76 self.__priority = priority 77 78 79 def __illbug(self, cr): 80 url = "http://illumos.org/issues/%s.xml" % cr 81 req = urllib2.Request(url) 82 83 try: 84 data = urllib2.urlopen(req) 85 except urllib2.HTTPError, e: 86 if e.code == 404: 87 raise NonExistentBug(cr) 88 else: 89 raise 90 91 bug = ElementTree.parse(data) 92 93 return {'cr_number': bug.find('id').text, 94 'synopsis': bug.find('subject').text, 95 'status': bug.find('status').attrib['name'] 96 } 97 98 99 def lookup(self, crs): 100 """Return all info for requested change reports. 101 102 Argument: 103 crs: one change request id (may be integer, string, or list), 104 or multiple change request ids (must be a list) 105 106 Returns: 107 Dictionary, mapping CR=>dictionary, where the nested dictionary 108 is a mapping of field=>value 109 """ 110 results = {} 111 if not isinstance(crs, list): 112 crs = [str(crs)] 113 for database in self.__priority: 114 if database == "illumos": 115 for cr in crs: 116 try: 117 results[str(cr)] = self.__illbug(cr) 118 except NonExistentBug: 119 continue 120 121 # the CR has already been found by one bug database 122 # so don't bother looking it up in the others 123 for cr in crs: 124 if cr in results: 125 crs.remove(cr) 126 127 return results