修复代码格式和文件名大小写问题

This commit is contained in:
Windpicker-owo
2025-08-31 20:50:17 +08:00
parent df29014e41
commit 8149731925
218 changed files with 6913 additions and 8257 deletions

View File

@@ -15,13 +15,13 @@ logger = get_logger("dependency_manager")
class DependencyManager:
"""Python包依赖管理器
负责检查和自动安装插件的Python包依赖
"""
def __init__(self, auto_install: bool = True, use_mirror: bool = False, mirror_url: Optional[str] = None):
"""初始化依赖管理器
Args:
auto_install: 是否自动安装缺失的依赖
use_mirror: 是否使用PyPI镜像源
@@ -30,38 +30,39 @@ class DependencyManager:
# 延迟导入配置以避免循环依赖
try:
from src.plugin_system.utils.dependency_config import get_dependency_config
config = get_dependency_config()
# 优先使用配置文件中的设置,参数作为覆盖
self.auto_install = config.auto_install if auto_install is True else auto_install
self.use_mirror = config.use_mirror if use_mirror is False else use_mirror
self.mirror_url = config.mirror_url if mirror_url is None else mirror_url
self.install_timeout = config.install_timeout
except Exception as e:
logger.warning(f"无法加载依赖配置,使用默认设置: {e}")
self.auto_install = auto_install
self.use_mirror = use_mirror or False
self.mirror_url = mirror_url or ""
self.install_timeout = 300
def check_dependencies(self, dependencies: Any, plugin_name: str = "") -> Tuple[bool, List[str], List[str]]:
"""检查依赖包是否满足要求
Args:
dependencies: 依赖列表支持字符串或PythonDependency对象
plugin_name: 插件名称,用于日志记录
Returns:
Tuple[bool, List[str], List[str]]: (是否全部满足, 缺失的包, 错误信息)
"""
missing_packages = []
error_messages = []
log_prefix = f"[Plugin:{plugin_name}] " if plugin_name else ""
# 标准化依赖格式
normalized_deps = self._normalize_dependencies(dependencies)
for dep in normalized_deps:
try:
if not self._check_single_dependency(dep):
@@ -71,38 +72,40 @@ class DependencyManager:
error_msg = f"检查依赖 {dep.package_name} 时发生错误: {str(e)}"
error_messages.append(error_msg)
logger.error(f"{log_prefix}{error_msg}")
all_satisfied = len(missing_packages) == 0 and len(error_messages) == 0
if all_satisfied:
logger.debug(f"{log_prefix}所有Python依赖检查通过")
else:
logger.warning(f"{log_prefix}Python依赖检查失败: 缺失{len(missing_packages)}个包, {len(error_messages)}个错误")
logger.warning(
f"{log_prefix}Python依赖检查失败: 缺失{len(missing_packages)}个包, {len(error_messages)}个错误"
)
return all_satisfied, missing_packages, error_messages
def install_dependencies(self, packages: List[str], plugin_name: str = "") -> Tuple[bool, List[str]]:
"""自动安装缺失的依赖包
Args:
packages: 要安装的包列表
plugin_name: 插件名称,用于日志记录
Returns:
Tuple[bool, List[str]]: (是否全部安装成功, 失败的包列表)
"""
if not packages:
return True, []
if not self.auto_install:
logger.info(f"[Plugin:{plugin_name}] 自动安装已禁用,跳过安装: {packages}")
return False, packages
log_prefix = f"[Plugin:{plugin_name}] " if plugin_name else ""
logger.info(f"{log_prefix}开始自动安装Python依赖: {packages}")
failed_packages = []
for package in packages:
try:
if self._install_single_package(package, plugin_name):
@@ -113,37 +116,37 @@ class DependencyManager:
except Exception as e:
failed_packages.append(package)
logger.error(f"{log_prefix}❌ 安装 {package} 时发生异常: {str(e)}")
success = len(failed_packages) == 0
if success:
logger.info(f"{log_prefix}🎉 所有依赖安装完成")
else:
logger.error(f"{log_prefix}⚠️ 部分依赖安装失败: {failed_packages}")
return success, failed_packages
def check_and_install_dependencies(self, dependencies: Any, plugin_name: str = "") -> Tuple[bool, List[str]]:
"""检查并自动安装依赖(组合操作)
Args:
dependencies: 依赖列表
plugin_name: 插件名称
Returns:
Tuple[bool, List[str]]: (是否全部满足, 错误信息列表)
"""
# 第一步:检查依赖
all_satisfied, missing_packages, check_errors = self.check_dependencies(dependencies, plugin_name)
if all_satisfied:
return True, []
all_errors = check_errors.copy()
# 第二步:尝试安装缺失的包
if missing_packages and self.auto_install:
install_success, failed_packages = self.install_dependencies(missing_packages, plugin_name)
if not install_success:
all_errors.extend([f"安装失败: {pkg}" for pkg in failed_packages])
else:
@@ -156,13 +159,13 @@ class DependencyManager:
return True, []
else:
all_errors.extend([f"缺失依赖: {pkg}" for pkg in missing_packages])
return False, all_errors
def _normalize_dependencies(self, dependencies: Any) -> List[PythonDependency]:
"""将依赖列表标准化为PythonDependency对象"""
normalized = []
for dep in dependencies:
if isinstance(dep, str):
# 解析字符串格式的依赖
@@ -170,28 +173,27 @@ class DependencyManager:
# 尝试解析为requirement格式 (如 "package>=1.0.0")
req = Requirement(dep)
version_spec = str(req.specifier) if req.specifier else ""
normalized.append(PythonDependency(
package_name=req.name,
version=version_spec,
install_name=dep # 保持原始的安装名称
))
normalized.append(
PythonDependency(
package_name=req.name,
version=version_spec,
install_name=dep, # 保持原始的安装名称
)
)
except Exception:
# 如果解析失败,作为简单包名处理
normalized.append(PythonDependency(
package_name=dep,
install_name=dep
))
normalized.append(PythonDependency(package_name=dep, install_name=dep))
elif isinstance(dep, PythonDependency):
normalized.append(dep)
else:
logger.warning(f"未知的依赖格式: {dep}")
return normalized
def _check_single_dependency(self, dep: PythonDependency) -> bool:
"""检查单个依赖是否满足要求"""
def _try_check(import_name: str) -> bool:
"""尝试使用给定的导入名进行检查"""
try:
@@ -206,11 +208,11 @@ class DependencyManager:
# 检查版本要求
try:
module = importlib.import_module(import_name)
installed_version = getattr(module, '__version__', None)
installed_version = getattr(module, "__version__", None)
if installed_version is None:
# 尝试其他常见的版本属性
installed_version = getattr(module, 'VERSION', None)
installed_version = getattr(module, "VERSION", None)
if installed_version is None:
logger.debug(f"无法获取包 {import_name} 的版本信息,假设满足要求")
return True
@@ -243,33 +245,27 @@ class DependencyManager:
# 3. 如果别名也失败了,或者没有别名,最终确认失败
return False
def _install_single_package(self, package: str, plugin_name: str = "") -> bool:
"""安装单个包"""
try:
cmd = [sys.executable, "-m", "pip", "install", package]
# 添加镜像源设置
if self.use_mirror and self.mirror_url:
cmd.extend(["-i", self.mirror_url])
logger.debug(f"[Plugin:{plugin_name}] 使用PyPI镜像源: {self.mirror_url}")
logger.debug(f"[Plugin:{plugin_name}] 执行安装命令: {' '.join(cmd)}")
result = subprocess.run(
cmd,
capture_output=True,
text=True,
timeout=self.install_timeout,
check=False
)
result = subprocess.run(cmd, capture_output=True, text=True, timeout=self.install_timeout, check=False)
if result.returncode == 0:
return True
else:
logger.error(f"[Plugin:{plugin_name}] pip安装失败: {result.stderr}")
return False
except subprocess.TimeoutExpired:
logger.error(f"[Plugin:{plugin_name}] 安装 {package} 超时")
return False
@@ -294,7 +290,5 @@ def configure_dependency_manager(auto_install: bool = True, use_mirror: bool = F
"""配置全局依赖管理器"""
global _global_dependency_manager
_global_dependency_manager = DependencyManager(
auto_install=auto_install,
use_mirror=use_mirror,
mirror_url=mirror_url
)
auto_install=auto_install, use_mirror=use_mirror, mirror_url=mirror_url
)