From 16bd71a6cbf82f0ac74c0daa9be27891dc18066a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=99=AF=E5=A4=A7=E4=BE=A0?= Date: Tue, 20 Jan 2026 13:33:51 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=95=B4=E7=90=86=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E6=95=88=E7=8E=87=E3=80=81=E5=87=8F=E5=B0=91=E9=A2=9D?= =?UTF-8?q?=E5=A4=96=E9=80=92=E5=BD=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/chain/storage.py | 8 ++--- app/chain/transfer.py | 74 ++++++++++++++++--------------------------- tests/cases/files.py | 1 + tests/test_bluray.py | 3 +- 4 files changed, 35 insertions(+), 51 deletions(-) diff --git a/app/chain/storage.py b/app/chain/storage.py index 86d339d5..3461e7cd 100644 --- a/app/chain/storage.py +++ b/app/chain/storage.py @@ -151,10 +151,10 @@ class StorageChain(ChainBase): 判断是否包含蓝光必备的文件夹 """ required_files = ("BDMV", "CERTIFICATE") - for item in fileitems or []: - if item.type == "dir" and item.name in required_files: - return True - return False + return any( + item.type == "dir" and item.name in required_files + for item in fileitems or [] + ) def delete_media_file(self, fileitem: schemas.FileItem, delete_self: bool = True) -> bool: """ diff --git a/app/chain/transfer.py b/app/chain/transfer.py index c4f46dc5..bdddbf12 100755 --- a/app/chain/transfer.py +++ b/app/chain/transfer.py @@ -895,13 +895,13 @@ class TransferChain(ChainBase, metaclass=Singleton): return True def __get_trans_fileitems( - self, fileitem: FileItem, depth: int = 1 + self, fileitem: FileItem, check: bool = True ) -> List[Tuple[FileItem, bool]]: """ 获取整理目录或文件列表 :param fileitem: 文件项 - :param depth: 递归深度,默认为1 + :param check: 检查文件是否存在,默认为True """ storagechain = StorageChain() @@ -920,44 +920,40 @@ class TransferChain(ChainBase, metaclass=Singleton): return storagechain.get_file_item(storage=_storage, path=p.parent) return None - latest_fileitem = storagechain.get_item(fileitem) - if not latest_fileitem: - logger.warn(f"目录或文件不存在:{fileitem.path}") - return [] - # 确保从历史记录重新整理时 能获得最新的源文件大小、修改日期等 - fileitem = latest_fileitem + if check: + latest_fileitem = storagechain.get_item(fileitem) + if not latest_fileitem: + logger.warn(f"目录或文件不存在:{fileitem.path}") + return [] + # 确保从历史记录重新整理时 能获得最新的源文件大小、修改日期等 + fileitem = latest_fileitem - # 蓝光原盘子目录或文件 + # 是否蓝光原盘子目录或文件 if __is_bluray_sub(fileitem.path): - dir_item = __get_bluray_dir(fileitem.storage, Path(fileitem.path)) - if dir_item: + if dir_item := __get_bluray_dir(fileitem.storage, Path(fileitem.path)): + # 返回该文件所在的原盘根目录 return [(dir_item, True)] # 单文件 if fileitem.type == "file": return [(fileitem, False)] - # 蓝光原盘根目录 - sub_items = storagechain.list_files(fileitem) or [] + # 是否蓝光原盘根目录 + sub_items = storagechain.list_files(fileitem, recursion=False) or [] if storagechain.contains_bluray_subdirectories(sub_items): + # 当前目录是原盘根目录,不需要递归 return [(fileitem, True)] - # 需要整理的文件项列表 - trans_items = [] - # 先检查当前目录的下级目录,以支持合集的情况 - for sub_dir in sub_items if depth >= 1 else []: - if sub_dir.type == "dir": - trans_items.extend(self.__get_trans_fileitems(sub_dir, depth=depth - 1)) - - if not trans_items: - # 没有有效子目录,直接整理当前目录 - trans_items.append((fileitem, False)) - else: - # 有子目录时,把当前目录的文件添加到整理任务中 - if sub_items: - trans_items.extend([(f, False) for f in sub_items if f.type == "file"]) - - return trans_items + # 不是原盘根目录 递归获取目录内需要整理的文件项列表 + return [ + item + for sub_item in sub_items + for item in ( + self.__get_trans_fileitems(sub_item, check=False) + if sub_item.type == "dir" + else [(sub_item, False)] + ) + ] def do_transfer(self, fileitem: FileItem, meta: MetaBase = None, mediainfo: MediaInfo = None, @@ -1024,27 +1020,13 @@ class TransferChain(ChainBase, metaclass=Singleton): transfer_exclude_words = SystemConfigOper().get(SystemConfigKey.TransferExcludeWords) # 汇总错误信息 err_msgs: List[str] = [] - # 待整理目录或文件项 - trans_items = self.__get_trans_fileitems( - fileitem, depth=2 # 为解决 issue#4371 深度至少需要>=2 - ) - # 待整理的文件列表 - file_items: List[Tuple[FileItem, bool]] = [] + # 递归获取待整理的文件/目录列表 + file_items = self.__get_trans_fileitems(fileitem) - if not trans_items: + if not file_items: logger.warn(f"{fileitem.path} 没有找到可整理的媒体文件") return False, f"{fileitem.name} 没有找到可整理的媒体文件" - # 转换为所有待处理的文件清单 - for trans_item, bluray_dir in trans_items: - # 如果是目录且不是⼀蓝光原盘,获取所有文件并整理 - if trans_item.type == "dir" and not bluray_dir: - # 遍历获取下载目录所有文件(递归) - if files := StorageChain().list_files(trans_item, recursion=True): - file_items.extend([(file, False) for file in files]) - else: - file_items.append((trans_item, bluray_dir)) - # 有集自定义格式,过滤文件 if formaterHandler: file_items = [f for f in file_items if formaterHandler.match(f[0].name)] diff --git a/tests/cases/files.py b/tests/cases/files.py index 9f2ec84b..c9c0cd6c 100644 --- a/tests/cases/files.py +++ b/tests/cases/files.py @@ -94,6 +94,7 @@ bluray_files = [ ("Pokemon.2029.mp4", 104857600), ("Pokemon.2039.mp4", 104857600), ("Pokemon (2030)", [("S", 104857600)]), + ("Pokemon (2031)", [("Pokemon (2031).mp4", 104857600)]), ], ) ] diff --git a/tests/test_bluray.py b/tests/test_bluray.py index 5f8f9a7e..225c911b 100644 --- a/tests/test_bluray.py +++ b/tests/test_bluray.py @@ -126,8 +126,9 @@ class BluRayTest(TestCase): "/FOLDER/Pokemon (2028)/Pokemon.2028.mkv", "/FOLDER/Pokemon.2029.mp4", "/FOLDER/Pokemon.2039.mp4", + "/FOLDER/Pokemon (2031)/Pokemon (2031).mp4", ], - __test_do_transfer("/FOLDER"), + __test_do_transfer("/"), ) def _test_scrape_metadata(self, mock_metadata_nfo):