root/protocols/protocol_bugzilla.py

Revision 81, 3.4 kB (checked in by ploum@…, 3 months ago)

a few more icon

Line 
1#!/usr/bin/python
2# -*- coding: utf-8 -*-
3
4import gtk, gobject
5import urllib, re, xml.dom.minidom, csv, urlparse
6import bug
7import BeautifulSoup
8
9Bug = bug.bug
10Comment = bug.comment
11
12class protocol:
13        @staticmethod
14        def Name():
15                return "Bugzilla"
16       
17        def __init__(self, account):
18                self.account = account
19       
20        def getBugUrl(self,nbr):
21                return self.__url('show_bug.cgi', id=nbr)
22       
23        def btsName(self):
24                return urlparse.urlsplit(self.account.url)[1]
25
26        def retrieveBug(self,nbr):
27                """ Get bug #nbr """
28                def tagval(parent,tag):
29                        return parent.getElementsByTagName(tag)[0].firstChild.nodeValue
30               
31                fd = urllib.urlopen(self.__url('show_bug.cgi', id=nbr, ctype='xml'))
32                xbug = xml.dom.minidom.parse(fd).getElementsByTagName('bug')[0]
33                if xbug.getAttribute('error'):
34                        return Bug(-1)
35                bug = Bug(nbr)
36               
37                comments = xbug.getElementsByTagName('long_desc')
38                bug.setPackage(tagval(xbug, 'product'))
39                bug.setTitle(tagval(xbug, 'short_desc'))
40                bug.setDescription(tagval(comments[0], 'thetext'))
41                bug.setStatus(tagval(xbug, 'bug_status'))
42                bug.setImportance(tagval(xbug, 'bug_severity'))
43                bug.setAssignee(tagval(xbug, 'assigned_to'))
44                bug.setCommentable(False) # fixme !
45               
46                for i, comment in enumerate(comments[1:]):
47                        c_content = tagval(comment, 'thetext')
48                        c_number = i+1
49                        c_author = tagval(comment, 'who')
50                        c_date = tagval(comment, 'bug_when')
51                       
52                        bug.addComment(Comment(c_number, c_content, c_author, "", c_date))
53               
54                return bug
55       
56        def genericSearch(self, string):
57                """ Search for a string """
58                return self.__searchResults(query=string, quicksearch=string)
59       
60        def packageSearch(self, pkg, string):
61                """ Search for a string, but only for bug of package "pkg"
62                        Well, sin't meaningful for Gentoo BTS ;) """
63                return self.__searchResults(product=pkg, content=string, bug_status='__open__')
64       
65        def packageExist(self, pkg):
66                return False
67                #fixme!
68                potage = BeautifulSoup.BeautifulSoup(urllib.urlopen(self.__url('query.cgi', format="specific")))
69                products = potage.find('select', id='product').findAll('option')
70                print [p.string.strip() for p in products]
71                return pkg in products
72       
73        def advancedSearch(self, pkg):
74                # fixme !
75                pass
76       
77        def __searchResults(self, **kwargs):
78                url = self.__url('buglist.cgi', ctype='csv', **kwargs)
79                data = urllib.urlopen(url)
80                fmt = [x.replace('"', '').strip() for x in data.readline().split(',')]
81                indexes = (fmt.index('bug_id'), fmt.index('short_short_desc'), fmt.index('bug_severity'), fmt.index('bug_status'))
82                bugs = self.__newResult()
83                for bug in csv.reader(data, quoting=csv.QUOTE_NONNUMERIC):
84                        bugs.append((int(bug[indexes[0]]), '', bug[indexes[1]], bug[indexes[2]], bug[indexes[3]]))
85                return bugs
86       
87        def __newResult(self) :
88                #private function to create a new result gtk.ListStore
89                # Bug id, package, title, importance, status
90                return gtk.ListStore(gobject.TYPE_INT, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING)
91       
92        def __url(self, base, **qs):
93                root = self.account.url
94                if not root.startswith('http://') and not root.startswith('https://'):
95                        root = 'http://' + root
96                if not root.endswith('/'):
97                        root += '/'
98                s_qs = urllib.urlencode(qs)
99                if s_qs:
100                        s_qs = '?' + s_qs
101                return root + base + s_qs
102       
103        def availableStatus(self):
104                return ('UNCONFIRMED', 'NEW', 'ASSIGNED', 'REOPENED', 'RESOLVED', 'VERIFIED', 'CLOSED')
105       
106        def availableImportance(self):
107                return ('Blocker', 'Critical', 'Major', 'Minor', 'Trivial', 'Enhancement')
Note: See TracBrowser for help on using the browser.