move command aliases out to their own module (aliases.py)

This commit is contained in:
jesopo 2019-11-20 11:34:36 +00:00
parent 2f07c308ea
commit 17edb1c8cb
2 changed files with 126 additions and 66 deletions

113
modules/aliases.py Normal file
View file

@ -0,0 +1,113 @@
#--depends-on commands
import re
from src import EventManager, ModuleManager, utils
REGEX_ARG_NUMBER = re.compile(r"\$(?:(\d+)(-?)|(-))")
SETTING_PREFIX = "alias-"
class Module(ModuleManager.BaseModule):
def _arg_replace(self, s, args_split):
for match in REGEX_ARG_NUMBER.finditer(s):
if match.group(1):
index = int(match.group(1))
continuous = match.group(2) == "-"
if index >= len(args_split):
raise IndexError("Unknown alias arg index")
else:
index = 0
continuous = True
if continuous:
replace = " ".join(args_split[index:])
else:
replace = args_split[index]
s = s.replace(match.group(0), replace)
return s
def _get_alias(self, server, target, command):
setting = "%s%s" % (SETTING_PREFIX, command)
alias = self.bot.get_setting(setting,
server.get_setting(setting,
target.get_setting(setting, None)))
if not alias == None:
alias, _, args = alias.partition(" ")
return alias, args
return None
def _get_aliases(self, targets):
alias_list = []
for target in targets:
alias_list += target.find_settings(prefix=SETTING_PREFIX)
aliases = {}
for alias in alias_list:
alias, _, args = alias.partition(" ")
if not alias in aliases:
aliases[alias] = args or None
return aliases
@utils.hook("get.command")
@utils.kwarg("priority", EventManager.PRIORITY_URGENT)
def get_command(self, event):
alias = self._get_alias(event["server"], event["target"],
event["command"].command)
if not alias == None:
alias, alias_args = alias
event["command"].command = alias
event["command"].args = self._arg_replace(alias_args,
event["command"].args.split(" "))
@utils.hook("received.command.alias")
@utils.hook("received.command.calias")
@utils.kwarg("min_args", 1)
@utils.kwarg("usage", "list")
@utils.kwarg("usage", "add <alias> <command> [arg1 [arg2 ...]]")
@utils.kwarg("usage", "remove <alias>")
@utils.kwarg("remove_empty", False)
def alias(self, event):
target = event["server"]
if event["command"] == "calias":
if not event["is_channel"]:
raise utils.EventError("%scalias can only be used in-channel"
% event["command_prefix"])
target = event["target"]
subcommand = event["args_split"][0].lower()
if subcommand == "list":
aliases = self._get_aliases([target])
event["stdout"].write("Available aliases: %s" %
", ".join(sorted(aliases.keys())))
elif subcommand == "show":
if not len(event["args_split"]) > 1:
raise utils.EventError("Please provide an alias to remove")
alias = event["args_split"][0].lower()
setting = target.get_setting("%s%s" % (SETTING_PREFIX, alias), None)
if setting == None:
raise utils.EventError("I don't have an '%s' alias" % alias)
prefix = event["command_prefix"]
event["stdout"].write(f"{prefix}{alias}: {prefix}{setting}")
elif subcommand == "add":
if not len(event["args_split"]) > 2:
raise utils.EventError("Please provide an alias and a command")
alias = event["args_split"][1].lower()
command = event["args_split"][2].lower()
command = " ".join([command]+event["args_split"][3:])
target.set_setting("%s%s" % (SETTING_PREFIX, alias), command)
event["stdout"].write("Added '%s' alias" % alias)
elif subcommand == "remove":
if not len(event["args_split"]) > 1:
raise utils.EventError("Please provide an alias to remove")
alias = event["args_split"][1].lower()
setting = "%s%s" % (SETTING_PREFIX, alias)
if target.get_setting(setting, None) == None:
raise utils.EventError("I don't have an '%s' alias" % alias)
target.del_setting(setting)
event["stdout"].write("Removed '%s' alias" % alias)

View file

