"""Optionales ResolveURL-Backend für das Kodi-Addon. Wenn `script.module.resolveurl` installiert ist, kann damit eine Hoster-URL zu einer abspielbaren Media-URL (inkl. evtl. Header-Suffix) aufgelöst werden. """ from __future__ import annotations from typing import Optional import sys _LAST_RESOLVE_ERROR = "" def _append_kodi_dependency_paths() -> None: """Ensure optional Kodi module dependencies are importable.""" try: import xbmcaddon # type: ignore import xbmcvfs # type: ignore except Exception: return for addon_id in ("script.module.resolveurl", "script.module.kodi-six", "script.module.six"): try: addon = xbmcaddon.Addon(addon_id) addon_path = addon.getAddonInfo("path") or "" except Exception: addon_path = "" if not addon_path: continue try: addon_path = xbmcvfs.translatePath(addon_path) except Exception: pass lib_path = f"{addon_path}/lib" for candidate in (lib_path, addon_path): if candidate and candidate not in sys.path: sys.path.append(candidate) def get_last_error() -> str: return str(_LAST_RESOLVE_ERROR or "") def resolve(url: str) -> Optional[str]: global _LAST_RESOLVE_ERROR _LAST_RESOLVE_ERROR = "" if not url: return None resolveurl = None try: import resolveurl as _resolveurl # type: ignore resolveurl = _resolveurl except Exception: # Ohne harte addon.xml-Abhaengigkeit liegen optionale libs ggf. nicht im Python-Pfad. _append_kodi_dependency_paths() try: import resolveurl as _resolveurl # type: ignore resolveurl = _resolveurl except Exception: resolveurl = None if resolveurl is None: _LAST_RESOLVE_ERROR = "resolveurl missing" return None try: hosted = getattr(resolveurl, "HostedMediaFile", None) if callable(hosted): hmf = hosted(url) valid = getattr(hmf, "valid_url", None) if callable(valid) and not valid(): _LAST_RESOLVE_ERROR = "invalid url" return None resolver = getattr(hmf, "resolve", None) if callable(resolver): result = resolver() if result: return str(result) _LAST_RESOLVE_ERROR = "unresolved" return None except Exception as exc: _LAST_RESOLVE_ERROR = str(exc or "") pass try: resolve_fn = getattr(resolveurl, "resolve", None) if callable(resolve_fn): result = resolve_fn(url) if result: return str(result) _LAST_RESOLVE_ERROR = "unresolved" return None except Exception as exc: _LAST_RESOLVE_ERROR = str(exc or "") return None return None