summaryrefslogtreecommitdiff
blob: 578b0e05596c1221d3f6253a4e40be75557843d2 (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
128
129
130
131
# Copyright 2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2

import cStringIO
import datetime
import getpass
import re

import portage


CPV_REGEX = re.compile("[A-Za-z0-9+_.-]+/[A-Za-z0-9+_-]+-[0-9]+(?:\.[0-9]+)*[a-z0-9_]*(?:-r[0-9]+)?")


def chunks(iterable, length):
	for i in range(0, len(iterable), length):
		yield iterable[i:i + length]


# Snippet from http://bugs.python.org/issue9584
def expand_braces(orig):
	r = r'.*(\{.+?[^\\]\})'
	p = re.compile(r)

	s = orig[:]
	res = list()

	m = p.search(s)
	if m is not None:
		sub = m.group(1)
		open_brace = s.find(sub)
		close_brace = open_brace + len(sub) - 1
		if ',' in sub:
			for pat in sub.strip('{}').split(','):
				res.extend(expand_braces(s[:open_brace] + pat + s[close_brace+1:]))

		else:
			res.extend(expand_braces(s[:open_brace] + sub.replace('}', '\\}') + s[close_brace+1:]))

	else:
		res.append(s.replace('\\}', '}'))

	return list(set(res))


def detect_cpvs(text):
	cpvs = []
	for cpv_string in list(set([text] + expand_braces(text))):
		for cpv_candidate in CPV_REGEX.findall(cpv_string):
			if portage.db["/"]["porttree"].dbapi.cpv_exists(cpv_candidate):
				cpvs.append(cpv_candidate)
	return list(set(cpvs))


def get_input(prompt):
	return raw_input(prompt)


def login(bugzilla):
	"""Authenticate a session.
	"""
	# prompt for username
	user = get_input('Bugzilla Username: ')

	# prompt for password
	password = getpass.getpass()

	# perform login
	params = {}
	params['login'] = user
	params['password'] = password
	return user, bugzilla.User.login(params)


class Bug:
	def __init__(self, xml=None, id_number=None, summary=None, status=None):
		if xml is not None:
			self.__id = int(xml.find("bug_id").text)
			self.__summary = xml.find("short_desc").text
			self.__status = xml.find("bug_status").text
			self.__depends_on = [int(dep.text) for dep in xml.findall("dependson")]
			self.__comments = [c.find("who").text + "\n" + c.find("thetext").text for c in xml.findall("long_desc")]
			self.__cc = [cc.text for cc in xml.findall("cc")]
			self.__creation_timestamp = datetime.datetime.strptime(xml.find('creation_ts').text, '%Y-%m-%d %H:%M:%S +0000')

			self.__keywords = []
			keywords_elem = xml.find("keywords")
			if keywords_elem is not None and keywords_elem.text:
				self.__keywords = [k.strip() for k in keywords_elem.text.split(",")]
		if id_number is not None:
			self.__id = id_number
		if summary is not None:
			self.__summary = summary
		if status is not None:
			self.__status = status
		self.__cpvs_detected = False
		self.__cpvs = []
	
	def detect_cpvs(self):
		if self.__cpvs_detected:
			return
		self.__cpvs = detect_cpvs(self.summary())
		self.__cpvs_detected = True
	
	def id_number(self):
		return self.__id
	
	def summary(self):
		return self.__summary
	
	def status(self):
		return self.__status
	
	def depends_on(self):
		return self.__depends_on
	
	def comments(self):
		return self.__comments
	
	def cc(self):
		return self.__cc

	def creation_timestamp(self):
		return self.__creation_timestamp

	def keywords(self):
		return self.__keywords
	
	def cpvs(self):
		assert(self.__cpvs_detected)
		return self.__cpvs