diff --git a/plugins/Games/plugin.py b/plugins/Games/plugin.py
index 7bc25870d..427880193 100644
--- a/plugins/Games/plugin.py
+++ b/plugins/Games/plugin.py
@@ -1,5 +1,6 @@
###
# Copyright (c) 2003-2005, Jeremiah Fincher
+# Copyright (c) 2010, James Vega
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -57,11 +58,7 @@ class Games(callbacks.Plugin):
ten-sided dice.
"""
(dice, sides) = utils.iter.imap(int, m.groups())
- if dice > 6:
- irc.error('You can\'t roll more than 6 dice.')
- elif sides > 100:
- irc.error('Dice can\'t have more than 100 sides.')
- elif sides < 3:
+ if sides < 3:
irc.error('Dice can\'t have fewer than 3 sides.')
else:
L = [0] * dice
diff --git a/plugins/Google/config.py b/plugins/Google/config.py
index d34f530a1..a309911ab 100644
--- a/plugins/Google/config.py
+++ b/plugins/Google/config.py
@@ -1,6 +1,6 @@
###
# Copyright (c) 2005, Jeremiah Fincher
-# Copyright (c) 2008-2009, James Vega
+# Copyright (c) 2008-2010, James Vega
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -37,13 +37,7 @@ def configure(advanced):
output("""The Google plugin has the functionality to watch for URLs
that match a specific pattern. (We call this a snarfer)
When supybot sees such a URL, it will parse the web page
- for information and reply with the results.
-
- Google has two available snarfers: Google Groups link
- snarfing and a google search snarfer.""")
- if yn('Do you want the Google Groups link snarfer enabled by '
- 'default?'):
- conf.supybot.plugins.Google.groupsSnarfer.setValue(True)
+ for information and reply with the results.""")
if yn('Do you want the Google search snarfer enabled by default?'):
conf.supybot.plugins.Google.searchSnarfer.setValue(True)
@@ -104,10 +98,6 @@ conf.registerGlobalValue(Google, 'referer',
the Referer field of the search requests. If this value is empty, a
Referer will be generated in the following format:
http://$server/$botName"""))
-conf.registerChannelValue(Google, 'groupsSnarfer',
- registry.Boolean(False, """Determines whether the groups snarfer is
- enabled. If so, URLs at groups.google.com will be snarfed and their
- group/title messaged to the channel."""))
conf.registerChannelValue(Google, 'searchSnarfer',
registry.Boolean(False, """Determines whether the search snarfer is
enabled. If so, messages (even unaddressed ones) beginning with the word
diff --git a/plugins/Google/plugin.py b/plugins/Google/plugin.py
index f9b2fa0fd..2adef8ef3 100644
--- a/plugins/Google/plugin.py
+++ b/plugins/Google/plugin.py
@@ -1,6 +1,6 @@
###
# Copyright (c) 2002-2004, Jeremiah Fincher
-# Copyright (c) 2008-2009, James Vega
+# Copyright (c) 2008-2010, James Vega
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -66,7 +66,7 @@ except ImportError:
class Google(callbacks.PluginRegexp):
threaded = True
callBefore = ['Web']
- regexps = ['googleSnarfer', 'googleGroups']
+ regexps = ['googleSnarfer']
_colorGoogles = {}
def _getColorGoogle(self, m):
@@ -288,44 +288,6 @@ class Google(callbacks.PluginRegexp):
irc.reply(url.encode('utf-8'), prefixNick=False)
googleSnarfer = urlSnarfer(googleSnarfer)
- _ggThread = re.compile(r'Subject: ([^<]+)', re.I)
- _ggGroup = re.compile(r'
Google Groups :\s*([^<]+)', re.I)
- _ggThreadm = re.compile(r'src="(/group[^"]+)">', re.I)
- _ggSelm = re.compile(r'selm=[^&]+', re.I)
- _threadmThread = re.compile(r'TITLE="([^"]+)">', re.I)
- _threadmGroup = re.compile(r'class=groupname[^>]+>([^<]+)<', re.I)
- def googleGroups(self, irc, msg, match):
- r"http://groups.google.[\w.]+/\S+\?(\S+)"
- if not self.registryValue('groupsSnarfer', msg.args[0]):
- return
- queries = cgi.parse_qsl(match.group(1))
- queries = [q for q in queries if q[0] in ('threadm', 'selm')]
- if not queries:
- return
- queries.append(('hl', 'en'))
- url = 'http://groups.google.com/groups?' + urllib.urlencode(queries)
- text = utils.web.getUrl(url)
- mThread = None
- mGroup = None
- if 'threadm=' in url:
- path = self._ggThreadm.search(text)
- if path is not None:
- url = 'http://groups-beta.google.com' + path.group(1)
- text = utils.web.getUrl(url)
- mThread = self._threadmThread.search(text)
- mGroup = self._threadmGroup.search(text)
- else:
- mThread = self._ggThread.search(text)
- mGroup = self._ggGroup.search(text)
- if mThread and mGroup:
- irc.reply(format('Google Groups: %s, %s',
- mGroup.group(1), mThread.group(1)),
- prefixNick=False)
- else:
- self.log.debug('Unable to snarf. %s doesn\'t appear to be a '
- 'proper Google Groups page.', match.group(1))
- googleGroups = urlSnarfer(googleGroups)
-
def _googleUrl(self, s):
s = s.replace('+', '%2B')
s = s.replace(' ', '+')
diff --git a/plugins/Google/test.py b/plugins/Google/test.py
index 92b7aeee0..fe7affc3d 100644
--- a/plugins/Google/test.py
+++ b/plugins/Google/test.py
@@ -64,60 +64,4 @@ class GoogleTestCase(ChannelPluginTestCase):
def testCalcDoesNotHaveExtraSpaces(self):
self.assertNotRegexp('google calc 1000^2', r'\s+,\s+')
- def testGroupsSnarfer(self):
- orig = conf.supybot.plugins.Google.groupsSnarfer()
- try:
- conf.supybot.plugins.Google.groupsSnarfer.setValue(True)
- # This should work, and does work in practice, but is failing
- # in the tests.
- #self.assertSnarfRegexp(
- # 'http://groups.google.com/groups?dq=&hl=en&lr=lang_en&'
- # 'ie=UTF-8&oe=UTF-8&selm=698f09f8.0310132012.738e22fc'
- # '%40posting.google.com',
- # r'comp\.lang\.python.*question: usage of __slots__')
- self.assertSnarfRegexp(
- 'http://groups.google.com/groups?selm=ExDm.8bj.23'
- '%40gated-at.bofh.it&oe=UTF-8&output=gplain',
- r'linux\.kernel.*NFS client freezes')
- self.assertSnarfRegexp(
- 'http://groups.google.com/groups?q=kernel+hot-pants&'
- 'hl=en&lr=&ie=UTF-8&oe=UTF-8&selm=1.5.4.32.199703131'
- '70853.00674d60%40adan.kingston.net&rnum=1',
- r'Madrid Bluegrass Ramble')
- self.assertSnarfRegexp(
- 'http://groups.google.com/groups?selm=1.5.4.32.19970'
- '313170853.00674d60%40adan.kingston.net&oe=UTF-8&'
- 'output=gplain',
- r'Madrid Bluegrass Ramble')
- self.assertSnarfRegexp(
- 'http://groups.google.com/groups?dq=&hl=en&lr=&'
- 'ie=UTF-8&threadm=mailman.1010.1069645289.702.'
- 'python-list%40python.org&prev=/groups%3Fhl%3Den'
- '%26lr%3D%26ie%3DUTF-8%26group%3Dcomp.lang.python',
- r'comp\.lang\.python.*What exactly are bound')
- # Test for Bug #1002547
- self.assertSnarfRegexp(
- 'http://groups.google.com/groups?q=supybot+is+the&'
- 'hl=en&lr=&ie=UTF-8&c2coff=1&selm=1028329672'
- '%40freshmeat.net&rnum=9',
- r'fm\.announce.*SupyBot')
- finally:
- conf.supybot.plugins.Google.groupsSnarfer.setValue(orig)
-
- def testConfig(self):
- orig = conf.supybot.plugins.Google.groupsSnarfer()
- try:
- conf.supybot.plugins.Google.groupsSnarfer.setValue(False)
- self.assertSnarfNoResponse(
- 'http://groups.google.com/groups?dq=&hl=en&lr=lang_en&'
- 'ie=UTF-8&oe=UTF-8&selm=698f09f8.0310132012.738e22fc'
- '%40posting.google.com')
- conf.supybot.plugins.Google.groupsSnarfer.setValue(True)
- self.assertSnarfNotError(
- 'http://groups.google.com/groups?dq=&hl=en&lr=lang_en&'
- 'ie=UTF-8&oe=UTF-8&selm=698f09f8.0310132012.738e22fc'
- '%40posting.google.com')
- finally:
- conf.supybot.plugins.Google.groupsSnarfer.setValue(orig)
-
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
diff --git a/plugins/Karma/plugin.py b/plugins/Karma/plugin.py
index d7a33ec41..02570b5af 100644
--- a/plugins/Karma/plugin.py
+++ b/plugins/Karma/plugin.py
@@ -276,11 +276,12 @@ class Karma(callbacks.Plugin):
def karma(self, irc, msg, args, channel, things):
"""[] [ ...]
- Returns the karma of . If is not given, returns the top
- three and bottom three karmas. If one is given, returns the
- details of its karma; if more than one is given, returns the
- total karma of each of the the things. is only necessary if
- the message isn't sent on the channel itself.
+ Returns the karma of . If is not given, returns the top
+ N karmas, where N is determined by the config variable
+ supybot.plugins.Karma.rankingDisplay. If one is given, returns
+ the details of its karma; if more than one is given, returns
+ the total karma of each of the the things. is only necessary
+ if the message isn't sent on the channel itself.
"""
if len(things) == 1:
name = things[0]
diff --git a/plugins/Limiter/test.py b/plugins/Limiter/test.py
index 9941dd433..f70eccdf3 100644
--- a/plugins/Limiter/test.py
+++ b/plugins/Limiter/test.py
@@ -47,7 +47,7 @@ class LimiterTestCase(ChannelPluginTestCase):
conf.supybot.plugins.Limiter.maximumExcess.setValue(7)
self.irc.feedMsg(ircmsgs.part('#foo', prefix='bar!root@host'))
m = self.irc.takeMsg()
- self.assertEqual(m, ircmsgs.limit('#foo', 1-5))
+ self.assertEqual(m, ircmsgs.limit('#foo', 1+5))
finally:
conf.supybot.plugins.Limiter.minimumExcess.setValue(origMin)
conf.supybot.plugins.Limiter.maximumExcess.setValue(origMax)
diff --git a/plugins/News/plugin.py b/plugins/News/plugin.py
index 2cef9c966..554ddd825 100644
--- a/plugins/News/plugin.py
+++ b/plugins/News/plugin.py
@@ -147,16 +147,11 @@ class News(callbacks.Plugin):
irc.reply(format('No news for %s.', channel))
else:
try:
- if id < 1:
- raise ValueError
record = self.db.get(channel, id)
irc.reply(str(record))
except dbi.NoRecordError, id:
irc.errorInvalid('news item id', id)
- except ValueError:
- irc.errorInvalid('news item id', id,
- ' must be a positive integer.')
- news = wrap(news, ['channeldb', additional('int')])
+ news = wrap(news, ['channeldb', additional('positiveInt')])
def remove(self, irc, msg, args, channel, id):
"""[]
@@ -165,16 +160,11 @@ class News(callbacks.Plugin):
necessary if the message isn't sent in the channel itself.
"""
try:
- if id < 1:
- raise ValueError
self.db.remove(channel, id)
irc.replySuccess()
except dbi.NoRecordError:
irc.errorInvalid('news item id', id)
- except ValueError:
- irc.errorInvalid('news item id', id,
- ' must be a positive integer.')
- remove = wrap(remove, ['channeldb', 'int'])
+ remove = wrap(remove, ['channeldb', 'positiveInt'])
def change(self, irc, msg, args, channel, id, replacer):
"""[]
@@ -185,16 +175,11 @@ class News(callbacks.Plugin):
isn't sent on the channel itself.
"""
try:
- if id < 1:
- raise ValueError
self.db.change(channel, id, replacer)
irc.replySuccess()
except dbi.NoRecordError:
irc.errorInvalid('news item id', id)
- except ValueError:
- irc.errorInvalid('news item id', id,
- ' must be a positive integer.')
- change = wrap(change, ['channeldb', 'int', 'regexpReplacer'])
+ change = wrap(change, ['channeldb', 'positiveInt', 'regexpReplacer'])
def old(self, irc, msg, args, channel, id):
"""[] []
@@ -205,15 +190,10 @@ class News(callbacks.Plugin):
"""
if id:
try:
- if id < 1:
- raise ValueError
record = self.db.getOld(channel, id)
irc.reply(str(record))
except dbi.NoRecordError, id:
irc.errorInvalid('news item id', id)
- except ValueError:
- irc.errorInvalid('news item id', id,
- ' must be a positive integer.')
else:
try:
records = self.db.getOld(channel)
@@ -222,7 +202,7 @@ class News(callbacks.Plugin):
irc.reply(s)
except dbi.NoRecordError:
irc.reply(format('No old news for %s.', channel))
- old = wrap(old, ['channeldb', additional('int')])
+ old = wrap(old, ['channeldb', additional('positiveInt')])
Class = News
diff --git a/plugins/Note/plugin.py b/plugins/Note/plugin.py
index 95a53bbea..3fd3cb326 100644
--- a/plugins/Note/plugin.py
+++ b/plugins/Note/plugin.py
@@ -30,7 +30,6 @@
import re
import time
-import fnmatch
import operator
import supybot.dbi as dbi
@@ -98,15 +97,9 @@ class DbiNoteDB(dbi.DB):
self.set(id, n)
def getUnnotifiedIds(self, to):
-## def p(note):
-## return not note.notified and note.to == to
-## return [note.id for note in self.select(p)]
return self.unNotified.get(to, [])
def getUnreadIds(self, to):
-## def p(note):
-## return not note.read and note.to == to
-## return [note.id for note in self.select(p)]
return self.unRead.get(to, [])
def send(self, frm, to, public, text):
@@ -303,9 +296,8 @@ class Note(callbacks.Plugin):
elif option == 'sent':
own = frm
if glob:
- glob = fnmatch.translate(glob)
- # ignore the trailing $ fnmatch.translate adds to the regexp
- criteria.append(re.compile(glob[:-1]).search)
+ glob = utils.python.glob2re(glob)
+ criteria.append(re.compile(glob).search)
def match(note):
for p in criteria:
if not p(note.text):
diff --git a/plugins/Todo/plugin.py b/plugins/Todo/plugin.py
index efc415e5f..b995140ba 100644
--- a/plugins/Todo/plugin.py
+++ b/plugins/Todo/plugin.py
@@ -1,5 +1,6 @@
###
# Copyright (c) 2003-2005, Daniel DiPaolo
+# Copyright (c) 2010, James Vega
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -30,7 +31,6 @@
import os
import re
import time
-import fnmatch
import operator
import supybot.dbi as dbi
@@ -230,8 +230,8 @@ class Todo(callbacks.Plugin):
if option == 'regexp':
criteria.append(arg.search)
for glob in globs:
- glob = fnmatch.translate(glob)
- criteria.append(re.compile(glob[:-1]).search)
+ glob = utils.python.glob2re(glob)
+ criteria.append(re.compile(glob).search)
try:
tasks = self.db.select(user.id, criteria)
L = [format('#%i: %s', t.id, self._shrink(t.task)) for t in tasks]
diff --git a/src/utils/python.py b/src/utils/python.py
index d636d62bb..f38de2f78 100644
--- a/src/utils/python.py
+++ b/src/utils/python.py
@@ -1,6 +1,6 @@
###
# Copyright (c) 2005-2009, Jeremiah Fincher
-# Copyright (c) 2009, James Vega
+# Copyright (c) 2009-2010, James Vega
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -30,6 +30,7 @@
import sys
import types
+import fnmatch
import UserDict
import threading
@@ -65,7 +66,6 @@ def changeFunctionName(f, name, doc=None):
class Object(object):
def __ne__(self, other):
return not self == other
-
class Synchronized(type):
METHODS = '__synchronized__'
@@ -103,5 +103,15 @@ class Synchronized(type):
newclass = super(Synchronized, cls).__new__(cls, name, bases, dict)
return newclass
+# Translate glob to regular expression, trimming the "match EOL" portion of
+# the regular expression.
+if sys.version_info < (2, 6, 0):
+ # Pre-2.6 just uses the $ anchor
+ def glob2re(g):
+ return fnmatch.translate(g)[:-1]
+else:
+ # Post-2.6 uses \Z(?ms) per http://issues.python.org/6665
+ def glob2re(g):
+ return fnmatch.translate(g)[:-7]
# vim:set shiftwidth=4 softtabstop=8 expandtab textwidth=78: