parent
70adbfe6b5
commit
d7c6c27679
@ -1,7 +1,7 @@
|
|||||||
import copy
|
import copy
|
||||||
import json
|
import json
|
||||||
import re
|
import re
|
||||||
from typing import Any, Optional, Dict
|
from typing import Any, Optional, Dict, Union
|
||||||
|
|
||||||
from app.chain import ChainBase
|
from app.chain import ChainBase
|
||||||
from app.chain.download import DownloadChain
|
from app.chain.download import DownloadChain
|
||||||
@ -14,7 +14,7 @@ from app.core.event import EventManager
|
|||||||
from app.core.meta import MetaBase
|
from app.core.meta import MetaBase
|
||||||
from app.helper.torrent import TorrentHelper
|
from app.helper.torrent import TorrentHelper
|
||||||
from app.log import logger
|
from app.log import logger
|
||||||
from app.schemas import Notification
|
from app.schemas import Notification, NotExistMediaInfo
|
||||||
from app.schemas.types import EventType, MessageChannel, MediaType
|
from app.schemas.types import EventType, MessageChannel, MediaType
|
||||||
from app.utils.string import StringUtils
|
from app.utils.string import StringUtils
|
||||||
|
|
||||||
@ -40,10 +40,47 @@ class MessageChain(ChainBase):
|
|||||||
self.downloadchain = DownloadChain()
|
self.downloadchain = DownloadChain()
|
||||||
self.subscribechain = SubscribeChain()
|
self.subscribechain = SubscribeChain()
|
||||||
self.searchchain = SearchChain()
|
self.searchchain = SearchChain()
|
||||||
self.medtachain = MediaChain()
|
self.mediachain = MediaChain()
|
||||||
self.eventmanager = EventManager()
|
self.eventmanager = EventManager()
|
||||||
self.torrenthelper = TorrentHelper()
|
self.torrenthelper = TorrentHelper()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def __get_noexits_info(
|
||||||
|
_meta: MetaBase,
|
||||||
|
_mediainfo: MediaInfo) -> Dict[Union[int, str], Dict[int, NotExistMediaInfo]]:
|
||||||
|
"""
|
||||||
|
获取缺失的媒体信息
|
||||||
|
"""
|
||||||
|
if _mediainfo.type == MediaType.TV:
|
||||||
|
_mediakey = _mediainfo.tmdb_id or _mediainfo.douban_id
|
||||||
|
_no_exists = {
|
||||||
|
_mediakey: {}
|
||||||
|
}
|
||||||
|
if _meta.begin_season:
|
||||||
|
episodes = _mediainfo.seasons.get(_meta.begin_season)
|
||||||
|
if not episodes:
|
||||||
|
return {}
|
||||||
|
_no_exists[_mediakey][_meta.begin_season] = NotExistMediaInfo(
|
||||||
|
season=_meta.begin_season,
|
||||||
|
episodes=[],
|
||||||
|
total_episode=len(episodes),
|
||||||
|
start_episode=episodes[0]
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
for sea, eps in _mediainfo.seasons.items():
|
||||||
|
if not eps:
|
||||||
|
continue
|
||||||
|
_no_exists[_mediakey][sea] = NotExistMediaInfo(
|
||||||
|
season=sea,
|
||||||
|
episodes=[],
|
||||||
|
total_episode=len(eps),
|
||||||
|
start_episode=eps[0]
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
_no_exists = {}
|
||||||
|
|
||||||
|
return _no_exists
|
||||||
|
|
||||||
def process(self, body: Any, form: Any, args: Any) -> None:
|
def process(self, body: Any, form: Any, args: Any) -> None:
|
||||||
"""
|
"""
|
||||||
识别消息内容,执行操作
|
识别消息内容,执行操作
|
||||||
@ -84,6 +121,7 @@ class MessageChain(ChainBase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
elif text.isdigit():
|
elif text.isdigit():
|
||||||
|
# 用户选择了具体的条目
|
||||||
# 缓存
|
# 缓存
|
||||||
cache_data: dict = user_cache.get(userid)
|
cache_data: dict = user_cache.get(userid)
|
||||||
# 选择项目
|
# 选择项目
|
||||||
@ -100,31 +138,44 @@ class MessageChain(ChainBase):
|
|||||||
# 缓存列表
|
# 缓存列表
|
||||||
cache_list: list = copy.deepcopy(cache_data.get('items'))
|
cache_list: list = copy.deepcopy(cache_data.get('items'))
|
||||||
# 选择
|
# 选择
|
||||||
if cache_type == "Search":
|
if cache_type in ["Search", "ReSearch"]:
|
||||||
|
# 当前媒体信息
|
||||||
mediainfo: MediaInfo = cache_list[_choice]
|
mediainfo: MediaInfo = cache_list[_choice]
|
||||||
_current_media = mediainfo
|
_current_media = mediainfo
|
||||||
# 查询缺失的媒体信息
|
# 查询缺失的媒体信息
|
||||||
exist_flag, no_exists = self.downloadchain.get_no_exists_info(meta=_current_meta,
|
exist_flag, no_exists = self.downloadchain.get_no_exists_info(meta=_current_meta,
|
||||||
mediainfo=_current_media)
|
mediainfo=_current_media)
|
||||||
if exist_flag:
|
if exist_flag and cache_type == "Search":
|
||||||
|
# 媒体库中已存在
|
||||||
self.post_message(
|
self.post_message(
|
||||||
Notification(channel=channel,
|
Notification(channel=channel,
|
||||||
title=f"{_current_media.title_year}"
|
title=f"{_current_media.title_year}"
|
||||||
f"{_current_meta.sea} 媒体库中已存在",
|
f"{_current_meta.sea} 媒体库中已存在,如需重新下载请发送:搜索 XXX 或 下载 XXX",
|
||||||
userid=userid))
|
userid=userid))
|
||||||
return
|
return
|
||||||
|
elif exist_flag:
|
||||||
|
# 没有缺失,但要全量重新搜索和下载
|
||||||
|
no_exists = self.__get_noexits_info(_current_meta, _current_media)
|
||||||
# 发送缺失的媒体信息
|
# 发送缺失的媒体信息
|
||||||
if no_exists:
|
messages = []
|
||||||
# 发送消息
|
if no_exists and cache_type == "Search":
|
||||||
|
# 发送缺失消息
|
||||||
mediakey = mediainfo.tmdb_id or mediainfo.douban_id
|
mediakey = mediainfo.tmdb_id or mediainfo.douban_id
|
||||||
messages = [
|
messages = [
|
||||||
f"第 {sea} 季缺失 {StringUtils.str_series(no_exist.episodes) if no_exist.episodes else no_exist.total_episode} 集"
|
f"第 {sea} 季缺失 {StringUtils.str_series(no_exist.episodes) if no_exist.episodes else no_exist.total_episode} 集"
|
||||||
for sea, no_exist in no_exists.get(mediakey).items()]
|
for sea, no_exist in no_exists.get(mediakey).items()]
|
||||||
|
elif no_exists:
|
||||||
|
# 发送总集数的消息
|
||||||
|
mediakey = mediainfo.tmdb_id or mediainfo.douban_id
|
||||||
|
messages = [
|
||||||
|
f"第 {sea} 季总 {no_exist.total_episode} 集"
|
||||||
|
for sea, no_exist in no_exists.get(mediakey).items()]
|
||||||
|
if messages:
|
||||||
self.post_message(Notification(channel=channel,
|
self.post_message(Notification(channel=channel,
|
||||||
title=f"{mediainfo.title_year}:\n" + "\n".join(messages),
|
title=f"{mediainfo.title_year}:\n" + "\n".join(messages),
|
||||||
userid=userid))
|
userid=userid))
|
||||||
# 搜索种子,过滤掉不需要的剧集,以便选择
|
# 搜索种子,过滤掉不需要的剧集,以便选择
|
||||||
logger.info(f"{mediainfo.title_year} 媒体库中不存在,开始搜索 ...")
|
logger.info(f"开始搜索 {mediainfo.title_year} ...")
|
||||||
self.post_message(
|
self.post_message(
|
||||||
Notification(channel=channel,
|
Notification(channel=channel,
|
||||||
title=f"开始搜索 {mediainfo.type.value} {mediainfo.title_year} ...",
|
title=f"开始搜索 {mediainfo.type.value} {mediainfo.title_year} ...",
|
||||||
@ -144,13 +195,16 @@ class MessageChain(ChainBase):
|
|||||||
# 判断是否设置自动下载
|
# 判断是否设置自动下载
|
||||||
auto_download_user = settings.AUTO_DOWNLOAD_USER
|
auto_download_user = settings.AUTO_DOWNLOAD_USER
|
||||||
# 匹配到自动下载用户
|
# 匹配到自动下载用户
|
||||||
if auto_download_user and (auto_download_user == "all" or any(userid == user for user in auto_download_user.split(","))):
|
if auto_download_user \
|
||||||
logger.info(f"用户 {userid} 在自动下载用户中,开始自动择优下载")
|
and (auto_download_user == "all"
|
||||||
|
or any(userid == user for user in auto_download_user.split(","))):
|
||||||
|
logger.info(f"用户 {userid} 在自动下载用户中,开始自动择优下载 ...")
|
||||||
# 自动选择下载
|
# 自动选择下载
|
||||||
self.__auto_download(channel=channel,
|
self.__auto_download(channel=channel,
|
||||||
cache_list=contexts,
|
cache_list=contexts,
|
||||||
userid=userid,
|
userid=userid,
|
||||||
username=username)
|
username=username,
|
||||||
|
no_exists=no_exists)
|
||||||
else:
|
else:
|
||||||
# 更新缓存
|
# 更新缓存
|
||||||
user_cache[userid] = {
|
user_cache[userid] = {
|
||||||
@ -165,19 +219,24 @@ class MessageChain(ChainBase):
|
|||||||
userid=userid,
|
userid=userid,
|
||||||
total=len(contexts))
|
total=len(contexts))
|
||||||
|
|
||||||
elif cache_type == "Subscribe":
|
elif cache_type in ["Subscribe", "ReSubscribe"]:
|
||||||
# 订阅媒体
|
# 订阅或洗版媒体
|
||||||
mediainfo: MediaInfo = cache_list[_choice]
|
mediainfo: MediaInfo = cache_list[_choice]
|
||||||
|
# 洗版标识
|
||||||
|
best_version = False
|
||||||
# 查询缺失的媒体信息
|
# 查询缺失的媒体信息
|
||||||
exist_flag, _ = self.downloadchain.get_no_exists_info(meta=_current_meta,
|
if cache_type == "Subscribe":
|
||||||
mediainfo=mediainfo)
|
exist_flag, _ = self.downloadchain.get_no_exists_info(meta=_current_meta,
|
||||||
if exist_flag:
|
mediainfo=mediainfo)
|
||||||
self.post_message(Notification(
|
if exist_flag:
|
||||||
channel=channel,
|
self.post_message(Notification(
|
||||||
title=f"{mediainfo.title_year}"
|
channel=channel,
|
||||||
f"{_current_meta.sea} 媒体库中已存在",
|
title=f"{mediainfo.title_year}"
|
||||||
userid=userid))
|
f"{_current_meta.sea} 媒体库中已存在,如需洗版请发送:洗版 XXX",
|
||||||
return
|
userid=userid))
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
best_version = True
|
||||||
# 添加订阅,状态为N
|
# 添加订阅,状态为N
|
||||||
self.subscribechain.add(title=mediainfo.title,
|
self.subscribechain.add(title=mediainfo.title,
|
||||||
year=mediainfo.year,
|
year=mediainfo.year,
|
||||||
@ -186,10 +245,11 @@ class MessageChain(ChainBase):
|
|||||||
season=_current_meta.begin_season,
|
season=_current_meta.begin_season,
|
||||||
channel=channel,
|
channel=channel,
|
||||||
userid=userid,
|
userid=userid,
|
||||||
username=username)
|
username=username,
|
||||||
|
best_version=best_version)
|
||||||
elif cache_type == "Torrent":
|
elif cache_type == "Torrent":
|
||||||
if int(text) == 0:
|
if int(text) == 0:
|
||||||
# 自动选择下载
|
# 自动选择下载,强制下载模式
|
||||||
self.__auto_download(channel=channel,
|
self.__auto_download(channel=channel,
|
||||||
cache_list=cache_list,
|
cache_list=cache_list,
|
||||||
userid=userid,
|
userid=userid,
|
||||||
@ -280,6 +340,14 @@ class MessageChain(ChainBase):
|
|||||||
# 订阅
|
# 订阅
|
||||||
content = re.sub(r"订阅[::\s]*", "", text)
|
content = re.sub(r"订阅[::\s]*", "", text)
|
||||||
action = "Subscribe"
|
action = "Subscribe"
|
||||||
|
elif text.startswith("洗版"):
|
||||||
|
# 洗版
|
||||||
|
content = re.sub(r"洗版[::\s]*", "", text)
|
||||||
|
action = "ReSubscribe"
|
||||||
|
elif text.startswith("搜索") or text.startswith("下载"):
|
||||||
|
# 重新搜索/下载
|
||||||
|
content = re.sub(r"(搜索|下载)[::\s]*", "", text)
|
||||||
|
action = "ReSearch"
|
||||||
elif text.startswith("#") \
|
elif text.startswith("#") \
|
||||||
or re.search(r"^请[问帮你]", text) \
|
or re.search(r"^请[问帮你]", text) \
|
||||||
or re.search(r"[??]$", text) \
|
or re.search(r"[??]$", text) \
|
||||||
@ -290,12 +358,12 @@ class MessageChain(ChainBase):
|
|||||||
action = "chat"
|
action = "chat"
|
||||||
else:
|
else:
|
||||||
# 搜索
|
# 搜索
|
||||||
content = re.sub(r"(搜索|下载)[::\s]*", "", text)
|
content = text
|
||||||
action = "Search"
|
action = "Search"
|
||||||
|
|
||||||
if action in ["Subscribe", "Search"]:
|
if action != "chat":
|
||||||
# 搜索
|
# 搜索
|
||||||
meta, medias = self.medtachain.search(content)
|
meta, medias = self.mediachain.search(content)
|
||||||
# 识别
|
# 识别
|
||||||
if not meta.name:
|
if not meta.name:
|
||||||
self.post_message(Notification(
|
self.post_message(Notification(
|
||||||
@ -334,20 +402,22 @@ class MessageChain(ChainBase):
|
|||||||
# 保存缓存
|
# 保存缓存
|
||||||
self.save_cache(user_cache, self._cache_file)
|
self.save_cache(user_cache, self._cache_file)
|
||||||
|
|
||||||
def __auto_download(self, channel, cache_list, userid, username):
|
def __auto_download(self, channel: MessageChannel, cache_list: list[Context],
|
||||||
|
userid: Union[str, int], username: str,
|
||||||
|
no_exists: Optional[Dict[Union[int, str], Dict[int, NotExistMediaInfo]]] = None):
|
||||||
"""
|
"""
|
||||||
自动择优下载
|
自动择优下载
|
||||||
"""
|
"""
|
||||||
# 查询缺失的媒体信息
|
if no_exists is None:
|
||||||
exist_flag, no_exists = self.downloadchain.get_no_exists_info(meta=_current_meta,
|
# 查询缺失的媒体信息
|
||||||
mediainfo=_current_media)
|
exist_flag, no_exists = self.downloadchain.get_no_exists_info(
|
||||||
if exist_flag:
|
meta=_current_meta,
|
||||||
self.post_message(Notification(
|
mediainfo=_current_media
|
||||||
channel=channel,
|
)
|
||||||
title=f"{_current_media.title_year}"
|
if exist_flag:
|
||||||
f"{_current_meta.sea} 媒体库中已存在",
|
# 媒体库中已存在,查询全量
|
||||||
userid=userid))
|
no_exists = self.__get_noexits_info(_current_meta, _current_media)
|
||||||
return
|
|
||||||
# 批量下载
|
# 批量下载
|
||||||
downloads, lefts = self.downloadchain.batch_download(contexts=cache_list,
|
downloads, lefts = self.downloadchain.batch_download(contexts=cache_list,
|
||||||
no_exists=no_exists,
|
no_exists=no_exists,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user