From 09c6a3204372134d007a70f9bbc77ffeafa5cf32 Mon Sep 17 00:00:00 2001 From: "itdrui.de" Date: Sun, 1 Feb 2026 21:37:50 +0100 Subject: [PATCH] Pass series URLs through navigation for faster serienstream --- addon/default.py | 56 +++++++++++++++++++++------- addon/plugins/serienstream_plugin.py | 31 +++++++++++++++ 2 files changed, 73 insertions(+), 14 deletions(-) diff --git a/addon/default.py b/addon/default.py index 67d010d..859999d 100644 --- a/addon/default.py +++ b/addon/default.py @@ -944,11 +944,12 @@ def _show_plugin_search_results(plugin_name: str, query: str) -> None: display_label = _label_with_duration(title, info_labels) display_label = _label_with_playstate(display_label, playstate) direct_play = bool(plugin_name.casefold() == "einschalten" and _get_setting_bool("einschalten_enable_playback", default=False)) + extra_params = _series_url_params(plugin, title) _add_directory_item( handle, display_label, "play_movie" if direct_play else "seasons", - {"plugin": plugin_name, "title": title}, + {"plugin": plugin_name, "title": title, **extra_params}, is_folder=not direct_play, info_labels=merged_info, art=art, @@ -1025,6 +1026,17 @@ def _run_async(coro): return asyncio.run(coro) +def _series_url_params(plugin: BasisPlugin, title: str) -> dict[str, str]: + getter = getattr(plugin, "series_url_for_title", None) + if not callable(getter): + return {} + try: + series_url = str(getter(title) or "").strip() + except Exception: + return {} + return {"series_url": series_url} if series_url else {} + + def _show_search() -> None: _log("Suche gestartet.") dialog = xbmcgui.Dialog() @@ -1071,11 +1083,12 @@ def _show_search_results(query: str) -> None: direct_play = bool( plugin_name.casefold() == "einschalten" and _get_setting_bool("einschalten_enable_playback", default=False) ) + extra_params = _series_url_params(plugin, title) _add_directory_item( handle, label, "play_movie" if direct_play else "seasons", - {"plugin": plugin_name, "title": title}, + {"plugin": plugin_name, "title": title, **extra_params}, is_folder=not direct_play, info_labels=merged_info, art=art, @@ -1084,7 +1097,7 @@ def _show_search_results(query: str) -> None: xbmcplugin.endOfDirectory(handle) -def _show_seasons(plugin_name: str, title: str) -> None: +def _show_seasons(plugin_name: str, title: str, series_url: str = "") -> None: handle = _get_handle() _log(f"Staffeln laden: {plugin_name} / {title}") plugin = _discover_plugins().get(plugin_name) @@ -1092,6 +1105,13 @@ def _show_seasons(plugin_name: str, title: str) -> None: xbmcgui.Dialog().notification("Staffeln", "Plugin nicht gefunden.", xbmcgui.NOTIFICATION_INFO, 3000) xbmcplugin.endOfDirectory(handle) return + if series_url: + remember_series_url = getattr(plugin, "remember_series_url", None) + if callable(remember_series_url): + try: + remember_series_url(title, series_url) + except Exception: + pass # Einschalten liefert Filme. Für Playback soll nach dem Öffnen des Titels direkt ein # einzelnes abspielbares Item angezeigt werden: -> ( abspielbar). @@ -1227,7 +1247,7 @@ def _show_seasons(plugin_name: str, title: str) -> None: handle, _label_with_playstate(season, season_state), "episodes", - {"plugin": plugin_name, "title": title, "season": season}, + {"plugin": plugin_name, "title": title, "season": season, "series_url": series_url}, is_folder=True, info_labels=merged_labels or None, art=merged_art, @@ -1236,7 +1256,7 @@ def _show_seasons(plugin_name: str, title: str) -> None: xbmcplugin.endOfDirectory(handle) -def _show_episodes(plugin_name: str, title: str, season: str) -> None: +def _show_episodes(plugin_name: str, title: str, season: str, series_url: str = "") -> None: handle = _get_handle() _log(f"Episoden laden: {plugin_name} / {title} / {season}") plugin = _discover_plugins().get(plugin_name) @@ -1244,6 +1264,13 @@ def _show_episodes(plugin_name: str, title: str, season: str) -> None: xbmcgui.Dialog().notification("Episoden", "Plugin nicht gefunden.", xbmcgui.NOTIFICATION_INFO, 3000) xbmcplugin.endOfDirectory(handle) return + if series_url: + remember_series_url = getattr(plugin, "remember_series_url", None) + if callable(remember_series_url): + try: + remember_series_url(title, series_url) + except Exception: + pass season_number = _extract_first_int(season) if season_number is not None: xbmcplugin.setPluginCategory(handle, f"{title} - Staffel {season_number}") @@ -1439,7 +1466,7 @@ def _show_genre_titles_page(plugin_name: str, genre: str, page: int = 1) -> None handle, display_label, "play_movie" if direct_play else "seasons", - {"plugin": plugin_name, "title": title}, + {"plugin": plugin_name, "title": title, **_series_url_params(plugin, title)}, is_folder=not direct_play, info_labels=info_labels, art=art, @@ -1456,7 +1483,7 @@ def _show_genre_titles_page(plugin_name: str, genre: str, page: int = 1) -> None handle, _label_with_playstate(title, playstate), "play_movie" if direct_play else "seasons", - {"plugin": plugin_name, "title": title}, + {"plugin": plugin_name, "title": title, **_series_url_params(plugin, title)}, is_folder=not direct_play, info_labels=_apply_playstate_to_info({"title": title}, playstate), ) @@ -1672,7 +1699,7 @@ def _show_popular(plugin_name: str | None = None, page: int = 1) -> None: handle, display_label, "seasons", - {"plugin": plugin_name, "title": title}, + {"plugin": plugin_name, "title": title, **_series_url_params(plugin, title)}, is_folder=True, info_labels=info_labels, art=art, @@ -1685,7 +1712,7 @@ def _show_popular(plugin_name: str | None = None, page: int = 1) -> None: handle, _label_with_playstate(title, playstate), "seasons", - {"plugin": plugin_name, "title": title}, + {"plugin": plugin_name, "title": title, **_series_url_params(plugin, title)}, is_folder=True, info_labels=_apply_playstate_to_info({"title": title}, playstate), ) @@ -1817,7 +1844,7 @@ def _show_new_titles(plugin_name: str, page: int = 1) -> None: handle, display_label, "play_movie" if direct_play else "seasons", - {"plugin": plugin_name, "title": title}, + {"plugin": plugin_name, "title": title, **_series_url_params(plugin, title)}, is_folder=not direct_play, info_labels=info_labels, art=art, @@ -1834,7 +1861,7 @@ def _show_new_titles(plugin_name: str, page: int = 1) -> None: handle, _label_with_playstate(title, playstate), "play_movie" if direct_play else "seasons", - {"plugin": plugin_name, "title": title}, + {"plugin": plugin_name, "title": title, **_series_url_params(plugin, title)}, is_folder=not direct_play, info_labels=_apply_playstate_to_info({"title": title}, playstate), ) @@ -1986,7 +2013,7 @@ def _show_genre_series_group(plugin_name: str, genre: str, group_code: str, page handle, display_label, "seasons", - {"plugin": plugin_name, "title": title}, + {"plugin": plugin_name, "title": title, **_series_url_params(plugin, title)}, is_folder=True, info_labels=info_labels, art=art, @@ -1999,7 +2026,7 @@ def _show_genre_series_group(plugin_name: str, genre: str, group_code: str, page handle, _label_with_playstate(title, playstate), "seasons", - {"plugin": plugin_name, "title": title}, + {"plugin": plugin_name, "title": title, **_series_url_params(plugin, title)}, is_folder=True, info_labels=_apply_playstate_to_info({"title": title}, playstate), ) @@ -2373,12 +2400,13 @@ def run() -> None: elif action == "settings": _open_settings() elif action == "seasons": - _show_seasons(params.get("plugin", ""), params.get("title", "")) + _show_seasons(params.get("plugin", ""), params.get("title", ""), params.get("series_url", "")) elif action == "episodes": _show_episodes( params.get("plugin", ""), params.get("title", ""), params.get("season", ""), + params.get("series_url", ""), ) elif action == "play_episode": _play_episode( diff --git a/addon/plugins/serienstream_plugin.py b/addon/plugins/serienstream_plugin.py index f96cc67..e83aaea 100644 --- a/addon/plugins/serienstream_plugin.py +++ b/addon/plugins/serienstream_plugin.py @@ -835,6 +835,17 @@ class SerienstreamPlugin(BasisPlugin): if cached is not None: return list(cached) series = self._series_results.get(title) + if not series: + catalog = self._ensure_catalog() + lookup_key = title.casefold().strip() + for entries in catalog.values(): + for entry in entries: + if entry.title.casefold().strip() == lookup_key: + series = entry + self._series_results[entry.title] = entry + break + if series: + break if not series: return [] try: @@ -844,6 +855,26 @@ class SerienstreamPlugin(BasisPlugin): self._season_links_cache[title] = list(seasons) return list(seasons) + def remember_series_url(self, title: str, series_url: str) -> None: + title = (title or "").strip() + series_url = (series_url or "").strip() + if not title or not series_url: + return + self._series_results[title] = SeriesResult(title=title, description="", url=series_url) + + def series_url_for_title(self, title: str) -> str: + title = (title or "").strip() + if not title: + return "" + direct = self._series_results.get(title) + if direct and direct.url: + return direct.url + lookup_key = title.casefold().strip() + for entry in self._series_results.values(): + if entry.title.casefold().strip() == lookup_key and entry.url: + return entry.url + return "" + def _ensure_season_episodes(self, title: str, season_number: int) -> Optional[SeasonInfo]: seasons = self._season_cache.get(title) or [] for season in seasons: