Bugtracker: Add Python 3 support (by Mattia Rizzolo)
This commit is contained in:
@ -2,6 +2,7 @@
|
|||||||
###
|
###
|
||||||
# Copyright (c) 2005-2007 Dennis Kaarsemaker
|
# Copyright (c) 2005-2007 Dennis Kaarsemaker
|
||||||
# Copyright (c) 2008-2010 Terence Simpson
|
# Copyright (c) 2008-2010 Terence Simpson
|
||||||
|
# Copyright (c) 2017- Krytarik Raido
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of version 2 of the GNU General Public License as
|
# it under the terms of version 2 of the GNU General Public License as
|
||||||
@ -21,19 +22,22 @@ This plugin will display bug information when requested.
|
|||||||
import supybot
|
import supybot
|
||||||
import supybot.world as world
|
import supybot.world as world
|
||||||
|
|
||||||
__version__ = "2.5.1"
|
from imp import reload
|
||||||
__author__ = supybot.Author("Terence Simpson", "tsimpson", "tsimpson@ubuntu.com")
|
|
||||||
__contributors__ = {
|
|
||||||
supybot.Author("Dennis Kaarsemaker","Seveas","dennis@kaarsemaker.net"): ['Original Author']
|
|
||||||
}
|
|
||||||
__url__ = 'https://launchpad.net/ubuntu-bots/'
|
|
||||||
|
|
||||||
import config
|
__version__ = "2.6.0"
|
||||||
|
__author__ = supybot.Author("Krytarik Raido", "krytarik", "krytarik@tuxgarage.com")
|
||||||
|
__contributors__ = {
|
||||||
|
supybot.Author("Dennis Kaarsemaker", "Seveas", "dennis@kaarsemaker.net"): ['Original Author'],
|
||||||
|
supybot.Author("Terence Simpson", "tsimpson", "tsimpson@ubuntu.com"): ['Original Author']
|
||||||
|
}
|
||||||
|
__url__ = 'https://launchpad.net/ubuntu-bots'
|
||||||
|
|
||||||
|
from . import config
|
||||||
reload(config)
|
reload(config)
|
||||||
import plugin
|
from . import plugin
|
||||||
reload(plugin)
|
reload(plugin)
|
||||||
|
|
||||||
if world.testing:
|
if world.testing:
|
||||||
import test
|
from . import test
|
||||||
Class = plugin.Class
|
Class = plugin.Class
|
||||||
configure = config.configure
|
configure = config.configure
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
###
|
###
|
||||||
# Copyright (c) 2005-2007 Dennis Kaarsemaker
|
# Copyright (c) 2005-2007 Dennis Kaarsemaker
|
||||||
# Copyright (c) 2008-2010 Terence Simpson
|
# Copyright (c) 2008-2010 Terence Simpson
|
||||||
|
# Copyright (c) 2017- Krytarik Raido
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of version 2 of the GNU General Public License as
|
# it under the terms of version 2 of the GNU General Public License as
|
||||||
@ -24,12 +25,15 @@ import supybot.registry as registry
|
|||||||
import supybot.schedule as schedule
|
import supybot.schedule as schedule
|
||||||
import supybot.log as supylog
|
import supybot.log as supylog
|
||||||
|
|
||||||
|
from functools import cmp_to_key
|
||||||
|
|
||||||
#import imaplib
|
#import imaplib
|
||||||
import re, os, time, commands
|
import re, os, sys, time, subprocess
|
||||||
import xml.dom.minidom as minidom
|
import xml.dom.minidom as minidom
|
||||||
from htmlentitydefs import entitydefs as entities
|
from html.entities import entitydefs as entities
|
||||||
import email.FeedParser
|
from email.parser import FeedParser
|
||||||
import SOAPpy
|
if sys.version_info < (3,0):
|
||||||
|
import SOAPpy
|
||||||
|
|
||||||
# All the words below will be censored when reporting bug information
|
# All the words below will be censored when reporting bug information
|
||||||
bad_words = set(["fuck","fuk","fucking","fuking","fukin","fuckin","fucked","fuked","fucker","shit","cunt","bastard","nazi","nigger","nigga","cock","bitches","bitch"])
|
bad_words = set(["fuck","fuk","fucking","fuking","fukin","fuckin","fucked","fuked","fucker","shit","cunt","bastard","nazi","nigger","nigga","cock","bitches","bitch"])
|
||||||
@ -52,7 +56,7 @@ def registerBugtracker(name, url='', description='', trackertype=''):
|
|||||||
if description:
|
if description:
|
||||||
DESC.setValue(description)
|
DESC.setValue(description)
|
||||||
if trackertype:
|
if trackertype:
|
||||||
if defined_bugtrackers.has_key(trackertype.lower()):
|
if trackertype.lower() in defined_bugtrackers:
|
||||||
TRACKERTYPE.setValue(trackertype.lower())
|
TRACKERTYPE.setValue(trackertype.lower())
|
||||||
else:
|
else:
|
||||||
raise BugtrackerError("Unknown trackertype: %s" % trackertype)
|
raise BugtrackerError("Unknown trackertype: %s" % trackertype)
|
||||||
@ -64,7 +68,7 @@ def _getnodetxt(node):
|
|||||||
if childnode.nodeType == childnode.TEXT_NODE:
|
if childnode.nodeType == childnode.TEXT_NODE:
|
||||||
L.append(childnode.data)
|
L.append(childnode.data)
|
||||||
if not L:
|
if not L:
|
||||||
raise ValueError, "No text nodes"
|
raise ValueError("No text nodes")
|
||||||
val = ''.join(L)
|
val = ''.join(L)
|
||||||
if node.hasAttribute('encoding'):
|
if node.hasAttribute('encoding'):
|
||||||
encoding = node.getAttribute('encoding')
|
encoding = node.getAttribute('encoding')
|
||||||
@ -103,11 +107,11 @@ class Bugtracker(callbacks.PluginRegexp):
|
|||||||
for name in self.registryValue('bugtrackers'):
|
for name in self.registryValue('bugtrackers'):
|
||||||
registerBugtracker(name)
|
registerBugtracker(name)
|
||||||
group = self.registryValue('bugtrackers.%s' % name.replace('.','\\.'), value=False)
|
group = self.registryValue('bugtrackers.%s' % name.replace('.','\\.'), value=False)
|
||||||
if group.trackertype() in defined_bugtrackers.keys():
|
if group.trackertype() in defined_bugtrackers:
|
||||||
self.db[name] = defined_bugtrackers[group.trackertype()](name, group.url(), group.description())
|
self.db[name] = defined_bugtrackers[group.trackertype()](name, group.url(), group.description())
|
||||||
else:
|
else:
|
||||||
self.log.warning("Bugtracker: Unknown trackertype: %s (%s)" % (group.trackertype(), name))
|
self.log.warning("Bugtracker: Unknown trackertype: %s (%s)" % (group.trackertype(), name))
|
||||||
self.shorthand = utils.abbrev(self.db.keys())
|
self.shorthand = utils.abbrev(list(self.db.keys()))
|
||||||
self.shown = {}
|
self.shown = {}
|
||||||
|
|
||||||
# # Schedule bug reporting
|
# # Schedule bug reporting
|
||||||
@ -134,7 +138,7 @@ class Bugtracker(callbacks.PluginRegexp):
|
|||||||
def is_ok(self, channel, tracker, bug):
|
def is_ok(self, channel, tracker, bug):
|
||||||
'''Flood/repeat protection'''
|
'''Flood/repeat protection'''
|
||||||
now = time.time()
|
now = time.time()
|
||||||
for k in self.shown.keys():
|
for k in list(self.shown.keys()):
|
||||||
if self.shown[k] < now - self.registryValue('repeatdelay', channel):
|
if self.shown[k] < now - self.registryValue('repeatdelay', channel):
|
||||||
self.shown.pop(k)
|
self.shown.pop(k)
|
||||||
if (channel, tracker, bug) not in self.shown:
|
if (channel, tracker, bug) not in self.shown:
|
||||||
@ -171,7 +175,7 @@ class Bugtracker(callbacks.PluginRegexp):
|
|||||||
# # Read all new mail
|
# # Read all new mail
|
||||||
# for m in new_mail:
|
# for m in new_mail:
|
||||||
# msg = sc.fetch(m, 'RFC822')[1][0][1]
|
# msg = sc.fetch(m, 'RFC822')[1][0][1]
|
||||||
# fp = email.FeedParser.FeedParser()
|
# fp = FeedParser()
|
||||||
# sc.store(m, '+FLAGS', "(\Deleted)") # Mark message deleted so we don't have to process it again
|
# sc.store(m, '+FLAGS', "(\Deleted)") # Mark message deleted so we don't have to process it again
|
||||||
# fp.feed(msg)
|
# fp.feed(msg)
|
||||||
# bug = fp.close()
|
# bug = fp.close()
|
||||||
@ -258,7 +262,7 @@ class Bugtracker(callbacks.PluginRegexp):
|
|||||||
irc.error("Bugtrackers of type '%s' are not understood" % trackertype)
|
irc.error("Bugtrackers of type '%s' are not understood" % trackertype)
|
||||||
return
|
return
|
||||||
registerBugtracker(name, url, description, trackertype)
|
registerBugtracker(name, url, description, trackertype)
|
||||||
self.shorthand = utils.abbrev(self.db.keys())
|
self.shorthand = utils.abbrev(list(self.db.keys()))
|
||||||
irc.replySuccess()
|
irc.replySuccess()
|
||||||
add = wrap(add, [('checkCapability', 'admin'), 'something', 'something', 'url', additional('text')])
|
add = wrap(add, [('checkCapability', 'admin'), 'something', 'something', 'url', additional('text')])
|
||||||
|
|
||||||
@ -272,7 +276,7 @@ class Bugtracker(callbacks.PluginRegexp):
|
|||||||
name = self.shorthand[name.lower()]
|
name = self.shorthand[name.lower()]
|
||||||
del self.db[name]
|
del self.db[name]
|
||||||
self.registryValue('bugtrackers').remove(name)
|
self.registryValue('bugtrackers').remove(name)
|
||||||
self.shorthand = utils.abbrev(self.db.keys())
|
self.shorthand = utils.abbrev(list(self.db.keys()))
|
||||||
irc.replySuccess()
|
irc.replySuccess()
|
||||||
except KeyError:
|
except KeyError:
|
||||||
s = self.registryValue('replyNoBugtracker', ircutils.isChannel(msg.args[0]) and msg.args[0] or None)
|
s = self.registryValue('replyNoBugtracker', ircutils.isChannel(msg.args[0]) and msg.args[0] or None)
|
||||||
@ -294,7 +298,7 @@ class Bugtracker(callbacks.PluginRegexp):
|
|||||||
registerBugtracker(newname, group.url(), d, group.trackertype())
|
registerBugtracker(newname, group.url(), d, group.trackertype())
|
||||||
del self.db[name]
|
del self.db[name]
|
||||||
self.registryValue('bugtrackers').remove(name)
|
self.registryValue('bugtrackers').remove(name)
|
||||||
self.shorthand = utils.abbrev(self.db.keys())
|
self.shorthand = utils.abbrev(list(self.db.keys()))
|
||||||
irc.replySuccess()
|
irc.replySuccess()
|
||||||
except KeyError:
|
except KeyError:
|
||||||
s = self.registryValue('replyNoBugtracker', ircutils.isChannel(msg.args[0]) and msg.args[0] or None)
|
s = self.registryValue('replyNoBugtracker', ircutils.isChannel(msg.args[0]) and msg.args[0] or None)
|
||||||
@ -319,7 +323,7 @@ class Bugtracker(callbacks.PluginRegexp):
|
|||||||
irc.error(s % name)
|
irc.error(s % name)
|
||||||
else:
|
else:
|
||||||
if self.db:
|
if self.db:
|
||||||
L = self.db.keys()
|
L = list(self.db.keys())
|
||||||
L.sort()
|
L.sort()
|
||||||
irc.reply(utils.str.commaAndify(L))
|
irc.reply(utils.str.commaAndify(L))
|
||||||
else:
|
else:
|
||||||
@ -355,7 +359,7 @@ class Bugtracker(callbacks.PluginRegexp):
|
|||||||
# filter out bug number that are 4 numbers, start with '1' and end in '04' or '10
|
# filter out bug number that are 4 numbers, start with '1' and end in '04' or '10
|
||||||
# (let's fix this for 2020 ;)
|
# (let's fix this for 2020 ;)
|
||||||
if match.group('bt').lower() == 'ubuntu':
|
if match.group('bt').lower() == 'ubuntu':
|
||||||
bugids = filter(lambda bugnum: not (len(bugnum) == 4 and bugnum[0] == '1' and bugnum[2:] in ('04', '10')), bugids)
|
bugids = [bugnum for bugnum in bugids if not (len(bugnum) == 4 and bugnum[0] == '1' and bugnum[2:] in ('04', '10'))]
|
||||||
# End HACK
|
# End HACK
|
||||||
|
|
||||||
if not sure_bug:
|
if not sure_bug:
|
||||||
@ -364,7 +368,7 @@ class Bugtracker(callbacks.PluginRegexp):
|
|||||||
bugids = list(set(bugids)) ## remove dups
|
bugids = list(set(bugids)) ## remove dups
|
||||||
|
|
||||||
msg.tag('nbugs', nbugs + len(bugids))
|
msg.tag('nbugs', nbugs + len(bugids))
|
||||||
bt = map(lambda x: x.lower(), match.group('bt').split())
|
bt = [x.lower() for x in match.group('bt').split()]
|
||||||
# Strip off trailing ':' from the tracker name. Allows for (LP: #nnnnnn)
|
# Strip off trailing ':' from the tracker name. Allows for (LP: #nnnnnn)
|
||||||
if bt and bt[0].endswith(':'):
|
if bt and bt[0].endswith(':'):
|
||||||
bt[0] = bt[:-1]
|
bt[0] = bt[:-1]
|
||||||
@ -407,7 +411,7 @@ class Bugtracker(callbacks.PluginRegexp):
|
|||||||
except BugNotFoundError:
|
except BugNotFoundError:
|
||||||
if self.registryValue('replyWhenNotFound'):
|
if self.registryValue('replyWhenNotFound'):
|
||||||
irc.error("%s bug %d could not be found" % (tracker.description, bugid))
|
irc.error("%s bug %d could not be found" % (tracker.description, bugid))
|
||||||
except BugtrackerError, e:
|
except BugtrackerError as e:
|
||||||
# if 'private' in str(e):
|
# if 'private' in str(e):
|
||||||
# irc.reply("Bug %d on http://launchpad.net/bugs/%d is private" % (bugid, bugid))
|
# irc.reply("Bug %d on http://launchpad.net/bugs/%d is private" % (bugid, bugid))
|
||||||
# return
|
# return
|
||||||
@ -433,9 +437,9 @@ class Bugtracker(callbacks.PluginRegexp):
|
|||||||
if not tracker:
|
if not tracker:
|
||||||
return
|
return
|
||||||
report = self.get_bug(channel, tracker, int(match.group('bug')), self.registryValue('showassignee', channel), do_url = False)
|
report = self.get_bug(channel, tracker, int(match.group('bug')), self.registryValue('showassignee', channel), do_url = False)
|
||||||
except BugtrackerError, e:
|
except BugtrackerError as e:
|
||||||
irc.error(str(e))
|
irc.error(str(e))
|
||||||
except BugNotFoundError, e:
|
except BugNotFoundError as e:
|
||||||
irc.error("%s bug %s not found" % (tracker, match.group('bug')))
|
irc.error("%s bug %s not found" % (tracker, match.group('bug')))
|
||||||
else:
|
else:
|
||||||
for r in report:
|
for r in report:
|
||||||
@ -463,7 +467,7 @@ class Bugtracker(callbacks.PluginRegexp):
|
|||||||
if not self.is_ok(channel, 'cve', cve):
|
if not self.is_ok(channel, 'cve', cve):
|
||||||
return
|
return
|
||||||
url = 'http://cve.mitre.org/cgi-bin/cvename.cgi?name=%s' % cve
|
url = 'http://cve.mitre.org/cgi-bin/cvename.cgi?name=%s' % cve
|
||||||
cvedata = utils.web.getUrl(url)
|
cvedata = utils.web.getUrl(url).decode('utf-8')
|
||||||
m = cvere.search(cvedata)
|
m = cvere.search(cvedata)
|
||||||
if m:
|
if m:
|
||||||
cve = m.group(1).replace('\n', ' ')
|
cve = m.group(1).replace('\n', ' ')
|
||||||
@ -500,7 +504,7 @@ class Bugtracker(callbacks.PluginRegexp):
|
|||||||
if 'sourceforge.net' in snarfurl: # See below
|
if 'sourceforge.net' in snarfurl: # See below
|
||||||
return None
|
return None
|
||||||
|
|
||||||
for t in self.db.keys():
|
for t in list(self.db.keys()):
|
||||||
tracker = self.db.get(t, None)
|
tracker = self.db.get(t, None)
|
||||||
if not tracker:
|
if not tracker:
|
||||||
self.log.error("No tracker for key %r" % t)
|
self.log.error("No tracker for key %r" % t)
|
||||||
@ -525,7 +529,7 @@ class Bugtracker(callbacks.PluginRegexp):
|
|||||||
tracker = Bugzilla().get_tracker(snarfurl)
|
tracker = Bugzilla().get_tracker(snarfurl)
|
||||||
if tracker:
|
if tracker:
|
||||||
self.db[tracker.name] = tracker
|
self.db[tracker.name] = tracker
|
||||||
self.shorthand = utils.abbrev(self.db.keys())
|
self.shorthand = utils.abbrev(list(self.db.keys()))
|
||||||
return tracker
|
return tracker
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@ -613,16 +617,16 @@ class Bugzilla(IBugtracker):
|
|||||||
try:
|
try:
|
||||||
bugxml = utils.web.getUrl(url)
|
bugxml = utils.web.getUrl(url)
|
||||||
zilladom = minidom.parseString(bugxml)
|
zilladom = minidom.parseString(bugxml)
|
||||||
except Exception, e:
|
except Exception as e:
|
||||||
s = 'Could not parse XML returned by %s: %s (%s)' % (self.description, e, url)
|
s = 'Could not parse XML returned by %s: %s (%s)' % (self.description, e, url)
|
||||||
raise BugtrackerError, s
|
raise BugtrackerError(s)
|
||||||
bug_n = zilladom.getElementsByTagName('bug')[0]
|
bug_n = zilladom.getElementsByTagName('bug')[0]
|
||||||
if bug_n.hasAttribute('error'):
|
if bug_n.hasAttribute('error'):
|
||||||
errtxt = bug_n.getAttribute('error')
|
errtxt = bug_n.getAttribute('error')
|
||||||
if errtxt == 'NotFound':
|
if errtxt == 'NotFound':
|
||||||
raise BugNotFoundError
|
raise BugNotFoundError
|
||||||
s = 'Error getting %s bug #%s: %s' % (self.description, id, errtxt)
|
s = 'Error getting %s bug #%s: %s' % (self.description, id, errtxt)
|
||||||
raise BugtrackerError, s
|
raise BugtrackerError(s)
|
||||||
try:
|
try:
|
||||||
title = _getnodetxt(bug_n.getElementsByTagName('short_desc')[0])
|
title = _getnodetxt(bug_n.getElementsByTagName('short_desc')[0])
|
||||||
status = _getnodetxt(bug_n.getElementsByTagName('bug_status')[0])
|
status = _getnodetxt(bug_n.getElementsByTagName('bug_status')[0])
|
||||||
@ -637,9 +641,9 @@ class Bugzilla(IBugtracker):
|
|||||||
assignee = _getnodetxt(bug_n.getElementsByTagName('assigned_to')[0])
|
assignee = _getnodetxt(bug_n.getElementsByTagName('assigned_to')[0])
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
except Exception, e:
|
except Exception as e:
|
||||||
s = 'Could not parse XML returned by %s bugzilla: %s (%s)' % (self.description, e, url)
|
s = 'Could not parse XML returned by %s bugzilla: %s (%s)' % (self.description, e, url)
|
||||||
raise BugtrackerError, s
|
raise BugtrackerError(s)
|
||||||
return [(id, component, title, severity, status, assignee, "%s/show_bug.cgi?id=%d" % (self.url, id))]
|
return [(id, component, title, severity, status, assignee, "%s/show_bug.cgi?id=%d" % (self.url, id))]
|
||||||
|
|
||||||
class Issuezilla(Bugzilla):
|
class Issuezilla(Bugzilla):
|
||||||
@ -705,7 +709,7 @@ class Launchpad(IBugtracker):
|
|||||||
supylog.exception("Unknown exception while accessing the Launchpad API")
|
supylog.exception("Unknown exception while accessing the Launchpad API")
|
||||||
|
|
||||||
def _parse(self, task): #Depricated
|
def _parse(self, task): #Depricated
|
||||||
parser = email.FeedParser.FeedParser()
|
parser = FeedParser()
|
||||||
parser.feed(task)
|
parser.feed(task)
|
||||||
return parser.close()
|
return parser.close()
|
||||||
|
|
||||||
@ -769,7 +773,7 @@ class Launchpad(IBugtracker):
|
|||||||
try:
|
try:
|
||||||
bugdata = self.lp.bugs[id]
|
bugdata = self.lp.bugs[id]
|
||||||
if bugdata.private:
|
if bugdata.private:
|
||||||
raise BugtrackerError, "This bug is private"
|
raise BugtrackerError("This bug is private")
|
||||||
dup = bugdata.duplicate_of
|
dup = bugdata.duplicate_of
|
||||||
summary_prefix = '' # Used to made dups easier
|
summary_prefix = '' # Used to made dups easier
|
||||||
while dup:
|
while dup:
|
||||||
@ -784,14 +788,14 @@ class Launchpad(IBugtracker):
|
|||||||
if tasks.total_size != 1:
|
if tasks.total_size != 1:
|
||||||
tasks = list(tasks)
|
tasks = list(tasks)
|
||||||
try:
|
try:
|
||||||
tasks.sort(self._sort)
|
tasks = sorted(tasks, key=cmp_to_key(self._sort))
|
||||||
taskdata = tasks[-1]
|
taskdata = tasks[-1]
|
||||||
except ValueError:
|
except ValueError:
|
||||||
tasks = [_ for _ in tasks if _.bug_target_name.endswith(u'(Ubuntu)')]
|
tasks = [_ for _ in tasks if _.bug_target_name.endswith('(Ubuntu)')]
|
||||||
if tasks:
|
if tasks:
|
||||||
if len(tasks) != 1:
|
if len(tasks) != 1:
|
||||||
try:
|
try:
|
||||||
tasks.sort(self._sort)
|
tasks = sorted(tasks, key=cmp_to_key(self._sort))
|
||||||
taskdata = tasks[-1]
|
taskdata = tasks[-1]
|
||||||
except ValueError:
|
except ValueError:
|
||||||
taskdata = bugdata.bug_tasks[bugdata.bug_tasks.total_size - 1]
|
taskdata = bugdata.bug_tasks[bugdata.bug_tasks.total_size - 1]
|
||||||
@ -806,24 +810,24 @@ class Launchpad(IBugtracker):
|
|||||||
t = taskdata.bug_target_display_name #task name
|
t = taskdata.bug_target_display_name #task name
|
||||||
|
|
||||||
if assignee: # "Diaplay Name (Launchpad ID)"
|
if assignee: # "Diaplay Name (Launchpad ID)"
|
||||||
assignee = u"%s (%s)" % (assignee.display_name, assignee.name)
|
assignee = "%s (%s)" % (assignee.display_name, assignee.name)
|
||||||
else:
|
else:
|
||||||
assignee = ''
|
assignee = ''
|
||||||
|
|
||||||
except Exception, e:
|
except Exception as e:
|
||||||
if type(e).__name__ == 'HTTPError': # messy, but saves trying to import lazr.restfulclient.errors.HTPError
|
if type(e).__name__ == 'HTTPError': # messy, but saves trying to import lazr.restfulclient.errors.HTPError
|
||||||
if e.response.status == 404:
|
if e.response.status == 404:
|
||||||
bugNo = e.content.split(None)[-1][2:-1] # extract the real bug number
|
bugNo = e.content.split(None)[-1][2:-1] # extract the real bug number
|
||||||
if bugNo != str(id): # A duplicate of a private bug, at least we know it exists
|
if bugNo != str(id): # A duplicate of a private bug, at least we know it exists
|
||||||
raise BugtrackerError, 'Bug #%s is a duplicate of bug #%s, but it is private (%s/bugs/%s)' % (id, bugNo, self.url, bugNo)
|
raise BugtrackerError('Bug #%s is a duplicate of bug #%s, but it is private (%s/bugs/%s)' % (id, bugNo, self.url, bugNo))
|
||||||
raise BugtrackerError, "Bug #%s (%s/bugs/%d) is private or doesn't exist" % (id, self.url, id) # Could be private, could just not exist
|
raise BugtrackerError("Bug #%s (%s/bugs/%d) is private or doesn't exist" % (id, self.url, id)) # Could be private, could just not exist
|
||||||
|
|
||||||
supylog.exception("Error gathering bug data for %s bug #%d" % (self.description, id))
|
supylog.exception("Error gathering bug data for %s bug #%d" % (self.description, id))
|
||||||
raise BugtrackerError, "Could not gather data from %s for bug #%s (%s/bugs/%s). The error has been logged" % (self.description, id, self.url, id)
|
raise BugtrackerError("Could not gather data from %s for bug #%s (%s/bugs/%s). The error has been logged" % (self.description, id, self.url, id))
|
||||||
elif isinstance(e, KeyError):
|
elif isinstance(e, KeyError):
|
||||||
raise BugNotFoundError
|
raise BugNotFoundError
|
||||||
supylog.exception("Error gathering bug data for %s bug %d" % (self.description, id))
|
supylog.exception("Error gathering bug data for %s bug %d" % (self.description, id))
|
||||||
raise BugtrackerError, "Could not gather data from %s for bug #%s (%s/bugs/%s). The error has been logged" % (self.description, id, self.url, id)
|
raise BugtrackerError("Could not gather data from %s for bug #%s (%s/bugs/%s). The error has been logged" % (self.description, id, self.url, id))
|
||||||
|
|
||||||
extinfo = "(affected: %d, heat: %d)" % (affected, heat)
|
extinfo = "(affected: %d, heat: %d)" % (affected, heat)
|
||||||
|
|
||||||
@ -832,34 +836,34 @@ class Launchpad(IBugtracker):
|
|||||||
|
|
||||||
def get_bug_old(self, id): #Depricated
|
def get_bug_old(self, id): #Depricated
|
||||||
if id == 1:
|
if id == 1:
|
||||||
raise BugtrackerError, "https://bugs.launchpad.net/ubuntu/+bug/1 (Not reporting large bug)"
|
raise BugtrackerError("https://bugs.launchpad.net/ubuntu/+bug/1 (Not reporting large bug)")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
bugdata = utils.web.getUrl("%s/bugs/%d/+text" % (self.url,id))
|
bugdata = utils.web.getUrl("%s/bugs/%d/+text" % (self.url,id)).decode('utf-8')
|
||||||
except Exception, e:
|
except Exception as e:
|
||||||
if '404' in str(e):
|
if '404' in str(e):
|
||||||
raise BugNotFoundError
|
raise BugNotFoundError
|
||||||
s = 'Could not parse data returned by %s: %s (%s/bugs/%d)' % (self.description, e, self.url, id)
|
s = 'Could not parse data returned by %s: %s (%s/bugs/%d)' % (self.description, e, self.url, id)
|
||||||
raise BugtrackerError, s
|
raise BugtrackerError(s)
|
||||||
summary = {}
|
summary = {}
|
||||||
# Trap private bugs
|
# Trap private bugs
|
||||||
if "<!-- 4a. didn't try to log in last time: -->" in bugdata:
|
if "<!-- 4a. didn't try to log in last time: -->" in bugdata:
|
||||||
raise BugtrackerError, "This bug is private"
|
raise BugtrackerError("This bug is private")
|
||||||
try:
|
try:
|
||||||
# Split bug data into separate pieces (bug data, task data)
|
# Split bug data into separate pieces (bug data, task data)
|
||||||
data = bugdata.split('\n\n')
|
data = bugdata.split('\n\n')
|
||||||
bugdata = data[0]
|
bugdata = data[0]
|
||||||
taskdata = data[1:]
|
taskdata = data[1:]
|
||||||
parser = email.FeedParser.FeedParser()
|
parser = FeedParser()
|
||||||
parser.feed(bugdata)
|
parser.feed(bugdata)
|
||||||
bugdata = parser.close()
|
bugdata = parser.close()
|
||||||
taskdata = map(self._parse, taskdata)
|
taskdata = list(map(self._parse, taskdata))
|
||||||
taskdata.sort(self._old_sort)
|
taskdata = sorted(taskdata, key=cmp_to_key(self._old_sort))
|
||||||
taskdata = taskdata[-1]
|
taskdata = taskdata[-1]
|
||||||
|
|
||||||
except Exception, e:
|
except Exception as e:
|
||||||
s = 'Could not parse data returned by %s: %s (%s/bugs/%d)' % (self.description, e, self.url, id)
|
s = 'Could not parse data returned by %s: %s (%s/bugs/%d)' % (self.description, e, self.url, id)
|
||||||
raise BugtrackerError, s
|
raise BugtrackerError(s)
|
||||||
# Try and find duplicates
|
# Try and find duplicates
|
||||||
t = taskdata['task']
|
t = taskdata['task']
|
||||||
if '(' in t:
|
if '(' in t:
|
||||||
@ -868,9 +872,9 @@ class Launchpad(IBugtracker):
|
|||||||
bugNo = bugdata['duplicate-of']
|
bugNo = bugdata['duplicate-of']
|
||||||
try:
|
try:
|
||||||
data = self.get_bug(int(bugdata['duplicate-of']))
|
data = self.get_bug(int(bugdata['duplicate-of']))
|
||||||
except Exception, e:
|
except Exception as e:
|
||||||
if '404' in str(e):
|
if '404' in str(e):
|
||||||
raise BugtrackerError, 'Bug #%s is a duplicate of Bug #%s, but it is private. (%s/bugs/%s)' % (id, bugNo, self.url, bugNo)
|
raise BugtrackerError('Bug #%s is a duplicate of Bug #%s, but it is private. (%s/bugs/%s)' % (id, bugNo, self.url, bugNo))
|
||||||
data = list(data[0])
|
data = list(data[0])
|
||||||
data[2] = ('duplicate for #%d ' % id) + data[2]
|
data[2] = ('duplicate for #%d ' % id) + data[2]
|
||||||
return [tuple(data)]
|
return [tuple(data)]
|
||||||
@ -889,6 +893,9 @@ class Launchpad(IBugtracker):
|
|||||||
# </rant>
|
# </rant>
|
||||||
class Debbugs(IBugtracker):
|
class Debbugs(IBugtracker):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
if not sys.version_info < (3,0):
|
||||||
|
# XXX python3 does not have SOAPpy, so just quit here (for now)
|
||||||
|
return
|
||||||
IBugtracker.__init__(self, *args, **kwargs)
|
IBugtracker.__init__(self, *args, **kwargs)
|
||||||
self.soap_proxy = SOAPpy.SOAPProxy("bugs.debian.org/cgi-bin/soap.cgi", "Debbugs/SOAP/Status")
|
self.soap_proxy = SOAPpy.SOAPProxy("bugs.debian.org/cgi-bin/soap.cgi", "Debbugs/SOAP/Status")
|
||||||
self.soap_proxy.soapaction = "Debbugs/SOAP/Status#get_status"
|
self.soap_proxy.soapaction = "Debbugs/SOAP/Status#get_status"
|
||||||
@ -897,9 +904,9 @@ class Debbugs(IBugtracker):
|
|||||||
bug_url = "http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=%d" % id
|
bug_url = "http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=%d" % id
|
||||||
try:
|
try:
|
||||||
raw = self.soap_proxy.get_status(id)
|
raw = self.soap_proxy.get_status(id)
|
||||||
except Exception, e:
|
except Exception as e:
|
||||||
s = 'Could not parse data returned by %s: %s' % (self.description, e)
|
s = 'Could not parse data returned by %s: %s' % (self.description, e)
|
||||||
raise BugtrackerError, s
|
raise BugtrackerError(s)
|
||||||
if not raw:
|
if not raw:
|
||||||
raise BugNotFoundError
|
raise BugNotFoundError
|
||||||
raw = raw['item']['value']
|
raw = raw['item']['value']
|
||||||
@ -909,12 +916,15 @@ class Debbugs(IBugtracker):
|
|||||||
else:
|
else:
|
||||||
status = 'Open'
|
status = 'Open'
|
||||||
return [(id, raw['package'], raw['subject'], raw['severity'], status, '', "%s/%s" % (self.url, id))]
|
return [(id, raw['package'], raw['subject'], raw['severity'], status, '', "%s/%s" % (self.url, id))]
|
||||||
except Exception, e:
|
except Exception as e:
|
||||||
s = 'Could not parse data returned by %s bugtracker: %s (%s)' % (self.description, e, bug_url)
|
s = 'Could not parse data returned by %s bugtracker: %s (%s)' % (self.description, e, bug_url)
|
||||||
raise BugtrackerError, s
|
raise BugtrackerError(s)
|
||||||
|
|
||||||
class Mantis(IBugtracker):
|
class Mantis(IBugtracker):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
if not sys.version_info < (3,0):
|
||||||
|
# XXX python3 does not have SOAPpy, so just quit here (for now)
|
||||||
|
return
|
||||||
IBugtracker.__init__(self, *args, **kwargs)
|
IBugtracker.__init__(self, *args, **kwargs)
|
||||||
self.soap_proxy = SOAPpy.SOAPProxy(self.url + "/api/soap/mantisconnect.php", "http://futureware.biz/mantisconnect")
|
self.soap_proxy = SOAPpy.SOAPProxy(self.url + "/api/soap/mantisconnect.php", "http://futureware.biz/mantisconnect")
|
||||||
self.soap_proxy.soapaction = "http://futureware.biz/mantisconnect#mc_issue_get"
|
self.soap_proxy.soapaction = "http://futureware.biz/mantisconnect#mc_issue_get"
|
||||||
@ -923,16 +933,16 @@ class Mantis(IBugtracker):
|
|||||||
url = self.url + "/view.php?id=%i" % id
|
url = self.url + "/view.php?id=%i" % id
|
||||||
try:
|
try:
|
||||||
raw = self.soap_proxy.mc_issue_get('', "", id)
|
raw = self.soap_proxy.mc_issue_get('', "", id)
|
||||||
except Exception, e:
|
except Exception as e:
|
||||||
s = 'Could not parse data returned by %s: %s (%s)' % (self.description, e, url)
|
s = 'Could not parse data returned by %s: %s (%s)' % (self.description, e, url)
|
||||||
raise BugtrackerError, s
|
raise BugtrackerError(s)
|
||||||
if not raw:
|
if not raw:
|
||||||
raise BugNotFoundError
|
raise BugNotFoundError
|
||||||
try:
|
try:
|
||||||
return [(id, raw['project']['name'], raw['summary'], raw['priority']['name'], raw['resolution']['name'], '', url)]
|
return [(id, raw['project']['name'], raw['summary'], raw['priority']['name'], raw['resolution']['name'], '', url)]
|
||||||
except Exception, e:
|
except Exception as e:
|
||||||
s = 'Could not parse data returned by %s bugtracker: %s (%s)' % (self.description, e, url)
|
s = 'Could not parse data returned by %s bugtracker: %s (%s)' % (self.description, e, url)
|
||||||
raise BugtrackerError, s
|
raise BugtrackerError(s)
|
||||||
|
|
||||||
# For trac based trackers we get the tab-separated-values format.
|
# For trac based trackers we get the tab-separated-values format.
|
||||||
# The other option is a comma-separated-values format, but if the description
|
# The other option is a comma-separated-values format, but if the description
|
||||||
@ -942,12 +952,12 @@ class Trac(IBugtracker):
|
|||||||
def get_bug(self, id): # This is still a little rough, but it works :)
|
def get_bug(self, id): # This is still a little rough, but it works :)
|
||||||
bug_url = "%s/%d" % (self.url, id)
|
bug_url = "%s/%d" % (self.url, id)
|
||||||
try:
|
try:
|
||||||
raw = utils.web.getUrl("%s?format=tab" % bug_url)
|
raw = utils.web.getUrl("%s?format=tab" % bug_url).decode('utf-8')
|
||||||
except Exception, e:
|
except Exception as e:
|
||||||
if 'HTTP Error 500' in str(e):
|
if 'HTTP Error 500' in str(e):
|
||||||
raise BugNotFoundError
|
raise BugNotFoundError
|
||||||
s = 'Could not parse data returned by %s: %s' % (self.description, e, bug_url)
|
s = 'Could not parse data returned by %s: %s' % (self.description, e, bug_url)
|
||||||
raise BugtrackerError, s
|
raise BugtrackerError(s)
|
||||||
raw = raw.replace("\r\n", '\n')
|
raw = raw.replace("\r\n", '\n')
|
||||||
(headers, rest) = raw.split('\n', 1)
|
(headers, rest) = raw.split('\n', 1)
|
||||||
headers = headers.strip().split('\t')
|
headers = headers.strip().split('\t')
|
||||||
@ -977,12 +987,12 @@ class WikiForms(IBugtracker):
|
|||||||
|
|
||||||
url = "%s/%05d" % (self.url, id)
|
url = "%s/%05d" % (self.url, id)
|
||||||
try:
|
try:
|
||||||
bugdata = utils.web.getUrl(url)
|
bugdata = utils.web.getUrl(url).decode('utf-8')
|
||||||
except Exception, e:
|
except Exception as e:
|
||||||
if 'HTTP Error 404' in str(e):
|
if 'HTTP Error 404' in str(e):
|
||||||
raise BugNotFoundError
|
raise BugNotFoundError
|
||||||
s = 'Could not parse data returned by %s: %s (%s)' % (self.description, e, url)
|
s = 'Could not parse data returned by %s: %s (%s)' % (self.description, e, url)
|
||||||
raise BugtrackerError, s
|
raise BugtrackerError(s)
|
||||||
for l in bugdata.split("\n"):
|
for l in bugdata.split("\n"):
|
||||||
l2 = l.lower()
|
l2 = l.lower()
|
||||||
if '<dt>importance</dt>' in l2:
|
if '<dt>importance</dt>' in l2:
|
||||||
@ -1003,10 +1013,10 @@ class Str(IBugtracker):
|
|||||||
return s
|
return s
|
||||||
url = "%s?L%d" % (self.url, id)
|
url = "%s?L%d" % (self.url, id)
|
||||||
try:
|
try:
|
||||||
bugdata = utils.web.getUrl(url)
|
bugdata = utils.web.getUrl(url).decode('utf-8')
|
||||||
except Exception, e:
|
except Exception as e:
|
||||||
s = 'Could not parse data returned by %s: %s (%s)' % (self.description, e, url)
|
s = 'Could not parse data returned by %s: %s (%s)' % (self.description, e, url)
|
||||||
raise BugtrackerError, s
|
raise BugtrackerError(s)
|
||||||
for l in bugdata.split("\n"):
|
for l in bugdata.split("\n"):
|
||||||
l2 = l.lower()
|
l2 = l.lower()
|
||||||
if 'nowrap>priority:</th>' in l2:
|
if 'nowrap>priority:</th>' in l2:
|
||||||
@ -1043,10 +1053,10 @@ class Sourceforge(IBugtracker):
|
|||||||
def get_bug(self, id):
|
def get_bug(self, id):
|
||||||
url = self._sf_url % id
|
url = self._sf_url % id
|
||||||
try:
|
try:
|
||||||
bugdata = utils.web.getUrl(url)
|
bugdata = utils.web.getUrl(url).decode('utf-8')
|
||||||
except Exception, e:
|
except Exception as e:
|
||||||
s = 'Could not parse data returned by %s: %s (%s)' % (self.description, e, url)
|
s = 'Could not parse data returned by %s: %s (%s)' % (self.description, e, url)
|
||||||
raise BugtrackerError, s
|
raise BugtrackerError(s)
|
||||||
try:
|
try:
|
||||||
reo = sfre.search(bugdata)
|
reo = sfre.search(bugdata)
|
||||||
status = reo.group('status')
|
status = reo.group('status')
|
||||||
@ -1060,7 +1070,7 @@ class Sourceforge(IBugtracker):
|
|||||||
# Introspection is quite cool
|
# Introspection is quite cool
|
||||||
defined_bugtrackers = {}
|
defined_bugtrackers = {}
|
||||||
v = vars()
|
v = vars()
|
||||||
for k in v.keys():
|
for k in list(v.keys()):
|
||||||
if type(v[k]) == type(IBugtracker) and issubclass(v[k], IBugtracker) and not (v[k] == IBugtracker):
|
if type(v[k]) == type(IBugtracker) and issubclass(v[k], IBugtracker) and not (v[k] == IBugtracker):
|
||||||
defined_bugtrackers[k.lower()] = v[k]
|
defined_bugtrackers[k.lower()] = v[k]
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user