mirror of
https://github.com/zhenxun-org/zhenxun_bot.git
synced 2025-12-14 21:52:56 +08:00
✨ 适配新版本webui (#1905)
Co-authored-by: molanp <104612722+molanp@users.noreply.github.com> Co-authored-by: BalconyJH <73932916+BalconyJH@users.noreply.github.com>
This commit is contained in:
parent
6546eb990b
commit
9cda0e5d8f
@ -40,7 +40,9 @@ async def create_help_img(
|
||||
|
||||
match help_type:
|
||||
case "html":
|
||||
result = BuildImage.open(await build_html_image(group_id, is_detail))
|
||||
result = BuildImage.open(
|
||||
await build_html_image(session, group_id, is_detail)
|
||||
)
|
||||
case "zhenxun":
|
||||
result = BuildImage.open(
|
||||
await build_zhenxun_image(session, group_id, is_detail)
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
from collections.abc import Callable
|
||||
|
||||
from nonebot_plugin_uninfo import Uninfo
|
||||
|
||||
from zhenxun.models.bot_console import BotConsole
|
||||
from zhenxun.models.group_console import GroupConsole
|
||||
from zhenxun.models.plugin_info import PluginInfo
|
||||
from zhenxun.utils.enum import PluginType
|
||||
@ -27,13 +30,15 @@ async def sort_type() -> dict[str, list[PluginInfo]]:
|
||||
|
||||
|
||||
async def classify_plugin(
|
||||
group_id: str | None, is_detail: bool, handle: Callable
|
||||
session: Uninfo, group_id: str | None, is_detail: bool, handle: Callable
|
||||
) -> dict[str, list]:
|
||||
"""对插件进行分类并判断状态
|
||||
|
||||
参数:
|
||||
session: Uninfo对象
|
||||
group_id: 群组id
|
||||
is_detail: 是否详细帮助
|
||||
handle: 回调方法
|
||||
|
||||
返回:
|
||||
dict[str, list[Item]]: 分类插件数据
|
||||
@ -41,9 +46,10 @@ async def classify_plugin(
|
||||
sort_data = await sort_type()
|
||||
classify: dict[str, list] = {}
|
||||
group = await GroupConsole.get_or_none(group_id=group_id) if group_id else None
|
||||
bot = await BotConsole.get_or_none(bot_id=session.self_id)
|
||||
for menu, value in sort_data.items():
|
||||
for plugin in value:
|
||||
if not classify.get(menu):
|
||||
classify[menu] = []
|
||||
classify[menu].append(handle(plugin, group, is_detail))
|
||||
classify[menu].append(handle(bot, plugin, group, is_detail))
|
||||
return classify
|
||||
|
||||
@ -2,9 +2,11 @@ import os
|
||||
import random
|
||||
|
||||
from nonebot_plugin_htmlrender import template_to_pic
|
||||
from nonebot_plugin_uninfo import Uninfo
|
||||
from pydantic import BaseModel
|
||||
|
||||
from zhenxun.configs.path_config import TEMPLATE_PATH
|
||||
from zhenxun.models.bot_console import BotConsole
|
||||
from zhenxun.models.group_console import GroupConsole
|
||||
from zhenxun.models.plugin_info import PluginInfo
|
||||
from zhenxun.utils.enum import BlockType
|
||||
@ -48,11 +50,12 @@ ICON2STR = {
|
||||
|
||||
|
||||
def __handle_item(
|
||||
plugin: PluginInfo, group: GroupConsole | None, is_detail: bool
|
||||
bot: BotConsole, plugin: PluginInfo, group: GroupConsole | None, is_detail: bool
|
||||
) -> Item:
|
||||
"""构造Item
|
||||
|
||||
参数:
|
||||
bot: BotConsole
|
||||
plugin: PluginInfo
|
||||
group: 群组
|
||||
is_detail: 是否详细
|
||||
@ -73,10 +76,13 @@ def __handle_item(
|
||||
]:
|
||||
sta = 2
|
||||
if group:
|
||||
if f"{plugin.module}:super," in group.block_plugin:
|
||||
if f"{plugin.module}," in group.superuser_block_plugin:
|
||||
sta = 2
|
||||
if f"{plugin.module}," in group.block_plugin:
|
||||
sta = 1
|
||||
if bot:
|
||||
if f"{plugin.module}," in bot.block_plugins:
|
||||
sta = 2
|
||||
return Item(plugin_name=plugin.name, sta=sta)
|
||||
|
||||
|
||||
@ -119,14 +125,17 @@ def build_plugin_data(classify: dict[str, list[Item]]) -> list[dict[str, str]]:
|
||||
return plugin_list
|
||||
|
||||
|
||||
async def build_html_image(group_id: str | None, is_detail: bool) -> bytes:
|
||||
async def build_html_image(
|
||||
session: Uninfo, group_id: str | None, is_detail: bool
|
||||
) -> bytes:
|
||||
"""构造HTML帮助图片
|
||||
|
||||
参数:
|
||||
session: Uninfo
|
||||
group_id: 群号
|
||||
is_detail: 是否详细帮助
|
||||
"""
|
||||
classify = await classify_plugin(group_id, is_detail, __handle_item)
|
||||
classify = await classify_plugin(session, group_id, is_detail, __handle_item)
|
||||
plugin_list = build_plugin_data(classify)
|
||||
return await template_to_pic(
|
||||
template_path=str((TEMPLATE_PATH / "menu").absolute()),
|
||||
|
||||
@ -6,6 +6,7 @@ from pydantic import BaseModel
|
||||
from zhenxun.configs.config import BotConfig
|
||||
from zhenxun.configs.path_config import TEMPLATE_PATH
|
||||
from zhenxun.configs.utils import PluginExtraData
|
||||
from zhenxun.models.bot_console import BotConsole
|
||||
from zhenxun.models.group_console import GroupConsole
|
||||
from zhenxun.models.plugin_info import PluginInfo
|
||||
from zhenxun.utils.enum import BlockType
|
||||
@ -21,12 +22,19 @@ class Item(BaseModel):
|
||||
"""插件命令"""
|
||||
|
||||
|
||||
def __handle_item(plugin: PluginInfo, group: GroupConsole | None, is_detail: bool):
|
||||
def __handle_item(
|
||||
bot: BotConsole | None,
|
||||
plugin: PluginInfo,
|
||||
group: GroupConsole | None,
|
||||
is_detail: bool,
|
||||
):
|
||||
"""构造Item
|
||||
|
||||
参数:
|
||||
bot: BotConsole
|
||||
plugin: PluginInfo
|
||||
group: 群组
|
||||
is_detail: 是否为详细
|
||||
|
||||
返回:
|
||||
Item: Item
|
||||
@ -40,6 +48,8 @@ def __handle_item(plugin: PluginInfo, group: GroupConsole | None, is_detail: boo
|
||||
plugin.name = f"{plugin.name}(不可用)"
|
||||
elif group and f"{plugin.module}," in group.block_plugin:
|
||||
plugin.name = f"{plugin.name}(不可用)"
|
||||
elif bot and f"{plugin.module}," in bot.block_plugins:
|
||||
plugin.name = f"{plugin.name}(不可用)"
|
||||
commands = []
|
||||
nb_plugin = nonebot.get_plugin_by_module_name(plugin.module_path)
|
||||
if is_detail and nb_plugin and nb_plugin.metadata and nb_plugin.metadata.extra:
|
||||
@ -142,7 +152,7 @@ async def build_zhenxun_image(
|
||||
group_id: 群号
|
||||
is_detail: 是否详细帮助
|
||||
"""
|
||||
classify = await classify_plugin(group_id, is_detail, __handle_item)
|
||||
classify = await classify_plugin(session, group_id, is_detail, __handle_item)
|
||||
plugin_list = build_plugin_data(classify)
|
||||
platform = PlatformUtils.get_platform(session)
|
||||
bot_id = BotConfig.get_qbot_uid(session.self_id) or session.self_id
|
||||
|
||||
@ -46,7 +46,10 @@ class MenuManage:
|
||||
icon="database",
|
||||
),
|
||||
MenuItem(
|
||||
name="系统信息", module="system", router="/system", icon="system"
|
||||
name="文件管理", module="system", router="/system", icon="system"
|
||||
),
|
||||
MenuItem(
|
||||
name="关于我们", module="about", router="/about", icon="about"
|
||||
),
|
||||
]
|
||||
self.save()
|
||||
|
||||
@ -16,7 +16,7 @@ from zhenxun.utils.platform import PlatformUtils
|
||||
|
||||
from ....base_model import Result
|
||||
from ....config import QueryDateType
|
||||
from ....utils import authentication, get_system_status
|
||||
from ....utils import authentication, clear_help_image, get_system_status
|
||||
from .data_source import ApiDataSource
|
||||
from .model import (
|
||||
ActiveGroup,
|
||||
@ -234,6 +234,7 @@ async def _(param: BotManageUpdateParam):
|
||||
bot_data.block_plugins = CommonUtils.convert_module_format(param.block_plugins)
|
||||
bot_data.block_tasks = CommonUtils.convert_module_format(param.block_tasks)
|
||||
await bot_data.save(update_fields=["block_plugins", "block_tasks"])
|
||||
clear_help_image()
|
||||
return Result.ok()
|
||||
except Exception as e:
|
||||
logger.error(f"{router.prefix}/update_bot_manage 调用错误", "WebUi", e=e)
|
||||
|
||||
@ -92,7 +92,7 @@ class ApiDataSource:
|
||||
"""
|
||||
version_file = Path() / "__version__"
|
||||
if version_file.exists():
|
||||
if text := version_file.open().read():
|
||||
if text := version_file.open(encoding="utf-8").read():
|
||||
return text.replace("__version__: ", "").strip()
|
||||
return "unknown"
|
||||
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
from datetime import datetime
|
||||
|
||||
from fastapi import APIRouter
|
||||
import nonebot
|
||||
from nonebot import on_message
|
||||
@ -49,13 +51,14 @@ async def message_handle(
|
||||
message: UniMsg,
|
||||
group_id: str | None,
|
||||
):
|
||||
time = str(datetime.now().replace(microsecond=0))
|
||||
messages = []
|
||||
for m in message:
|
||||
if isinstance(m, Text | str):
|
||||
messages.append(MessageItem(type="text", msg=str(m)))
|
||||
messages.append(MessageItem(type="text", msg=str(m), time=time))
|
||||
elif isinstance(m, Image):
|
||||
if m.url:
|
||||
messages.append(MessageItem(type="img", msg=m.url))
|
||||
messages.append(MessageItem(type="img", msg=m.url, time=time))
|
||||
elif isinstance(m, At):
|
||||
if group_id:
|
||||
if m.target == "0":
|
||||
@ -72,9 +75,9 @@ async def message_handle(
|
||||
uname = group_user.user_name
|
||||
if m.target not in ID2NAME[group_id]:
|
||||
ID2NAME[group_id][m.target] = uname
|
||||
messages.append(MessageItem(type="at", msg=f"@{uname}"))
|
||||
messages.append(MessageItem(type="at", msg=f"@{uname}", time=time))
|
||||
elif isinstance(m, Hyper):
|
||||
messages.append(MessageItem(type="text", msg="[分享消息]"))
|
||||
messages.append(MessageItem(type="text", msg="[分享消息]", time=time))
|
||||
return messages
|
||||
|
||||
|
||||
|
||||
@ -237,6 +237,8 @@ class MessageItem(BaseModel):
|
||||
"""消息类型"""
|
||||
msg: str
|
||||
"""内容"""
|
||||
time: str
|
||||
"""发送日期"""
|
||||
|
||||
|
||||
class Message(BaseModel):
|
||||
|
||||
@ -6,7 +6,7 @@ from zhenxun.services.log import logger
|
||||
from zhenxun.utils.enum import BlockType, PluginType
|
||||
|
||||
from ....base_model import Result
|
||||
from ....utils import authentication
|
||||
from ....utils import authentication, clear_help_image
|
||||
from .data_source import ApiDataSource
|
||||
from .model import (
|
||||
BatchUpdatePlugins,
|
||||
@ -80,6 +80,7 @@ async def _() -> Result[PluginCount]:
|
||||
async def _(param: UpdatePlugin) -> Result:
|
||||
try:
|
||||
await ApiDataSource.update_plugin(param)
|
||||
clear_help_image()
|
||||
return Result.ok(info="已经帮你写好啦!")
|
||||
except (ValueError, KeyError):
|
||||
return Result.fail("插件数据不存在...")
|
||||
@ -107,6 +108,7 @@ async def _(param: PluginSwitch) -> Result:
|
||||
db_plugin.block_type = None
|
||||
db_plugin.status = True
|
||||
await db_plugin.save()
|
||||
clear_help_image()
|
||||
return Result.ok(info="成功改变了开关状态!")
|
||||
except Exception as e:
|
||||
logger.error(f"{router.prefix}/change_switch 调用错误", "WebUi", e=e)
|
||||
@ -173,6 +175,7 @@ async def batch_update_plugin_config_api(
|
||||
updated_count=result_dict["updated_count"],
|
||||
errors=result_dict["errors"],
|
||||
)
|
||||
clear_help_image()
|
||||
return Result.ok(result_model, "插件配置更新完成")
|
||||
except Exception as e:
|
||||
logger.error(f"{router.prefix}/plugins/batch_update 调用错误", "WebUi", e=e)
|
||||
@ -192,6 +195,7 @@ async def rename_menu_type_api(payload: RenameMenuTypePayload) -> Result:
|
||||
old_name=payload.old_name, new_name=payload.new_name
|
||||
)
|
||||
if result.get("success"):
|
||||
clear_help_image()
|
||||
return Result.ok(
|
||||
info=result.get(
|
||||
"info",
|
||||
|
||||
@ -52,6 +52,10 @@ class ApiDataSource:
|
||||
status=plugin.status,
|
||||
author=plugin.author,
|
||||
block_type=plugin.block_type,
|
||||
is_builtin="builtin_plugins" in plugin.module_path
|
||||
or plugin.plugin_type == PluginType.HIDDEN,
|
||||
allow_setting=plugin.plugin_type != PluginType.HIDDEN,
|
||||
allow_switch=plugin.plugin_type != PluginType.HIDDEN,
|
||||
)
|
||||
plugin_list.append(plugin_info)
|
||||
return plugin_list
|
||||
|
||||
@ -78,6 +78,13 @@ class PluginInfo(BaseModel):
|
||||
author: str | None = None
|
||||
"""作者"""
|
||||
block_type: BlockType | None = Field(None, description="插件禁用状态 (None: 启用)")
|
||||
"""禁用状态"""
|
||||
is_builtin: bool = False
|
||||
"""是否为内置插件"""
|
||||
allow_switch: bool = True
|
||||
"""是否允许开关"""
|
||||
allow_setting: bool = True
|
||||
"""是否允许设置"""
|
||||
|
||||
|
||||
class PluginConfig(BaseModel):
|
||||
|
||||
@ -36,6 +36,8 @@ async def _(path: str | None = None) -> Result[list[DirFile]]:
|
||||
is_image=is_image,
|
||||
name=file,
|
||||
parent=path,
|
||||
size=None if file_path.is_dir() else file_path.stat().st_size,
|
||||
mtime=file_path.stat().st_mtime,
|
||||
)
|
||||
)
|
||||
return Result.ok(data_list)
|
||||
@ -215,3 +217,13 @@ async def _(full_path: str) -> Result[str]:
|
||||
return Result.ok(BuildImage.open(path).pic2bs4())
|
||||
except Exception as e:
|
||||
return Result.warning_(f"获取图片失败: {e!s}")
|
||||
|
||||
|
||||
@router.get(
|
||||
"/ping",
|
||||
response_model=Result[str],
|
||||
response_class=JSONResponse,
|
||||
description="检查服务器状态",
|
||||
)
|
||||
async def _() -> Result[str]:
|
||||
return Result.ok("pong")
|
||||
|
||||
@ -14,6 +14,10 @@ class DirFile(BaseModel):
|
||||
"""文件夹或文件名称"""
|
||||
parent: str | None = None
|
||||
"""父级"""
|
||||
size: int | None = None
|
||||
"""文件大小"""
|
||||
mtime: float | None = None
|
||||
"""修改时间"""
|
||||
|
||||
|
||||
class DeleteFile(BaseModel):
|
||||
|
||||
@ -11,7 +11,7 @@ import psutil
|
||||
import ujson as json
|
||||
|
||||
from zhenxun.configs.config import Config
|
||||
from zhenxun.configs.path_config import DATA_PATH
|
||||
from zhenxun.configs.path_config import DATA_PATH, IMAGE_PATH
|
||||
|
||||
from .base_model import SystemFolderSize, SystemStatus, User
|
||||
|
||||
@ -28,6 +28,22 @@ if token_file.exists():
|
||||
token_data = json.load(open(token_file, encoding="utf8"))
|
||||
|
||||
|
||||
GROUP_HELP_PATH = DATA_PATH / "group_help"
|
||||
SIMPLE_HELP_IMAGE = IMAGE_PATH / "SIMPLE_HELP.png"
|
||||
SIMPLE_DETAIL_HELP_IMAGE = IMAGE_PATH / "SIMPLE_DETAIL_HELP.png"
|
||||
|
||||
|
||||
def clear_help_image():
|
||||
"""清理帮助图片"""
|
||||
if SIMPLE_HELP_IMAGE.exists():
|
||||
SIMPLE_HELP_IMAGE.unlink()
|
||||
if SIMPLE_DETAIL_HELP_IMAGE.exists():
|
||||
SIMPLE_DETAIL_HELP_IMAGE.unlink()
|
||||
for file in GROUP_HELP_PATH.iterdir():
|
||||
if file.is_file():
|
||||
file.unlink()
|
||||
|
||||
|
||||
def get_user(uname: str) -> User | None:
|
||||
"""获取账号密码
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user