fix(async): offload file metadata checks

This commit is contained in:
InfinityPacer
2026-08-23 12:06:52 +08:00
parent 56293bc82a
commit e8cfe272c4
9 changed files with 182 additions and 12 deletions
+22 -6
View File
@@ -2,6 +2,7 @@
import json
import shutil
from pathlib import Path
from typing import Any, Optional
from app.runtime.settings import RuntimeSettingsCompat
@@ -25,6 +26,17 @@ DEFAULT_PLUGIN_CANDIDATE_LIMIT = 50
MAX_PLUGIN_CANDIDATE_LIMIT = 200
def _remove_plugin_directory(path: Path) -> bool:
"""删除插件目录并返回是否完成,供受控线程执行。"""
if not path.exists():
return False
try:
shutil.rmtree(path)
except Exception:
return False
return True
def get_plugin_snapshot(plugin_id: str) -> Optional[dict[str, Any]]:
"""
获取已安装插件的基础信息快照。
@@ -394,6 +406,7 @@ async def uninstall_plugin_runtime(plugin_id: str) -> dict[str, Any]:
from app.application.plugin.folders import remove_plugin_from_folders
from app.application.plugin.routes import remove_plugin_api
from app.application.scheduling import remove_plugin_job
from app.agent.tools.base import run_agent_blocking
plugin_manager = get_plugin_manager()
virtual_instance = plugin_manager.get_plugin_instance(plugin_id)
@@ -423,13 +436,16 @@ async def uninstall_plugin_runtime(plugin_id: str) -> dict[str, Any]:
plugin_manager.delete_plugin_config(plugin_id)
plugin_manager.delete_plugin_data(plugin_id)
plugin_base_dir = settings.ROOT_PATH / "app" / "plugins" / plugin_id.lower()
if plugin_base_dir.exists():
try:
shutil.rmtree(plugin_base_dir)
try:
clone_files_removed = await run_agent_blocking(
"plugin",
_remove_plugin_directory,
plugin_base_dir,
)
if clone_files_removed:
plugin_manager.plugins.pop(plugin_id, None)
clone_files_removed = True
except Exception:
clone_files_removed = False
except Exception:
clone_files_removed = False
remove_plugin_from_folders(plugin_id)
plugin_manager.remove_plugin(plugin_id)
+15 -2
View File
@@ -26,6 +26,12 @@ from app.domain.media import normalize_music_type
from ._music_utils import simplify_music_info
def _inspect_local_path(path: Path) -> tuple[bool, bool]:
"""返回本地路径是否存在及是否为目录。"""
exists = path.exists()
return exists and path.is_dir(), exists
class ScrapeMetadataInput(BaseModel):
"""刮削媒体元数据工具的输入参数模型"""
@@ -151,7 +157,14 @@ class ScrapeMetadataTool(MoviePilotTool):
media_id = normalized_media_id or None
local_path = Path(path)
is_local_directory = (storage or "local") == "local" and local_path.is_dir()
is_local_directory = False
path_exists = True
if (storage or "local") == "local":
is_local_directory, path_exists = await self.run_blocking(
"storage",
_inspect_local_path,
local_path,
)
file_type = "dir" if is_local_directory or not local_path.suffix else "file"
fileitem = FileItem(
storage=storage or "local",
@@ -161,7 +174,7 @@ class ScrapeMetadataTool(MoviePilotTool):
# 检查本地存储路径是否存在
if storage == "local":
if not Path(path).exists():
if not path_exists:
return json.dumps(
{"success": False, "message": f"刮削路径不存在: {path}"},
ensure_ascii=False,