From bfba4d1dda22bd9a6ffadbd9c9fcc29ad388876e Mon Sep 17 00:00:00 2001 From: EstrellaXD Date: Tue, 9 May 2023 20:24:43 +0800 Subject: [PATCH] Finished new version of renamer.py --- src/module/app.py | 2 +- src/module/core/download_client.py | 13 +- src/module/downloader/client/qb_downloader.py | 2 +- src/module/manager/renamer.py | 132 +++++++++--------- src/module/models/torrent.py | 2 + src/module/network/notification.py | 10 +- src/module/parser/analyser/torrent_parser.py | 6 +- 7 files changed, 86 insertions(+), 81 deletions(-) diff --git a/src/module/app.py b/src/module/app.py index 0c5613ab..04dc880e 100644 --- a/src/module/app.py +++ b/src/module/app.py @@ -21,7 +21,7 @@ async def rss_loop( rss_link: str, settings: Config, ): - with RSSAnalyser(settings) as analyser: + with RSSAnalyser() as analyser: analyser.rss_to_datas(rss_link) if settings.bangumi_manage.eps_complete: with FullSeasonGet(settings) as season: diff --git a/src/module/core/download_client.py b/src/module/core/download_client.py index 9e25c87d..df251904 100644 --- a/src/module/core/download_client.py +++ b/src/module/core/download_client.py @@ -3,14 +3,15 @@ import logging import os from module.downloader import getClient -from module.models import BangumiData, Config +from module.models import BangumiData +from module.conf import settings logger = logging.getLogger(__name__) class DownloadClient: - def __init__(self, settings: Config): + def __init__(self): self.client = getClient(settings) self.authed = False self.download_path = settings.downloader.path @@ -50,7 +51,7 @@ class DownloadClient: info.official_title, info.title_raw, info.season, - info.group, + info.group_name, ) rule = { "enable": True, @@ -85,11 +86,11 @@ class DownloadClient: self.client.rss_add_feed(url=rss_link, item_path=item_path) logger.info("Add Collection RSS Feed successfully.") - def add_rules(self, bangumi_info: list[BangumiData], rss_link: str): + def add_rules(self, bangumi_info: list[BangumiData]): logger.debug("Start adding rules.") for info in bangumi_info: if not info.added: - self.set_rule(info, rss_link) + self.set_rule(info) info.added = True logger.debug("Finished.") @@ -97,7 +98,7 @@ class DownloadClient: return self.client.torrents_info(status_filter="completed", category=category) def rename_torrent_file(self, _hash, old_path, new_path) -> bool: - logger.debug(f"{old_path} >> {new_path}") + logger.info(f"{old_path} >> {new_path}") return self.client.torrents_rename_file( torrent_hash=_hash, old_path=old_path, new_path=new_path ) diff --git a/src/module/downloader/client/qb_downloader.py b/src/module/downloader/client/qb_downloader.py index c6d21126..e868b806 100644 --- a/src/module/downloader/client/qb_downloader.py +++ b/src/module/downloader/client/qb_downloader.py @@ -69,7 +69,7 @@ class QbDownloader: ) return True except Conflict409Error: - logger.debug(f"Conflict409Error: {old_path} -> {new_path}") + logger.debug(f"Conflict409Error: {old_path} >> {new_path}") return False def check_rss(self, url, item_path) -> tuple[str | None, bool]: diff --git a/src/module/manager/renamer.py b/src/module/manager/renamer.py index 60261c54..1b7c4843 100644 --- a/src/module/manager/renamer.py +++ b/src/module/manager/renamer.py @@ -7,17 +7,17 @@ from module.core.download_client import DownloadClient from module.parser import TitleParser from module.network import PostNotification -from module.models import Config, SubtitleFile, EpisodeFile +from module.models import SubtitleFile, EpisodeFile +from module.conf import settings logger = logging.getLogger(__name__) class Renamer(DownloadClient): - def __init__(self, settings: Config): - super().__init__(settings) + def __init__(self): + super().__init__() self._renamer = TitleParser() self._notification = PostNotification() - self.settings = settings @staticmethod def print_result(torrent_count, rename_count): @@ -27,7 +27,7 @@ class Renamer(DownloadClient): ) logger.debug(f"Checked {torrent_count} files") - def get_torrent_info(self, category="Bangumi"): + def rename_info(self, category="Bangumi"): recent_info = self.get_torrent_info(category=category) torrent_count = len(recent_info) return recent_info, torrent_count @@ -45,33 +45,49 @@ class Renamer(DownloadClient): subtitle_list.append(file_name) return media_list, subtitle_list + @staticmethod + def gen_path(file_info: EpisodeFile | SubtitleFile, bangumi_name: str, method: str) -> str: + season = f"0{file_info.season}" if file_info.season < 10 else file_info.season + episode = f"0{file_info.episode}" if file_info.episode < 10 else file_info.episode + if method == "None": + return file_info.media_path + elif method == "pn": + return f"{file_info.title} S{season}E{episode}{file_info.suffix}" + elif method == "advance": + return f"{bangumi_name} S{file_info.season}E{file_info.episode}{file_info.suffix}" + elif method == "subtitle_pn": + return f"{file_info.title} S{season}E{episode}.{file_info.language}{file_info.suffix}" + elif method == "subtitle_advance": + return f"{bangumi_name} S{season}E{episode}.{file_info.language}{file_info.suffix}" + def rename_file( self, info, media_path: str, - method: str, bangumi_name: str, + method: str, season: int, - remove_bad_torrents: bool, ): ep = self._renamer.torrent_parser( torrent_path=media_path, season=season, ) - new_path = self.gen_path(ep, method) - # TODO: rewrite rename file func - if media_path != new_path: - pass - renamed = self.rename_torrent_file( - _hash=info.hash, old_path=media_path, new_path=new_path - ) - if renamed: - logger.info(f"{bangumi_name} Season {ep.season} Ep {ep.episode} renamed.") - self._notification.send_msg(bangumi_name, f"{new_path}已经更新,已自动重命名。") - else: - logger.warning(f"{bangumi_name} Season {ep.season} Ep {ep.episode} rename failed.") - if remove_bad_torrents: - self.delete_torrent(info.hash) + if ep: + new_path = self.gen_path(ep, bangumi_name, method=method) + if media_path != new_path: + renamed = self.rename_torrent_file( + _hash=info.hash, old_path=media_path, new_path=new_path + ) + if renamed: + if settings.notification.enable: + # self._notification.send_msg() + pass + else: + logger.warning(f"{bangumi_name} Season {ep.season} Ep {ep.episode} rename failed.") + if settings.bangumi_manage.remove_bad_torrent: + self.delete_torrent(info.hash) + else: + logger.warning(f"{media_path} parse failed") def rename_collection( self, @@ -79,36 +95,27 @@ class Renamer(DownloadClient): media_list: list[str], bangumi_name: str, season: int, - remove_bad_torrents: bool, method: str, ): _hash = info.hash for media_path in media_list: path_len = len(media_path.split(os.path.sep)) if path_len <= 2: - suffix = os.path.splitext(media_path)[-1] - torrent_name = self.get_file_name(media_path) - new_name = self._renamer.torrent_parser( - torrent_name=torrent_name, - bangumi_name=bangumi_name, + ep = self._renamer.torrent_parser( + torrent_path=media_path, season=season, - suffix=suffix, - method=method, ) - if torrent_name != new_name: - try: - self.rename_torrent_file( - _hash=_hash, old_path=media_path, new_path=new_name - ) - except Exception as e: - logger.warning(f"{torrent_name} rename failed") - logger.warning( - f"Bangumi name: {bangumi_name}, Season: {season}, Suffix: {suffix}" - ) - logger.debug(e) + new_path = self.gen_path(ep, bangumi_name, method=method) + if media_path != new_path: + renamed = self.rename_torrent_file( + _hash=_hash, old_path=media_path, new_path=new_path + ) + if not renamed: + logger.warning(f"{media_path} rename failed") # Delete bad torrent. - self.delete_torrent(_hash, remove_bad_torrents) - self.set_category(category="BangumiCollection", hashes=_hash) + if settings.bangumi_manage.remove_bad_torrent: + self.delete_torrent(_hash) + break def rename_subtitles( self, @@ -120,24 +127,17 @@ class Renamer(DownloadClient): ): method = "subtitle_" + method for subtitle_path in subtitle_list: - suffix = os.path.splitext(subtitle_path)[-1] - old_name = self.get_file_name(subtitle_path) - new_name = self._renamer.torrent_parser( - method=method, - torrent_name=old_name, - bangumi_name=bangumi_name, + sub = self._renamer.torrent_parser( + torrent_path=subtitle_path, season=season, - suffix=suffix, ) - if old_name != new_name: - try: - self.rename_torrent_file( - _hash=_hash, old_path=subtitle_path, new_path=new_name - ) - except Exception as e: - logger.warning(f"{old_name} rename failed") - logger.warning(f"Suffix: {suffix}") - logger.debug(e) + new_path = self.gen_path(sub, bangumi_name, method=method) + if subtitle_path != new_path: + renamed = self.rename_torrent_file( + _hash=_hash, old_path=subtitle_path, new_path=new_path + ) + if not renamed: + logger.warning(f"{subtitle_path} rename failed") @staticmethod def get_season_info(save_path: str, download_path: str): @@ -181,10 +181,9 @@ class Renamer(DownloadClient): def rename(self): # Get torrent info - download_path = self.settings.downloader.path - rename_method = self.settings.bangumi_manage.rename_method - remove_bad_torrents = self.settings.bangumi_manage.remove_bad_torrent - recent_info, torrent_count = self.get_torrent_info() + download_path = settings.downloader.path + rename_method = settings.bangumi_manage.rename_method + recent_info, torrent_count = self.rename_info() for info in recent_info: media_list, subtitle_list = self.check_files(info) bangumi_name, season = self.get_season_info(info.save_path, download_path) @@ -195,7 +194,6 @@ class Renamer(DownloadClient): method=rename_method, bangumi_name=bangumi_name, season=season, - remove_bad_torrents=remove_bad_torrents, ) if len(subtitle_list) > 0: self.rename_subtitles( @@ -212,7 +210,6 @@ class Renamer(DownloadClient): media_list=media_list, bangumi_name=bangumi_name, season=season, - remove_bad_torrents=remove_bad_torrents, method=rename_method, ) if len(subtitle_list) > 0: @@ -225,3 +222,10 @@ class Renamer(DownloadClient): ) else: logger.warning(f"{info.name} has no media file") + + +if __name__ == '__main__': + from module.conf import setup_logger + setup_logger() + with Renamer() as renamer: + renamer.rename() diff --git a/src/module/models/torrent.py b/src/module/models/torrent.py index 83dbbf9b..97da96c4 100644 --- a/src/module/models/torrent.py +++ b/src/module/models/torrent.py @@ -13,6 +13,7 @@ class FileSet(BaseModel): class EpisodeFile(BaseModel): + media_path: str = Field(...) group: str | None = Field(None) title: str = Field(...) season: int = Field(...) @@ -21,6 +22,7 @@ class EpisodeFile(BaseModel): class SubtitleFile(BaseModel): + media_path: str = Field(...) group: str | None = Field(None) title: str = Field(...) season: int = Field(...) diff --git a/src/module/network/notification.py b/src/module/network/notification.py index 0b876bd3..4272e752 100644 --- a/src/module/network/notification.py +++ b/src/module/network/notification.py @@ -2,15 +2,15 @@ import logging from module.network.request_contents import RequestContent from module.models import Notification +from module.conf import settings logger = logging.getLogger(__name__) class PostNotification: - def __init__(self, settings): + def __init__(self): self.type: str = settings.notification.type - self.enable: bool = settings.notification.enable self.token = settings.notification.token self.chat_id = settings.notification.chat_id self.client = self.getClient() @@ -30,8 +30,6 @@ class PostNotification: f"季度: 第{info.season}季\n" \ f"更新集数: 第{info.episode}集\n" \ f"{info.poster_link}\n" - if not self.enable: - return False if self.client is None: return False return self.client.send_msg(text) @@ -85,9 +83,7 @@ class BarkNotification: if __name__ == '__main__': - from module.conf import settings - print(settings.notification) - notification = PostNotification(settings=settings) + notification = PostNotification() info = Notification( official_title="魔法纪录 魔法少女小圆外传", season=2, diff --git a/src/module/parser/analyser/torrent_parser.py b/src/module/parser/analyser/torrent_parser.py index 8f3882da..77da389d 100644 --- a/src/module/parser/analyser/torrent_parser.py +++ b/src/module/parser/analyser/torrent_parser.py @@ -60,9 +60,9 @@ def torrent_parser(torrent_path: str, season: int | None = None, file_type: str media_path = split_path(torrent_path) for rule in RULES: match_obj = re.match(rule, media_path, re.I) - if match_obj is not None: + if match_obj: group, title = get_group(match_obj.group(1)) - if season is None: + if not season: title, season = get_season_and_title(title) else: title, _ = get_season_and_title(title) @@ -70,6 +70,7 @@ def torrent_parser(torrent_path: str, season: int | None = None, file_type: str suffix = unix_path.splitext(torrent_path)[-1] if file_type == "media": return EpisodeFile( + media_path=torrent_path, group=group, title=title, season=season, @@ -79,6 +80,7 @@ def torrent_parser(torrent_path: str, season: int | None = None, file_type: str elif file_type == "subtitle": language = get_subtitle_lang(media_path) return SubtitleFile( + media_path=torrent_path, group=group, title=title, season=season,