as_plugin.py 2.7 KB

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