fix 优雅停止

This commit is contained in:
jxxghp 2023-06-08 09:52:18 +08:00
parent a99cd77b68
commit e3a12e856a
8 changed files with 78 additions and 31 deletions

View File

@ -1,6 +1,6 @@
from fastapi import APIRouter from fastapi import APIRouter
from app.api.endpoints import login, users, sites, messages, webhooks, subscribes, media from app.api.endpoints import login, users, sites, messages, webhooks, subscribes, media, douban
api_router = APIRouter() api_router = APIRouter()
api_router.include_router(login.router, tags=["login"]) api_router.include_router(login.router, tags=["login"])
@ -10,3 +10,4 @@ api_router.include_router(messages.router, prefix="/messages", tags=["messages"]
api_router.include_router(webhooks.router, prefix="/webhooks", tags=["webhooks"]) api_router.include_router(webhooks.router, prefix="/webhooks", tags=["webhooks"])
api_router.include_router(subscribes.router, prefix="/subscribes", tags=["subscribes"]) api_router.include_router(subscribes.router, prefix="/subscribes", tags=["subscribes"])
api_router.include_router(media.router, prefix="/media", tags=["media"]) api_router.include_router(media.router, prefix="/media", tags=["media"])
api_router.include_router(douban.router, prefix="/douban", tags=["douban"])

View File

@ -0,0 +1,28 @@
from typing import List
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from app import schemas
from app.chain.douban_sync import DoubanSyncChain
from app.db import get_db
from app.db.models.user import User
from app.db.userauth import get_current_active_superuser
router = APIRouter()
@router.get("/sync", response_model=schemas.Response)
async def sync_douban(
db: Session = Depends(get_db),
current_user: User = Depends(get_current_active_superuser)):
"""
查询所有订阅
"""
if not current_user:
raise HTTPException(
status_code=400,
detail="需要授权",
)
DoubanSyncChain().process()
return {"success": True}

View File

@ -88,3 +88,35 @@ async def seerr_subscribe(request: Request, background_tasks: BackgroundTasks,
username=user_name) username=user_name)
return {"success": True} return {"success": True}
@router.get("/refresh", response_model=schemas.Response)
async def refresh_subscribes(
db: Session = Depends(get_db),
current_user: User = Depends(get_current_active_superuser)):
"""
刷新所有订阅
"""
if not current_user:
raise HTTPException(
status_code=400,
detail="需要授权",
)
SubscribeChain().refresh()
return {"success": True}
@router.get("/search", response_model=schemas.Response)
async def search_subscribes(
db: Session = Depends(get_db),
current_user: User = Depends(get_current_active_superuser)):
"""
搜索所有订阅
"""
if not current_user:
raise HTTPException(
status_code=400,
detail="需要授权",
)
SubscribeChain().search(state='R')
return {"success": True}

View File

@ -379,7 +379,7 @@ class CommonChain(_ChainBase):
exist_seasons = exists_tvs.get("seasons") exist_seasons = exists_tvs.get("seasons")
if exist_seasons.get(season): if exist_seasons.get(season):
# 取差集 # 取差集
episodes = set(episodes).difference(set(exist_seasons['season'])) episodes = set(episodes).difference(set(exist_seasons[season]))
# 添加不存在的季集信息 # 添加不存在的季集信息
__append_no_exists(season, episodes) __append_no_exists(season, episodes)
# 存在不完整的剧集 # 存在不完整的剧集

View File

@ -12,7 +12,7 @@ from app.log import logger
class DoubanSyncChain(_ChainBase): class DoubanSyncChain(_ChainBase):
""" """
同步豆瓣看数据 同步豆瓣看数据
""" """
_interests_url: str = "https://www.douban.com/feed/people/%s/interests" _interests_url: str = "https://www.douban.com/feed/people/%s/interests"
@ -28,7 +28,7 @@ class DoubanSyncChain(_ChainBase):
def process(self): def process(self):
""" """
通过用户RSS同步豆瓣看数据 通过用户RSS同步豆瓣看数据
""" """
if not settings.DOUBAN_USER_IDS: if not settings.DOUBAN_USER_IDS:
return return
@ -97,9 +97,9 @@ class DoubanSyncChain(_ChainBase):
# 订阅成功 # 订阅成功
self.common.post_message( self.common.post_message(
title=f"{mediainfo.get_title_string()} 已添加订阅", title=f"{mediainfo.get_title_string()} 已添加订阅",
text="来自:豆瓣", text="来自:豆瓣",
image=mediainfo.get_message_image()) image=mediainfo.get_message_image())
logger.info(f"用户 {user_id} 豆瓣看同步完成") logger.info(f"用户 {user_id} 豆瓣看同步完成")
# 保存缓存 # 保存缓存
self._cache_path.write_text("\n".join(caches)) self._cache_path.write_text("\n".join(caches))

