mirror of
https://github.com/zhenxun-org/zhenxun_bot.git
synced 2025-12-15 14:22:55 +08:00
🐛 插件商店测试修复
This commit is contained in:
parent
724a25251f
commit
c766ecd9d3
@ -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
|
||||
|
||||
@ -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", "名称", "简介", "作者", "版本", "类型"],
|
||||
[
|
||||
|
||||
@ -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")],
|
||||
)
|
||||
|
||||
|
||||
@ -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")],
|
||||
)
|
||||
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@ -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"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@ -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:
|
||||
|
||||
1
zhenxun/utils/html_template/__init__.py
Normal file
1
zhenxun/utils/html_template/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
|
||||
36
zhenxun/utils/html_template/component.py
Normal file
36
zhenxun/utils/html_template/component.py
Normal 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: ...
|
||||
15
zhenxun/utils/html_template/components/title.py
Normal file
15
zhenxun/utils/html_template/components/title.py
Normal 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
|
||||
31
zhenxun/utils/html_template/container.py
Normal file
31
zhenxun/utils/html_template/container.py
Normal 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
|
||||
Loading…
Reference in New Issue
Block a user