as_plugin.py 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. import logging
  2. import inspect
  3. from ...messaging import RollbotResponse, RollbotFailure, RollbotFailureException
  4. from ..base import RollbotPlugin
  5. def get_converters(parameters, annotations):
  6. converters = []
  7. for p in parameters:
  8. annot = annotations.get(p, None)
  9. if isinstance(annot, ArgConverter):
  10. converters.append(annot.conv)
  11. elif p in ("msg", "message", "_msg"):
  12. converters.append(Message.conv)
  13. elif p in ("db", "database"):
  14. converters.append(Database.conv)
  15. elif p in ("log", "logger"):
  16. converters.append(Logger.conv)
  17. elif p in ("bot", "rollbot"):
  18. converters.append(Bot.conv)
  19. elif p in ("args", "arg_list"):
  20. converters.append(ArgList.conv)
  21. elif p in ("subc", "subcommand"):
  22. converters.append(Subcommand.conv)
  23. elif p in ("cfg", "config"):
  24. converters.append(Config())
  25. elif p.startswith("cfg") or p.endswith("cfg"):
  26. converters.append(Config(annot or p).conv)
  27. elif p.startswith("data") or p.endswith("data"):
  28. converters.append(Singleton(annot).conv)
  29. else:
  30. raise ValueError(p)
  31. return converters
  32. def as_plugin(command):
  33. if isinstance(command, str):
  34. command_name = command
  35. else:
  36. command_name = command.__name__
  37. def init_standin(self, bot, logger=logging.getLogger(__name__)):
  38. RollbotPlugin.__init__(self, command_name, bot, logger=logger)
  39. def decorator(fn):
  40. sig = inspect.signature(fn)
  41. try:
  42. converters = get_converters(sig.parameters, fn.__annotations__)
  43. except ValueError as ve:
  44. raise ValueError(f"Illegal argument name {str(ve)} in decorated plugin {command_name}")
  45. def on_command_standin(self, db, msg):
  46. try:
  47. res = fn(*[c(self, db, msg) for c in converters])
  48. except RollbotFailureException as rfe:
  49. res = rfe.failure
  50. if res is None:
  51. return RollbotResponse(msg, respond=False)
  52. elif isinstance(res, RollbotResponse):
  53. return res
  54. elif isinstance(res, RollbotFailure):
  55. return RollbotResponse(msg, failure=res, debugging=res.get_debugging())
  56. else:
  57. return RollbotResponse(msg, txt=str(res))
  58. return type(
  59. f"AutoGenerated`{command_name}`Command",
  60. (RollbotPlugin,),
  61. dict(
  62. __init__=init_standin,
  63. on_command=on_command_standin,
  64. )
  65. )
  66. if isinstance(command, str):
  67. return decorator
  68. else:
  69. return decorator(command)