feat 整合RSS订阅模式
This commit is contained in:
@ -8,6 +8,7 @@ from app.core.context import TorrentInfo, Context, MediaInfo
|
||||
from app.core.metainfo import MetaInfo
|
||||
from app.db import SessionFactory
|
||||
from app.db.systemconfig_oper import SystemConfigOper
|
||||
from app.helper.rss import RssHelper
|
||||
from app.helper.sites import SitesHelper
|
||||
from app.log import logger
|
||||
from app.schemas import Notification
|
||||
@ -18,15 +19,17 @@ from app.utils.string import StringUtils
|
||||
|
||||
class TorrentsChain(ChainBase, metaclass=Singleton):
|
||||
"""
|
||||
站点首页种子处理链,服务于订阅、刷流等
|
||||
站点首页或RSS种子处理链,服务于订阅、刷流等
|
||||
"""
|
||||
|
||||
_cache_file = "__torrents_cache__"
|
||||
_spider_file = "__torrents_cache__"
|
||||
_rss_file = "__rss_cache__"
|
||||
|
||||
def __init__(self):
|
||||
self._db = SessionFactory()
|
||||
super().__init__(self._db)
|
||||
self.siteshelper = SitesHelper()
|
||||
self.rsshelper = RssHelper()
|
||||
self.systemconfig = SystemConfigOper()
|
||||
|
||||
def remote_refresh(self, channel: MessageChannel, userid: Union[str, int] = None):
|
||||
@ -39,12 +42,20 @@ class TorrentsChain(ChainBase, metaclass=Singleton):
|
||||
self.post_message(Notification(channel=channel,
|
||||
title=f"种子刷新完成!", userid=userid))
|
||||
|
||||
def get_torrents(self) -> Dict[str, List[Context]]:
|
||||
def get_torrents(self, stype: str = None) -> Dict[str, List[Context]]:
|
||||
"""
|
||||
获取当前缓存的种子
|
||||
:param stype: 强制指定缓存类型,spider:爬虫缓存,rss:rss缓存
|
||||
"""
|
||||
|
||||
if not stype:
|
||||
stype = settings.SUBSCRIBE_MODE
|
||||
|
||||
# 读取缓存
|
||||
return self.load_cache(self._cache_file) or {}
|
||||
if stype == 'spider':
|
||||
return self.load_cache(self._spider_file) or {}
|
||||
else:
|
||||
return self.load_cache(self._rss_file) or {}
|
||||
|
||||
@cached(cache=TTLCache(maxsize=128, ttl=600))
|
||||
def browse(self, domain: str) -> List[TorrentInfo]:
|
||||
@ -59,10 +70,55 @@ class TorrentsChain(ChainBase, metaclass=Singleton):
|
||||
return []
|
||||
return self.refresh_torrents(site=site)
|
||||
|
||||
def refresh(self) -> Dict[str, List[Context]]:
|
||||
@cached(cache=TTLCache(maxsize=128, ttl=300))
|
||||
def rss(self, domain: str) -> List[TorrentInfo]:
|
||||
"""
|
||||
获取站点RSS内容,返回种子清单,TTL缓存5分钟
|
||||
:param domain: 站点域名
|
||||
"""
|
||||
logger.info(f'开始获取站点 {domain} RSS ...')
|
||||
site = self.siteshelper.get_indexer(domain)
|
||||
if not site:
|
||||
logger.error(f'站点 {domain} 不存在!')
|
||||
return []
|
||||
if not site.get("rss"):
|
||||
logger.error(f'站点 {domain} 未配置RSS地址!')
|
||||
return []
|
||||
rss_items = self.rsshelper.parse(site.get("rss"), True if site.get("proxy") else False)
|
||||
if not rss_items:
|
||||
logger.error(f'站点 {domain} 未获取到RSS数据!')
|
||||
return []
|
||||
# 组装种子
|
||||
ret_torrents: List[TorrentInfo] = []
|
||||
for item in rss_items:
|
||||
if not item.get("title"):
|
||||
continue
|
||||
torrentinfo = TorrentInfo(
|
||||
site=site.get("id"),
|
||||
site_name=site.get("name"),
|
||||
site_cookie=site.get("cookie"),
|
||||
site_ua=site.get("ua") or settings.USER_AGENT,
|
||||
site_proxy=site.get("proxy"),
|
||||
site_order=site.get("pri"),
|
||||
title=item.get("title"),
|
||||
description=item.get("description"),
|
||||
enclosure=item.get("enclosure"),
|
||||
page_url=item.get("link"),
|
||||
size=item.get("size"),
|
||||
pubdate=item["pubdate"].strftime("%Y-%m-%d %H:%M:%S") if item.get("pubdate") else None,
|
||||
)
|
||||
ret_torrents.append(torrentinfo)
|
||||
|
||||
return ret_torrents
|
||||
|
||||
def refresh(self, stype: str = None) -> Dict[str, List[Context]]:
|
||||
"""
|
||||
刷新站点最新资源,识别并缓存起来
|
||||
:param stype: 强制指定缓存类型,spider:爬虫缓存,rss:rss缓存
|
||||
"""
|
||||
# 刷新类型
|
||||
if not stype:
|
||||
stype = settings.SUBSCRIBE_MODE
|
||||
|
||||
# 读取缓存
|
||||
torrents_cache = self.get_torrents()
|
||||
@ -77,7 +133,12 @@ class TorrentsChain(ChainBase, metaclass=Singleton):
|
||||
if config_indexers and str(indexer.get("id")) not in config_indexers:
|
||||
continue
|
||||
domain = StringUtils.get_url_domain(indexer.get("domain"))
|
||||
torrents: List[TorrentInfo] = self.browse(domain=domain)
|
||||
if stype == "spider":
|
||||
# 刷新首页种子
|
||||
torrents: List[TorrentInfo] = self.browse(domain=domain)
|
||||
else:
|
||||
# 刷新RSS种子
|
||||
torrents: List[TorrentInfo] = self.rss(site=indexer)
|
||||
# 按pubdate降序排列
|
||||
torrents.sort(key=lambda x: x.pubdate or '', reverse=True)
|
||||
# 取前N条
|
||||
@ -120,6 +181,9 @@ class TorrentsChain(ChainBase, metaclass=Singleton):
|
||||
else:
|
||||
logger.info(f'{indexer.get("name")} 没有获取到种子')
|
||||
# 保存缓存到本地
|
||||
self.save_cache(torrents_cache, self._cache_file)
|
||||
if stype == "spider":
|
||||
self.save_cache(torrents_cache, self._spider_file)
|
||||
else:
|
||||
self.save_cache(torrents_cache, self._rss_file)
|
||||
# 返回
|
||||
return torrents_cache
|
||||
|
Reference in New Issue
Block a user