mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-09-05 23:47:41 +08:00
feat(plugin): reuse plugin wheels in batch dependency install
This commit is contained in:
+51
-9
@@ -444,23 +444,63 @@ class PluginHelper(metaclass=WeakSingleton):
|
|||||||
if plugin_dir.exists():
|
if plugin_dir.exists():
|
||||||
shutil.rmtree(plugin_dir, ignore_errors=True)
|
shutil.rmtree(plugin_dir, ignore_errors=True)
|
||||||
|
|
||||||
|
def __collect_plugin_wheels_dirs(self) -> List[Path]:
|
||||||
|
"""
|
||||||
|
收集已安装插件目录下可用的 wheels 目录,供批量依赖安装时复用。
|
||||||
|
"""
|
||||||
|
wheels_dirs = []
|
||||||
|
try:
|
||||||
|
install_plugins = {
|
||||||
|
plugin_id.lower()
|
||||||
|
for plugin_id in self.systemconfig.get(SystemConfigKey.UserInstalledPlugins) or []
|
||||||
|
}
|
||||||
|
for plugin_id in install_plugins:
|
||||||
|
wheels_dir = PLUGIN_DIR / plugin_id / "wheels"
|
||||||
|
if wheels_dir.is_dir():
|
||||||
|
wheels_dirs.append(wheels_dir)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"收集插件 wheels 目录时发生错误:{e}")
|
||||||
|
return []
|
||||||
|
|
||||||
|
# 去重并保持稳定顺序,避免重复传递相同目录
|
||||||
|
return list(dict.fromkeys(wheels_dirs))
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def pip_install_with_fallback(requirements_file: Path) -> Tuple[bool, str]:
|
def pip_install_with_fallback(requirements_file: Path,
|
||||||
|
find_links_dirs: Optional[List[Path]] = None) -> Tuple[bool, str]:
|
||||||
"""
|
"""
|
||||||
使用自动降级策略安装依赖,并确保新安装的包可被动态导入
|
使用自动降级策略安装依赖,并确保新安装的包可被动态导入
|
||||||
:param requirements_file: 依赖的 requirements.txt 文件路径
|
:param requirements_file: 依赖的 requirements.txt 文件路径
|
||||||
|
:param find_links_dirs: 额外的本地 wheels 目录列表
|
||||||
:return: (是否成功, 错误信息)
|
:return: (是否成功, 错误信息)
|
||||||
"""
|
"""
|
||||||
wheels_dir = requirements_file.parent / "wheels"
|
wheels_dir = requirements_file.parent / "wheels"
|
||||||
|
candidate_dirs = []
|
||||||
|
if wheels_dir.is_dir():
|
||||||
|
candidate_dirs.append(wheels_dir)
|
||||||
|
if find_links_dirs:
|
||||||
|
candidate_dirs.extend(find_links_dirs)
|
||||||
|
|
||||||
|
# 去重并保持传入顺序
|
||||||
|
resolved_dirs = []
|
||||||
|
seen_dirs = set()
|
||||||
|
for candidate_dir in candidate_dirs:
|
||||||
|
candidate_path = Path(candidate_dir)
|
||||||
|
if not candidate_path.is_dir():
|
||||||
|
continue
|
||||||
|
candidate_key = str(candidate_path.resolve())
|
||||||
|
if candidate_key in seen_dirs:
|
||||||
|
continue
|
||||||
|
seen_dirs.add(candidate_key)
|
||||||
|
resolved_dirs.append(candidate_path)
|
||||||
|
|
||||||
find_links_option = []
|
find_links_option = []
|
||||||
if wheels_dir.is_dir():
|
if resolved_dirs:
|
||||||
# 如果目录存在,增加 --find-links 选项
|
for local_wheels_dir in resolved_dirs:
|
||||||
logger.debug(f"[PIP] 发现插件内嵌的 wheels 目录: {wheels_dir},将优先从本地安装。")
|
logger.debug(f"[PIP] 发现可用的 wheels 目录: {local_wheels_dir},将优先从本地安装。")
|
||||||
find_links_option = ["--find-links", str(wheels_dir)]
|
find_links_option.extend(["--find-links", str(local_wheels_dir)])
|
||||||
else:
|
else:
|
||||||
# 如果不存在,选项为空列表,对后续命令无影响
|
logger.debug(f"[PIP] 未发现可用的 wheels 目录,将仅使用在线源。")
|
||||||
logger.debug(f"[PIP] 未发现插件内嵌的 wheels 目录,将仅使用在线源。")
|
|
||||||
|
|
||||||
base_cmd = [sys.executable, "-m", "pip", "install"] + find_links_option + ["-r", str(requirements_file)]
|
base_cmd = [sys.executable, "-m", "pip", "install"] + find_links_option + ["-r", str(requirements_file)]
|
||||||
strategies = []
|
strategies = []
|
||||||
@@ -719,7 +759,8 @@ class PluginHelper(metaclass=WeakSingleton):
|
|||||||
f.write(dep + "\n")
|
f.write(dep + "\n")
|
||||||
try:
|
try:
|
||||||
# 使用自动降级策略安装依赖
|
# 使用自动降级策略安装依赖
|
||||||
return self.pip_install_with_fallback(requirements_temp_file)
|
wheels_dirs = self.__collect_plugin_wheels_dirs()
|
||||||
|
return self.pip_install_with_fallback(requirements_temp_file, wheels_dirs)
|
||||||
finally:
|
finally:
|
||||||
# 删除临时文件
|
# 删除临时文件
|
||||||
requirements_temp_file.unlink()
|
requirements_temp_file.unlink()
|
||||||
@@ -1237,7 +1278,8 @@ class PluginHelper(metaclass=WeakSingleton):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
# 使用自动降级策略安装依赖
|
# 使用自动降级策略安装依赖
|
||||||
return self.pip_install_with_fallback(Path(requirements_temp_file))
|
wheels_dirs = self.__collect_plugin_wheels_dirs()
|
||||||
|
return self.pip_install_with_fallback(Path(requirements_temp_file), wheels_dirs)
|
||||||
finally:
|
finally:
|
||||||
# 删除临时文件
|
# 删除临时文件
|
||||||
await requirements_temp_file.unlink()
|
await requirements_temp_file.unlink()
|
||||||
|
|||||||
Reference in New Issue
Block a user