🐛 插件商店测试修复

This commit is contained in:
HibiKier 2025-06-20 19:03:37 +08:00
parent 724a25251f
commit c766ecd9d3
11 changed files with 117 additions and 54 deletions

View File

@ -359,7 +359,7 @@ async def test_add_plugin_exist(
init_mocked_api(mocked_api=mocked_api)
mocker.patch(
"zhenxun.builtin_plugins.plugin_store.data_source.ShopManage.get_loaded_plugins",
"zhenxun.builtin_plugins.plugin_store.data_source.StoreManager.get_loaded_plugins",
return_value=[("search_image", "0.1")],
)
plugin_id = 1

View File

@ -57,7 +57,7 @@ async def test_search_plugin_name(
)
ctx.receive_event(bot=bot, event=event)
mock_table_page.assert_awaited_once_with(
"插件列表",
"商店插件列表",
"通过添加/移除插件 ID 来管理插件",
["-", "ID", "名称", "简介", "作者", "版本", "类型"],
[
@ -123,7 +123,7 @@ async def test_search_plugin_author(
)
ctx.receive_event(bot=bot, event=event)
mock_table_page.assert_awaited_once_with(
"插件列表",
"商店插件列表",
"通过添加/移除插件 ID 来管理插件",
["-", "ID", "名称", "简介", "作者", "版本", "类型"],
[

View File

@ -32,7 +32,7 @@ async def test_update_all_plugin_basic_need_update(
new=tmp_path / "zhenxun",
)
mocker.patch(
"zhenxun.builtin_plugins.plugin_store.data_source.ShopManage.get_loaded_plugins",
"zhenxun.builtin_plugins.plugin_store.data_source.StoreManager.get_loaded_plugins",
return_value=[("search_image", "0.0")],
)
@ -87,7 +87,7 @@ async def test_update_all_plugin_basic_is_new(
new=tmp_path / "zhenxun",
)
mocker.patch(
"zhenxun.builtin_plugins.plugin_store.data_source.ShopManage.get_loaded_plugins",
"zhenxun.builtin_plugins.plugin_store.data_source.StoreManager.get_loaded_plugins",
return_value=[("search_image", "0.1")],
)

View File

@ -32,7 +32,7 @@ async def test_update_plugin_basic_need_update(
new=tmp_path / "zhenxun",
)
mocker.patch(
"zhenxun.builtin_plugins.plugin_store.data_source.ShopManage.get_loaded_plugins",
"zhenxun.builtin_plugins.plugin_store.data_source.StoreManager.get_loaded_plugins",
return_value=[("search_image", "0.0")],
)
@ -87,7 +87,7 @@ async def test_update_plugin_basic_is_new(
new=tmp_path / "zhenxun",
)
mocker.patch(
"zhenxun.builtin_plugins.plugin_store.data_source.ShopManage.get_loaded_plugins",
"zhenxun.builtin_plugins.plugin_store.data_source.StoreManager.get_loaded_plugins",
return_value=[("search_image", "0.1")],
)

View File

@ -1,5 +1,6 @@
{
"鸡汤": {
[
{
"name": "鸡汤",
"module": "jitang",
"module_path": "plugins.alapi.jitang",
"description": "喏,亲手为你煮的鸡汤",
@ -9,7 +10,8 @@
"plugin_type": "NORMAL",
"is_dir": false
},
"识图": {
{
"name": "识图",
"module": "search_image",
"module_path": "plugins.search_image",
"description": "以图搜图,看破本源",
@ -19,7 +21,8 @@
"plugin_type": "NORMAL",
"is_dir": true
},
"网易云热评": {
{
"name": "网易云热评",
"module": "comments_163",
"module_path": "plugins.alapi.comments_163",
"description": "生了个人,我很抱歉",
@ -29,7 +32,8 @@
"plugin_type": "NORMAL",
"is_dir": false
},
"B站订阅": {
{
"name": "B站订阅",
"module": "bilibili_sub",
"module_path": "plugins.bilibili_sub",
"description": "非常便利的B站订阅通知",
@ -39,4 +43,4 @@
"plugin_type": "NORMAL",
"is_dir": true
}
}
]

View File

@ -1,5 +1,6 @@
{
"github订阅": {
[
{
"name": "github订阅",
"module": "github_sub",
"module_path": "github_sub",
"description": "订阅github用户或仓库",
@ -10,7 +11,8 @@
"is_dir": true,
"github_url": "https://github.com/xuanerwa/zhenxun_github_sub"
},
"Minecraft查服": {
{
"name": "Minecraft查服",
"module": "mc_check",
"module_path": "mc_check",
"description": "Minecraft服务器状态查询支持IPv6",
@ -21,4 +23,4 @@
"is_dir": true,
"github_url": "https://github.com/molanp/zhenxun_check_Minecraft"
}
}
]

View File

@ -55,32 +55,6 @@ def install_requirement(plugin_path: Path):
):
VirtualEnvPackageManager.install_requirement(existing_requirements)
if not existing_requirements:
logger.debug(
f"No requirement.txt found for plugin: {plugin_path.name}", "插件管理"
)
return
try:
command = WIN_COMMAND if BAT_FILE.exists() else DEFAULT_COMMAND
command.append(str(existing_requirements))
result = subprocess.run(
command,
check=True,
capture_output=True,
text=True,
)
logger.debug(
"Successfully installed dependencies for"
f" plugin: {plugin_path.name}. Output:\n{result.stdout}",
"插件管理",
)
except subprocess.CalledProcessError:
logger.error(
f"Failed to install dependencies for plugin: {plugin_path.name}. "
" Error:\n{e.stderr}"
)
class StoreManager:
@classmethod
@ -232,7 +206,7 @@ class StoreManager:
db_plugin_list = await cls.get_loaded_plugins("module")
plugin_info = next(p for p in plugin_list if p.module == plugin_key)
if plugin_info.module in [p[0] for p in db_plugin_list]:
return f"插件 {plugin_key} 已安装,无需重复安装"
return f"插件 {plugin_info.name} 已安装,无需重复安装"
is_external = True
if plugin_info.github_url is None:
plugin_info.github_url = DEFAULT_GITHUB_URL
@ -241,14 +215,14 @@ class StoreManager:
if len(version_split) > 1:
github_url_split = plugin_info.github_url.split("/tree/")
plugin_info.github_url = f"{github_url_split[0]}/tree/{version_split[1]}"
logger.info(f"正在安装插件 {plugin_key}...", LOG_COMMAND)
logger.info(f"正在安装插件 {plugin_info.name}...", LOG_COMMAND)
await cls.install_plugin_with_repo(
plugin_info.github_url,
plugin_info.module_path,
plugin_info.is_dir,
is_external,
)
return f"插件 {plugin_key} 安装成功! 重启后生效"
return f"插件 {plugin_info.name} 安装成功! 重启后生效"
@classmethod
async def install_plugin_with_repo(
@ -348,14 +322,14 @@ class StoreManager:
if not plugin_info.is_dir:
path = Path(f"{path}.py")
if not path.exists():
return f"插件 {plugin_key} 不存在..."
logger.debug(f"尝试移除插件 {plugin_key} 文件: {path}", LOG_COMMAND)
return f"插件 {plugin_info.name} 不存在..."
logger.debug(f"尝试移除插件 {plugin_info.name} 文件: {path}", LOG_COMMAND)
if plugin_info.is_dir:
shutil.rmtree(path)
else:
path.unlink()
await PluginInitManager.remove(f"zhenxun.{plugin_info.module_path}")
return f"插件 {plugin_key} 移除成功! 重启后生效"
return f"插件 {plugin_info.name} 移除成功! 重启后生效"
@classmethod
async def search_plugin(cls, plugin_name_or_author: str) -> BuildImage | str:
@ -393,7 +367,7 @@ class StoreManager:
return "未找到相关插件..."
column_name = ["-", "ID", "名称", "简介", "作者", "版本", "类型"]
return await ImageTemplate.table_page(
"商店列表",
"商店插件列表",
"通过添加/移除插件 ID 来管理插件",
column_name,
data_list,
@ -415,15 +389,15 @@ class StoreManager:
plugin_key = await cls._resolve_plugin_key(plugin_id)
except ValueError as e:
return str(e)
logger.info(f"尝试更新插件 {plugin_key}", LOG_COMMAND)
plugin_info = next(p for p in plugin_list if p.module == plugin_key)
logger.info(f"尝试更新插件 {plugin_info.name}", LOG_COMMAND)
db_plugin_list = await cls.get_loaded_plugins("module", "version")
suc_plugin = {p[0]: (p[1] or "Unknown") for p in db_plugin_list}
if plugin_info.module not in [p[0] for p in db_plugin_list]:
return f"插件 {plugin_key} 未安装,无法更新"
return f"插件 {plugin_info.name} 未安装,无法更新"
logger.debug(f"当前插件列表: {suc_plugin}", LOG_COMMAND)
if cls.check_version_is_new(plugin_info, suc_plugin):
return f"插件 {plugin_key} 已是最新版本"
return f"插件 {plugin_info.name} 已是最新版本"
is_external = True
if plugin_info.github_url is None:
plugin_info.github_url = DEFAULT_GITHUB_URL
@ -434,7 +408,7 @@ class StoreManager:
plugin_info.is_dir,
is_external,
)
return f"插件 {plugin_key} 更新成功! 重启后生效"
return f"插件 {plugin_info.name} 更新成功! 重启后生效"
@classmethod
async def update_all_plugin(cls) -> str:

View File

@ -0,0 +1 @@

View File

@ -0,0 +1,36 @@
from abc import ABC
from typing import Literal
from pydantic import BaseModel
class Style(BaseModel):
"""常用样式"""
padding: str = "0px"
margin: str = "0px"
border: str = "0px"
border_radius: str = "0px"
text_align: Literal["left", "right", "center"] = "left"
color: str = "#000"
font_size: str = "16px"
class Component(ABC):
def __init__(self, background_color: str = "#fff", is_container: bool = False):
self.extra_style = []
self.style = Style()
self.background_color = background_color
self.is_container = is_container
self.children = []
def add_child(self, child: "Component | str"):
self.children.append(child)
def set_style(self, style: Style):
self.style = style
def add_style(self, style: str):
self.extra_style.append(style)
def to_html(self) -> str: ...

View File

@ -0,0 +1,15 @@
from ..component import Component, Style
from ..container import Row
class Title(Component):
def __init__(self, text: str, color: str = "#000"):
self.text = text
self.color = color
def build(self):
row = Row()
style = Style(font_size="36px", color=self.color)
row.set_style(style)
# def

View File

@ -0,0 +1,31 @@
from .component import Component
class Row(Component):
def __init__(self, background_color: str = "#fff"):
super().__init__(background_color, True)
class Col(Component):
def __init__(self, background_color: str = "#fff"):
super().__init__(background_color, True)
class Container(Component):
def __init__(self, background_color: str = "#fff"):
super().__init__(background_color, True)
self.children = []
class GlobalOverview:
def __init__(self, name: str):
self.name = name
self.class_name: dict[str, list[str]] = {}
self.content = None
def set_content(self, content: Container):
self.content = content
def add_class(self, class_name: str, contents: list[str]):
"""全局样式"""
self.class_name[class_name] = contents