fix commands

This commit is contained in:
jxxghp 2023-06-17 20:46:34 +08:00
parent 4ddaa020de
commit e9d2ebca89
9 changed files with 179 additions and 62 deletions

View File

@ -5,6 +5,7 @@ from sqlalchemy.orm import Session
from app import schemas from app import schemas
from app.chain.cookiecloud import CookieCloudChain from app.chain.cookiecloud import CookieCloudChain
from app.chain.site import SiteChain
from app.db import get_db from app.db import get_db
from app.db.models.site import Site from app.db.models.site import Site
from app.db.models.user import User from app.db.models.user import User
@ -42,6 +43,24 @@ async def update_site(
return site return site
@router.get("/{site_id}", response_model=schemas.Site)
async def read_site(
site_id: int,
db: Session = Depends(get_db),
_: User = Depends(get_current_active_user),
) -> Any:
"""
获取站点信息
"""
site = Site.get(db, site_id)
if not site:
raise HTTPException(
status_code=404,
detail=f"站点 {site_id} 不存在",
)
return site
@router.get("/cookiecloud", response_model=schemas.Response) @router.get("/cookiecloud", response_model=schemas.Response)
async def cookie_cloud_sync(_: User = Depends(get_current_active_user)) -> Any: async def cookie_cloud_sync(_: User = Depends(get_current_active_user)) -> Any:
""" """
@ -51,3 +70,30 @@ async def cookie_cloud_sync(_: User = Depends(get_current_active_user)) -> Any:
if not status: if not status:
return {"success": False, "message": error_msg} return {"success": False, "message": error_msg}
return {"success": True, "message": error_msg} return {"success": True, "message": error_msg}
@router.get("/cookie", response_model=schemas.Response)
async def update_cookie(
site_id: int,
username: str,
password: str,
db: Session = Depends(get_db),
_: User = Depends(get_current_active_user)) -> Any:
"""
使用用户密码更新站点Cookie
"""
# 查询站点
site_info = Site.get(db, site_id)
if not site_info:
raise HTTPException(
status_code=404,
detail=f"站点 {site_id} 不存在!",
)
# 更新Cookie
status, msg = SiteChain().update_cookie(site_info=site_info,
username=username,
password=password)
if not status:
return {"success": False, "message": msg}
else:
return {"success": True, "message": msg}

View File

@ -1,5 +1,5 @@
import base64 import base64
from typing import Tuple, Optional from typing import Tuple, Optional, Union
from urllib.parse import urljoin from urllib.parse import urljoin
from lxml import etree from lxml import etree
@ -30,6 +30,18 @@ class CookieCloudChain(ChainBase):
password=settings.COOKIECLOUD_PASSWORD password=settings.COOKIECLOUD_PASSWORD
) )
def remote_sync(self, userid: Union[int, str]):
"""
远程触发同步站点发送消息
"""
self.post_message(title="开始同步CookieCloud站点 ...", userid=userid)
# 开始同步
success, msg = self.process()
if success:
self.post_message(title=f"同步站点成功,{msg}", userid=userid)
else:
self.post_message(title=f"同步站点失败:{msg}", userid=userid)
def process(self) -> Tuple[bool, str]: def process(self) -> Tuple[bool, str]:
""" """
通过CookieCloud同步站点Cookie 通过CookieCloud同步站点Cookie

View File

@ -1,5 +1,5 @@
from pathlib import Path from pathlib import Path
from typing import Optional from typing import Optional, Union
from app.chain import ChainBase from app.chain import ChainBase
from app.chain.download import DownloadChain from app.chain.download import DownloadChain
@ -28,6 +28,14 @@ class DoubanChain(ChainBase):
self.searchchain = SearchChain() self.searchchain = SearchChain()
self.subscribechain = SubscribeChain() self.subscribechain = SubscribeChain()
def remote_sync(self, userid: Union[int, str]):
"""
同步豆瓣想看数据发送消息
"""
self.post_message(title="开始同步豆瓣想看 ...", userid=userid)
self.sync()
self.post_message(title="同步豆瓣想看数据完成!", userid=userid)
def sync(self): def sync(self):
""" """
通过用户RSS同步豆瓣想看数据 通过用户RSS同步豆瓣想看数据

View File

