feat torrents全局缓存共享

This commit is contained in:
jxxghp 2023-09-09 17:42:31 +08:00
parent 27238ac467
commit 5bcbacf3a5
7 changed files with 28 additions and 42 deletions

View File

@ -6,8 +6,8 @@ from starlette.background import BackgroundTasks
from app import schemas from app import schemas
from app.chain.cookiecloud import CookieCloudChain from app.chain.cookiecloud import CookieCloudChain
from app.chain.search import SearchChain
from app.chain.site import SiteChain from app.chain.site import SiteChain
from app.chain.torrents import TorrentsChain
from app.core.event import EventManager from app.core.event import EventManager
from app.core.security import verify_token from app.core.security import verify_token
from app.db import get_db from app.db import get_db
@ -191,7 +191,7 @@ def site_icon(site_id: int,
@router.get("/resource/{site_id}", summary="站点资源", response_model=List[schemas.TorrentInfo]) @router.get("/resource/{site_id}", summary="站点资源", response_model=List[schemas.TorrentInfo])
def site_resource(site_id: int, keyword: str = None, def site_resource(site_id: int,
db: Session = Depends(get_db), db: Session = Depends(get_db),
_: schemas.TokenPayload = Depends(verify_token)) -> Any: _: schemas.TokenPayload = Depends(verify_token)) -> Any:
""" """
@ -203,7 +203,7 @@ def site_resource(site_id: int, keyword: str = None,
status_code=404, status_code=404,
detail=f"站点 {site_id} 不存在", detail=f"站点 {site_id} 不存在",
) )
torrents = SearchChain(db).browse(site.domain, keyword) torrents = TorrentsChain(db).browse(domain=site.domain)
if not torrents: if not torrents:
return [] return []
return [torrent.to_dict() for torrent in torrents] return [torrent.to_dict() for torrent in torrents]

View File

@ -197,7 +197,7 @@ class ChainBase(metaclass=ABCMeta):
return self.run_module("search_medias", meta=meta) return self.run_module("search_medias", meta=meta)
def search_torrents(self, site: CommentedMap, def search_torrents(self, site: CommentedMap,
mediainfo: Optional[MediaInfo] = None, mediainfo: MediaInfo,
keyword: str = None, keyword: str = None,
page: int = 0, page: int = 0,
area: str = "title") -> List[TorrentInfo]: area: str = "title") -> List[TorrentInfo]:

View File

