mirror of https://github.com/Mikaela/Limnoria.git
Merge branch 'maint/0.83.4'
This commit is contained in:
commit
0abe22f5d1
|
@ -1,5 +1,6 @@
|
||||||
###
|
###
|
||||||
# Copyright (c) 2003-2005, Jeremiah Fincher
|
# Copyright (c) 2003-2005, Jeremiah Fincher
|
||||||
|
# Copyright (c) 2010, James Vega
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
# Redistribution and use in source and binary forms, with or without
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -57,11 +58,7 @@ class Games(callbacks.Plugin):
|
||||||
ten-sided dice.
|
ten-sided dice.
|
||||||
"""
|
"""
|
||||||
(dice, sides) = utils.iter.imap(int, m.groups())
|
(dice, sides) = utils.iter.imap(int, m.groups())
|
||||||
if dice > 6:
|
if sides < 3:
|
||||||
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:
|
|
||||||
irc.error('Dice can\'t have fewer than 3 sides.')
|
irc.error('Dice can\'t have fewer than 3 sides.')
|
||||||
else:
|
else:
|
||||||
L = [0] * dice
|
L = [0] * dice
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
###
|
###
|
||||||
# Copyright (c) 2005, Jeremiah Fincher
|
# Copyright (c) 2005, Jeremiah Fincher
|
||||||
# Copyright (c) 2008-2009, James Vega
|
# Copyright (c) 2008-2010, James Vega
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
# Redistribution and use in source and binary forms, with or without
|
# 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
|
output("""The Google plugin has the functionality to watch for URLs
|
||||||
that match a specific pattern. (We call this a snarfer)
|
that match a specific pattern. (We call this a snarfer)
|
||||||
When supybot sees such a URL, it will parse the web page
|
When supybot sees such a URL, it will parse the web page
|
||||||
for information and reply with the results.
|
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)
|
|
||||||
if yn('Do you want the Google search snarfer enabled by default?'):
|
if yn('Do you want the Google search snarfer enabled by default?'):
|
||||||
conf.supybot.plugins.Google.searchSnarfer.setValue(True)
|
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
|
the Referer field of the search requests. If this value is empty, a
|
||||||
Referer will be generated in the following format:
|
Referer will be generated in the following format:
|
||||||
http://$server/$botName"""))
|
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',
|
conf.registerChannelValue(Google, 'searchSnarfer',
|
||||||
registry.Boolean(False, """Determines whether the search snarfer is
|
registry.Boolean(False, """Determines whether the search snarfer is
|
||||||
enabled. If so, messages (even unaddressed ones) beginning with the word
|
enabled. If so, messages (even unaddressed ones) beginning with the word
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
###
|
###
|
||||||
# Copyright (c) 2002-2004, Jeremiah Fincher
|
# Copyright (c) 2002-2004, Jeremiah Fincher
|
||||||
# Copyright (c) 2008-2009, James Vega
|
# Copyright (c) 2008-2010, James Vega
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
# Redistribution and use in source and binary forms, with or without
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -66,7 +66,7 @@ except ImportError:
|
||||||
class Google(callbacks.PluginRegexp):
|
class Google(callbacks.PluginRegexp):
|
||||||
threaded = True
|
threaded = True
|
||||||
callBefore = ['Web']
|
callBefore = ['Web']
|
||||||
regexps = ['googleSnarfer', 'googleGroups']
|
regexps = ['googleSnarfer']
|
||||||
|
|
||||||
_colorGoogles = {}
|
_colorGoogles = {}
|
||||||
def _getColorGoogle(self, m):
|
def _getColorGoogle(self, m):
|
||||||
|
@ -288,44 +288,6 @@ class Google(callbacks.PluginRegexp):
|
||||||
irc.reply(url.encode('utf-8'), prefixNick=False)
|
irc.reply(url.encode('utf-8'), prefixNick=False)
|
||||||
googleSnarfer = urlSnarfer(googleSnarfer)
|
googleSnarfer = urlSnarfer(googleSnarfer)
|
||||||
|
|
||||||
_ggThread = re.compile(r'Subject: <b>([^<]+)</b>', re.I)
|
|
||||||
_ggGroup = re.compile(r'<TITLE>Google Groups :\s*([^<]+)</TITLE>', 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):
|
def _googleUrl(self, s):
|
||||||
s = s.replace('+', '%2B')
|
s = s.replace('+', '%2B')
|
||||||
s = s.replace(' ', '+')
|
s = s.replace(' ', '+')
|
||||||
|
|
|
@ -64,60 +64,4 @@ class GoogleTestCase(ChannelPluginTestCase):
|
||||||
def testCalcDoesNotHaveExtraSpaces(self):
|
def testCalcDoesNotHaveExtraSpaces(self):
|
||||||
self.assertNotRegexp('google calc 1000^2', r'\s+,\s+')
|
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:
|
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
|
||||||
|
|
|
@ -276,11 +276,12 @@ class Karma(callbacks.Plugin):
|
||||||
def karma(self, irc, msg, args, channel, things):
|
def karma(self, irc, msg, args, channel, things):
|
||||||
"""[<channel>] [<thing> ...]
|
"""[<channel>] [<thing> ...]
|
||||||
|
|
||||||
Returns the karma of <text>. If <thing> is not given, returns the top
|
Returns the karma of <thing>. If <thing> is not given, returns the top
|
||||||
three and bottom three karmas. If one <thing> is given, returns the
|
N karmas, where N is determined by the config variable
|
||||||
details of its karma; if more than one <thing> is given, returns the
|
supybot.plugins.Karma.rankingDisplay. If one <thing> is given, returns
|
||||||
total karma of each of the the things. <channel> is only necessary if
|
the details of its karma; if more than one <thing> is given, returns
|
||||||
the message isn't sent on the channel itself.
|
the total karma of each of the the things. <channel> is only necessary
|
||||||
|
if the message isn't sent on the channel itself.
|
||||||
"""
|
"""
|
||||||
if len(things) == 1:
|
if len(things) == 1:
|
||||||
name = things[0]
|
name = things[0]
|
||||||
|
|
|
@ -47,7 +47,7 @@ class LimiterTestCase(ChannelPluginTestCase):
|
||||||
conf.supybot.plugins.Limiter.maximumExcess.setValue(7)
|
conf.supybot.plugins.Limiter.maximumExcess.setValue(7)
|
||||||
self.irc.feedMsg(ircmsgs.part('#foo', prefix='bar!root@host'))
|
self.irc.feedMsg(ircmsgs.part('#foo', prefix='bar!root@host'))
|
||||||
m = self.irc.takeMsg()
|
m = self.irc.takeMsg()
|
||||||
self.assertEqual(m, ircmsgs.limit('#foo', 1-5))
|
self.assertEqual(m, ircmsgs.limit('#foo', 1+5))
|
||||||
finally:
|
finally:
|
||||||
conf.supybot.plugins.Limiter.minimumExcess.setValue(origMin)
|
conf.supybot.plugins.Limiter.minimumExcess.setValue(origMin)
|
||||||
conf.supybot.plugins.Limiter.maximumExcess.setValue(origMax)
|
conf.supybot.plugins.Limiter.maximumExcess.setValue(origMax)
|
||||||
|
|
|
@ -147,16 +147,11 @@ class News(callbacks.Plugin):
|
||||||
irc.reply(format('No news for %s.', channel))
|
irc.reply(format('No news for %s.', channel))
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
if id < 1:
|
|
||||||
raise ValueError
|
|
||||||
record = self.db.get(channel, id)
|
record = self.db.get(channel, id)
|
||||||
irc.reply(str(record))
|
irc.reply(str(record))
|
||||||
except dbi.NoRecordError, id:
|
except dbi.NoRecordError, id:
|
||||||
irc.errorInvalid('news item id', id)
|
irc.errorInvalid('news item id', id)
|
||||||
except ValueError:
|
news = wrap(news, ['channeldb', additional('positiveInt')])
|
||||||
irc.errorInvalid('news item id', id,
|
|
||||||
'<id> must be a positive integer.')
|
|
||||||
news = wrap(news, ['channeldb', additional('int')])
|
|
||||||
|
|
||||||
def remove(self, irc, msg, args, channel, id):
|
def remove(self, irc, msg, args, channel, id):
|
||||||
"""[<channel>] <id>
|
"""[<channel>] <id>
|
||||||
|
@ -165,16 +160,11 @@ class News(callbacks.Plugin):
|
||||||
necessary if the message isn't sent in the channel itself.
|
necessary if the message isn't sent in the channel itself.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
if id < 1:
|
|
||||||
raise ValueError
|
|
||||||
self.db.remove(channel, id)
|
self.db.remove(channel, id)
|
||||||
irc.replySuccess()
|
irc.replySuccess()
|
||||||
except dbi.NoRecordError:
|
except dbi.NoRecordError:
|
||||||
irc.errorInvalid('news item id', id)
|
irc.errorInvalid('news item id', id)
|
||||||
except ValueError:
|
remove = wrap(remove, ['channeldb', 'positiveInt'])
|
||||||
irc.errorInvalid('news item id', id,
|
|
||||||
'<id> must be a positive integer.')
|
|
||||||
remove = wrap(remove, ['channeldb', 'int'])
|
|
||||||
|
|
||||||
def change(self, irc, msg, args, channel, id, replacer):
|
def change(self, irc, msg, args, channel, id, replacer):
|
||||||
"""[<channel>] <id> <regexp>
|
"""[<channel>] <id> <regexp>
|
||||||
|
@ -185,16 +175,11 @@ class News(callbacks.Plugin):
|
||||||
isn't sent on the channel itself.
|
isn't sent on the channel itself.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
if id < 1:
|
|
||||||
raise ValueError
|
|
||||||
self.db.change(channel, id, replacer)
|
self.db.change(channel, id, replacer)
|
||||||
irc.replySuccess()
|
irc.replySuccess()
|
||||||
except dbi.NoRecordError:
|
except dbi.NoRecordError:
|
||||||
irc.errorInvalid('news item id', id)
|
irc.errorInvalid('news item id', id)
|
||||||
except ValueError:
|
change = wrap(change, ['channeldb', 'positiveInt', 'regexpReplacer'])
|
||||||
irc.errorInvalid('news item id', id,
|
|
||||||
'<id> must be a positive integer.')
|
|
||||||
change = wrap(change, ['channeldb', 'int', 'regexpReplacer'])
|
|
||||||
|
|
||||||
def old(self, irc, msg, args, channel, id):
|
def old(self, irc, msg, args, channel, id):
|
||||||
"""[<channel>] [<id>]
|
"""[<channel>] [<id>]
|
||||||
|
@ -205,15 +190,10 @@ class News(callbacks.Plugin):
|
||||||
"""
|
"""
|
||||||
if id:
|
if id:
|
||||||
try:
|
try:
|
||||||
if id < 1:
|
|
||||||
raise ValueError
|
|
||||||
record = self.db.getOld(channel, id)
|
record = self.db.getOld(channel, id)
|
||||||
irc.reply(str(record))
|
irc.reply(str(record))
|
||||||
except dbi.NoRecordError, id:
|
except dbi.NoRecordError, id:
|
||||||
irc.errorInvalid('news item id', id)
|
irc.errorInvalid('news item id', id)
|
||||||
except ValueError:
|
|
||||||
irc.errorInvalid('news item id', id,
|
|
||||||
'<id> must be a positive integer.')
|
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
records = self.db.getOld(channel)
|
records = self.db.getOld(channel)
|
||||||
|
@ -222,7 +202,7 @@ class News(callbacks.Plugin):
|
||||||
irc.reply(s)
|
irc.reply(s)
|
||||||
except dbi.NoRecordError:
|
except dbi.NoRecordError:
|
||||||
irc.reply(format('No old news for %s.', channel))
|
irc.reply(format('No old news for %s.', channel))
|
||||||
old = wrap(old, ['channeldb', additional('int')])
|
old = wrap(old, ['channeldb', additional('positiveInt')])
|
||||||
|
|
||||||
|
|
||||||
Class = News
|
Class = News
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
|
|
||||||
import re
|
import re
|
||||||
import time
|
import time
|
||||||
import fnmatch
|
|
||||||
import operator
|
import operator
|
||||||
|
|
||||||
import supybot.dbi as dbi
|
import supybot.dbi as dbi
|
||||||
|
@ -98,15 +97,9 @@ class DbiNoteDB(dbi.DB):
|
||||||
self.set(id, n)
|
self.set(id, n)
|
||||||
|
|
||||||
def getUnnotifiedIds(self, to):
|
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, [])
|
return self.unNotified.get(to, [])
|
||||||
|
|
||||||
def getUnreadIds(self, 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, [])
|
return self.unRead.get(to, [])
|
||||||
|
|
||||||
def send(self, frm, to, public, text):
|
def send(self, frm, to, public, text):
|
||||||
|
@ -303,9 +296,8 @@ class Note(callbacks.Plugin):
|
||||||
elif option == 'sent':
|
elif option == 'sent':
|
||||||
own = frm
|
own = frm
|
||||||
if glob:
|
if glob:
|
||||||
glob = fnmatch.translate(glob)
|
glob = utils.python.glob2re(glob)
|
||||||
# ignore the trailing $ fnmatch.translate adds to the regexp
|
criteria.append(re.compile(glob).search)
|
||||||
criteria.append(re.compile(glob[:-1]).search)
|
|
||||||
def match(note):
|
def match(note):
|
||||||
for p in criteria:
|
for p in criteria:
|
||||||
if not p(note.text):
|
if not p(note.text):
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
###
|
###
|
||||||
# Copyright (c) 2003-2005, Daniel DiPaolo
|
# Copyright (c) 2003-2005, Daniel DiPaolo
|
||||||
|
# Copyright (c) 2010, James Vega
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
# Redistribution and use in source and binary forms, with or without
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -30,7 +31,6 @@
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import time
|
import time
|
||||||
import fnmatch
|
|
||||||
import operator
|
import operator
|
||||||
|
|
||||||
import supybot.dbi as dbi
|
import supybot.dbi as dbi
|
||||||
|
@ -230,8 +230,8 @@ class Todo(callbacks.Plugin):
|
||||||
if option == 'regexp':
|
if option == 'regexp':
|
||||||
criteria.append(arg.search)
|
criteria.append(arg.search)
|
||||||
for glob in globs:
|
for glob in globs:
|
||||||
glob = fnmatch.translate(glob)
|
glob = utils.python.glob2re(glob)
|
||||||
criteria.append(re.compile(glob[:-1]).search)
|
criteria.append(re.compile(glob).search)
|
||||||
try:
|
try:
|
||||||
tasks = self.db.select(user.id, criteria)
|
tasks = self.db.select(user.id, criteria)
|
||||||
L = [format('#%i: %s', t.id, self._shrink(t.task)) for t in tasks]
|
L = [format('#%i: %s', t.id, self._shrink(t.task)) for t in tasks]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
###
|
###
|
||||||
# Copyright (c) 2005-2009, Jeremiah Fincher
|
# Copyright (c) 2005-2009, Jeremiah Fincher
|
||||||
# Copyright (c) 2009, James Vega
|
# Copyright (c) 2009-2010, James Vega
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
# Redistribution and use in source and binary forms, with or without
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -30,6 +30,7 @@
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import types
|
import types
|
||||||
|
import fnmatch
|
||||||
import UserDict
|
import UserDict
|
||||||
import threading
|
import threading
|
||||||
|
|
||||||
|
@ -65,7 +66,6 @@ def changeFunctionName(f, name, doc=None):
|
||||||
class Object(object):
|
class Object(object):
|
||||||
def __ne__(self, other):
|
def __ne__(self, other):
|
||||||
return not self == other
|
return not self == other
|
||||||
|
|
||||||
|
|
||||||
class Synchronized(type):
|
class Synchronized(type):
|
||||||
METHODS = '__synchronized__'
|
METHODS = '__synchronized__'
|
||||||
|
@ -103,5 +103,15 @@ class Synchronized(type):
|
||||||
newclass = super(Synchronized, cls).__new__(cls, name, bases, dict)
|
newclass = super(Synchronized, cls).__new__(cls, name, bases, dict)
|
||||||
return newclass
|
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:
|
# vim:set shiftwidth=4 softtabstop=8 expandtab textwidth=78:
|
||||||
|
|
Loading…
Reference in New Issue