xref: /titanic_44/usr/src/tools/onbld/Checks/DbLookups.py (revision 37cc68d40a0ab1290a015e66cad4cade598c921b)
1cdf0c1d5Smjnelson#! /usr/bin/python
2cdf0c1d5Smjnelson#
3cdf0c1d5Smjnelson# CDDL HEADER START
4cdf0c1d5Smjnelson#
5cdf0c1d5Smjnelson# The contents of this file are subject to the terms of the
6cdf0c1d5Smjnelson# Common Development and Distribution License (the "License").
7cdf0c1d5Smjnelson# You may not use this file except in compliance with the License.
8cdf0c1d5Smjnelson#
9cdf0c1d5Smjnelson# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10cdf0c1d5Smjnelson# or http://www.opensolaris.org/os/licensing.
11cdf0c1d5Smjnelson# See the License for the specific language governing permissions
12cdf0c1d5Smjnelson# and limitations under the License.
13cdf0c1d5Smjnelson#
14cdf0c1d5Smjnelson# When distributing Covered Code, include this CDDL HEADER in each
15cdf0c1d5Smjnelson# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16cdf0c1d5Smjnelson# If applicable, add the following below this CDDL HEADER, with the
17cdf0c1d5Smjnelson# fields enclosed by brackets "[]" replaced with your own identifying
18cdf0c1d5Smjnelson# information: Portions Copyright [yyyy] [name of copyright owner]
19cdf0c1d5Smjnelson#
20cdf0c1d5Smjnelson# CDDL HEADER END
21cdf0c1d5Smjnelson#
22cdf0c1d5Smjnelson
23cdf0c1d5Smjnelson#
2484bb51dbSMark J. Nelson# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
25cdf0c1d5Smjnelson#
26cdf0c1d5Smjnelson
272f54b716SRichard Lowe# Copyright 2010, Richard Lowe
282f54b716SRichard Lowe
29cdf0c1d5Smjnelson#
30cdf0c1d5Smjnelson# Various database lookup classes/methods, i.e.:
31cdf0c1d5Smjnelson#     * monaco
32cdf0c1d5Smjnelson#     * bugs.opensolaris.org (b.o.o.)
332f54b716SRichard Lowe#     * redmine (illumos.org)
34cdf0c1d5Smjnelson#
35cdf0c1d5Smjnelson
362f54b716SRichard Loweimport htmllib
37cdf0c1d5Smjnelsonimport re
38cdf0c1d5Smjnelsonimport urllib
39c08a253cSJohn Sonnenscheinimport urllib2
40cdf0c1d5Smjnelson
412f54b716SRichard Lowetry:				# Python >= 2.5
422f54b716SRichard Lowe	from xml.etree import ElementTree
432f54b716SRichard Loweexcept ImportError:
442f54b716SRichard Lowe	from elementtree import ElementTree
45cdf0c1d5Smjnelson
4641a5f560SMark J. Nelsonclass NonExistentBug(Exception):
47cdf0c1d5Smjnelson	def __str__(self):
4841a5f560SMark J. Nelson		return "Bug %s does not exist" % (Exception.__str__(self))
49cdf0c1d5Smjnelson
50c08a253cSJohn Sonnenscheinclass BugDBException(Exception):
51c08a253cSJohn Sonnenschein	def __str__(self):
5241a5f560SMark J. Nelson		return "Unknown bug database: %s" % (Exception.__str__(self))
53cdf0c1d5Smjnelson
54cdf0c1d5Smjnelsonclass BugDB(object):
55cdf0c1d5Smjnelson	"""Lookup change requests.
56cdf0c1d5Smjnelson
57cdf0c1d5Smjnelson	Usage:
58cdf0c1d5Smjnelson	bdb = BugDB()
59cdf0c1d5Smjnelson	r = bdb.lookup("6455550")
60cdf0c1d5Smjnelson	print r["6455550"]["synopsis"]
61cdf0c1d5Smjnelson	r = bdb.lookup(["6455550", "6505625"])
62cdf0c1d5Smjnelson	print r["6505625"]["synopsis"]
63cdf0c1d5Smjnelson	"""
64cdf0c1d5Smjnelson
65*37cc68d4SJoshua M. Clulow	VALID_DBS = ["illumos"]
662f54b716SRichard Lowe
67*37cc68d4SJoshua M. Clulow	def __init__(self, priority = ["illumos"]):
68cdf0c1d5Smjnelson		"""Create a BugDB object.
69cdf0c1d5Smjnelson
70cdf0c1d5Smjnelson		Keyword argument:
71c08a253cSJohn Sonnenschein		priority: use bug databases in this order
72cdf0c1d5Smjnelson		"""
73c08a253cSJohn Sonnenschein		for database in priority:
742f54b716SRichard Lowe			if database not in self.VALID_DBS:
75c08a253cSJohn Sonnenschein				raise BugDBException, database
76c08a253cSJohn Sonnenschein		self.__priority = priority
77c08a253cSJohn Sonnenschein
78c08a253cSJohn Sonnenschein
792f54b716SRichard Lowe	def __illbug(self, cr):
802f54b716SRichard Lowe		url = "http://illumos.org/issues/%s.xml" % cr
812f54b716SRichard Lowe		req = urllib2.Request(url)
822f54b716SRichard Lowe
832f54b716SRichard Lowe		try:
842f54b716SRichard Lowe			data = urllib2.urlopen(req)
852f54b716SRichard Lowe		except urllib2.HTTPError, e:
862f54b716SRichard Lowe			if e.code == 404:
872f54b716SRichard Lowe				raise NonExistentBug(cr)
882f54b716SRichard Lowe			else:
892f54b716SRichard Lowe				raise
902f54b716SRichard Lowe
912f54b716SRichard Lowe		bug = ElementTree.parse(data)
922f54b716SRichard Lowe
932f54b716SRichard Lowe		return {'cr_number': bug.find('id').text,
942f54b716SRichard Lowe			'synopsis': bug.find('subject').text,
952f54b716SRichard Lowe			'status': bug.find('status').attrib['name']
962f54b716SRichard Lowe		}
972f54b716SRichard Lowe
982f54b716SRichard Lowe
99cdf0c1d5Smjnelson	def lookup(self, crs):
100cdf0c1d5Smjnelson		"""Return all info for requested change reports.
101cdf0c1d5Smjnelson
102cdf0c1d5Smjnelson		Argument:
103cdf0c1d5Smjnelson		crs: one change request id (may be integer, string, or list),
104cdf0c1d5Smjnelson		     or multiple change request ids (must be a list)
105cdf0c1d5Smjnelson
106cdf0c1d5Smjnelson		Returns:
107cdf0c1d5Smjnelson		Dictionary, mapping CR=>dictionary, where the nested dictionary
108cdf0c1d5Smjnelson		is a mapping of field=>value
109cdf0c1d5Smjnelson		"""
110c08a253cSJohn Sonnenschein		results = {}
111cdf0c1d5Smjnelson		if not isinstance(crs, list):
112cdf0c1d5Smjnelson			crs = [str(crs)]
113c08a253cSJohn Sonnenschein		for database in self.__priority:
114*37cc68d4SJoshua M. Clulow			if database == "illumos":
1152f54b716SRichard Lowe				for cr in crs:
1162f54b716SRichard Lowe					try:
1172f54b716SRichard Lowe						results[str(cr)] = self.__illbug(cr)
1182f54b716SRichard Lowe					except NonExistentBug:
1192f54b716SRichard Lowe						continue
120cdf0c1d5Smjnelson
121c08a253cSJohn Sonnenschein			# the CR has already been found by one bug database
122c08a253cSJohn Sonnenschein			# so don't bother looking it up in the others
123c08a253cSJohn Sonnenschein			for cr in crs:
124c08a253cSJohn Sonnenschein				if cr in results:
125c08a253cSJohn Sonnenschein					crs.remove(cr)
126cdf0c1d5Smjnelson
127cdf0c1d5Smjnelson		return results
128