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:
Jeremy Fincher 2003-03-22 03:16:20 +00:00
parent 8c27ab7917
commit 089e6a400d

View File

@ -89,8 +89,8 @@ def reply(msg, s):
return m return m
class RateLimiter: class RateLimiter:
lastRequest = {}
def __init__(self): def __init__(self):
self.lastRequest = {}
self.limited = [] self.limited = []
self.unlimited = [] self.unlimited = []
@ -110,6 +110,7 @@ class RateLimiter:
if not self.limit(msg): if not self.limit(msg):
self.unlimited.append(msg) self.unlimited.append(msg)
else: else:
debug.printf('Limiting message from %s' % msg.prefix)
self.limited.append(msg) self.limited.append(msg)
def limit(self, msg, penalize=True): def limit(self, msg, penalize=True):
@ -227,7 +228,6 @@ class IrcObjectProxy:
self.finalEvaled = True self.finalEvaled = True
name = self.args.pop(0) name = self.args.pop(0)
callback = self.findCallback(name) callback = self.findCallback(name)
# Use the old Irc object.
try: try:
callback.callCommand(getattr(callback, name), callback.callCommand(getattr(callback, name),
(self, self.msg, self.args)) (self, self.msg, self.args))
@ -246,7 +246,7 @@ class IrcObjectProxy:
self.evalArgs() self.evalArgs()
def error(self, msg, s): def error(self, msg, s):
self.reply(msg, 'Error: ' + s) raise Error, s
def killProxy(self): def killProxy(self):
if not isinstance(self.irc, irclib.Irc): if not isinstance(self.irc, irclib.Irc):
@ -262,22 +262,30 @@ class IrcObjectProxy:
def __getattr__(self, attr): def __getattr__(self, attr):
return getattr(self.irc, 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): class Privmsg(irclib.IrcCallback):
"""Base class for all Privmsg handlers.""" """Base class for all Privmsg handlers."""
threaded = False threaded = False
public = True public = True
def __init__(self): def __init__(self):
self.rateLimiter = RateLimiter() self.rateLimiter = RateLimiter()
if self.threaded:
self.Proxy = IrcObjectProxyThreaded
else:
self.Proxy = IrcObjectProxy
def __call__(self, irc, msg): 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() msg = self.rateLimiter.get()
if msg: if msg:
irclib.IrcCallback.__call__(self, irc, msg) s = addressed(irc.nick, msg)
self.Proxy(irc, msg, Tokenizer().tokenize(s))
def isCommand(self, methodName): def isCommand(self, methodName):
# This function is ugly, but I don't want users to call methods like # This function is ugly, but I don't want users to call methods like
@ -313,7 +321,9 @@ class Privmsg(irclib.IrcCallback):
return return
m = self._r.match(s) m = self._r.match(s)
if m and self.isCommand(canonicalName(m.group(1))): 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: class IrcObjectProxyRegexp:
@ -321,7 +331,7 @@ class IrcObjectProxyRegexp:
self.irc = irc self.irc = irc
def error(self, msg, s): def error(self, msg, s):
self.irc.queueMsg(reply(msg, 'Error: ' + s)) raise Error, s
def reply(self, msg, s): def reply(self, msg, s):
self.irc.queueMsg(reply(msg, s)) self.irc.queueMsg(reply(msg, s))
@ -330,9 +340,11 @@ class IrcObjectProxyRegexp:
print attr print attr
return getattr(self.irc, 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): class PrivmsgRegexp(Privmsg):
"""A class to allow a person to create regular expression callbacks. """A class to allow a person to create regular expression callbacks.
@ -353,30 +365,32 @@ class PrivmsgRegexp(Privmsg):
threaded = False # Again, like Privmsg... threaded = False # Again, like Privmsg...
def __init__(self): def __init__(self):
Privmsg.__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): def doPrivmsg(self, irc, msg):
#for name, value in self.__class__.__dict__.iteritems(): for (r, method) in self.res:
self.rateLimiter.put(msg) m = r.search(msg.args[1])
msg = self.rateLimiter.get() if m:
if msg: self.rateLimiter.put(msg)
for name, value in self.__class__.__dict__.items(): msg = self.rateLimiter.get()
value = getattr(self, name) if msg:
if name[0] != '_' and inspect.ismethod(value) and \ irc = IrcObjectProxyRegexp(irc)
inspect.getargs(value.im_func.func_code) == \ self.callCommand(method, (irc, msg, m))
(['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))