Yay! Finally able to consolidate Sourceforge.{rfe,bug} into

Sourceforge.tracker. Less code, more functionality. What could be better?
This commit is contained in:
James Vega 2004-04-15 06:20:21 +00:00
parent c428e8908b
commit 08fc07b698
3 changed files with 73 additions and 127 deletions

View File

@ -1,3 +1,7 @@
* Replaced Sourceforge.{rfe,bug} with Sourceforge.tracker, which
can query any tracker type (not just RFEs and bugs) and responds
with more information, a la trackerSnarfer.
* Added supybot.log.individualPluginLogfiles, which determines
whether plugin logs will be logged to their individual logfiles
in addition to the misc.log logfile.

View File

@ -108,13 +108,15 @@ class Sourceforge(callbacks.PrivmsgCommandAndRegexp):
'&_group=100&order=artifact_id&sort=DESC'
_resolution=re.compile(r'<b>(Resolution):</b> <a.+?<br>(.+?)</td>',_reopts)
_assigned=re.compile(r'<b>(Assigned To):</b> <a.+?<br>(.+?)</td>', _reopts)
_submitted = re.compile(r'<b>(Submitted By):</b><br>([^<]+)</td>', _reopts)
_submitted = re.compile(r'<b>(Submitted By):</b><br>([^-]+) - '
r'(?:nobody|<a href)', _reopts)
_priority = re.compile(r'<b>(Priority):</b> <a.+?<br>(.+?)</td>', _reopts)
_status = re.compile(r'<b>(Status):</b> <a.+?<br>(.+?)</td>', _reopts)
_regexps =(_resolution, _assigned, _submitted, _priority, _status)
_statusOpt = {'any':100, 'open':1, 'closed':2, 'deleted':3, 'pending':4}
_projectURL = 'http://sourceforge.net/projects/'
_trackerURL = 'https://sourceforge.net/support/tracker.php?aid='
def __init__(self):
callbacks.PrivmsgCommandAndRegexp.__init__(self)
self.__class__.sf = self.__class__.sourceforge
@ -159,16 +161,49 @@ class Sourceforge(callbacks.PrivmsgCommandAndRegexp):
except webutils.WebError, e:
raise callbacks.Error, str(e)
def _getTrackerInfo(self, irc, msg, url, num):
_bold = lambda self, m: (ircutils.bold(m[0]),) + m[1:]
_sfTitle = re.compile(r'Detail:(\d+) - ([^<]+)</title>', re.I)
_linkType = re.compile(r'(\w+ \w+|\w+): Tracker Detailed View', re.I)
def _getTrackerInfo(self, url):
try:
text = webutils.getUrl(url)
head = '%s <http://sourceforge.net%s>'
resp = [head % match for match in self._formatResp(text,num)]
if resp:
irc.reply(resp[0])
return
irc.errorPossibleBug('No Trackers were found.')
s = webutils.getUrl(url)
self.log.warning(s)
resp = []
head = ''
m = self._linkType.search(s)
n = self._sfTitle.search(s)
if m and n:
linktype = m.group(1)
linktype = utils.depluralize(linktype)
(num, desc) = n.groups()
head = '%s #%s:' % (ircutils.bold(linktype), num)
resp.append(desc)
else:
return None
for r in self._regexps:
m = r.search(s)
if m:
resp.append('%s: %s' % self._bold(m.groups()))
return '%s #%s: %s' % (ircutils.bold(linktype), ircutils.bold(num),
'; '.join(resp))
except webutils.WebError, e:
raise TrackerError, str(e)
def tracker(self, irc, msg, args):
"""<num>
Returns a description of the tracker with Tracker id <num> and the
corresponding Tracker url.
"""
num = privmsgs.getArgs(args)
try:
url = '%s%s' % (self._trackerURL, num)
resp = self._getTrackerInfo(url)
if resp is None:
irc.error('Invalid Tracker page snarfed: %s' % url)
else:
irc.reply(resp)
except TrackerError, e:
irc.error(str(e))
_bugLink = re.compile(r'"([^"]+)">Bugs')
@ -225,38 +260,6 @@ class Sourceforge(callbacks.PrivmsgCommandAndRegexp):
else:
irc.error('Could not find bug statistics.')
def bug(self, irc, msg, args):
"""[--{any,open,closed,deleted,pending}] [<project>] <num>
Returns a description of the bug with Tracker id <num> and the
corresponding Tracker URL. <project> is not needed if there is a
default project set. Search defaults to open bugs.
"""
(optlist, rest) = getopt.getopt(args, '', self._statusOpt.keys())
(project, bugnum) = privmsgs.getArgs(rest, optional=1)
status = 'open'
for (option, _) in optlist:
option = option.lstrip('-').lower()
if option in self._statusOpt:
status = option
if not bugnum:
try:
int(project)
except ValueError:
irc.error('"%s" is not a proper bugnumber.' % project)
return
bugnum = project
project = self.registryValue('defaultProject', msg.args[0])
if not project:
raise callbacks.ArgumentError
try:
url = self._getTrackerURL(project, self._bugLink, status)
#self.log.warning(url)
except TrackerError, e:
irc.error('%s. I can\'t find the Bugs link.' % e)
return
self._getTrackerInfo(irc, msg, url, bugnum)
_rfeLink = re.compile(r'"([^"]+)">RFE')
def rfes(self, irc, msg, args):
"""[--{any,open,closed,deleted,pending}] [<project>]
@ -310,40 +313,6 @@ class Sourceforge(callbacks.PrivmsgCommandAndRegexp):
else:
irc.error('Could not find RFE statistics.')
def rfe(self, irc, msg, args):
"""[--{any,open,closed,deleted,pending}] [<project>] <num>
Returns a description of the bug with Tracker id <num> and the
corresponding Tracker URL. <project> is not needed if there is a
default project set. Search defaults to open RFEs.
"""
(optlist, rest) = getopt.getopt(args, '', self._statusOpt.keys())
(project, rfenum) = privmsgs.getArgs(rest, optional=1)
status = 'open'
for (option, _) in optlist:
option = option.lstrip('-').lower()
if option in self._statusOpt:
status = option
if not rfenum:
try:
int(project)
except ValueError:
irc.error('"%s" is not a proper rfenumber.' % project)
return
rfenum = project
project = self.registryValue('defaultProject', msg.args[0])
if not project:
raise callbacks.ArgumentError
try:
url = self._getTrackerURL(project, self._rfeLink, status)
except TrackerError, e:
irc.error('%s. I can\'t find the RFEs link.' % e)
return
self._getTrackerInfo(irc, msg, url, rfenum)
_bold = lambda self, m: (ircutils.bold(m[0]),) + m[1:]
_sfTitle = re.compile(r'Detail:(\d+) - ([^<]+)</title>', re.I)
_linkType = re.compile(r'(\w+ \w+|\w+): Tracker Detailed View', re.I)
def sfSnarfer(self, irc, msg, match):
r"https?://(?:www\.)?(?:sourceforge|sf)\.net/tracker/" \
r".*\?(?:&?func=detail|&?aid=\d+|&?group_id=\d+|&?atid=\d+){4}"
@ -351,26 +320,12 @@ class Sourceforge(callbacks.PrivmsgCommandAndRegexp):
return
try:
url = match.group(0)
s = webutils.getUrl(url)
resp = []
head = ''
m = self._linkType.search(s)
n = self._sfTitle.search(s)
if m and n:
linktype = m.group(1)
linktype = utils.depluralize(linktype)
(num, desc) = n.groups()
head = '%s #%s:' % (ircutils.bold(linktype), num)
resp.append(desc)
else:
resp = self._getTrackerInfo(url)
if resp is None:
self.log.warning('Invalid Tracker page snarfed: %s', url)
for r in self._regexps:
m = r.search(s)
if m:
resp.append('%s: %s' % self._bold(m.groups()))
irc.reply('%s #%s: %s' % (ircutils.bold(linktype),
ircutils.bold(num), '; '.join(resp)), prefixName = False)
except webutils.WebError, e:
else:
irc.reply(resp, prefixName=False)
except TrackerError, e:
self.log.warning(str(e))
sfSnarfer = privmsgs.urlSnarfer(sfSnarfer)

View File

@ -34,56 +34,47 @@ import re
from testsupport import *
if network:
class SourceforgeTest(ChannelPluginTestCase, PluginDocumentation):
class SourceforgeTest(ChannelPluginTestCase):
plugins = ('Sourceforge',)
def testBug(self):
self.assertHelp('bug')
m = self.getMsg('bugs gaim')
self.failUnless(m, 'No response from Sourceforge.')
n = re.search('#(\d+)', m.args[1]).group(1)
self.assertNotError('bug gaim %s' % n)
self.assertError('bug gaim')
self.assertRegexp('bug lkadf 9', 'find the Bugs')
def testAny(self):
m = self.getMsg('bugs --any gaim')
self.failUnless(m, 'No response from Sourceforge.')
n = re.search('#(\d+)', m.args[1]).group(1)
self.assertNotError('bug --any gaim %s' % n)
self.assertNotError('tracker %s' % n)
m = self.getMsg('rfes --any gaim')
self.failUnless(m, 'No response from Sourceforge.')
n = re.search('#(\d+)', m.args[1]).group(1)
self.assertNotError('rfe --any gaim %s' % n)
self.assertNotError('tracker %s' % n)
def testClosed(self):
m = self.getMsg('bugs --closed gaim')
self.failUnless(m, 'No response from Sourceforge.')
n = re.search('#(\d+)', m.args[1]).group(1)
self.assertNotError('bug --closed gaim %s' % n)
self.assertNotError('tracker %s' % n)
m = self.getMsg('rfes --closed gaim')
self.failUnless(m, 'No response from Sourceforge.')
n = re.search('#(\d+)', m.args[1]).group(1)
self.assertNotError('rfe --closed gaim %s' % n)
self.assertNotError('tracker %s' % n)
def testDeleted(self):
m = self.getMsg('bugs --deleted gaim')
self.failUnless(m, 'No response from Sourceforge.')
n = re.search('#(\d+)', m.args[1]).group(1)
self.assertNotError('bug --deleted gaim %s' % n)
self.assertNotError('tracker %s' % n)
m = self.getMsg('rfes --deleted gaim')
self.failUnless(m, 'No response from Sourceforge.')
n = re.search('#(\d+)', m.args[1]).group(1)
self.assertNotError('rfe --deleted gaim %s' % n)
self.assertNotError('tracker %s' % n)
def testOpen(self):
m = self.getMsg('bugs --open gaim')
self.failUnless(m, 'No response from Sourceforge.')
n = re.search('#(\d+)', m.args[1]).group(1)
self.assertNotError('bug --open gaim %s' % n)
self.assertNotError('tracker %s' % n)
m = self.getMsg('rfes --open gaim')
self.failUnless(m, 'No response from Sourceforge.')
n = re.search('#(\d+)', m.args[1]).group(1)
self.assertNotError('rfe --open gaim %s' % n)
self.assertNotError('tracker %s' % n)
def testBugs(self):
self.assertHelp('bugs')
@ -97,14 +88,6 @@ if network:
finally:
conf.supybot.plugins.Sourceforge.defaultProject.set(original)
def testRfe(self):
m = self.getMsg('rfes gaim')
self.failUnless(m, 'No response from Sourceforge.')
n = re.search('#(\d+)', m.args[1]).group(1)
self.assertNotError('rfe gaim %s' % n)
self.assertError('rfe gaim')
self.assertRegexp('rfe lakdf 9', 'find the RFEs')
def testRfes(self):
self.assertHelp('rfes')
self.assertRegexp('rfes 83423', 'Use the rfe command')
@ -118,19 +101,23 @@ if network:
conf.supybot.plugins.Sourceforge.defaultProject.set(original)
def testDefaultproject(self):
self.assertHelp('bugs')
try:
original = conf.supybot.plugins.Sourceforge.defaultProject()
conf.supybot.plugins.Sourceforge.defaultProject.set('supybot')
conf.supybot.plugins.Sourceforge.defaultProject.setValue('supybot')
self.assertNotError('bugs')
m = self.getMsg('bugs')
n = re.search('#(\d+)', m.args[1]).group(1)
self.assertNotError('bug supybot %s' % n)
# This should have the same effect as calling 'bug supybot %s'
self.assertNotError('bug %s' % n)
conf.supybot.plugins.Sourceforge.defaultProject.setValue('')
self.assertHelp('bugs')
finally:
conf.supybot.plugins.Sourceforge.defaultProject.set(original)
def testTracker(self):
bug = r'Bug.*Status.*: \w+'
rfe = r'Feature Request.*Status.*: \w+'
self.assertRegexp('tracker 589953', bug)
self.assertRegexp('tracker 712761', rfe)
self.assertRegexp('tracker 721761', 'Timo Hoenig')
self.assertRegexp('tracker 851239', 'Nobody/Anonymous')
def testSnarfer(self):
s = r'.*Status.*: \w+'
try: