mirror of
https://github.com/Mikaela/Limnoria.git
synced 2024-11-27 05:09:23 +01:00
Properly added and abstracted trackers commands
This commit is contained in:
parent
d98de454b9
commit
977a33a43f
@ -96,11 +96,6 @@ 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):
|
||||||
"""
|
"""
|
||||||
@ -112,7 +107,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>', _reopts)
|
r'"([^"]+)">([^<]+)</a>', re.I)
|
||||||
_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)
|
||||||
@ -132,20 +127,10 @@ class Sourceforge(callbacks.PrivmsgCommandAndRegexp):
|
|||||||
super(Sourceforge, self).__init__()
|
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
|
||||||
contain the bug/rfe information.
|
contain the tracker information.
|
||||||
"""
|
"""
|
||||||
if num:
|
if num:
|
||||||
for item in ifilter(lambda s, n=num: s and n in s,
|
for item in ifilter(lambda s, n=num: s and n in s,
|
||||||
@ -157,6 +142,9 @@ class Sourceforge(callbacks.PrivmsgCommandAndRegexp):
|
|||||||
yield (item[0], utils.htmlToText(item[2]))
|
yield (item[0], utils.htmlToText(item[2]))
|
||||||
|
|
||||||
def _getTrackerURL(self, project, regex, status):
|
def _getTrackerURL(self, project, regex, status):
|
||||||
|
"""
|
||||||
|
Searches the project's Summary page to find the proper tracker link.
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
text = webutils.getUrl('%s%s' % (self._projectURL, project))
|
text = webutils.getUrl('%s%s' % (self._projectURL, project))
|
||||||
m = regex.search(text)
|
m = regex.search(text)
|
||||||
@ -169,6 +157,9 @@ class Sourceforge(callbacks.PrivmsgCommandAndRegexp):
|
|||||||
raise callbacks.Error, str(e)
|
raise callbacks.Error, str(e)
|
||||||
|
|
||||||
def _getTrackerList(self, url):
|
def _getTrackerList(self, url):
|
||||||
|
"""
|
||||||
|
Searches the tracker list page and returns a list of the trackers.
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
text = webutils.getUrl(url)
|
text = webutils.getUrl(url)
|
||||||
if "No matches found." in text:
|
if "No matches found." in text:
|
||||||
@ -188,6 +179,9 @@ class Sourceforge(callbacks.PrivmsgCommandAndRegexp):
|
|||||||
_sfTitle = re.compile(r'Detail:(\d+) - ([^<]+)</title>', re.I)
|
_sfTitle = re.compile(r'Detail:(\d+) - ([^<]+)</title>', re.I)
|
||||||
_linkType = re.compile(r'(\w+ \w+|\w+): Tracker Detailed View', re.I)
|
_linkType = re.compile(r'(\w+ \w+|\w+): Tracker Detailed View', re.I)
|
||||||
def _getTrackerInfo(self, url):
|
def _getTrackerInfo(self, url):
|
||||||
|
"""
|
||||||
|
Parses the specific tracker page, returning useful information.
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
s = webutils.getUrl(url)
|
s = webutils.getUrl(url)
|
||||||
resp = []
|
resp = []
|
||||||
@ -231,33 +225,22 @@ class Sourceforge(callbacks.PrivmsgCommandAndRegexp):
|
|||||||
'rfes': re.compile(r'"([^"]+)">RFE'),
|
'rfes': re.compile(r'"([^"]+)">RFE'),
|
||||||
'patches': re.compile(r'"([^"]+)">Patches'),
|
'patches': re.compile(r'"([^"]+)">Patches'),
|
||||||
}
|
}
|
||||||
def trackers(self, irc, msg, args):
|
def _trackers(self, irc, args, msg, tracker):
|
||||||
"""[--{any,open,closed,deleted,pending}] {bugs,patches,rfes}
|
|
||||||
[<project>]
|
|
||||||
|
|
||||||
Returns a list of the most recent trackers filed against <project>.
|
|
||||||
<project> is not needed if there is a default project set. Search
|
|
||||||
defaults to open trackers.
|
|
||||||
"""
|
|
||||||
(optlist, rest) = getopt.getopt(args, '', self._statusOpt.keys())
|
(optlist, rest) = getopt.getopt(args, '', self._statusOpt.keys())
|
||||||
(tracker, project) = privmsgs.getArgs(rest, optional=1)
|
project = privmsgs.getArgs(rest, required=0, 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(tracker)
|
int(project)
|
||||||
# They want the tracker command, they're giving us an id#.
|
s = 'Use the tracker command to get information about a specific'\
|
||||||
s = 'Use the tracker command (e.g., tracker %s) for info about a'\
|
'tracker.'
|
||||||
' 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:
|
||||||
@ -271,6 +254,33 @@ class Sourceforge(callbacks.PrivmsgCommandAndRegexp):
|
|||||||
return
|
return
|
||||||
irc.reply(self._getTrackerList(url))
|
irc.reply(self._getTrackerList(url))
|
||||||
|
|
||||||
|
def bugs(self, irc, msg, args):
|
||||||
|
"""[--{any,open,closed,deleted,pending}] [<project>]
|
||||||
|
|
||||||
|
Returns a list of the most recent bugs filed against <project>.
|
||||||
|
<project> is not needed if there is a default project set. Search
|
||||||
|
defaults to open bugs.
|
||||||
|
"""
|
||||||
|
self._trackers(irc, args, msg, 'bugs')
|
||||||
|
|
||||||
|
def rfes(self, irc, msg, args):
|
||||||
|
"""[--{any,open,closed,deleted,pending}] [<project>]
|
||||||
|
|
||||||
|
Returns a list of the most recent rfes filed against <project>.
|
||||||
|
<project> is not needed if there is a default project set. Search
|
||||||
|
defaults to open rfes.
|
||||||
|
"""
|
||||||
|
self._trackers(irc, args, msg, 'rfes')
|
||||||
|
|
||||||
|
def patches(self, irc, msg, args):
|
||||||
|
"""[--{any,open,closed,deleted,pending}] [<project>]
|
||||||
|
|
||||||
|
Returns a list of the most recent patches filed against <project>.
|
||||||
|
<project> is not needed if there is a default project set. Search
|
||||||
|
defaults to open patches.
|
||||||
|
"""
|
||||||
|
self._trackers(irc, args, msg, 'patches')
|
||||||
|
|
||||||
_totbugs = re.compile(r'Bugs</a>\s+?\( <b>([^<]+)</b>', re.S | re.I)
|
_totbugs = re.compile(r'Bugs</a>\s+?\( <b>([^<]+)</b>', re.S | re.I)
|
||||||
def _getNumBugs(self, project):
|
def _getNumBugs(self, project):
|
||||||
text = webutils.getUrl('%s%s' % (self._projectURL, project))
|
text = webutils.getUrl('%s%s' % (self._projectURL, project))
|
||||||
@ -291,7 +301,7 @@ class Sourceforge(callbacks.PrivmsgCommandAndRegexp):
|
|||||||
return ''
|
return ''
|
||||||
|
|
||||||
def total(self, irc, msg, args):
|
def total(self, irc, msg, args):
|
||||||
"""[bugs|rfes] [<project>]
|
"""{bugs,rfes} [<project>]
|
||||||
|
|
||||||
Returns the total count of open bugs or rfes. <project> is only
|
Returns the total count of open bugs or rfes. <project> is only
|
||||||
necessary if a default project is not set.
|
necessary if a default project is not set.
|
||||||
|
@ -40,54 +40,54 @@ class SourceforgeTest(ChannelPluginTestCase):
|
|||||||
plugins = ('Sourceforge',)
|
plugins = ('Sourceforge',)
|
||||||
if network:
|
if network:
|
||||||
def testAny(self):
|
def testAny(self):
|
||||||
m = self.getMsg('trackers --any bugs gaim')
|
m = self.getMsg('bugs --any 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('trackers --any rfes gaim')
|
m = self.getMsg('rfes --any 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('trackers --closed bugs gaim')
|
m = self.getMsg('bugs --closed 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('trackers --closed patches gaim')
|
m = self.getMsg('patches --closed 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('trackers --deleted bugs gaim')
|
m = self.getMsg('bugs --deleted 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('trackers --deleted rfes gaim')
|
m = self.getMsg('rfes --deleted 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('trackers --open bugs gaim')
|
m = self.getMsg('bugs --open 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('trackers --open rfes gaim')
|
m = self.getMsg('rfes --open 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 testTrackers(self):
|
def testTrackers(self):
|
||||||
self.assertHelp('trackers bugs')
|
self.assertHelp('bugs')
|
||||||
self.assertRegexp('trackers bugs 83423', 'find the Bug')
|
self.assertRegexp('bugs 83423', 'use the tracker')
|
||||||
try:
|
try:
|
||||||
original = Sf.defaultProject()
|
original = Sf.defaultProject()
|
||||||
Sf.defaultProject.set('supybot')
|
Sf.defaultProject.set('supybot')
|
||||||
self.assertRegexp('trackers bugs alkjfi83fa8', 'find the Bugs')
|
self.assertRegexp('bugs alkjfi83fa8', 'find the Bugs')
|
||||||
self.assertNotError('trackers rfes gaim')
|
self.assertNotError('rfes gaim')
|
||||||
self.assertNotError('trackers patches')
|
self.assertNotError('patches')
|
||||||
finally:
|
finally:
|
||||||
Sf.defaultProject.set(original)
|
Sf.defaultProject.set(original)
|
||||||
|
|
||||||
@ -95,9 +95,9 @@ class SourceforgeTest(ChannelPluginTestCase):
|
|||||||
try:
|
try:
|
||||||
original = Sf.defaultProject()
|
original = Sf.defaultProject()
|
||||||
Sf.defaultProject.setValue('supybot')
|
Sf.defaultProject.setValue('supybot')
|
||||||
self.assertNotError('trackers bugs')
|
self.assertNotError('bugs')
|
||||||
Sf.defaultProject.setValue('')
|
Sf.defaultProject.setValue('')
|
||||||
self.assertHelp('trackers bugs')
|
self.assertHelp('bugs')
|
||||||
finally:
|
finally:
|
||||||
Sf.defaultProject.set(original)
|
Sf.defaultProject.set(original)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user