Browse Source

Implement subcommand arg extraction injection, subcommand memoing, and expose an Injector for calling functions

Kirk Trombley 4 years ago
parent
commit
dc2150ca6a
2 changed files with 42 additions and 15 deletions
  1. 18 15
      lib/rollbot/messaging.py
  2. 24 0
      lib/rollbot/plugins/injection.py

+ 18 - 15
lib/rollbot/messaging.py

@@ -67,6 +67,7 @@ class RollbotMessage:
 
     def __post_init__(self):
         self.is_command = False
+        self._subc_memo = None
         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:
@@ -74,21 +75,23 @@ class RollbotMessage:
                 self.raw_command = cmd
                 self.command = cmd.lower()
                 self.raw_args = raw
-                self._arg_list_thunk = None
+                self._arg_list_memo = None
+                
 
     @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
+        if msg._subc_memo is None:
+            msg._subc_memo = 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 msg._subc_memo.is_command:
+            return msg._subc_memo
         # silently return None if a subcommand could not be made
 
     @staticmethod
@@ -151,9 +154,9 @@ class RollbotMessage:
         Behavior is undefined if this method is called on a message whose
         is_command field is false.
         """
-        if self._arg_list_thunk is None:
-            self._arg_list_thunk = self.raw_args.split()
-        return self._arg_list_thunk
+        if self._arg_list_memo is None:
+            self._arg_list_memo = self.raw_args.split()
+        return self._arg_list_memo
 
 
 class RollbotFailureException(BaseException):

+ 24 - 0
lib/rollbot/plugins/injection.py

@@ -12,8 +12,11 @@ Message = ArgConverter(lambda _, __, msg: msg)
 Database = ArgConverter(lambda _, db, __: db)
 Logger = ArgConverter(lambda cmd, _, __: cmd.logger)
 Bot = ArgConverter(lambda cmd, _, __: cmd.bot)
+ArgString = ArgConverter(lambda _, __, msg: msg.raw_args)
 ArgList = ArgConverter(lambda _, __, msg: msg.arg_list())
 Subcommand = ArgConverter(lambda _, __, msg: RollbotMessage.from_subcommand(msg))
+Subcommand.ArgString = ArgConverter(lambda _, __, msg: RollbotMessage.from_subcommand(msg).raw_args)
+Subcommand.ArgList = ArgConverter(lambda _, __, msg: RollbotMessage.from_subcommand(msg).arg_list())
 
 
 class Arg(ArgConverter):
@@ -34,6 +37,14 @@ class Arg(ArgConverter):
             RollbotFailure.INVALID_ARGUMENTS.with_reason(self.fail_msg.format(arg)).raise_exc()
 
 
+class _SubcArg(Arg):
+    def _convert(self, cmd, db, msg):
+        return super()._convert(self, cmd, db, RollbotMessage.from_subcommand(msg))
+
+
+Subcommand.Arg = _SubcArg
+
+
 class Config(ArgConverter):
     def __init__(self, key=None):
         if key is None:
@@ -97,3 +108,16 @@ class Lazy(ArgConverter):
         if not self.run:
             self.result = self.child.conv(self.cmd, self.db, self.msg)
         return self.result
+
+
+class _Executor:
+    def __init__(self, cmd, db, msg):
+        self.cmd = cmd
+        self.db = db
+        self.msg = msg
+
+    def run_with_deps(self, fn):
+        return _run_converter_function(fn, cmd, db, msg)
+        
+
+Injector = ArgConverter(_Executor)