mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-05-29 07:26:52 +00:00
fix: skip non-transferable monitor files
This commit is contained in:
@@ -326,6 +326,8 @@ class Monitor(ConfigReloadMixin, metaclass=SingletonClass):
|
||||
processed_count = 0
|
||||
for file_path, file_info in new_snapshot.items():
|
||||
try:
|
||||
if not self.__is_transfer_candidate_path(Path(file_path)):
|
||||
continue
|
||||
logger.info(f"处理文件:{file_path}")
|
||||
file_size = file_info.get('size', 0) if isinstance(file_info, dict) else file_info
|
||||
self.__handle_file(storage=storage, event_path=Path(file_path), file_size=file_size)
|
||||
@@ -417,6 +419,40 @@ class Monitor(ConfigReloadMixin, metaclass=SingletonClass):
|
||||
|
||||
return changes
|
||||
|
||||
@staticmethod
|
||||
def __is_bluray_sub(_path: Path) -> bool:
|
||||
"""
|
||||
判断是否蓝光原盘目录内的媒体流文件。
|
||||
"""
|
||||
return True if re.search(r"BDMV[/\\]STREAM", _path.as_posix(), re.IGNORECASE) else False
|
||||
|
||||
@staticmethod
|
||||
def __get_bluray_dir(_path: Path) -> Optional[Path]:
|
||||
"""
|
||||
获取蓝光原盘BDMV目录的上级目录。
|
||||
"""
|
||||
for p in _path.parents:
|
||||
if p.name == "BDMV":
|
||||
return p.parent
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def __has_suffix_in(file_path: Path, extensions: List[str]) -> bool:
|
||||
"""
|
||||
判断路径后缀是否命中给定扩展名列表。
|
||||
"""
|
||||
if not file_path.suffix:
|
||||
return False
|
||||
return file_path.suffix.casefold() in {ext.casefold() for ext in extensions}
|
||||
|
||||
def __is_transfer_candidate_path(self, file_path: Path) -> bool:
|
||||
"""
|
||||
判断监控事件路径是否需要进入整理链。
|
||||
"""
|
||||
if self.__has_suffix_in(file_path, settings.DOWNLOAD_TMPEXT):
|
||||
return False
|
||||
return self.__has_suffix_in(file_path, self.all_exts)
|
||||
|
||||
@staticmethod
|
||||
def count_directory_files(directory: Path, max_check: int = 10000) -> int:
|
||||
"""
|
||||
@@ -713,24 +749,34 @@ class Monitor(ConfigReloadMixin, metaclass=SingletonClass):
|
||||
if not is_first_snapshot:
|
||||
# 比较快照找出变化
|
||||
changes = self.compare_snapshots(old_snapshot, new_snapshot)
|
||||
added_files = [
|
||||
file_path
|
||||
for file_path in changes['added']
|
||||
if self.__is_transfer_candidate_path(Path(file_path))
|
||||
]
|
||||
modified_files = [
|
||||
file_path
|
||||
for file_path in changes['modified']
|
||||
if self.__is_transfer_candidate_path(Path(file_path))
|
||||
]
|
||||
|
||||
# 处理新增文件
|
||||
for new_file in changes['added']:
|
||||
for new_file in added_files:
|
||||
logger.info(f"发现新增文件:{new_file}")
|
||||
file_info = new_snapshot.get(new_file, {})
|
||||
file_size = file_info.get('size', 0) if isinstance(file_info, dict) else file_info
|
||||
self.__handle_file(storage=storage, event_path=Path(new_file), file_size=file_size)
|
||||
|
||||
# 处理修改文件
|
||||
for modified_file in changes['modified']:
|
||||
for modified_file in modified_files:
|
||||
logger.info(f"发现修改文件:{modified_file}")
|
||||
file_info = new_snapshot.get(modified_file, {})
|
||||
file_size = file_info.get('size', 0) if isinstance(file_info, dict) else file_info
|
||||
self.__handle_file(storage=storage, event_path=Path(modified_file), file_size=file_size)
|
||||
|
||||
if changes['added'] or changes['modified']:
|
||||
if added_files or modified_files:
|
||||
logger.info(
|
||||
f"{storage} 发现 {len(changes['added'])} 个新增文件,{len(changes['modified'])} 个修改文件")
|
||||
f"{storage} 发现 {len(added_files)} 个新增文件,{len(modified_files)} 个修改文件")
|
||||
else:
|
||||
logger.debug(f"{storage} 无文件变化")
|
||||
else:
|
||||
@@ -765,6 +811,8 @@ class Monitor(ConfigReloadMixin, metaclass=SingletonClass):
|
||||
:param file_size: 文件大小
|
||||
"""
|
||||
if not event.is_directory:
|
||||
if not self.__is_transfer_candidate_path(Path(event_path)):
|
||||
return
|
||||
# 文件发生变化
|
||||
logger.debug(f"检测到文件变化: {event_path} [{text}]")
|
||||
# 整理文件
|
||||
@@ -777,31 +825,17 @@ class Monitor(ConfigReloadMixin, metaclass=SingletonClass):
|
||||
:param event_path: 事件文件路径
|
||||
:param file_size: 文件大小
|
||||
"""
|
||||
|
||||
def __is_bluray_sub(_path: Path) -> bool:
|
||||
"""
|
||||
判断是否蓝光原盘目录内的子目录或文件
|
||||
"""
|
||||
return True if re.search(r"BDMV/STREAM", _path.as_posix(), re.IGNORECASE) else False
|
||||
|
||||
def __get_bluray_dir(_path: Path) -> Optional[Path]:
|
||||
"""
|
||||
获取蓝光原盘BDMV目录的上级目录
|
||||
"""
|
||||
for p in _path.parents:
|
||||
if p.name == "BDMV":
|
||||
return p.parent
|
||||
return None
|
||||
|
||||
# 全程加锁
|
||||
with lock:
|
||||
is_bluray_folder = False
|
||||
# 蓝光原盘文件处理
|
||||
if __is_bluray_sub(event_path):
|
||||
event_path = __get_bluray_dir(event_path)
|
||||
if self.__is_bluray_sub(event_path):
|
||||
event_path = self.__get_bluray_dir(event_path)
|
||||
if not event_path:
|
||||
return
|
||||
is_bluray_folder = True
|
||||
elif not self.__is_transfer_candidate_path(event_path):
|
||||
return
|
||||
|
||||
# TTL缓存控重
|
||||
if self._cache.get(str(event_path)):
|
||||
|
||||
@@ -94,6 +94,7 @@ class MonitorWatchfilesEventTest(unittest.TestCase):
|
||||
文件事件应继续按 local 存储交给整理流程。
|
||||
"""
|
||||
monitor = object.__new__(Monitor)
|
||||
monitor.all_exts = [".mkv"]
|
||||
handle_file = MagicMock()
|
||||
setattr(monitor, "_Monitor__handle_file", handle_file)
|
||||
event_path = Path("/downloads/movie.mkv")
|
||||
@@ -121,6 +122,7 @@ class MonitorWatchfilesEventTest(unittest.TestCase):
|
||||
目录事件不应进入文件整理流程。
|
||||
"""
|
||||
monitor = object.__new__(Monitor)
|
||||
monitor.all_exts = [".mkv"]
|
||||
handle_file = MagicMock()
|
||||
setattr(monitor, "_Monitor__handle_file", handle_file)
|
||||
event_path = Path("/downloads/folder")
|
||||
@@ -137,3 +139,51 @@ class MonitorWatchfilesEventTest(unittest.TestCase):
|
||||
)
|
||||
|
||||
handle_file.assert_not_called()
|
||||
|
||||
def test_event_handler_ignores_download_temp_files(self):
|
||||
"""
|
||||
下载器临时文件不应进入整理流程。
|
||||
"""
|
||||
monitor = object.__new__(Monitor)
|
||||
monitor.all_exts = [".mkv"]
|
||||
handle_file = MagicMock()
|
||||
setattr(monitor, "_Monitor__handle_file", handle_file)
|
||||
event_path = Path("/downloads/movie.mkv.!qB")
|
||||
event = DirectoryChangeEvent(
|
||||
change_type=Change.modified,
|
||||
src_path=event_path.as_posix(),
|
||||
is_directory=False
|
||||
)
|
||||
|
||||
monitor.event_handler(
|
||||
event=event,
|
||||
text="修改",
|
||||
event_path=event_path.as_posix(),
|
||||
file_size=1024
|
||||
)
|
||||
|
||||
handle_file.assert_not_called()
|
||||
|
||||
def test_event_handler_ignores_non_transferable_files(self):
|
||||
"""
|
||||
非可整理后缀文件不应进入整理流程。
|
||||
"""
|
||||
monitor = object.__new__(Monitor)
|
||||
monitor.all_exts = [".mkv"]
|
||||
handle_file = MagicMock()
|
||||
setattr(monitor, "_Monitor__handle_file", handle_file)
|
||||
event_path = Path("/downloads/movie.nfo")
|
||||
event = DirectoryChangeEvent(
|
||||
change_type=Change.added,
|
||||
src_path=event_path.as_posix(),
|
||||
is_directory=False
|
||||
)
|
||||
|
||||
monitor.event_handler(
|
||||
event=event,
|
||||
text="新增",
|
||||
event_path=event_path.as_posix(),
|
||||
file_size=1024
|
||||
)
|
||||
|
||||
handle_file.assert_not_called()
|
||||
|
||||
Reference in New Issue
Block a user