mirror of
				https://github.com/Mikaela/Limnoria.git
				synced 2025-11-04 09:37:25 +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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user