Standardize plugin base URLs

This commit is contained in:
2026-02-01 18:25:22 +01:00
parent 4e0b0ffd1a
commit cd2e8e2b15
4 changed files with 86 additions and 36 deletions

View File

@@ -37,7 +37,7 @@ except ImportError: # pragma: no cover - allow running outside Kodi
xbmcgui = None
from plugin_interface import BasisPlugin
from plugin_helpers import dump_response_html, get_setting_bool, log_url, notify_url
from plugin_helpers import dump_response_html, get_setting_bool, get_setting_string, log_url, notify_url
from http_session_pool import get_requests_session
from regex_patterns import SEASON_EPISODE_TAG, SEASON_EPISODE_URL
@@ -49,10 +49,8 @@ else: # pragma: no cover
BeautifulSoupT: TypeAlias = Any
BASE_URL = "https://s.to"
SERIES_BASE_URL = f"{BASE_URL}/serie/stream"
POPULAR_SERIES_URL = f"{BASE_URL}/beliebte-serien"
LATEST_EPISODES_URL = f"{BASE_URL}"
SETTING_BASE_URL = "serienstream_base_url"
DEFAULT_BASE_URL = "https://s.to"
DEFAULT_PREFERRED_HOSTERS = ["voe"]
DEFAULT_TIMEOUT = 20
ADDON_ID = "plugin.video.viewit"
@@ -101,15 +99,34 @@ class SeasonInfo:
episodes: List[EpisodeInfo]
def _get_base_url() -> str:
base = get_setting_string(ADDON_ID, SETTING_BASE_URL, default=DEFAULT_BASE_URL).strip()
if not base:
base = DEFAULT_BASE_URL
return base.rstrip("/")
def _series_base_url() -> str:
return f"{_get_base_url()}/serie/stream"
def _popular_series_url() -> str:
return f"{_get_base_url()}/beliebte-serien"
def _latest_episodes_url() -> str:
return f"{_get_base_url()}"
def _absolute_url(href: str) -> str:
return f"{BASE_URL}{href}" if href.startswith("/") else href
return f"{_get_base_url()}{href}" if href.startswith("/") else href
def _normalize_series_url(identifier: str) -> str:
if identifier.startswith("http://") or identifier.startswith("https://"):
return identifier.rstrip("/")
slug = identifier.strip("/")
return f"{SERIES_BASE_URL}/{slug}"
return f"{_series_base_url()}/{slug}"
def _series_root_url(url: str) -> str:
@@ -227,7 +244,7 @@ def search_series(query: str) -> List[SeriesResult]:
if not normalized_query:
return []
# Direkter Abruf wie in fetch_serien.py.
catalog_url = f"{BASE_URL}/serien?by=genre"
catalog_url = f"{_get_base_url()}/serien?by=genre"
soup = _get_soup_simple(catalog_url)
results: List[SeriesResult] = []
for series in parse_series_catalog(soup).values():
@@ -424,7 +441,7 @@ def fetch_episode_stream_link(
session = get_requests_session("serienstream", headers=HEADERS)
# Preflight optional: Startseite kann 5xx liefern, Zielseite aber funktionieren.
try:
_get_soup(BASE_URL, session=session)
_get_soup(_get_base_url(), session=session)
except Exception:
pass
soup = _get_soup(normalized_url, session=session)
@@ -453,7 +470,7 @@ def fetch_episode_hoster_names(episode_url: str) -> List[str]:
session = get_requests_session("serienstream", headers=HEADERS)
# Preflight optional: Startseite kann 5xx liefern, Zielseite aber funktionieren.
try:
_get_soup(BASE_URL, session=session)
_get_soup(_get_base_url(), session=session)
except Exception:
pass
soup = _get_soup(normalized_url, session=session)
@@ -546,7 +563,7 @@ def resolve_redirect(target_url: str) -> Optional[str]:
session = get_requests_session("serienstream", headers=HEADERS)
# Preflight optional: Startseite kann 5xx liefern, Zielseite aber funktionieren.
try:
_get_soup(BASE_URL, session=session)
_get_soup(_get_base_url(), session=session)
except Exception:
pass
response = session.get(
@@ -571,7 +588,7 @@ def scrape_series_detail(
session = get_requests_session("serienstream", headers=HEADERS)
# Preflight ist optional; manche Umgebungen/Provider leiten die Startseite um.
try:
_get_soup(BASE_URL, session=session)
_get_soup(_get_base_url(), session=session)
except Exception:
pass
soup = _get_soup(series_url, session=session)
@@ -636,7 +653,7 @@ class SerienstreamPlugin(BasisPlugin):
if self._catalog_cache is not None:
return self._catalog_cache
# Stand: 2026-01 liefert `?by=genre` konsistente Gruppen für `genres()`.
catalog_url = f"{BASE_URL}/serien?by=genre"
catalog_url = f"{_get_base_url()}/serien?by=genre"
soup = _get_soup_simple(catalog_url)
self._catalog_cache = parse_series_catalog(soup)
return self._catalog_cache
@@ -678,7 +695,7 @@ class SerienstreamPlugin(BasisPlugin):
"""Laedt und cached die Liste der beliebten Serien aus `/beliebte-serien`."""
if self._popular_cache is not None:
return list(self._popular_cache)
soup = _get_soup_simple(POPULAR_SERIES_URL)
soup = _get_soup_simple(_popular_series_url())
results: List[SeriesResult] = []
seen: set[str] = set()
@@ -894,7 +911,7 @@ class SerienstreamPlugin(BasisPlugin):
if cached is not None:
return list(cached)
url = LATEST_EPISODES_URL
url = _latest_episodes_url()
if page > 1:
url = f"{url}?page={page}"
soup = _get_soup_simple(url)