Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 适配 NoneBot 2.0 正式版的插件元数据 #60

Merged
merged 4 commits into from
Jun 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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