dev: bump to 0.1.91.5-dev TMDb Helper Fix, Autoplay Fix, Gesperrte Hoster

This commit is contained in:
2026-04-11 22:01:41 +02:00
parent 03a4997132
commit 7df6bc61c4
8 changed files with 146 additions and 20 deletions

View File

@@ -119,6 +119,7 @@ from metadata_utils import (
from tmdb import TmdbCastMember, TmdbExternalIds, fetch_external_ids, fetch_tv_episode_credits, lookup_movie, lookup_tv_season, lookup_tv_season_summary, lookup_tv_show
from core.metadata import _resolve_tmdb_api_key
from core.router import Router
from hosters import ALL_HOSTERS, normalize_hoster_name
_router = Router()
@@ -618,18 +619,69 @@ def _get_setting_int(setting_id: str, *, default: int = 0) -> int:
return default
_PREFERRED_HOSTERS_LIST = [
"voe", "streamtape", "doodstream", "vidoza", "mixdrop", "supervideo", "dropload",
]
_PREFERRED_HOSTERS_LIST = [h["id"] for h in ALL_HOSTERS]
def _get_preferred_hoster() -> str:
"""Liest preferred_hoster (enum-Index) und gibt den Hosternamen zurueck."""
raw = _get_setting_string("preferred_hoster").strip()
raw_int = _get_setting_int("preferred_hoster", default=-1)
_log(f"preferred_hoster raw_string='{raw}' raw_int={raw_int}", xbmc.LOGINFO)
# getSettingString liefert bei enum den Display-Wert (z.B. "voe"), nicht den Index.
# Prüfe ob raw bereits ein bekannter Hoster-Name ist.
if raw.casefold() in [h.casefold() for h in _PREFERRED_HOSTERS_LIST]:
return raw
# Fallback: Index-basiert über getSettingInt
if raw_int >= 0:
try:
return _PREFERRED_HOSTERS_LIST[raw_int]
except IndexError:
pass
# Fallback: Index aus String
try:
return _PREFERRED_HOSTERS_LIST[int(raw)]
except (ValueError, IndexError):
return raw # Fallback: Textwert direkt verwenden
return raw
def _get_blocked_hosters() -> set[str]:
"""Gibt die Menge der gesperrten Hoster-IDs zurück."""
raw = _get_setting_string("blocked_hosters").strip()
if not raw:
return set()
return {h.strip().casefold() for h in raw.split(",") if h.strip()}
def _filter_hosters(hosters: list[str], blocked: set[str]) -> list[str]:
"""Entfernt gesperrte Hoster aus der Liste. Unbekannte Hoster bleiben erhalten."""
if not blocked:
return hosters
result = []
for h in hosters:
hid = normalize_hoster_name(h)
if hid and hid.casefold() in blocked:
_log(f"Hoster '{h}' ist gesperrt und wird entfernt.", xbmc.LOGDEBUG)
continue
result.append(h)
return result
def _configure_blocked_hosters_dialog() -> None:
"""Multi-Select-Dialog zum Sperren/Entsperren von Hostern."""
blocked = _get_blocked_hosters()
labels = [h["display"] for h in ALL_HOSTERS]
preselected = [i for i, h in enumerate(ALL_HOSTERS) if h["id"].casefold() in blocked]
result = xbmcgui.Dialog().multiselect("Gesperrte Hoster auswaehlen", labels, preselect=preselected)
if result is None:
return # Abgebrochen
blocked_ids = sorted(ALL_HOSTERS[i]["id"] for i in result)
_set_setting_string("blocked_hosters", ",".join(blocked_ids))
count = len(blocked_ids)
msg = f"{count} Hoster gesperrt" if count else "Keine Hoster gesperrt"
xbmcgui.Dialog().notification("Hoster-Sperrung", msg, xbmcgui.NOTIFICATION_INFO, 3000)
_log(f"Gesperrte Hoster gespeichert: {blocked_ids}", xbmc.LOGINFO)
def _metadata_policy(
@@ -1258,7 +1310,28 @@ RESOLVEURL_ADDON_ID = "script.module.resolveurl"
RESOLVEURL_AUTO_INSTALL_INTERVAL_SEC = 6 * 60 * 60
YTDLP_ADDON_ID = "script.module.yt-dlp"
TMDB_HELPER_ADDON_ID = "plugin.video.themoviedb.helper"
TMDB_HELPER_PLAYERS_DIR = Path.home() / ".kodi" / "addons" / TMDB_HELPER_ADDON_ID / "resources" / "players"
def _kodi_userdata_dir() -> Path:
"""Ermittelt das Kodi-Userdata-Verzeichnis plattformübergreifend."""
import platform
system = platform.system()
if system == "Windows":
appdata = os.environ.get("APPDATA") or os.environ.get("LOCALAPPDATA") or ""
if appdata:
return Path(appdata) / "Kodi" / "userdata"
if system == "Darwin":
return Path.home() / "Library" / "Application Support" / "Kodi" / "userdata"
# Linux, LibreELEC, OSMC, Flatpak-Fallback → ~/.kodi/userdata
flatpak = Path.home() / ".var" / "app" / "tv.kodi.Kodi" / "data" / "userdata"
if flatpak.exists():
return flatpak
return Path.home() / ".kodi" / "userdata"
def _tmdb_helper_players_dir() -> Path:
"""Gibt das players/-Verzeichnis im TMDb-Helper-Addon-Data-Ordner zurück."""
return _kodi_userdata_dir() / "addon_data" / TMDB_HELPER_ADDON_ID / "players"
def _selected_update_channel() -> int:
@@ -1768,10 +1841,11 @@ def _install_tmdb_helper_players() -> None:
if not source_files:
xbmcgui.Dialog().notification("TMDb Helper", "Keine Player-Dateien gefunden.", xbmcgui.NOTIFICATION_WARNING, 4000)
return
TMDB_HELPER_PLAYERS_DIR.mkdir(parents=True, exist_ok=True)
dest_dir = _tmdb_helper_players_dir()
dest_dir.mkdir(parents=True, exist_ok=True)
import shutil
for src in source_files:
shutil.copy2(src, TMDB_HELPER_PLAYERS_DIR / src.name)
shutil.copy2(src, dest_dir / src.name)
_log(f"TMDb Helper Player installiert: {[f.name for f in source_files]}")
xbmcgui.Dialog().notification("TMDb Helper", f"{len(source_files)} Player installiert.", xbmcgui.NOTIFICATION_INFO, 3000)
except Exception as exc:
@@ -4543,6 +4617,9 @@ def _play_episode(
forced_hoster = (forced_hoster or "").strip()
autoplay = _get_setting_bool("autoplay_enabled", default=False)
preferred = _get_preferred_hoster()
blocked = _get_blocked_hosters()
available_hosters = _filter_hosters(available_hosters, blocked)
_log(f"Autoplay={autoplay}, preferred='{preferred}', blocked={blocked}, hosters={available_hosters}", xbmc.LOGINFO)
if available_hosters:
if forced_hoster:
for hoster in available_hosters:
@@ -4671,6 +4748,9 @@ def _play_episode_url(
selected_hoster: str | None = None
autoplay = _get_setting_bool("autoplay_enabled", default=False)
preferred = _get_preferred_hoster()
blocked = _get_blocked_hosters()
available_hosters = _filter_hosters(available_hosters, blocked)
_log(f"Autoplay={autoplay}, preferred='{preferred}', blocked={blocked}, hosters={available_hosters}", xbmc.LOGINFO)
if available_hosters:
if autoplay and preferred:
pref_lower = preferred.casefold()
@@ -5518,6 +5598,11 @@ def _route_install_tmdb_helper_players(params: dict[str, str]) -> None:
_install_tmdb_helper_players()
@_router.route("configure_blocked_hosters")
def _route_configure_blocked_hosters(params: dict[str, str]) -> None:
_configure_blocked_hosters_dialog()
@_router.route("choose_source")
def _route_choose_source(params: dict[str, str]) -> None:
_show_choose_source(params.get("title", ""), params.get("plugins", ""))