From 1b2f09b95f48d3bdd299bd775bbe8a9ce570a07b Mon Sep 17 00:00:00 2001 From: thsrite Date: Tue, 12 Sep 2023 12:45:39 +0800 Subject: [PATCH 01/12] =?UTF-8?q?fix=20=E8=87=AA=E5=AE=9A=E4=B9=89?= =?UTF-8?q?=E8=AE=A2=E9=98=85=E6=8F=92=E4=BB=B6=E5=A2=9E=E5=8A=A0=E8=AF=86?= =?UTF-8?q?=E5=88=AB=E6=8C=89=E9=92=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/plugins/rsssubscribe/__init__.py | 54 ++++++++++++++++++++-------- 1 file changed, 40 insertions(+), 14 deletions(-) diff --git a/app/plugins/rsssubscribe/__init__.py b/app/plugins/rsssubscribe/__init__.py index 08c6f4b7..f6d755b7 100644 --- a/app/plugins/rsssubscribe/__init__.py +++ b/app/plugins/rsssubscribe/__init__.py @@ -65,6 +65,7 @@ class RssSubscribe(_PluginBase): _clear: bool = False _clearflag: bool = False _action: str = "subscribe" + _recognization: str = "Y" _save_path: str = "" def init_plugin(self, config: dict = None): @@ -89,6 +90,7 @@ class RssSubscribe(_PluginBase): self._filter = config.get("filter") self._clear = config.get("clear") self._action = config.get("action") + self._recognization = config.get("recognization") self._save_path = config.get("save_path") if self._enabled or self._onlyonce: @@ -219,7 +221,7 @@ class RssSubscribe(_PluginBase): 'component': 'VCol', 'props': { 'cols': 12, - 'md': 6 + 'md': 4 }, 'content': [ { @@ -236,7 +238,7 @@ class RssSubscribe(_PluginBase): 'component': 'VCol', 'props': { 'cols': 12, - 'md': 6 + 'md': 4 }, 'content': [ { @@ -251,6 +253,26 @@ class RssSubscribe(_PluginBase): } } ] + }, + { + 'component': 'VCol', + 'props': { + 'cols': 12, + 'md': 4 + }, + 'content': [ + { + 'component': 'VSelect', + 'props': { + 'model': 'recognization', + 'label': '识别', + 'items': [ + {'title': '是', 'value': 'Y'}, + {'title': '否', 'value': 'N'} + ] + } + } + ] } ] }, @@ -403,6 +425,7 @@ class RssSubscribe(_PluginBase): "clear": False, "filter": False, "action": "subscribe", + "recognization": "Y", "save_path": "" } @@ -525,7 +548,9 @@ class RssSubscribe(_PluginBase): "include": self._include, "exclude": self._exclude, "proxy": self._proxy, - "clear": self._clear + "clear": self._clear, + "action": self._action, + "recognization": self._recognization, }) def check(self): @@ -605,17 +630,18 @@ class RssSubscribe(_PluginBase): continue else: if self._action == "download": - if mediainfo.type == MediaType.TV: - if no_exists: - exist_info = no_exists.get(mediainfo.tmdb_id) - season_info = exist_info.get(meta.begin_season or 1) - if not season_info: - logger.info(f'{mediainfo.title_year} {meta.season} 己存在') - continue - if (season_info.episodes - and not set(meta.episode_list).issubset(set(season_info.episodes))): - logger.info(f'{mediainfo.title_year} {meta.season_episode} 己存在') - continue + if str(self._recognization) == "Y": + if mediainfo.type == MediaType.TV: + if no_exists: + exist_info = no_exists.get(mediainfo.tmdb_id) + season_info = exist_info.get(meta.begin_season or 1) + if not season_info: + logger.info(f'{mediainfo.title_year} {meta.season} 己存在') + continue + if (season_info.episodes + and not set(meta.episode_list).issubset(set(season_info.episodes))): + logger.info(f'{mediainfo.title_year} {meta.season_episode} 己存在') + continue # 添加下载 result = self.downloadchain.download_single( context=Context( From d8afa339de22d38c7be0567b7b98f4cc6909f3a7 Mon Sep 17 00:00:00 2001 From: thsrite Date: Tue, 12 Sep 2023 13:29:12 +0800 Subject: [PATCH 02/12] =?UTF-8?q?fix=20=E5=AA=92=E4=BD=93=E5=BA=93?= =?UTF-8?q?=E5=88=AE=E5=89=8A=E6=8F=92=E4=BB=B6=E5=BC=80=E5=90=AF=E5=BC=BA?= =?UTF-8?q?=E5=88=B6=E5=88=AE=E5=89=8A=E6=97=B6=E5=BF=BD=E7=95=A5SCRAP=5FM?= =?UTF-8?q?ETADATA=E5=8F=98=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/chain/__init__.py | 5 +++-- app/plugins/libraryscraper/__init__.py | 6 +++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/app/chain/__init__.py b/app/chain/__init__.py index d5591509..c7e42443 100644 --- a/app/chain/__init__.py +++ b/app/chain/__init__.py @@ -385,14 +385,15 @@ class ChainBase(metaclass=ABCMeta): """ return self.run_module("post_torrents_message", message=message, torrents=torrents) - def scrape_metadata(self, path: Path, mediainfo: MediaInfo) -> None: + def scrape_metadata(self, path: Path, mediainfo: MediaInfo, scrap_metadata: bool = settings.SCRAP_METADATA) -> None: """ 刮削元数据 :param path: 媒体文件路径 :param mediainfo: 识别的媒体信息 + :param scrap_metadata: 是否刮削 :return: 成功或失败 """ - if settings.SCRAP_METADATA: + if scrap_metadata: return self.run_module("scrape_metadata", path=path, mediainfo=mediainfo) return None diff --git a/app/plugins/libraryscraper/__init__.py b/app/plugins/libraryscraper/__init__.py index 8b61fef7..9738cb94 100644 --- a/app/plugins/libraryscraper/__init__.py +++ b/app/plugins/libraryscraper/__init__.py @@ -321,6 +321,8 @@ class LibraryScraper(_PluginBase): meta_info = MetaInfo(file.name) # 合并 meta_info.merge(dir_meta) + # 是否刮削 + scrap_metadata = settings.SCRAP_METADATA # 识别媒体信息 if not mediainfo: @@ -359,6 +361,7 @@ class LibraryScraper(_PluginBase): # 覆盖模式时,提前删除nfo if self._mode in ["force_all", "force_nfo"]: + scrap_metadata = True nfo_files = SystemUtils.list_files(path, [".nfo"]) for nfo_file in nfo_files: try: @@ -369,6 +372,7 @@ class LibraryScraper(_PluginBase): # 覆盖模式时,提前删除图片文件 if self._mode in ["force_all", "force_image"]: + scrap_metadata = True image_files = SystemUtils.list_files(path, [".jpg", ".png"]) for image_file in image_files: if ".actors" in str(image_file): @@ -380,7 +384,7 @@ class LibraryScraper(_PluginBase): print(str(err)) # 刮削单个文件 - self.chain.scrape_metadata(path=file, mediainfo=mediainfo) + self.chain.scrape_metadata(path=file, mediainfo=mediainfo, scrap_metadata=scrap_metadata) @staticmethod def __get_tmdbid_from_nfo(file_path: Path): From dd7803c90af439a9a891b352cd5cc2de7ff934a5 Mon Sep 17 00:00:00 2001 From: thsrite Date: Tue, 12 Sep 2023 14:57:31 +0800 Subject: [PATCH 03/12] =?UTF-8?q?fix=20=E5=8D=B8=E8=BD=BD=E6=8F=92?= =?UTF-8?q?=E4=BB=B6=E6=97=B6=E5=88=A0=E9=99=A4=E6=8F=92=E4=BB=B6=E9=85=8D?= =?UTF-8?q?=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/endpoints/plugin.py | 2 ++ app/db/models/plugin.py | 5 +++++ app/db/plugindata_oper.py | 7 +++++-- app/db/systemconfig_oper.py | 19 +++++++++++++++++-- 4 files changed, 29 insertions(+), 4 deletions(-) diff --git a/app/api/endpoints/plugin.py b/app/api/endpoints/plugin.py index 47615c96..d0f824a4 100644 --- a/app/api/endpoints/plugin.py +++ b/app/api/endpoints/plugin.py @@ -101,6 +101,8 @@ def uninstall_plugin(plugin_id: str, if plugin == plugin_id: install_plugins.remove(plugin) break + # 删除插件配置 + SystemConfigOper().delete_by_key(plugin_id) # 保存 SystemConfigOper().set(SystemConfigKey.UserInstalledPlugins, install_plugins) # 重载插件管理器 diff --git a/app/db/models/plugin.py b/app/db/models/plugin.py index e060512a..16da8c96 100644 --- a/app/db/models/plugin.py +++ b/app/db/models/plugin.py @@ -26,6 +26,11 @@ class PluginData(Base): db.query(PluginData).filter(PluginData.plugin_id == plugin_id, PluginData.key == key).delete() Base.commit(db) + @staticmethod + def del_plugin_data_by_plugin_id(db: Session, plugin_id: str): + db.query(PluginData).filter(PluginData.plugin_id == plugin_id).delete() + Base.commit(db) + @staticmethod def get_plugin_data_by_plugin_id(db: Session, plugin_id: str): return db.query(PluginData).filter(PluginData.plugin_id == plugin_id).all() diff --git a/app/db/plugindata_oper.py b/app/db/plugindata_oper.py index 4f2c29c0..58f38184 100644 --- a/app/db/plugindata_oper.py +++ b/app/db/plugindata_oper.py @@ -43,13 +43,16 @@ class PluginDataOper(DbOper): return json.loads(data.value) return data.value - def del_data(self, plugin_id: str, key: str) -> Any: + def del_data(self, plugin_id: str, key: str = None) -> Any: """ 删除插件数据 :param plugin_id: 插件id :param key: 数据key """ - PluginData.del_plugin_data_by_key(self._db, plugin_id, key) + if key: + PluginData.del_plugin_data_by_key(self._db, plugin_id, key) + else: + PluginData.del_plugin_data_by_plugin_id(self._db, plugin_id) def truncate(self): """ diff --git a/app/db/systemconfig_oper.py b/app/db/systemconfig_oper.py index f4ef206f..2ccb1e81 100644 --- a/app/db/systemconfig_oper.py +++ b/app/db/systemconfig_oper.py @@ -3,6 +3,7 @@ from typing import Any, Union from app.db import DbOper, SessionFactory from app.db.models.systemconfig import SystemConfig +from app.db.plugindata_oper import PluginDataOper from app.schemas.types import SystemConfigKey from app.utils.object import ObjectUtils from app.utils.singleton import Singleton @@ -17,8 +18,11 @@ class SystemConfigOper(DbOper, metaclass=Singleton): 加载配置到内存 """ self._db = SessionFactory() + self._syscomconfig = SystemConfig() + # 插件数据 + self.plugindata = PluginDataOper(self._db) super().__init__(self._db) - for item in SystemConfig.list(self._db): + for item in self._syscomconfig.list(self._db): if ObjectUtils.is_obj(item.value): self.__SYSTEMCONF[item.key] = json.loads(item.value) else: @@ -37,7 +41,7 @@ class SystemConfigOper(DbOper, metaclass=Singleton): value = json.dumps(value) elif value is None: value = '' - conf = SystemConfig.get_by_key(self._db, key) + conf = self._syscomconfig.get_by_key(self._db, key) if conf: if value: conf.update(self._db, {"value": value}) @@ -57,6 +61,17 @@ class SystemConfigOper(DbOper, metaclass=Singleton): return self.__SYSTEMCONF return self.__SYSTEMCONF.get(key) + def delete_by_key(self, key: str = None) -> Any: + """ + 删除系统设置 + """ + if self.__SYSTEMCONF.get(f"plugin.{key}"): + del self.__SYSTEMCONF[f"plugin.{key}"] + # 删除系统配置 + self._syscomconfig.delete_by_key(db=self._db, key=f"plugin.{key}") + # 删除插件数据 + self.plugindata.del_data(plugin_id=key) + def __del__(self): if self._db: self._db.close() From d7310ade8694132f14817618ce62f19069196600 Mon Sep 17 00:00:00 2001 From: thsrite Date: Tue, 12 Sep 2023 15:21:34 +0800 Subject: [PATCH 04/12] =?UTF-8?q?fix=20=E5=90=8C=E6=AD=A5=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E6=8F=92=E4=BB=B6=E5=85=BC=E5=AE=B9=E5=A4=9A=E5=88=86?= =?UTF-8?q?=E8=BE=A8=E7=8E=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/db/models/transferhistory.py | 20 ++++++--- app/db/transferhistory_oper.py | 3 +- app/plugins/mediasyncdel/__init__.py | 67 +++++++++++++++++++++++----- 3 files changed, 72 insertions(+), 18 deletions(-) diff --git a/app/db/models/transferhistory.py b/app/db/models/transferhistory.py index a3a8b323..d0f1e98d 100644 --- a/app/db/models/transferhistory.py +++ b/app/db/models/transferhistory.py @@ -86,7 +86,7 @@ class TransferHistory(Base): @staticmethod def list_by(db: Session, mtype: str = None, title: str = None, year: str = None, season: str = None, - episode: str = None, tmdbid: int = None): + episode: str = None, tmdbid: int = None, dest: str = None): """ 据tmdbid、season、season_episode查询转移记录 tmdbid + mtype 或 title + year 必输 @@ -98,16 +98,19 @@ class TransferHistory(Base): return db.query(TransferHistory).filter(TransferHistory.tmdbid == tmdbid, TransferHistory.type == mtype, TransferHistory.seasons == season, - TransferHistory.episodes == episode).all() + TransferHistory.episodes == episode, + TransferHistory.dest == dest).all() elif season: # 查询一季 return db.query(TransferHistory).filter(TransferHistory.tmdbid == tmdbid, TransferHistory.type == mtype, - TransferHistory.seasons == season).all() + TransferHistory.seasons == season, + TransferHistory.dest == dest).all() else: # 查询所有 return db.query(TransferHistory).filter(TransferHistory.tmdbid == tmdbid, - TransferHistory.type == mtype).all() + TransferHistory.type == mtype, + TransferHistory.dest == dest).all() # 标题 + 年份 elif title and year: # 电视剧某季某集 @@ -115,16 +118,19 @@ class TransferHistory(Base): return db.query(TransferHistory).filter(TransferHistory.title == title, TransferHistory.year == year, TransferHistory.seasons == season, - TransferHistory.episodes == episode).all() + TransferHistory.episodes == episode, + TransferHistory.dest == dest).all() # 电视剧某季 elif season: return db.query(TransferHistory).filter(TransferHistory.title == title, TransferHistory.year == year, - TransferHistory.seasons == season).all() + TransferHistory.seasons == season, + TransferHistory.dest == dest).all() # 电视剧所有季集|电影 else: return db.query(TransferHistory).filter(TransferHistory.title == title, - TransferHistory.year == year).all() + TransferHistory.year == year, + TransferHistory.dest == dest).all() return [] diff --git a/app/db/transferhistory_oper.py b/app/db/transferhistory_oper.py index da7c86a7..95dc3db4 100644 --- a/app/db/transferhistory_oper.py +++ b/app/db/transferhistory_oper.py @@ -52,13 +52,14 @@ class TransferHistoryOper(DbOper): return TransferHistory.statistic(self._db, days) def get_by(self, title: str = None, year: str = None, mtype: str = None, - season: str = None, episode: str = None, tmdbid: int = None) -> List[TransferHistory]: + season: str = None, episode: str = None, tmdbid: int = None, dest: str = None) -> List[TransferHistory]: """ 按类型、标题、年份、季集查询转移记录 """ return TransferHistory.list_by(db=self._db, mtype=mtype, title=title, + dest=dest, year=year, season=season, episode=episode, diff --git a/app/plugins/mediasyncdel/__init__.py b/app/plugins/mediasyncdel/__init__.py index 163f9147..2693d5bf 100644 --- a/app/plugins/mediasyncdel/__init__.py +++ b/app/plugins/mediasyncdel/__init__.py @@ -57,6 +57,7 @@ class MediaSyncDel(_PluginBase): _notify = False _del_source = False _exclude_path = None + _library_path = None _transferhis = None _downloadhis = None qb = None @@ -80,6 +81,7 @@ class MediaSyncDel(_PluginBase): self._notify = config.get("notify") self._del_source = config.get("del_source") self._exclude_path = config.get("exclude_path") + self._library_path = config.get("library_path") if self._enabled and str(self._sync_type) == "log": self._scheduler = BackgroundScheduler(timezone=settings.TZ) @@ -231,6 +233,28 @@ class MediaSyncDel(_PluginBase): } ] }, + { + 'component': 'VRow', + 'content': [ + { + 'component': 'VCol', + 'props': { + 'cols': 12, + }, + 'content': [ + { + 'component': 'VTextarea', + 'props': { + 'model': 'library_path', + 'rows': '2', + 'label': '媒体库路径', + 'placeholder': '媒体服务器路径:MoviePilot路径(一行一个)' + } + } + ] + } + ] + }, { 'component': 'VRow', 'content': [ @@ -260,6 +284,7 @@ class MediaSyncDel(_PluginBase): "enabled": False, "notify": True, "del_source": False, + "library_path": "", "sync_type": "webhook", "cron": "*/30 * * * *", "exclude_path": "", @@ -528,6 +553,7 @@ class MediaSyncDel(_PluginBase): # 查询转移记录 msg, transfer_history = self.__get_transfer_his(media_type=media_type, media_name=media_name, + media_path=media_path, tmdb_id=tmdb_id, season_num=season_num, episode_num=episode_num) @@ -626,12 +652,11 @@ class MediaSyncDel(_PluginBase): # 保存历史 self.save_data("history", history) - def __get_transfer_his(self, media_type: str, media_name: str, + def __get_transfer_his(self, media_type: str, media_name: str, media_path: str, tmdb_id: int, season_num: int, episode_num: int): """ 查询转移记录 """ - # 季数 if season_num: season_num = str(season_num).rjust(2, '0') @@ -642,16 +667,25 @@ class MediaSyncDel(_PluginBase): # 类型 mtype = MediaType.MOVIE if media_type in ["Movie", "MOV"] else MediaType.TV + # 处理路径映射 (处理同一媒体多分辨率的情况) + if self._library_path: + paths = self._library_path.split("\n") + for path in paths: + sub_paths = path.split(":") + media_path = media_path.replace(sub_paths[0], sub_paths[1]).replace('\\', '/') + # 删除电影 if mtype == MediaType.MOVIE: msg = f'电影 {media_name} {tmdb_id}' transfer_history: List[TransferHistory] = self._transferhis.get_by(tmdbid=tmdb_id, - mtype=mtype.value) + mtype=mtype.value, + dest=media_path) # 删除电视剧 elif mtype == MediaType.TV and not season_num and not episode_num: msg = f'剧集 {media_name} {tmdb_id}' transfer_history: List[TransferHistory] = self._transferhis.get_by(tmdbid=tmdb_id, - mtype=mtype.value) + mtype=mtype.value, + dest=media_path) # 删除季 S02 elif mtype == MediaType.TV and season_num and not episode_num: if not season_num or not str(season_num).isdigit(): @@ -660,7 +694,8 @@ class MediaSyncDel(_PluginBase): msg = f'剧集 {media_name} S{season_num} {tmdb_id}' transfer_history: List[TransferHistory] = self._transferhis.get_by(tmdbid=tmdb_id, mtype=mtype.value, - season=f'S{season_num}') + season=f'S{season_num}', + dest=media_path) # 删除剧集S02E02 elif mtype == MediaType.TV and season_num and episode_num: if not season_num or not str(season_num).isdigit() or not episode_num or not str(episode_num).isdigit(): @@ -670,7 +705,8 @@ class MediaSyncDel(_PluginBase): transfer_history: List[TransferHistory] = self._transferhis.get_by(tmdbid=tmdb_id, mtype=mtype.value, season=f'S{season_num}', - episode=f'E{episode_num}') + episode=f'E{episode_num}', + dest=media_path) else: return "", [] @@ -723,26 +759,36 @@ class MediaSyncDel(_PluginBase): logger.info(f"媒体路径 {media_path} 已被排除,暂不处理") return + # 处理路径映射 (处理同一媒体多分辨率的情况) + if self._library_path: + paths = self._library_path.split("\n") + for path in paths: + sub_paths = path.split(":") + media_path = media_path.replace(sub_paths[0], sub_paths[1]).replace('\\', '/') + # 获取删除的记录 # 删除电影 if media_type == "Movie": msg = f'电影 {media_name}' transfer_history: List[TransferHistory] = self._transferhis.get_by( title=media_name, - year=media_year) + year=media_year, + dest=media_path) # 删除电视剧 elif media_type == "Series": msg = f'剧集 {media_name}' transfer_history: List[TransferHistory] = self._transferhis.get_by( title=media_name, - year=media_year) + year=media_year, + dest=media_path) # 删除季 S02 elif media_type == "Season": msg = f'剧集 {media_name} {media_season}' transfer_history: List[TransferHistory] = self._transferhis.get_by( title=media_name, year=media_year, - season=media_season) + season=media_season, + dest=media_path) # 删除剧集S02E02 elif media_type == "Episode": msg = f'剧集 {media_name} {media_season}{media_episode}' @@ -750,7 +796,8 @@ class MediaSyncDel(_PluginBase): title=media_name, year=media_year, season=media_season, - episode=media_episode) + episode=media_episode, + dest=media_path) else: continue From 0cb75d689cabf480155abe289ecc2e15aece22c2 Mon Sep 17 00:00:00 2001 From: thsrite Date: Tue, 12 Sep 2023 15:28:21 +0800 Subject: [PATCH 05/12] =?UTF-8?q?fix=20=E6=A0=B9=E6=8D=AEtype=E5=92=8Ctmdb?= =?UTF-8?q?id=E6=9F=A5=E8=AF=A2=E8=BD=AC=E7=A7=BB=E8=AE=B0=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/chain/transfer.py | 8 ++++---- app/db/models/transferhistory.py | 8 ++++++++ app/db/transferhistory_oper.py | 8 ++++++++ app/plugins/dirmonitor/__init__.py | 8 ++++---- app/plugins/libraryscraper/__init__.py | 8 ++++---- 5 files changed, 28 insertions(+), 12 deletions(-) diff --git a/app/chain/transfer.py b/app/chain/transfer.py index 2e210072..e2126b39 100644 --- a/app/chain/transfer.py +++ b/app/chain/transfer.py @@ -253,10 +253,10 @@ class TransferChain(ChainBase): # 如果未开启新增已入库媒体是否跟随TMDB信息变化则根据tmdbid查询之前的title if not settings.SCRAP_FOLLOW_TMDB: - transfer_historys = self.transferhis.get_by(tmdbid=file_mediainfo.tmdb_id, - mtype=file_mediainfo.type.value) - if transfer_historys: - file_mediainfo.title = transfer_historys[0].title + transfer_history = self.transferhis.get_by_type_tmdbid(tmdbid=file_mediainfo.tmdb_id, + mtype=file_mediainfo.type.value) + if transfer_history: + file_mediainfo.title = transfer_history.title logger.info(f"{file_path.name} 识别为:{file_mediainfo.type.value} {file_mediainfo.title_year}") diff --git a/app/db/models/transferhistory.py b/app/db/models/transferhistory.py index d0f1e98d..88e172bb 100644 --- a/app/db/models/transferhistory.py +++ b/app/db/models/transferhistory.py @@ -134,6 +134,14 @@ class TransferHistory(Base): return [] + @staticmethod + def get_by_type_tmdbid(db: Session, mtype: str = None, tmdbid: int = None): + """ + 据tmdbid、type查询转移记录 + """ + return db.query(TransferHistory).filter(TransferHistory.tmdbid == tmdbid, + TransferHistory.type == mtype).first() + @staticmethod def update_download_hash(db: Session, historyid: int = None, download_hash: str = None): db.query(TransferHistory).filter(TransferHistory.id == historyid).update( diff --git a/app/db/transferhistory_oper.py b/app/db/transferhistory_oper.py index 95dc3db4..98902841 100644 --- a/app/db/transferhistory_oper.py +++ b/app/db/transferhistory_oper.py @@ -65,6 +65,14 @@ class TransferHistoryOper(DbOper): episode=episode, tmdbid=tmdbid) + def get_by_type_tmdbid(self, mtype: str = None, tmdbid: int = None) -> TransferHistory: + """ + 按类型、tmdb查询转移记录 + """ + return TransferHistory.get_by_type_tmdbid(db=self._db, + mtype=mtype, + tmdbid=tmdbid) + def delete(self, historyid): """ 删除转移记录 diff --git a/app/plugins/dirmonitor/__init__.py b/app/plugins/dirmonitor/__init__.py index 65c04190..bc4cacd2 100644 --- a/app/plugins/dirmonitor/__init__.py +++ b/app/plugins/dirmonitor/__init__.py @@ -270,10 +270,10 @@ class DirMonitor(_PluginBase): # 如果未开启新增已入库媒体是否跟随TMDB信息变化则根据tmdbid查询之前的title if not settings.SCRAP_FOLLOW_TMDB: - transfer_historys = self.transferhis.get_by(tmdbid=mediainfo.tmdb_id, - mtype=mediainfo.type.value) - if transfer_historys: - mediainfo.title = transfer_historys[0].title + transfer_history = self.transferhis.get_by_type_tmdbid(tmdbid=mediainfo.tmdb_id, + mtype=mediainfo.type.value) + if transfer_history: + mediainfo.title = transfer_history.title logger.info(f"{file_path.name} 识别为:{mediainfo.type.value} {mediainfo.title_year}") # 更新媒体图片 diff --git a/app/plugins/libraryscraper/__init__.py b/app/plugins/libraryscraper/__init__.py index 9738cb94..d3033446 100644 --- a/app/plugins/libraryscraper/__init__.py +++ b/app/plugins/libraryscraper/__init__.py @@ -354,10 +354,10 @@ class LibraryScraper(_PluginBase): # 如果未开启新增已入库媒体是否跟随TMDB信息变化则根据tmdbid查询之前的title if not settings.SCRAP_FOLLOW_TMDB: - transfer_historys = self.transferhis.get_by(tmdbid=mediainfo.tmdb_id, - mtype=mediainfo.type.value) - if transfer_historys: - mediainfo.title = transfer_historys[0].title + transfer_history = self.transferhis.get_by_type_tmdbid(tmdbid=mediainfo.tmdb_id, + mtype=mediainfo.type.value) + if transfer_history: + mediainfo.title = transfer_history.title # 覆盖模式时,提前删除nfo if self._mode in ["force_all", "force_nfo"]: From 01a153902eeddbd786ac289f7264e9d16a9313f8 Mon Sep 17 00:00:00 2001 From: thsrite Date: Wed, 13 Sep 2023 09:21:56 +0800 Subject: [PATCH 06/12] =?UTF-8?q?Revert=20"fix=20=E8=87=AA=E5=AE=9A?= =?UTF-8?q?=E4=B9=89=E8=AE=A2=E9=98=85=E6=8F=92=E4=BB=B6=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E8=AF=86=E5=88=AB=E6=8C=89=E9=92=AE"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 1b2f09b95f48d3bdd299bd775bbe8a9ce570a07b. --- app/plugins/rsssubscribe/__init__.py | 54 ++++++++-------------------- 1 file changed, 14 insertions(+), 40 deletions(-) diff --git a/app/plugins/rsssubscribe/__init__.py b/app/plugins/rsssubscribe/__init__.py index f6d755b7..08c6f4b7 100644 --- a/app/plugins/rsssubscribe/__init__.py +++ b/app/plugins/rsssubscribe/__init__.py @@ -65,7 +65,6 @@ class RssSubscribe(_PluginBase): _clear: bool = False _clearflag: bool = False _action: str = "subscribe" - _recognization: str = "Y" _save_path: str = "" def init_plugin(self, config: dict = None): @@ -90,7 +89,6 @@ class RssSubscribe(_PluginBase): self._filter = config.get("filter") self._clear = config.get("clear") self._action = config.get("action") - self._recognization = config.get("recognization") self._save_path = config.get("save_path") if self._enabled or self._onlyonce: @@ -221,7 +219,7 @@ class RssSubscribe(_PluginBase): 'component': 'VCol', 'props': { 'cols': 12, - 'md': 4 + 'md': 6 }, 'content': [ { @@ -238,7 +236,7 @@ class RssSubscribe(_PluginBase): 'component': 'VCol', 'props': { 'cols': 12, - 'md': 4 + 'md': 6 }, 'content': [ { @@ -253,26 +251,6 @@ class RssSubscribe(_PluginBase): } } ] - }, - { - 'component': 'VCol', - 'props': { - 'cols': 12, - 'md': 4 - }, - 'content': [ - { - 'component': 'VSelect', - 'props': { - 'model': 'recognization', - 'label': '识别', - 'items': [ - {'title': '是', 'value': 'Y'}, - {'title': '否', 'value': 'N'} - ] - } - } - ] } ] }, @@ -425,7 +403,6 @@ class RssSubscribe(_PluginBase): "clear": False, "filter": False, "action": "subscribe", - "recognization": "Y", "save_path": "" } @@ -548,9 +525,7 @@ class RssSubscribe(_PluginBase): "include": self._include, "exclude": self._exclude, "proxy": self._proxy, - "clear": self._clear, - "action": self._action, - "recognization": self._recognization, + "clear": self._clear }) def check(self): @@ -630,18 +605,17 @@ class RssSubscribe(_PluginBase): continue else: if self._action == "download": - if str(self._recognization) == "Y": - if mediainfo.type == MediaType.TV: - if no_exists: - exist_info = no_exists.get(mediainfo.tmdb_id) - season_info = exist_info.get(meta.begin_season or 1) - if not season_info: - logger.info(f'{mediainfo.title_year} {meta.season} 己存在') - continue - if (season_info.episodes - and not set(meta.episode_list).issubset(set(season_info.episodes))): - logger.info(f'{mediainfo.title_year} {meta.season_episode} 己存在') - continue + if mediainfo.type == MediaType.TV: + if no_exists: + exist_info = no_exists.get(mediainfo.tmdb_id) + season_info = exist_info.get(meta.begin_season or 1) + if not season_info: + logger.info(f'{mediainfo.title_year} {meta.season} 己存在') + continue + if (season_info.episodes + and not set(meta.episode_list).issubset(set(season_info.episodes))): + logger.info(f'{mediainfo.title_year} {meta.season_episode} 己存在') + continue # 添加下载 result = self.downloadchain.download_single( context=Context( From 4659e7367fdd9c464591c1b8c53f7a33e5a23c50 Mon Sep 17 00:00:00 2001 From: thsrite Date: Wed, 13 Sep 2023 09:24:16 +0800 Subject: [PATCH 07/12] =?UTF-8?q?fix=20d8afa339=20=E5=87=BD=E6=95=B0?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/chain/__init__.py | 6 +++--- app/plugins/libraryscraper/__init__.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/chain/__init__.py b/app/chain/__init__.py index c7e42443..8de3b680 100644 --- a/app/chain/__init__.py +++ b/app/chain/__init__.py @@ -385,15 +385,15 @@ class ChainBase(metaclass=ABCMeta): """ return self.run_module("post_torrents_message", message=message, torrents=torrents) - def scrape_metadata(self, path: Path, mediainfo: MediaInfo, scrap_metadata: bool = settings.SCRAP_METADATA) -> None: + def scrape_metadata(self, path: Path, mediainfo: MediaInfo, scrap: bool = settings.SCRAP_METADATA) -> None: """ 刮削元数据 :param path: 媒体文件路径 :param mediainfo: 识别的媒体信息 - :param scrap_metadata: 是否刮削 + :param scrap: 是否刮削 :return: 成功或失败 """ - if scrap_metadata: + if scrap: return self.run_module("scrape_metadata", path=path, mediainfo=mediainfo) return None diff --git a/app/plugins/libraryscraper/__init__.py b/app/plugins/libraryscraper/__init__.py index d3033446..ea81ca1a 100644 --- a/app/plugins/libraryscraper/__init__.py +++ b/app/plugins/libraryscraper/__init__.py @@ -384,7 +384,7 @@ class LibraryScraper(_PluginBase): print(str(err)) # 刮削单个文件 - self.chain.scrape_metadata(path=file, mediainfo=mediainfo, scrap_metadata=scrap_metadata) + self.chain.scrape_metadata(path=file, mediainfo=mediainfo, scrap=scrap_metadata) @staticmethod def __get_tmdbid_from_nfo(file_path: Path): From 08560fc7c3ada16dc64d0d6c1407b856152381c5 Mon Sep 17 00:00:00 2001 From: thsrite Date: Wed, 13 Sep 2023 09:29:52 +0800 Subject: [PATCH 08/12] fix dd7803c9 --- app/db/systemconfig_oper.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/app/db/systemconfig_oper.py b/app/db/systemconfig_oper.py index 2ccb1e81..79e4a463 100644 --- a/app/db/systemconfig_oper.py +++ b/app/db/systemconfig_oper.py @@ -2,8 +2,8 @@ import json from typing import Any, Union from app.db import DbOper, SessionFactory +from app.db.models.plugin import PluginData from app.db.models.systemconfig import SystemConfig -from app.db.plugindata_oper import PluginDataOper from app.schemas.types import SystemConfigKey from app.utils.object import ObjectUtils from app.utils.singleton import Singleton @@ -19,8 +19,7 @@ class SystemConfigOper(DbOper, metaclass=Singleton): """ self._db = SessionFactory() self._syscomconfig = SystemConfig() - # 插件数据 - self.plugindata = PluginDataOper(self._db) + self._plugindata = PluginData() super().__init__(self._db) for item in self._syscomconfig.list(self._db): if ObjectUtils.is_obj(item.value): @@ -70,7 +69,7 @@ class SystemConfigOper(DbOper, metaclass=Singleton): # 删除系统配置 self._syscomconfig.delete_by_key(db=self._db, key=f"plugin.{key}") # 删除插件数据 - self.plugindata.del_data(plugin_id=key) + self._plugindata.del_plugin_data_by_plugin_id(db=self._db, plugin_id=key) def __del__(self): if self._db: From 7c3c6ee999f5faffceed9e7177febd86cd4f7aad Mon Sep 17 00:00:00 2001 From: thsrite Date: Wed, 13 Sep 2023 09:52:05 +0800 Subject: [PATCH 09/12] fix --- app/plugins/mediasyncdel/__init__.py | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/app/plugins/mediasyncdel/__init__.py b/app/plugins/mediasyncdel/__init__.py index 2693d5bf..5e410c33 100644 --- a/app/plugins/mediasyncdel/__init__.py +++ b/app/plugins/mediasyncdel/__init__.py @@ -571,11 +571,6 @@ class MediaSyncDel(_PluginBase): stop_cnt = 0 error_cnt = 0 for transferhis in transfer_history: - title = transferhis.title - if title not in media_name: - logger.warn( - f"当前转移记录 {transferhis.id} {title} {transferhis.tmdbid} 与删除媒体{media_name}不符,防误删,暂不自动删除") - continue image = transferhis.image year = transferhis.year @@ -815,11 +810,6 @@ class MediaSyncDel(_PluginBase): stop_cnt = 0 error_cnt = 0 for transferhis in transfer_history: - title = transferhis.title - if title not in media_name: - logger.warn( - f"当前转移记录 {transferhis.id} {title} {transferhis.tmdbid} 与删除媒体{media_name}不符,防误删,暂不自动删除") - continue image = transferhis.image # 0、删除转移记录 self._transferhis.delete(transferhis.id) From 221c31f4814a60d9f2b73c62aa803b1b605087ca Mon Sep 17 00:00:00 2001 From: thsrite Date: Wed, 13 Sep 2023 10:37:13 +0800 Subject: [PATCH 10/12] =?UTF-8?q?fix=20=E8=87=AA=E5=AE=9A=E4=B9=89?= =?UTF-8?q?=E8=AF=86=E5=88=AB=E8=AF=8D=E5=A2=9E=E5=8A=A0=E8=A7=84=E5=88=99?= =?UTF-8?q?=EF=BC=9A=E8=A2=AB=E6=9B=BF=E6=8D=A2=E8=AF=8D=20=3D>=20?= =?UTF-8?q?=E6=9B=BF=E6=8D=A2=E8=AF=8D=20&&=20=E5=81=8F=E7=A7=BB=E5=89=8D?= =?UTF-8?q?=20<>=20=E5=81=8F=E7=A7=BB=E5=90=8E=20>>=20=E9=9B=86=E5=81=8F?= =?UTF-8?q?=E7=A7=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/core/meta/words.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/app/core/meta/words.py b/app/core/meta/words.py index e0f466a7..213938ec 100644 --- a/app/core/meta/words.py +++ b/app/core/meta/words.py @@ -28,7 +28,23 @@ class WordsMatcher(metaclass=Singleton): if not word: continue try: - if word.count(" => "): + if word.count(" => ") and word.count(" && ") and word.count(" >> ") and word.count(" <> "): + # 替换词 + thc = re.findall(r'(.*?)\s*=>', word)[0] + # 被替换词 + bthc = re.findall(r'=>\s*(.*?)\s*&&', word)[0] + # 集偏移前字段 + pyq = re.findall(r'&&\s*(.*?)\s*<>', word)[0] + # 集偏移后字段 + pyh = re.findall(r'<>(.*?)\s*>>', word)[0] + # 集偏移 + offsets = re.findall(r'>>\s*(.*?)$', word)[0] + # 替换词 + title, message, state = self.__replace_regex(title, thc, bthc) + if state: + # 替换词成功再进行集偏移 + title, message, state = self.__episode_offset(title, pyq, pyh, offsets) + elif word.count(" => "): # 替换词 strings = word.split(" => ") title, message, state = self.__replace_regex(title, strings[0], strings[1]) From ac11d4eb30c0070e4865e887ce0b73afda9ad06a Mon Sep 17 00:00:00 2001 From: thsrite Date: Wed, 13 Sep 2023 11:58:30 +0800 Subject: [PATCH 11/12] Revert "fix dd7803c9" This reverts commit 08560fc7c3ada16dc64d0d6c1407b856152381c5. --- app/db/systemconfig_oper.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/db/systemconfig_oper.py b/app/db/systemconfig_oper.py index 79e4a463..2ccb1e81 100644 --- a/app/db/systemconfig_oper.py +++ b/app/db/systemconfig_oper.py @@ -2,8 +2,8 @@ import json from typing import Any, Union from app.db import DbOper, SessionFactory -from app.db.models.plugin import PluginData from app.db.models.systemconfig import SystemConfig +from app.db.plugindata_oper import PluginDataOper from app.schemas.types import SystemConfigKey from app.utils.object import ObjectUtils from app.utils.singleton import Singleton @@ -19,7 +19,8 @@ class SystemConfigOper(DbOper, metaclass=Singleton): """ self._db = SessionFactory() self._syscomconfig = SystemConfig() - self._plugindata = PluginData() + # 插件数据 + self.plugindata = PluginDataOper(self._db) super().__init__(self._db) for item in self._syscomconfig.list(self._db): if ObjectUtils.is_obj(item.value): @@ -69,7 +70,7 @@ class SystemConfigOper(DbOper, metaclass=Singleton): # 删除系统配置 self._syscomconfig.delete_by_key(db=self._db, key=f"plugin.{key}") # 删除插件数据 - self._plugindata.del_plugin_data_by_plugin_id(db=self._db, plugin_id=key) + self.plugindata.del_data(plugin_id=key) def __del__(self): if self._db: From f38defb5157d1db370e97d5a40a5d7596fc42ef5 Mon Sep 17 00:00:00 2001 From: thsrite Date: Wed, 13 Sep 2023 11:58:37 +0800 Subject: [PATCH 12/12] =?UTF-8?q?Revert=20"fix=20=E5=8D=B8=E8=BD=BD?= =?UTF-8?q?=E6=8F=92=E4=BB=B6=E6=97=B6=E5=88=A0=E9=99=A4=E6=8F=92=E4=BB=B6?= =?UTF-8?q?=E9=85=8D=E7=BD=AE"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit dd7803c90af439a9a891b352cd5cc2de7ff934a5. --- app/api/endpoints/plugin.py | 2 -- app/db/models/plugin.py | 5 ----- app/db/plugindata_oper.py | 7 ++----- app/db/systemconfig_oper.py | 19 ++----------------- 4 files changed, 4 insertions(+), 29 deletions(-) diff --git a/app/api/endpoints/plugin.py b/app/api/endpoints/plugin.py index d0f824a4..47615c96 100644 --- a/app/api/endpoints/plugin.py +++ b/app/api/endpoints/plugin.py @@ -101,8 +101,6 @@ def uninstall_plugin(plugin_id: str, if plugin == plugin_id: install_plugins.remove(plugin) break - # 删除插件配置 - SystemConfigOper().delete_by_key(plugin_id) # 保存 SystemConfigOper().set(SystemConfigKey.UserInstalledPlugins, install_plugins) # 重载插件管理器 diff --git a/app/db/models/plugin.py b/app/db/models/plugin.py index 16da8c96..e060512a 100644 --- a/app/db/models/plugin.py +++ b/app/db/models/plugin.py @@ -26,11 +26,6 @@ class PluginData(Base): db.query(PluginData).filter(PluginData.plugin_id == plugin_id, PluginData.key == key).delete() Base.commit(db) - @staticmethod - def del_plugin_data_by_plugin_id(db: Session, plugin_id: str): - db.query(PluginData).filter(PluginData.plugin_id == plugin_id).delete() - Base.commit(db) - @staticmethod def get_plugin_data_by_plugin_id(db: Session, plugin_id: str): return db.query(PluginData).filter(PluginData.plugin_id == plugin_id).all() diff --git a/app/db/plugindata_oper.py b/app/db/plugindata_oper.py index 58f38184..4f2c29c0 100644 --- a/app/db/plugindata_oper.py +++ b/app/db/plugindata_oper.py @@ -43,16 +43,13 @@ class PluginDataOper(DbOper): return json.loads(data.value) return data.value - def del_data(self, plugin_id: str, key: str = None) -> Any: + def del_data(self, plugin_id: str, key: str) -> Any: """ 删除插件数据 :param plugin_id: 插件id :param key: 数据key """ - if key: - PluginData.del_plugin_data_by_key(self._db, plugin_id, key) - else: - PluginData.del_plugin_data_by_plugin_id(self._db, plugin_id) + PluginData.del_plugin_data_by_key(self._db, plugin_id, key) def truncate(self): """ diff --git a/app/db/systemconfig_oper.py b/app/db/systemconfig_oper.py index 2ccb1e81..f4ef206f 100644 --- a/app/db/systemconfig_oper.py +++ b/app/db/systemconfig_oper.py @@ -3,7 +3,6 @@ from typing import Any, Union from app.db import DbOper, SessionFactory from app.db.models.systemconfig import SystemConfig -from app.db.plugindata_oper import PluginDataOper from app.schemas.types import SystemConfigKey from app.utils.object import ObjectUtils from app.utils.singleton import Singleton @@ -18,11 +17,8 @@ class SystemConfigOper(DbOper, metaclass=Singleton): 加载配置到内存 """ self._db = SessionFactory() - self._syscomconfig = SystemConfig() - # 插件数据 - self.plugindata = PluginDataOper(self._db) super().__init__(self._db) - for item in self._syscomconfig.list(self._db): + for item in SystemConfig.list(self._db): if ObjectUtils.is_obj(item.value): self.__SYSTEMCONF[item.key] = json.loads(item.value) else: @@ -41,7 +37,7 @@ class SystemConfigOper(DbOper, metaclass=Singleton): value = json.dumps(value) elif value is None: value = '' - conf = self._syscomconfig.get_by_key(self._db, key) + conf = SystemConfig.get_by_key(self._db, key) if conf: if value: conf.update(self._db, {"value": value}) @@ -61,17 +57,6 @@ class SystemConfigOper(DbOper, metaclass=Singleton): return self.__SYSTEMCONF return self.__SYSTEMCONF.get(key) - def delete_by_key(self, key: str = None) -> Any: - """ - 删除系统设置 - """ - if self.__SYSTEMCONF.get(f"plugin.{key}"): - del self.__SYSTEMCONF[f"plugin.{key}"] - # 删除系统配置 - self._syscomconfig.delete_by_key(db=self._db, key=f"plugin.{key}") - # 删除插件数据 - self.plugindata.del_data(plugin_id=key) - def __del__(self): if self._db: self._db.close()