mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-02-03 02:25:32 +08:00
fix 远程交互命令
This commit is contained in:
@@ -19,16 +19,7 @@ from app.utils.object import ObjectUtils
|
||||
from app.utils.singleton import Singleton
|
||||
|
||||
|
||||
class CommandChian(ChainBase):
|
||||
"""
|
||||
插件处理链
|
||||
"""
|
||||
|
||||
def process(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
|
||||
class Command(metaclass=Singleton):
|
||||
class CommandChain(ChainBase, metaclass=Singleton):
|
||||
"""
|
||||
全局命令管理,消费事件
|
||||
"""
|
||||
@@ -37,14 +28,14 @@ class Command(metaclass=Singleton):
|
||||
|
||||
def __init__(self):
|
||||
# 插件管理器
|
||||
super().__init__()
|
||||
self.pluginmanager = PluginManager()
|
||||
# 处理链
|
||||
self.chain = CommandChian()
|
||||
# 定时服务管理
|
||||
self.scheduler = Scheduler()
|
||||
# 消息管理器
|
||||
self.messagehelper = MessageHelper()
|
||||
# 内置命令
|
||||
# 内置命令:标准参数 arg_str: str, channel: MessageChannel, userid: Union[str, int] = None, source: str = None
|
||||
# 其中 arg_str 为用户输入的参数,channel 为消息渠道,userid 为用户ID,source 为消息来源,arg_str 可选
|
||||
self._commands = {
|
||||
"/cookiecloud": {
|
||||
"id": "cookiecloud",
|
||||
@@ -148,7 +139,7 @@ class Command(metaclass=Singleton):
|
||||
for command in plugin_commands:
|
||||
self.register(
|
||||
cmd=command.get('cmd'),
|
||||
func=Command.send_plugin_event,
|
||||
func=self.send_plugin_event,
|
||||
desc=command.get('desc'),
|
||||
category=command.get('category'),
|
||||
data={
|
||||
@@ -158,9 +149,7 @@ class Command(metaclass=Singleton):
|
||||
)
|
||||
# 广播注册命令菜单
|
||||
if not settings.DEV:
|
||||
self.chain.register_commands(commands=self.get_commands())
|
||||
# 重启msg
|
||||
SystemChain().restart_finish()
|
||||
self.register_commands(commands=self.get_commands())
|
||||
|
||||
def __run_command(self, command: Dict[str, any], data_str: str = "",
|
||||
channel: MessageChannel = None, source: str = None, userid: Union[str, int] = None):
|
||||
@@ -170,7 +159,7 @@ class Command(metaclass=Singleton):
|
||||
if command.get("type") == "scheduler":
|
||||
# 定时服务
|
||||
if userid:
|
||||
self.chain.post_message(
|
||||
self.post_message(
|
||||
Notification(
|
||||
channel=channel,
|
||||
source=source,
|
||||
@@ -183,7 +172,7 @@ class Command(metaclass=Singleton):
|
||||
self.scheduler.start(job_id=command.get("id"))
|
||||
|
||||
if userid:
|
||||
self.chain.post_message(
|
||||
self.post_message(
|
||||
Notification(
|
||||
channel=channel,
|
||||
source=source,
|
||||
@@ -203,15 +192,15 @@ class Command(metaclass=Singleton):
|
||||
data['source'] = source
|
||||
data['user'] = userid
|
||||
if data_str:
|
||||
data['args'] = data_str
|
||||
data['arg_str'] = data_str
|
||||
cmd_data['data'] = data
|
||||
command['func'](**cmd_data)
|
||||
elif args_num == 3:
|
||||
# 没有输入参数,只输入渠道来源、和用户ID
|
||||
command['func'](channel, source, userid)
|
||||
# 没有输入参数,只输入渠道来源、用户ID和消息来源
|
||||
command['func'](channel, userid, source)
|
||||
elif args_num > 3:
|
||||
# 多个输入参数:用户输入、用户ID
|
||||
command['func'](data_str, channel, source, userid)
|
||||
command['func'](data_str, channel, userid, source)
|
||||
else:
|
||||
# 没有参数
|
||||
command['func']()
|
||||
@@ -295,4 +284,5 @@ class Command(metaclass=Singleton):
|
||||
cmd = event_str.split()[0]
|
||||
args = " ".join(event_str.split()[1:])
|
||||
if self.get(cmd):
|
||||
self.execute(cmd, args, event_channel, event_source, event_user)
|
||||
self.execute(cmd=cmd, data_str=args,
|
||||
channel=event_channel, source=event_source, userid=event_user)
|
||||
@@ -874,7 +874,7 @@ class DownloadChain(ChainBase):
|
||||
# 全部存在
|
||||
return True, no_exists
|
||||
|
||||
def remote_downloading(self, channel: MessageChannel, source: str, userid: Union[str, int] = None):
|
||||
def remote_downloading(self, channel: MessageChannel, userid: Union[str, int] = None, source: str = None):
|
||||
"""
|
||||
查询正在下载的任务,并发送消息
|
||||
"""
|
||||
|
||||
@@ -504,7 +504,8 @@ class SiteChain(ChainBase):
|
||||
return False, f"无法打开网站!"
|
||||
return True, "连接成功"
|
||||
|
||||
def remote_list(self, channel: MessageChannel, userid: Union[str, int] = None):
|
||||
def remote_list(self, channel: MessageChannel,
|
||||
userid: Union[str, int] = None, source: str = None):
|
||||
"""
|
||||
查询所有站点,发送消息
|
||||
"""
|
||||
@@ -532,10 +533,13 @@ class SiteChain(ChainBase):
|
||||
# 发送列表
|
||||
self.post_message(Notification(
|
||||
channel=channel,
|
||||
source=source,
|
||||
title=title, text="\n".join(messages), userid=userid,
|
||||
link=settings.MP_DOMAIN('#/site')))
|
||||
link=settings.MP_DOMAIN('#/site'))
|
||||
)
|
||||
|
||||
def remote_disable(self, arg_str, channel: MessageChannel, userid: Union[str, int] = None):
|
||||
def remote_disable(self, arg_str: str, channel: MessageChannel,
|
||||
userid: Union[str, int] = None, source: str = None):
|
||||
"""
|
||||
禁用站点
|
||||
"""
|
||||
@@ -557,9 +561,10 @@ class SiteChain(ChainBase):
|
||||
"is_active": False
|
||||
})
|
||||
# 重新发送消息
|
||||
self.remote_list(channel, userid)
|
||||
self.remote_list(channel=channel, userid=userid, source=source)
|
||||
|
||||
def remote_enable(self, arg_str, channel: MessageChannel, userid: Union[str, int] = None):
|
||||
def remote_enable(self, arg_str: str, channel: MessageChannel,
|
||||
userid: Union[str, int] = None, source: str = None):
|
||||
"""
|
||||
启用站点
|
||||
"""
|
||||
@@ -582,7 +587,7 @@ class SiteChain(ChainBase):
|
||||
"is_active": True
|
||||
})
|
||||
# 重新发送消息
|
||||
self.remote_list(channel, userid)
|
||||
self.remote_list(channel=channel, userid=userid, source=source)
|
||||
|
||||
def update_cookie(self, site_info: Site,
|
||||
username: str, password: str, two_step_code: str = None) -> Tuple[bool, str]:
|
||||
@@ -613,7 +618,8 @@ class SiteChain(ChainBase):
|
||||
return True, msg
|
||||
return False, "未知错误"
|
||||
|
||||
def remote_cookie(self, arg_str: str, channel: MessageChannel, userid: Union[str, int] = None):
|
||||
def remote_cookie(self, arg_str: str, channel: MessageChannel,
|
||||
userid: Union[str, int] = None, source: str = None):
|
||||
"""
|
||||
使用用户名密码更新站点Cookie
|
||||
"""
|
||||
@@ -622,6 +628,7 @@ class SiteChain(ChainBase):
|
||||
if not arg_str:
|
||||
self.post_message(Notification(
|
||||
channel=channel,
|
||||
source=source,
|
||||
title=err_title, userid=userid))
|
||||
return
|
||||
arg_str = str(arg_str).strip()
|
||||
@@ -633,12 +640,14 @@ class SiteChain(ChainBase):
|
||||
elif len(args) != 3:
|
||||
self.post_message(Notification(
|
||||
channel=channel,
|
||||
source=source,
|
||||
title=err_title, userid=userid))
|
||||
return
|
||||
site_id = args[0]
|
||||
if not site_id.isdigit():
|
||||
self.post_message(Notification(
|
||||
channel=channel,
|
||||
source=source,
|
||||
title=err_title, userid=userid))
|
||||
return
|
||||
# 站点ID
|
||||
@@ -648,10 +657,12 @@ class SiteChain(ChainBase):
|
||||
if not site_info:
|
||||
self.post_message(Notification(
|
||||
channel=channel,
|
||||
source=source,
|
||||
title=f"站点编号 {site_id} 不存在!", userid=userid))
|
||||
return
|
||||
self.post_message(Notification(
|
||||
channel=channel,
|
||||
source=source,
|
||||
title=f"开始更新【{site_info.name}】Cookie&UA ...", userid=userid))
|
||||
# 用户名
|
||||
username = args[1]
|
||||
@@ -666,11 +677,13 @@ class SiteChain(ChainBase):
|
||||
logger.error(msg)
|
||||
self.post_message(Notification(
|
||||
channel=channel,
|
||||
source=source,
|
||||
title=f"【{site_info.name}】 Cookie&UA更新失败!",
|
||||
text=f"错误原因:{msg}",
|
||||
userid=userid))
|
||||
else:
|
||||
self.post_message(Notification(
|
||||
channel=channel,
|
||||
source=source,
|
||||
title=f"【{site_info.name}】 Cookie&UA更新成功",
|
||||
userid=userid))
|
||||
|
||||
@@ -941,13 +941,15 @@ class SubscribeChain(ChainBase):
|
||||
"doubanid": mediainfo.douban_id
|
||||
})
|
||||
|
||||
def remote_list(self, channel: MessageChannel, userid: Union[str, int] = None):
|
||||
def remote_list(self, channel: MessageChannel,
|
||||
userid: Union[str, int] = None, source: str = None):
|
||||
"""
|
||||
查询订阅并发送消息
|
||||
"""
|
||||
subscribes = self.subscribeoper.list()
|
||||
if not subscribes:
|
||||
self.post_message(Notification(channel=channel,
|
||||
source=source,
|
||||
title='没有任何订阅!', userid=userid))
|
||||
return
|
||||
title = f"共有 {len(subscribes)} 个订阅,回复对应指令操作: " \
|
||||
@@ -964,15 +966,16 @@ class SubscribeChain(ChainBase):
|
||||
f"[{subscribe.total_episode - (subscribe.lack_episode or subscribe.total_episode)}"
|
||||
f"/{subscribe.total_episode}]")
|
||||
# 发送列表
|
||||
self.post_message(Notification(channel=channel,
|
||||
self.post_message(Notification(channel=channel, source=source,
|
||||
title=title, text='\n'.join(messages), userid=userid))
|
||||
|
||||
def remote_delete(self, arg_str: str, channel: MessageChannel, userid: Union[str, int] = None):
|
||||
def remote_delete(self, arg_str: str, channel: MessageChannel,
|
||||
userid: Union[str, int] = None, source: str = None):
|
||||
"""
|
||||
删除订阅
|
||||
"""
|
||||
if not arg_str:
|
||||
self.post_message(Notification(channel=channel,
|
||||
self.post_message(Notification(channel=channel, source=source,
|
||||
title="请输入正确的命令格式:/subscribe_delete [id],"
|
||||
"[id]为订阅编号", userid=userid))
|
||||
return
|
||||
@@ -984,7 +987,7 @@ class SubscribeChain(ChainBase):
|
||||
subscribe_id = int(arg_str)
|
||||
subscribe = self.subscribeoper.get(subscribe_id)
|
||||
if not subscribe:
|
||||
self.post_message(Notification(channel=channel,
|
||||
self.post_message(Notification(channel=channel, source=source,
|
||||
title=f"订阅编号 {subscribe_id} 不存在!", userid=userid))
|
||||
return
|
||||
# 删除订阅
|
||||
@@ -995,7 +998,7 @@ class SubscribeChain(ChainBase):
|
||||
"doubanid": subscribe.doubanid
|
||||
})
|
||||
# 重新发送消息
|
||||
self.remote_list(channel, userid)
|
||||
self.remote_list(channel=channel, userid=userid, source=source)
|
||||
|
||||
@staticmethod
|
||||
def __get_subscribe_no_exits(subscribe_name: str,
|
||||
|
||||
@@ -19,20 +19,25 @@ class SystemChain(ChainBase, metaclass=Singleton):
|
||||
|
||||
_restart_file = "__system_restart__"
|
||||
|
||||
def remote_clear_cache(self, channel: MessageChannel, userid: Union[int, str]):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
# 重启完成检测
|
||||
self.restart_finish()
|
||||
|
||||
def remote_clear_cache(self, channel: MessageChannel, userid: Union[int, str], source: str = None):
|
||||
"""
|
||||
清理系统缓存
|
||||
"""
|
||||
self.clear_cache()
|
||||
self.post_message(Notification(channel=channel,
|
||||
self.post_message(Notification(channel=channel, source=source,
|
||||
title=f"缓存清理完成!", userid=userid))
|
||||
|
||||
def restart(self, channel: MessageChannel, userid: Union[int, str]):
|
||||
def restart(self, channel: MessageChannel, userid: Union[int, str], source: str = None):
|
||||
"""
|
||||
重启系统
|
||||
"""
|
||||
if channel and userid:
|
||||
self.post_message(Notification(channel=channel,
|
||||
self.post_message(Notification(channel=channel, source=source,
|
||||
title="系统正在重启,请耐心等候!", userid=userid))
|
||||
# 保存重启信息
|
||||
self.save_cache({
|
||||
@@ -59,11 +64,11 @@ class SystemChain(ChainBase, metaclass=Singleton):
|
||||
title += f"当前前端版本:{front_local_version},远程版本:{front_release_version}"
|
||||
return title
|
||||
|
||||
def version(self, channel: MessageChannel, userid: Union[int, str]):
|
||||
def version(self, channel: MessageChannel, userid: Union[int, str], source: str = None):
|
||||
"""
|
||||
查看当前版本、远程版本
|
||||
"""
|
||||
self.post_message(Notification(channel=channel,
|
||||
self.post_message(Notification(channel=channel, source=source,
|
||||
title=self.__get_version_message(),
|
||||
userid=userid))
|
||||
|
||||
|
||||
@@ -534,13 +534,14 @@ class TransferChain(ChainBase):
|
||||
|
||||
return trans_items
|
||||
|
||||
def remote_transfer(self, arg_str: str, channel: MessageChannel, userid: Union[str, int] = None):
|
||||
def remote_transfer(self, arg_str: str, channel: MessageChannel,
|
||||
userid: Union[str, int] = None, source: str = None):
|
||||
"""
|
||||
远程重新整理,参数 历史记录ID TMDBID|类型
|
||||
"""
|
||||
|
||||
def args_error():
|
||||
self.post_message(Notification(channel=channel,
|
||||
self.post_message(Notification(channel=channel, source=source,
|
||||
title="请输入正确的命令格式:/redo [id] [tmdbid/豆瓣id]|[类型],"
|
||||
"[id]历史记录编号", userid=userid))
|
||||
|
||||
@@ -571,7 +572,7 @@ class TransferChain(ChainBase):
|
||||
mtype=MediaType(type_str),
|
||||
mediaid=media_id)
|
||||
if not state:
|
||||
self.post_message(Notification(channel=channel, title="手动整理失败",
|
||||
self.post_message(Notification(channel=channel, title="手动整理失败", source=source,
|
||||
text=errmsg, userid=userid, link=settings.MP_DOMAIN('#/history')))
|
||||
return
|
||||
|
||||
|
||||
@@ -423,7 +423,7 @@ class EventManager(metaclass=Singleton):
|
||||
|
||||
# 如果类不在全局变量中,尝试动态导入模块并创建实例
|
||||
try:
|
||||
# 导入模块,除了插件和Command,只有chain能响应事件
|
||||
# 导入模块,除了插件,只有chain能响应事件
|
||||
if not class_name.endswith("Chain"):
|
||||
logger.debug(f"事件处理出错:无效的 Chain 类名: {class_name},类名必须以 'Chain' 结尾")
|
||||
return None
|
||||
|
||||
@@ -22,9 +22,9 @@ from app.helper.resource import ResourceHelper
|
||||
from app.helper.message import MessageHelper
|
||||
from app.scheduler import Scheduler
|
||||
from app.monitor import Monitor
|
||||
from app.command import Command, CommandChian
|
||||
from app.schemas import Notification, NotificationType
|
||||
from app.db import close_database
|
||||
from app.chain.command import CommandChain
|
||||
|
||||
|
||||
def start_frontend():
|
||||
@@ -79,7 +79,7 @@ def check_auth():
|
||||
if SitesHelper().auth_level < 2:
|
||||
err_msg = "用户认证失败,站点相关功能将无法使用!"
|
||||
MessageHelper().put(f"注意:{err_msg}", title="用户认证", role="system")
|
||||
CommandChian().post_message(
|
||||
CommandChain().post_message(
|
||||
Notification(
|
||||
mtype=NotificationType.Manual,
|
||||
title="MoviePilot用户认证",
|
||||
@@ -139,7 +139,7 @@ def start_modules(_: FastAPI):
|
||||
# 启动定时服务
|
||||
Scheduler()
|
||||
# 加载命令
|
||||
Command()
|
||||
CommandChain()
|
||||
# 启动前端服务
|
||||
start_frontend()
|
||||
# 检查认证状态
|
||||
|
||||
Reference in New Issue
Block a user