diff --git a/src/core_modules/command_spec.py b/src/core_modules/command_spec.py new file mode 100644 index 00000000..fbf5aa7e --- /dev/null +++ b/src/core_modules/command_spec.py @@ -0,0 +1,73 @@ +from src import ModuleManager, utils + +class Module(ModuleManager.BaseModule): + def _spec_chunk(self, server, channel, types, args): + options = [] + first_error = None + for type in types: + chunk = None + n = 0 + error = None + + if type == "time" and args: + time, _ = utils.parse.timed_args(args) + chunk = time + n = 1 + error = "Invalid timeframe" + elif type == "channel" and args: + if args[0] in server.channels: + chunk = server.channels.get(args[0]) + n = 1 + error = "No such channel" + elif type == "cuser" and args: + user = server.get_user(args[0], create=False) + if user and channel.has_user(user): + chunk = user + n = 1 + error = "That user is not in this channel" + elif type == "user" and args: + chunk = server.get_user(args[0], create=False) + n = 1 + error = "No such user" + elif type == "word" and args: + chunk = args[0] + n = 1 + elif type == "...": + chunk = " ".join(args) + n = len(args) + + options.append([type, chunk, n, error]) + return options + + @utils.hook("preprocess.command") + def preprocess(self, event): + spec = event["hook"].get_kwarg("spec", None) + if not spec == None: + server = event["server"] + channel = event["target"] if event["is_channel"] else None + args = event["args_split"].copy() + + out = [] + for word in spec.split(): + types = word[1:].split("|") + optional = word[0] == "?" + + options = self._spec_chunk(server, channel, types, args) + + found = False + first_error = None + for type, chunk, n, error in options: + if error and not first_error: + first_error = error + + if chunk: + found = True + args = args[n:] + if len(types) > 1: + chunk = [type, chunk] + out.append(chunk) + + if not optional and not found: + error = first_error or "Invalid arguments" + return utils.consts.PERMISSION_HARD_FAIL, error + event["kwargs"]["spec"] = out diff --git a/src/core_modules/commands/__init__.py b/src/core_modules/commands/__init__.py index b22541d5..5a312bda 100644 --- a/src/core_modules/commands/__init__.py +++ b/src/core_modules/commands/__init__.py @@ -184,7 +184,8 @@ class Module(ModuleManager.BaseModule): "target": target, "target_str": target_str, "is_channel": is_channel, "line": line, "args_split": args_split, "command": command, "args": " ".join(args_split), "stdout": stdout, - "stderr": stderr, "tags": {}} + "stderr": stderr, "tags": {}, "kwargs": {}} + event_kwargs.update(kwargs) check_assert = lambda check: self._check_assert(event_kwargs, user, @@ -195,6 +196,7 @@ class Module(ModuleManager.BaseModule): check_success, check_message = self._check("preprocess", event_kwargs) if check_success: + event_kwargs.update(event_kwargs.pop("kwargs")) new_event = self.events.on(hook.event_name).make_event(**event_kwargs) self.log.trace("calling command '%s': %s", [command, new_event.kwargs])