MoviePilot/app/chain/user_message.py
2023-06-06 07:15:17 +08:00

267 lines
11 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from typing import Dict
from fastapi import Request
from app.chain import _ChainBase
from app.chain.common import *
from app.chain.search import SearchChain
from app.core import MediaInfo, TorrentInfo, MetaInfo
from app.db.subscribes import Subscribes
from app.log import logger
from app.utils.types import EventType
class UserMessageChain(_ChainBase):
"""
外来消息处理链
"""
# 缓存的用户数据 {userid: {type: str, items: list}}
_user_cache: Dict[str, dict] = {}
# 每页数据量
_page_size: int = 8
# 当前页面
_current_page: int = 0
# 当前元数据
_current_meta: Optional[MetaInfo] = None
# 当前媒体信息
_current_media: Optional[MediaInfo] = None
def __init__(self):
super().__init__()
self.common = CommonChain()
self.subscribes = Subscribes()
self.searchchain = SearchChain()
def process(self, request: Request, *args, **kwargs) -> None:
"""
识别消息内容,执行操作
"""
# 获取消息内容
info: dict = self.run_module('message_parser', request=request)
if not info:
return
# 用户ID
userid = info.get('userid')
if not userid:
logger.debug(f'未识别到用户ID{request}')
return
# 消息内容
text = str(info.get('text')).strip() if info.get('text') else None
if not text:
logger.debug(f'未识别到消息内容:{request}')
return
logger.info(f'收到用户消息内容,用户:{userid},内容:{text}')
if text.startswith('/'):
# 执行命令
self.eventmanager.send_event(
EventType.CommandExcute,
{
"cmd": text
}
)
elif text.isdigit():
# 缓存
cache_data: dict = self._user_cache.get(userid)
# 选择项目
if not cache_data \
or not cache_data.get('items') \
or len(cache_data.get('items')) < int(text):
# 发送消息
self.common.post_message(title="输入有误!", userid=userid)
return
# 缓存类型
cache_type: str = cache_data.get('type')
# 缓存列表
cache_list: list = cache_data.get('items')
# 选择
if cache_type == "Search":
mediainfo: MediaInfo = cache_list[int(text) - 1]
self._current_media = mediainfo
# 检查是否已存在
exists: list = self.run_module('media_exists', mediainfo=mediainfo)
if exists:
# 已存在
self.common.post_message(
title=f"{mediainfo.type.value} {mediainfo.get_title_string()} 媒体库中已存在", userid=userid)
return
# 搜索种子
contexts = self.searchchain.process(meta=self._current_meta, mediainfo=mediainfo)
if not contexts:
# 没有数据
self.common.post_message(title=f"{mediainfo.title} 未搜索到资源!", userid=userid)
return
# 更新缓存
self._user_cache[userid] = {
"type": "Torrent",
"items": contexts
}
self._current_page = 0
# 发送种子数据
self.__post_torrents_message(items=contexts[:self._page_size], userid=userid)
elif cache_type == "Subscribe":
# 订阅媒体
mediainfo: MediaInfo = cache_list[int(text) - 1]
self._current_media = mediainfo
state, msg = self.subscribes.add(mediainfo,
season=self._current_meta.begin_season,
episode=self._current_meta.begin_episode)
if state:
# 订阅成功
self.common.post_message(
title=f"{mediainfo.get_title_string()} 已添加订阅",
image=mediainfo.get_message_image(),
userid=userid)
else:
# 订阅失败
self.common.post_message(title=f"{mediainfo.title} 添加订阅失败:{msg}", userid=userid)
elif cache_type == "Torrent":
if int(text) == 0:
# 自动选择下载
# 查询缺失的媒体信息
exist_flag, no_exists = self.common.get_no_exists_info(mediainfo=self._current_media)
if exist_flag:
self.common.post_message(title=f"{self._current_media.get_title_string()} 媒体库中已存在",
userid=userid)
return
# 批量下载
self.common.batch_download(contexts=cache_list, need_tvs=no_exists, userid=userid)
else:
# 下载种子
torrent: TorrentInfo = cache_list[int(text) - 1]
# 识别种子信息
meta = MetaInfo(torrent.title)
# 预处理种子
torrent_file, msg = self.run_module("prepare_torrent", torrentinfo=torrent)
if not torrent_file:
# 下载失败
self.run_module('post_message',
title=f"{torrent.title} 种子下载失败!",
text=f"错误信息:{msg}\n种子链接:{torrent.enclosure}",
userid=userid)
return
# 添加下载
state, msg = self.run_module("download_torrent",
torrent_path=torrent_file,
mediainfo=self._current_media)
if not state:
# 下载失败
self.common.post_message(title=f"{torrent.title} 添加下载失败!",
text=f"错误信息:{msg}",
userid=userid)
return
# 下载成功,发送通知
self.common.post_download_message(meta=meta, mediainfo=self._current_media, torrent=torrent)
elif text.lower() == "p":
# 上一页
cache_data: dict = self._user_cache.get(userid)
if not cache_data:
# 没有缓存
self.common.post_message(title="输入有误!", userid=userid)
return
if self._current_page == 0:
# 第一页
self.common.post_message(title="已经是第一页了!", userid=userid)
return
cache_type: str = cache_data.get('type')
cache_list: list = cache_data.get('items')
# 减一页
self._current_page -= 1
if self._current_page == 0:
start = 0
end = self._page_size
else:
start = self._current_page * self._page_size
end = start + self._page_size
if cache_type == "Torrent":
# 发送种子数据
self.__post_torrents_message(items=cache_list[start:end], userid=userid)
else:
# 发送媒体数据
self.__post_medias_message(items=cache_list[start:end], userid=userid)
elif text.lower() == "n":
# 下一页
cache_data: dict = self._user_cache.get(userid)
if not cache_data:
# 没有缓存
self.common.post_message(title="输入有误!", userid=userid)
return
cache_type: str = cache_data.get('type')
cache_list: list = cache_data.get('items')
# 加一页
self._current_page += 1
cache_list = cache_list[self._current_page * self._page_size:]
if not cache_list:
# 没有数据
self.common.post_message(title="已经是最后一页了!", userid=userid)
return
else:
if cache_type == "Torrent":
# 发送种子数据
self.__post_torrents_message(items=cache_list, userid=userid)
else:
# 发送媒体数据
self.__post_medias_message(items=cache_list, userid=userid)
else:
# 搜索或订阅
if text.startswith("订阅"):
# 订阅
content = re.sub(r"订阅[:\s]*", "", text)
action = "Subscribe"
else:
# 搜索
content = re.sub(r"(搜索|下载)[:\s]*", "", text)
action = "Search"
# 提取要素
mtype, key_word, season_num, episode_num, year, title = StringUtils.get_keyword(content)
# 识别
meta = MetaInfo(title)
if not meta.get_name():
self.common.post_message(title="无法识别输入内容!", userid=userid)
return
# 合并信息
if mtype:
meta.type = mtype
if season_num:
meta.begin_season = season_num
if episode_num:
meta.begin_episode = episode_num
if year:
meta.year = year
self._current_meta = meta
# 开始搜索
medias = self.run_module('search_medias', meta=meta)
if not medias:
self.common.post_message(title=f"{meta.get_name()} 没有找到对应的媒体信息!", userid=userid)
return
self._user_cache[userid] = {
'type': action,
'items': medias
}
self._current_page = 0
self._current_media = None
# 发送媒体列表
self.__post_medias_message(items=medias[:self._page_size], userid=userid)
def __post_medias_message(self, items: list, userid: str):
"""
发送媒体列表消息
"""
self.run_module('post_medias_message',
title="请回复数字选择对应媒体p上一页, n下一页",
items=items,
userid=userid)
def __post_torrents_message(self, items: list, userid: str):
"""
发送种子列表消息
"""
self.run_module('post_torrents_message',
title="请回复数字下载对应资源0自动选择, p上一页, n下一页",
items=items,
userid=userid)