From 0a52fe0a7acc223c7b044d0fc799259f61d9557f Mon Sep 17 00:00:00 2001 From: jxxghp Date: Mon, 17 Feb 2025 19:01:05 +0800 Subject: [PATCH] refactor: site browse api --- app/api/endpoints/site.py | 32 ++++++++++++++++++++++++++++++-- app/chain/__init__.py | 7 +++++-- app/chain/torrents.py | 7 +++++-- app/modules/indexer/__init__.py | 16 +++++++++++++--- app/schemas/site.py | 6 ++++++ 5 files changed, 59 insertions(+), 9 deletions(-) diff --git a/app/api/endpoints/site.py b/app/api/endpoints/site.py index 8837a827..cfcf7dcf 100644 --- a/app/api/endpoints/site.py +++ b/app/api/endpoints/site.py @@ -1,4 +1,4 @@ -from typing import List, Any +from typing import List, Any, Dict from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.orm import Session @@ -259,8 +259,36 @@ def site_icon(site_id: int, }) +@router.get("/category/{site_id}", summary="站点分类", response_model=List[schemas.SiteCategory]) +def site_category(site_id: int, + db: Session = Depends(get_db), + _: schemas.TokenPayload = Depends(verify_token)) -> Any: + """ + 获取站点分类 + """ + site = Site.get(db, site_id) + if not site: + raise HTTPException( + status_code=404, + detail=f"站点 {site_id} 不存在", + ) + indexer = SitesHelper().get_indexer(site.domain) + if not indexer: + raise HTTPException( + status_code=404, + detail=f"站点 {site.domain} 不支持", + ) + category: Dict[str, List[dict]] = indexer.get('category') or [] + if not category: + return [] + return list({category.get('movie') + category.get('tv')}) + + @router.get("/resource/{site_id}", summary="站点资源", response_model=List[schemas.TorrentInfo]) def site_resource(site_id: int, + keyword: str = None, + cat: str = None, + page: int = 0, db: Session = Depends(get_db), _: schemas.TokenPayload = Depends(get_current_active_superuser)) -> Any: """ @@ -272,7 +300,7 @@ def site_resource(site_id: int, status_code=404, detail=f"站点 {site_id} 不存在", ) - torrents = TorrentsChain().browse(domain=site.domain) + torrents = TorrentsChain().browse(domain=site.domain, keyword=keyword, cat=cat, page=page) if not torrents: return [] return [torrent.to_dict() for torrent in torrents] diff --git a/app/chain/__init__.py b/app/chain/__init__.py index 04ca91bf..d00d8043 100644 --- a/app/chain/__init__.py +++ b/app/chain/__init__.py @@ -322,13 +322,16 @@ class ChainBase(metaclass=ABCMeta): return self.run_module("search_torrents", site=site, keywords=keywords, mtype=mtype, page=page) - def refresh_torrents(self, site: dict) -> List[TorrentInfo]: + def refresh_torrents(self, site: dict, keyword: str = None, cat: str = None, page: int = 0) -> List[TorrentInfo]: """ 获取站点最新一页的种子,多个站点需要多线程处理 :param site: 站点 + :param keyword: 标题 + :param cat: 分类 + :param page: 页码 :reutrn: 种子资源列表 """ - return self.run_module("refresh_torrents", site=site) + return self.run_module("refresh_torrents", site=site, keyword=keyword, cat=cat, page=page) def filter_torrents(self, rule_groups: List[str], torrent_list: List[TorrentInfo], diff --git a/app/chain/torrents.py b/app/chain/torrents.py index a352cc21..f0b8e231 100644 --- a/app/chain/torrents.py +++ b/app/chain/torrents.py @@ -73,17 +73,20 @@ class TorrentsChain(ChainBase, metaclass=Singleton): logger.info(f'种子缓存数据清理完成') @cached(cache=TTLCache(maxsize=128, ttl=595)) - def browse(self, domain: str) -> List[TorrentInfo]: + def browse(self, domain: str, keyword: str = None, cat: str = None, page: int = 0) -> List[TorrentInfo]: """ 浏览站点首页内容,返回种子清单,TTL缓存10分钟 :param domain: 站点域名 + :param keyword: 搜索标题 + :param cat: 搜索分类 + :param page: 页码 """ logger.info(f'开始获取站点 {domain} 最新种子 ...') site = self.siteshelper.get_indexer(domain) if not site: logger.error(f'站点 {domain} 不存在!') return [] - return self.refresh_torrents(site=site) + return self.refresh_torrents(site=site, keyword=keyword, cat=cat, page=page) @cached(cache=TTLCache(maxsize=128, ttl=295)) def rss(self, domain: str) -> List[TorrentInfo]: diff --git a/app/modules/indexer/__init__.py b/app/modules/indexer/__init__.py index 43894dd6..c68b9d0a 100644 --- a/app/modules/indexer/__init__.py +++ b/app/modules/indexer/__init__.py @@ -76,12 +76,14 @@ class IndexerModule(_ModuleBase): def search_torrents(self, site: dict, keywords: List[str] = None, mtype: MediaType = None, + cat: str = None, page: int = 0) -> List[TorrentInfo]: """ 搜索一个站点 :param site: 站点 :param keywords: 搜索关键词列表 :param mtype: 媒体类型 + :param cat: 分类 :param page: 页码 :return: 资源列表 """ @@ -156,6 +158,7 @@ class IndexerModule(_ModuleBase): search_word=search_word, indexer=site, mtype=mtype, + cat=cat, page=page ) if error_flag: @@ -204,30 +207,37 @@ class IndexerModule(_ModuleBase): def __spider_search(indexer: dict, search_word: str = None, mtype: MediaType = None, + cat: str = None, page: int = 0) -> Tuple[bool, List[dict]]: """ 根据关键字搜索单个站点 :param: indexer: 站点配置 :param: search_word: 关键字 + :param: cat: 分类 :param: page: 页码 :param: mtype: 媒体类型 :param: timeout: 超时时间 :return: 是否发生错误, 种子列表 """ _spider = SiteSpider(indexer=indexer, - mtype=mtype, keyword=search_word, + mtype=mtype, + cat=cat, page=page) return _spider.is_error, _spider.get_torrents() - def refresh_torrents(self, site: dict) -> Optional[List[TorrentInfo]]: + def refresh_torrents(self, site: dict, + keyword: str = None, cat: str = None, page: int = 0) -> Optional[List[TorrentInfo]]: """ 获取站点最新一页的种子,多个站点需要多线程处理 :param site: 站点 + :param keyword: 关键字 + :param cat: 分类 + :param page: 页码 :reutrn: 种子资源列表 """ - return self.search_torrents(site=site) + return self.search_torrents(site=site, keywords=[keyword], cat=cat, page=page) def refresh_userdata(self, site: dict) -> Optional[SiteUserData]: """ diff --git a/app/schemas/site.py b/app/schemas/site.py index 7b95e480..c928bd7a 100644 --- a/app/schemas/site.py +++ b/app/schemas/site.py @@ -115,3 +115,9 @@ class SiteUserData(BaseModel): class SiteAuth(BaseModel): site: Optional[str] = None params: Optional[Dict[str, Union[int, str]]] = Field(default_factory=dict) + + +class SiteCategory(BaseModel): + id: Optional[int] = None + cat: Optional[str] = None + desc: Optional[str] = None