| 1 | """This is probably overkill for packages.gentoo.org, but perhaps it can be |
1 | """/bugs/ |
| 2 | used elsewhere""" |
2 | Like /licenses/ this is only a redirector. Redirect to bugzilla. |
|
|
3 | """ |
|
|
4 | from quixote import redirect |
| 3 | |
5 | |
| 4 | __revision__ = '$Revision: 1.2 $' |
6 | _q_exports = [] |
| 5 | # $Source: /var/cvsroot/gentoo/src/packages/bugs.py,v $ |
|
|
| 6 | |
7 | |
| 7 | # importers may want to override this. This is the current(?) |
8 | BBASE = 'http://bugs.gentoo.org/show_bug.cgi' |
| 8 | # bugs.gentoo.org settings |
|
|
| 9 | STATUS = {'UNCONFIRMED': 'UNCONFIRMED', |
|
|
| 10 | 'NEW': 'NEW', |
|
|
| 11 | 'ASSIGNED': 'ASSIGNED', |
|
|
| 12 | 'REOPENED': 'REOPENED', |
|
|
| 13 | 'RESOLVED': 'RESOLVED', |
|
|
| 14 | 'VERIFIED': 'VERIFIED', |
|
|
| 15 | 'CLOSED': 'CLOSED'} |
|
|
| 16 | |
|
|
| 17 | class Bug: |
|
|
| 18 | """a bugzilla bug""" |
|
|
| 19 | def __init__(self, bug_id, severity, priority, rep_platform, assigned_to, |
|
|
| 20 | status, resolution, short_desc): |
|
|
| 21 | self.bug_id = bug_id |
|
|
| 22 | self.severity = severity |
|
|
| 23 | self.priority = priority |
|
|
| 24 | self.rep_platform = rep_platform |
|
|
| 25 | self.assigned_to = assigned_to |
|
|
| 26 | self.status = status |
|
|
| 27 | self.resolution = resolution |
|
|
| 28 | self.short_desc = short_desc |
|
|
| 29 | |
9 | |
| 30 | self.data = (self.bug_id, self.severity, self.priority, |
10 | def _q_index(_): |
| 31 | self.rep_platform, self.assigned_to, self.status, self.resolution, |
11 | """This should never be called""" |
| 32 | self.short_desc) |
12 | return redirect(BBASE) |
| 33 | |
|
|
| 34 | def to_dict(self): |
|
|
| 35 | """convert to dict""" |
|
|
| 36 | return {'bug_id': self.bug_id, |
|
|
| 37 | 'severity': self.severity, |
|
|
| 38 | 'priority': self.priority, |
|
|
| 39 | 'rep_platform': self.rep_platform, |
|
|
| 40 | 'assigned_to': self.assigned_to, |
|
|
| 41 | 'status': self.status, |
|
|
| 42 | 'resolution': self.resolution, |
|
|
| 43 | 'short_desc': self.short_desc} |
|
|
| 44 | |
|
|
| 45 | def to_tuple(self): |
|
|
| 46 | """convert to tuple""" |
|
|
| 47 | return self.data |
|
|
| 48 | |
13 | |
| 49 | def __iter__(self): |
14 | def _q_lookup(_, component): |
| 50 | """Same as above""" |
15 | """Redirect: component should be a bug number""" |
| 51 | for field in self.data: |
16 | return redirect('%s?id=%s' % (BBASE, component)) |
| 52 | yield field |
|
|
| 53 | |
|
|
| 54 | def __getitem__(self, index): |
|
|
| 55 | """Makes me look like a tuple or list""" |
|
|
| 56 | return self.data[index] |
|
|
| 57 | |
|
|
| 58 | class BugFactory: |
|
|
| 59 | """create bugs from dict data""" |
|
|
| 60 | def __init__(self): |
|
|
| 61 | """to shut pylint up""" |
|
|
| 62 | pass |
|
|
| 63 | |
|
|
| 64 | def from_dict(self, mapping): |
|
|
| 65 | """from_dict => BugFactory.from_dict(mapping).to_dict() == mapping""" |
|
|
| 66 | bug_id = mapping.get("bug_id", "unknown") |
|
|
| 67 | severity = mapping.get("severity") |
|
|
| 68 | priority = mapping.get("priority") |
|
|
| 69 | rep_platform = mapping.get("rep_platform") |
|
|
| 70 | assigned_to = mapping.get("assigned_to") |
|
|
| 71 | status = mapping.get("status") |
|
|
| 72 | resolution = mapping.get("resolution") |
|
|
| 73 | short_desc = mapping.get("short_desc") |
|
|
| 74 | |
|
|
| 75 | return Bug(bug_id, severity, priority, rep_platform, assigned_to, |
|
|
| 76 | status, resolution, short_desc) |
|
|
| 77 | |
|
|
| 78 | def from_list_of_dicts(self, buglist): |
|
|
| 79 | """when you have a list of dicts""" |
|
|
| 80 | return [self.from_dict(mapping) for mapping in buglist] |
|
|
| 81 | |
|
|
| 82 | def from_list_of_lists(self, lists): |
|
|
| 83 | """Return list of bugs from list of lists. Lists must be in same |
|
|
| 84 | order as call to Bug.__init__() |
|
|
| 85 | """ |
|
|
| 86 | return [Bug(*bug_list) for bug_list in lists] |
|
|
| 87 | |
|
|
| 88 | from_db_query = from_list_of_lists |
|
|
| 89 | |
|
|
| 90 | def from_csv(self, csv_file): |
|
|
| 91 | """fp should be a file object with CSV data in the format as returned |
|
|
| 92 | by bugzlla""" |
|
|
| 93 | |
|
|
| 94 | import csv |
|
|
| 95 | reader = csv.reader(csv_file) |
|
|
| 96 | return [Bug(*data[:8]) for data in reader] |
|
|
| 97 | |
|
|
| 98 | class HTMLWriter: |
|
|
| 99 | """convert list of bugs to HTML""" |
|
|
| 100 | def __init__(self, bugs, bugzilla_site=None): |
|
|
| 101 | """where <bugs> is a list of Bugs""" |
|
|
| 102 | |
|
|
| 103 | table_begin = '<table class="buglist">' |
|
|
| 104 | table_heading = ('<tr class="heading">' |
|
|
| 105 | '<th class="bug_id">Bug ID</th>' |
|
|
| 106 | '<th class="severity">Severity</th>' |
|
|
| 107 | '<th class="priority">Priority</th>' |
|
|
| 108 | '<th class="platform">Platform</th>' |
|
|
| 109 | #'<th class="assigned_to">Assigned To</th>' |
|
|
| 110 | '<th class="status">Status</th>' |
|
|
| 111 | #'<th class="resolution">Resolution</th>' |
|
|
| 112 | '<th class="description">Description</th>' |
|
|
| 113 | '</tr>') |
|
|
| 114 | rows = [] |
|
|
| 115 | for bug in bugs: |
|
|
| 116 | bug_dict = bug.to_dict() |
|
|
| 117 | if bugzilla_site: |
|
|
| 118 | bug_id = ('<td class="bug_id">' |
|
|
| 119 | '<a href="http://%s/show_bug.cgi?id=%s">' |
|
|
| 120 | '%s</td>' % (bugzilla_site, bug_dict['bug_id'], |
|
|
| 121 | bug_dict['bug_id'])) |
|
|
| 122 | else: |
|
|
| 123 | bug_id = '<td class="bug_id">%(bug_id)s</td>' % bug_dict |
|
|
| 124 | |
|
|
| 125 | bug_data = ('<td class="severity">%(severity)s</td>' |
|
|
| 126 | '<td class="priority">%(priority)s</td>' |
|
|
| 127 | '<td class="platform">%(rep_platform)s' |
|
|
| 128 | #'<td class="assigned_to">%(assigned_to)s</td>' |
|
|
| 129 | '<td class="status">%(status)s</td>' |
|
|
| 130 | #'<td class="resolution">%(resolution)s</td>' |
|
|
| 131 | '<td class="description">%(short_desc)s</td>' |
|
|
| 132 | % bug_dict) |
|
|
| 133 | row = '<tr class="bug">%(bug_id)s%(bug_data)s</tr>' % locals() |
|
|
| 134 | rows.append(row) |
|
|
| 135 | table_end = '</table>' |
|
|
| 136 | self.html = '\n '.join([table_begin, table_heading] + rows + |
|
|
| 137 | [table_end]) |
|
|
| 138 | |
|
|
| 139 | def __str__(self): |
|
|
| 140 | return self.html |
|
|