refactor: isolate subscription media server aggregation

This commit is contained in:
jxxghp
2026-08-22 19:34:19 +08:00
parent 1bb6e36e8c
commit c8e2ba0ea7
+55 -36
View File
@@ -3259,10 +3259,7 @@ class SubscribeChain(MusicSubscribeMixin, InteractionChainMixin, ChainBase):
info = _SchemaSubscribeEpisodeInfo() info = _SchemaSubscribeEpisodeInfo()
info.title = episode.name info.title = episode.name
info.description = episode.overview info.description = episode.overview
info.backdrop = self.runtime_config.tmdb_image_url( info.backdrop = self.runtime_config.tmdb_image_url(episode.still_path, "w500")
episode.still_path,
"w500",
)
episodes[episode.episode_number] = info episodes[episode.episode_number] = info
elif subscribe.type == MediaType.TV.value: elif subscribe.type == MediaType.TV.value:
# 根据开始结束集计算集信息 # 根据开始结束集计算集信息
@@ -3350,31 +3347,54 @@ class SubscribeChain(MusicSubscribeMixin, InteractionChainMixin, ChainBase):
else: else:
episodes[0].library.append(file_info) episodes[0].library.append(file_info)
# 合并所有媒体服务器已存在条目(逐台查询,不只取第一个命中) self._append_subscribe_media_servers(subscribe, mediainfo, episodes)
# 更新订阅信息
subscribe_info.subscribe = Subscribe(**subscribe.to_dict())
subscribe_info.episodes = episodes
return subscribe_info
def _append_subscribe_media_servers(
self,
subscribe: Subscribe,
mediainfo: MediaInfo,
episodes: Dict[int, _SchemaSubscribeEpisodeInfo],
) -> None:
"""合并媒体服务器条目,跳过已经由本地媒体库记录覆盖的服务。"""
mediaserver_chain = MediaServerChain() mediaserver_chain = MediaServerChain()
server_names = list(MediaServerHelper().get_services().keys()) server_names = list(MediaServerHelper().get_services().keys())
def _has_server_entry(library_list: List[_SchemaSubscribeLibraryFileInfo], def has_server_entry(
library_list: List[_SchemaSubscribeLibraryFileInfo],
server_name: Optional[str], server_name: Optional[str],
server_type: Optional[str]) -> bool: server_type: Optional[str],
) -> bool:
"""判断媒体库列表是否已经包含目标服务条目。"""
for info in library_list or []: for info in library_list or []:
if info.server and server_name and info.server == server_name: if info.server and server_name and info.server == server_name:
return True return True
if info.server_type and server_type and info.server_type == server_type \ if (
and info.server == server_name \ info.server_type
and (not info.file_path or str(info.file_path).startswith(("http://", "https://"))): and server_type
and info.server_type == server_type
and info.server == server_name
and (
not info.file_path
or str(info.file_path).startswith(("http://", "https://"))
)
):
return True return True
return False return False
for server_name in server_names: for server_name in server_names:
exists_media = self.media_exists(mediainfo=mediainfo, server=server_name) exists_media = self.media_exists(mediainfo=mediainfo, server=server_name)
# 仅合并真实媒体服务器结果,跳过本地 FileManager 兜底(已由 media_files 覆盖)
if not exists_media or not (exists_media.server or exists_media.server_type): if not exists_media or not (exists_media.server or exists_media.server_type):
continue continue
resolved_server = exists_media.server or server_name resolved_server = exists_media.server or server_name
server_storage = exists_media.server_type or resolved_server server_storage = exists_media.server_type or resolved_server
server_itemid = str(exists_media.itemid) if exists_media.itemid is not None else None server_itemid = (
str(exists_media.itemid) if exists_media.itemid is not None else None
)
series_detail_url = None series_detail_url = None
if resolved_server and exists_media.itemid is not None: if resolved_server and exists_media.itemid is not None:
series_detail_url = mediaserver_chain.get_play_url( series_detail_url = mediaserver_chain.get_play_url(
@@ -3382,7 +3402,22 @@ class SubscribeChain(MusicSubscribeMixin, InteractionChainMixin, ChainBase):
item_id=exists_media.itemid, item_id=exists_media.itemid,
) )
if subscribe.type == MediaType.TV.value: if subscribe.type != MediaType.TV.value:
episode_info = episodes.get(0)
if episode_info and not has_server_entry(
episode_info.library, resolved_server, exists_media.server_type
):
episode_info.library.append(
_SchemaSubscribeLibraryFileInfo(
storage=server_storage,
file_path=series_detail_url,
server=resolved_server,
server_type=exists_media.server_type,
itemid=server_itemid,
)
)
continue
season_number = subscribe.season if subscribe.season is not None else 1 season_number = subscribe.season if subscribe.season is not None else 1
exist_episodes = (exists_media.seasons or {}).get(season_number) or [] exist_episodes = (exists_media.seasons or {}).get(season_number) or []
episode_item_ids: Dict[int, str] = {} episode_item_ids: Dict[int, str] = {}
@@ -3394,9 +3429,9 @@ class SubscribeChain(MusicSubscribeMixin, InteractionChainMixin, ChainBase):
) )
for episode_number in exist_episodes: for episode_number in exist_episodes:
episode_info = episodes.get(episode_number) episode_info = episodes.get(episode_number)
if not episode_info: if not episode_info or has_server_entry(
continue episode_info.library, resolved_server, exists_media.server_type
if _has_server_entry(episode_info.library, resolved_server, exists_media.server_type): ):
continue continue
episode_itemid = episode_item_ids.get(episode_number) or server_itemid episode_itemid = episode_item_ids.get(episode_number) or server_itemid
detail_url = series_detail_url detail_url = series_detail_url
@@ -3411,27 +3446,11 @@ class SubscribeChain(MusicSubscribeMixin, InteractionChainMixin, ChainBase):
file_path=detail_url, file_path=detail_url,
server=resolved_server, server=resolved_server,
server_type=exists_media.server_type, server_type=exists_media.server_type,
itemid=str(episode_itemid) if episode_itemid is not None else None, itemid=(
str(episode_itemid) if episode_itemid is not None else None
),
) )
) )
else:
episode_info = episodes.get(0)
if episode_info and not _has_server_entry(
episode_info.library, resolved_server, exists_media.server_type):
episode_info.library.append(
_SchemaSubscribeLibraryFileInfo(
storage=server_storage,
file_path=series_detail_url,
server=resolved_server,
server_type=exists_media.server_type,
itemid=server_itemid,
)
)
# 更新订阅信息
subscribe_info.subscribe = Subscribe(**subscribe.to_dict())
subscribe_info.episodes = episodes
return subscribe_info
def check_and_handle_existing_media(self, subscribe: Subscribe, meta: MetaBase, def check_and_handle_existing_media(self, subscribe: Subscribe, meta: MetaBase,
mediainfo: MediaInfo, mediakey: Union[str, int]): mediainfo: MediaInfo, mediakey: Union[str, int]):