mirror of
https://github.com/nirvana-7777/script.service.ultimate.git
synced 2026-09-23 09:32:22 +02:00
Prepare RTLPlus for new streaming prov
This commit is contained in:
@@ -34,9 +34,9 @@ class RTLPlusVodManager:
|
||||
|
||||
Navigation hierarchy:
|
||||
root
|
||||
└── folder_<id> (Bedrock folder, e.g. folder_3 = Serien)
|
||||
└── program_<id> (program layout → seasons or direct video)
|
||||
└── season_<block_id> (block layout → episodes)
|
||||
└── folder:<id> (Bedrock folder, e.g. folder:3 = Serien)
|
||||
└── program:<id> (program layout → seasons or direct video)
|
||||
└── season:<block_id> (block layout → episodes)
|
||||
└── clip_id (video layout, playable)
|
||||
|
||||
Manifest and DRM for playable items are always resolved through
|
||||
@@ -78,10 +78,10 @@ class RTLPlusVodManager:
|
||||
|
||||
content_id conventions
|
||||
----------------------
|
||||
"" → root (fetched from home layout)
|
||||
"folder_<id>" → Bedrock folder (e.g. "folder_3")
|
||||
"program_<id>" → program/series (e.g. "program_68137")
|
||||
"season_<id>" → season block (e.g. "season_abc-123")
|
||||
"" → root (fetched from home layout)
|
||||
"folder:<id>" → Bedrock folder (e.g. "folder:3")
|
||||
"p_<id>" → program/series (e.g. "p_68137")
|
||||
"season:<id>" → season block (e.g. "season:abc-123")
|
||||
|
||||
Returns
|
||||
-------
|
||||
@@ -94,22 +94,22 @@ class RTLPlusVodManager:
|
||||
if not content_id:
|
||||
return self._get_root_category()
|
||||
|
||||
if content_id.startswith("folder_"):
|
||||
if content_id.startswith("folder:"):
|
||||
folder_id = content_id[7:] # "3"
|
||||
return self._get_folder_contents(folder_id, cursor, page_size)
|
||||
|
||||
if content_id.startswith("program_"):
|
||||
if content_id.startswith("program:"):
|
||||
program_id = content_id[8:] # "68137" (numeric)
|
||||
slug = kwargs.get("slug")
|
||||
return self._get_program_contents(program_id, cursor, page_size, slug=slug)
|
||||
|
||||
if content_id.startswith("season_"):
|
||||
if content_id.startswith("season:"):
|
||||
season_id = content_id[7:]
|
||||
return self._get_season_episodes(season_id, cursor, page_size)
|
||||
|
||||
# Bare numeric ID → treat as program (backward compatibility)
|
||||
if content_id.isdigit():
|
||||
return self._get_program_contents(content_id, cursor, page_size)
|
||||
return self._get_program_contents(f"p_{content_id}", cursor, page_size)
|
||||
|
||||
logger.warning(f"Unrecognised VOD content_id format: {content_id!r}")
|
||||
return {"entries": [], "next_cursor": None, "total": 0}
|
||||
@@ -200,7 +200,7 @@ class RTLPlusVodManager:
|
||||
cat = self._extract_vod_category_from_block_item(item)
|
||||
if cat:
|
||||
# Separate folders from programs
|
||||
if cat.content_id.startswith("folder_"):
|
||||
if cat.content_id.startswith("folder:"):
|
||||
folder_categories.append(cat)
|
||||
else:
|
||||
program_categories.append(cat)
|
||||
@@ -439,27 +439,35 @@ class RTLPlusVodManager:
|
||||
|
||||
if layout_type == "video":
|
||||
logger.debug(f" Found video in action.target.value_layout")
|
||||
vod_item = self._extract_vod_item_from_block_item(item)
|
||||
if vod_item:
|
||||
# Make sure the content_id is the clip_id, not the program_id
|
||||
clip_id = value_layout.get("id") # This should be "clip_1417600"
|
||||
logger.debug(f" Setting VodItem content_id to: {clip_id}")
|
||||
vod_item.content_id = clip_id # Ensure it's set correctly
|
||||
clip_id = value_layout.get("id") # "clip_1417600"
|
||||
|
||||
# Store program context for potential future use
|
||||
parent = value_layout.get("parent", {})
|
||||
import json
|
||||
vod_item.manifest_script = json.dumps({
|
||||
"program_id": parent.get("id"),
|
||||
"program_slug": parent.get("seo"),
|
||||
"clip_id": clip_id
|
||||
})
|
||||
# Resolve title: itemContent.title in Jumbotron blocks is
|
||||
# often the genre label ("Film"), not the real title.
|
||||
# analytics.tealium.program_title is authoritative.
|
||||
analytics = action.get("analytics", {})
|
||||
tealium = analytics.get("tealium", {}) if isinstance(analytics, dict) else {}
|
||||
program_title = tealium.get("program_title")
|
||||
clip_title = tealium.get("clip_title")
|
||||
item_content_title = item_content.get("title", "")
|
||||
title = (
|
||||
program_title
|
||||
or clip_title
|
||||
or (item_content_title if item_content_title else clip_id)
|
||||
)
|
||||
|
||||
logger.debug(
|
||||
f" Successfully extracted VodItem: {vod_item.name} (ID: {vod_item.content_id})")
|
||||
return vod_item
|
||||
else:
|
||||
logger.debug(f" Failed to extract VodItem from item")
|
||||
vod_item = VodItem.create_movie(
|
||||
name=title,
|
||||
content_id=clip_id,
|
||||
provider=self._provider.provider_name,
|
||||
)
|
||||
vod_item.description = item_content.get("description")
|
||||
vod_item.logo_url = self._extract_thumbnail(item_content)
|
||||
# manifest_script must not be set on VodItems —
|
||||
# manifest resolution is handled by get_manifest()
|
||||
|
||||
logger.debug(
|
||||
f" Successfully extracted VodItem: {vod_item.name} (ID: {vod_item.content_id})")
|
||||
return vod_item
|
||||
else:
|
||||
logger.debug(f" action is not a dict, it's {type(action)}")
|
||||
|
||||
@@ -468,19 +476,14 @@ class RTLPlusVodManager:
|
||||
logger.debug(f" Found video in itemContent.type")
|
||||
clip_id = item_content.get("id")
|
||||
if clip_id:
|
||||
vod_item = VodItem.create_episode(
|
||||
vod_item = VodItem.create_movie(
|
||||
name=item_content.get("title", clip_id),
|
||||
content_id=clip_id,
|
||||
provider=self._provider.provider_name,
|
||||
)
|
||||
vod_item.description = item_content.get("description")
|
||||
vod_item.logo_url = self._extract_thumbnail(item_content)
|
||||
|
||||
# Store program context
|
||||
import json
|
||||
vod_item.manifest_script = json.dumps({
|
||||
"clip_id": clip_id
|
||||
})
|
||||
# manifest_script must not be set on VodItems
|
||||
|
||||
logger.debug(
|
||||
f" Created VodItem from direct video: {vod_item.name} (ID: {vod_item.content_id})")
|
||||
@@ -529,7 +532,7 @@ class RTLPlusVodManager:
|
||||
if block_id:
|
||||
seasons.append(VodCategory(
|
||||
name=season_title,
|
||||
content_id=f"season_{block_id}",
|
||||
content_id=f"season:{block_id}",
|
||||
provider=self._provider.provider_name,
|
||||
description=None,
|
||||
child_count=(
|
||||
@@ -550,7 +553,7 @@ class RTLPlusVodManager:
|
||||
.get("title", {})
|
||||
.get("short", "Alle Staffeln")
|
||||
),
|
||||
content_id=f"season_{block_id}",
|
||||
content_id=f"season:{block_id}",
|
||||
provider=self._provider.provider_name,
|
||||
child_count=(
|
||||
block.get("content", {})
|
||||
@@ -755,15 +758,10 @@ class RTLPlusVodManager:
|
||||
vod_item.duration_seconds = self._extract_duration(item_content)
|
||||
vod_item.progress = item_content.get("progress", 0)
|
||||
|
||||
# Store program context in manifest_script for later use (e.g., manifest fetching)
|
||||
# manifest_script must not be set on VodItems — manifest resolution
|
||||
# is handled by provider.get_manifest(content_id) upstream.
|
||||
if program_id or program_slug:
|
||||
import json
|
||||
vod_item.manifest_script = json.dumps({
|
||||
"program_id": program_id,
|
||||
"program_slug": program_slug,
|
||||
"clip_id": clip_id
|
||||
})
|
||||
logger.debug(f" Stored program context: program_id={program_id}, program_slug={program_slug}")
|
||||
logger.debug(f" Program context: program_id={program_id}, program_slug={program_slug} (not stored in manifest_script)")
|
||||
|
||||
logger.debug(f" Created VodItem: '{vod_item.name}' with content_id='{vod_item.content_id}'")
|
||||
return vod_item
|
||||
@@ -796,9 +794,9 @@ class RTLPlusVodManager:
|
||||
|
||||
# Store with type prefix for clarity
|
||||
if layout_type == "folder":
|
||||
content_id = f"folder_{content_id}" # folder_3
|
||||
content_id = f"folder:{content_id}" # folder:3
|
||||
elif layout_type == "program":
|
||||
content_id = f"program_{content_id}" # program_68137
|
||||
content_id = f"program:{content_id}" # program:68137
|
||||
|
||||
# Capture the SEO slug from the API (e.g. "american-pie")
|
||||
seo_slug = value_layout.get("seo") or ""
|
||||
@@ -827,7 +825,7 @@ class RTLPlusVodManager:
|
||||
|
||||
return VodCategory(
|
||||
name=name,
|
||||
content_id=content_id, # "folder_3" or "program_68137"
|
||||
content_id=content_id, # "folder:3" or "p_68137"
|
||||
provider=self._provider.provider_name,
|
||||
logo_url=self._extract_thumbnail(item_content),
|
||||
description=item_content.get("description") or item_content.get("highlight"),
|
||||
@@ -944,8 +942,8 @@ class RTLPlusVodManager:
|
||||
self._provider.invalidate_layout_cache()
|
||||
return
|
||||
|
||||
if content_id.startswith("program_"):
|
||||
program_id = content_id[len("program_"):]
|
||||
if content_id.startswith("program:"):
|
||||
program_id = content_id[len("program:"):]
|
||||
# Program layouts are cached under "program:<id>:<page>:<nb>"
|
||||
cache_key = (
|
||||
f"program:{program_id}"
|
||||
@@ -954,8 +952,8 @@ class RTLPlusVodManager:
|
||||
)
|
||||
self._provider.invalidate_layout_cache(cache_key)
|
||||
|
||||
elif content_id.startswith("season_"):
|
||||
season_id = content_id[len("season_"):].split("?")[0]
|
||||
elif content_id.startswith("season:"):
|
||||
season_id = content_id[len("season:"):].split("?")[0]
|
||||
cache_key = (
|
||||
f"block:{season_id}"
|
||||
f":{RTLPlusDefaults.DEFAULT_BLOCK_PAGE}"
|
||||
@@ -963,8 +961,8 @@ class RTLPlusVodManager:
|
||||
)
|
||||
self._provider.invalidate_layout_cache(cache_key)
|
||||
|
||||
elif content_id.startswith("folder_"):
|
||||
folder_id = content_id[len("folder_"):]
|
||||
elif content_id.startswith("folder:"):
|
||||
folder_id = content_id[len("folder:"):]
|
||||
cache_key = (
|
||||
f"folder:{folder_id}"
|
||||
f":{RTLPlusDefaults.DEFAULT_BLOCK_PAGE}"
|
||||
|
||||
Reference in New Issue
Block a user