fix 远程交互命令

This commit is contained in:
jxxghp
2024-10-20 01:54:24 +08:00
parent c650f1b5e3
commit 08e07625cd
8 changed files with 63 additions and 51 deletions

View File

@@ -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 为用户IDsource 为消息来源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)

View File

@@ -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):
"""
查询正在下载的任务,并发送消息
"""

View File

@@ -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))

View File

@@ -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,

View File

@@ -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))

View File

@@ -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

View File

@@ -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

View File

@@ -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()
# 检查认证状态