Skip to content

Commit

Permalink
feat: 适配 NoneBot 2.0 正式版的插件元数据 (#60)
Browse files Browse the repository at this point in the history
* 通过 supported_adapters 判断是否是支持的适配器
* 通过 type 判断是否是支持的插件类型
  • Loading branch information
he0119 authored Jun 6, 2023
1 parent 3344409 commit 50d9345
Show file tree
Hide file tree
Showing 13 changed files with 512 additions and 419 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/lang/zh-CN/

## [Unreleased]

### Added

- 适配 NoneBot 2.0 正式版的插件元数据

## [0.1.0] - 2023-04-16

### Changed
Expand Down
2 changes: 2 additions & 0 deletions nonebot_plugin_treehelp/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
获取某个插件的树
/help --tree 插件名
""",
type="application",
homepage="https://github.com/he0119/nonebot-plugin-treehelp",
)

parser = ArgumentParser("帮助", description="获取插件帮助信息")
Expand Down
62 changes: 45 additions & 17 deletions nonebot_plugin_treehelp/data_source.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,49 @@ def format_description(plugins: List["Plugin"]) -> str:
)


def is_supported_adapter(bot: "Bot", plugin: "Plugin") -> bool:
def is_supported_adapter(bot: "Bot", metadata: "PluginMetadata") -> bool:
"""是否是支持的适配器"""
supported_adapters = plugin.metadata.extra.get("adapters") # type: ignore
if (
supported_adapters # 拥有 adapters 信息
and isinstance(supported_adapters, (set, list)) # 并且是集合或列表
and bot.adapter.get_name() not in supported_adapters # 且当前适配器名不在集合中
):
if metadata.supported_adapters is None:
return True

supported_adapters = metadata.get_supported_adapters()
if not supported_adapters:
return False

for adapter in supported_adapters:
if isinstance(bot.adapter, adapter):
return True

return False


def is_supported_type(metadata: "PluginMetadata") -> bool:
"""是否是支持的插件类型
当前有 library 和 application 两种类型
仅支持 application 类型的插件
"""
type_ = metadata.type
# 如果没有指定类型,则默认支持
if type_ is None:
return True
# 当前仅支持 application 类型
if type_ == "application":
return True
return False


def is_supported(bot: "Bot", plugin: "Plugin") -> bool:
"""是否是支持的插件"""
if plugin.metadata is None:
return False

if not is_supported_type(plugin.metadata):
return False

if not is_supported_adapter(bot, plugin.metadata):
return False

return True


Expand All @@ -80,7 +114,7 @@ def get_plugin_list(bot: "Bot", tree: bool = False) -> str:
plugins = [
plugin
for plugin in get_plugins().values()
if plugin.parent_plugin is None and is_supported_adapter(bot, plugin)
if plugin.parent_plugin is None and is_supported(bot, plugin)
]
sorted_plugins = sorted(plugins, key=lambda x: x.metadata.name) # type: ignore

Expand Down Expand Up @@ -110,7 +144,7 @@ def get_plugin_help(bot: "Bot", name: str, tree: bool = False) -> Optional[str]:
return

# 排除不支持的插件
if not is_supported_adapter(bot, plugin):
if not is_supported(bot, plugin):
return

metadata = cast("PluginMetadata", plugin.metadata)
Expand All @@ -120,11 +154,7 @@ def get_plugin_help(bot: "Bot", name: str, tree: bool = False) -> Optional[str]:
get_tree_string(bot, docs, plugin.sub_plugins, "")
return "\n".join(docs)

sub_plugins = [
plugin
for plugin in plugin.sub_plugins
if plugin.metadata is not None and is_supported_adapter(bot, plugin)
]
sub_plugins = [plugin for plugin in plugin.sub_plugins if is_supported(bot, plugin)]
sub_plugins_desc = format_description(sub_plugins)
return "\n\n".join(
[x for x in [metadata.name, metadata.usage, sub_plugins_desc] if x]
Expand All @@ -140,9 +170,7 @@ def get_tree_string(
"""通过递归获取树形结构的字符串"""
previous_tree_bar = previous_tree_bar.replace("├", "│")

filtered_plugins = filter(
lambda x: x.metadata is not None and is_supported_adapter(bot, x), plugins
)
filtered_plugins = filter(lambda x: is_supported(bot, x), plugins)
sorted_plugins = sorted(filtered_plugins, key=lambda x: x.metadata.name) # type: ignore

tree_bar = previous_tree_bar + "├"
Expand Down
789 changes: 406 additions & 383 deletions poetry.lock

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@ documentation = "https://github.com/he0119/nonebot-plugin-treehelp#readme"

[tool.poetry.dependencies]
python = "^3.8"
nonebot2 = "^2.0.0-beta.5"
nonebot2 = "^2.0.0"

[tool.poetry.group.dev.dependencies]
black = "*"
isort = "*"
pre-commit = "*"
nonebot-adapter-console = "^0.3.2"
nb-cli = "^1.0.4"
nonebot-adapter-console = "^0.3.2"
nonebot-adapter-onebot = "^2.2.3"

[tool.poetry.group.test.dependencies]
nonebug = "^0.3.1"
Expand Down
13 changes: 13 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,19 @@ def pytest_configure(config: pytest.Config) -> None:
config.stash[NONEBOT_INIT_KWARGS] = {"command_sep": [".", "。"]}


@pytest.fixture(autouse=True)
def register_adapters(nonebug_init: None):
from nonebot import get_driver
from nonebot.adapters.console import Adapter as ConsoleAdapter
from nonebot.adapters.onebot.v11 import Adapter as OnebotV11Adapter
from nonebot.adapters.onebot.v12 import Adapter as OnebotV12Adapter

driver = get_driver()
driver.register_adapter(ConsoleAdapter)
driver.register_adapter(OnebotV11Adapter)
driver.register_adapter(OnebotV12Adapter)


@pytest.fixture
def app(nonebug_init: None):
clear_plugins()
Expand Down
1 change: 1 addition & 0 deletions tests/plugins/adapters/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
name="适配器",
description="测试不同适配器",
usage="",
type="application",
)

_sub_plugins = set()
Expand Down
4 changes: 1 addition & 3 deletions tests/plugins/adapters/plugins/sub1.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,5 @@
name="OneBot",
description="测试 OneBot 适配器",
usage="/onebot",
extra={
"adapters": ["OneBot"],
},
supported_adapters={"~onebot.v11", "~onebot.v12"},
)
10 changes: 4 additions & 6 deletions tests/plugins/adapters/plugins/sub2.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
from nonebot.plugin import PluginMetadata

__plugin_meta__ = PluginMetadata(
name="Fake",
description="测试 Fake 适配器",
usage="/fake",
extra={
"adapters": ["fake"],
},
name="Console",
description="测试 Console 适配器",
usage="/console",
supported_adapters={"~console"},
)
9 changes: 9 additions & 0 deletions tests/plugins/adapters/plugins/sub3.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from nonebot.plugin import PluginMetadata

__plugin_meta__ = PluginMetadata(
name="library",
description="测试库插件",
usage="/library",
supported_adapters={"~console"},
type="library",
)
9 changes: 9 additions & 0 deletions tests/plugins/adapters/plugins/sub4.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
""" 插件支持的适配器不存在 """
from nonebot.plugin import PluginMetadata

__plugin_meta__ = PluginMetadata(
name="Console",
description="测试 Console 适配器",
usage="/console",
supported_adapters={"~fake"},
)
1 change: 1 addition & 0 deletions tests/plugins/adapters/plugins/sub5.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
""" 没有插件元数据 """
22 changes: 14 additions & 8 deletions tests/test_adapters.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,36 +21,42 @@ async def test_adapters(app: App):


async def test_adapters_plugin(app: App):
"""仅支持 Fake 适配器的插件"""
from nonebot import require
"""仅支持 Console 适配器的插件"""
from nonebot import get_adapter, require
from nonebot.adapters.console import Adapter

adapter = get_adapter(Adapter)

require("tests.plugins.adapters")
from nonebot_plugin_treehelp import help_cmd

async with app.test_matcher(help_cmd) as ctx:
bot = ctx.create_bot()
bot = ctx.create_bot(adapter=adapter)
message = message = make_fake_message()("/help 适配器")
event = make_fake_event(_message=message)()

ctx.receive_event(bot, event)
ctx.should_call_send(event, "适配器\n\nFake # 测试 Fake 适配器", True)
ctx.should_call_send(event, "适配器\n\nConsole # 测试 Console 适配器", True)
ctx.should_finished()


async def test_adapters_supported_plugin(app: App):
"""支持的插件"""
from nonebot import require
from nonebot import get_adapter, require
from nonebot.adapters.console import Adapter

adapter = get_adapter(Adapter)

require("tests.plugins.adapters")
from nonebot_plugin_treehelp import help_cmd

async with app.test_matcher(help_cmd) as ctx:
bot = ctx.create_bot()
message = message = make_fake_message()("/help Fake")
bot = ctx.create_bot(adapter=adapter)
message = message = make_fake_message()("/help 适配器")
event = make_fake_event(_message=message)()

ctx.receive_event(bot, event)
ctx.should_call_send(event, "Fake\n\n/fake", True)
ctx.should_call_send(event, "适配器\n\nConsole # 测试 Console 适配器", True)
ctx.should_finished()


Expand Down

0 comments on commit 50d9345

Please sign in to comment.