Consolidate @bugs, @rfes into @trackers and add support for retrieving info

on patches.  Add (commented out) infrastructure for supporting usage of
@bugs, @rfes, and @trackers depending on the value of a config var.
This commit is contained in:
James Vega 2004-09-03 19:46:50 +00:00
parent 5f00a39ce4
commit 553a61515c
2 changed files with 71 additions and 92 deletions

View File

@ -96,6 +96,11 @@ conf.registerChannelValue(conf.supybot.plugins.Sourceforge, 'trackerSnarfer',
conf.registerChannelValue(conf.supybot.plugins.Sourceforge, 'defaultProject', conf.registerChannelValue(conf.supybot.plugins.Sourceforge, 'defaultProject',
registry.String('', """Sets the default project to use in the case that no registry.String('', """Sets the default project to use in the case that no
explicit project is given.""")) explicit project is given."""))
#conf.registerGlobalValue(conf.supybot.plugins.Sourceforge,
# 'enableSeparateTrackersCommands',
# registry.Boolean(True, """Determines whether the bot will recognize the
# tracker types as commands. For example, "@bugs supybot" would be the same
# as calling "@trackers bugs supybot"."""))
class Sourceforge(callbacks.PrivmsgCommandAndRegexp): class Sourceforge(callbacks.PrivmsgCommandAndRegexp):
""" """
@ -107,7 +112,7 @@ class Sourceforge(callbacks.PrivmsgCommandAndRegexp):
_reopts = re.I _reopts = re.I
_infoRe = re.compile(r'<td nowrap>(\d+)</td><td><a href=' _infoRe = re.compile(r'<td nowrap>(\d+)</td><td><a href='
r'"([^"]+)">([^<]+)</a>', re.I) r'"([^"]+)">([^<]+)</a>', _reopts)
_hrefOpts = '&set=custom&_assigned_to=0&_status=%s&_category=100' \ _hrefOpts = '&set=custom&_assigned_to=0&_status=%s&_category=100' \
'&_group=100&order=artifact_id&sort=DESC' '&_group=100&order=artifact_id&sort=DESC'
_resolution=re.compile(r'<b>(Resolution):</b> <a.+?<br>(.+?)</td>',_reopts) _resolution=re.compile(r'<b>(Resolution):</b> <a.+?<br>(.+?)</td>',_reopts)
@ -124,9 +129,19 @@ class Sourceforge(callbacks.PrivmsgCommandAndRegexp):
_projectURL = 'http://sourceforge.net/projects/' _projectURL = 'http://sourceforge.net/projects/'
_trackerURL = 'http://sourceforge.net/support/tracker.php?aid=' _trackerURL = 'http://sourceforge.net/support/tracker.php?aid='
def __init__(self): def __init__(self):
callbacks.PrivmsgCommandAndRegexp.__init__(self) super(Sourceforge, self).__init__()
self.__class__.sf = self.__class__.sourceforge self.__class__.sf = self.__class__.sourceforge
# def isCommand(self, methodName):
# if hasattr(self, methodName):
# return True
# if methodName not in ('bugs', 'rfes', 'patches'):
# return False
# elif self.registryValue('enableSeparateTrackersCommands'):
# return True
# else:
# return False
def _formatResp(self, text, num=''): def _formatResp(self, text, num=''):
""" """
Parses the Sourceforge query to return a list of tuples that Parses the Sourceforge query to return a list of tuples that
@ -212,37 +227,47 @@ class Sourceforge(callbacks.PrivmsgCommandAndRegexp):
except TrackerError, e: except TrackerError, e:
irc.error(str(e)) irc.error(str(e))
_bugLink = re.compile(r'"([^"]+)">Bugs') _trackerLink = {'bugs': re.compile(r'"([^"]+)">Bugs'),
def bugs(self, irc, msg, args): 'rfes': re.compile(r'"([^"]+)">RFE'),
"""[--{any,open,closed,deleted,pending}] [<project>] 'patches': re.compile(r'"([^"]+)">Patches'),
}
def trackers(self, irc, msg, args):
"""[--{any,open,closed,deleted,pending}] {bugs,patches,rfes}
[<project>]
Returns a list of the most recent bugs filed against <project>. Returns a list of the most recent trackers filed against <project>.
<project> is not needed if there is a default project set. Search <project> is not needed if there is a default project set. Search
defaults to open bugs. defaults to open trackers.
""" """
(optlist, rest) = getopt.getopt(args, '', self._statusOpt.keys()) (optlist, rest) = getopt.getopt(args, '', self._statusOpt.keys())
project = privmsgs.getArgs(rest, required=0, optional=1) (tracker, project) = privmsgs.getArgs(rest, optional=1)
status = 'open' status = 'open'
for (option, _) in optlist: for (option, _) in optlist:
option = option.lstrip('-').lower() option = option.lstrip('-').lower()
if option in self._statusOpt: if option in self._statusOpt:
status = option status = option
try: try:
int(project) int(tracker)
# They want the bug command, they're giving us an id#. # They want the tracker command, they're giving us an id#.
s = 'Use the bug command to get information about a specific bug.' s = 'Use the tracker command (e.g., tracker %s) for info about a'\
' specific tracker.' % tracker
irc.error(s) irc.error(s)
return return
except ValueError: except ValueError:
pass pass
tracker = tracker.lower()
if tracker not in self._trackerLink:
raise callbacks.ArgumentError
if not project: if not project:
project = self.registryValue('defaultProject', msg.args[0]) project = self.registryValue('defaultProject', msg.args[0])
if not project: if not project:
raise callbacks.ArgumentError raise callbacks.ArgumentError
try: try:
url = self._getTrackerURL(project, self._bugLink, status) url = self._getTrackerURL(project, self._trackerLink[tracker],
status)
except TrackerError, e: except TrackerError, e:
irc.error('%s. I can\'t find the Bugs link.' % e) irc.error('%s. I can\'t find the %s link.' %
(e, tracker.capitalize()))
return return
irc.reply(self._getTrackerList(url)) irc.reply(self._getTrackerList(url))
@ -265,8 +290,6 @@ class Sourceforge(callbacks.PrivmsgCommandAndRegexp):
else: else:
return '' return ''
# TODO: consolidate total* into one command which takes options for all
# the viable statistics that can be snarfed from the project page
def total(self, irc, msg, args): def total(self, irc, msg, args):
"""[bugs|rfes] [<project>] """[bugs|rfes] [<project>]
@ -315,40 +338,6 @@ class Sourceforge(callbacks.PrivmsgCommandAndRegexp):
else: else:
irc.error('Could not find RFE statistics.') irc.error('Could not find RFE statistics.')
_rfeLink = re.compile(r'"([^"]+)">RFE')
def rfes(self, irc, msg, args):
"""[--{any,open,closed,deleted,pending}] [<project>]
Returns a list of the most recent Requests For Enhancement (RFEs)
filed against <project>. <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 = privmsgs.getArgs(rest, required=0, optional=1)
status = 'open'
for (option, _) in optlist:
option = option.lstrip('-').lower()
if option in self._statusOpt:
status = option
try:
int(project)
# They want a specific RFE, they gave us its id#.
s = 'Use the rfe command to get information about a specific rfe.'
irc.error(s)
return
except ValueError:
pass
if not 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
irc.reply(self._getTrackerList(url))
def fight(self, irc, msg, args): def fight(self, irc, msg, args):
"""[--{bugs,rfes}] [--{open,closed}] <project name> <project name> """[--{bugs,rfes}] [--{open,closed}] <project name> <project name>

View File

@ -33,82 +33,73 @@ import re
from testsupport import * from testsupport import *
if network: import supybot.plugins.Sourceforge
class SourceforgeTest(ChannelPluginTestCase): Sf = conf.supybot.plugins.Sourceforge
class SourceforgeTest(ChannelPluginTestCase):
plugins = ('Sourceforge',) plugins = ('Sourceforge',)
if network:
def testAny(self): def testAny(self):
m = self.getMsg('bugs --any gaim') m = self.getMsg('trackers --any bugs gaim')
self.failUnless(m, 'No response from Sourceforge.') self.failUnless(m, 'No response from Sourceforge.')
n = re.search('#(\d+)', m.args[1]).group(1) n = re.search('#(\d+)', m.args[1]).group(1)
self.assertNotError('tracker %s' % n) self.assertNotError('tracker %s' % n)
m = self.getMsg('rfes --any gaim') m = self.getMsg('trackers --any rfes gaim')
self.failUnless(m, 'No response from Sourceforge.') self.failUnless(m, 'No response from Sourceforge.')
n = re.search('#(\d+)', m.args[1]).group(1) n = re.search('#(\d+)', m.args[1]).group(1)
self.assertNotError('tracker %s' % n) self.assertNotError('tracker %s' % n)
def testClosed(self): def testClosed(self):
m = self.getMsg('bugs --closed gaim') m = self.getMsg('trackers --closed bugs gaim')
self.failUnless(m, 'No response from Sourceforge.') self.failUnless(m, 'No response from Sourceforge.')
n = re.search('#(\d+)', m.args[1]).group(1) n = re.search('#(\d+)', m.args[1]).group(1)
self.assertNotError('tracker %s' % n) self.assertNotError('tracker %s' % n)
m = self.getMsg('rfes --closed gaim') m = self.getMsg('trackers --closed patches gaim')
self.failUnless(m, 'No response from Sourceforge.') self.failUnless(m, 'No response from Sourceforge.')
n = re.search('#(\d+)', m.args[1]).group(1) n = re.search('#(\d+)', m.args[1]).group(1)
self.assertNotError('tracker %s' % n) self.assertNotError('tracker %s' % n)
def testDeleted(self): def testDeleted(self):
m = self.getMsg('bugs --deleted gaim') m = self.getMsg('trackers --deleted bugs gaim')
self.failUnless(m, 'No response from Sourceforge.') self.failUnless(m, 'No response from Sourceforge.')
n = re.search('#(\d+)', m.args[1]).group(1) n = re.search('#(\d+)', m.args[1]).group(1)
self.assertNotError('tracker %s' % n) self.assertNotError('tracker %s' % n)
m = self.getMsg('rfes --deleted gaim') m = self.getMsg('trackers --deleted rfes gaim')
self.failUnless(m, 'No response from Sourceforge.') self.failUnless(m, 'No response from Sourceforge.')
n = re.search('#(\d+)', m.args[1]).group(1) n = re.search('#(\d+)', m.args[1]).group(1)
self.assertNotError('tracker %s' % n) self.assertNotError('tracker %s' % n)
def testOpen(self): def testOpen(self):
m = self.getMsg('bugs --open gaim') m = self.getMsg('trackers --open bugs gaim')
self.failUnless(m, 'No response from Sourceforge.') self.failUnless(m, 'No response from Sourceforge.')
n = re.search('#(\d+)', m.args[1]).group(1) n = re.search('#(\d+)', m.args[1]).group(1)
self.assertNotError('tracker %s' % n) self.assertNotError('tracker %s' % n)
m = self.getMsg('rfes --open gaim') m = self.getMsg('trackers --open rfes gaim')
self.failUnless(m, 'No response from Sourceforge.') self.failUnless(m, 'No response from Sourceforge.')
n = re.search('#(\d+)', m.args[1]).group(1) n = re.search('#(\d+)', m.args[1]).group(1)
self.assertNotError('tracker %s' % n) self.assertNotError('tracker %s' % n)
def testBugs(self): def testTrackers(self):
self.assertHelp('bugs') self.assertHelp('trackers bugs')
self.assertRegexp('bugs 83423', 'Use the bug command') self.assertRegexp('trackers bugs 83423', 'find the Bug')
try: try:
original = conf.supybot.plugins.Sourceforge.defaultProject() original = Sf.defaultProject()
conf.supybot.plugins.Sourceforge.defaultProject.set('supybot') Sf.defaultProject.set('supybot')
self.assertRegexp('bugs alkjfi83fa8', 'find the Bugs') self.assertRegexp('trackers bugs alkjfi83fa8', 'find the Bugs')
self.assertNotError('bugs gaim') self.assertNotError('trackers rfes gaim')
self.assertNotError('bugs') self.assertNotError('trackers patches')
finally: finally:
conf.supybot.plugins.Sourceforge.defaultProject.set(original) Sf.defaultProject.set(original)
def testRfes(self):
self.assertHelp('rfes')
self.assertRegexp('rfes 83423', 'Use the rfe command')
try:
original = conf.supybot.plugins.Sourceforge.defaultProject()
conf.supybot.plugins.Sourceforge.defaultProject.set('gaim')
self.assertNotError('rfes')
self.assertRegexp('rfes alkjfi83hfa8', 'find the RFEs')
self.assertNotError('rfes gaim')
finally:
conf.supybot.plugins.Sourceforge.defaultProject.set(original)
def testDefaultproject(self): def testDefaultproject(self):
try: try:
original = conf.supybot.plugins.Sourceforge.defaultProject() original = Sf.defaultProject()
conf.supybot.plugins.Sourceforge.defaultProject.setValue('supybot') Sf.defaultProject.setValue('supybot')
self.assertNotError('bugs') self.assertNotError('trackers bugs')
conf.supybot.plugins.Sourceforge.defaultProject.setValue('') Sf.defaultProject.setValue('')
self.assertHelp('bugs') self.assertHelp('trackers bugs')
finally: finally:
conf.supybot.plugins.Sourceforge.defaultProject.set(original) Sf.defaultProject.set(original)
def testTracker(self): def testTracker(self):
bug = r'Bug.*Status.*: \w+' bug = r'Bug.*Status.*: \w+'
@ -121,8 +112,8 @@ if network:
def testSnarfer(self): def testSnarfer(self):
s = r'.*Status.*: \w+' s = r'.*Status.*: \w+'
try: try:
original = conf.supybot.plugins.Sourceforge.trackerSnarfer() original = Sf.trackerSnarfer()
conf.supybot.plugins.Sourceforge.trackerSnarfer.setValue(True) Sf.trackerSnarfer.setValue(True)
self.assertSnarfRegexp('http://sourceforge.net/tracker/index.' self.assertSnarfRegexp('http://sourceforge.net/tracker/index.'
'php?func=detail&aid=589953&group_id=' 'php?func=detail&aid=589953&group_id='
'58965&atid=489447', '58965&atid=489447',
@ -166,8 +157,7 @@ if network:
self.assertSnarfNoResponse('https://sourceforge.net/tracker/?' self.assertSnarfNoResponse('https://sourceforge.net/tracker/?'
'group_id=58965&atid=489447') 'group_id=58965&atid=489447')
finally: finally:
conf.supybot.plugins.Sourceforge.trackerSnarfer.setValue( Sf.trackerSnarfer.setValue(original)
original)
def testTotal(self): def testTotal(self):
self.assertRegexp('total bugs gaim', r'\d+ open / \d+ total') self.assertRegexp('total bugs gaim', r'\d+ open / \d+ total')