plugins.py 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. import logging
  2. import inspect
  3. from .messaging import RollbotResponse
  4. class RollbotPlugin:
  5. def __init__(self, command, bot, logger=logging.getLogger(__name__)):
  6. self.command = command
  7. self.bot = bot
  8. self.logger = logger
  9. self.logger.info(f"Intializing {type(self).__name__} matching {command}")
  10. def on_start(self, db):
  11. self.logger.info(f"No on_start initialization of {type(self).__name__}")
  12. def on_shutdown(self, db):
  13. self.logger.info(f"No on_shutdown de-initialization of {type(self).__name__}")
  14. def on_command(self, db, message):
  15. raise NotImplementedError
  16. def as_plugin(command):
  17. if isinstance(command, str):
  18. command_name = command
  19. else:
  20. command_name = command.__name__
  21. def init_standin(self, bot, logger=logging.getLogger(__name__)):
  22. RollbotPlugin.__init__(self, command_name, bot, logger=logger)
  23. def decorator(fn):
  24. sig = inspect.signature(fn)
  25. converters = []
  26. for p in sig.parameters:
  27. if p in ("msg", "message", "_msg"):
  28. converters.append(lambda cmd, db, msg: msg)
  29. elif p in ("db", "database"):
  30. converters.append(lambda cmd, db, msg: db)
  31. elif p in ("log", "logger"):
  32. converters.append(lambda cmd, db, msg: cmd.logger)
  33. elif p in ("bot", "rollbot"):
  34. converters.append(lambda cmd, db, msg: cmd.bot)
  35. elif p.startswith("data") or p.endswith("data") or p in ("group_singleton", "singleton"):
  36. annot = fn.__annotations__.get(p, p)
  37. converters.append(lambda cmd, db, msg, sing_cls=annot: sing_cls.get_or_create(db, msg.group_id))
  38. else:
  39. raise ValueError(f"Illegal argument name {p} in decorated plugin {command_name}")
  40. def on_command_standin(self, db, msg):
  41. res = fn(*[c(self, db, msg) for c in converters])
  42. if isinstance(res, RollbotResponse):
  43. return res
  44. else:
  45. return RollbotResponse(msg, txt=str(res))
  46. return type(
  47. f"AutoGenerated`{command_name}`Command",
  48. (RollbotPlugin,),
  49. dict(
  50. __init__=init_standin,
  51. on_command=on_command_standin,
  52. )
  53. )
  54. if isinstance(command, str):
  55. return decorator
  56. else:
  57. return decorator(command)