Merge remote-tracking branch 'origin/wlj0909' into wlj0909
This commit is contained in:
commit
f4633788e9
@ -223,16 +223,19 @@ class ChainBase(metaclass=ABCMeta):
|
|||||||
|
|
||||||
def filter_torrents(self, rule_string: str,
|
def filter_torrents(self, rule_string: str,
|
||||||
torrent_list: List[TorrentInfo],
|
torrent_list: List[TorrentInfo],
|
||||||
season_episodes: Dict[int, list] = None) -> List[TorrentInfo]:
|
season_episodes: Dict[int, list] = None,
|
||||||
|
mediainfo: MediaInfo = None) -> List[TorrentInfo]:
|
||||||
"""
|
"""
|
||||||
过滤种子资源
|
过滤种子资源
|
||||||
:param rule_string: 过滤规则
|
:param rule_string: 过滤规则
|
||||||
:param torrent_list: 资源列表
|
:param torrent_list: 资源列表
|
||||||
:param season_episodes: 季集数过滤 {season:[episodes]}
|
:param season_episodes: 季集数过滤 {season:[episodes]}
|
||||||
|
:param mediainfo: 识别的媒体信息
|
||||||
:return: 过滤后的资源列表,添加资源优先级
|
:return: 过滤后的资源列表,添加资源优先级
|
||||||
"""
|
"""
|
||||||
return self.run_module("filter_torrents", rule_string=rule_string,
|
return self.run_module("filter_torrents", rule_string=rule_string,
|
||||||
torrent_list=torrent_list, season_episodes=season_episodes)
|
torrent_list=torrent_list, season_episodes=season_episodes,
|
||||||
|
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
|
||||||
|
@ -225,7 +225,7 @@ class DownloadChain(ChainBase):
|
|||||||
self.downloadhis.add_files(files_to_add)
|
self.downloadhis.add_files(files_to_add)
|
||||||
|
|
||||||
# 发送消息
|
# 发送消息
|
||||||
self.post_download_message(meta=_meta, mediainfo=_media, torrent=_torrent, channel=channel)
|
self.post_download_message(meta=_meta, mediainfo=_media, torrent=_torrent, channel=channel, userid=userid)
|
||||||
# 下载成功后处理
|
# 下载成功后处理
|
||||||
self.download_added(context=context, download_dir=download_dir, torrent_path=torrent_file)
|
self.download_added(context=context, download_dir=download_dir, torrent_path=torrent_file)
|
||||||
# 广播事件
|
# 广播事件
|
||||||
|
@ -135,7 +135,8 @@ class SearchChain(ChainBase):
|
|||||||
logger.info(f'开始过滤资源,当前规则:{filter_rule} ...')
|
logger.info(f'开始过滤资源,当前规则:{filter_rule} ...')
|
||||||
result: List[TorrentInfo] = self.filter_torrents(rule_string=filter_rule,
|
result: List[TorrentInfo] = self.filter_torrents(rule_string=filter_rule,
|
||||||
torrent_list=torrents,
|
torrent_list=torrents,
|
||||||
season_episodes=season_episodes)
|
season_episodes=season_episodes,
|
||||||
|
mediainfo=mediainfo)
|
||||||
if result is not None:
|
if result is not None:
|
||||||
torrents = result
|
torrents = result
|
||||||
if not torrents:
|
if not torrents:
|
||||||
|
@ -512,7 +512,8 @@ class SubscribeChain(ChainBase):
|
|||||||
filter_rule = self.systemconfig.get(SystemConfigKey.FilterRules)
|
filter_rule = self.systemconfig.get(SystemConfigKey.FilterRules)
|
||||||
result: List[TorrentInfo] = self.filter_torrents(
|
result: List[TorrentInfo] = self.filter_torrents(
|
||||||
rule_string=filter_rule,
|
rule_string=filter_rule,
|
||||||
torrent_list=[torrent_info])
|
torrent_list=[torrent_info],
|
||||||
|
mediainfo=torrent_mediainfo)
|
||||||
if result is not None and not result:
|
if result is not None and not result:
|
||||||
# 不符合过滤规则
|
# 不符合过滤规则
|
||||||
logger.info(f"{torrent_info.title} 不匹配当前过滤规则")
|
logger.info(f"{torrent_info.title} 不匹配当前过滤规则")
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import glob
|
||||||
import re
|
import re
|
||||||
import shutil
|
import shutil
|
||||||
import threading
|
import threading
|
||||||
@ -601,8 +602,10 @@ class TransferChain(ChainBase):
|
|||||||
if not path.exists():
|
if not path.exists():
|
||||||
return
|
return
|
||||||
if path.is_file():
|
if path.is_file():
|
||||||
# 删除文件
|
# 删除文件、nfo、jpg
|
||||||
path.unlink()
|
files = glob.glob(f"{Path(path.parent).joinpath(path.stem)}*")
|
||||||
|
for file in files:
|
||||||
|
Path(file).unlink()
|
||||||
logger.warn(f"文件 {path} 已删除")
|
logger.warn(f"文件 {path} 已删除")
|
||||||
# 需要删除父目录
|
# 需要删除父目录
|
||||||
elif str(path.parent) == str(path.root):
|
elif str(path.parent) == str(path.root):
|
||||||
@ -615,11 +618,24 @@ class TransferChain(ChainBase):
|
|||||||
# 删除目录
|
# 删除目录
|
||||||
logger.warn(f"目录 {path} 已删除")
|
logger.warn(f"目录 {path} 已删除")
|
||||||
# 需要删除父目录
|
# 需要删除父目录
|
||||||
# 判断父目录是否为空, 为空则删除
|
|
||||||
for parent_path in path.parents:
|
# 判断当前媒体父路径下是否有媒体文件,如有则无需遍历父级
|
||||||
if str(parent_path.parent) != str(path.root):
|
if not SystemUtils.exits_files(path.parent, settings.RMT_MEDIAEXT):
|
||||||
# 父目录非根目录,才删除父目录
|
# 媒体库二级分类根路径
|
||||||
files = SystemUtils.list_files(parent_path, settings.RMT_MEDIAEXT)
|
library_root_names = [
|
||||||
if not files:
|
settings.LIBRARY_MOVIE_NAME or '电影',
|
||||||
shutil.rmtree(parent_path)
|
settings.LIBRARY_TV_NAME or '电视剧',
|
||||||
logger.warn(f"目录 {parent_path} 已删除")
|
settings.LIBRARY_ANIME_NAME or '动漫',
|
||||||
|
]
|
||||||
|
|
||||||
|
# 判断父目录是否为空, 为空则删除
|
||||||
|
for parent_path in path.parents:
|
||||||
|
# 遍历父目录到媒体库二级分类根路径
|
||||||
|
if str(parent_path.name) in library_root_names:
|
||||||
|
break
|
||||||
|
if str(parent_path.parent) != str(path.root):
|
||||||
|
# 父目录非根目录,才删除父目录
|
||||||
|
if not SystemUtils.exits_files(path.parent, settings.RMT_MEDIAEXT):
|
||||||
|
# 当前路径下没有媒体文件则删除
|
||||||
|
shutil.rmtree(parent_path)
|
||||||
|
logger.warn(f"目录 {parent_path} 已删除")
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import re
|
import re
|
||||||
from typing import List, Tuple, Union, Dict, Optional
|
from typing import List, Tuple, Union, Dict, Optional
|
||||||
|
|
||||||
from app.core.context import TorrentInfo
|
from app.core.context import TorrentInfo, MediaInfo
|
||||||
from app.core.metainfo import MetaInfo
|
from app.core.metainfo import MetaInfo
|
||||||
from app.log import logger
|
from app.log import logger
|
||||||
from app.modules import _ModuleBase
|
from app.modules import _ModuleBase
|
||||||
@ -9,9 +9,10 @@ from app.modules.filter.RuleParser import RuleParser
|
|||||||
|
|
||||||
|
|
||||||
class FilterModule(_ModuleBase):
|
class FilterModule(_ModuleBase):
|
||||||
|
|
||||||
# 规则解析器
|
# 规则解析器
|
||||||
parser: RuleParser = None
|
parser: RuleParser = None
|
||||||
|
# 媒体信息
|
||||||
|
media: MediaInfo = None
|
||||||
|
|
||||||
# 内置规则集
|
# 内置规则集
|
||||||
rule_set: Dict[str, dict] = {
|
rule_set: Dict[str, dict] = {
|
||||||
@ -37,8 +38,13 @@ class FilterModule(_ModuleBase):
|
|||||||
},
|
},
|
||||||
# 中字
|
# 中字
|
||||||
"CNSUB": {
|
"CNSUB": {
|
||||||
"include": [r'[中国國繁简](/|\s|\\|\|)?[繁简英粤]|[英简繁](/|\s|\\|\|)?[中繁简]|繁體|简体|[中国國][字配]|国语|國語|中文|中字'],
|
"include": [
|
||||||
"exclude": []
|
r'[中国國繁简](/|\s|\\|\|)?[繁简英粤]|[英简繁](/|\s|\\|\|)?[中繁简]|繁體|简体|[中国國][字配]|国语|國語|中文|中字'],
|
||||||
|
"exclude": [],
|
||||||
|
# 只处理对应TMDB信息的数据
|
||||||
|
"tmdb": {
|
||||||
|
"original_language": "zh,cn"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
# 特效字幕
|
# 特效字幕
|
||||||
"SPECSUB": {
|
"SPECSUB": {
|
||||||
@ -107,16 +113,19 @@ class FilterModule(_ModuleBase):
|
|||||||
|
|
||||||
def filter_torrents(self, rule_string: str,
|
def filter_torrents(self, rule_string: str,
|
||||||
torrent_list: List[TorrentInfo],
|
torrent_list: List[TorrentInfo],
|
||||||
season_episodes: Dict[int, list] = None) -> List[TorrentInfo]:
|
season_episodes: Dict[int, list] = None,
|
||||||
|
mediainfo: MediaInfo = None) -> List[TorrentInfo]:
|
||||||
"""
|
"""
|
||||||
过滤种子资源
|
过滤种子资源
|
||||||
:param rule_string: 过滤规则
|
:param rule_string: 过滤规则
|
||||||
:param torrent_list: 资源列表
|
:param torrent_list: 资源列表
|
||||||
:param season_episodes: 季集数过滤 {season:[episodes]}
|
:param season_episodes: 季集数过滤 {season:[episodes]}
|
||||||
|
:param mediainfo: 媒体信息
|
||||||
:return: 过滤后的资源列表,添加资源优先级
|
:return: 过滤后的资源列表,添加资源优先级
|
||||||
"""
|
"""
|
||||||
if not rule_string:
|
if not rule_string:
|
||||||
return torrent_list
|
return torrent_list
|
||||||
|
self.media = mediainfo
|
||||||
# 返回种子列表
|
# 返回种子列表
|
||||||
ret_torrents = []
|
ret_torrents = []
|
||||||
for torrent in torrent_list:
|
for torrent in torrent_list:
|
||||||
@ -215,6 +224,11 @@ class FilterModule(_ModuleBase):
|
|||||||
if not self.rule_set.get(rule_name):
|
if not self.rule_set.get(rule_name):
|
||||||
# 规则不存在
|
# 规则不存在
|
||||||
return False
|
return False
|
||||||
|
# TMDB规则
|
||||||
|
tmdb = self.rule_set[rule_name].get("tmdb")
|
||||||
|
# 不符合TMDB规则的直接返回True,即不过滤
|
||||||
|
if tmdb and not self.__match_tmdb(tmdb):
|
||||||
|
return True
|
||||||
# 包含规则项
|
# 包含规则项
|
||||||
includes = self.rule_set[rule_name].get("include") or []
|
includes = self.rule_set[rule_name].get("include") or []
|
||||||
# 排除规则项
|
# 排除规则项
|
||||||
@ -236,3 +250,44 @@ class FilterModule(_ModuleBase):
|
|||||||
# FREE规则不匹配
|
# FREE规则不匹配
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def __match_tmdb(self, tmdb: dict) -> bool:
|
||||||
|
"""
|
||||||
|
判断种子是否匹配TMDB规则
|
||||||
|
"""
|
||||||
|
def __get_media_value(key: str):
|
||||||
|
try:
|
||||||
|
return getattr(self.media, key)
|
||||||
|
except ValueError:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
if not self.media:
|
||||||
|
return False
|
||||||
|
|
||||||
|
for attr, value in tmdb.items():
|
||||||
|
if not value:
|
||||||
|
continue
|
||||||
|
# 获取media信息的值
|
||||||
|
info_value = __get_media_value(attr)
|
||||||
|
if not info_value:
|
||||||
|
# 没有该值,不匹配
|
||||||
|
return False
|
||||||
|
elif attr == "production_countries":
|
||||||
|
# 国家信息
|
||||||
|
info_values = [str(val.get("iso_3166_1")).upper() for val in info_value]
|
||||||
|
else:
|
||||||
|
# media信息转化为数组
|
||||||
|
if isinstance(info_value, list):
|
||||||
|
info_values = [str(val).upper() for val in info_value]
|
||||||
|
else:
|
||||||
|
info_values = [str(info_value).upper()]
|
||||||
|
# 过滤值转化为数组
|
||||||
|
if value.find(",") != -1:
|
||||||
|
values = [str(val).upper() for val in value.split(",")]
|
||||||
|
else:
|
||||||
|
values = [str(value).upper()]
|
||||||
|
# 没有交集为不匹配
|
||||||
|
if not set(values).intersection(set(info_values)):
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
@ -131,7 +131,7 @@ class TransmissionModule(_ModuleBase):
|
|||||||
title=torrent.name,
|
title=torrent.name,
|
||||||
path=Path(torrent.download_dir) / torrent.name,
|
path=Path(torrent.download_dir) / torrent.name,
|
||||||
hash=torrent.hashString,
|
hash=torrent.hashString,
|
||||||
tags=torrent.labels
|
tags=",".join(torrent.labels or [])
|
||||||
))
|
))
|
||||||
elif status == TorrentStatus.DOWNLOADING:
|
elif status == TorrentStatus.DOWNLOADING:
|
||||||
# 获取正在下载的任务
|
# 获取正在下载的任务
|
||||||
|
@ -593,7 +593,8 @@ class RssSubscribe(_PluginBase):
|
|||||||
if self._filter:
|
if self._filter:
|
||||||
result = self.chain.filter_torrents(
|
result = self.chain.filter_torrents(
|
||||||
rule_string=filter_rule,
|
rule_string=filter_rule,
|
||||||
torrent_list=[torrentinfo]
|
torrent_list=[torrentinfo],
|
||||||
|
mediainfo=mediainfo
|
||||||
)
|
)
|
||||||
if not result:
|
if not result:
|
||||||
logger.info(f"{title} {description} 不匹配过滤规则")
|
logger.info(f"{title} {description} 不匹配过滤规则")
|
||||||
|
@ -106,7 +106,7 @@ class SystemUtils:
|
|||||||
|
|
||||||
if directory.is_file():
|
if directory.is_file():
|
||||||
return [directory]
|
return [directory]
|
||||||
|
|
||||||
if not min_filesize:
|
if not min_filesize:
|
||||||
min_filesize = 0
|
min_filesize = 0
|
||||||
|
|
||||||
@ -122,6 +122,36 @@ class SystemUtils:
|
|||||||
|
|
||||||
return files
|
return files
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def exits_files(directory: Path, extensions: list, min_filesize: int = 0) -> bool:
|
||||||
|
"""
|
||||||
|
判断目录下是否存在指定扩展名的文件
|
||||||
|
:return True存在 False不存在
|
||||||
|
"""
|
||||||
|
|
||||||
|
if not min_filesize:
|
||||||
|
min_filesize = 0
|
||||||
|
|
||||||
|
if not directory.exists():
|
||||||
|
return False
|
||||||
|
|
||||||
|
if directory.is_file():
|
||||||
|
return True
|
||||||
|
|
||||||
|
if not min_filesize:
|
||||||
|
min_filesize = 0
|
||||||
|
|
||||||
|
pattern = r".*(" + "|".join(extensions) + ")$"
|
||||||
|
|
||||||
|
# 遍历目录及子目录
|
||||||
|
for path in directory.rglob('**/*'):
|
||||||
|
if path.is_file() \
|
||||||
|
and re.match(pattern, path.name, re.IGNORECASE) \
|
||||||
|
and path.stat().st_size >= min_filesize * 1024 * 1024:
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def list_sub_files(directory: Path, extensions: list) -> List[Path]:
|
def list_sub_files(directory: Path, extensions: list) -> List[Path]:
|
||||||
"""
|
"""
|
||||||
|
Loading…
x
Reference in New Issue
Block a user