Files
MoviePilot/app/workflow/actions/fetch_rss.py

115 lines
4.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from typing import Optional
from pydantic import Field
from app.application.configuration import get_chain_runtime_config_snapshot
from app.application.rss import RssHelper
from app.chain.media import MediaChain
from app.domain.context import Context, TorrentInfo
from app.domain.metainfo import MetaInfo
from app.runtime.log import logger
from app.runtime.stop import runtime_stop_state
from app.schemas.workflow import ActionContext, ActionParams
from app.workflow.actions import BaseAction
class FetchRssParams(ActionParams):
"""
获取RSS资源列表参数
"""
url: str = Field(default=None, description="RSS地址")
proxy: Optional[bool] = Field(default=False, description="是否使用代理")
timeout: Optional[int] = Field(default=15, description="超时时间")
content_type: Optional[str] = Field(default=None, description="Content-Type")
referer: Optional[str] = Field(default=None, description="Referer")
ua: Optional[str] = Field(default=None, description="User-Agent")
match_media: Optional[bool] = Field(default=False, description="匹配媒体信息")
class FetchRssAction(BaseAction):
"""
获取RSS资源列表
"""
contract = {
"outputs": [{"name": "torrents", "label": "资源", "kind": "list"}],
}
def __init__(self, action_id: str):
super().__init__(action_id)
self._rss_torrents = []
self._has_error = False
name = "获取RSS资源"
description = "订阅RSS地址获取资源"
data = FetchRssParams().model_dump()
@property
def success(self) -> bool:
return not self._has_error
def execute(self, workflow_id: int, params: dict, context: ActionContext) -> ActionContext:
"""
请求RSS地址获取数据,并解析为资源列表
"""
params = FetchRssParams(**params)
if not params.url:
return context
headers = {}
if params.content_type:
headers["Content-Type"] = params.content_type
if params.referer:
headers["Referer"] = params.referer
if params.ua:
headers["User-Agent"] = params.ua
rss_items = RssHelper().parse(url=params.url,
proxy=(
get_chain_runtime_config_snapshot().proxy
if params.proxy
else None
),
timeout=params.timeout,
headers=headers)
if rss_items is None or rss_items is False:
logger.error(f'RSS地址 {params.url} 请求失败!')
self._has_error = True
return context
if not rss_items:
logger.error(f'RSS地址 {params.url} 未获取到RSS数据!')
return context
# 组装种子
for item in rss_items:
if runtime_stop_state.is_workflow_stopped(workflow_id):
break
if not item.get("title"):
continue
torrentinfo = TorrentInfo(
title=item.get("title"),
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,
)
meta = MetaInfo(title=torrentinfo.title, subtitle=torrentinfo.description)
mediainfo = None
if params.match_media:
mediainfo = MediaChain().recognize_by_meta(
meta,
obtain_images=False,
)
if not mediainfo:
logger.warning(f"{torrentinfo.title} 未识别到媒体信息")
continue
self._rss_torrents.append(Context(meta_info=meta, media_info=mediainfo, torrent_info=torrentinfo))
if self._rss_torrents:
logger.info(f"获取到 {len(self._rss_torrents)} 个RSS资源")
context.torrents.extend(self._rss_torrents)
self.job_done(f"获取到 {len(self._rss_torrents)} 个资源")
return context