Files
MoviePilot/moviepilot_snapshot_fix.md
2025-07-05 07:19:53 +00:00

3.5 KiB
Raw Blame History

MoviePilot 文件整理快照处理问题修复

问题描述

MoviePilot 在版本 2.6.1 中存在一个严重的文件整理问题:

  1. 症状: 待整理的文件一直没有被处理,即使是新加入的文件或对已存在文件重命名后仍无法触发整理
  2. 日志表现: 频繁出现 "首次快照仅建立基准,不会处理现有文件" 的日志消息
  3. 根本原因: 快照处理逻辑存在缺陷,导致系统始终认为每次扫描都是首次快照

问题分析

问题出现在 app/monitor.pypolling_observer 方法中:

# 原始有问题的代码
if old_snapshot:  # 这里的判断逻辑有问题
    # 比较快照找出变化
    changes = self.compare_snapshots(old_snapshot, new_snapshot)
    # ... 处理变化的文件
else:
    # 首次快照,不处理文件
    logger.info("*** 首次快照仅建立基准,不会处理现有文件 ***")

问题的根本原因:

  1. old_snapshot 是从JSON文件中的 snapshot 字段提取的字典
  2. 当快照文件不存在或快照为空时,old_snapshot 为空字典 {}
  3. 在Python中空字典 {} 在布尔上下文中评估为 False
  4. 因此条件 if old_snapshot: 始终为 False,导致系统认为每次都是首次快照

修复方案

修复1: 修正首次快照判断逻辑

# 修复后的代码
# 判断是否为首次快照:检查快照文件是否存在且有效
is_first_snapshot = old_snapshot_data is None

# 使用新的判断条件
if not is_first_snapshot:
    # 比较快照找出变化
    changes = self.compare_snapshots(old_snapshot, new_snapshot)
    # ... 处理变化的文件
else:
    # 首次快照,不处理文件
    logger.info("*** 首次快照仅建立基准,不会处理现有文件 ***")

修复2: 增强调试日志

def load_snapshot(self, storage: str) -> Optional[Dict]:
    # 添加调试日志
    logger.debug(f"成功加载快照: {cache_file}, 包含 {len(data.get('snapshot', {}))} 个文件")
    logger.debug(f"快照文件不存在: {cache_file}")

修复3: 新增实用方法

  1. 重置快照方法: 允许用户手动重置快照
def reset_snapshot(self, storage: str) -> bool:
    """重置快照,强制下次扫描时重新建立基准"""
  1. 强制全量扫描方法: 允许用户处理所有现有文件
def force_full_scan(self, storage: str, mon_path: Path) -> bool:
    """强制全量扫描并处理所有文件(包括已存在的文件)"""

修复效果

修复后的系统行为:

  1. 首次运行: 创建快照基准,不处理现有文件(符合设计)
  2. 后续运行: 正确比较快照差异,处理新增和修改的文件
  3. 调试友好: 增加了详细的调试日志,便于排查问题
  4. 管理灵活: 提供了重置快照和强制全量扫描的功能

验证方法

  1. 检查日志中不再频繁出现 "首次快照仅建立基准" 消息
  2. 新增文件能够被正确检测和处理
  3. 修改文件能够被正确检测和处理
  4. 快照文件能够正确保存和加载

其他建议

  1. 如果用户想要处理现有文件,可以使用新增的 force_full_scan 方法
  2. 如果快照数据出现问题,可以使用 reset_snapshot 方法重置
  3. 建议在生产环境中先测试修复效果,确认无误后再部署

相关文件

  • 主要修复文件: app/monitor.py
  • 涉及的方法: polling_observer, save_snapshot, load_snapshot
  • 新增方法: reset_snapshot, force_full_scan