summaryrefslogtreecommitdiff
path: root/usr/src/tools/onbld/Checks/DbLookups.py
blob: 11fd4185be1d1fb7c578f57d6e754ab4b9039186 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#! /usr/bin/python
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#

#
# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
#

# Copyright 2010, Richard Lowe

#
# Various database lookup classes/methods, i.e.:
#     * monaco
#     * bugs.opensolaris.org (b.o.o.)
#     * redmine (illumos.org)
#

import htmllib
import re
import urllib
import urllib2

try:				# Python >= 2.5
	from xml.etree import ElementTree
except ImportError:
	from elementtree import ElementTree

class NonExistentBug(Exception):
	def __str__(self):
		return "Bug %s does not exist" % (Exception.__str__(self))

class BugDBException(Exception):
	def __str__(self):
		return "Unknown bug database: %s" % (Exception.__str__(self))

class BugDB(object):
	"""Lookup change requests.

	Usage:
	bdb = BugDB()
	r = bdb.lookup("6455550")
	print r["6455550"]["synopsis"]
	r = bdb.lookup(["6455550", "6505625"])
	print r["6505625"]["synopsis"]
	"""

	VALID_DBS = ["illumos"]

	def __init__(self, priority = ["illumos"]):
		"""Create a BugDB object.

		Keyword argument:
		priority: use bug databases in this order
		"""
		for database in priority:
			if database not in self.VALID_DBS:
				raise BugDBException, database
		self.__priority = priority


	def __illbug(self, cr):
		url = "http://illumos.org/issues/%s.xml" % cr
		req = urllib2.Request(url)

		try:
			data = urllib2.urlopen(req)
		except urllib2.HTTPError, e:
			if e.code == 404:
				raise NonExistentBug(cr)
			else:
				raise

		bug = ElementTree.parse(data)

		return {'cr_number': bug.find('id').text,
			'synopsis': bug.find('subject').text,
			'status': bug.find('status').attrib['name']
		}


	def lookup(self, crs):
		"""Return all info for requested change reports.

		Argument:
		crs: one change request id (may be integer, string, or list),
		     or multiple change request ids (must be a list)

		Returns:
		Dictionary, mapping CR=>dictionary, where the nested dictionary
		is a mapping of field=>value
		"""
		results = {}
		if not isinstance(crs, list):
			crs = [str(crs)]
		for database in self.__priority:
			if database == "illumos":
				for cr in crs:
					try:
						results[str(cr)] = self.__illbug(cr)
					except NonExistentBug:
						continue

			# the CR has already been found by one bug database
			# so don't bother looking it up in the others
			for cr in crs:
				if cr in results:
					crs.remove(cr)

		return results