From 0b0da9716dc6be8dcfa4560ce86a69bf3a1b05be Mon Sep 17 00:00:00 2001 From: Valentin Lorentz Date: Sat, 11 Apr 2020 15:00:46 +0200 Subject: [PATCH] callbacks: honor network-specificity of supybot.reply.whenAddressedBy. A side-effect is that plugins should now pass 'irc' instead of 'irc.nick' when they call 'callbacks.addressed()'. --- plugins/MessageParser/plugin.py | 2 +- plugins/Owner/plugin.py | 2 +- plugins/Web/plugin.py | 2 +- src/callbacks.py | 25 ++++++++++++----- test/test_callbacks.py | 49 ++++++++++++++++++++++++++++----- 5 files changed, 63 insertions(+), 17 deletions(-) diff --git a/plugins/MessageParser/plugin.py b/plugins/MessageParser/plugin.py index 0f210345f..604378e36 100644 --- a/plugins/MessageParser/plugin.py +++ b/plugins/MessageParser/plugin.py @@ -189,7 +189,7 @@ class MessageParser(callbacks.Plugin, plugins.ChannelDBHandler): self._runCommandFunction(irc, msg, action) def doPrivmsg(self, irc, msg): - if not callbacks.addressed(irc.nick, msg): #message is not direct command + if not callbacks.addressed(irc, msg): #message is not direct command self.do_privmsg_notice(irc, msg) def doNotice(self, irc, msg): diff --git a/plugins/Owner/plugin.py b/plugins/Owner/plugin.py index 65f768cca..056ce8b02 100644 --- a/plugins/Owner/plugin.py +++ b/plugins/Owner/plugin.py @@ -233,7 +233,7 @@ class Owner(callbacks.Plugin): 'Owner isn\'t first callback: %r' % irc.callbacks if ircmsgs.isCtcp(msg): return - s = callbacks.addressed(irc.nick, msg) + s = callbacks.addressed(irc, msg) if s: ignored = ircdb.checkIgnored(msg.prefix) if ignored: diff --git a/plugins/Web/plugin.py b/plugins/Web/plugin.py index f464fcbee..201b2b619 100644 --- a/plugins/Web/plugin.py +++ b/plugins/Web/plugin.py @@ -208,7 +208,7 @@ class Web(callbacks.PluginRegexp): network = irc.network if not channel: return - if callbacks.addressed(irc.nick, msg): + if callbacks.addressed(irc, msg): return if self.registryValue('titleSnarfer', channel, network): url = match.group(0) diff --git a/src/callbacks.py b/src/callbacks.py index cba199cd6..bf976d3e9 100644 --- a/src/callbacks.py +++ b/src/callbacks.py @@ -40,6 +40,7 @@ from . import shlex import codecs import getopt import inspect +import warnings from . import (conf, ircdb, irclib, ircmsgs, ircutils, log, registry, utils, world) @@ -48,13 +49,22 @@ from .utils.iter import any, all from .i18n import PluginInternationalization _ = PluginInternationalization() -def _addressed(nick, msg, prefixChars=None, nicks=None, +def _addressed(irc, msg, prefixChars=None, nicks=None, prefixStrings=None, whenAddressedByNick=None, whenAddressedByNickAtEnd=None): + if isinstance(irc, str): + warnings.warn( + "callbacks.addressed's first argument should now be be the Irc " + "object instead of the bot's nick.", + DeprecationWarning) + network = None + nick = irc + else: + network = irc.network + nick = irc.nick def get(group): - if ircutils.isChannel(target): - group = group.get(target) - return group() + v = group.getSpecific(network=network, channel=msg.channel) + return v() def stripPrefixStrings(payload): for prefixString in prefixStrings: if payload.startswith(prefixString): @@ -62,7 +72,8 @@ def _addressed(nick, msg, prefixChars=None, nicks=None, return payload assert msg.command == 'PRIVMSG' - (target, payload) = msg.args + target = msg.channel or msg.args[0] + payload = msg.args[1] if not payload: return '' if prefixChars is None: @@ -125,7 +136,7 @@ def _addressed(nick, msg, prefixChars=None, nicks=None, else: return '' -def addressed(nick, msg, **kwargs): +def addressed(irc, msg, **kwargs): """If msg is addressed to 'name', returns the portion after the address. Otherwise returns the empty string. """ @@ -133,7 +144,7 @@ def addressed(nick, msg, **kwargs): if payload is not None: return payload else: - payload = _addressed(nick, msg, **kwargs) + payload = _addressed(irc, msg, **kwargs) msg.tag('addressed', payload) return payload diff --git a/test/test_callbacks.py b/test/test_callbacks.py index 2f55cb84e..2b6fec9c0 100644 --- a/test/test_callbacks.py +++ b/test/test_callbacks.py @@ -175,6 +175,34 @@ class FunctionsTestCase(SupyTestCase): self.assertEqual('foobar--', callbacks.canonicalName('foobar--')) def testAddressed(self): + irc = getTestIrc() + oldprefixchars = str(conf.supybot.reply.whenAddressedBy.chars) + nick = irc.nick + conf.supybot.reply.whenAddressedBy.chars.set('~!@') + inChannel = ['~foo', '@foo', '!foo', + '%s: foo' % nick, '%s foo' % nick, + '%s: foo' % nick.capitalize(), '%s: foo' % nick.upper()] + inChannel = [ircmsgs.privmsg('#foo', s) for s in inChannel] + badmsg = ircmsgs.privmsg('#foo', '%s:foo' % nick) + self.assertFalse(callbacks.addressed(irc, badmsg)) + badmsg = ircmsgs.privmsg('#foo', '%s^: foo' % nick) + self.assertFalse(callbacks.addressed(irc, badmsg)) + for msg in inChannel: + self.assertEqual('foo', callbacks.addressed(irc, msg), msg) + msg = ircmsgs.privmsg(nick, 'foo') + irc._tagMsg(msg) + self.assertEqual('foo', callbacks.addressed(irc, msg)) + conf.supybot.reply.whenAddressedBy.chars.set(oldprefixchars) + msg = ircmsgs.privmsg('#foo', '%s::::: bar' % nick) + self.assertEqual('bar', callbacks.addressed(irc, msg)) + msg = ircmsgs.privmsg('#foo', '%s: foo' % nick.upper()) + self.assertEqual('foo', callbacks.addressed(irc, msg)) + badmsg = ircmsgs.privmsg('#foo', '%s`: foo' % nick) + self.assertFalse(callbacks.addressed(irc, badmsg)) + + def testAddressedLegacy(self): + """Checks callbacks.addressed still accepts the 'nick' argument + instead of 'irc'.""" irc = getTestIrc() oldprefixchars = str(conf.supybot.reply.whenAddressedBy.chars) nick = 'supybot' @@ -184,21 +212,28 @@ class FunctionsTestCase(SupyTestCase): '%s: foo' % nick.capitalize(), '%s: foo' % nick.upper()] inChannel = [ircmsgs.privmsg('#foo', s) for s in inChannel] badmsg = ircmsgs.privmsg('#foo', '%s:foo' % nick) - self.assertFalse(callbacks.addressed(nick, badmsg)) + with self.assertWarnsRegex(DeprecationWarning, 'Irc object instead'): + self.assertFalse(callbacks.addressed(nick, badmsg)) badmsg = ircmsgs.privmsg('#foo', '%s^: foo' % nick) - self.assertFalse(callbacks.addressed(nick, badmsg)) + with self.assertWarnsRegex(DeprecationWarning, 'Irc object instead'): + self.assertFalse(callbacks.addressed(nick, badmsg)) for msg in inChannel: - self.assertEqual('foo', callbacks.addressed(nick, msg), msg) + with self.assertWarns(DeprecationWarning): + self.assertEqual('foo', callbacks.addressed(nick, msg), msg) msg = ircmsgs.privmsg(nick, 'foo') irc._tagMsg(msg) - self.assertEqual('foo', callbacks.addressed(nick, msg)) + with self.assertWarns(DeprecationWarning): + self.assertEqual('foo', callbacks.addressed(nick, msg)) conf.supybot.reply.whenAddressedBy.chars.set(oldprefixchars) msg = ircmsgs.privmsg('#foo', '%s::::: bar' % nick) - self.assertEqual('bar', callbacks.addressed(nick, msg)) + with self.assertWarns(DeprecationWarning): + self.assertEqual('bar', callbacks.addressed(nick, msg)) msg = ircmsgs.privmsg('#foo', '%s: foo' % nick.upper()) - self.assertEqual('foo', callbacks.addressed(nick, msg)) + with self.assertWarns(DeprecationWarning): + self.assertEqual('foo', callbacks.addressed(nick, msg)) badmsg = ircmsgs.privmsg('#foo', '%s`: foo' % nick) - self.assertFalse(callbacks.addressed(nick, badmsg)) + with self.assertWarns(DeprecationWarning): + self.assertFalse(callbacks.addressed(nick, badmsg)) def testAddressedReplyWhenNotAddressed(self): msg1 = ircmsgs.privmsg('#foo', '@bar')