From 7218d10e1bd10288af760348ae3e76c98353e353 Mon Sep 17 00:00:00 2001 From: jxxghp Date: Mon, 26 Jan 2026 19:33:50 +0800 Subject: [PATCH] =?UTF-8?q?feat(transfer):=20=E6=8B=86=E5=88=86=E5=AD=97?= =?UTF-8?q?=E5=B9=95=E5=92=8C=E9=9F=B3=E9=A2=91=E6=95=B4=E7=90=86=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/chain/transfer.py | 75 +++++++++++++++++++++++++++++++++++------ app/schemas/transfer.py | 8 ----- app/schemas/types.py | 17 ++++++++-- 3 files changed, 79 insertions(+), 21 deletions(-) diff --git a/app/chain/transfer.py b/app/chain/transfer.py index 366a87b9..9013b6cb 100755 --- a/app/chain/transfer.py +++ b/app/chain/transfer.py @@ -417,10 +417,12 @@ class TransferChain(ChainBase, ConfigReloadMixin, metaclass=Singleton): super().__init__() # 主要媒体文件后缀 self._media_exts = settings.RMT_MEDIAEXT - # 附加文件后缀 - self._extra_exts = settings.RMT_SUBEXT + settings.RMT_AUDIOEXT + # 字幕文件后缀 + self._subtitle_exts = settings.RMT_SUBEXT + # 音频文件后缀 + self._audio_exts = settings.RMT_AUDIOEXT # 可处理的文件后缀(视频文件、字幕、音频文件) - self._allowed_exts = self._media_exts + self._extra_exts + self._allowed_exts = self._media_exts + self._audio_exts + self._subtitle_exts # 待整理任务队列 self._queue = queue.Queue() # 文件整理线程 @@ -470,21 +472,21 @@ class TransferChain(ChainBase, ConfigReloadMixin, metaclass=Singleton): self.__stop() self.__init() - def __is_allowed_file(self, fileitem: FileItem) -> bool: + def __is_subtitle_file(self, fileitem: FileItem) -> bool: """ - 判断是否允许的扩展名 + 判断是否为字幕文件 """ if not fileitem.extension: return False - return True if f".{fileitem.extension.lower()}" in self._allowed_exts else False + return True if f".{fileitem.extension.lower()}" in self._subtitle_exts else False - def __is_extra_file(self, fileitem: FileItem) -> bool: + def __is_audio_file(self, fileitem: FileItem) -> bool: """ - 判断是否额外的扩展名 + 判断是否为音频文件 """ if not fileitem.extension: return False - return True if f".{fileitem.extension.lower()}" in self._extra_exts else False + return True if f".{fileitem.extension.lower()}" in self._audio_exts else False def __is_media_file(self, fileitem: FileItem) -> bool: """ @@ -497,6 +499,14 @@ class TransferChain(ChainBase, ConfigReloadMixin, metaclass=Singleton): return False return True if f".{fileitem.extension.lower()}" in self._media_exts else False + def __is_allowed_file(self, fileitem: FileItem) -> bool: + """ + 判断是否允许的扩展名 + """ + if not fileitem.extension: + return False + return True if f".{fileitem.extension.lower()}" in self._allowed_exts else False + @staticmethod def __is_allow_filesize(fileitem: FileItem, min_filesize: int) -> bool: """ @@ -573,6 +583,7 @@ class TransferChain(ChainBase, ConfigReloadMixin, metaclass=Singleton): # 整理失败事件 if self.__is_media_file(task.fileitem): + # 主要媒体文件整理失败事件 self.eventmanager.send_event(EventType.TransferFailed, { 'fileitem': task.fileitem, 'meta': task.meta, @@ -581,6 +592,26 @@ class TransferChain(ChainBase, ConfigReloadMixin, metaclass=Singleton): 'downloader': task.downloader, 'download_hash': task.download_hash, }) + elif self.__is_subtitle_file(task.fileitem): + # 字幕整理失败事件 + self.eventmanager.send_event(EventType.SubtitleTransferFailed, { + 'fileitem': task.fileitem, + 'meta': task.meta, + 'mediainfo': task.mediainfo, + 'transferinfo': transferinfo, + 'downloader': task.downloader, + 'download_hash': task.download_hash, + }) + elif self.__is_audio_file(task.fileitem): + # 音频文件整理失败事件 + self.eventmanager.send_event(EventType.AudioTransferFailed, { + 'fileitem': task.fileitem, + 'meta': task.meta, + 'mediainfo': task.mediainfo, + 'transferinfo': transferinfo, + 'downloader': task.downloader, + 'download_hash': task.download_hash, + }) # 发送失败消息 self.post_message(Notification( @@ -616,6 +647,7 @@ class TransferChain(ChainBase, ConfigReloadMixin, metaclass=Singleton): # task整理完成事件 if self.__is_media_file(task.fileitem): + # 主要媒体文件整理完成事件 self.eventmanager.send_event(EventType.TransferComplete, { 'fileitem': task.fileitem, 'meta': task.meta, @@ -624,6 +656,26 @@ class TransferChain(ChainBase, ConfigReloadMixin, metaclass=Singleton): 'downloader': task.downloader, 'download_hash': task.download_hash, }) + elif self.__is_subtitle_file(task.fileitem): + # 字幕整理完成事件 + self.eventmanager.send_event(EventType.SubtitleTransferComplete, { + 'fileitem': task.fileitem, + 'meta': task.meta, + 'mediainfo': task.mediainfo, + 'transferinfo': transferinfo, + 'downloader': task.downloader, + 'download_hash': task.download_hash, + }) + elif self.__is_audio_file(task.fileitem): + # 音频文件整理完成事件 + self.eventmanager.send_event(EventType.AudioTransferComplete, { + 'fileitem': task.fileitem, + 'meta': task.meta, + 'mediainfo': task.mediainfo, + 'transferinfo': transferinfo, + 'downloader': task.downloader, + 'download_hash': task.download_hash, + }) # task登记转移成功文件清单 target_dir_path = transferinfo.target_diritem.path @@ -1180,8 +1232,9 @@ class TransferChain(ChainBase, ConfigReloadMixin, metaclass=Singleton): # 过滤后缀和大小(蓝光目录、附加文件不过滤大小) file_items = [f for f in file_items if f[1] or - self.__is_extra_file(f[0]) or - (self.__is_allowed_file(f[0]) and self.__is_allow_filesize(f[0], min_filesize))] + self.__is_subtitle_file(f[0]) or + self.__is_audio_file(f[0]) or + (self.__is_media_file(f[0]) and self.__is_allow_filesize(f[0], min_filesize))] if not file_items: logger.warn(f"{fileitem.path} 没有找到可整理的媒体文件") diff --git a/app/schemas/transfer.py b/app/schemas/transfer.py index b12f16c7..d4aa5404 100644 --- a/app/schemas/transfer.py +++ b/app/schemas/transfer.py @@ -124,14 +124,6 @@ class TransferInfo(BaseModel): total_size: Optional[int] = Field(default=0) # 失败清单 fail_list: Optional[list] = Field(default_factory=list) - # 处理字幕文件清单 - subtitle_list: Optional[list] = Field(default_factory=list) - # 目标字幕文件清单 - subtitle_list_new: Optional[list] = Field(default_factory=list) - # 处理音频文件清单 - audio_list: Optional[list] = Field(default_factory=list) - # 目标音频文件清单 - audio_list_new: Optional[list] = Field(default_factory=list) # 错误信息 message: Optional[str] = None # 是否需要刮削 diff --git a/app/schemas/types.py b/app/schemas/types.py index a177859b..eb19100d 100644 --- a/app/schemas/types.py +++ b/app/schemas/types.py @@ -38,10 +38,18 @@ class EventType(Enum): SiteUpdated = "site.updated" # 站点已刷新 SiteRefreshed = "site.refreshed" - # 整理完成 + # 媒体文件整理完成 TransferComplete = "transfer.complete" - # 整理失败 + # 媒体文件整理失败 TransferFailed = "transfer.failed" + # 字幕整理完成 + SubtitleTransferComplete = "transfer.subtitle.complete" + # 字幕整理失败 + SubtitleTransferFailed = "transfer.subtitle.failed" + # 音频文件整理完成 + AudioTransferComplete = "transfer.audio.complete" + # 音频文件整理失败 + AudioTransferFailed = "transfer.audio.failed" # 下载已添加 DownloadAdded = "download.added" # 删除历史记录 @@ -88,6 +96,11 @@ EVENT_TYPE_NAMES = { EventType.SiteUpdated: "站点已更新", EventType.SiteRefreshed: "站点已刷新", EventType.TransferComplete: "整理完成", + EventType.TransferFailed: "整理失败", + EventType.SubtitleTransferComplete: "字幕整理完成", + EventType.SubtitleTransferFailed: "字幕整理失败", + EventType.AudioTransferComplete: "音频整理完成", + EventType.AudioTransferFailed: "音频整理失败", EventType.DownloadAdded: "添加下载", EventType.HistoryDeleted: "删除历史记录", EventType.DownloadFileDeleted: "删除下载源文件",