View File

@ -19,6 +19,8 @@ class Settings(BaseSettings):
HOST: str = "0.0.0.0" HOST: str = "0.0.0.0"
# 监听端口 # 监听端口
PORT: int = 3001 PORT: int = 3001
# 是否自动重载
RELOAD: bool = False
# 配置文件目录 # 配置文件目录
CONFIG_DIR: str = None CONFIG_DIR: str = None
# 超级管理员 # 超级管理员

View File

@ -36,9 +36,9 @@ class PluginManager(metaclass=Singleton):
self.systemconfigs = SystemConfigs() self.systemconfigs = SystemConfigs()
self.eventmanager = EventManager() self.eventmanager = EventManager()
# 停止已有插件 # 停止已有插件
self.stop_service() self.stop()
# 启动插件 # 启动插件
self.start_service() self.start()
def __run(self): def __run(self):
""" """
@ -55,7 +55,7 @@ class PluginManager(metaclass=Singleton):
except Exception as e: except Exception as e:
logger.error(f"事件处理出错:{str(e)} - {traceback.format_exc()}") logger.error(f"事件处理出错:{str(e)} - {traceback.format_exc()}")
def start_service(self): def start(self):
""" """
启动 启动
""" """
@ -68,7 +68,7 @@ class PluginManager(metaclass=Singleton):
# 启动事件处理线程 # 启动事件处理线程
self._thread.start() self._thread.start()
def stop_service(self): def stop(self):
""" """
停止 停止
""" """
@ -127,8 +127,8 @@ class PluginManager(metaclass=Singleton):
停止所有插件 停止所有插件
""" """
for plugin in self._running_plugins.values(): for plugin in self._running_plugins.values():
if hasattr(plugin, "stop_service"): if hasattr(plugin, "stop"):
plugin.stop_service() plugin.stop()
def get_plugin_config(self, pid: str) -> dict: def get_plugin_config(self, pid: str) -> dict:
""" """

View File

@ -1,8 +1,3 @@
import os
import signal
import sys
from typing import Any
import uvicorn as uvicorn import uvicorn as uvicorn
from fastapi import FastAPI from fastapi import FastAPI
from uvicorn import Config from uvicorn import Config
@ -21,7 +16,7 @@ App = FastAPI(title=settings.PROJECT_NAME,
App.include_router(api_router, prefix=settings.API_V1_STR) App.include_router(api_router, prefix=settings.API_V1_STR)
# uvicorn服务 # uvicorn服务
server = uvicorn.Server(Config(App, host=settings.HOST, port=settings.PORT, reload=False)) Server = uvicorn.Server(Config(App, host=settings.HOST, port=settings.PORT, reload=settings.RELOAD))
@App.on_event("shutdown") @App.on_event("shutdown")
@ -30,6 +25,7 @@ def shutdown_server():
服务关闭 服务关闭
""" """
Scheduler().stop() Scheduler().stop()
PluginManager().stop()
@App.on_event("startup") @App.on_event("startup")
@ -47,22 +43,10 @@ def start_module():
Scheduler() Scheduler()
def graceful_exit(signum: Any, frame: Any):
"""
优雅退出
"""
if server is not None:
server.should_exit = True
# 注册退出信号处理函数
signal.signal(signal.SIGINT, graceful_exit)
signal.signal(signal.SIGTERM, graceful_exit)
if __name__ == '__main__': if __name__ == '__main__':
# 初始化数据库 # 初始化数据库
init_db() init_db()
# 更新数据库 # 更新数据库
update_db() update_db()
# 启动服务 # 启动服务
server.run() Server.run()