Browse Source

Merge branch 'subcommand-injection' of kirkleon/rollbot3 into master

kirkleon 5 years ago
parent
commit
6f5ecdba15
5 changed files with 34 additions and 22 deletions
  1. 17 1
      lib/rollbot/messaging.py
  2. 3 1
      lib/rollbot/plugins.py
  3. 7 13
      src/plugins/curse.py
  4. 1 1
      src/plugins/finchat.py
  5. 6 6
      src/plugins/watchlist.py

+ 17 - 1
lib/rollbot/messaging.py

@@ -26,13 +26,29 @@ class RollbotMessage:
 
     def __post_init__(self):
         self.is_command = False
-        if len(self.message_txt) > 0 and self.message_txt[0] in BANGS:
+        if self.message_txt is not None and len(self.message_txt) > 0 and self.message_txt[0] in BANGS:
             cmd, raw = pop_arg(self.message_txt[1:].strip())
             if cmd is not None:
                 self.is_command = True
+                self.raw_command = cmd
                 self.command = cmd.lower()
                 self.raw_args = raw
 
+    @staticmethod
+    def from_subcommand(msg):
+        subc = RollbotMessage(
+            msg.src,
+            msg.name,
+            msg.sender_id,
+            msg.group_id,
+            msg.message_id,
+            msg.raw_args, # this strips the command of the old message
+            msg.from_admin
+        )
+        if subc.is_command:
+            return subc
+        # silently return None if a subcommand could not be made
+
     @staticmethod
     def from_groupme(msg, global_admins=(), group_admins={}):
         sender_id = msg["sender_id"]

+ 3 - 1
lib/rollbot/plugins.py

@@ -2,7 +2,7 @@ import logging
 import inspect
 from functools import reduce
 
-from .messaging import RollbotResponse
+from .messaging import RollbotResponse, RollbotMessage
 
 
 class RollbotPlugin:
@@ -50,6 +50,8 @@ def as_plugin(command):
                 converters.append(lambda cmd, db, msg: cmd.logger)
             elif p in ("bot", "rollbot"):
                 converters.append(lambda cmd, db, msg: cmd.bot)
+            elif p in ("subc", "subcommand"):
+                converters.append(lambda cmd, db, msg: RollbotMessage.from_subcommand(msg))
             elif p.startswith("data") or p.endswith("data") or p in ("group_singleton", "singleton"):
                 annot = fn.__annotations__.get(p, p)
                 converters.append(lambda cmd, db, msg, sing_cls=annot: sing_cls.get_or_create(db, msg.group_id))

+ 7 - 13
src/plugins/curse.py

@@ -106,10 +106,11 @@ BAN_LIST = get_secret("curse.banlist")
 
 
 @as_plugin
-def curse(db, msg):
-    # TODO might be nice to add subcommands to this later
-    name, args = pop_arg(msg.raw_args)
-    if not name.startswith("!"):
+def curse(db, msg, subc):
+    if subc is None:
+        name, _ = pop_arg(msg.raw_args)
+        if name is None:
+            return "Sorry - you need to provide the name of someone to curse!"
         person_id = name.strip().lower()
         if is_banned(msg, person_id):
             if msg.sender_id in get_secret("curse.nolist"):
@@ -120,14 +121,7 @@ def curse(db, msg):
         score.curses = score.curses + 1
         return get_response(msg, name, score)
 
-    # strip off the '!'
-    subc = name[1:].strip()
-    if len(subc) == 0:
-        # handle the case of spaces between ! and subcommand
-        subc, args = pop_arg(args)
-    subc = subc.lower()
-
-    return SUBC_MAP.get(subc, lambda *a: RollbotResponse(msg, failure=RollbotFailure.INVALID_SUBCOMMAND))(db, msg, args)
+    return SUBC_MAP.get(subc.command, lambda *_: RollbotResponse(msg, failure=RollbotFailure.INVALID_SUBCOMMAND))(db, msg, subc.raw_args)
 
 
 class Bless(RollbotPlugin):
@@ -140,7 +134,7 @@ class Bless(RollbotPlugin):
     def on_command(self, db, msg):
         name, _ = pop_arg(msg.raw_args)
         if name.startswith("!"):
-            return "Sorry! Subcommands have to go on !curse for now - this will be fixed in the future!"
+            return RollbotResponse(msg, txt="Sorry! Subcommands have to go on !curse for now - this will be fixed in the future!")
         person_id = name.strip().lower()
         if is_banned(msg, person_id):
             self.bot.manually_post_message("Hey! You aren't allowed to affect that person's score! And cheaters never propser!", msg.group_id)

+ 1 - 1
src/plugins/finchat.py

@@ -21,4 +21,4 @@ FFFFFFF
 
 @as_plugin("f")
 def finchat(msg):
-    return "frick!" if msg.message_txt[1:].strip().startswith("f") else Fs
+    return "frick!" if msg.raw_command == "f" else Fs

+ 6 - 6
src/plugins/watchlist.py

@@ -79,12 +79,12 @@ subcommands = {
 
 
 @as_plugin
-def watchlist(msg, data: Watchlist):
-    if msg.raw_args is not None and msg.raw_args.startswith("!"):
-        subc, args = pop_arg(msg.raw_args)
-        subc = subc[1:].lower()
-        subc_fn = subcommands.get(subc, lambda *_: f"Sorry, subcommand must be one of {', '.join(subcommands)}, you used: {subc}")
-        return subc_fn(args, data)
+def watchlist(subc, data: Watchlist):
+    if subc:
+        subc_fn = subcommands.get(subc.command, None)
+        if subc_fn:
+            return subc_fn(subc.raw_args, data)
+        return f"Sorry, subcommand must be one of {', '.join(subcommands)}, you used: {subc.command}"
     return subcommands["help"]() # default to help message
 
 # some quick aliases for convenience, !wl is aliased in the config file instead