Merge pull request #3724 from wikrin/subscribe_words

fix: - 修复订阅识别词在下载阶段不生效的问题
This commit is contained in:
jxxghp
2025-01-15 08:10:03 +08:00
committed by GitHub
6 changed files with 70 additions and 72 deletions
+1 -4
View File
@@ -326,19 +326,16 @@ class ChainBase(metaclass=ABCMeta):
def filter_torrents(self, rule_groups: List[str], def filter_torrents(self, rule_groups: List[str],
torrent_list: List[TorrentInfo], torrent_list: List[TorrentInfo],
season_episodes: Dict[int, list] = None,
mediainfo: MediaInfo = None) -> List[TorrentInfo]: mediainfo: MediaInfo = None) -> List[TorrentInfo]:
""" """
过滤种子资源 过滤种子资源
:param rule_groups: 过滤规则组名称列表 :param rule_groups: 过滤规则组名称列表
:param torrent_list: 资源列表 :param torrent_list: 资源列表
:param season_episodes: 季集数过滤 {season:[episodes]}
:param mediainfo: 识别的媒体信息 :param mediainfo: 识别的媒体信息
:return: 过滤后的资源列表,添加资源优先级 :return: 过滤后的资源列表,添加资源优先级
""" """
return self.run_module("filter_torrents", rule_groups=rule_groups, return self.run_module("filter_torrents", rule_groups=rule_groups,
torrent_list=torrent_list, season_episodes=season_episodes, torrent_list=torrent_list, mediainfo=mediainfo)
mediainfo=mediainfo)
def download(self, content: Union[Path, str], download_dir: Path, cookie: str, 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,
+11 -7
View File
@@ -125,7 +125,6 @@ class SearchChain(ChainBase):
""" """
return self.filter_torrents(rule_groups=rule_groups, return self.filter_torrents(rule_groups=rule_groups,
torrent_list=torrent_list, torrent_list=torrent_list,
season_episodes=season_episodes,
mediainfo=mediainfo) or [] mediainfo=mediainfo) or []
# 豆瓣标题处理 # 豆瓣标题处理
@@ -185,7 +184,10 @@ class SearchChain(ChainBase):
# 开始过滤 # 开始过滤
self.progress.update(value=0, text=f'开始过滤,总 {len(torrents)} 个资源,请稍候...', self.progress.update(value=0, text=f'开始过滤,总 {len(torrents)} 个资源,请稍候...',
key=ProgressKey.Search) key=ProgressKey.Search)
# 匹配订阅附加参数
if filter_params:
logger.info(f'开始附加参数过滤,附加参数:{filter_params} ...')
torrents = [torrent for torrent in torrents if self.torrenthelper.filter_torrent(torrent, filter_params)]
# 开始过滤规则过滤 # 开始过滤规则过滤
if rule_groups is None: if rule_groups is None:
# 取搜索过滤规则 # 取搜索过滤规则
@@ -222,16 +224,18 @@ class SearchChain(ChainBase):
if not torrent.title: if not torrent.title:
continue continue
# 匹配订阅附加参数
if filter_params and not self.torrenthelper.filter_torrent(torrent_info=torrent,
filter_params=filter_params):
continue
# 识别元数据 # 识别元数据
torrent_meta = MetaInfo(title=torrent.title, subtitle=torrent.description, torrent_meta = MetaInfo(title=torrent.title, subtitle=torrent.description,
custom_words=custom_words) custom_words=custom_words)
if torrent.title != torrent_meta.org_string: if torrent.title != torrent_meta.org_string:
logger.info(f"种子名称应用识别词后发生改变:{torrent.title} => {torrent_meta.org_string}") logger.info(f"种子名称应用识别词后发生改变:{torrent.title} => {torrent_meta.org_string}")
# 季集数过滤
if season_episodes \
and not self.torrenthelper.match_season_episodes(
torrent=torrent,
meta=torrent_meta,
season_episodes=season_episodes):
continue
# 比对IMDBID # 比对IMDBID
if torrent.imdbid \ if torrent.imdbid \
and mediainfo.imdb_id \ and mediainfo.imdb_id \
+16 -13
View File
@@ -384,7 +384,7 @@ class SubscribeChain(ChainBase, metaclass=Singleton):
self.message.put('没有找到订阅!', title="订阅搜索", role="system") self.message.put('没有找到订阅!', title="订阅搜索", role="system")
logger.debug(f"search Lock released at {datetime.now()}") logger.debug(f"search Lock released at {datetime.now()}")
def update_subscribe_priority(self, subscribe: Subscribe, meta: MetaInfo, def update_subscribe_priority(self, subscribe: Subscribe, meta: MetaBase,
mediainfo: MediaInfo, downloads: List[Context]): mediainfo: MediaInfo, downloads: List[Context]):
""" """
更新订阅已下载资源的优先级 更新订阅已下载资源的优先级
@@ -407,7 +407,7 @@ class SubscribeChain(ChainBase, metaclass=Singleton):
# 正在洗版,更新资源优先级 # 正在洗版,更新资源优先级
logger.info(f'{mediainfo.title_year} 正在洗版,更新资源优先级为 {priority}') logger.info(f'{mediainfo.title_year} 正在洗版,更新资源优先级为 {priority}')
def finish_subscribe_or_not(self, subscribe: Subscribe, meta: MetaInfo, mediainfo: MediaInfo, def finish_subscribe_or_not(self, subscribe: Subscribe, meta: MetaBase, mediainfo: MediaInfo,
downloads: List[Context] = None, downloads: List[Context] = None,
lefts: Dict[Union[int | str], Dict[int, NotExistMediaInfo]] = None, lefts: Dict[Union[int | str], Dict[int, NotExistMediaInfo]] = None,
force: bool = False): force: bool = False):
@@ -584,6 +584,8 @@ class SubscribeChain(ChainBase, metaclass=Singleton):
# 重新识别元数据 # 重新识别元数据
torrent_meta = MetaInfo(title=torrent_info.title, subtitle=torrent_info.description, torrent_meta = MetaInfo(title=torrent_info.title, subtitle=torrent_info.description,
custom_words=custom_words_list) custom_words=custom_words_list)
# 更新识别元数据缓存
context.meta_info = torrent_meta
# 媒体信息需要重新识别 # 媒体信息需要重新识别
torrent_mediainfo = None torrent_mediainfo = None
@@ -1145,16 +1147,17 @@ class SubscribeChain(ChainBase, metaclass=Singleton):
# 默认过滤规则 # 默认过滤规则
default_rule = self.systemconfig.get(SystemConfigKey.SubscribeDefaultParams) or {} default_rule = self.systemconfig.get(SystemConfigKey.SubscribeDefaultParams) or {}
return { return {
"include": subscribe.include or default_rule.get("include"), key: value for key, value in {
"exclude": subscribe.exclude or default_rule.get("exclude"), "include": subscribe.include or default_rule.get("include"),
"quality": subscribe.quality or default_rule.get("quality"), "exclude": subscribe.exclude or default_rule.get("exclude"),
"resolution": subscribe.resolution or default_rule.get("resolution"), "quality": subscribe.quality or default_rule.get("quality"),
"effect": subscribe.effect or default_rule.get("effect"), "resolution": subscribe.resolution or default_rule.get("resolution"),
"tv_size": default_rule.get("tv_size"), "effect": subscribe.effect or default_rule.get("effect"),
"movie_size": default_rule.get("movie_size"), "tv_size": default_rule.get("tv_size"),
"min_seeders": default_rule.get("min_seeders"), "movie_size": default_rule.get("movie_size"),
"min_seeders_time": default_rule.get("min_seeders_time"), "min_seeders": default_rule.get("min_seeders"),
} "min_seeders_time": default_rule.get("min_seeders_time"),
}.items() if value is not None}
def subscribe_files_info(self, subscribe: Subscribe) -> Optional[SubscrbieInfo]: def subscribe_files_info(self, subscribe: Subscribe) -> Optional[SubscrbieInfo]:
""" """
@@ -1266,7 +1269,7 @@ class SubscribeChain(ChainBase, metaclass=Singleton):
subscribe_info.episodes = episodes subscribe_info.episodes = episodes
return subscribe_info return subscribe_info
def check_and_handle_existing_media(self, subscribe: Subscribe, meta: MetaInfo, def check_and_handle_existing_media(self, subscribe: Subscribe, meta: MetaBase,
mediainfo: MediaInfo, mediakey: str): mediainfo: MediaInfo, mediakey: str):
""" """
检查媒体是否已经存在,并根据情况执行相应的操作 检查媒体是否已经存在,并根据情况执行相应的操作
+36 -1
View File
@@ -9,7 +9,7 @@ from torrentool.api import Torrent
from app.core.config import settings from app.core.config import settings
from app.core.context import Context, TorrentInfo, MediaInfo from app.core.context import Context, TorrentInfo, MediaInfo
from app.core.metainfo import MetaInfo from app.core.metainfo import MetaBase, MetaInfo
from app.db.site_oper import SiteOper from app.db.site_oper import SiteOper
from app.db.systemconfig_oper import SystemConfigOper from app.db.systemconfig_oper import SystemConfigOper
from app.log import logger from app.log import logger
@@ -445,3 +445,38 @@ class TorrentHelper(metaclass=Singleton):
return False return False
return True return True
@staticmethod
def match_season_episodes(torrent: TorrentInfo, meta: MetaBase, season_episodes: Dict[int, list]) -> bool:
"""
判断种子是否匹配季集数
:param torrent: 种子信息
:param meta: 种子元数据
:param season_episodes: 季集数 {season:[episodes]}
"""
# 匹配季
seasons = season_episodes.keys()
# 种子季
torrent_seasons = meta.season_list
if not torrent_seasons:
# 按第一季处理
torrent_seasons = [1]
# 种子集
torrent_episodes = meta.episode_list
if not set(torrent_seasons).issubset(set(seasons)):
# 种子季不在过滤季中
logger.debug(
f"种子 {torrent.site_name} - {torrent.title} 包含季 {torrent_seasons} 不是需要的季 {list(seasons)}")
return False
if not torrent_episodes:
# 整季按匹配处理
return True
if len(torrent_seasons) == 1:
need_episodes = season_episodes.get(torrent_seasons[0])
if need_episodes \
and not set(torrent_episodes).intersection(set(need_episodes)):
# 单季集没有交集的不要
logger.debug(f"种子 {torrent.site_name} - {torrent.title} "
f"{torrent_episodes} 没有需要的集:{need_episodes}")
return False
return True
+3 -44
View File
@@ -192,13 +192,11 @@ class FilterModule(_ModuleBase):
def filter_torrents(self, rule_groups: List[str], def filter_torrents(self, rule_groups: List[str],
torrent_list: List[TorrentInfo], torrent_list: List[TorrentInfo],
season_episodes: Dict[int, list] = None,
mediainfo: MediaInfo = None) -> List[TorrentInfo]: mediainfo: MediaInfo = None) -> List[TorrentInfo]:
""" """
过滤种子资源 过滤种子资源
:param rule_groups: 过滤规则组名称列表 :param rule_groups: 过滤规则组名称列表
:param torrent_list: 资源列表 :param torrent_list: 资源列表
:param season_episodes: 季集数过滤 {season:[episodes]}
:param mediainfo: 媒体信息 :param mediainfo: 媒体信息
:return: 过滤后的资源列表,添加资源优先级 :return: 过滤后的资源列表,添加资源优先级
""" """
@@ -215,24 +213,18 @@ class FilterModule(_ModuleBase):
torrent_list = self.__filter_torrents( torrent_list = self.__filter_torrents(
rule_string=group.rule_string, rule_string=group.rule_string,
rule_name=group.name, rule_name=group.name,
torrent_list=torrent_list, torrent_list=torrent_list
season_episodes=season_episodes )
)
return torrent_list return torrent_list
def __filter_torrents(self, rule_string: str, rule_name: str, def __filter_torrents(self, rule_string: str, rule_name: str,
torrent_list: List[TorrentInfo], torrent_list: List[TorrentInfo]) -> List[TorrentInfo]:
season_episodes: Dict[int, list]) -> List[TorrentInfo]:
""" """
过滤种子 过滤种子
""" """
# 返回种子列表 # 返回种子列表
ret_torrents = [] ret_torrents = []
for torrent in torrent_list: for torrent in torrent_list:
# 季集数过滤
if season_episodes \
and not self.__match_season_episodes(torrent, season_episodes):
continue
# 能命中优先级的才返回 # 能命中优先级的才返回
if not self.__get_order(torrent, rule_string): if not self.__get_order(torrent, rule_string):
logger.debug(f"种子 {torrent.site_name} - {torrent.title} {torrent.description} " logger.debug(f"种子 {torrent.site_name} - {torrent.title} {torrent.description} "
@@ -242,39 +234,6 @@ class FilterModule(_ModuleBase):
return ret_torrents return ret_torrents
@staticmethod
def __match_season_episodes(torrent: TorrentInfo, season_episodes: Dict[int, list]):
"""
判断种子是否匹配季集数
"""
# 匹配季
seasons = season_episodes.keys()
meta = MetaInfo(title=torrent.title, subtitle=torrent.description)
# 种子季
torrent_seasons = meta.season_list
if not torrent_seasons:
# 按第一季处理
torrent_seasons = [1]
# 种子集
torrent_episodes = meta.episode_list
if not set(torrent_seasons).issubset(set(seasons)):
# 种子季不在过滤季中
logger.debug(
f"种子 {torrent.site_name} - {torrent.title} 包含季 {torrent_seasons} 不是需要的季 {list(seasons)}")
return False
if not torrent_episodes:
# 整季按匹配处理
return True
if len(torrent_seasons) == 1:
need_episodes = season_episodes.get(torrent_seasons[0])
if need_episodes \
and not set(torrent_episodes).intersection(set(need_episodes)):
# 单季集没有交集的不要
logger.debug(f"种子 {torrent.site_name} - {torrent.title} "
f"{torrent_episodes} 没有需要的集:{need_episodes}")
return False
return True
def __get_order(self, torrent: TorrentInfo, rule_str: str) -> Optional[TorrentInfo]: def __get_order(self, torrent: TorrentInfo, rule_str: str) -> Optional[TorrentInfo]:
""" """
获取种子匹配的规则优先级,值越大越优先,未匹配时返回None 获取种子匹配的规则优先级,值越大越优先,未匹配时返回None
+3 -3
View File
@@ -48,9 +48,9 @@ class TransferTask(BaseModel):
""" """
文件整理任务 文件整理任务
""" """
fileitem: FileItem = None fileitem: Optional[FileItem] = None
meta: Any = None meta: Optional[MetaInfo] = None
mediainfo: Optional[Any] = None mediainfo: Optional[MediaInfo] = None
target_directory: Optional[TransferDirectoryConf] = None target_directory: Optional[TransferDirectoryConf] = None
target_storage: Optional[str] = None target_storage: Optional[str] = None
target_path: Optional[Path] = None target_path: Optional[Path] = None