mirror of
https://github.com/zhenxun-org/zhenxun_bot.git
synced 2026-10-07 04:40:00 +08:00
✨ 重构插件商店,支持Gitee插件管理,更新相关逻辑和配置 (#1931)
This commit is contained in:
@@ -21,6 +21,9 @@ CACHED_API_TTL = 300
|
||||
RAW_CONTENT_FORMAT = "https://raw.githubusercontent.com/{owner}/{repo}/{branch}/{path}"
|
||||
"""raw content格式"""
|
||||
|
||||
GITEE_RAW_CONTENT_FORMAT = "https://gitee.com/{owner}/{repo}/raw/main/{path}"
|
||||
"""gitee raw content格式"""
|
||||
|
||||
ARCHIVE_URL_FORMAT = "https://github.com/{owner}/{repo}/archive/refs/heads/{branch}.zip"
|
||||
"""archive url格式"""
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ from zhenxun.utils.http_utils import AsyncHttpx
|
||||
|
||||
from .const import (
|
||||
ARCHIVE_URL_FORMAT,
|
||||
GITEE_RAW_CONTENT_FORMAT,
|
||||
RAW_CONTENT_FORMAT,
|
||||
RELEASE_ASSETS_FORMAT,
|
||||
RELEASE_SOURCE_FORMAT,
|
||||
@@ -21,6 +22,7 @@ async def __get_fastest_formats(formats: dict[str, str]) -> list[str]:
|
||||
async def get_fastest_raw_formats() -> list[str]:
|
||||
"""获取最快的raw下载地址格式"""
|
||||
formats: dict[str, str] = {
|
||||
"https://gitee.com/": GITEE_RAW_CONTENT_FORMAT,
|
||||
"https://raw.githubusercontent.com/": RAW_CONTENT_FORMAT,
|
||||
"https://ghproxy.cc/": f"https://ghproxy.cc/{RAW_CONTENT_FORMAT}",
|
||||
"https://gh-proxy.com/": f"https://gh-proxy.com/{RAW_CONTENT_FORMAT}",
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -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: ...
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -0,0 +1,159 @@
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
from subprocess import CalledProcessError
|
||||
from typing import ClassVar
|
||||
|
||||
from zhenxun.services.log import logger
|
||||
|
||||
BAT_FILE = Path() / "win启动.bat"
|
||||
|
||||
LOG_COMMAND = "VirtualEnvPackageManager"
|
||||
|
||||
|
||||
class VirtualEnvPackageManager:
|
||||
WIN_COMMAND: ClassVar[list[str]] = [
|
||||
"./Python310/python.exe",
|
||||
"-m",
|
||||
"pip",
|
||||
]
|
||||
|
||||
DEFAULT_COMMAND: ClassVar[list[str]] = ["poetry", "run", "pip"]
|
||||
|
||||
@classmethod
|
||||
def __get_command(cls) -> list[str]:
|
||||
return cls.WIN_COMMAND if BAT_FILE.exists() else cls.DEFAULT_COMMAND
|
||||
|
||||
@classmethod
|
||||
def install(cls, package: list[str] | str):
|
||||
"""安装依赖包
|
||||
|
||||
参数:
|
||||
package: 安装依赖包名称或列表
|
||||
"""
|
||||
if isinstance(package, str):
|
||||
package = [package]
|
||||
try:
|
||||
command = cls.__get_command()
|
||||
command.append("install")
|
||||
command.append(" ".join(package))
|
||||
logger.info(f"执行虚拟环境安装包指令: {command}", LOG_COMMAND)
|
||||
result = subprocess.run(
|
||||
command,
|
||||
check=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
logger.debug(
|
||||
f"安装虚拟环境包指令执行完成: {result.stdout}",
|
||||
LOG_COMMAND,
|
||||
)
|
||||
except CalledProcessError as e:
|
||||
logger.error(f"安装虚拟环境包指令执行失败: {e.stderr}.", LOG_COMMAND)
|
||||
|
||||
@classmethod
|
||||
def uninstall(cls, package: list[str] | str):
|
||||
"""卸载依赖包
|
||||
|
||||
参数:
|
||||
package: 卸载依赖包名称或列表
|
||||
"""
|
||||
if isinstance(package, str):
|
||||
package = [package]
|
||||
try:
|
||||
command = cls.__get_command()
|
||||
command.append("uninstall")
|
||||
command.append(" ".join(package))
|
||||
logger.info(f"执行虚拟环境卸载包指令: {command}", LOG_COMMAND)
|
||||
result = subprocess.run(
|
||||
command,
|
||||
check=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
logger.debug(
|
||||
f"卸载虚拟环境包指令执行完成: {result.stdout}",
|
||||
LOG_COMMAND,
|
||||
)
|
||||
except CalledProcessError as e:
|
||||
logger.error(f"卸载虚拟环境包指令执行失败: {e.stderr}.", LOG_COMMAND)
|
||||
|
||||
@classmethod
|
||||
def update(cls, package: list[str] | str):
|
||||
"""更新依赖包
|
||||
|
||||
参数:
|
||||
package: 更新依赖包名称或列表
|
||||
"""
|
||||
if isinstance(package, str):
|
||||
package = [package]
|
||||
try:
|
||||
command = cls.__get_command()
|
||||
command.append("install")
|
||||
command.append("--upgrade")
|
||||
command.append(" ".join(package))
|
||||
logger.info(f"执行虚拟环境更新包指令: {command}", LOG_COMMAND)
|
||||
result = subprocess.run(
|
||||
command,
|
||||
check=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
logger.debug(f"更新虚拟环境包指令执行完成: {result.stdout}", LOG_COMMAND)
|
||||
except CalledProcessError as e:
|
||||
logger.error(f"更新虚拟环境包指令执行失败: {e.stderr}.", LOG_COMMAND)
|
||||
|
||||
@classmethod
|
||||
def install_requirement(cls, requirement_file: Path):
|
||||
"""安装依赖文件
|
||||
|
||||
参数:
|
||||
requirement_file: requirement文件路径
|
||||
|
||||
异常:
|
||||
FileNotFoundError: 文件不存在
|
||||
"""
|
||||
if not requirement_file.exists():
|
||||
raise FileNotFoundError(f"依赖文件 {requirement_file} 不存在", LOG_COMMAND)
|
||||
try:
|
||||
command = cls.__get_command()
|
||||
command.append("install")
|
||||
command.append("-r")
|
||||
command.append(str(requirement_file.absolute()))
|
||||
logger.info(f"执行虚拟环境安装依赖文件指令: {command}", LOG_COMMAND)
|
||||
result = subprocess.run(
|
||||
command,
|
||||
check=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
logger.debug(
|
||||
f"安装虚拟环境依赖文件指令执行完成: {result.stdout}",
|
||||
LOG_COMMAND,
|
||||
)
|
||||
except CalledProcessError as e:
|
||||
logger.error(
|
||||
f"安装虚拟环境依赖文件指令执行失败: {e.stderr}.",
|
||||
LOG_COMMAND,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def list(cls) -> str:
|
||||
"""列出已安装的依赖包"""
|
||||
try:
|
||||
command = cls.__get_command()
|
||||
command.append("list")
|
||||
logger.info(f"执行虚拟环境列出包指令: {command}", LOG_COMMAND)
|
||||
result = subprocess.run(
|
||||
command,
|
||||
check=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
logger.debug(
|
||||
f"列出虚拟环境包指令执行完成: {result.stdout}",
|
||||
LOG_COMMAND,
|
||||
)
|
||||
return result.stdout
|
||||
except CalledProcessError as e:
|
||||
logger.error(f"列出虚拟环境包指令执行失败: {e.stderr}.", LOG_COMMAND)
|
||||
return ""
|
||||
Reference in New Issue
Block a user