From b949fb0b6c9c4e2e1598984dc65e8bfa43a7695e Mon Sep 17 00:00:00 2001 From: Griatch Date: Sun, 4 Jul 2021 21:54:27 +0200 Subject: [PATCH] Custom evennia launcher commands with EXTRA_LAUNCHER_COMMANDS setting --- evennia/server/evennia_launcher.py | 49 ++++++++++++++++++++++++++++++ evennia/settings_default.py | 5 +++ 2 files changed, 54 insertions(+) diff --git a/evennia/server/evennia_launcher.py b/evennia/server/evennia_launcher.py index 03c4f830d3..cfd40a5955 100644 --- a/evennia/server/evennia_launcher.py +++ b/evennia/server/evennia_launcher.py @@ -1913,6 +1913,51 @@ def list_settings(keys): print(table) +def run_custom_commands(option, *args): + """ + Inject a custom option into the evennia launcher command chain. + + Args: + option (str): Incoming option - the first argument after `evennia` on + the command line. + *args: All args will passed to a found callable.__dict__ + + Returns: + bool: If a custom command was found and handled the option. + + Notes: + Provide new commands in settings with + + CUSTOM_EVENNIA_LAUNCHER_COMMANDS = {"mycmd": "path.to.callable", ...} + + The callable will be passed any `*args` given on the command line and is expected to + handle/validate the input correctly. Use like any other evennia command option on + in the terminal/console, for example: + + evennia mycmd foo bar + + """ + from django.conf import settings + import importlib + + try: + # a dict of {option: callable(*args), ...} + custom_commands = settings.EXTRA_LAUNCHER_COMMANDS + except AttributeError: + return False + cmdpath = custom_commands.get(option) + if cmdpath: + modpath, *cmdname = cmdpath.rsplit('.', 1) + if cmdname: + cmdname = cmdname[0] + mod = importlib.import_module(modpath) + command = mod.__dict__.get(cmdname) + if command: + command(*args) + return True + return False + + def run_menu(): """ This launches an interactive menu. @@ -2286,6 +2331,10 @@ def main(): django.core.management.call_command(*([option] + unknown_args)) sys.exit(0) + if run_custom_commands(option, *unknown_args): + # run any custom commands + sys.exit() + # pass on to the core django manager - re-parse the entire input line # but keep 'evennia' as the name instead of django-admin. This is # an exit condition. diff --git a/evennia/settings_default.py b/evennia/settings_default.py index bc510bbddb..bde49cf1b0 100644 --- a/evennia/settings_default.py +++ b/evennia/settings_default.py @@ -225,6 +225,11 @@ MAX_CONNECTION_RATE = 2 MAX_COMMAND_RATE = 80 # The warning to echo back to users if they send commands too fast COMMAND_RATE_WARNING = "You entered commands too fast. Wait a moment and try again." +# custom, extra commands to add to the `evennia` launcher. This is a dict +# of {'cmdname': 'path.to.callable', ...}, where the callable will be passed +# any extra args given on the command line. For example `evennia cmdname foo bar`. +CUSTOM_LAUNCHER_COMMANDS = {} + # Determine how large of a string can be sent to the server in number # of characters. If they attempt to enter a string over this character # limit, we stop them and send a message. To make unlimited, set to