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 36import htmllib 37import re 38import urllib 39import urllib2 40 41try: # Python >= 2.5 42 from xml.etree import ElementTree 43except ImportError: 44 from elementtree import ElementTree 45 46class NonExistentBug(Exception): 47 def __str__(self): 48 return "Bug %s does not exist" % (Exception.__str__(self)) 49 50class BugDBException(Exception): 51 def __str__(self): 52 return "Unknown bug database: %s" % (Exception.__str__(self)) 53 54class 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 128