mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-09-05 07:27:15 +08:00
fix 适配新版飞牛影视
This commit is contained in:
@@ -16,6 +16,7 @@ from fastapi import APIRouter, Body, Depends, HTTPException, Header, Request, Re
|
|||||||
from fastapi.responses import StreamingResponse
|
from fastapi.responses import StreamingResponse
|
||||||
|
|
||||||
from app import schemas
|
from app import schemas
|
||||||
|
from app.chain.mediaserver import MediaServerChain
|
||||||
from app.chain.search import SearchChain
|
from app.chain.search import SearchChain
|
||||||
from app.chain.system import SystemChain
|
from app.chain.system import SystemChain
|
||||||
from app.core.cache import AsyncFileCache
|
from app.core.cache import AsyncFileCache
|
||||||
@@ -52,6 +53,7 @@ async def fetch_image(
|
|||||||
proxy: bool = False,
|
proxy: bool = False,
|
||||||
use_cache: bool = False,
|
use_cache: bool = False,
|
||||||
if_none_match: Optional[str] = None,
|
if_none_match: Optional[str] = None,
|
||||||
|
cookies: Optional[str | dict] = None,
|
||||||
allowed_domains: Optional[set[str]] = None) -> Optional[Response]:
|
allowed_domains: Optional[set[str]] = None) -> Optional[Response]:
|
||||||
"""
|
"""
|
||||||
处理图片缓存逻辑,支持HTTP缓存和磁盘缓存
|
处理图片缓存逻辑,支持HTTP缓存和磁盘缓存
|
||||||
@@ -96,8 +98,13 @@ async def fetch_image(
|
|||||||
# 请求远程图片
|
# 请求远程图片
|
||||||
referer = "https://movie.douban.com/" if "doubanio.com" in url else None
|
referer = "https://movie.douban.com/" if "doubanio.com" in url else None
|
||||||
proxies = settings.PROXY if proxy else None
|
proxies = settings.PROXY if proxy else None
|
||||||
response = await AsyncRequestUtils(ua=settings.NORMAL_USER_AGENT, proxies=proxies, referer=referer,
|
response = await AsyncRequestUtils(
|
||||||
accept_type="image/avif,image/webp,image/apng,*/*").get_res(url=url)
|
ua=settings.NORMAL_USER_AGENT,
|
||||||
|
proxies=proxies,
|
||||||
|
referer=referer,
|
||||||
|
cookies=cookies,
|
||||||
|
accept_type="image/avif,image/webp,image/apng,*/*",
|
||||||
|
).get_res(url=url)
|
||||||
if not response:
|
if not response:
|
||||||
logger.warn(f"Failed to fetch image from URL: {url}")
|
logger.warn(f"Failed to fetch image from URL: {url}")
|
||||||
return None
|
return None
|
||||||
@@ -150,7 +157,8 @@ async def proxy_img(
|
|||||||
hosts = [config.config.get("host") for config in MediaServerHelper().get_configs().values() if
|
hosts = [config.config.get("host") for config in MediaServerHelper().get_configs().values() if
|
||||||
config and config.config and config.config.get("host")]
|
config and config.config and config.config.get("host")]
|
||||||
allowed_domains = set(settings.SECURITY_IMAGE_DOMAINS) | set(hosts)
|
allowed_domains = set(settings.SECURITY_IMAGE_DOMAINS) | set(hosts)
|
||||||
return await fetch_image(url=imgurl, proxy=proxy, use_cache=cache,
|
cookies = MediaServerChain().get_image_cookies(server=None, image_url=imgurl)
|
||||||
|
return await fetch_image(url=imgurl, proxy=proxy, use_cache=cache, cookies=cookies,
|
||||||
if_none_match=if_none_match, allowed_domains=allowed_domains)
|
if_none_match=if_none_match, allowed_domains=allowed_domains)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -113,6 +113,16 @@ class MediaServerChain(ChainBase):
|
|||||||
"""
|
"""
|
||||||
return self.run_module("mediaserver_play_url", server=server, item_id=item_id)
|
return self.run_module("mediaserver_play_url", server=server, item_id=item_id)
|
||||||
|
|
||||||
|
def get_image_cookies(
|
||||||
|
self, server: Optional[str], image_url: str
|
||||||
|
) -> Optional[str | dict]:
|
||||||
|
"""
|
||||||
|
获取图片的Cookies
|
||||||
|
"""
|
||||||
|
return self.run_module(
|
||||||
|
"mediaserver_image_cookies", server=server, image_url=image_url
|
||||||
|
)
|
||||||
|
|
||||||
def sync(self):
|
def sync(self):
|
||||||
"""
|
"""
|
||||||
同步媒体库所有数据到本地数据库
|
同步媒体库所有数据到本地数据库
|
||||||
|
|||||||
@@ -382,3 +382,27 @@ class TrimeMediaModule(_ModuleBase, _MediaServerBase[TrimeMedia]):
|
|||||||
if not server_obj:
|
if not server_obj:
|
||||||
return []
|
return []
|
||||||
return server_obj.get_latest_backdrops(num=count, remote=remote) or []
|
return server_obj.get_latest_backdrops(num=count, remote=remote) or []
|
||||||
|
|
||||||
|
def mediaserver_image_cookies(
|
||||||
|
self,
|
||||||
|
server: Optional[str] = None,
|
||||||
|
image_url: Optional[str] = None,
|
||||||
|
**kwargs,
|
||||||
|
) -> Optional[str | dict]:
|
||||||
|
"""
|
||||||
|
获取飞牛影视服务器的图片Cookies
|
||||||
|
|
||||||
|
:param server: 媒体服务器名称
|
||||||
|
:param image_url: 图片网址
|
||||||
|
"""
|
||||||
|
if not image_url:
|
||||||
|
return None
|
||||||
|
if server:
|
||||||
|
server_obj = self.get_instance(server)
|
||||||
|
if not server_obj:
|
||||||
|
return None
|
||||||
|
return server_obj.get_image_cookies(image_url)
|
||||||
|
else:
|
||||||
|
for server_obj in self.get_instances().values():
|
||||||
|
if cookies := server_obj.get_image_cookies(image_url):
|
||||||
|
return cookies
|
||||||
|
|||||||
@@ -190,7 +190,7 @@ class Api:
|
|||||||
"""
|
"""
|
||||||
用户列表(仅管理员有权访问)
|
用户列表(仅管理员有权访问)
|
||||||
"""
|
"""
|
||||||
if (res := self.request("/memory/user/list")) and res.success:
|
if (res := self.request("/manager/user/list")) and res.success:
|
||||||
if not res.data:
|
if not res.data:
|
||||||
return []
|
return []
|
||||||
return [
|
return [
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import app.modules.trimemedia.api as fnapi
|
|||||||
from app import schemas
|
from app import schemas
|
||||||
from app.log import logger
|
from app.log import logger
|
||||||
from app.schemas import MediaType
|
from app.schemas import MediaType
|
||||||
|
from app.utils.security import SecurityUtils
|
||||||
from app.utils.url import UrlUtils
|
from app.utils.url import UrlUtils
|
||||||
|
|
||||||
|
|
||||||
@@ -20,6 +21,7 @@ class TrimeMedia:
|
|||||||
_sync_libraries: List[str] = []
|
_sync_libraries: List[str] = []
|
||||||
|
|
||||||
_api: Optional[fnapi.Api] = None
|
_api: Optional[fnapi.Api] = None
|
||||||
|
_version: Optional[fnapi.Version] = None
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
@@ -55,6 +57,13 @@ class TrimeMedia:
|
|||||||
"""
|
"""
|
||||||
return self._api
|
return self._api
|
||||||
|
|
||||||
|
@property
|
||||||
|
def version(self) -> Optional[fnapi.Version]:
|
||||||
|
"""
|
||||||
|
获得飞牛API的版本
|
||||||
|
"""
|
||||||
|
return self._version
|
||||||
|
|
||||||
class _ApiCreateResult:
|
class _ApiCreateResult:
|
||||||
api: fnapi.Api
|
api: fnapi.Api
|
||||||
version: fnapi.Version
|
version: fnapi.Version
|
||||||
@@ -123,7 +132,9 @@ class TrimeMedia:
|
|||||||
self.disconnect()
|
self.disconnect()
|
||||||
if result := self.__create_api(self._host):
|
if result := self.__create_api(self._host):
|
||||||
self._api = result.api
|
self._api = result.api
|
||||||
|
self._version = result.version
|
||||||
# 版本号:0.8.53, 服务版本:0.8.23
|
# 版本号:0.8.53, 服务版本:0.8.23
|
||||||
|
# 版本号:0.8.56, 服务版本:0.8.23 接口/memory/user/list改为/manager/user/list
|
||||||
logger.debug(
|
logger.debug(
|
||||||
f"版本号:{result.version.frontend}, 服务版本:{result.version.backend}"
|
f"版本号:{result.version.frontend}, 服务版本:{result.version.backend}"
|
||||||
)
|
)
|
||||||
@@ -603,6 +614,7 @@ class TrimeMedia:
|
|||||||
if (item_details := self._api.item(item.guid)) is None:
|
if (item_details := self._api.item(item.guid)) is None:
|
||||||
continue
|
continue
|
||||||
if remote:
|
if remote:
|
||||||
|
# FIXME 新版飞牛的壁纸无法直接在浏览器中访问
|
||||||
img_host = self._playhost or self._api.host
|
img_host = self._playhost or self._api.host
|
||||||
else:
|
else:
|
||||||
img_host = self._api.host
|
img_host = self._api.host
|
||||||
@@ -631,3 +643,13 @@ class TrimeMedia:
|
|||||||
)
|
)
|
||||||
else False
|
else False
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def get_image_cookies(self, image_url: str):
|
||||||
|
"""
|
||||||
|
获得指定图片的Cookies
|
||||||
|
"""
|
||||||
|
if not image_url or not SecurityUtils.is_safe_url(
|
||||||
|
image_url, [self._api.host], strict=True
|
||||||
|
):
|
||||||
|
return None
|
||||||
|
return {"Trim-MC-token": self._api.token}
|
||||||
|
|||||||
Reference in New Issue
Block a user