@ -509,7 +509,7 @@ class DownloadChain(ChainBase):
# 全部存在 # 全部存在
return True, no_exists return True, no_exists
def get_downloading(self, userid: Union[str, int] = None): def remote_downloading(self, userid: Union[str, int] = None):
""" """
查询正在下载的任务并发送消息 查询正在下载的任务并发送消息
""" """

View File

@ -63,7 +63,6 @@ class MessageChain(ChainBase):
"user": userid "user": userid
} }
) )
self.post_message(title=f"正在运行,请稍候 ...", userid=userid)
elif text.isdigit(): elif text.isdigit():
# 缓存 # 缓存

View File

@ -1,7 +1,8 @@
from typing import Union from typing import Union, Tuple
from app.chain import ChainBase from app.chain import ChainBase
from app.core.config import settings from app.core.config import settings
from app.db.models.site import Site
from app.db.site_oper import SiteOper from app.db.site_oper import SiteOper
from app.helper.cookie import CookieHelper from app.helper.cookie import CookieHelper
from app.log import logger from app.log import logger
@ -20,7 +21,7 @@ class SiteChain(ChainBase):
self._siteoper = SiteOper() self._siteoper = SiteOper()
self._cookiehelper = CookieHelper() self._cookiehelper = CookieHelper()
def list(self, userid: Union[str, int] = None): def remote_list(self, userid: Union[str, int] = None):
""" """
查询所有站点发送消息 查询所有站点发送消息
""" """
@ -44,7 +45,7 @@ class SiteChain(ChainBase):
# 发送列表 # 发送列表
self.post_message(title=title, text="\n".join(messages), userid=userid) self.post_message(title=title, text="\n".join(messages), userid=userid)
def disable(self, arg_str, userid: Union[str, int] = None): def remote_disable(self, arg_str, userid: Union[str, int] = None):
""" """
禁用站点 禁用站点
""" """
@ -63,9 +64,9 @@ class SiteChain(ChainBase):
"is_active": False "is_active": False
}) })
# 重新发送消息 # 重新发送消息
self.list() self.remote_list()
def enable(self, arg_str, userid: Union[str, int] = None): def remote_enable(self, arg_str, userid: Union[str, int] = None):
""" """
启用站点 启用站点
""" """
@ -84,9 +85,36 @@ class SiteChain(ChainBase):
"is_active": True "is_active": True
}) })
# 重新发送消息 # 重新发送消息
self.list() self.remote_list()
def get_cookie(self, arg_str: str, userid: Union[str, int] = None): def update_cookie(self, site_info: Site,
username: str, password: str) -> Tuple[bool, str]:
"""
根据用户名密码更新站点Cookie
:param site_info: 站点信息
:param username: 用户名
:param password: 密码
:return: (是否成功, 错误信息)
"""
# 更新站点Cookie
result = self._cookiehelper.get_site_cookie_ua(
url=site_info.url,
username=username,
password=password,
proxies=settings.PROXY_HOST if site_info.proxy else None
)
if result:
cookie, ua, msg = result
if not cookie:
return False, msg
self._siteoper.update(site_info.id, {
"cookie": cookie,
"ua": ua
})
return True, msg
return False, "未知错误"
def remote_cookie(self, arg_str: str, userid: Union[str, int] = None):
""" """
使用用户名密码更新站点Cookie 使用用户名密码更新站点Cookie
""" """
@ -111,28 +139,20 @@ class SiteChain(ChainBase):
if not site_info: if not site_info:
self.post_message(title=f"站点编号 {site_id} 不存在!", userid=userid) self.post_message(title=f"站点编号 {site_id} 不存在!", userid=userid)
return return
self.post_message(title=f"开始更新【{site_info.name}】Cookie&UA ...", userid=userid)
# 用户名 # 用户名
username = args[1] username = args[1]
# 密码 # 密码
password = args[2] password = args[2]
# 更新站点Cookie # 更新Cookie
result = self._cookiehelper.get_site_cookie_ua( status, msg = self.update_cookie(site_info=site_info,
url=site_info.url,
username=username, username=username,
password=password, password=password)
proxies=settings.PROXY_HOST if site_info.proxy else None if not status:
)
if result:
cookie, ua, msg = result
if not cookie:
logger.error(msg) logger.error(msg)
self.post_message(title=f"{site_info.name}】 Cookie&UA更新失败", self.post_message(title=f"{site_info.name}】 Cookie&UA更新失败",
text=f"错误原因:{msg}", text=f"错误原因:{msg}",
userid=userid) userid=userid)
return else:
self._siteoper.update(site_id, {
"cookie": cookie,
"ua": ua
})
self.post_message(title=f"{site_info.name}】 Cookie&UA更新成功", self.post_message(title=f"{site_info.name}】 Cookie&UA更新成功",
userid=userid) userid=userid)

