diff --git a/app/api/endpoints/site.py b/app/api/endpoints/site.py index fa2b5b0e..5630b9fc 100644 --- a/app/api/endpoints/site.py +++ b/app/api/endpoints/site.py @@ -2,6 +2,7 @@ from typing import List, Any from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.orm import Session +from starlette.background import BackgroundTasks from app import schemas from app.chain.cookiecloud import CookieCloudChain @@ -11,11 +12,27 @@ from app.core.security import verify_token from app.db import get_db from app.db.models.site import Site from app.db.models.siteicon import SiteIcon -from app.db.siteicon_oper import SiteIconOper router = APIRouter() +def start_cookiecloud_sync(): + """ + 后台启动CookieCloud站点同步 + """ + CookieCloudChain().process(manual=True) + + +def start_site_cookie(site_info: Site, username: str, password: str): + """ + 后台启动站点Cookie更新 + """ + SiteChain().update_cookie(site_info=site_info, + username=username, + password=password, + manual=True) + + @router.get("/", summary="所有站点", response_model=List[schemas.Site]) async def read_sites(db: Session = Depends(get_db), _: schemas.TokenPayload = Depends(verify_token)) -> List[dict]: @@ -77,14 +94,13 @@ async def delete_site( @router.get("/cookiecloud", summary="CookieCloud同步", response_model=schemas.Response) -async def cookie_cloud_sync(_: schemas.TokenPayload = Depends(verify_token)) -> Any: +async def cookie_cloud_sync(background_tasks: BackgroundTasks, + _: schemas.TokenPayload = Depends(verify_token)) -> Any: """ 运行CookieCloud同步站点信息 """ - status, error_msg = CookieCloudChain().process() - if not status: - schemas.Response(success=True, message=error_msg) - return schemas.Response(success=True, message="同步成功!") + background_tasks.add_task(start_cookiecloud_sync) + return schemas.Response(success=True, message="CookieCloud同步任务已启动!") @router.get("/cookie/{site_id}", summary="更新站点Cookie&UA", response_model=schemas.Response) @@ -92,6 +108,7 @@ async def update_cookie( site_id: int, username: str, password: str, + background_tasks: BackgroundTasks, db: Session = Depends(get_db), _: schemas.TokenPayload = Depends(verify_token)) -> Any: """ @@ -105,13 +122,11 @@ async def update_cookie( detail=f"站点 {site_id} 不存在!", ) # 更新Cookie - status, msg = SiteChain().update_cookie(site_info=site_info, - username=username, - password=password) - if not status: - return schemas.Response(success=False, message=msg) - else: - return schemas.Response(success=True, message=msg) + background_tasks.add_task(start_site_cookie, + site_info=site_info, + username=username, + password=password) + return schemas.Response(success=True, message="站点Cookie更新任务已启动!") @router.get("/test/{site_id}", summary="连接测试", response_model=schemas.Response) diff --git a/app/api/endpoints/subscribe.py b/app/api/endpoints/subscribe.py index 2366dcff..3d4e86df 100644 --- a/app/api/endpoints/subscribe.py +++ b/app/api/endpoints/subscribe.py @@ -29,7 +29,7 @@ def start_subscribe_search(sid: Optional[int], state: Optional[str]): """ 启动订阅搜索任务 """ - SubscribeChain().search(sid=sid, state=state) + SubscribeChain().search(sid=sid, state=state, manul=True) @router.get("/", summary="所有订阅", response_model=List[schemas.Subscribe]) diff --git a/app/chain/cookiecloud.py b/app/chain/cookiecloud.py index 7aa4f566..76ad4abe 100644 --- a/app/chain/cookiecloud.py +++ b/app/chain/cookiecloud.py @@ -10,6 +10,7 @@ from app.core.config import settings from app.db.siteicon_oper import SiteIconOper from app.db.site_oper import SiteOper from app.helper.cookiecloud import CookieCloudHelper +from app.helper.message import MessageHelper from app.helper.sites import SitesHelper from app.log import logger from app.utils.http import RequestUtils @@ -26,6 +27,7 @@ class CookieCloudChain(ChainBase): self.siteiconoper = SiteIconOper() self.siteshelper = SitesHelper() self.sitechain = SiteChain() + self.message = MessageHelper() self.cookiecloud = CookieCloudHelper( server=settings.COOKIECLOUD_HOST, key=settings.COOKIECLOUD_KEY, @@ -44,7 +46,7 @@ class CookieCloudChain(ChainBase): else: self.post_message(title=f"同步站点失败:{msg}", userid=userid) - def process(self) -> Tuple[bool, str]: + def process(self, manual=False) -> Tuple[bool, str]: """ 通过CookieCloud同步站点Cookie """ @@ -93,6 +95,8 @@ class CookieCloudChain(ChainBase): logger.warn(f"缓存站点 {indexer.get('name')} 图标失败") # 处理完成 ret_msg = f"更新了{_update_count}个站点,新增了{_add_count}个站点" + if manual: + self.message.put(f"CookieCloud同步成功, {ret_msg}") logger.info(f"CookieCloud同步成功:{ret_msg}") return True, ret_msg diff --git a/app/chain/site.py b/app/chain/site.py index ad983d58..0fd8dc7f 100644 --- a/app/chain/site.py +++ b/app/chain/site.py @@ -7,6 +7,7 @@ from app.db.site_oper import SiteOper from app.helper.browser import PlaywrightHelper from app.helper.cloudflare import under_challenge from app.helper.cookie import CookieHelper +from app.helper.message import MessageHelper from app.log import logger from app.utils.http import RequestUtils from app.utils.site import SiteUtils @@ -18,13 +19,11 @@ class SiteChain(ChainBase): 站点管理处理链 """ - _siteoper: SiteOper = None - _cookiehelper: CookieHelper = None - def __init__(self): super().__init__() - self._siteoper = SiteOper() - self._cookiehelper = CookieHelper() + self.siteoper = SiteOper() + self.cookiehelper = CookieHelper() + self.message = MessageHelper() def test(self, url: str) -> Tuple[bool, str]: """ @@ -34,7 +33,7 @@ class SiteChain(ChainBase): """ # 检查域名是否可用 domain = StringUtils.get_url_domain(url) - site_info = self._siteoper.get_by_domain(domain) + site_info = self.siteoper.get_by_domain(domain) if not site_info: return False, f"站点【{url}】不存在" site_url = site_info.url @@ -84,7 +83,7 @@ class SiteChain(ChainBase): """ 查询所有站点,发送消息 """ - site_list = self._siteoper.list() + site_list = self.siteoper.list() if not site_list: self.post_message(title="没有维护任何站点信息!") title = f"共有 {len(site_list)} 个站点,回复对应指令操作:" \ @@ -114,12 +113,12 @@ class SiteChain(ChainBase): if not arg_str.isdigit(): return site_id = int(arg_str) - site = self._siteoper.get(site_id) + site = self.siteoper.get(site_id) if not site: self.post_message(title=f"站点编号 {site_id} 不存在!", userid=userid) return # 禁用站点 - self._siteoper.update(site_id, { + self.siteoper.update(site_id, { "is_active": False }) # 重新发送消息 @@ -135,28 +134,30 @@ class SiteChain(ChainBase): if not arg_str.isdigit(): return site_id = int(arg_str) - site = self._siteoper.get(site_id) + site = self.siteoper.get(site_id) if not site: self.post_message(title=f"站点编号 {site_id} 不存在!", userid=userid) return # 禁用站点 - self._siteoper.update(site_id, { + self.siteoper.update(site_id, { "is_active": True }) # 重新发送消息 self.remote_list() def update_cookie(self, site_info: Site, - username: str, password: str) -> Tuple[bool, str]: + username: str, password: str, + manual=False) -> Tuple[bool, str]: """ 根据用户名密码更新站点Cookie :param site_info: 站点信息 :param username: 用户名 :param password: 密码 + :param manual: 是否手动更新 :return: (是否成功, 错误信息) """ # 更新站点Cookie - result = self._cookiehelper.get_site_cookie_ua( + result = self.cookiehelper.get_site_cookie_ua( url=site_info.url, username=username, password=password, @@ -165,11 +166,15 @@ class SiteChain(ChainBase): if result: cookie, ua, msg = result if not cookie: + if manual: + self.message.put(f"站点 {site_info.name} Cookie更新失败:{msg}!") return False, msg - self._siteoper.update(site_info.id, { + self.siteoper.update(site_info.id, { "cookie": cookie, "ua": ua }) + if manual: + self.message.put(f"站点 {site_info.name} Cookie更新成功!") return True, msg return False, "未知错误" @@ -194,7 +199,7 @@ class SiteChain(ChainBase): # 站点ID site_id = int(site_id) # 站点信息 - site_info = self._siteoper.get(site_id) + site_info = self.siteoper.get(site_id) if not site_info: self.post_message(title=f"站点编号 {site_id} 不存在!", userid=userid) return diff --git a/app/chain/subscribe.py b/app/chain/subscribe.py index f4d84671..8bf46e99 100644 --- a/app/chain/subscribe.py +++ b/app/chain/subscribe.py @@ -10,6 +10,7 @@ from app.core.context import TorrentInfo, Context, MediaInfo from app.core.config import settings from app.db.models.subscribe import Subscribe from app.db.subscribe_oper import SubscribeOper +from app.helper.message import MessageHelper from app.helper.sites import SitesHelper from app.log import logger from app.schemas import NotExistMediaInfo @@ -31,6 +32,7 @@ class SubscribeChain(ChainBase): self.searchchain = SearchChain() self.subscribehelper = SubscribeOper() self.siteshelper = SitesHelper() + self.message = MessageHelper() def add(self, title: str, year: str, mtype: MediaType = None, @@ -150,11 +152,12 @@ class SubscribeChain(ChainBase): 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', manul: bool = False): """ 订阅搜索 :param sid: 订阅ID,有值时只处理该订阅 :param state: 订阅状态 N:未搜索 R:已搜索 + :param manul: 是否手动搜索 :return: 更新订阅状态为R或删除订阅 """ if sid: @@ -239,6 +242,12 @@ class SubscribeChain(ChainBase): update_date = True if downloads else False self.__upate_lack_episodes(lefts=lefts, subscribe=subscribe, mediainfo=mediainfo, update_date=update_date) + # 手动触发时发送系统消息 + if manul: + if sid: + self.message.put(f'订阅 {subscribes[0].name} 搜索完成!') + else: + self.message.put(f'所有订阅搜索完成!') def refresh(self): """