From eb8e5aa39dca6a3c50c613b4d44a245c03889397 Mon Sep 17 00:00:00 2001 From: yanyongyu Date: Wed, 24 Feb 2021 17:48:08 +0800 Subject: [PATCH] :wheelchair: add plugin loading using json/toml --- nonebot/__init__.py | 3 +++ nonebot/drivers/__init__.py | 2 ++ nonebot/plugin/__init__.py | 29 ++++++++++++++++++++++++++++- nonebot/plugin/__init__.pyi | 8 ++++++++ poetry.lock | 19 ++++++++++++++++++- pyproject.toml | 1 + tests/bot.py | 5 ++--- tests/plugins.toml | 3 +++ 8 files changed, 65 insertions(+), 5 deletions(-) create mode 100644 tests/plugins.toml diff --git a/nonebot/__init__.py b/nonebot/__init__.py index 9c65b5a0..aaf5ca77 100644 --- a/nonebot/__init__.py +++ b/nonebot/__init__.py @@ -19,6 +19,8 @@ - ``load_plugin`` => ``nonebot.plugin.load_plugin`` - ``load_plugins`` => ``nonebot.plugin.load_plugins`` - ``load_all_plugins`` => ``nonebot.plugin.load_all_plugins`` +- ``load_from_json`` => ``nonebot.plugin.load_from_json`` +- ``load_from_toml`` => ``nonebot.plugin.load_from_toml`` - ``load_builtin_plugins`` => ``nonebot.plugin.load_builtin_plugins`` - ``get_plugin`` => ``nonebot.plugin.get_plugin`` - ``get_loaded_plugins`` => ``nonebot.plugin.get_loaded_plugins`` @@ -228,4 +230,5 @@ def run(host: Optional[str] = None, from nonebot.plugin import on_message, on_notice, on_request, on_metaevent, CommandGroup, MatcherGroup from nonebot.plugin import on_startswith, on_endswith, on_keyword, on_command, on_shell_command, on_regex from nonebot.plugin import load_plugin, load_plugins, load_all_plugins, load_builtin_plugins +from nonebot.plugin import load_from_json, load_from_toml from nonebot.plugin import export, require, get_plugin, get_loaded_plugins diff --git a/nonebot/drivers/__init__.py b/nonebot/drivers/__init__.py index 134b2078..fd435704 100644 --- a/nonebot/drivers/__init__.py +++ b/nonebot/drivers/__init__.py @@ -73,6 +73,8 @@ class Driver(abc.ABC): * ``name: str``: 适配器名称,用于在连接时进行识别 * ``adapter: Type[Bot]``: 适配器 Class """ + if name in self._adapters: + print("============", name) self._adapters[name] = adapter adapter.register(self, self.config, **kwargs) logger.opt( diff --git a/nonebot/plugin/__init__.py b/nonebot/plugin/__init__.py index 38269e4c..be96ecfd 100644 --- a/nonebot/plugin/__init__.py +++ b/nonebot/plugin/__init__.py @@ -5,12 +5,13 @@ 为 NoneBot 插件开发提供便携的定义函数。 """ import re +import json from types import ModuleType from dataclasses import dataclass -from importlib._bootstrap import _load from contextvars import Context, ContextVar, copy_context from typing import Any, Set, List, Dict, Type, Tuple, Union, Optional, TYPE_CHECKING +import tomlkit from nonebot.log import logger from nonebot.matcher import Matcher from nonebot.permission import Permission @@ -1069,6 +1070,32 @@ def load_all_plugins(module_path: Set[str], return loaded_plugins +def load_from_json(file_path: str, encoding: str = "utf-8") -> Set[Plugin]: + with open(file_path, "r", encoding=encoding) as f: + data = json.load(f) + plugins = data.get("plugins") + plugin_dirs = data.get("plugin_dirs") + assert isinstance(plugins, list), "plugins must be a list of plugin name" + assert isinstance(plugin_dirs, + list), "plugin_dirs must be a list of directories" + return load_all_plugins(set(plugins), set(plugin_dirs)) + + +def load_from_toml(file_path: str, encoding: str = "utf-8") -> Set[Plugin]: + with open(file_path, "r", encoding=encoding) as f: + data = tomlkit.parse(f.read()) + + nonebot_data = data.get("nonebot", {}).get("plugins") + if not nonebot_data: + raise ValueError("Cannot find '[nonebot.plugins]' in given toml file!") + plugins = nonebot_data.get("plugins", []) + plugin_dirs = nonebot_data.get("plugin_dirs", []) + assert isinstance(plugins, list), "plugins must be a list of plugin name" + assert isinstance(plugin_dirs, + list), "plugin_dirs must be a list of directories" + return load_all_plugins(set(plugins), set(plugin_dirs)) + + def load_builtin_plugins(name: str = "echo") -> Optional[Plugin]: """ :说明: diff --git a/nonebot/plugin/__init__.pyi b/nonebot/plugin/__init__.pyi index 9549d45e..02cc6b96 100644 --- a/nonebot/plugin/__init__.pyi +++ b/nonebot/plugin/__init__.pyi @@ -181,6 +181,14 @@ def load_all_plugins(module_path: Set[str], ... +def load_from_json(file_path: str, encoding: str = ...) -> Set[Plugin]: + ... + + +def load_from_toml(file_path: str, encoding: str = ...) -> Set[Plugin]: + ... + + def load_builtin_plugins(name: str = ...): ... diff --git a/poetry.lock b/poetry.lock index 72dfa941..1b3c0b95 100644 --- a/poetry.lock +++ b/poetry.lock @@ -857,6 +857,19 @@ type = "legacy" url = "https://mirrors.aliyun.com/pypi/simple" reference = "aliyun" +[[package]] +name = "tomlkit" +version = "0.7.0" +description = "Style preserving TOML library" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[package.source] +type = "legacy" +url = "https://mirrors.aliyun.com/pypi/simple" +reference = "aliyun" + [[package]] name = "typing-extensions" version = "3.7.4.3" @@ -1040,7 +1053,7 @@ quart = ["Quart"] [metadata] lock-version = "1.1" python-versions = "^3.7.3" -content-hash = "5ed7961113ab7fb77bae986bb67280715f852822bb25f51725dcb5382bdfd08c" +content-hash = "472f4191d75922660770d7a4f8669a5dbde12586970daebf188b23cf605dec0d" [metadata.files] aiofiles = [ @@ -1317,6 +1330,10 @@ toml = [ {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, ] +tomlkit = [ + {file = "tomlkit-0.7.0-py2.py3-none-any.whl", hash = "sha256:6babbd33b17d5c9691896b0e68159215a9387ebfa938aa3ac42f4a4beeb2b831"}, + {file = "tomlkit-0.7.0.tar.gz", hash = "sha256:ac57f29693fab3e309ea789252fcce3061e19110085aa31af5446ca749325618"}, +] typing-extensions = [ {file = "typing_extensions-3.7.4.3-py2-none-any.whl", hash = "sha256:dafc7639cde7f1b6e1acc0f457842a83e722ccca8eef5270af2d74792619a89f"}, {file = "typing_extensions-3.7.4.3-py3-none-any.whl", hash = "sha256:7cb407020f00f7bfc3cb3e7881628838e69d8f3fcab2f64742a5e76b2f841918"}, diff --git a/pyproject.toml b/pyproject.toml index 7db8f57f..8fc0c490 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,6 +30,7 @@ fastapi = "^0.63.0" uvicorn = "^0.11.5" Quart = { version = "^0.14.1", optional = true } pydantic = { extras = ["dotenv", "typing_extensions"], version = "^1.7.3" } +tomlkit = "^0.7.0" [tool.poetry.dev-dependencies] yapf = "^0.30.0" diff --git a/tests/bot.py b/tests/bot.py index e4ec39e4..f60c1878 100644 --- a/tests/bot.py +++ b/tests/bot.py @@ -27,8 +27,7 @@ driver.register_adapter("mirai", MiraiBot) nonebot.load_builtin_plugins() # load all plugins -nonebot.load_all_plugins({"nonebot_plugin_apscheduler", "nonebot_plugin_test"}, - {"test_plugins"}) +nonebot.load_from_toml("plugins.toml") # modify some config / config depends on loaded configs config = driver.config @@ -36,4 +35,4 @@ config.custom_config3 = config.custom_config1 config.custom_config4 = "New custom config" if __name__ == "__main__": - nonebot.run(app="bot:app") + nonebot.run(app="__mp_main__:app") diff --git a/tests/plugins.toml b/tests/plugins.toml new file mode 100644 index 00000000..85eefe30 --- /dev/null +++ b/tests/plugins.toml @@ -0,0 +1,3 @@ +[nonebot.plugins] +plugins = ["nonebot_plugin_test"] +plugin_dirs = ["test_plugins"]