fix(file-summary): 同步压缩包工作流状态与结果刷新

This commit is contained in:
2026-06-06 19:45:49 +08:00
parent daa0642142
commit 7e561ea213
12 changed files with 560 additions and 32 deletions

View File

@@ -1,5 +1,6 @@
from __future__ import annotations
import logging
import subprocess
from pathlib import Path
from zipfile import ZipFile
@@ -9,6 +10,8 @@ import py7zr
ARCHIVE_EXTENSIONS = {"zip", "7z", "rar"}
logger = logging.getLogger("review_agent.file_summary.services.archive")
def _ensure_inside_target(path: Path, target_dir: Path) -> None:
target = target_dir.resolve()
@@ -63,6 +66,51 @@ def _extract_7z(archive_path: Path, target_dir: Path) -> list[Path]:
def _extract_rar(archive_path: Path, target_dir: Path) -> list[Path]:
try:
extracted = _extract_rar_with_libarchive(archive_path, target_dir)
except Exception as exc:
logger.warning(
"RAR libarchive extract failed, falling back to 7z",
extra={"archive_path": str(archive_path), "target_dir": str(target_dir), "error": str(exc)},
)
else:
if extracted:
return extracted
logger.info(
"RAR libarchive extract produced no files, falling back to 7z",
extra={"archive_path": str(archive_path), "target_dir": str(target_dir)},
)
return _extract_rar_with_7z(archive_path, target_dir)
def _extract_rar_with_libarchive(archive_path: Path, target_dir: Path) -> list[Path]:
try:
import libarchive
except ImportError as exc:
raise RuntimeError("未安装 libarchive跳过 Python RAR 解压。") from exc
extracted: list[Path] = []
with libarchive.file_reader(str(archive_path)) as entries:
for entry in entries:
destination = _safe_member_path(target_dir, entry.pathname)
if entry.isdir:
destination.mkdir(parents=True, exist_ok=True)
continue
if not entry.isfile:
logger.info(
"RAR libarchive skipped non-regular entry",
extra={"archive_path": str(archive_path), "entry": entry.pathname},
)
continue
destination.parent.mkdir(parents=True, exist_ok=True)
with destination.open("wb") as target:
for block in entry.get_blocks():
target.write(block)
extracted.append(destination)
return extracted
def _extract_rar_with_7z(archive_path: Path, target_dir: Path) -> list[Path]:
result = subprocess.run(
["7z", "x", f"-o{target_dir}", str(archive_path), "-y"],
check=False,