feat(media): 媒体信息补充 TVDB slug 字段,修复 TheTvDb 数字 ID 链接 404

TVDB 已弃用数字 ID 直达 URL,仅 slug 形式可访问。详情接口在电视剧有 TVDB ID 时通过轻量 get_series 接口获取 slug,并随 MediaInfo 合并下发。Closes jxxghp/MoviePilot-Frontend#643
This commit is contained in:
jxxghp
2026-08-10 21:41:04 +08:00
parent 4a14af706c
commit a322c4c375
6 changed files with 38 additions and 1 deletions
+5
View File
@@ -521,6 +521,11 @@ async def detail(
# 识别 # 识别
if mediainfo: if mediainfo:
await mediachain.async_obtain_images(mediainfo) await mediachain.async_obtain_images(mediainfo)
# 电视剧且有 TVDB ID 时,补充获取 slug 用于构建 TheTvDb 直达链接
if mediainfo.type == MediaType.TV and mediainfo.tvdb_id and not mediainfo.tvdb_slug:
slug = mediachain.tvdb_slug(mediainfo.tvdb_id)
if slug:
mediainfo.tvdb_slug = slug
return mediainfo.to_dict() return mediainfo.to_dict()
return schemas.MediaInfo() return schemas.MediaInfo()
+8
View File
@@ -1040,6 +1040,14 @@ class ChainBase(metaclass=ABCMeta):
""" """
return self.run_module("tvdb_info", tvdbid=tvdbid) return self.run_module("tvdb_info", tvdbid=tvdbid)
def tvdb_slug(self, tvdbid: int) -> Optional[str]:
"""
获取TVDB剧集 slug(别名),用于构建 TheTvDb 直达链接。
:param tvdbid: int
:return: slug 字符串
"""
return self.run_module("tvdb_slug", tvdbid=tvdbid)
def tmdb_info( def tmdb_info(
self, tmdbid: int, mtype: MediaType, season: Optional[int] = None self, tmdbid: int, mtype: MediaType, season: Optional[int] = None
) -> Optional[dict]: ) -> Optional[dict]:
+1 -1
View File
@@ -707,7 +707,7 @@ class MediaChain(ChainBase, ConfigReloadMixin, metaclass=Singleton):
mediainfo.category = tmdb_media.category mediainfo.category = tmdb_media.category
if not mediainfo.genre_ids: if not mediainfo.genre_ids:
mediainfo.genre_ids = list(tmdb_media.genre_ids or []) mediainfo.genre_ids = list(tmdb_media.genre_ids or [])
for field in ("imdb_id", "tvdb_id", "collection_id"): for field in ("imdb_id", "tvdb_id", "tvdb_slug", "collection_id"):
if not getattr(mediainfo, field, None): if not getattr(mediainfo, field, None):
setattr(mediainfo, field, getattr(tmdb_media, field, None)) setattr(mediainfo, field, getattr(tmdb_media, field, None))
return mediainfo return mediainfo
+7
View File
@@ -206,6 +206,11 @@ class MusicInfo:
"""音乐不使用 TVDB ID,兼容现有下载历史字段。""" """音乐不使用 TVDB ID,兼容现有下载历史字段。"""
return None return None
@property
def tvdb_slug(self) -> None:
"""音乐不使用 TVDB Slug,兼容现有字段。"""
return None
@property @property
def douban_id(self) -> None: def douban_id(self) -> None:
"""音乐不使用豆瓣 ID,兼容现有下载历史字段。""" """音乐不使用豆瓣 ID,兼容现有下载历史字段。"""
@@ -888,6 +893,8 @@ class MediaInfo:
imdb_id: str = None imdb_id: str = None
# TVDB ID # TVDB ID
tvdb_id: int = None tvdb_id: int = None
# TVDB Slug(别名,用于构建 TheTvDb 直达链接)
tvdb_slug: str = None
# 豆瓣ID # 豆瓣ID
douban_id: str = None douban_id: str = None
# Bangumi ID # Bangumi ID
+15
View File
@@ -143,6 +143,21 @@ class TheTvDbModule(_ModuleBase):
logger.error(f"获取TVDB信息失败: {str(err)}") logger.error(f"获取TVDB信息失败: {str(err)}")
return None return None
def tvdb_slug(self, tvdbid: int) -> Optional[str]:
"""
获取TVDB剧集的 slug别名用于构建 TheTvDb 直达链接
:param tvdbid: int
:return: slug 字符串 "speed-and-love"
"""
try:
result = self._handle_tvdb_call("get_series", tvdbid)
if result and isinstance(result, dict):
return result.get("slug")
return None
except Exception as err:
logger.error(f"获取TVDB slug 失败: {str(err)}")
return None
def search_tvdb(self, title: str) -> list: def search_tvdb(self, title: str) -> list:
""" """
用标题搜索TVDB剧集 用标题搜索TVDB剧集
+2
View File
@@ -105,6 +105,8 @@ class MediaInfo(BaseModel):
imdb_id: Optional[str] = None imdb_id: Optional[str] = None
# TVDB ID # TVDB ID
tvdb_id: Optional[int] = None tvdb_id: Optional[int] = None
# TVDB Slug(别名,用于构建 TheTvDb 直达链接)
tvdb_slug: Optional[str] = None
# 豆瓣ID # 豆瓣ID
douban_id: Optional[str] = None douban_id: Optional[str] = None
# Bangumi ID # Bangumi ID