mirror of
https://github.com/Mikaela/Limnoria.git
synced 2024-11-16 23:39:22 +01:00
Fixed a lot of RateLimiter problems; solved Forums.gameknot problem. Also made irc.error raise an exception (that's later handled) in non-threaded callbacks, so there's less a chance of error in not returning after irc.error.
This commit is contained in:
parent
8c27ab7917
commit
089e6a400d
@ -89,8 +89,8 @@ def reply(msg, s):
|
||||
return m
|
||||
|
||||
class RateLimiter:
|
||||
lastRequest = {}
|
||||
def __init__(self):
|
||||
self.lastRequest = {}
|
||||
self.limited = []
|
||||
self.unlimited = []
|
||||
|
||||
@ -110,6 +110,7 @@ class RateLimiter:
|
||||
if not self.limit(msg):
|
||||
self.unlimited.append(msg)
|
||||
else:
|
||||
debug.printf('Limiting message from %s' % msg.prefix)
|
||||
self.limited.append(msg)
|
||||
|
||||
def limit(self, msg, penalize=True):
|
||||
@ -227,7 +228,6 @@ class IrcObjectProxy:
|
||||
self.finalEvaled = True
|
||||
name = self.args.pop(0)
|
||||
callback = self.findCallback(name)
|
||||
# Use the old Irc object.
|
||||
try:
|
||||
callback.callCommand(getattr(callback, name),
|
||||
(self, self.msg, self.args))
|
||||
@ -246,7 +246,7 @@ class IrcObjectProxy:
|
||||
self.evalArgs()
|
||||
|
||||
def error(self, msg, s):
|
||||
self.reply(msg, 'Error: ' + s)
|
||||
raise Error, s
|
||||
|
||||
def killProxy(self):
|
||||
if not isinstance(self.irc, irclib.Irc):
|
||||
@ -262,22 +262,30 @@ class IrcObjectProxy:
|
||||
def __getattr__(self, attr):
|
||||
return getattr(self.irc, attr)
|
||||
|
||||
## def __setattr__(self, attr, value):
|
||||
## setattr(self.irc, attr, value)
|
||||
|
||||
class IrcObjectProxyThreaded(IrcObjectProxy):
|
||||
def error(self, msg, s):
|
||||
self.reply(msg, 'Error: ' + s)
|
||||
|
||||
|
||||
class Privmsg(irclib.IrcCallback):
|
||||
"""Base class for all Privmsg handlers."""
|
||||
threaded = False
|
||||
public = True
|
||||
def __init__(self):
|
||||
self.rateLimiter = RateLimiter()
|
||||
if self.threaded:
|
||||
self.Proxy = IrcObjectProxyThreaded
|
||||
else:
|
||||
self.Proxy = IrcObjectProxy
|
||||
|
||||
def __call__(self, irc, msg):
|
||||
self.rateLimiter.put(msg)
|
||||
irclib.IrcCallback.__call__(self, irc, msg)
|
||||
# Now, if there's anything in the rateLimiter...
|
||||
msg = self.rateLimiter.get()
|
||||
if msg:
|
||||
irclib.IrcCallback.__call__(self, irc, msg)
|
||||
s = addressed(irc.nick, msg)
|
||||
self.Proxy(irc, msg, Tokenizer().tokenize(s))
|
||||
|
||||
def isCommand(self, methodName):
|
||||
# This function is ugly, but I don't want users to call methods like
|
||||
@ -313,7 +321,9 @@ class Privmsg(irclib.IrcCallback):
|
||||
return
|
||||
m = self._r.match(s)
|
||||
if m and self.isCommand(canonicalName(m.group(1))):
|
||||
IrcObjectProxy(irc, msg, Tokenizer().tokenize(s))
|
||||
self.rateLimiter.put(msg)
|
||||
msg = self.rateLimiter.get()
|
||||
self.Proxy(irc, msg, Tokenizer().tokenize(s))
|
||||
|
||||
|
||||
class IrcObjectProxyRegexp:
|
||||
@ -321,7 +331,7 @@ class IrcObjectProxyRegexp:
|
||||
self.irc = irc
|
||||
|
||||
def error(self, msg, s):
|
||||
self.irc.queueMsg(reply(msg, 'Error: ' + s))
|
||||
raise Error, s
|
||||
|
||||
def reply(self, msg, s):
|
||||
self.irc.queueMsg(reply(msg, s))
|
||||
@ -330,9 +340,11 @@ class IrcObjectProxyRegexp:
|
||||
print attr
|
||||
return getattr(self.irc, attr)
|
||||
|
||||
## def __setattr__(self, attr, value):
|
||||
## setattr(self.irc, attr, value)
|
||||
|
||||
|
||||
class IrcObjectProxyRegexpThreaded(IrcObjectProxyRegexp):
|
||||
def error(self, msg, s):
|
||||
self.irc.queueMsg(reply(msg, 'Error: ' + s))
|
||||
|
||||
|
||||
class PrivmsgRegexp(Privmsg):
|
||||
"""A class to allow a person to create regular expression callbacks.
|
||||
@ -353,30 +365,32 @@ class PrivmsgRegexp(Privmsg):
|
||||
threaded = False # Again, like Privmsg...
|
||||
def __init__(self):
|
||||
Privmsg.__init__(self)
|
||||
self.recache = {}
|
||||
if self.threaded:
|
||||
self.Proxy = IrcObjectProxyRegexpThreaded
|
||||
else:
|
||||
self.Proxy = IrcObjectProxyRegexp
|
||||
self.res = []
|
||||
#for name, value in self.__class__.__dict__.iteritems():
|
||||
for name, value in self.__class__.__dict__.items():
|
||||
value = getattr(self, name)
|
||||
if name[0] != '_' and inspect.ismethod(value) and \
|
||||
inspect.getargs(value.im_func.func_code) == \
|
||||
(['self', 'irc', 'msg', 'match'], None, None):
|
||||
try:
|
||||
r = re.compile(value.__doc__)
|
||||
self.res.append((r, value))
|
||||
except sre_constants.error, e:
|
||||
s = '%s.%s has an invalid regexp %s: %s' % \
|
||||
(self.__class__.__name__, name,
|
||||
value.__doc__, debug.exnToString(e))
|
||||
debug.debugMsg(s)
|
||||
|
||||
def doPrivmsg(self, irc, msg):
|
||||
#for name, value in self.__class__.__dict__.iteritems():
|
||||
self.rateLimiter.put(msg)
|
||||
msg = self.rateLimiter.get()
|
||||
if msg:
|
||||
for name, value in self.__class__.__dict__.items():
|
||||
value = getattr(self, name)
|
||||
if name[0] != '_' and inspect.ismethod(value) and \
|
||||
inspect.getargs(value.im_func.func_code) == \
|
||||
(['self', 'irc', 'msg', 'match'], None, None):
|
||||
try:
|
||||
r = self.recache[value.__doc__]
|
||||
except KeyError:
|
||||
try:
|
||||
r = re.compile(value.__doc__)
|
||||
self.recache[value.__doc__] = r
|
||||
except sre_constants.error, e:
|
||||
s = '%s.%s has an invalid regexp %s: %s' % \
|
||||
(self.__class__.__name__, name,
|
||||
value.__doc__, debug.exnToString(e))
|
||||
debug.debugMsg(s)
|
||||
m = r.search(msg.args[1])
|
||||
if m:
|
||||
irc = IrcObjectProxyRegexp(irc)
|
||||
self.callCommand(value, (irc, msg, m))
|
||||
for (r, method) in self.res:
|
||||
m = r.search(msg.args[1])
|
||||
if m:
|
||||
self.rateLimiter.put(msg)
|
||||
msg = self.rateLimiter.get()
|
||||
if msg:
|
||||
irc = IrcObjectProxyRegexp(irc)
|
||||
self.callCommand(method, (irc, msg, m))
|
||||
|
Loading…
Reference in New Issue
Block a user