@ -8,8 +8,6 @@ from . import outs
COMMAND_METHOD = "command-method" COMMAND_METHOD = "command-method"
COMMAND_METHODS = ["PRIVMSG", "NOTICE"] COMMAND_METHODS = ["PRIVMSG", "NOTICE"]
REGEX_ARG_NUMBER = re.compile(r"\$(?:(\d+)(-?)|(-))")
MESSAGE_TAGS_CAP = utils.irc.Capability("message-tags", MESSAGE_TAGS_CAP = utils.irc.Capability("message-tags",
"draft/message-tags-0.2") "draft/message-tags-0.2")
MSGID_TAG = utils.irc.MessageTag("msgid", "draft/msgid") MSGID_TAG = utils.irc.MessageTag("msgid", "draft/msgid")
@ -21,6 +19,11 @@ class BadContextException(Exception):
self.required_context = required_context self.required_context = required_context
Exception.__init__(self) Exception.__init__(self)
class CommandEvent(object):
def __init__(self, command, args):
self.command = command
self.args = args
SETTING_COMMANDMETHOD = utils.OptionsSetting(COMMAND_METHODS, COMMAND_METHOD, SETTING_COMMANDMETHOD = utils.OptionsSetting(COMMAND_METHODS, COMMAND_METHOD,
"Set the method used to respond to commands") "Set the method used to respond to commands")
@ -59,44 +62,19 @@ class Module(ModuleManager.BaseModule):
if s and s[-1] in [":", ","]: if s and s[-1] in [":", ","]:
return server.is_own_nickname(s[:-1]) return server.is_own_nickname(s[:-1])
def _get_aliases(self, server):
return server.get_setting("command-aliases", {})
def _set_aliases(self, server, aliases):
server.set_setting("command-aliases", aliases)
def _alias_arg_replace(self, s, args_split):
for match in REGEX_ARG_NUMBER.finditer(s):
if match.group(1):
index = int(match.group(1))
continuous = match.group(2) == "-"
if index >= len(args_split):
raise IndexError("Unknown alias arg index")
else:
index = 0
continuous = True
if continuous:
replace = " ".join(args_split[index:])
else:
replace = args_split[index]
s = s.replace(match.group(0), replace)
return s
def _command_method(self, target, server): def _command_method(self, target, server):
return target.get_setting(COMMAND_METHOD, return target.get_setting(COMMAND_METHOD,
server.get_setting(COMMAND_METHOD, server.get_setting(COMMAND_METHOD,
self.bot.get_setting(COMMAND_METHOD, "PRIVMSG"))) self.bot.get_setting(COMMAND_METHOD, "PRIVMSG")))
def _find_command_hook(self, server, command, is_channel, args): def _find_command_hook(self, server, target, is_channel, command, args):
if not self.has_command(command): if not self.has_command(command):
aliases = self._get_aliases(server) command_event = CommandEvent(command, args)
if command.lower() in aliases: self.events.on("get.command").call(command=command_event,
command, _, new_args = aliases[command.lower()].partition(" ") server=server, target=target, is_channel=is_channel)
try: command = command_event.command
args = self._alias_arg_replace(new_args, shlex.split(args)) args = command_event.args
except IndexError:
return None, None, None
hook = None hook = None
args_split = [] args_split = []
@ -300,7 +278,7 @@ class Module(ModuleManager.BaseModule):
if command: if command:
try: try:
hook, command, args_split = self._find_command_hook( hook, command, args_split = self._find_command_hook(
event["server"], command, True, args) event["server"], event["channel"], True, command, args)
except BadContextException: except BadContextException:
event["channel"].send_message( event["channel"].send_message(
"%s: That command is not valid in a channel" % "%s: That command is not valid in a channel" %
@ -359,7 +337,7 @@ class Module(ModuleManager.BaseModule):
try: try:
hook, command, args_split = self._find_command_hook( hook, command, args_split = self._find_command_hook(
event["server"], command, False, args) event["server"], event["user"], False, command, args)
except BadContextException: except BadContextException:
event["user"].send_message( event["user"].send_message(
"That command is not valid in a PM") "That command is not valid in a PM")
@ -424,37 +402,6 @@ class Module(ModuleManager.BaseModule):
if stderr.has_text(): if stderr.has_text():
event["target"].last_stderr = stderr event["target"].last_stderr = stderr
@utils.hook("received.command.alias", min_args=2)
def add_alias(self, event):
"""
:help: Add a command alias
:usage: <alias> <command> <args...>
:permission: command-alias
"""
alias = event["args_split"][0].lower()
command = " ".join(event["args_split"][1:])
aliases = self._get_aliases(event["server"])
aliases[alias] = command
self._set_aliases(event["server"], aliases)
event["stdout"].write("Added '%s' alias" % alias)
@utils.hook("received.command.removealias", min_args=1)
def remove_alias(self, event):
"""
:help: Remove a command alias
:usage: <alias>
:permission: command-alias
"""
alias = event["args_split"][0].lower()
aliases = self._get_aliases(event["server"])
if not alias in aliases:
raise utils.EventError("No '%s' alias" % alias)
del aliases[alias]
self._set_aliases(event["server"], aliases)
event["stdout"].write("Removed '%s' alias" % alias)
@utils.hook("check.command.self") @utils.hook("check.command.self")
def check_command_self(self, event): def check_command_self(self, event):
if event["server"].irc_lower(event["request_args"][0] if event["server"].irc_lower(event["request_args"][0]