mirror of
https://github.com/zhenxun-org/zhenxun_bot.git
synced 2025-12-14 21:52:56 +08:00
✨ 新增依赖管理功能,支持安装和卸载虚拟环境依赖,同时优化相关API和数据模型 (#1936)
This commit is contained in:
parent
bd62698ea5
commit
4bcc5aeea5
@ -4,6 +4,7 @@ from fastapi.responses import JSONResponse
|
|||||||
from zhenxun.models.plugin_info import PluginInfo as DbPluginInfo
|
from zhenxun.models.plugin_info import PluginInfo as DbPluginInfo
|
||||||
from zhenxun.services.log import logger
|
from zhenxun.services.log import logger
|
||||||
from zhenxun.utils.enum import BlockType, PluginType
|
from zhenxun.utils.enum import BlockType, PluginType
|
||||||
|
from zhenxun.utils.manager.virtual_env_package_manager import VirtualEnvPackageManager
|
||||||
|
|
||||||
from ....base_model import Result
|
from ....base_model import Result
|
||||||
from ....utils import authentication, clear_help_image
|
from ....utils import authentication, clear_help_image
|
||||||
@ -11,6 +12,7 @@ from .data_source import ApiDataSource
|
|||||||
from .model import (
|
from .model import (
|
||||||
BatchUpdatePlugins,
|
BatchUpdatePlugins,
|
||||||
BatchUpdateResult,
|
BatchUpdateResult,
|
||||||
|
InstallDependenciesPayload,
|
||||||
PluginCount,
|
PluginCount,
|
||||||
PluginDetail,
|
PluginDetail,
|
||||||
PluginInfo,
|
PluginInfo,
|
||||||
@ -162,9 +164,9 @@ async def _(module: str) -> Result[PluginDetail]:
|
|||||||
dependencies=[authentication()],
|
dependencies=[authentication()],
|
||||||
response_model=Result[BatchUpdateResult],
|
response_model=Result[BatchUpdateResult],
|
||||||
response_class=JSONResponse,
|
response_class=JSONResponse,
|
||||||
summary="批量更新插件配置",
|
description="批量更新插件配置",
|
||||||
)
|
)
|
||||||
async def batch_update_plugin_config_api(
|
async def _(
|
||||||
params: BatchUpdatePlugins,
|
params: BatchUpdatePlugins,
|
||||||
) -> Result[BatchUpdateResult]:
|
) -> Result[BatchUpdateResult]:
|
||||||
"""批量更新插件配置,如开关、类型等"""
|
"""批量更新插件配置,如开关、类型等"""
|
||||||
@ -187,9 +189,9 @@ async def batch_update_plugin_config_api(
|
|||||||
"/menu_type/rename",
|
"/menu_type/rename",
|
||||||
dependencies=[authentication()],
|
dependencies=[authentication()],
|
||||||
response_model=Result,
|
response_model=Result,
|
||||||
summary="重命名菜单类型",
|
description="重命名菜单类型",
|
||||||
)
|
)
|
||||||
async def rename_menu_type_api(payload: RenameMenuTypePayload) -> Result:
|
async def _(payload: RenameMenuTypePayload) -> Result[str]:
|
||||||
try:
|
try:
|
||||||
result = await ApiDataSource.rename_menu_type(
|
result = await ApiDataSource.rename_menu_type(
|
||||||
old_name=payload.old_name, new_name=payload.new_name
|
old_name=payload.old_name, new_name=payload.new_name
|
||||||
@ -213,3 +215,24 @@ async def rename_menu_type_api(payload: RenameMenuTypePayload) -> Result:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"{router.prefix}/menu_type/rename 调用错误", "WebUi", e=e)
|
logger.error(f"{router.prefix}/menu_type/rename 调用错误", "WebUi", e=e)
|
||||||
return Result.fail(info=f"发生未知错误: {type(e).__name__}")
|
return Result.fail(info=f"发生未知错误: {type(e).__name__}")
|
||||||
|
|
||||||
|
|
||||||
|
@router.post(
|
||||||
|
"/install_dependencies",
|
||||||
|
dependencies=[authentication()],
|
||||||
|
response_model=Result,
|
||||||
|
response_class=JSONResponse,
|
||||||
|
description="安装/卸载依赖",
|
||||||
|
)
|
||||||
|
async def _(payload: InstallDependenciesPayload) -> Result:
|
||||||
|
try:
|
||||||
|
if not payload.dependencies:
|
||||||
|
return Result.fail("依赖列表不能为空")
|
||||||
|
if payload.handle_type == "install":
|
||||||
|
result = VirtualEnvPackageManager.install(payload.dependencies)
|
||||||
|
else:
|
||||||
|
result = VirtualEnvPackageManager.uninstall(payload.dependencies)
|
||||||
|
return Result.ok(result)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"{router.prefix}/install_dependencies 调用错误", "WebUi", e=e)
|
||||||
|
return Result.fail(f"发生了一点错误捏 {type(e)}: {e}")
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
from typing import Any
|
from typing import Any, Literal
|
||||||
|
|
||||||
from pydantic import BaseModel, Field
|
from pydantic import BaseModel, Field
|
||||||
|
|
||||||
@ -162,3 +162,15 @@ class BatchUpdateResult(BaseModel):
|
|||||||
default_factory=list, description="错误信息列表"
|
default_factory=list, description="错误信息列表"
|
||||||
)
|
)
|
||||||
"""错误信息列表"""
|
"""错误信息列表"""
|
||||||
|
|
||||||
|
|
||||||
|
class InstallDependenciesPayload(BaseModel):
|
||||||
|
"""
|
||||||
|
安装依赖
|
||||||
|
"""
|
||||||
|
|
||||||
|
handle_type: Literal["install", "uninstall"] = Field(..., description="处理类型")
|
||||||
|
"""处理类型"""
|
||||||
|
|
||||||
|
dependencies: list[str] = Field(..., description="依赖列表")
|
||||||
|
"""依赖列表"""
|
||||||
|
|||||||
@ -31,7 +31,9 @@ class VirtualEnvPackageManager:
|
|||||||
def __get_command(cls) -> list[str]:
|
def __get_command(cls) -> list[str]:
|
||||||
if path := Config.get_config("virtualenv", "python_path"):
|
if path := Config.get_config("virtualenv", "python_path"):
|
||||||
return [path, "-m", "pip"]
|
return [path, "-m", "pip"]
|
||||||
return cls.WIN_COMMAND if BAT_FILE.exists() else cls.DEFAULT_COMMAND
|
return (
|
||||||
|
cls.WIN_COMMAND.copy() if BAT_FILE.exists() else cls.DEFAULT_COMMAND.copy()
|
||||||
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def install(cls, package: list[str] | str):
|
def install(cls, package: list[str] | str):
|
||||||
@ -57,8 +59,10 @@ class VirtualEnvPackageManager:
|
|||||||
f"安装虚拟环境包指令执行完成: {result.stdout}",
|
f"安装虚拟环境包指令执行完成: {result.stdout}",
|
||||||
LOG_COMMAND,
|
LOG_COMMAND,
|
||||||
)
|
)
|
||||||
|
return result.stdout
|
||||||
except CalledProcessError as e:
|
except CalledProcessError as e:
|
||||||
logger.error(f"安装虚拟环境包指令执行失败: {e.stderr}.", LOG_COMMAND)
|
logger.error(f"安装虚拟环境包指令执行失败: {e.stderr}.", LOG_COMMAND)
|
||||||
|
return e.stderr
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def uninstall(cls, package: list[str] | str):
|
def uninstall(cls, package: list[str] | str):
|
||||||
@ -72,6 +76,7 @@ class VirtualEnvPackageManager:
|
|||||||
try:
|
try:
|
||||||
command = cls.__get_command()
|
command = cls.__get_command()
|
||||||
command.append("uninstall")
|
command.append("uninstall")
|
||||||
|
command.append("-y")
|
||||||
command.append(" ".join(package))
|
command.append(" ".join(package))
|
||||||
logger.info(f"执行虚拟环境卸载包指令: {command}", LOG_COMMAND)
|
logger.info(f"执行虚拟环境卸载包指令: {command}", LOG_COMMAND)
|
||||||
result = subprocess.run(
|
result = subprocess.run(
|
||||||
@ -84,8 +89,10 @@ class VirtualEnvPackageManager:
|
|||||||
f"卸载虚拟环境包指令执行完成: {result.stdout}",
|
f"卸载虚拟环境包指令执行完成: {result.stdout}",
|
||||||
LOG_COMMAND,
|
LOG_COMMAND,
|
||||||
)
|
)
|
||||||
|
return result.stdout
|
||||||
except CalledProcessError as e:
|
except CalledProcessError as e:
|
||||||
logger.error(f"卸载虚拟环境包指令执行失败: {e.stderr}.", LOG_COMMAND)
|
logger.error(f"卸载虚拟环境包指令执行失败: {e.stderr}.", LOG_COMMAND)
|
||||||
|
return e.stderr
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def update(cls, package: list[str] | str):
|
def update(cls, package: list[str] | str):
|
||||||
@ -109,8 +116,10 @@ class VirtualEnvPackageManager:
|
|||||||
text=True,
|
text=True,
|
||||||
)
|
)
|
||||||
logger.debug(f"更新虚拟环境包指令执行完成: {result.stdout}", LOG_COMMAND)
|
logger.debug(f"更新虚拟环境包指令执行完成: {result.stdout}", LOG_COMMAND)
|
||||||
|
return result.stdout
|
||||||
except CalledProcessError as e:
|
except CalledProcessError as e:
|
||||||
logger.error(f"更新虚拟环境包指令执行失败: {e.stderr}.", LOG_COMMAND)
|
logger.error(f"更新虚拟环境包指令执行失败: {e.stderr}.", LOG_COMMAND)
|
||||||
|
return e.stderr
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def install_requirement(cls, requirement_file: Path):
|
def install_requirement(cls, requirement_file: Path):
|
||||||
@ -140,11 +149,13 @@ class VirtualEnvPackageManager:
|
|||||||
f"安装虚拟环境依赖文件指令执行完成: {result.stdout}",
|
f"安装虚拟环境依赖文件指令执行完成: {result.stdout}",
|
||||||
LOG_COMMAND,
|
LOG_COMMAND,
|
||||||
)
|
)
|
||||||
|
return result.stdout
|
||||||
except CalledProcessError as e:
|
except CalledProcessError as e:
|
||||||
logger.error(
|
logger.error(
|
||||||
f"安装虚拟环境依赖文件指令执行失败: {e.stderr}.",
|
f"安装虚拟环境依赖文件指令执行失败: {e.stderr}.",
|
||||||
LOG_COMMAND,
|
LOG_COMMAND,
|
||||||
)
|
)
|
||||||
|
return e.stderr
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def list(cls) -> str:
|
def list(cls) -> str:
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user