From 360a2036ac26d78c3f98db37239da9987f5c326a Mon Sep 17 00:00:00 2001 From: James McCoy Date: Mon, 5 Dec 2011 22:48:09 -0500 Subject: [PATCH 01/10] Use socket.inet_aton for isIPV4 since Windows doesn't (always?) have inet_pton Closes: Sf#3430008 Signed-off-by: James McCoy --- src/utils/net.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/net.py b/src/utils/net.py index ffe8c2005..17abb3b5b 100644 --- a/src/utils/net.py +++ b/src/utils/net.py @@ -73,7 +73,7 @@ def isIPV4(s): 0 """ try: - return bool(socket.inet_pton(socket.AF_INET, s)) + return bool(socket.inet_aton(s)) except socket.error: return False From 5b4c150d037ddfcd7358e00850178a4b60fd44b8 Mon Sep 17 00:00:00 2001 From: James McCoy Date: Mon, 5 Dec 2011 23:13:09 -0500 Subject: [PATCH 02/10] Prevent nesting of Misc.tell Signed-off-by: James McCoy --- plugins/Misc/plugin.py | 2 ++ plugins/Misc/test.py | 3 +++ 2 files changed, 5 insertions(+) diff --git a/plugins/Misc/plugin.py b/plugins/Misc/plugin.py index 702a70b3b..4ed95f50d 100644 --- a/plugins/Misc/plugin.py +++ b/plugins/Misc/plugin.py @@ -381,6 +381,8 @@ class Misc(callbacks.Plugin): Tells the whatever is. Use nested commands to your benefit here. """ + if irc.nested: + irc.error('This command cannot be nested.', Raise=True) if target.lower() == 'me': target = msg.nick if ircutils.isChannel(target): diff --git a/plugins/Misc/test.py b/plugins/Misc/test.py index bf7948dbd..1f379263b 100644 --- a/plugins/Misc/test.py +++ b/plugins/Misc/test.py @@ -142,6 +142,9 @@ class MiscTestCase(ChannelPluginTestCase): m = self.getMsg('tell me you love me') self.failUnless(m.args[0] == self.nick) + def testNoNestedTell(self): + self.assertRegexp('echo [tell %s foo]' % self.nick, 'nested') + def testTellDoesNotPropogateAction(self): m = self.getMsg('tell foo [action bar]') self.failIf(ircmsgs.isAction(m)) From a79e9c0cad23cb6917a95a17598e46ed00643fdf Mon Sep 17 00:00:00 2001 From: Valentin Lorentz Date: Sun, 13 Nov 2011 16:34:01 +0100 Subject: [PATCH 03/10] Debug: Fix import. --- sandbox/Debug/plugin.py | 1 + 1 file changed, 1 insertion(+) diff --git a/sandbox/Debug/plugin.py b/sandbox/Debug/plugin.py index 26175ef44..3ee72750f 100644 --- a/sandbox/Debug/plugin.py +++ b/sandbox/Debug/plugin.py @@ -46,6 +46,7 @@ import supybot.conf as conf import supybot.utils as utils import supybot.ircdb as ircdb from supybot.commands import * +import supybot.ircmsgs as ircmsgs import supybot.callbacks as callbacks def getTracer(fd): From 4ddfae427f9846c77d72cbb3fe3b6a8cdef658e9 Mon Sep 17 00:00:00 2001 From: James McCoy Date: Mon, 5 Dec 2011 23:52:38 -0500 Subject: [PATCH 04/10] Perform all received* IrcMsg tagging in one spot. This also fixes a long-standing failing Misc test since it was relying on the receivedAt tag. Signed-off-by: James McCoy --- src/drivers/__init__.py | 2 -- src/irclib.py | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/drivers/__init__.py b/src/drivers/__init__.py index 333ec8258..03cf9e59b 100644 --- a/src/drivers/__init__.py +++ b/src/drivers/__init__.py @@ -210,11 +210,9 @@ def newDriver(irc, moduleName=None): return driver def parseMsg(s): - start = time.time() s = s.strip() if s: msg = ircmsgs.IrcMsg(s) - msg.tag('receivedAt', start) return msg else: return None diff --git a/src/irclib.py b/src/irclib.py index 4f7fc7951..164f23050 100644 --- a/src/irclib.py +++ b/src/irclib.py @@ -777,6 +777,7 @@ class Irc(IrcCommandDispatcher): """Called by the IrcDriver; feeds a message received.""" msg.tag('receivedBy', self) msg.tag('receivedOn', self.network) + msg.tag('receivedAt', time.time()) if msg.args and self.isChannel(msg.args[0]): channel = msg.args[0] else: From f6f9e654cb5801baa05adfe141df640a29dc3c90 Mon Sep 17 00:00:00 2001 From: James McCoy Date: Tue, 6 Dec 2011 00:08:01 -0500 Subject: [PATCH 05/10] Only use ircmsg.whois's mask argument if it's non-empty. Closes: Sf#3121298 Signed-off-by: James McCoy --- src/ircmsgs.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/ircmsgs.py b/src/ircmsgs.py index f2fec7aec..9859febb9 100644 --- a/src/ircmsgs.py +++ b/src/ircmsgs.py @@ -727,7 +727,10 @@ def whois(nick, mask='', prefix='', msg=None): assert isNick(nick), repr(nick) if msg and not prefix: prefix = msg.prefix - return IrcMsg(prefix=prefix, command='WHOIS', args=(nick, mask), msg=msg) + args = (nick,) + if mask: + args = (nick, mask) + return IrcMsg(prefix=prefix, command='WHOIS', args=args, msg=msg) def names(channel=None, prefix='', msg=None): if conf.supybot.protocols.irc.strictRfc(): From 998819da58aa79858d9d683c345d8dac0f49b721 Mon Sep 17 00:00:00 2001 From: James McCoy Date: Tue, 6 Dec 2011 00:22:40 -0500 Subject: [PATCH 06/10] Bug fixes in src/ircmsgs.py unbans did send the repr() of the ban list, and IrcMsg.__hash__ did try to hash a list. Conflicts: src/version.py Signed-off-by: James McCoy --- src/ircmsgs.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ircmsgs.py b/src/ircmsgs.py index 9859febb9..911a2290b 100644 --- a/src/ircmsgs.py +++ b/src/ircmsgs.py @@ -182,7 +182,7 @@ class IrcMsg(object): return self._hash self._hash = hash(self.command) ^ \ hash(self.prefix) ^ \ - hash(self.args) + hash(repr(self.args)) return self._hash def __repr__(self): @@ -522,7 +522,8 @@ def unbans(channel, hostmasks, prefix='', msg=None): if msg and not prefix: prefix = msg.prefix return IrcMsg(prefix=prefix, command='MODE', msg=msg, - args=(channel, '-' + ('b'*len(hostmasks)), hostmasks)) + args=(channel, '-' + ('b'*len(hostmasks)), + ' '.join(hostmasks))) def kick(channel, nick, s='', prefix='', msg=None): """Returns a KICK to kick nick from channel with the message msg.""" From 71bcc2bc7c7e6ecb7906f453a1180b26fc73e783 Mon Sep 17 00:00:00 2001 From: Daniel Folkinshteyn Date: Tue, 18 Jan 2011 13:51:34 -0500 Subject: [PATCH 07/10] Services: add some more strings indicating identification success. Signed-off-by: James McCoy --- plugins/Services/plugin.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/Services/plugin.py b/plugins/Services/plugin.py index 1d17a8085..651c68db8 100644 --- a/plugins/Services/plugin.py +++ b/plugins/Services/plugin.py @@ -301,6 +301,8 @@ class Services(callbacks.Plugin): pass elif ('now recognized' in s) or \ ('already identified' in s) or \ + ('already logged in' in s) or \ + ('successfully identified' in s) or \ ('password accepted' in s) or \ ('now identified' in s): # freenode, oftc, arstechnica, zirc, .... From d5648ab5344c3b930d35890a0a3698492f89a42d Mon Sep 17 00:00:00 2001 From: Daniel Folkinshteyn Date: Sun, 13 Mar 2011 14:21:46 -0400 Subject: [PATCH 08/10] Services: fix problem with some channels being mixed up between networks on startup, when noJoinsUntilIdentified is true. When noJoinsUntilIdentified config is true, the bot holds join messages in a 'waitingJoins' list, and processes them once nickserv identification comes through. The problem was that when the bot is configured to join multiple networks, join messages from different networks would get appended to the same list, without any differentiation by which message belongs to which network. Thus, if there are messages waiting for multiple networks, it would often be the case that whichever network got identification done first, would 'pick up' other network's join messages. This fix stores the network name along with the join messages in the list, and has each network pick out only its own join messages. Conflicts: src/version.py Signed-off-by: James McCoy --- plugins/Services/plugin.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/plugins/Services/plugin.py b/plugins/Services/plugin.py index 651c68db8..105bca1b0 100644 --- a/plugins/Services/plugin.py +++ b/plugins/Services/plugin.py @@ -30,6 +30,7 @@ import re import time +import copy import config @@ -76,7 +77,7 @@ class Services(callbacks.Plugin): if self.registryValue('noJoinsUntilIdentified'): self.log.info('Holding JOIN to %s until identified.', msg.args[0]) - self.waitingJoins.append(msg) + self.waitingJoins.append((irc.network, msg,)) return None return msg @@ -314,9 +315,11 @@ class Services(callbacks.Plugin): for channel in self.channels: irc.queueMsg(networkGroup.channels.join(channel)) if self.waitingJoins: - for m in self.waitingJoins: - irc.sendMsg(m) - self.waitingJoins = [] + tmp_wj = copy.deepcopy(self.waitingJoins) # can't iterate over list if we're modifying it + for netname, m in tmp_wj: + if netname == irc.network: + irc.sendMsg(m) + self.waitingJoins.remove((netname, m,)) elif 'not yet authenticated' in s: # zirc.org has this, it requires an auth code. email = s.split()[-1] From 1e1b39783b2789b696b57ab60209c16cd13c3c35 Mon Sep 17 00:00:00 2001 From: Daniel Folkinshteyn Date: Mon, 8 Aug 2011 18:45:02 -0400 Subject: [PATCH 09/10] Services: catch occasional error when removing waiting joins from list Signed-off-by: James McCoy --- plugins/Services/plugin.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plugins/Services/plugin.py b/plugins/Services/plugin.py index 105bca1b0..28d719544 100644 --- a/plugins/Services/plugin.py +++ b/plugins/Services/plugin.py @@ -319,7 +319,10 @@ class Services(callbacks.Plugin): for netname, m in tmp_wj: if netname == irc.network: irc.sendMsg(m) - self.waitingJoins.remove((netname, m,)) + try: + self.waitingJoins.remove((netname, m,)) + except ValueError: + pass # weird stuff happen sometimes elif 'not yet authenticated' in s: # zirc.org has this, it requires an auth code. email = s.split()[-1] From c90fafebe790f86291e3560938da573ab0f837d4 Mon Sep 17 00:00:00 2001 From: James McCoy Date: Tue, 6 Dec 2011 00:55:29 -0500 Subject: [PATCH 10/10] Simplify handling of per-network waitingJoins Signed-off-by: James McCoy --- plugins/Services/plugin.py | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/plugins/Services/plugin.py b/plugins/Services/plugin.py index 28d719544..5ca8484f1 100644 --- a/plugins/Services/plugin.py +++ b/plugins/Services/plugin.py @@ -30,7 +30,6 @@ import re import time -import copy import config @@ -62,7 +61,7 @@ class Services(callbacks.Plugin): self.channels = [] self.sentGhost = None self.identified = False - self.waitingJoins = [] + self.waitingJoins = {} def disabled(self, irc): disabled = self.registryValue('disabledNetworks') @@ -77,7 +76,8 @@ class Services(callbacks.Plugin): if self.registryValue('noJoinsUntilIdentified'): self.log.info('Holding JOIN to %s until identified.', msg.args[0]) - self.waitingJoins.append((irc.network, msg,)) + self.waitingJoins.setdefault(irc.network, []) + self.waitingJoins[irc.network].append(msg) return None return msg @@ -314,15 +314,10 @@ class Services(callbacks.Plugin): self.checkPrivileges(irc, channel) for channel in self.channels: irc.queueMsg(networkGroup.channels.join(channel)) - if self.waitingJoins: - tmp_wj = copy.deepcopy(self.waitingJoins) # can't iterate over list if we're modifying it - for netname, m in tmp_wj: - if netname == irc.network: - irc.sendMsg(m) - try: - self.waitingJoins.remove((netname, m,)) - except ValueError: - pass # weird stuff happen sometimes + waitingJoins = self.waitingJoins.pop(irc.network, None) + if waitingJoins: + for m in waitingJoins: + irc.sendMsg(m) elif 'not yet authenticated' in s: # zirc.org has this, it requires an auth code. email = s.split()[-1]