mirror of
https://github.com/Mikaela/Limnoria.git
synced 2024-12-25 12:12:54 +01:00
Removed crazy-buggy rate limiting stuff.
This commit is contained in:
parent
94e3726b82
commit
65e469ba38
@ -109,8 +109,6 @@ class Owner(privmsgs.CapabilityCheckingPrivmsg):
|
|||||||
|
|
||||||
def doPrivmsg(self, irc, msg):
|
def doPrivmsg(self, irc, msg):
|
||||||
callbacks.Privmsg.handled = False
|
callbacks.Privmsg.handled = False
|
||||||
if ircdb.checkIgnored(msg.prefix, msg.args[0]):
|
|
||||||
return
|
|
||||||
s = callbacks.addressed(irc.nick, msg)
|
s = callbacks.addressed(irc.nick, msg)
|
||||||
if s:
|
if s:
|
||||||
try:
|
try:
|
||||||
|
117
src/callbacks.py
117
src/callbacks.py
@ -135,78 +135,6 @@ def getSyntax(method, name=None):
|
|||||||
doclines = method.__doc__.splitlines()
|
doclines = method.__doc__.splitlines()
|
||||||
return '%s %s' % (name, doclines[0])
|
return '%s %s' % (name, doclines[0])
|
||||||
|
|
||||||
class RateLimiter:
|
|
||||||
"""This class is used to rate limit replies to certain people, in order to
|
|
||||||
prevent abuse of the bot. Basically, you put messages in with the .put
|
|
||||||
method, and then take a message out with the .get method. .get may return
|
|
||||||
None if there is no message waiting that isn't being rate limited.
|
|
||||||
"""
|
|
||||||
# lastRequest must be class-global, so each instance of it uses the same
|
|
||||||
# information. Otherwise, if it was an instance variable, then rate
|
|
||||||
# limiting would only work within a single plugin.
|
|
||||||
lastRequest = {}
|
|
||||||
def __init__(self):
|
|
||||||
self.limited = []
|
|
||||||
self.unlimited = []
|
|
||||||
|
|
||||||
def get(self):
|
|
||||||
"""Returns the next un-ratelimited message, or the next rate-limited
|
|
||||||
message whose time has come up."""
|
|
||||||
if self.unlimited:
|
|
||||||
return self.unlimited.pop(0)
|
|
||||||
elif self.limited:
|
|
||||||
for i in range(len(self.limited)):
|
|
||||||
msg = self.limited[i]
|
|
||||||
if not self._limit(msg, penalize=False):
|
|
||||||
return self.limited.pop(i)
|
|
||||||
return None
|
|
||||||
else:
|
|
||||||
return None
|
|
||||||
|
|
||||||
def put(self, msg):
|
|
||||||
"""Puts a message in for possible ratelimiting."""
|
|
||||||
t = self._limit(msg)
|
|
||||||
if t and not world.testing:
|
|
||||||
s = 'Limiting message from %s for %s seconds' % (msg.prefix, t)
|
|
||||||
debug.msg(s, 'normal')
|
|
||||||
self.limited.append(msg)
|
|
||||||
else:
|
|
||||||
self.unlimited.append(msg)
|
|
||||||
|
|
||||||
def _limit(self, msg, penalize=True):
|
|
||||||
if msg.prefix and ircutils.isUserHostmask(msg.prefix):
|
|
||||||
(nick, user, host) = ircutils.splitHostmask(msg.prefix)
|
|
||||||
key = '@'.join((user, host))
|
|
||||||
now = time.time()
|
|
||||||
if ircdb.checkCapabilities(msg.prefix, ('owner', 'admin')):
|
|
||||||
return 0
|
|
||||||
if key in self.lastRequest:
|
|
||||||
# Here's how we throttle requests. We keep a dictionary of
|
|
||||||
# (lastRequest, wait period) tuples. When a request arrives,
|
|
||||||
# we check to see if we have a lastRequest tuple, and if so,
|
|
||||||
# we check to make sure that lastRequest was more than wait
|
|
||||||
# seconds ago. If not, we're getting flooded, and we set
|
|
||||||
# the lastRequest time to the current time and increment wait,
|
|
||||||
# thus making it even harder for the flooder to get us to
|
|
||||||
# send them messages.
|
|
||||||
(t, wait) = self.lastRequest[key]
|
|
||||||
if now - t <= wait:
|
|
||||||
if penalize:
|
|
||||||
newWait = wait + conf.throttleTime
|
|
||||||
else:
|
|
||||||
newWait = wait - (now - t)
|
|
||||||
self.lastRequest[key] = (now, newWait)
|
|
||||||
return newWait
|
|
||||||
else:
|
|
||||||
self.lastRequest[key] = (now, conf.throttleTime)
|
|
||||||
return 0
|
|
||||||
else:
|
|
||||||
self.lastRequest[key] = (now, conf.throttleTime)
|
|
||||||
return 0
|
|
||||||
else:
|
|
||||||
return 0
|
|
||||||
|
|
||||||
|
|
||||||
class Error(Exception):
|
class Error(Exception):
|
||||||
"""Generic class for errors in Privmsg callbacks."""
|
"""Generic class for errors in Privmsg callbacks."""
|
||||||
pass
|
pass
|
||||||
@ -597,10 +525,10 @@ class Privmsg(irclib.IrcCallback):
|
|||||||
public = True
|
public = True
|
||||||
handled = False
|
handled = False
|
||||||
alwaysCall = ()
|
alwaysCall = ()
|
||||||
|
noIgnore = False
|
||||||
commandArgs = ['self', 'irc', 'msg', 'args']
|
commandArgs = ['self', 'irc', 'msg', 'args']
|
||||||
_mores = {} # This must be class-scope, so all subclasses use the same one.
|
_mores = {} # This must be class-scope, so all subclasses use the same one.
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.rateLimiter = RateLimiter()
|
|
||||||
self.Proxy = IrcObjectProxy
|
self.Proxy = IrcObjectProxy
|
||||||
canonicalname = canonicalName(self.name())
|
canonicalname = canonicalName(self.name())
|
||||||
self._original = getattr(self, canonicalname, None)
|
self._original = getattr(self, canonicalname, None)
|
||||||
@ -658,17 +586,13 @@ class Privmsg(irclib.IrcCallback):
|
|||||||
world.startup = False
|
world.startup = False
|
||||||
|
|
||||||
def __call__(self, irc, msg):
|
def __call__(self, irc, msg):
|
||||||
|
if msg.command == 'PRIVMSG':
|
||||||
|
if self.noIgnore or not ircdb.checkIgnored(msg.prefix,msg.args[0]):
|
||||||
|
irclib.IrcCallback.__call__(self, irc, msg)
|
||||||
|
else:
|
||||||
|
debug.msg('Ignoring %s.' % msg.prefix)
|
||||||
|
else:
|
||||||
irclib.IrcCallback.__call__(self, irc, msg)
|
irclib.IrcCallback.__call__(self, irc, msg)
|
||||||
# Now, if there's anything in the rateLimiter...
|
|
||||||
msg = self.rateLimiter.get()
|
|
||||||
while msg:
|
|
||||||
s = addressed(irc.nick, msg)
|
|
||||||
try:
|
|
||||||
args = tokenize(s)
|
|
||||||
self.Proxy(irc, msg, args)
|
|
||||||
except SyntaxError, e:
|
|
||||||
irc.queueMsg(reply(msg, str(e)))
|
|
||||||
msg = self.rateLimiter.get()
|
|
||||||
|
|
||||||
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
|
||||||
@ -734,7 +658,6 @@ class PrivmsgRegexp(Privmsg):
|
|||||||
better class to use, at the very least for consistency's sake, but also
|
better class to use, at the very least for consistency's sake, but also
|
||||||
because it's much more easily coded and maintained.
|
because it's much more easily coded and maintained.
|
||||||
"""
|
"""
|
||||||
threaded = False # Again, like Privmsg...
|
|
||||||
flags = re.I
|
flags = re.I
|
||||||
commandArgs = ['self', 'irc', 'msg', 'match']
|
commandArgs = ['self', 'irc', 'msg', 'match']
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@ -763,10 +686,6 @@ class PrivmsgRegexp(Privmsg):
|
|||||||
irc.error(msg, debug.exnToString(e))
|
irc.error(msg, debug.exnToString(e))
|
||||||
|
|
||||||
def doPrivmsg(self, irc, msg):
|
def doPrivmsg(self, irc, msg):
|
||||||
if ircdb.checkIgnored(msg.prefix, msg.args[0]):
|
|
||||||
debug.msg('PrivmsgRegexp.doPrivmsg: ignoring %s' % msg.prefix)
|
|
||||||
return
|
|
||||||
fed = False
|
|
||||||
for (r, method) in self.res:
|
for (r, method) in self.res:
|
||||||
spans = sets.Set()
|
spans = sets.Set()
|
||||||
for m in r.finditer(msg.args[1]):
|
for m in r.finditer(msg.args[1]):
|
||||||
@ -775,11 +694,6 @@ class PrivmsgRegexp(Privmsg):
|
|||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
spans.add(m.span())
|
spans.add(m.span())
|
||||||
if not fed:
|
|
||||||
fed = True
|
|
||||||
self.rateLimiter.put(msg)
|
|
||||||
msg = self.rateLimiter.get()
|
|
||||||
if msg:
|
|
||||||
proxy = IrcObjectProxyRegexp(irc)
|
proxy = IrcObjectProxyRegexp(irc)
|
||||||
self.callCommand(method, proxy, msg, m)
|
self.callCommand(method, proxy, msg, m)
|
||||||
|
|
||||||
@ -790,8 +704,8 @@ class PrivmsgCommandAndRegexp(Privmsg):
|
|||||||
(or list) attribute "regexps".
|
(or list) attribute "regexps".
|
||||||
"""
|
"""
|
||||||
flags = re.I
|
flags = re.I
|
||||||
regexps = () # Use sets.Set() in your own callbacks.
|
regexps = ()
|
||||||
addressedRegexps = () # Ditto on the sets.Sets() idea.
|
addressedRegexps = ()
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
Privmsg.__init__(self)
|
Privmsg.__init__(self)
|
||||||
self.res = []
|
self.res = []
|
||||||
@ -816,20 +730,12 @@ class PrivmsgCommandAndRegexp(Privmsg):
|
|||||||
raise
|
raise
|
||||||
|
|
||||||
def doPrivmsg(self, irc, msg):
|
def doPrivmsg(self, irc, msg):
|
||||||
if ircdb.checkIgnored(msg.prefix, msg.args[0]):
|
|
||||||
return
|
|
||||||
fed = False
|
|
||||||
for (r, method) in self.res:
|
for (r, method) in self.res:
|
||||||
originalHandled = self.handled
|
originalHandled = self.handled
|
||||||
name = method.__name__
|
name = method.__name__
|
||||||
for m in r.finditer(msg.args[1]):
|
for m in r.finditer(msg.args[1]):
|
||||||
if originalHandled and name not in self.alwaysCall:
|
if originalHandled and name not in self.alwaysCall:
|
||||||
continue
|
continue
|
||||||
if not fed:
|
|
||||||
fed = True
|
|
||||||
self.rateLimiter.put(msg)
|
|
||||||
msg = self.rateLimiter.get()
|
|
||||||
if msg:
|
|
||||||
proxy = IrcObjectProxyRegexp(irc)
|
proxy = IrcObjectProxyRegexp(irc)
|
||||||
self.callCommand(method, proxy, msg, m, catchErrors=True)
|
self.callCommand(method, proxy, msg, m, catchErrors=True)
|
||||||
s = addressed(irc.nick, msg)
|
s = addressed(irc.nick, msg)
|
||||||
@ -840,11 +746,6 @@ class PrivmsgCommandAndRegexp(Privmsg):
|
|||||||
for m in r.finditer(s):
|
for m in r.finditer(s):
|
||||||
if originalHandled and name not in self.alwaysCall:
|
if originalHandled and name not in self.alwaysCall:
|
||||||
continue
|
continue
|
||||||
if not fed:
|
|
||||||
fed = True
|
|
||||||
self.rateLimiter.put(msg)
|
|
||||||
msg = self.rateLimiter.get()
|
|
||||||
if msg:
|
|
||||||
proxy = IrcObjectProxyRegexp(irc)
|
proxy = IrcObjectProxyRegexp(irc)
|
||||||
self.callCommand(method,proxy,msg,m,catchErrors=True)
|
self.callCommand(method,proxy,msg,m,catchErrors=True)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user