Update analysis and plan files to enhance duplicate handling and reporting

- Updated `analysis.json` with a new generation timestamp.
- Modified `plan.json` to include a new plan ID and created timestamp, and changed operation types from "no-op" to "quarantine" for specific files needing manual review.
- Enhanced the README.md to document the new `--analysis` option for generating execution plans, which now includes a human-readable summary and duplicate handling strategies.
- Introduced a new `duplicate_resolve.py` module to manage duplicate file resolution strategies.
- Improved the execution engine to support quarantine operations and added rollback functionality for quarantined files.

These changes improve the functionality of the Video Library Manager by providing better duplicate management and clearer reporting capabilities.
This commit is contained in:
windyboy
2026-02-10 18:07:38 +08:00
parent dcd87754cf
commit 79f5ddf1f5
14 changed files with 882 additions and 456 deletions
+41
View File
@@ -10,6 +10,7 @@ from uuid import uuid4
import pytest
from vlm.config import Config
from vlm.executor import ExecutionEngine
from vlm.models import ExecutionPlan, FileOperation
@@ -904,3 +905,43 @@ class TestRollbackExecution:
actual_failed = sum(1 for r in rollback_results if not r.success)
assert rollback_summary["successful"] == actual_success
assert rollback_summary["failed"] == actual_failed
def test_rollback_quarantine_operation(self, tmp_path):
"""Test that rollback restores quarantined files via QuarantineManager."""
library_root = tmp_path / "library"
library_root.mkdir()
(library_root / "movie").mkdir()
config = Config(library_root=library_root, quarantine_dir=".quarantine")
engine = ExecutionEngine(logger=logging.getLogger("test_executor"), config=config)
original_path = library_root / "movie" / "Duplicate (2020).mkv"
original_path.write_text("movie content")
plan = ExecutionPlan(
plan_id=str(uuid4()),
created_at=datetime.now(),
operations=[
FileOperation(
operation_type="quarantine",
source_path=original_path,
destination_path=None,
reason="duplicate",
has_conflict=False,
conflict_reason=None,
),
],
summary={"quarantine": 1},
)
results, _, rollback_log = engine.execute_plan(plan, mode="execute", confirmed=True)
assert results[0].success
assert not original_path.exists()
quarantine_path = config.library_root / "movie" / ".quarantine" / "Duplicate (2020).mkv"
assert quarantine_path.exists()
rollback_results, rollback_summary = engine.rollback(rollback_log)
assert rollback_summary["successful"] == 1
assert rollback_summary["failed"] == 0
assert original_path.exists()
assert original_path.read_text() == "movie content"
assert not quarantine_path.exists()