@ -76,22 +76,6 @@ class SearchChain(ChainBase):
print(str(e)) print(str(e))
return [] return []
def browse(self, domain: str, keyword: str = None) -> List[TorrentInfo]:
"""
浏览站点首页内容
:param domain: 站点域名
:param keyword: 关键词有值时为搜索
"""
if not keyword:
logger.info(f'开始浏览站点首页内容,站点:{domain} ...')
else:
logger.info(f'开始搜索资源,关键词:{keyword},站点:{domain} ...')
site = self.siteshelper.get_indexer(domain)
if not site:
logger.error(f'站点 {domain} 不存在!')
return []
return self.search_torrents(site=site, keyword=keyword)
def process(self, mediainfo: MediaInfo, def process(self, mediainfo: MediaInfo,
keyword: str = None, keyword: str = None,
no_exists: Dict[int, Dict[int, NotExistMediaInfo]] = None, no_exists: Dict[int, Dict[int, NotExistMediaInfo]] = None,

View File

@ -375,14 +375,14 @@ class SubscribeChain(ChainBase):
def refresh(self): def refresh(self):
""" """
刷新订阅 订阅刷新
""" """
# 查询所有订阅 # 查询所有订阅
subscribes = self.subscribeoper.list('R') subscribes = self.subscribeoper.list('R')
if not subscribes: if not subscribes:
# 没有订阅不运行 # 没有订阅不运行
return return
# 刷新站点资源,从缓存中匹配订阅 # 触发刷新站点资源,从缓存中匹配订阅
self.match( self.match(
self.torrentschain.refresh() self.torrentschain.refresh()
) )

View File

@ -1,6 +1,6 @@
from datetime import datetime
from typing import Dict, List, Union from typing import Dict, List, Union
from cachetools import cached, TTLCache
from requests import Session from requests import Session
from app.chain import ChainBase from app.chain import ChainBase
@ -12,17 +12,16 @@ from app.helper.sites import SitesHelper
from app.log import logger from app.log import logger
from app.schemas import Notification from app.schemas import Notification
from app.schemas.types import SystemConfigKey, MessageChannel from app.schemas.types import SystemConfigKey, MessageChannel
from app.utils.singleton import Singleton
from app.utils.string import StringUtils from app.utils.string import StringUtils
from app.utils.timer import TimerUtils
class TorrentsChain(ChainBase): class TorrentsChain(ChainBase, metaclass=Singleton):
""" """
种子刷新处理链 站点首页种子处理链服务于订阅刷流等
""" """
_cache_file = "__torrents_cache__" _cache_file = "__torrents_cache__"
_last_refresh_time = None
def __init__(self, db: Session = None): def __init__(self, db: Session = None):
super().__init__(db) super().__init__(db)
@ -46,17 +45,23 @@ class TorrentsChain(ChainBase):
# 读取缓存 # 读取缓存
return self.load_cache(self._cache_file) or {} return self.load_cache(self._cache_file) or {}
@cached(cache=TTLCache(maxsize=128, ttl=600))
def browse(self, domain: str) -> List[TorrentInfo]:
"""
浏览站点首页内容返回种子清单TTL缓存10分钟
:param domain: 站点域名
"""
logger.info(f'开始获取站点 {domain} 最新种子 ...')
site = self.siteshelper.get_indexer(domain)
if not site:
logger.error(f'站点 {domain} 不存在!')
return []
return self.refresh_torrents(site=site)
def refresh(self) -> Dict[str, List[Context]]: def refresh(self) -> Dict[str, List[Context]]:
""" """
刷新站点最新资源 刷新站点最新资源识别并缓存起来
""" """
# 控制刷新频率不能小于10分钟
if self._last_refresh_time and TimerUtils.diff_minutes(self._last_refresh_time) < 10:
logger.warn(f'种子刷新频率过快,跳过本次刷新')
return self.get_torrents()
# 记录刷新时间
self._last_refresh_time = datetime.now()
# 读取缓存 # 读取缓存
torrents_cache = self.get_torrents() torrents_cache = self.get_torrents()
@ -70,9 +75,8 @@ class TorrentsChain(ChainBase):
# 未开启的站点不搜索 # 未开启的站点不搜索
if config_indexers and str(indexer.get("id")) not in config_indexers: if config_indexers and str(indexer.get("id")) not in config_indexers:
continue continue
logger.info(f'开始刷新 {indexer.get("name")} 最新种子 ...')
domain = StringUtils.get_url_domain(indexer.get("domain")) domain = StringUtils.get_url_domain(indexer.get("domain"))
torrents: List[TorrentInfo] = self.refresh_torrents(site=indexer) torrents: List[TorrentInfo] = self.browse(domain=domain)
# 按pubdate降序排列 # 按pubdate降序排列
torrents.sort(key=lambda x: x.pubdate or '', reverse=True) torrents.sort(key=lambda x: x.pubdate or '', reverse=True)
# 取前N条 # 取前N条

View File

@ -9,7 +9,6 @@ import pytz
from apscheduler.schedulers.background import BackgroundScheduler from apscheduler.schedulers.background import BackgroundScheduler
from app import schemas from app import schemas
from app.chain.search import SearchChain
from app.chain.torrents import TorrentsChain from app.chain.torrents import TorrentsChain
from app.core.config import settings from app.core.config import settings
from app.db.site_oper import SiteOper from app.db.site_oper import SiteOper
@ -50,7 +49,6 @@ class BrushFlow(_PluginBase):
siteshelper = None siteshelper = None
siteoper = None siteoper = None
torrents = None torrents = None
searchchain = None
qb = None qb = None
tr = None tr = None
# 添加种子定时 # 添加种子定时
@ -90,7 +88,6 @@ class BrushFlow(_PluginBase):
self.siteshelper = SitesHelper() self.siteshelper = SitesHelper()
self.siteoper = SiteOper() self.siteoper = SiteOper()
self.torrents = TorrentsChain() self.torrents = TorrentsChain()
self.searchchain = SearchChain()
if config: if config:
self._enabled = config.get("enabled") self._enabled = config.get("enabled")
self._notify = config.get("notify") self._notify = config.get("notify")
@ -1254,7 +1251,7 @@ class BrushFlow(_PluginBase):
logger.warn(f"站点不存在:{siteid}") logger.warn(f"站点不存在:{siteid}")
continue continue
logger.info(f"开始获取站点 {siteinfo.name} 的新种子 ...") logger.info(f"开始获取站点 {siteinfo.name} 的新种子 ...")
torrents = self.searchchain.browse(domain=siteinfo.domain) torrents = self.torrents.browse(domain=siteinfo.domain)
if not torrents: if not torrents:
logger.info(f"站点 {siteinfo.name} 没有获取到种子") logger.info(f"站点 {siteinfo.name} 没有获取到种子")
continue continue

View File

@ -50,4 +50,5 @@ cacheout~=0.14.1
click~=8.1.6 click~=8.1.6
requests_cache~=0.5.2 requests_cache~=0.5.2
parse~=1.19.0 parse~=1.19.0
docker~=6.1.3 docker~=6.1.3
cachetools~=5.3.1