From 961fa72d1973c6e0d3904e48ac0c145840966cb1 Mon Sep 17 00:00:00 2001 From: Kae Bartlett Date: Wed, 5 Jul 2023 03:50:08 +0100 Subject: [PATCH] Add console commands for when the bot is running --- novus/ext/client/cli/__main__.py | 43 ++++++++++++++++++++++++++++++-- pyproject.toml | 1 + requirements.txt | 1 + 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/novus/ext/client/cli/__main__.py b/novus/ext/client/cli/__main__.py index 4672d201..b585ff48 100644 --- a/novus/ext/client/cli/__main__.py +++ b/novus/ext/client/cli/__main__.py @@ -18,11 +18,14 @@ from __future__ import annotations import asyncio +import functools import logging import sys import textwrap from argparse import ArgumentParser, Namespace +from aioconsole import AsynchronousCli + import novus from novus.api._cache import NothingAPICache from novus.ext import client @@ -129,6 +132,36 @@ def get_parser() -> ArgumentParser: return p +def create_console(bot: client.Client) -> AsynchronousCli: + """ + Create a console that users are able to interact with while the bot is + running. + """ + + add_plugin = ArgumentParser() + add_plugin.add_argument("plugin") + remove_plugin = ArgumentParser() + remove_plugin.add_argument("plugin") + reload_plugin = ArgumentParser() + reload_plugin.add_argument("plugin") + + async def close(): + await bot.close() + exit(1) + + add = functools.partial(bot.add_plugin, load=True) + + def reload(p): + bot.remove_plugin_file(p) + bot.add_plugin(p) + + return AsynchronousCli({ + "add-plugin": (add, add_plugin,), + "reload-plugin": (reload, remove_plugin,), + "remove-plugin": (bot.remove_plugin, remove_plugin,), + "exit": (close, ArgumentParser(),), + }) + async def main(args: Namespace, unknown: list[str]) -> None: """ Main input point for our CLI. @@ -143,7 +176,10 @@ async def main(args: Namespace, unknown: list[str]) -> None: root.setLevel(level) config.merge_namespace(args, unknown) bot = client.Client(config) - await bot.run(sync=not args.no_sync) + await asyncio.gather( + bot.run(sync=not args.no_sync), + create_console(bot).interact(banner="Created console :)"), + ) case "run-webserver": config = client.Config.from_file(args.config) @@ -153,7 +189,10 @@ async def main(args: Namespace, unknown: list[str]) -> None: root.setLevel(level) config.merge_namespace(args, unknown) bot = client.Client(config) - await bot.run_webserver(sync=not args.no_sync, port=args.port) + await asyncio.gather( + bot.run_webserver(sync=not args.no_sync, port=args.port), + create_console(bot).interact(banner="Created console :)"), + ) case "run-status": config = client.Config.from_file(args.config) diff --git a/pyproject.toml b/pyproject.toml index d77c0d39..22598088 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,6 +29,7 @@ dependencies = [ "aiohttp>=3.8.0", "emoji", "typing_extensions", + "aioconsole", ] scripts.novus = "novus.ext.client.cli.__main__:main_sync" diff --git a/requirements.txt b/requirements.txt index 1da3b5ee..e3be1370 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,6 +4,7 @@ aiohttp>=3.8.0 emoji typing_extensions pynacl +aioconsole # Recommended python-dotenv