From 27d2d01a204f65b94e6edfe84edbe6ed8b28dc0c Mon Sep 17 00:00:00 2001 From: jxxghp Date: Sat, 9 Mar 2024 18:52:27 +0800 Subject: [PATCH] =?UTF-8?q?feat=EF=BC=9A=E4=B8=8B=E8=BD=BD=E5=99=A8?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=A4=9A=E9=80=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/endpoints/dashboard.py | 22 ++++++------ app/chain/__init__.py | 48 +++++++++++++++++--------- app/chain/dashboard.py | 2 +- app/modules/qbittorrent/__init__.py | 49 +++++++++++++++++++-------- app/modules/transmission/__init__.py | 50 ++++++++++++++++++++-------- 5 files changed, 116 insertions(+), 55 deletions(-) diff --git a/app/api/endpoints/dashboard.py b/app/api/endpoints/dashboard.py index ce437d37..eea76337 100644 --- a/app/api/endpoints/dashboard.py +++ b/app/api/endpoints/dashboard.py @@ -75,18 +75,16 @@ def downloader(_: schemas.TokenPayload = Depends(verify_token)) -> Any: """ 查询下载器信息 """ - transfer_info = DashboardChain().downloader_info() - free_space = SystemUtils.free_space(settings.SAVE_PATH) - if transfer_info: - return schemas.DownloaderInfo( - download_speed=transfer_info.download_speed, - upload_speed=transfer_info.upload_speed, - download_size=transfer_info.download_size, - upload_size=transfer_info.upload_size, - free_space=free_space - ) - else: - return schemas.DownloaderInfo() + downloader_info = schemas.DownloaderInfo() + transfer_infos = DashboardChain().downloader_info() + if transfer_infos: + for transfer_info in transfer_infos: + downloader_info.download_speed += transfer_info.download_speed + downloader_info.upload_speed += transfer_info.upload_speed + downloader_info.download_size += transfer_info.download_size + downloader_info.upload_size += transfer_info.upload_size + downloader_info.free_space = SystemUtils.free_space(settings.SAVE_PATH) + return downloader_info @router.get("/downloader2", summary="下载器信息(API_TOKEN)", response_model=schemas.DownloaderInfo) diff --git a/app/chain/__init__.py b/app/chain/__init__.py index 7f19a65a..50b0b4c6 100644 --- a/app/chain/__init__.py +++ b/app/chain/__init__.py @@ -282,7 +282,8 @@ class ChainBase(metaclass=ABCMeta): mediainfo=mediainfo) def download(self, content: Union[Path, str], download_dir: Path, cookie: str, - episodes: Set[int] = None, category: str = None + episodes: Set[int] = None, category: str = None, + downloader: str = settings.DEFAULT_DOWNLOADER ) -> Optional[Tuple[Optional[str], str]]: """ 根据种子文件,选择并添加下载任务 @@ -291,10 +292,12 @@ class ChainBase(metaclass=ABCMeta): :param cookie: cookie :param episodes: 需要下载的集数 :param category: 种子分类 + :param downloader: 下载器 :return: 种子Hash,错误信息 """ return self.run_module("download", content=content, download_dir=download_dir, - cookie=cookie, episodes=episodes, category=category) + cookie=cookie, episodes=episodes, category=category, + downloader=downloader) def download_added(self, context: Context, download_dir: Path, torrent_path: Path = None) -> None: """ @@ -308,18 +311,22 @@ class ChainBase(metaclass=ABCMeta): download_dir=download_dir) def list_torrents(self, status: TorrentStatus = None, - hashs: Union[list, str] = None) -> Optional[List[Union[TransferTorrent, DownloadingTorrent]]]: + hashs: Union[list, str] = None, + downloader: str = settings.DEFAULT_DOWNLOADER + ) -> Optional[List[Union[TransferTorrent, DownloadingTorrent]]]: """ 获取下载器种子列表 :param status: 种子状态 :param hashs: 种子Hash + :param downloader: 下载器 :return: 下载器中符合状态的种子列表 """ - return self.run_module("list_torrents", status=status, hashs=hashs) + return self.run_module("list_torrents", status=status, hashs=hashs, downloader=downloader) def transfer(self, path: Path, meta: MetaBase, mediainfo: MediaInfo, transfer_type: str, target: Path = None, - episodes_info: List[TmdbEpisode] = None) -> Optional[TransferInfo]: + episodes_info: List[TmdbEpisode] = None, + downloader: str = settings.DEFAULT_DOWNLOADER) -> Optional[TransferInfo]: """ 文件转移 :param path: 文件路径 @@ -328,52 +335,61 @@ class ChainBase(metaclass=ABCMeta): :param transfer_type: 转移模式 :param target: 转移目标路径 :param episodes_info: 当前季的全部集信息 + :param downloader: 下载器 :return: {path, target_path, message} """ return self.run_module("transfer", path=path, meta=meta, mediainfo=mediainfo, transfer_type=transfer_type, target=target, - episodes_info=episodes_info) + episodes_info=episodes_info, downloader=downloader) - def transfer_completed(self, hashs: Union[str, list], path: Path = None) -> None: + def transfer_completed(self, hashs: Union[str, list], path: Path = None, + downloader: str = settings.DEFAULT_DOWNLOADER) -> None: """ 转移完成后的处理 :param hashs: 种子Hash :param path: 源目录 + :param downloader: 下载器 """ - return self.run_module("transfer_completed", hashs=hashs, path=path) + return self.run_module("transfer_completed", hashs=hashs, path=path, downloader=downloader) - def remove_torrents(self, hashs: Union[str, list], delete_file: bool = True) -> bool: + def remove_torrents(self, hashs: Union[str, list], delete_file: bool = True, + downloader: str = settings.DEFAULT_DOWNLOADER) -> bool: """ 删除下载器种子 :param hashs: 种子Hash :param delete_file: 是否删除文件 + :param downloader: 下载器 :return: bool """ - return self.run_module("remove_torrents", hashs=hashs, delete_file=delete_file) + return self.run_module("remove_torrents", hashs=hashs, delete_file=delete_file, downloader=downloader) - def start_torrents(self, hashs: Union[list, str]) -> bool: + def start_torrents(self, hashs: Union[list, str], downloader: str = settings.DEFAULT_DOWNLOADER) -> bool: """ 开始下载 :param hashs: 种子Hash + :param downloader: 下载器 :return: bool """ - return self.run_module("start_torrents", hashs=hashs) + return self.run_module("start_torrents", hashs=hashs, downloader=downloader) - def stop_torrents(self, hashs: Union[list, str]) -> bool: + def stop_torrents(self, hashs: Union[list, str], downloader: str = settings.DEFAULT_DOWNLOADER) -> bool: """ 停止下载 :param hashs: 种子Hash + :param downloader: 下载器 :return: bool """ - return self.run_module("stop_torrents", hashs=hashs) + return self.run_module("stop_torrents", hashs=hashs, downloader=downloader) - def torrent_files(self, tid: str) -> Optional[Union[TorrentFilesList, List[File]]]: + def torrent_files(self, tid: str, + downloader: str = settings.DEFAULT_DOWNLOADER) -> Optional[Union[TorrentFilesList, List[File]]]: """ 获取种子文件 :param tid: 种子Hash + :param downloader: 下载器 :return: 种子文件 """ - return self.run_module("torrent_files", tid=tid) + return self.run_module("torrent_files", tid=tid, downloader=downloader) def media_exists(self, mediainfo: MediaInfo, itemid: str = None) -> Optional[ExistMediaInfo]: """ diff --git a/app/chain/dashboard.py b/app/chain/dashboard.py index 35258a90..033c0f03 100644 --- a/app/chain/dashboard.py +++ b/app/chain/dashboard.py @@ -15,7 +15,7 @@ class DashboardChain(ChainBase, metaclass=Singleton): """ return self.run_module("media_statistic") - def downloader_info(self) -> schemas.DownloaderInfo: + def downloader_info(self) -> Optional[List[schemas.DownloaderInfo]]: """ 下载器信息 """ diff --git a/app/modules/qbittorrent/__init__.py b/app/modules/qbittorrent/__init__.py index a0d07fd7..17471b5b 100644 --- a/app/modules/qbittorrent/__init__.py +++ b/app/modules/qbittorrent/__init__.py @@ -48,7 +48,8 @@ class QbittorrentModule(_ModuleBase): self.qbittorrent.reconnect() def download(self, content: Union[Path, str], download_dir: Path, cookie: str, - episodes: Set[int] = None, category: str = None) -> Optional[Tuple[Optional[str], str]]: + episodes: Set[int] = None, category: str = None, + downloader: str = settings.DEFAULT_DOWNLOADER) -> Optional[Tuple[Optional[str], str]]: """ 根据种子文件,选择并添加下载任务 :param content: 种子文件地址或者磁力链接 @@ -56,6 +57,7 @@ class QbittorrentModule(_ModuleBase): :param cookie: cookie :param episodes: 需要下载的集数 :param category: 分类 + :param downloader: 下载器 :return: 种子Hash,错误信息 """ @@ -74,7 +76,7 @@ class QbittorrentModule(_ModuleBase): return "", 0 # 不是默认下载器不处理 - if settings.DEFAULT_DOWNLOADER != "qbittorrent": + if downloader != "qbittorrent": return None if not content: @@ -165,13 +167,18 @@ class QbittorrentModule(_ModuleBase): return torrent_hash, "添加下载成功" def list_torrents(self, status: TorrentStatus = None, - hashs: Union[list, str] = None) -> Optional[List[Union[TransferTorrent, DownloadingTorrent]]]: + hashs: Union[list, str] = None, + downloader: str = settings.DEFAULT_DOWNLOADER + ) -> Optional[List[Union[TransferTorrent, DownloadingTorrent]]]: """ 获取下载器种子列表 :param status: 种子状态 :param hashs: 种子Hash + :param downloader: 下载器 :return: 下载器中符合状态的种子列表 """ + if downloader != "qbittorrent": + return None ret_torrents = [] if hashs: # 按Hash获取 @@ -231,13 +238,16 @@ class QbittorrentModule(_ModuleBase): return None return ret_torrents - def transfer_completed(self, hashs: Union[str, list], - path: Path = None) -> None: + def transfer_completed(self, hashs: Union[str, list], path: Path = None, + downloader: str = settings.DEFAULT_DOWNLOADER) -> None: """ 转移完成后的处理 :param hashs: 种子Hash :param path: 源目录 + :param downloader: 下载器 """ + if downloader != "qbittorrent": + return self.qbittorrent.set_torrents_tag(ids=hashs, tags=['已整理']) # 移动模式删除种子 if settings.TRANSFER_TYPE == "move": @@ -250,48 +260,61 @@ class QbittorrentModule(_ModuleBase): logger.warn(f"删除残留文件夹:{path}") shutil.rmtree(path, ignore_errors=True) - def remove_torrents(self, hashs: Union[str, list], delete_file: bool = True) -> bool: + def remove_torrents(self, hashs: Union[str, list], delete_file: bool = True, + downloader: str = settings.DEFAULT_DOWNLOADER) -> Optional[bool]: """ 删除下载器种子 :param hashs: 种子Hash :param delete_file: 是否删除文件 + :param downloader: 下载器 :return: bool """ + if downloader != "qbittorrent": + return None return self.qbittorrent.delete_torrents(delete_file=delete_file, ids=hashs) - def start_torrents(self, hashs: Union[list, str]) -> bool: + def start_torrents(self, hashs: Union[list, str], + downloader: str = settings.DEFAULT_DOWNLOADER) -> Optional[bool]: """ 开始下载 :param hashs: 种子Hash + :param downloader: 下载器 :return: bool """ + if downloader != "qbittorrent": + return None return self.qbittorrent.start_torrents(ids=hashs) - def stop_torrents(self, hashs: Union[list, str]) -> bool: + def stop_torrents(self, hashs: Union[list, str], downloader: str = settings.DEFAULT_DOWNLOADER) -> Optional[bool]: """ 停止下载 :param hashs: 种子Hash + :param downloader: 下载器 :return: bool """ + if downloader != "qbittorrent": + return None return self.qbittorrent.stop_torrents(ids=hashs) - def torrent_files(self, tid: str) -> Optional[TorrentFilesList]: + def torrent_files(self, tid: str, downloader: str = settings.DEFAULT_DOWNLOADER) -> Optional[TorrentFilesList]: """ 获取种子文件列表 """ + if downloader != "qbittorrent": + return None return self.qbittorrent.get_files(tid=tid) - def downloader_info(self) -> schemas.DownloaderInfo: + def downloader_info(self) -> [schemas.DownloaderInfo]: """ 下载器信息 """ # 调用Qbittorrent API查询实时信息 info = self.qbittorrent.transfer_info() if not info: - return schemas.DownloaderInfo() - return schemas.DownloaderInfo( + return [schemas.DownloaderInfo()] + return [schemas.DownloaderInfo( download_speed=info.get("dl_info_speed"), upload_speed=info.get("up_info_speed"), download_size=info.get("dl_info_data"), upload_size=info.get("up_info_data") - ) + )] diff --git a/app/modules/transmission/__init__.py b/app/modules/transmission/__init__.py index 6dfe7fbc..34b2f58f 100644 --- a/app/modules/transmission/__init__.py +++ b/app/modules/transmission/__init__.py @@ -48,7 +48,8 @@ class TransmissionModule(_ModuleBase): self.transmission.reconnect() def download(self, content: Union[Path, str], download_dir: Path, cookie: str, - episodes: Set[int] = None, category: str = None) -> Optional[Tuple[Optional[str], str]]: + episodes: Set[int] = None, category: str = None, + downloader: str = settings.DEFAULT_DOWNLOADER) -> Optional[Tuple[Optional[str], str]]: """ 根据种子文件,选择并添加下载任务 :param content: 种子文件地址或者磁力链接 @@ -56,6 +57,7 @@ class TransmissionModule(_ModuleBase): :param cookie: cookie :param episodes: 需要下载的集数 :param category: 分类,TR中未使用 + :param downloader: 下载器 :return: 种子Hash """ @@ -74,7 +76,7 @@ class TransmissionModule(_ModuleBase): return "", 0 # 不是默认下载器不处理 - if settings.DEFAULT_DOWNLOADER != "transmission": + if downloader != "transmission": return None if not content: @@ -158,13 +160,18 @@ class TransmissionModule(_ModuleBase): return torrent_hash, "添加下载任务成功" def list_torrents(self, status: TorrentStatus = None, - hashs: Union[list, str] = None) -> Optional[List[Union[TransferTorrent, DownloadingTorrent]]]: + hashs: Union[list, str] = None, + downloader: str = settings.DEFAULT_DOWNLOADER + ) -> Optional[List[Union[TransferTorrent, DownloadingTorrent]]]: """ 获取下载器种子列表 :param status: 种子状态 :param hashs: 种子Hash + :param downloader: 下载器 :return: 下载器中符合状态的种子列表 """ + if downloader != "transmission": + return None ret_torrents = [] if hashs: # 按Hash获取 @@ -219,14 +226,17 @@ class TransmissionModule(_ModuleBase): return None return ret_torrents - def transfer_completed(self, hashs: Union[str, list], - path: Path = None) -> None: + def transfer_completed(self, hashs: Union[str, list], path: Path = None, + downloader: str = settings.DEFAULT_DOWNLOADER) -> None: """ 转移完成后的处理 :param hashs: 种子Hash :param path: 源目录 + :param downloader: 下载器 :return: None """ + if downloader != "transmission": + return None self.transmission.set_torrent_tag(ids=hashs, tags=['已整理']) # 移动模式删除种子 if settings.TRANSFER_TYPE == "move": @@ -239,47 +249,61 @@ class TransmissionModule(_ModuleBase): logger.warn(f"删除残留文件夹:{path}") shutil.rmtree(path, ignore_errors=True) - def remove_torrents(self, hashs: Union[str, list], delete_file: bool = True) -> bool: + def remove_torrents(self, hashs: Union[str, list], delete_file: bool = True, + downloader: str = settings.DEFAULT_DOWNLOADER) -> Optional[bool]: """ 删除下载器种子 :param hashs: 种子Hash :param delete_file: 是否删除文件 + :param downloader: 下载器 :return: bool """ + if downloader != "transmission": + return None return self.transmission.delete_torrents(delete_file=delete_file, ids=hashs) - def start_torrents(self, hashs: Union[list, str]) -> bool: + def start_torrents(self, hashs: Union[list, str], + downloader: str = settings.DEFAULT_DOWNLOADER) -> Optional[bool]: """ 开始下载 :param hashs: 种子Hash + :param downloader: 下载器 :return: bool """ + if downloader != "transmission": + return None return self.transmission.start_torrents(ids=hashs) - def stop_torrents(self, hashs: Union[list, str]) -> bool: + def stop_torrents(self, hashs: Union[list, str], + downloader: str = settings.DEFAULT_DOWNLOADER) -> Optional[bool]: """ 停止下载 :param hashs: 种子Hash + :param downloader: 下载器 :return: bool """ + if downloader != "transmission": + return None return self.transmission.start_torrents(ids=hashs) - def torrent_files(self, tid: str) -> Optional[List[File]]: + def torrent_files(self, tid: str, downloader: str = settings.DEFAULT_DOWNLOADER) -> Optional[List[File]]: """ 获取种子文件列表 """ + if downloader != "transmission": + return None return self.transmission.get_files(tid=tid) - def downloader_info(self) -> schemas.DownloaderInfo: + def downloader_info(self) -> [schemas.DownloaderInfo]: """ 下载器信息 """ info = self.transmission.transfer_info() if not info: - return schemas.DownloaderInfo() - return schemas.DownloaderInfo( + return [schemas.DownloaderInfo()] + return [schemas.DownloaderInfo( download_speed=info.download_speed, upload_speed=info.upload_speed, download_size=info.current_stats.downloaded_bytes, upload_size=info.current_stats.uploaded_bytes - ) + )]