View File

@ -108,6 +108,37 @@ class SubscribeChain(ChainBase):
# 返回结果 # 返回结果
return sid return sid
def remote_refresh(self, userid: Union[str, int] = None):
"""
远程刷新订阅发送消息
"""
self.post_message(title=f"开始刷新订阅 ...", userid=userid)
self.refresh()
self.post_message(title=f"订阅刷新完成!", userid=userid)
def remote_search(self, arg_str: str, userid: Union[str, int] = None):
"""
远程搜索订阅发送消息
"""
if arg_str and not str(arg_str).isdigit():
self.post_message(title="请输入正确的命令格式:/subscribe_search [id]"
"[id]为订阅编号,不输入订阅编号时搜索所有订阅", userid=userid)
return
if arg_str:
sid = int(arg_str)
subscribe = self.subscribehelper.get(sid)
if not subscribe:
self.post_message(title=f"订阅编号 {sid} 不存在!", userid=userid)
return
self.post_message(title=f"开始搜索 {subscribe.name} ...", userid=userid)
# 搜索订阅
self.search(sid=int(arg_str))
self.post_message(title=f"{subscribe.name} 搜索完成!", userid=userid)
else:
self.post_message(title=f"开始搜索所有订阅 ...", userid=userid)
self.search(state='R')
self.post_message(title=f"订阅搜索完成!", userid=userid)
def search(self, sid: int = None, state: str = 'N'): def search(self, sid: int = None, state: str = 'N'):
""" """
订阅搜索 订阅搜索
@ -325,7 +356,7 @@ class SubscribeChain(ChainBase):
"lack_episode": len(left_episodes) "lack_episode": len(left_episodes)
}) })
def list(self, userid: Union[str, int] = None): def remote_list(self, userid: Union[str, int] = None):
""" """
查询订阅并发送消息 查询订阅并发送消息
""" """
@ -334,7 +365,9 @@ class SubscribeChain(ChainBase):
self.post_message(title='没有任何订阅!', userid=userid) self.post_message(title='没有任何订阅!', userid=userid)
return return
title = f"共有 {len(subscribes)} 个订阅,回复对应指令操作: " \ title = f"共有 {len(subscribes)} 个订阅,回复对应指令操作: " \
f"\n- 删除订阅:/subscribe_delete [id]" f"\n- 删除订阅:/subscribe_delete [id]" \
f"\n- 搜索订阅:/subscribe_search [id]" \
f"\n- 刷新订阅:/subscribe_refresh"
messages = [] messages = []
for subscribe in subscribes: for subscribe in subscribes:
if subscribe.type == MediaType.MOVIE.value: if subscribe.type == MediaType.MOVIE.value:
@ -349,7 +382,7 @@ class SubscribeChain(ChainBase):
# 发送列表 # 发送列表
self.post_message(title=title, text='\n'.join(messages), userid=userid) self.post_message(title=title, text='\n'.join(messages), userid=userid)
def delete(self, arg_str: str, userid: Union[str, int] = None): def remote_delete(self, arg_str: str, userid: Union[str, int] = None):
""" """
删除订阅 删除订阅
""" """
@ -366,7 +399,7 @@ class SubscribeChain(ChainBase):
# 删除订阅 # 删除订阅
self.subscribehelper.delete(subscribe_id) self.subscribehelper.delete(subscribe_id)
# 重新发送消息 # 重新发送消息
self.list() self.remote_list()
@staticmethod @staticmethod
def __get_subscribe_no_exits(no_exists: Dict[int, Dict[int, NotExistMediaInfo]], def __get_subscribe_no_exits(no_exists: Dict[int, Dict[int, NotExistMediaInfo]],

View File

@ -42,62 +42,60 @@ class Command(metaclass=Singleton):
self.eventmanager = EventManager() self.eventmanager = EventManager()
# 插件管理器 # 插件管理器
self.pluginmanager = PluginManager() self.pluginmanager = PluginManager()
# 汇总插件命令 # 内置命令
self._commands = { self._commands = {
"/cookiecloud": { "/cookiecloud": {
"func": CookieCloudChain().process, "func": CookieCloudChain().remote_sync,
"description": "同步站点", "description": "同步站点",
"data": {} "data": {}
}, },
"/sites": { "/sites": {
"func": SiteChain().list, "func": SiteChain().remote_list,
"description": "查询站点", "description": "查询站点",
"data": {} "data": {}
}, },
"/site_cookie": { "/site_cookie": {
"func": SiteChain().get_cookie, "func": SiteChain().remote_cookie,
"description": "更新站点Cookie", "description": "更新站点Cookie",
"data": {} "data": {}
}, },
"/site_enable": { "/site_enable": {
"func": SiteChain().enable, "func": SiteChain().remote_enable,
"description": "启用站点", "description": "启用站点",
"data": {} "data": {}
}, },
"/site_disable": { "/site_disable": {
"func": SiteChain().disable, "func": SiteChain().remote_disable,
"description": "禁用站点", "description": "禁用站点",
"data": {} "data": {}
}, },
"/douban_sync": { "/douban_sync": {
"func": DoubanChain().sync, "func": DoubanChain().remote_sync,
"description": "同步豆瓣想看", "description": "同步豆瓣想看",
"data": {} "data": {}
}, },
"/subscribes": { "/subscribes": {
"func": SubscribeChain().list, "func": SubscribeChain().remote_list,
"description": "查询订阅", "description": "查询订阅",
"data": {} "data": {}
}, },
"/subscribe_refresh": { "/subscribe_refresh": {
"func": SubscribeChain().refresh, "func": SubscribeChain().remote_refresh,
"description": "刷新订阅", "description": "刷新订阅",
"data": {} "data": {}
}, },
"/subscribe_search": { "/subscribe_search": {
"func": SubscribeChain().search, "func": SubscribeChain().remote_search,
"description": "搜索订阅", "description": "搜索订阅",
"data": { "data": {}
'state': 'R',
}
}, },
"/subscribe_delete": { "/subscribe_delete": {
"func": SubscribeChain().delete, "func": SubscribeChain().remote_delete,
"description": "删除订阅", "description": "删除订阅",
"data": {} "data": {}
}, },
"/downloading": { "/downloading": {
"func": DownloadChain().get_downloading, "func": DownloadChain().remote_downloading,
"description": "正在下载", "description": "正在下载",
"data": {} "data": {}
}, },
@ -107,6 +105,7 @@ class Command(metaclass=Singleton):
"data": {} "data": {}
} }
} }
# 汇总插件命令
plugin_commands = self.pluginmanager.get_plugin_commands() plugin_commands = self.pluginmanager.get_plugin_commands()
for command in plugin_commands: for command in plugin_commands:
self.register( self.register(
@ -120,7 +119,7 @@ class Command(metaclass=Singleton):
) )
# 处理链 # 处理链
self.chain = CommandChian() self.chain = CommandChian()
# 广播注册命令 # 广播注册命令菜单
self.chain.register_commands(commands=self.get_commands()) self.chain.register_commands(commands=self.get_commands())
# 消息处理线程 # 消息处理线程
self._thread = Thread(target=self.__run) self._thread = Thread(target=self.__run)
@ -184,16 +183,16 @@ class Command(metaclass=Singleton):
logger.info(f"用户 {userid} 开始执行:{command.get('description')} ...") logger.info(f"用户 {userid} 开始执行:{command.get('description')} ...")
cmd_data = command['data'] if command.get('data') else {} cmd_data = command['data'] if command.get('data') else {}
args_num = ObjectUtils.has_arguments(command['func']) args_num = ObjectUtils.has_arguments(command['func'])
if args_num: if args_num > 0:
if cmd_data: if cmd_data:
# 使用内置参数 # 有内置参数直接使用内置参数
command['func'](**cmd_data) command['func'](**cmd_data)
elif args_num > 1: elif args_num == 1:
# 使用用户输入参数
command['func'](data_str, userid)
else:
# 没有用户输入参数 # 没有用户输入参数
command['func'](data_str) command['func'](userid)
else:
# 多个输入参数用户输入、用户ID
command['func'](data_str, userid)
else: else:
# 没有参数 # 没有参数
command['func']() command['func']()

View File

@ -112,7 +112,7 @@ class Slack:
# 结构体 # 结构体
blocks = [] blocks = []
if not image: if not image:
message_text = f"*{title}*\n{text or ''}" message_text = f"{title}\n{text or ''}"
else: else:
# 消息图片 # 消息图片
if image: if image: