import logging import inspect from ...messaging import RollbotResponse, RollbotFailure, RollbotFailureException from ..base import RollbotPlugin def get_converters(parameters, annotations): converters = [] for p in parameters: annot = annotations.get(p, None) if isinstance(annot, ArgConverter): converters.append(annot.conv) elif p in ("msg", "message", "_msg"): converters.append(Message.conv) elif p in ("db", "database"): converters.append(Database.conv) elif p in ("log", "logger"): converters.append(Logger.conv) elif p in ("bot", "rollbot"): converters.append(Bot.conv) elif p in ("args", "arg_list"): converters.append(ArgList.conv) elif p in ("subc", "subcommand"): converters.append(Subcommand.conv) elif p in ("cfg", "config"): converters.append(Config()) elif p.startswith("cfg") or p.endswith("cfg"): converters.append(Config(annot or p).conv) elif p.startswith("data") or p.endswith("data"): converters.append(Singleton(annot).conv) else: raise ValueError(p) return converters def as_plugin(command): if isinstance(command, str): command_name = command else: command_name = command.__name__ def init_standin(self, bot, logger=logging.getLogger(__name__)): RollbotPlugin.__init__(self, command_name, bot, logger=logger) def decorator(fn): sig = inspect.signature(fn) try: converters = get_converters(sig.parameters, fn.__annotations__) except ValueError as ve: raise ValueError(f"Illegal argument name {str(ve)} in decorated plugin {command_name}") def on_command_standin(self, db, msg): try: res = fn(*[c(self, db, msg) for c in converters]) except RollbotFailureException as rfe: res = rfe.failure if res is None: return RollbotResponse(msg, respond=False) elif isinstance(res, RollbotResponse): return res elif isinstance(res, RollbotFailure): return RollbotResponse(msg, failure=res, debugging=res.get_debugging()) else: return RollbotResponse(msg, txt=str(res)) return type( f"AutoGenerated`{command_name}`Command", (RollbotPlugin,), dict( __init__=init_standin, on_command=on_command_standin, ) ) if isinstance(command, str): return decorator else: return decorator(command)