mirror of
https://github.com/Mikaela/Limnoria.git
synced 2025-01-16 14:42:53 +01:00
Finally put a small band-aid on the sourceforge functions. Now one can
specify the search type, but you'll still get an error if the bug isn't on the first page.
This commit is contained in:
parent
6a48344a98
commit
6c1e115434
@ -35,6 +35,7 @@ Accesses Sourceforge.net for various things
|
|||||||
|
|
||||||
import re
|
import re
|
||||||
import sets
|
import sets
|
||||||
|
import getopt
|
||||||
|
|
||||||
from itertools import ifilter, imap
|
from itertools import ifilter, imap
|
||||||
|
|
||||||
@ -106,7 +107,7 @@ class Sourceforge(callbacks.PrivmsgCommandAndRegexp, configurable.Mixin):
|
|||||||
_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>', re.I)
|
||||||
_hrefOpts = '&set=custom&_assigned_to=0&_status=1&_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)
|
||||||
_assigned=re.compile(r'<b>(Assigned To):</b> <a.+?<br>(.+?)</td>', _reopts)
|
_assigned=re.compile(r'<b>(Assigned To):</b> <a.+?<br>(.+?)</td>', _reopts)
|
||||||
@ -114,6 +115,7 @@ class Sourceforge(callbacks.PrivmsgCommandAndRegexp, configurable.Mixin):
|
|||||||
_priority = re.compile(r'<b>(Priority):</b> <a.+?<br>(.+?)</td>', _reopts)
|
_priority = re.compile(r'<b>(Priority):</b> <a.+?<br>(.+?)</td>', _reopts)
|
||||||
_status = re.compile(r'<b>(Status):</b> <a.+?<br>(.+?)</td>', _reopts)
|
_status = re.compile(r'<b>(Status):</b> <a.+?<br>(.+?)</td>', _reopts)
|
||||||
_regexps =(_resolution, _assigned, _submitted, _priority, _status)
|
_regexps =(_resolution, _assigned, _submitted, _priority, _status)
|
||||||
|
_statusOpt = {'any':100, 'open':1, 'closed':2, 'deleted':3, 'pending':4}
|
||||||
|
|
||||||
configurables = configurable.Dictionary(
|
configurables = configurable.Dictionary(
|
||||||
[('tracker-snarfer', configurable.BoolType, False,
|
[('tracker-snarfer', configurable.BoolType, False,
|
||||||
@ -146,7 +148,7 @@ class Sourceforge(callbacks.PrivmsgCommandAndRegexp, configurable.Mixin):
|
|||||||
for item in ifilter(None, self._infoRe.findall(text)):
|
for item in ifilter(None, self._infoRe.findall(text)):
|
||||||
yield (item[0], utils.htmlToText(item[2]))
|
yield (item[0], utils.htmlToText(item[2]))
|
||||||
|
|
||||||
def _getTrackerURL(self, project, regex):
|
def _getTrackerURL(self, project, regex, status):
|
||||||
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)
|
||||||
@ -154,7 +156,7 @@ class Sourceforge(callbacks.PrivmsgCommandAndRegexp, configurable.Mixin):
|
|||||||
raise TrackerError, 'Invalid Tracker page'
|
raise TrackerError, 'Invalid Tracker page'
|
||||||
else:
|
else:
|
||||||
return 'http://sourceforge.net%s%s' % (utils.htmlToText(
|
return 'http://sourceforge.net%s%s' % (utils.htmlToText(
|
||||||
m.group(1)), self._hrefOpts)
|
m.group(1)), self._hrefOpts % self._statusOpt[status])
|
||||||
except webutils.WebError, e:
|
except webutils.WebError, e:
|
||||||
raise callbacks.Error, str(e)
|
raise callbacks.Error, str(e)
|
||||||
|
|
||||||
@ -170,7 +172,7 @@ class Sourceforge(callbacks.PrivmsgCommandAndRegexp, configurable.Mixin):
|
|||||||
raise callbacks.Error, 'No Trackers were found. (%s)' % \
|
raise callbacks.Error, 'No Trackers were found. (%s)' % \
|
||||||
conf.replyPossibleBug
|
conf.replyPossibleBug
|
||||||
except webutils.WebError, e:
|
except webutils.WebError, e:
|
||||||
raise callbacks.Error, e.msg()
|
raise callbacks.Error, str(e)
|
||||||
|
|
||||||
def _getTrackerInfo(self, irc, msg, url, num):
|
def _getTrackerInfo(self, irc, msg, url, num):
|
||||||
try:
|
try:
|
||||||
@ -182,16 +184,23 @@ class Sourceforge(callbacks.PrivmsgCommandAndRegexp, configurable.Mixin):
|
|||||||
return
|
return
|
||||||
irc.errorPossibleBug('No Trackers were found.')
|
irc.errorPossibleBug('No Trackers were found.')
|
||||||
except webutils.WebError, e:
|
except webutils.WebError, e:
|
||||||
irc.error(e.msg())
|
irc.error(str(e))
|
||||||
|
|
||||||
_bugLink = re.compile(r'"([^"]+)">Bugs')
|
_bugLink = re.compile(r'"([^"]+)">Bugs')
|
||||||
def bugs(self, irc, msg, args):
|
def bugs(self, irc, msg, args):
|
||||||
"""[<project>]
|
"""[--{any,open,closed,deleted,pending}] [<project>]
|
||||||
|
|
||||||
Returns a list of the most recent bugs filed against <project>.
|
Returns a list of the most recent bugs filed against <project>.
|
||||||
<project> is not needed if there is a default project set.
|
<project> is not needed if there is a default project set. Search
|
||||||
|
defaults to open bugs.
|
||||||
"""
|
"""
|
||||||
project = privmsgs.getArgs(args, required=0, optional=1)
|
(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:
|
try:
|
||||||
int(project)
|
int(project)
|
||||||
# They want the bug command, they're giving us an id#.
|
# They want the bug command, they're giving us an id#.
|
||||||
@ -205,20 +214,27 @@ class Sourceforge(callbacks.PrivmsgCommandAndRegexp, configurable.Mixin):
|
|||||||
if not project:
|
if not project:
|
||||||
raise callbacks.ArgumentError
|
raise callbacks.ArgumentError
|
||||||
try:
|
try:
|
||||||
url = self._getTrackerURL(project, self._bugLink)
|
url = self._getTrackerURL(project, self._bugLink, status)
|
||||||
|
self.log.warning(url)
|
||||||
except TrackerError, e:
|
except TrackerError, e:
|
||||||
irc.error('%s. Can\'t find the Bugs link.' % e)
|
irc.error('%s. Can\'t find the Bugs link.' % e)
|
||||||
return
|
return
|
||||||
irc.reply(self._getTrackerList(url))
|
irc.reply(self._getTrackerList(url))
|
||||||
|
|
||||||
def bug(self, irc, msg, args):
|
def bug(self, irc, msg, args):
|
||||||
"""[<project>] <num>
|
"""[--{any,open,closed,deleted,pending}] [<project>] <num>
|
||||||
|
|
||||||
Returns a description of the bug with Tracker id <num> and the
|
Returns a description of the bug with Tracker id <num> and the
|
||||||
corresponding Tracker URL. <project> is not needed if there is a
|
corresponding Tracker URL. <project> is not needed if there is a
|
||||||
default project set.
|
default project set. Search defaults to open bugs.
|
||||||
"""
|
"""
|
||||||
(project, bugnum) = privmsgs.getArgs(args, optional=1)
|
(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:
|
if not bugnum:
|
||||||
try:
|
try:
|
||||||
int(project)
|
int(project)
|
||||||
@ -230,7 +246,8 @@ class Sourceforge(callbacks.PrivmsgCommandAndRegexp, configurable.Mixin):
|
|||||||
if not project:
|
if not project:
|
||||||
raise callbacks.ArgumentError
|
raise callbacks.ArgumentError
|
||||||
try:
|
try:
|
||||||
url = self._getTrackerURL(project, self._bugLink)
|
url = self._getTrackerURL(project, self._bugLink, status)
|
||||||
|
self.log.warning(url)
|
||||||
except TrackerError, e:
|
except TrackerError, e:
|
||||||
irc.error('%s. Can\'t find the Bugs link.' % e)
|
irc.error('%s. Can\'t find the Bugs link.' % e)
|
||||||
return
|
return
|
||||||
@ -238,12 +255,19 @@ class Sourceforge(callbacks.PrivmsgCommandAndRegexp, configurable.Mixin):
|
|||||||
|
|
||||||
_rfeLink = re.compile(r'"([^"]+)">RFE')
|
_rfeLink = re.compile(r'"([^"]+)">RFE')
|
||||||
def rfes(self, irc, msg, args):
|
def rfes(self, irc, msg, args):
|
||||||
"""[<project>]
|
"""[--{any,open,closed,deleted,pending}] [<project>]
|
||||||
|
|
||||||
Returns a list of the most recent RFEs filed against <project>.
|
Returns a list of the most recent RFEs filed against <project>.
|
||||||
<project> is not needed if there is a default project set.
|
<project> is not needed if there is a default project set. Search
|
||||||
|
defaults to open RFEs.
|
||||||
"""
|
"""
|
||||||
project = privmsgs.getArgs(args, required=0, optional=1)
|
(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:
|
try:
|
||||||
int(project)
|
int(project)
|
||||||
# They want a specific RFE, they gave us its id#.
|
# They want a specific RFE, they gave us its id#.
|
||||||
@ -257,20 +281,27 @@ class Sourceforge(callbacks.PrivmsgCommandAndRegexp, configurable.Mixin):
|
|||||||
if not project:
|
if not project:
|
||||||
raise callbacks.ArgumentError
|
raise callbacks.ArgumentError
|
||||||
try:
|
try:
|
||||||
url = self._getTrackerURL(project, self._rfeLink)
|
url = self._getTrackerURL(project, self._rfeLink, status)
|
||||||
|
self.log.warning(url)
|
||||||
except TrackerError, e:
|
except TrackerError, e:
|
||||||
irc.error('%s. Can\'t find the RFEs link.' % e)
|
irc.error('%s. Can\'t find the RFEs link.' % e)
|
||||||
return
|
return
|
||||||
irc.reply(self._getTrackerList(url))
|
irc.reply(self._getTrackerList(url))
|
||||||
|
|
||||||
def rfe(self, irc, msg, args):
|
def rfe(self, irc, msg, args):
|
||||||
"""[<project>] <num>
|
"""[--{any,open,closed,deleted,pending}] [<project>] <num>
|
||||||
|
|
||||||
Returns a description of the bug with Tracker id <num> and the
|
Returns a description of the bug with Tracker id <num> and the
|
||||||
corresponding Tracker URL. <project> is not needed if there is a
|
corresponding Tracker URL. <project> is not needed if there is a
|
||||||
default project set.
|
default project set. Search defaults to open RFEs.
|
||||||
"""
|
"""
|
||||||
(project, rfenum) = privmsgs.getArgs(args, optional=1)
|
(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:
|
if not rfenum:
|
||||||
try:
|
try:
|
||||||
int(project)
|
int(project)
|
||||||
@ -282,7 +313,8 @@ class Sourceforge(callbacks.PrivmsgCommandAndRegexp, configurable.Mixin):
|
|||||||
if not project:
|
if not project:
|
||||||
raise callbacks.ArgumentError
|
raise callbacks.ArgumentError
|
||||||
try:
|
try:
|
||||||
url = self._getTrackerURL(project, self._rfeLink)
|
url = self._getTrackerURL(project, self._rfeLink, status)
|
||||||
|
self.log.warning(url)
|
||||||
except TrackerError, e:
|
except TrackerError, e:
|
||||||
irc.error('%s. Can\'t find the RFEs link.' % e)
|
irc.error('%s. Can\'t find the RFEs link.' % e)
|
||||||
return
|
return
|
||||||
|
@ -45,6 +45,60 @@ if network:
|
|||||||
self.assertError('bug gaim')
|
self.assertError('bug gaim')
|
||||||
self.assertRegexp('bug lkadf 9', 'find the Bugs')
|
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)
|
||||||
|
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)
|
||||||
|
|
||||||
|
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)
|
||||||
|
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)
|
||||||
|
|
||||||
|
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)
|
||||||
|
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)
|
||||||
|
|
||||||
|
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)
|
||||||
|
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)
|
||||||
|
|
||||||
|
'''
|
||||||
|
Just assume pending works since we're not 99% guaranteed to have a
|
||||||
|
project that has pending bugs/rfes like we do with the others.
|
||||||
|
def testPending(self):
|
||||||
|
m = self.getMsg('bugs --pending gaim')
|
||||||
|
self.failUnless(m, 'No response from Sourceforge.')
|
||||||
|
n = re.search('#(\d+)', m.args[1]).group(1)
|
||||||
|
self.assertNotError('bug --pending gaim %s' % n)
|
||||||
|
m = self.getMsg('rfes --pending gaim')
|
||||||
|
self.failUnless(m, 'No response from Sourceforge.')
|
||||||
|
n = re.search('#(\d+)', m.args[1]).group(1)
|
||||||
|
self.assertNotError('rfe --pending gaim %s' % n)
|
||||||
|
'''
|
||||||
|
|
||||||
def testBugs(self):
|
def testBugs(self):
|
||||||
self.assertHelp('bugs')
|
self.assertHelp('bugs')
|
||||||
self.assertNotError('config defaultproject supybot')
|
self.assertNotError('config defaultproject supybot')
|
||||||
|
Loading…
Reference in New Issue
Block a user