From cdeb60152884fdaa31f85b024bc1ae52248290ee Mon Sep 17 00:00:00 2001 From: jxxghp Date: Thu, 13 Jul 2023 20:34:40 +0800 Subject: [PATCH] =?UTF-8?q?add=20=E6=B6=88=E6=81=AF=E7=B1=BB=E5=9E=8B&API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- app/api/endpoints/message.py | 42 ++++++++++++++++++++++++++++++++++-- app/api/endpoints/plugin.py | 20 +++++++++++------ app/api/endpoints/system.py | 11 +++++++--- app/chain/__init__.py | 4 ++-- app/db/systemconfig_oper.py | 6 +++--- app/schemas/context.py | 20 +++++++++++++++++ app/schemas/types.py | 16 ++++++++++++++ 8 files changed, 103 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 1ea6167a..a6bbe517 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ docker pull jxxghp/moviepilot:latest - **USER_AGENT:** CookieCloud对应的浏览器UA,可选,同步站点后可以在管理界面中修改 -- **MESSAGER:** 消息通知渠道,支持 `telegram`/`wechat`/`slack`,同时还需要配置对应渠道的环境变量,非对应渠道的变量可删除,推荐使用`telegram` +- **MESSAGER:** 消息通知渠道,支持 `telegram`/`wechat`/`slack`,开启多个渠道时使用`,`分隔。同时还需要配置对应渠道的环境变量,非对应渠道的变量可删除,推荐使用`telegram` `wechat`设置项: diff --git a/app/api/endpoints/message.py b/app/api/endpoints/message.py index 475abfb4..94647419 100644 --- a/app/api/endpoints/message.py +++ b/app/api/endpoints/message.py @@ -1,14 +1,20 @@ -from typing import Union, Any +from typing import Union, Any, List -from fastapi import APIRouter, BackgroundTasks +from fastapi import APIRouter, BackgroundTasks, Depends from fastapi import Request +from sqlalchemy.orm import Session from starlette.responses import PlainTextResponse from app import schemas from app.chain.message import MessageChain from app.core.config import settings +from app.core.security import verify_token +from app.db import get_db +from app.db.systemconfig_oper import SystemConfigOper from app.log import logger from app.modules.wechat.WXBizMsgCrypt3 import WXBizMsgCrypt +from app.schemas import Notification +from app.schemas.types import SystemConfigKey, NotificationType router = APIRouter() @@ -54,3 +60,35 @@ def wechat_verify(echostr: str, msg_signature: str, logger.error("微信请求验证失败 VerifyURL ret: %s" % str(ret)) # 验证URL成功,将sEchoStr返回给企业号 return PlainTextResponse(sEchoStr) + + +@router.get("/switchs", summary="查询通知消息渠道开关", response_model=List[Notification]) +def read_switchs(db: Session = Depends(get_db), + _: schemas.TokenPayload = Depends(verify_token)) -> Any: + """ + 查询通知消息渠道开关 + """ + return_list = [] + # 读取数据库 + switchs = SystemConfigOper(db).get(SystemConfigKey.NotificationChannels) + if not switchs: + for noti in NotificationType: + return_list.append(Notification(mtype=noti.value, switch=True)) + + return return_list + + +@router.put("/switchs", summary="设置通知消息渠道开关", response_model=schemas.Response) +def set_switchs(switchs: List[Notification], + db: Session = Depends(get_db), + _: schemas.TokenPayload = Depends(verify_token)) -> Any: + """ + 查询通知消息渠道开关 + """ + switch_list = [] + for switch in switchs: + switch_list.append(switch.dict()) + # 存入数据库 + SystemConfigOper(db).set(SystemConfigKey.NotificationChannels, switch_list) + + return schemas.Response(success=True) diff --git a/app/api/endpoints/plugin.py b/app/api/endpoints/plugin.py index fb21e7e8..e3e8590b 100644 --- a/app/api/endpoints/plugin.py +++ b/app/api/endpoints/plugin.py @@ -1,10 +1,12 @@ from typing import Any, List from fastapi import APIRouter, Depends +from sqlalchemy.orm import Session from app import schemas from app.core.plugin import PluginManager from app.core.security import verify_token +from app.db import get_db from app.db.systemconfig_oper import SystemConfigOper from app.schemas.types import SystemConfigKey @@ -20,11 +22,12 @@ def all_plugins(_: schemas.TokenPayload = Depends(verify_token)) -> Any: @router.get("/installed", summary="已安装插件", response_model=List[str]) -def installed_plugins(_: schemas.TokenPayload = Depends(verify_token)) -> Any: +def installed_plugins(db: Session = Depends(get_db), + _: schemas.TokenPayload = Depends(verify_token)) -> Any: """ 查询用户已安装插件清单 """ - return SystemConfigOper().get(SystemConfigKey.UserInstalledPlugins) or [] + return SystemConfigOper(db).get(SystemConfigKey.UserInstalledPlugins) or [] @router.get("/{plugin_id}", summary="获取插件配置") @@ -47,34 +50,37 @@ def set_plugin_config(plugin_id: str, conf: dict, @router.post("/{plugin_id}/install", summary="安装插件", response_model=schemas.Response) def install_plugin(plugin_id: str, + db: Session = Depends(get_db), _: schemas.TokenPayload = Depends(verify_token)) -> Any: """ 安装插件 """ # 已安装插件 - install_plugins = SystemConfigOper().get(SystemConfigKey.UserInstalledPlugins) or [] + install_plugins = SystemConfigOper(db).get(SystemConfigKey.UserInstalledPlugins) or [] # 安装插件 install_plugins.append(plugin_id) # 保存设置 - SystemConfigOper().set(SystemConfigKey.UserInstalledPlugins, install_plugins) + SystemConfigOper(db).set(SystemConfigKey.UserInstalledPlugins, install_plugins) # 重载插件管理器 PluginManager().init_config() return schemas.Response(success=True) @router.delete("/{plugin_id}", summary="卸载插件", response_model=schemas.Response) -def uninstall_plugin(plugin_id: str, _: schemas.TokenPayload = Depends(verify_token)) -> Any: +def uninstall_plugin(plugin_id: str, + db: Session = Depends(get_db), + _: schemas.TokenPayload = Depends(verify_token)) -> Any: """ 卸载插件 """ # 删除已安装信息 - install_plugins = SystemConfigOper().get(SystemConfigKey.UserInstalledPlugins) or [] + install_plugins = SystemConfigOper(db).get(SystemConfigKey.UserInstalledPlugins) or [] for plugin in install_plugins: if plugin == plugin_id: install_plugins.remove(plugin) break # 保存 - SystemConfigOper().set(SystemConfigKey.UserInstalledPlugins, install_plugins) + SystemConfigOper(db).set(SystemConfigKey.UserInstalledPlugins, install_plugins) # 重载插件管理器 PluginManager().init_config() return schemas.Response(success=True) diff --git a/app/api/endpoints/system.py b/app/api/endpoints/system.py index 2f4d8e84..d3662761 100644 --- a/app/api/endpoints/system.py +++ b/app/api/endpoints/system.py @@ -5,9 +5,11 @@ from typing import Any, List, Union from fastapi import APIRouter, HTTPException, Depends from fastapi.responses import StreamingResponse +from sqlalchemy.orm import Session from app import schemas from app.core.security import verify_token +from app.db import get_db from app.db.systemconfig_oper import SystemConfigOper from app.helper.message import MessageHelper from app.helper.progress import ProgressHelper @@ -38,22 +40,25 @@ def get_progress(process_type: str, token: str): @router.get("/setting/{key}", summary="查询系统设置", response_model=schemas.Response) -def get_setting(key: str, _: schemas.TokenPayload = Depends(verify_token)): +def get_setting(key: str, + db: Session = Depends(get_db), + _: schemas.TokenPayload = Depends(verify_token)): """ 查询系统设置 """ return schemas.Response(success=True, data={ - "value": SystemConfigOper().get(key) + "value": SystemConfigOper(db).get(key) }) @router.post("/setting/{key}", summary="更新系统设置", response_model=schemas.Response) def set_setting(key: str, value: Union[list, dict, str, int], + db: Session = Depends(get_db), _: schemas.TokenPayload = Depends(verify_token)): """ 更新系统设置 """ - SystemConfigOper().set(key, value) + SystemConfigOper(db).set(key, value) return schemas.Response(success=True) diff --git a/app/chain/__init__.py b/app/chain/__init__.py index 3a3c9664..40568e29 100644 --- a/app/chain/__init__.py +++ b/app/chain/__init__.py @@ -60,8 +60,8 @@ class ChainBase(AbstractSingleton, metaclass=Singleton): if isinstance(temp, list): result.extend(temp) else: - # 返回结果非列表也非空,则执行一次后跳出 - break + # 返回结果非列表也非空,则继续执行下一模块 + continue except Exception as err: logger.error(f"运行模块 {method} 出错:{module.__class__.__name__} - {err}\n{traceback.print_exc()}") return result diff --git a/app/db/systemconfig_oper.py b/app/db/systemconfig_oper.py index b36f3dc1..5cafdfdb 100644 --- a/app/db/systemconfig_oper.py +++ b/app/db/systemconfig_oper.py @@ -1,7 +1,7 @@ import json from typing import Any, Union -from app.db import DbOper +from app.db import DbOper, SessionLocal from app.db.models.systemconfig import SystemConfig from app.utils.object import ObjectUtils from app.utils.singleton import Singleton @@ -12,11 +12,11 @@ class SystemConfigOper(DbOper, metaclass=Singleton): # 配置对象 __SYSTEMCONF: dict = {} - def __init__(self): + def __init__(self, _db=SessionLocal()): """ 加载配置到内存 """ - super().__init__() + super().__init__(_db) for item in SystemConfig.list(self._db): if ObjectUtils.is_obj(item.value): self.__SYSTEMCONF[item.key] = json.loads(item.value) diff --git a/app/schemas/context.py b/app/schemas/context.py index 4d8faf21..ed7b5e7b 100644 --- a/app/schemas/context.py +++ b/app/schemas/context.py @@ -307,3 +307,23 @@ class TmdbEpisode(BaseModel): vote_average: Optional[float] = None crew: Optional[list] = [] guest_stars: Optional[list] = [] + + +class Notification(BaseModel): + """ + 消息 + """ + # 消息类型 + mtype: Optional[str] = None + # 标题 + title: Optional[str] = None + # 内容 + content: Optional[str] = None + # 图片 + image: Optional[str] = None + # 链接 + link: Optional[str] = None + # 用户ID + user_id: Optional[str] = None + # 开关 + switch: Optional[bool] = True diff --git a/app/schemas/types.py b/app/schemas/types.py index 7f844efd..0345cd80 100644 --- a/app/schemas/types.py +++ b/app/schemas/types.py @@ -40,6 +40,8 @@ class SystemConfigKey(Enum): IndexerSites = "IndexerSites" # 种子优先级规则 TorrentsPriority = "TorrentsPriority" + # 通知消息渠道设置 + NotificationChannels = "NotificationChannels" # 站点框架 @@ -69,3 +71,17 @@ class ProgressKey(Enum): class MediaImageType(Enum): Poster = "poster" Backdrop = "backdrop" + + +# 消息类型 +class NotificationType(Enum): + # 资源下载 + Download = "资源下载" + # 整理入库 + Organize = "整理入库" + # 订阅 + Subscribe = "订阅" + # 站点消息 + SiteMessage = "站点消息" + # 媒体服务器通知 + MediaServer = "媒体服务器通知"