aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar jesopo2020-01-24 16:25:50 +0000
committerGravatar jesopo2020-01-24 16:25:50 +0000
commitf0d885354900ea72823cae6b0906668574e49d3b (patch)
tree4bc06134e12c46bdf61b4323e3348f96d9b4117e /src
parentdon't args[0] for rchannel when [], better rchannel error (diff)
signature
implement "important" command spec pieces, esp. for channel perms
Diffstat (limited to 'src')
-rw-r--r--src/core_modules/command_spec.py65
1 files changed, 48 insertions, 17 deletions
diff --git a/src/core_modules/command_spec.py b/src/core_modules/command_spec.py
index 9a3c7943..920ce036 100644
--- a/src/core_modules/command_spec.py
+++ b/src/core_modules/command_spec.py
@@ -1,20 +1,36 @@
-from src import ModuleManager, utils
+from src import EventManager, ModuleManager, utils
+
+# describing command arg specifications, to centralise parsing and validating.
+#
+# format: <!|?><name>
+# ! = required
+# ? = optional
+#
+# if "name" contains "~", it will be marked as an "important" spec
+# this means that, e.g. "!r~channel" will be:
+# - marked as important
+# - name split to everything after ~
+# - the name, and it's value, will be offered to other preprocessors.
+#
+# this means, in practice, that "!r~channel" is a:
+# - "revelant" channel (current if in channel, explicit arg otherwise)
+# - will be used to check if a user has permissions
class Module(ModuleManager.BaseModule):
- def _spec_chunk(self, server, channel, user, types, args):
+ def _spec_chunk(self, server, channel, user, spec_types, args):
options = []
first_error = None
- for type in types:
+ for spec_type in spec_types:
chunk = None
n = 0
error = None
- if type == "time" and args:
+ if spec_type == "time" and args:
time, _ = utils.parse.timed_args(args)
chunk = time
n = 1
error = "Invalid timeframe"
- elif type == "rchannel":
+ elif spec_type == "rchannel":
if channel:
chunk = channel
elif args:
@@ -24,39 +40,45 @@ class Module(ModuleManager.BaseModule):
error = "No such channel"
else:
error = "No channel provided"
- elif type == "channel" and args:
+ elif spec_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:
+ elif spec_type == "cuser" and args:
tuser = server.get_user(args[0], create=False)
if tuser and channel.has_user(tuser):
chunk = tuser
n = 1
error = "That user is not in this channel"
- elif type == "ruser":
+ elif spec_type == "ruser":
if args:
chunk = server.get_user(args[0], create=False)
n = 1
else:
chunk = user
error = "No such user"
- elif type == "user" and args:
+ elif spec_type == "user" and args:
chunk = server.get_user(args[0], create=False)
n = 1
error = "No such user"
- elif type == "word" and args:
+ elif spec_type == "ouser" and args:
+ if server.has_user_id(args[0]):
+ chunk = server.get_user(args[0])
+ n = 1
+ error = "Unknown nickname"
+ elif spec_type == "word" and args:
chunk = args[0]
n = 1
- elif type == "...":
+ elif spec_type == "...":
chunk = " ".join(args)
n = len(args)
- options.append([type, chunk, n, error])
+ options.append([chunk, n, error])
return options
@utils.hook("preprocess.command")
+ @utils.kwarg("priority", EventManager.PRIORITY_HIGH)
def preprocess(self, event):
spec = event["hook"].get_kwarg("spec", None)
if not spec == None:
@@ -67,22 +89,31 @@ class Module(ModuleManager.BaseModule):
out = []
for word in spec.split():
- types = word[1:].split("|")
optional = word[0] == "?"
+ word = word[1:]
+
+ raw_spec_types = word.split("|")
+ spec_types = [t.replace("~", "", 1) for t in raw_spec_types]
- options = self._spec_chunk(server, channel, user, types, args)
+ options = self._spec_chunk(server, channel, user, spec_types, args)
found = None
first_error = None
- for type, chunk, n, error in options:
+ for i, (chunk, n, error) in enumerate(options):
+ spec_type = spec_types[i]
+ raw_spec_type = raw_spec_types[i]
+
if error and not first_error:
first_error = error
if chunk:
+ if "~" in raw_spec_type:
+ event["kwargs"][raw_spec_type.split("~", 1)[1]] = chunk
+
found = True
args = args[n:]
- if len(types) > 1:
- chunk = [type, chunk]
+ if len(spec_types) > 1:
+ chunk = [spec_type, chunk]
found = chunk
break
out.append(found)