From c06122ff190345e3db27e03317d6d3fbf02085d6 Mon Sep 17 00:00:00 2001 From: jxxghp Date: Tue, 13 Jun 2023 23:41:50 +0800 Subject: [PATCH] fix typing --- app/chain/__init__.py | 12 ++-- app/chain/download.py | 61 +++++++++++-------- app/chain/search.py | 3 +- app/chain/subscribe.py | 45 +++++++------- app/chain/transfer.py | 41 +++++++------ app/modules/__init__.py | 11 ++-- app/modules/emby/__init__.py | 11 ++-- app/modules/filetransfer/__init__.py | 11 ++-- app/modules/jellyfin/__init__.py | 10 +-- app/modules/plex/__init__.py | 10 +-- app/modules/qbittorrent/__init__.py | 30 ++++----- app/modules/transmission/__init__.py | 30 ++++----- app/modules/words/__init__.py | 2 - .../sitestatistic/siteuserinfo/__init__.py | 2 - app/schemas/context.py | 39 +++++++++++- 15 files changed, 186 insertions(+), 132 deletions(-) diff --git a/app/chain/__init__.py b/app/chain/__init__.py index d9f6c481..1b6f88be 100644 --- a/app/chain/__init__.py +++ b/app/chain/__init__.py @@ -10,6 +10,7 @@ from app.core.module import ModuleManager from app.core.context import MediaInfo, TorrentInfo from app.core.meta import MetaBase from app.log import logger +from app.schemas.context import TransferInfo, TransferTorrent, ExistMediaInfo from app.utils.singleton import AbstractSingleton, Singleton from app.utils.types import TorrentStatus, MediaType @@ -106,22 +107,23 @@ class ChainBase(AbstractSingleton, metaclass=Singleton): def download_added(self, context: Context, torrent_path: Path) -> None: return self.run_module("download_added", context=context, torrent_path=torrent_path) - def list_torrents(self, status: TorrentStatus = None, hashs: Union[list, str] = None) -> Optional[List[dict]]: + def list_torrents(self, status: TorrentStatus = None, + hashs: Union[list, str] = None) -> Optional[List[TransferTorrent]]: return self.run_module("list_torrents", status=status, hashs=hashs) - def transfer(self, path: str, mediainfo: MediaInfo) -> Optional[dict]: + def transfer(self, path: Path, mediainfo: MediaInfo) -> Optional[TransferInfo]: return self.run_module("transfer", path=path, mediainfo=mediainfo) - def transfer_completed(self, hashs: Union[str, list], transinfo: dict) -> None: + def transfer_completed(self, hashs: Union[str, list], transinfo: TransferInfo) -> None: return self.run_module("transfer_completed", hashs=hashs, transinfo=transinfo) def remove_torrents(self, hashs: Union[str, list]) -> bool: return self.run_module("remove_torrents", hashs=hashs) - def media_exists(self, mediainfo: MediaInfo) -> Optional[dict]: + def media_exists(self, mediainfo: MediaInfo) -> Optional[ExistMediaInfo]: return self.run_module("media_exists", mediainfo=mediainfo) - def refresh_mediaserver(self, mediainfo: MediaInfo, file_path: str) -> Optional[bool]: + def refresh_mediaserver(self, mediainfo: MediaInfo, file_path: Path) -> Optional[bool]: return self.run_module("refresh_mediaserver", mediainfo=mediainfo, file_path=file_path) def post_message(self, title: str, text: str = None, diff --git a/app/chain/download.py b/app/chain/download.py index 248c087b..755b3b8e 100644 --- a/app/chain/download.py +++ b/app/chain/download.py @@ -8,6 +8,7 @@ from app.core.meta import MetaBase from app.core.metainfo import MetaInfo from app.helper.torrent import TorrentHelper from app.log import logger +from app.schemas.context import ExistMediaInfo, NotExistMediaInfo from app.utils.string import StringUtils from app.utils.types import MediaType @@ -57,7 +58,7 @@ class DownloadChain(ChainBase): def batch_download(self, contexts: List[Context], - need_tvs: dict = None, + need_tvs: Dict[int, List[NotExistMediaInfo]] = None, userid: str = None) -> Tuple[List[Context], dict]: """ 根据缺失数据,自动种子列表中组合择优下载 @@ -155,7 +156,13 @@ class DownloadChain(ChainBase): """ need = list(set(need).difference(set(current))) if need: - need_tvs[tmdbid][seq]["episodes"] = need + not_exist = need_tvs[tmdbid][seq] + need_tvs[tmdbid][seq] = NotExistMediaInfo( + season=not_exist.season, + episodes=need, + total_episodes=not_exist.total_episodes, + start_episode=not_exist.start_episode + ) else: need_tvs[tmdbid].pop(seq) if not need_tvs.get(tmdbid) and need_tvs.get(tmdbid) is not None: @@ -189,10 +196,10 @@ class DownloadChain(ChainBase): for tv in need_tv: if not tv: continue - if not tv.get("episodes"): + if not tv.episodes: if not need_seasons.get(need_tmdbid): need_seasons[need_tmdbid] = [] - need_seasons[need_tmdbid].append(tv.get("season") or 1) + need_seasons[need_tmdbid].append(tv.season or 1) # 查找整季包含的种子,只处理整季没集的种子或者是集数超过季的种子 for need_tmdbid, need_season in need_seasons.items(): for context in contexts: @@ -236,10 +243,10 @@ class DownloadChain(ChainBase): continue index = 0 for tv in need_tv: - need_season = tv.get("season") or 1 - need_episodes = tv.get("episodes") - total_episodes = tv.get("total_episodes") - start_episode = tv.get("start_episode") or 1 + need_season = tv.season or 1 + need_episodes = tv.episodes + total_episodes = tv.total_episodes + start_episode = tv.start_episode or 1 # 缺失整季的转化为缺失集进行比较 if not need_episodes: need_episodes = list(range(start_episode, total_episodes + start_episode)) @@ -278,8 +285,8 @@ class DownloadChain(ChainBase): continue index = 0 for tv in need_tv: - need_season = tv.get("season") or 1 - need_episodes = tv.get("episodes") + need_season = tv.season or 1 + need_episodes = tv.episodes if not need_episodes: continue for context in contexts: @@ -326,7 +333,9 @@ class DownloadChain(ChainBase): return downloaded_list, need_tvs def get_no_exists_info(self, meta: MetaBase, - mediainfo: MediaInfo, no_exists: dict = None) -> Tuple[bool, dict]: + mediainfo: MediaInfo, + no_exists: Dict[int, List[NotExistMediaInfo]] = None + ) -> Tuple[bool, Dict[int, List[NotExistMediaInfo]]]: """ 检查媒体库,查询是否存在,对于剧集同时返回不存在的季集信息 :param meta: 元数据 @@ -347,26 +356,26 @@ class DownloadChain(ChainBase): """ if not no_exists.get(mediainfo.tmdb_id): no_exists[mediainfo.tmdb_id] = [ - { - "season": _season, - "episodes": _episodes, - "total_episodes": _total, - "start_episode": _start - } + NotExistMediaInfo( + season=_season, + episodes=_episodes, + total_episodes=_total, + start_episode=_start) ] else: - no_exists[mediainfo.tmdb_id].append({ - "season": _season, - "episodes": _episodes, - "total_episodes": _total, - "start_episode": _start - }) + no_exists[mediainfo.tmdb_id].append( + NotExistMediaInfo( + season=_season, + episodes=_episodes, + total_episodes=_total, + start_episode=_start) + ) if not no_exists: no_exists = {} if mediainfo.type == MediaType.MOVIE: # 电影 - exists_movies: Optional[dict] = self.media_exists(mediainfo) + exists_movies: Optional[ExistMediaInfo] = self.media_exists(mediainfo) if exists_movies: logger.info(f"媒体库中已存在电影:{mediainfo.get_title_string()}") return True, {} @@ -384,7 +393,7 @@ class DownloadChain(ChainBase): logger.error(f"媒体信息中没有季集信息:{mediainfo.get_title_string()}") return False, {} # 电视剧 - exists_tvs: Optional[dict] = self.media_exists(mediainfo) + exists_tvs: Optional[ExistMediaInfo] = self.media_exists(mediainfo) if not exists_tvs: # 所有剧集均缺失 for season, episodes in mediainfo.seasons.items(): @@ -400,7 +409,7 @@ class DownloadChain(ChainBase): if meta.begin_season \ and season not in meta.get_season_list(): continue - exist_seasons = exists_tvs.get("seasons") + exist_seasons = exists_tvs.seasons if exist_seasons.get(season): # 取差集 episodes = list(set(episodes).difference(set(exist_seasons[season]))) diff --git a/app/chain/search.py b/app/chain/search.py index 4d472b93..5302a54b 100644 --- a/app/chain/search.py +++ b/app/chain/search.py @@ -7,6 +7,7 @@ from app.core.meta import MetaBase from app.core.metainfo import MetaInfo from app.helper.sites import SitesHelper from app.log import logger +from app.schemas.context import NotExistMediaInfo from app.utils.string import StringUtils from app.utils.types import MediaType @@ -22,7 +23,7 @@ class SearchChain(ChainBase): def process(self, meta: MetaBase, mediainfo: MediaInfo, keyword: str = None, - no_exists: Dict[int, List[dict]] = None) -> Optional[List[Context]]: + no_exists: Dict[int, List[NotExistMediaInfo]] = None) -> Optional[List[Context]]: """ 根据媒体信息,执行搜索 :param meta: 元数据 diff --git a/app/chain/subscribe.py b/app/chain/subscribe.py index 918ebd7c..82bd2023 100644 --- a/app/chain/subscribe.py +++ b/app/chain/subscribe.py @@ -9,6 +9,7 @@ from app.core.config import settings from app.db.subscribes import Subscribes from app.helper.sites import SitesHelper from app.log import logger +from app.schemas.context import NotExistMediaInfo from app.utils.string import StringUtils from app.utils.types import MediaType @@ -290,7 +291,7 @@ class SubscribeChain(ChainBase): }) @staticmethod - def __get_subscribe_no_exits(no_exists: Dict[int, List[dict]], + def __get_subscribe_no_exits(no_exists: Dict[int, List[NotExistMediaInfo]], tmdb_id: int, begin_season: int, total_episode: int, @@ -310,37 +311,37 @@ class SubscribeChain(ChainBase): index = 0 for no_exist in no_exists.get(tmdb_id): # 替换原季值 - if no_exist.get("season") == begin_season: + if no_exist.season == begin_season: # 原季集列表 - episode_list = no_exist.get("episodes") + episode_list = no_exist.episodes # 原总集数 - total = no_exist.get("total_episodes") + total = no_exist.total_episodes if total_episode and start_episode: # 有开始集和总集数 episodes = list(range(start_episode, total_episode + 1)) - no_exists[tmdb_id][index] = { - "season": begin_season, - "episodes": episodes, - "total_episodes": total_episode, - "start_episode": start_episode - } + no_exists[tmdb_id][index] = NotExistMediaInfo( + season=begin_season, + episodes=episodes, + total_episodes=total_episode, + start_episode=start_episode + ) elif not start_episode: # 有总集数没有开始集 episodes = list(range(min(episode_list or [1]), total_episode + 1)) - no_exists[tmdb_id][index] = { - "season": begin_season, - "episodes": episodes, - "total_episodes": total_episode, - "start_episode": min(episode_list or [1]) - } + no_exists[tmdb_id][index] = NotExistMediaInfo( + season=begin_season, + episodes=episodes, + total_episodes=total_episode, + start_episode=min(episode_list or [1]) + ) elif not total_episode: # 有开始集没有总集数 episodes = list(range(start_episode, max(episode_list or [total]) + 1)) - no_exists[tmdb_id][index] = { - "season": begin_season, - "episodes": episodes, - "total_episodes": max(episode_list or [total]), - "start_episode": start_episode - } + no_exists[tmdb_id][index] = NotExistMediaInfo( + season=begin_season, + episodes=episodes, + total_episodes=max(episode_list or [total]), + start_episode=start_episode + ) index += 1 return no_exists diff --git a/app/chain/transfer.py b/app/chain/transfer.py index 09e0ead9..13247dee 100644 --- a/app/chain/transfer.py +++ b/app/chain/transfer.py @@ -1,12 +1,13 @@ import re +from pathlib import Path from typing import List, Optional from app.chain import ChainBase -from app.core.config import settings from app.core.context import MediaInfo from app.core.meta import MetaBase from app.core.metainfo import MetaInfo from app.log import logger +from app.schemas.context import TransferInfo, TransferTorrent from app.utils.string import StringUtils from app.utils.system import SystemUtils from app.utils.types import TorrentStatus @@ -43,16 +44,16 @@ class TransferChain(ChainBase): logger.error(f"参数错误,参数:{arg_str}") return False # 获取种子 - torrents: Optional[List[dict]] = self.list_torrents(hashs=torrent_hash) + torrents: Optional[List[TransferTorrent]] = self.list_torrents(hashs=torrent_hash) if not torrents: logger.error(f"没有获取到种子,参数:{arg_str}") return False # 识别前预处理 - result: Optional[tuple] = self.prepare_recognize(title=torrents[0].get("title")) + result: Optional[tuple] = self.prepare_recognize(title=torrents[0].title) if result: title, subtitle = result else: - title, subtitle = torrents[0].get("title"), None + title, subtitle = torrents[0].title, None # 识别 meta = MetaInfo(title=title, subtitle=subtitle) # 查询媒体信息 @@ -61,7 +62,7 @@ class TransferChain(ChainBase): arg_mediainfo = None logger.info("开始执行下载器文件转移 ...") # 从下载器获取种子列表 - torrents: Optional[List[dict]] = self.list_torrents(status=TorrentStatus.TRANSFER) + torrents: Optional[List[TransferTorrent]] = self.list_torrents(status=TorrentStatus.TRANSFER) if not torrents: logger.info("没有获取到已完成的下载任务") return False @@ -70,11 +71,11 @@ class TransferChain(ChainBase): # 识别 for torrent in torrents: # 识别前预处理 - result: Optional[tuple] = self.prepare_recognize(title=torrent.get("title")) + result: Optional[tuple] = self.prepare_recognize(title=torrent.title) if result: title, subtitle = result else: - title, subtitle = torrent.get("title"), None + title, subtitle = torrent.title, None # 识别元数据 meta: MetaBase = MetaInfo(title=title, subtitle=subtitle) if not meta.get_name(): @@ -84,45 +85,45 @@ class TransferChain(ChainBase): # 识别媒体信息 mediainfo: MediaInfo = self.recognize_media(meta=meta) if not mediainfo: - logger.warn(f'未识别到媒体信息,标题:{torrent.get("title")}') - self.post_message(title=f"{torrent.get('title')} 未识别到媒体信息,无法入库!\n" - f"回复:```\n/transfer {torrent.get('hash')} [tmdbid]\n``` 手动识别转移。") + logger.warn(f'未识别到媒体信息,标题:{torrent.title}') + self.post_message(title=f"{torrent.title} 未识别到媒体信息,无法入库!\n" + f"回复:```\n/transfer {torrent.hash} [tmdbid]\n``` 手动识别转移。") continue else: mediainfo = arg_mediainfo - logger.info(f"{torrent.get('title')} 识别为:{mediainfo.type.value} {mediainfo.get_title_string()}") + logger.info(f"{torrent.title} 识别为:{mediainfo.type.value} {mediainfo.get_title_string()}") # 更新媒体图片 self.obtain_image(mediainfo=mediainfo) # 转移 - transferinfo: dict = self.transfer(mediainfo=mediainfo, path=torrent.get("path")) - if not transferinfo or not transferinfo.get("target_path"): - logger.warn(f"{torrent.get('title')} 入库失败") + transferinfo: TransferInfo = self.transfer(mediainfo=mediainfo, path=Path(torrent.path)) + if not transferinfo or not transferinfo.target_path: + logger.warn(f"{torrent.title} 入库失败") self.post_message( title=f"{mediainfo.get_title_string()}{meta.get_season_episode_string()} 入库失败!", - text=f"原因:{transferinfo.get('message') if transferinfo else '未知'}", + text=f"原因:{transferinfo.message if transferinfo else '未知'}", image=mediainfo.get_message_image() ), continue # 转移完成 - self.transfer_completed(hashs=torrent.get("hash"), transinfo=transferinfo) + self.transfer_completed(hashs=torrent.hash, transinfo=transferinfo) # 刮剥 - self.scrape_metadata(path=transferinfo.get('target_path'), mediainfo=mediainfo) + self.scrape_metadata(path=transferinfo.target_path, mediainfo=mediainfo) # 刷新媒体库 - self.refresh_mediaserver(mediainfo=mediainfo, file_path=transferinfo.get('target_path')) + self.refresh_mediaserver(mediainfo=mediainfo, file_path=transferinfo.target_path) # 发送通知 self.__send_transfer_message(meta=meta, mediainfo=mediainfo, transferinfo=transferinfo) logger.info("下载器文件转移执行完成") return True - def __send_transfer_message(self, meta: MetaBase, mediainfo: MediaInfo, transferinfo: dict): + def __send_transfer_message(self, meta: MetaBase, mediainfo: MediaInfo, transferinfo: TransferInfo): """ 发送入库成功的消息 """ # 文件大小 file_size = StringUtils.str_filesize( SystemUtils.get_directory_size( - transferinfo.get('target_path') + transferinfo.target_path ) ) msg_title = f"{mediainfo.get_title_string()} 已入库" diff --git a/app/modules/__init__.py b/app/modules/__init__.py index 4f0d2ef6..45b5f3d9 100644 --- a/app/modules/__init__.py +++ b/app/modules/__init__.py @@ -6,6 +6,7 @@ from ruamel.yaml import CommentedMap from app.core.context import MediaInfo, TorrentInfo, Context from app.core.meta import MetaBase +from app.schemas.context import TransferInfo, TransferTorrent, ExistMediaInfo from app.utils.types import TorrentStatus, MediaType @@ -98,7 +99,7 @@ class _ModuleBase(metaclass=ABCMeta): """ pass - def media_exists(self, mediainfo: MediaInfo) -> Optional[dict]: + def media_exists(self, mediainfo: MediaInfo) -> Optional[ExistMediaInfo]: """ 判断媒体文件是否存在 :param mediainfo: 识别的媒体信息 @@ -156,7 +157,7 @@ class _ModuleBase(metaclass=ABCMeta): pass def list_torrents(self, status: TorrentStatus = None, - hashs: Union[list, str] = None) -> Optional[List[dict]]: + hashs: Union[list, str] = None) -> Optional[List[TransferTorrent]]: """ 获取下载器种子列表 :param status: 种子状态 @@ -165,7 +166,7 @@ class _ModuleBase(metaclass=ABCMeta): """ pass - def transfer(self, path: str, mediainfo: MediaInfo) -> Optional[dict]: + def transfer(self, path: Path, mediainfo: MediaInfo) -> Optional[TransferInfo]: """ 转移一个路径下的文件 :param path: 文件路径 @@ -174,7 +175,7 @@ class _ModuleBase(metaclass=ABCMeta): """ pass - def transfer_completed(self, hashs: Union[str, list], transinfo: dict) -> None: + def transfer_completed(self, hashs: Union[str, list], transinfo: TransferInfo) -> None: """ 转移完成后的处理 :param hashs: 种子Hash @@ -191,7 +192,7 @@ class _ModuleBase(metaclass=ABCMeta): """ pass - def refresh_mediaserver(self, mediainfo: MediaInfo, file_path: str) -> Optional[bool]: + def refresh_mediaserver(self, mediainfo: MediaInfo, file_path: Path) -> Optional[bool]: """ 刷新媒体库 :param mediainfo: 识别的媒体信息 diff --git a/app/modules/emby/__init__.py b/app/modules/emby/__init__.py index 90badafe..80d82870 100644 --- a/app/modules/emby/__init__.py +++ b/app/modules/emby/__init__.py @@ -1,10 +1,11 @@ -import json +from pathlib import Path from typing import Optional, Tuple, Union, Any from app.core.context import MediaInfo from app.log import logger from app.modules import _ModuleBase from app.modules.emby.emby import Emby +from app.schemas.context import ExistMediaInfo from app.utils.types import MediaType @@ -31,7 +32,7 @@ class EmbyModule(_ModuleBase): """ return self.emby.get_webhook_message(form.get("data")) - def media_exists(self, mediainfo: MediaInfo) -> Optional[dict]: + def media_exists(self, mediainfo: MediaInfo) -> Optional[ExistMediaInfo]: """ 判断媒体文件是否存在 :param mediainfo: 识别的媒体信息 @@ -44,7 +45,7 @@ class EmbyModule(_ModuleBase): return None else: logger.info(f"媒体库中已存在:{movies}") - return {"type": MediaType.MOVIE} + return ExistMediaInfo(type=MediaType.MOVIE) else: tvs = self.emby.get_tv_episodes(title=mediainfo.title, year=mediainfo.year, @@ -54,9 +55,9 @@ class EmbyModule(_ModuleBase): return None else: logger.info(f"{mediainfo.get_title_string()} 媒体库中已存在:{tvs}") - return {"type": MediaType.TV, "seasons": tvs} + return ExistMediaInfo(type=MediaType.TV, seasons=tvs) - def refresh_mediaserver(self, mediainfo: MediaInfo, file_path: str) -> Optional[bool]: + def refresh_mediaserver(self, mediainfo: MediaInfo, file_path: Path) -> Optional[bool]: """ 刷新媒体库 :param mediainfo: 识别的媒体信息 diff --git a/app/modules/filetransfer/__init__.py b/app/modules/filetransfer/__init__.py index af989184..711e5555 100644 --- a/app/modules/filetransfer/__init__.py +++ b/app/modules/filetransfer/__init__.py @@ -11,6 +11,7 @@ from app.core.config import settings from app.core.meta import MetaBase from app.log import logger from app.modules import _ModuleBase +from app.schemas.context import TransferInfo from app.utils.system import SystemUtils from app.utils.types import MediaType @@ -28,7 +29,7 @@ class FileTransferModule(_ModuleBase): def init_setting(self) -> Tuple[str, Union[str, bool]]: pass - def transfer(self, path: str, mediainfo: MediaInfo) -> Optional[dict]: + def transfer(self, path: Path, mediainfo: MediaInfo) -> Optional[TransferInfo]: """ 文件转移 :param path: 文件路径 @@ -38,18 +39,14 @@ class FileTransferModule(_ModuleBase): if not settings.LIBRARY_PATH: logger.error("未设置媒体库目录,无法转移文件") return None - target_path, msg = self.transfer_media(in_path=Path(path), + target_path, msg = self.transfer_media(in_path=path, meidainfo=mediainfo, rmt_mode=settings.TRANSFER_TYPE, target_dir=Path(settings.LIBRARY_PATH)) if not path: logger.error(msg) - return { - "path": path, - "target_path": target_path, - "message": msg - } + return TransferInfo(path=path, target_path=target_path, message=msg) @staticmethod def __transfer_command(file_item: Path, target_file: Path, rmt_mode) -> int: diff --git a/app/modules/jellyfin/__init__.py b/app/modules/jellyfin/__init__.py index 9358330c..5f45f0f5 100644 --- a/app/modules/jellyfin/__init__.py +++ b/app/modules/jellyfin/__init__.py @@ -1,10 +1,12 @@ import json +from pathlib import Path from typing import Optional, Tuple, Union, Any from app.core.context import MediaInfo from app.log import logger from app.modules import _ModuleBase from app.modules.jellyfin.jellyfin import Jellyfin +from app.schemas.context import ExistMediaInfo from app.utils.types import MediaType @@ -30,7 +32,7 @@ class JellyfinModule(_ModuleBase): """ return self.jellyfin.get_webhook_message(json.loads(body)) - def media_exists(self, mediainfo: MediaInfo) -> Optional[dict]: + def media_exists(self, mediainfo: MediaInfo) -> Optional[ExistMediaInfo]: """ 判断媒体文件是否存在 :param mediainfo: 识别的媒体信息 @@ -43,7 +45,7 @@ class JellyfinModule(_ModuleBase): return None else: logger.info(f"媒体库中已存在:{movies}") - return {"type": MediaType.MOVIE} + return ExistMediaInfo(type=MediaType.MOVIE) else: tvs = self.jellyfin.get_tv_episodes(title=mediainfo.title, year=mediainfo.year, @@ -53,9 +55,9 @@ class JellyfinModule(_ModuleBase): return None else: logger.info(f"{mediainfo.get_title_string()} 媒体库中已存在:{tvs}") - return {"type": MediaType.TV, "seasons": tvs} + return ExistMediaInfo(type=MediaType.TV, seasons=tvs) - def refresh_mediaserver(self, mediainfo: MediaInfo, file_path: str) -> Optional[bool]: + def refresh_mediaserver(self, mediainfo: MediaInfo, file_path: Path) -> Optional[bool]: """ 刷新媒体库 :param mediainfo: 识别的媒体信息 diff --git a/app/modules/plex/__init__.py b/app/modules/plex/__init__.py index c9171fc8..abfd6f4a 100644 --- a/app/modules/plex/__init__.py +++ b/app/modules/plex/__init__.py @@ -1,9 +1,11 @@ +from pathlib import Path from typing import Optional, Tuple, Union, Any from app.core.context import MediaInfo from app.log import logger from app.modules import _ModuleBase from app.modules.plex.plex import Plex +from app.schemas.context import ExistMediaInfo from app.utils.types import MediaType @@ -30,7 +32,7 @@ class PlexModule(_ModuleBase): """ return self.plex.get_webhook_message(form.get("payload")) - def media_exists(self, mediainfo: MediaInfo) -> Optional[dict]: + def media_exists(self, mediainfo: MediaInfo) -> Optional[ExistMediaInfo]: """ 判断媒体文件是否存在 :param mediainfo: 识别的媒体信息 @@ -43,7 +45,7 @@ class PlexModule(_ModuleBase): return None else: logger.info(f"媒体库中已存在:{movies}") - return {"type": MediaType.MOVIE} + return ExistMediaInfo(type=MediaType.MOVIE) else: tvs = self.plex.get_tv_episodes(title=mediainfo.title, year=mediainfo.year) @@ -52,9 +54,9 @@ class PlexModule(_ModuleBase): return None else: logger.info(f"{mediainfo.get_title_string()} 媒体库中已存在:{tvs}") - return {"type": MediaType.TV, "seasons": tvs} + return ExistMediaInfo(type=MediaType.TV, seasons=tvs) - def refresh_mediaserver(self, mediainfo: MediaInfo, file_path: str) -> Optional[bool]: + def refresh_mediaserver(self, mediainfo: MediaInfo, file_path: Path) -> Optional[bool]: """ 刷新媒体库 :param mediainfo: 识别的媒体信息 diff --git a/app/modules/qbittorrent/__init__.py b/app/modules/qbittorrent/__init__.py index 6660eb4f..1e4b833d 100644 --- a/app/modules/qbittorrent/__init__.py +++ b/app/modules/qbittorrent/__init__.py @@ -6,6 +6,7 @@ from app.core.metainfo import MetaInfo from app.log import logger from app.modules import _ModuleBase from app.modules.qbittorrent.qbittorrent import Qbittorrent +from app.schemas.context import TransferInfo, TransferTorrent from app.utils.string import StringUtils from app.utils.types import TorrentStatus @@ -84,7 +85,8 @@ class QbittorrentModule(_ModuleBase): else: return torrent_hash, "添加下载成功" - def list_torrents(self, status: TorrentStatus = None, hashs: Union[list, str] = None) -> Optional[List[dict]]: + def list_torrents(self, status: TorrentStatus = None, + hashs: Union[list, str] = None) -> Optional[List[TransferTorrent]]: """ 获取下载器种子列表 :param status: 种子状态 @@ -101,12 +103,12 @@ class QbittorrentModule(_ModuleBase): torrent_path = Path(content_path) else: torrent_path = Path(settings.DOWNLOAD_PATH) / torrent.get('name') - ret_torrents.append({ - 'title': torrent.get('name'), - 'path': torrent_path, - 'hash': torrent.get('hash'), - 'tags': torrent.get('tags') - }) + ret_torrents.append(TransferTorrent( + title=torrent.get('name'), + path=torrent_path, + hash=torrent.get('hash'), + tags=torrent.get('tags') + )) elif status == TorrentStatus.TRANSFER: # 获取已完成且未整理的 torrents = self.qbittorrent.get_completed_torrents(tags=settings.TORRENT_TAG) @@ -120,17 +122,17 @@ class QbittorrentModule(_ModuleBase): torrent_path = Path(content_path) else: torrent_path = Path(settings.DOWNLOAD_PATH) / torrent.get('name') - ret_torrents.append({ - 'title': torrent.get('name'), - 'path': torrent_path, - 'hash': torrent.get('hash'), - 'tags': torrent.get('tags') - }) + ret_torrents.append(TransferTorrent( + title=torrent.get('name'), + path=torrent_path, + hash=torrent.get('hash'), + tags=torrent.get('tags') + )) else: return None return ret_torrents - def transfer_completed(self, hashs: Union[str, list], transinfo: dict) -> None: + def transfer_completed(self, hashs: Union[str, list], transinfo: TransferInfo) -> None: """ 转移完成后的处理 :param hashs: 种子Hash diff --git a/app/modules/transmission/__init__.py b/app/modules/transmission/__init__.py index 3e05d7e5..99bea2d2 100644 --- a/app/modules/transmission/__init__.py +++ b/app/modules/transmission/__init__.py @@ -6,6 +6,7 @@ from app.core.metainfo import MetaInfo from app.log import logger from app.modules import _ModuleBase from app.modules.transmission.transmission import Transmission +from app.schemas.context import TransferInfo, TransferTorrent from app.utils.types import TorrentStatus @@ -71,7 +72,8 @@ class TransmissionModule(_ModuleBase): else: return torrent_hash, "添加下载任务成功" - def list_torrents(self, status: TorrentStatus = None, hashs: Union[list, str] = None) -> Optional[List[dict]]: + def list_torrents(self, status: TorrentStatus = None, + hashs: Union[list, str] = None) -> Optional[List[TransferTorrent]]: """ 获取下载器种子列表 :param status: 种子状态 @@ -83,12 +85,12 @@ class TransmissionModule(_ModuleBase): # 按Hash获取 torrents, _ = self.transmission.get_torrents(ids=hashs, tags=settings.TORRENT_TAG) for torrent in torrents: - ret_torrents.append({ - 'title': torrent.name, - 'path': Path(torrent.download_dir) / torrent.name, - 'hash': torrent.hashString, - 'tags': torrent.labels - }) + ret_torrents.append(TransferTorrent( + title=torrent.name, + path=Path(torrent.download_dir) / torrent.name, + hash=torrent.hashString, + tags=torrent.labels + )) elif status == TorrentStatus.TRANSFER: # 获取已完成且未整理的 torrents = self.transmission.get_completed_torrents(tags=settings.TORRENT_TAG) @@ -102,17 +104,17 @@ class TransmissionModule(_ModuleBase): if not path: logger.debug(f"未获取到 {torrent.name} 下载保存路径") continue - ret_torrents.append({ - 'title': torrent.name, - 'path': Path(path) / torrent.name, - 'hash': torrent.hashString, - 'tags': torrent.labels - }) + ret_torrents.append(TransferTorrent( + title=torrent.name, + path=Path(torrent.download_dir) / torrent.name, + hash=torrent.hashString, + tags=torrent.labels + )) else: return None return ret_torrents - def transfer_completed(self, hashs: Union[str, list], transinfo: dict) -> None: + def transfer_completed(self, hashs: Union[str, list], transinfo: TransferInfo) -> None: """ 转移完成后的处理 :param hashs: 种子Hash diff --git a/app/modules/words/__init__.py b/app/modules/words/__init__.py index 204f7d66..4c52e3d9 100644 --- a/app/modules/words/__init__.py +++ b/app/modules/words/__init__.py @@ -1,7 +1,5 @@ -from pathlib import Path from typing import Tuple, Union -from app.core.context import Context from app.modules import _ModuleBase diff --git a/app/plugins/sitestatistic/siteuserinfo/__init__.py b/app/plugins/sitestatistic/siteuserinfo/__init__.py index c82dfdb7..69a9b1a6 100644 --- a/app/plugins/sitestatistic/siteuserinfo/__init__.py +++ b/app/plugins/sitestatistic/siteuserinfo/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- -import base64 import json import re from abc import ABCMeta, abstractmethod @@ -7,7 +6,6 @@ from typing import Optional from urllib.parse import urljoin, urlsplit import requests -from lxml import etree from requests import Session from app.core.config import settings diff --git a/app/schemas/context.py b/app/schemas/context.py index 595c626f..139f6fdd 100644 --- a/app/schemas/context.py +++ b/app/schemas/context.py @@ -1,7 +1,10 @@ -from typing import Optional +from pathlib import Path +from typing import Optional, Dict from pydantic import BaseModel +from app.utils.types import MediaType + class MetaInfo(BaseModel): # 是否处理的文件 @@ -84,3 +87,37 @@ class Context(BaseModel): meta_info: Optional[MetaInfo] # 媒体信息 media_info: Optional[MediaInfo] + + +class TransferTorrent(BaseModel): + title: Optional[str] = None + path: Optional[Path] = None + hash: Optional[str] = None + tags: Optional[str] = None + + +class TransferInfo(BaseModel): + # 转移⼁路径 + path: Optional[Path] = None + # 转移后路径 + target_path: Optional[Path] = None + # 错误信息 + message: Optional[str] = None + + +class ExistMediaInfo(BaseModel): + # 类型 电影、电视剧 + type: MediaType + # 季 + seasons: Optional[Dict[int, list]] = None + + +class NotExistMediaInfo(BaseModel): + # 季 + season: int + # 剧集列表 + episodes: list = [] + # 总集数 + total_episodes: int = 0 + # 开始集 + start_episode: int = 0