mirror of
https://github.com/nirvana-7777/script.service.ultimate.git
synced 2026-10-03 14:32:15 +02:00
Add discovery
This commit is contained in:
@@ -152,7 +152,8 @@ class RTLPlusGraphQL:
|
||||
"WatchPlayerConfigV3":"fea0311fb572b6fded60c5a1a9d652f97f55d182bc4cedbdad676354a8d2797c",
|
||||
"SeoUrlData": "fcc4a812d6b93496f00c3068234db7722f553032bb760e09e5e6c74586c86f8d",
|
||||
"OverviewPage": "28aad4e992bb63330bfcd40a6906af3119d8a2612fa9fd28dae9c19127e247ca",
|
||||
"LiveEventsOverview": "77a8f26d5de76daf801fcd7ae54bebd0ecabbeeb3ecb90889bc4a2e5590b7d20",
|
||||
"LiveEventsOverviewPage": "77a8f26d5de76daf801fcd7ae54bebd0ecabbeeb3ecb90889bc4a2e5590b7d20",
|
||||
"SeasonWithFormatAndEpisodes": "cc0fbbe17143f549a35efa6f8665ceb9b1cfae44b590f0b2381a9a304304c584",
|
||||
}
|
||||
|
||||
@classmethod
|
||||
@@ -184,10 +185,18 @@ class RTLPlusGraphQL:
|
||||
f'{{"area":"{area}","offset":{offset},"take":{take}}}',
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def season_with_episodes(cls, season_rrn: str, offset: int = 0, limit: int = 48) -> dict:
|
||||
"""SeasonWithFormatAndEpisodes — episodes for a specific season RRN."""
|
||||
return cls._build(
|
||||
"SeasonWithFormatAndEpisodes",
|
||||
f'{{"seasonId":"{season_rrn}","offset":{offset},"limit":{limit}}}',
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def live_events_overview_page(cls) -> dict:
|
||||
"""LiveEventsOverview — all upcoming/live events grouped by teaserRows."""
|
||||
return cls._build("LiveEventsOverview", "{}")
|
||||
return cls._build("LiveEventsOverviewPage", "{}")
|
||||
|
||||
# --- VOD ---
|
||||
|
||||
|
||||
@@ -238,7 +238,7 @@ class RTLPlusProvider(StreamingProvider):
|
||||
|
||||
teaser_rows = (
|
||||
data.get("data", {})
|
||||
.get("liveEventsOverview", {})
|
||||
.get("liveEventsOverviewPage", {})
|
||||
.get("teaserRows", [])
|
||||
)
|
||||
|
||||
|
||||
@@ -143,9 +143,21 @@ class RTLPlusVodManager:
|
||||
if category_path[0].startswith(RTLPlusDefaults.VOD_SHOWS_ROOT_WATCH_PATH):
|
||||
return self._dispatch_shows(category_path)
|
||||
|
||||
# TopicWorlds branch — server RRNs only (rrn:multipurpose:...)
|
||||
if depth == 1 and category_path[0].startswith("rrn:"):
|
||||
return self._list_formats_for_topic(category_path[0])
|
||||
# RRN-namespace routing — dispatch by the kind of RRN, not depth.
|
||||
# This handles format/season RRNs returned by OverviewPage for
|
||||
# shows and serien (content_id = rrn:watch:videohub:format:* or season:*).
|
||||
first = category_path[0]
|
||||
if first.startswith("rrn:watch:videohub:format:"):
|
||||
# Format RRN → list seasons
|
||||
return self._list_seasons(first)
|
||||
|
||||
if first.startswith("rrn:watch:videohub:season:"):
|
||||
# Season RRN → list episodes via SeasonWithFormatAndEpisodes
|
||||
return self._list_episodes_for_season(first)
|
||||
|
||||
# TopicWorlds branch — rrn:multipurpose:* at depth 1
|
||||
if depth == 1 and first.startswith("rrn:"):
|
||||
return self._list_formats_for_topic(first)
|
||||
|
||||
if depth == 2:
|
||||
format_rrn = self._to_format_rrn(category_path[1])
|
||||
@@ -541,6 +553,54 @@ class RTLPlusVodManager:
|
||||
)
|
||||
return results
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Season RRN → Episodes (SeasonWithFormatAndEpisodes)
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
def _list_episodes_for_season(self, season_rrn: str) -> List[VodItem]:
|
||||
"""
|
||||
Fetch episodes for a season identified directly by its RRN.
|
||||
Uses SeasonWithFormatAndEpisodes (paginated).
|
||||
Response shape: data.season.episodes[]
|
||||
"""
|
||||
results: List[VodItem] = []
|
||||
seen: set = set()
|
||||
offset = 0
|
||||
limit = 48
|
||||
|
||||
while True:
|
||||
data = self._graphql_get(
|
||||
RTLPlusGraphQL.season_with_episodes(season_rrn, offset=offset, limit=limit)
|
||||
)
|
||||
if not data:
|
||||
break
|
||||
|
||||
season = data.get("data", {}).get("season", {}) or {}
|
||||
episodes = season.get("episodes", [])
|
||||
|
||||
for ep in episodes:
|
||||
if not ep:
|
||||
continue
|
||||
ep_id = ep.get("id", "")
|
||||
if not ep_id or ep_id in seen:
|
||||
continue
|
||||
seen.add(ep_id)
|
||||
vod = self._episode_to_item(ep)
|
||||
if vod:
|
||||
results.append(vod)
|
||||
|
||||
# SeasonWithFormatAndEpisodes doesn't paginate via pageInfo;
|
||||
# stop when we receive fewer items than requested.
|
||||
if len(episodes) < limit:
|
||||
break
|
||||
offset += limit
|
||||
|
||||
logger.debug(
|
||||
f"RTLPlusVodManager: _list_episodes_for_season({season_rrn}) "
|
||||
f"→ {len(results)} episodes"
|
||||
)
|
||||
return results
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Depth 2 (series) — Seasons for a Format
|
||||
# ------------------------------------------------------------------
|
||||
@@ -586,11 +646,11 @@ class RTLPlusVodManager:
|
||||
def _extract_seasons_from_format(data: dict) -> list:
|
||||
d = data.get("data", {})
|
||||
fmt = d.get("format", {}) or d.get("Format", {}) or {}
|
||||
return (
|
||||
fmt.get("seasons", {}).get("items", [])
|
||||
or fmt.get("seasons", [])
|
||||
or []
|
||||
)
|
||||
seasons = fmt.get("seasons", [])
|
||||
# seasons may be a list directly or {"items": [...]}
|
||||
if isinstance(seasons, dict):
|
||||
seasons = seasons.get("items", [])
|
||||
return seasons or []
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Depth 3 (series) — Episodes for a Season
|
||||
@@ -786,10 +846,17 @@ class RTLPlusVodManager:
|
||||
discriminator = server_id
|
||||
title = title or server_id
|
||||
|
||||
# Prefer the real season RRN when available (from Format.seasons[].id)
|
||||
# so the client can pass it back and route via _list_episodes_for_season.
|
||||
# Fall back to synthetic key for MRE nodes that lack an explicit id.
|
||||
season_rrn = node.get("id", "")
|
||||
content_id = season_rrn if season_rrn.startswith("rrn:watch:videohub:season:") else f"season:{discriminator}@{format_rrn}"
|
||||
|
||||
return VodCategory(
|
||||
name=title,
|
||||
content_id=f"season:{discriminator}@{format_rrn}",
|
||||
content_id=content_id,
|
||||
provider="rtlplus",
|
||||
child_count=node.get("numberOfEpisodes"),
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
|
||||
Reference in New Issue
Block a user