From e44f7ab50ccbfca03ac6aeafd860ffe3ac90f48d Mon Sep 17 00:00:00 2001 From: Jeremy Fincher Date: Tue, 14 Sep 2004 17:12:21 +0000 Subject: [PATCH] Fixed bug #1019387. Again. --- src/ircutils.py | 8 ++++++- src/privmsgs.py | 53 +++++++++++++++++++++++------------------------ src/structures.py | 4 ++++ 3 files changed, 37 insertions(+), 28 deletions(-) diff --git a/src/ircutils.py b/src/ircutils.py index 2a2000cf5..b06f3297b 100644 --- a/src/ircutils.py +++ b/src/ircutils.py @@ -533,7 +533,13 @@ class FloodQueue(object): return self.queues[key] except KeyError: if insert: - q = structures.TimeoutQueue(self.getTimeout) + # python-- + # instancemethod.__repr__ calls the instance.__repr__, which + # means that our __repr__ calls self.queues.__repr__, which + # calls structures.TimeoutQueue.__repr__, which calls + # getTimeout.__repr__, which calls our __repr__, which calls... + getTimeout = lambda : self.getTimeout() + q = structures.TimeoutQueue(getTimeout) self.queues[key] = q return q else: diff --git a/src/privmsgs.py b/src/privmsgs.py index cc278867d..700be577c 100644 --- a/src/privmsgs.py +++ b/src/privmsgs.py @@ -159,51 +159,50 @@ class UrlSnarfThread(threading.Thread): threading.Thread.__init__(self, *args, **kwargs) self.setDaemon(True) + def run(self): + try: + super(UrlSnarfThread, self).run() + finally: + # This was acquired in newf in urlSnarfer. + _snarfLock.release() + + class SnarfQueue(ircutils.FloodQueue): + timeout = conf.supybot.snarfThrottle def key(self, channel): return channel - def getTimeout(self): - return conf.supybot.snarfThrottle() - _snarfed = SnarfQueue() -class SnarfIrc(object): - def __init__(self, irc, channel, url): - self.irc = irc - self.url = url - self.channel = channel - - def reply(self, *args, **kwargs): - _snarfed.enqueue(self.channel, self.url) - self.irc.reply(*args, **kwargs) - - def __getattr__(self, attr): - return getattr(self.irc, attr) - +_snarfLock = threading.Lock() def urlSnarfer(f): """Protects the snarfer from loops and whatnot.""" def newf(self, irc, msg, match, *L, **kwargs): - if msg.repliedTo: - self.log.debug('Not calling snarfer, msg is already repliedTo.') - return + _snarfLock.acquire() + url = match.group(0) channel = msg.args[0] if not ircutils.isChannel(channel): return - c = ircdb.channels.getChannel(channel) - if c.lobotomized: - self.log.info('Refusing to snarf in %s: lobotomized.', channel) + if ircdb.channels.getChannel(channel).lobotomized: + self.log.info('Not snarfing in %s: lobotomized.', channel) return - url = match.group(0) if _snarfed.has(channel, url): - self.log.info('Refusing to snarf %s, already snarfed.', url) + self.log.info('Throttling snarf of %s in %s.', url, channel) return - irc = SnarfIrc(irc, channel, url) + _snarfed.enqueue(channel, url) + def doSnarf(): + try: + if msg.repliedTo: + self.log.debug('Not snarfing, msg is already repliedTo.') + return + f(self, irc, msg, match, *L, **kwargs) + finally: + _snarfLock.release() if threading.currentThread() is not world.mainThread: - f(self, irc, msg, match, *L, **kwargs) + doSnarf() else: L = list(L) - t = UrlSnarfThread(target=f,args=[self,irc,msg,match]+L,url=url) + t = UrlSnarfThread(target=doSnarf, url=url) t.start() newf = utils.changeFunctionName(newf, f.func_name, f.__doc__) return newf diff --git a/src/structures.py b/src/structures.py index 05c24a2db..653a25b5d 100644 --- a/src/structures.py +++ b/src/structures.py @@ -311,6 +311,10 @@ class TimeoutQueue(object): self.queue = queue self.timeout = timeout + def __repr__(self): + return '%s(timeout=%r, queue=%r)' % (self.__class__.__name__, + self.timeout, self.queue) + def _getTimeout(self): if callable(self.timeout): return self.timeout()