Support highlights as command triggers too

This commit is contained in:
dave 2018-02-10 16:44:51 -08:00
parent c3e14a8d0d
commit f7990667eb
8 changed files with 51 additions and 30 deletions

View File

@ -74,26 +74,36 @@ class TouchReload(Thread):
sleep(self.sleep)
def messageHasCommand(command, message, requireArgs=False):
"""Check if a message has a command with or without args in it
def messageHasCommand(command, message, requireArgs=False, withHighlight=False):
"""
Check if a message has a command with or without args in it
:param command: the command string to look for, like !ban. If a list is passed, the first match is returned.
:type command: str or list
:param message: the message string to look in, like "!ban Lil_Mac"
:type message: str
:param requireArgs: if true, only validate if the command use has any amount of trailing text
:type requireArgs: bool"""
:param requireArgs: only match if trailing data is passed with the command used. False-like values disable This
requirement. True-like values require any number of args greater than one. Int values require a specific number
of args
:type requireArgs: bool
:param withHighlight: if provided, treat 'Nick[:,] command args' the same as '.command args' where Nick is a string
provided by withHighlight
:type withHighlight: str
"""
if not type(command) == list:
command = [command]
for item in command:
cmd = messageHasCommandSingle(item, message, requireArgs)
cmd = messageHasCommandSingle(item, message, requireArgs, withHighlight)
if cmd:
return cmd
return False
def messageHasCommandSingle(command, message, requireArgs=False):
def messageHasCommandSingle(command, message, requireArgs=False, withHighlight=False):
if withHighlight:
if message.startswith(withHighlight + ": ") or message.startswith(withHighlight + ", "):
message = "." + message[len(withHighlight) + 2:]
# Check if the message at least starts with the command
messageBeginning = message[0:len(command)]
if messageBeginning != command:
@ -108,13 +118,16 @@ def messageHasCommandSingle(command, message, requireArgs=False):
args = ""
if argsStart > 0:
args = message[argsStart + 1:].strip()
if requireArgs and args == '':
return False
args_list = args.split()
if requireArgs:
if args == '':
return False
elif type(requireArgs) is int and len(args_list) != requireArgs:
return False
# Verified! Return the set.
return ParsedCommand(command,
args.split(" ") if args else [],
args_list,
args,
message)

View File

@ -58,6 +58,8 @@ class IRCCore(object):
self.bind_addr = None
"""Optionally bind to a specific address. This should be a (host, port) tuple."""
self.nick = None
# Set up hooks for modules
self.initHooks()

View File

@ -197,10 +197,13 @@ class command(hook):
:param keywords: commands to listen for
:type keywords: str
:param require_args: only match if trailing data is passed with the command used
:type require_args: bool
:param require_args: only match if trailing data is passed with the command used. False-like values disable This
requirement. True-like values require any number of args greater than one. Int values require a specific
number of args
:type require_args: bool, int
:param allow_private: enable matching in private messages
:type allow_private: bool
:param allow_highlight: treat 'Nick[:,] command args' the same as '.command args'
"""
prefix = "."
@ -208,12 +211,12 @@ class command(hook):
Hotkey that must appear before commands
"""
def __init__(self, *keywords, require_args=False, allow_private=False):
def __init__(self, *keywords, require_args=False, allow_private=False, allow_highlight=True):
super().__init__("PRIVMSG")
self.keywords = keywords
self.require_args = require_args
self.allow_private = allow_private
self.parsed_cmd = None
self.allow_highlight = allow_highlight
def validate(self, msg, bot):
"""
@ -224,19 +227,23 @@ class command(hook):
:param bot: reference to main pyircbot
:type bot: pyircbot.pyircbot.PyIRCBot
"""
bot_nick = bot.get_nick()
if not super().validate(msg, bot):
return False
if msg.args[0][0] != "#" and not self.allow_private:
return False
for keyword in self.keywords:
single = self._validate_one(msg, keyword)
single = self._validate_prefixedcommand(msg, keyword, bot_nick)
if single:
print(single)
return single
return False
def _validate_one(self, msg, keyword):
def _validate_prefixedcommand(self, msg, keyword, nick):
with_prefix = "{}{}".format(self.prefix, keyword)
return messageHasCommand(with_prefix, msg.trailing, requireArgs=self.require_args)
return messageHasCommand(with_prefix, msg.trailing,
requireArgs=self.require_args,
withHighlight=nick if self.allow_highlight else False)
class regex(hook):

View File

@ -9,7 +9,6 @@
from pyircbot.modulebase import ModuleBase, command
from pyircbot.modules.ModInfo import info
from pyircbot.common import messageHasCommand
from decimal import Decimal
import time
import hashlib

View File

@ -18,16 +18,8 @@ class LMGTFY(ModuleBase):
@info("lmgtfy <term> display a condescending internet query", cmds=["lmgtfy"])
@command("lmgtfy", require_args=True)
def handleMessage(self, msg, cmd):
message = msg.trailing.split(" ")[1:]
link = self.createLink(message)
self.bot.act_PRIVMSG(msg.args[0], "%s: %s" % (msg.prefix.nick, link))
link = self.createLink(cmd.args_str)
self.bot.act_PRIVMSG(msg.args[0], "{}: {}".format(msg.prefix.nick, link))
def createLink(self, message):
finalUrl = BASE_URL
for word in message:
finalUrl += urllib.parse.quote(word)
if word != message[-1]:
finalUrl += "+"
return finalUrl
return BASE_URL + "+".join([urllib.parse.quote(word) for word in message.split()])

View File

@ -3,4 +3,4 @@
export PYTHONUNBUFFERED=1
export PYTHONPATH=.
py.test --fulltrace --cov=pyircbot --cov-report html -n 4 tests/
py.test --fulltrace --cov=pyircbot --cov-report html -n 4 tests/ $@

View File

@ -50,6 +50,9 @@ class FakeBaseBot(PrimitiveBot):
super().unloadmodule(module_name)
self._modules.remove(module_name)
def get_nick(self):
return "testbot"
@pytest.fixture
def fakebot(tmpdir):

View File

@ -14,3 +14,8 @@ def googbot(fakebot):
def test_lmgtfy_basic(googbot):
googbot.feed_line(".lmgtfy foobar asdf")
googbot.act_PRIVMSG.assert_called_once_with('#test', 'chatter: http://lmgtfy.com/?q=foobar+asdf')
def test_lmgtfy_highlight(googbot):
googbot.feed_line("{}: lmgtfy foobar asdf".format(googbot.get_nick()))
googbot.act_PRIVMSG.assert_called_once_with('#test', 'chatter: http://lmgtfy.com/?q=foobar+asdf')