nightly: per-plugin metadata source option

This commit is contained in:
2026-02-08 22:33:07 +01:00
parent ed1f59d3f2
commit 537f0e23e1
3 changed files with 381 additions and 265 deletions

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<addon id="plugin.video.viewit" name="ViewIt" version="0.1.52" provider-name="ViewIt">
<addon id="plugin.video.viewit" name="ViewIt" version="0.1.53" provider-name="ViewIt">
<requires>
<import addon="xbmc.python" version="3.0.0" />
<import addon="script.module.requests" />

View File

@@ -402,6 +402,81 @@ def _get_setting_bool(setting_id: str, *, default: bool = False) -> bool:
return default
def _get_setting_int(setting_id: str, *, default: int = 0) -> int:
if xbmcaddon is None:
return default
addon = _get_addon()
if addon is None:
return default
getter = getattr(addon, "getSettingInt", None)
if callable(getter):
raw_getter = getattr(addon, "getSetting", None)
if callable(raw_getter):
try:
raw = str(raw_getter(setting_id) or "").strip()
except TypeError:
raw = ""
if raw == "":
return default
try:
return int(getter(setting_id))
except TypeError:
return default
getter = getattr(addon, "getSetting", None)
if callable(getter):
try:
raw = str(getter(setting_id) or "").strip()
except TypeError:
return default
if raw == "":
return default
try:
return int(raw)
except ValueError:
return default
return default
METADATA_MODE_AUTO = 0
METADATA_MODE_SOURCE = 1
METADATA_MODE_TMDB = 2
METADATA_MODE_MIX = 3
def _metadata_setting_id(plugin_name: str) -> str:
safe = re.sub(r"[^a-z0-9]+", "_", (plugin_name or "").strip().casefold()).strip("_")
return f"{safe}_metadata_source" if safe else "metadata_source"
def _plugin_supports_metadata(plugin: BasisPlugin) -> bool:
try:
return plugin.__class__.metadata_for is not BasisPlugin.metadata_for
except Exception:
return False
def _metadata_policy(
plugin_name: str,
plugin: BasisPlugin,
*,
allow_tmdb: bool,
) -> tuple[bool, bool, bool]:
mode = _get_setting_int(_metadata_setting_id(plugin_name), default=METADATA_MODE_AUTO)
supports_source = _plugin_supports_metadata(plugin)
if mode == METADATA_MODE_SOURCE:
return supports_source, False, True
if mode == METADATA_MODE_TMDB:
return False, allow_tmdb, False
if mode == METADATA_MODE_MIX:
return supports_source, allow_tmdb, True
prefer_source = bool(getattr(plugin, "prefer_source_metadata", False))
return supports_source, allow_tmdb, prefer_source
def _tmdb_list_enabled() -> bool:
return _tmdb_enabled() and _get_setting_bool("tmdb_genre_metadata", default=False)
def _set_setting_string(setting_id: str, value: str) -> None:
if xbmcaddon is None:
return
@@ -1124,14 +1199,15 @@ def _show_plugin_search_results(plugin_name: str, query: str) -> None:
results = [str(t).strip() for t in (results or []) if t and str(t).strip()]
results.sort(key=lambda value: value.casefold())
plugin_meta = _collect_plugin_metadata(plugin, results)
use_source, show_tmdb, prefer_source = _metadata_policy(
plugin_name, plugin, allow_tmdb=_tmdb_enabled()
)
plugin_meta = _collect_plugin_metadata(plugin, results) if use_source else {}
tmdb_prefetched: dict[str, tuple[dict[str, str], dict[str, str], list[TmdbCastMember]]] = {}
show_tmdb = _tmdb_enabled()
show_plot = _get_setting_bool("tmdb_show_plot", default=True)
show_art = _get_setting_bool("tmdb_show_art", default=True)
prefer_source = bool(getattr(plugin, "prefer_source_metadata", False))
tmdb_titles = list(results)
if show_tmdb and prefer_source:
tmdb_titles = list(results) if show_tmdb else []
if show_tmdb and prefer_source and use_source:
tmdb_titles = []
for title in results:
meta = plugin_meta.get(title)
@@ -1334,14 +1410,15 @@ def _show_search_results(query: str) -> None:
continue
results = [str(t).strip() for t in (results or []) if t and str(t).strip()]
_log(f"Treffer ({plugin_name}): {len(results)}", xbmc.LOGDEBUG)
plugin_meta = _collect_plugin_metadata(plugin, results)
use_source, show_tmdb, prefer_source = _metadata_policy(
plugin_name, plugin, allow_tmdb=_tmdb_enabled()
)
plugin_meta = _collect_plugin_metadata(plugin, results) if use_source else {}
tmdb_prefetched: dict[str, tuple[dict[str, str], dict[str, str], list[TmdbCastMember]]] = {}
show_tmdb = _tmdb_enabled()
show_plot = _get_setting_bool("tmdb_show_plot", default=True)
show_art = _get_setting_bool("tmdb_show_art", default=True)
prefer_source = bool(getattr(plugin, "prefer_source_metadata", False))
tmdb_titles = list(results)
if show_tmdb and prefer_source:
tmdb_titles = list(results) if show_tmdb else []
if show_tmdb and prefer_source and use_source:
tmdb_titles = []
for title in results:
meta = plugin_meta.get(title)
@@ -1485,11 +1562,14 @@ def _show_seasons(plugin_name: str, title: str, series_url: str = "") -> None:
except Exception:
pass
use_source, show_tmdb, _prefer_source = _metadata_policy(
plugin_name, plugin, allow_tmdb=_tmdb_enabled()
)
title_info_labels: dict[str, str] | None = None
title_art: dict[str, str] | None = None
title_cast: list[TmdbCastMember] | None = None
meta_getter = getattr(plugin, "metadata_for", None)
if callable(meta_getter):
if use_source and callable(meta_getter):
try:
with _busy_dialog():
meta_labels, meta_art, meta_cast = meta_getter(title)
@@ -1516,8 +1596,9 @@ def _show_seasons(plugin_name: str, title: str, series_url: str = "") -> None:
xbmcplugin.setPluginCategory(handle, f"{title} ({count} {suffix})")
_set_content(handle, "seasons")
# Staffel-Metadaten (Plot/Poster) optional via TMDB.
if show_tmdb:
_tmdb_labels_and_art(title)
api_key = _get_setting_string("tmdb_api_key").strip()
api_key = _get_setting_string("tmdb_api_key").strip() if show_tmdb else ""
language = _get_setting_string("tmdb_language").strip() or "de-DE"
show_plot = _get_setting_bool("tmdb_show_plot", default=True)
show_art = _get_setting_bool("tmdb_show_art", default=True)
@@ -1606,13 +1687,40 @@ def _show_episodes(plugin_name: str, title: str, season: str, series_url: str =
episodes = list(plugin.episodes_for(title, season))
if episodes:
use_source, show_tmdb, _prefer_source = _metadata_policy(
plugin_name, plugin, allow_tmdb=_tmdb_enabled()
)
show_info: dict[str, str] = {}
show_art: dict[str, str] = {}
show_cast: list[TmdbCastMember] | None = None
if show_tmdb:
show_info, show_art, show_cast = _tmdb_labels_and_art(title)
elif use_source:
meta_getter = getattr(plugin, "metadata_for", None)
if callable(meta_getter):
try:
with _busy_dialog():
meta_labels, meta_art, meta_cast = meta_getter(title)
if isinstance(meta_labels, dict):
show_info = {str(k): str(v) for k, v in meta_labels.items() if v}
if isinstance(meta_art, dict):
show_art = {str(k): str(v) for k, v in meta_art.items() if v}
if isinstance(meta_cast, list):
show_cast = meta_cast # noqa: PGH003
except Exception:
pass
show_fanart = (show_art or {}).get("fanart") if isinstance(show_art, dict) else ""
show_poster = (show_art or {}).get("poster") if isinstance(show_art, dict) else ""
with _busy_dialog():
for episode in episodes:
info_labels, art = _tmdb_episode_labels_and_art(title=title, season_label=season, episode_label=episode)
if show_tmdb:
info_labels, art = _tmdb_episode_labels_and_art(
title=title, season_label=season, episode_label=episode
)
episode_cast = _tmdb_episode_cast(title=title, season_label=season, episode_label=episode)
else:
info_labels, art, episode_cast = {}, {}, []
merged_info = dict(show_info or {})
merged_info.update(dict(info_labels or {}))
merged_art: dict[str, str] = {}
@@ -1803,16 +1911,16 @@ def _show_category_titles_page(plugin_name: str, category: str, page: int = 1) -
titles = [str(t).strip() for t in titles if t and str(t).strip()]
titles.sort(key=lambda value: value.casefold())
show_tmdb = _get_setting_bool("tmdb_genre_metadata", default=False)
if titles:
plugin_meta = _collect_plugin_metadata(plugin, titles)
show_tmdb = _tmdb_enabled()
use_source, show_tmdb, prefer_source = _metadata_policy(
plugin_name, plugin, allow_tmdb=_tmdb_list_enabled()
)
plugin_meta = _collect_plugin_metadata(plugin, titles) if use_source else {}
show_plot = _get_setting_bool("tmdb_show_plot", default=True)
show_art = _get_setting_bool("tmdb_show_art", default=True)
prefer_source = bool(getattr(plugin, "prefer_source_metadata", False))
tmdb_prefetched: dict[str, tuple[dict[str, str], dict[str, str], list[TmdbCastMember]]] = {}
tmdb_titles = list(titles)
if show_tmdb and prefer_source:
tmdb_titles = list(titles) if show_tmdb else []
if show_tmdb and prefer_source and use_source:
tmdb_titles = []
for title in titles:
meta = plugin_meta.get(title)
@@ -1823,9 +1931,8 @@ def _show_category_titles_page(plugin_name: str, category: str, page: int = 1) -
if show_tmdb and tmdb_titles:
with _busy_dialog():
tmdb_prefetched = _tmdb_labels_and_art_bulk(tmdb_titles)
if show_tmdb:
for title in titles:
tmdb_info, tmdb_art, tmdb_cast = tmdb_prefetched.get(title, ({}, {}, []))
tmdb_info, tmdb_art, tmdb_cast = tmdb_prefetched.get(title, ({}, {}, [])) if show_tmdb else ({}, {}, [])
meta = plugin_meta.get(title)
info_labels, art, cast = _merge_metadata(title, tmdb_info, tmdb_art, tmdb_cast, meta)
info_labels.setdefault("mediatype", "tvshow")
@@ -1849,25 +1956,6 @@ def _show_category_titles_page(plugin_name: str, category: str, page: int = 1) -
art=art,
cast=cast,
)
else:
for title in titles:
playstate = _title_playstate(plugin_name, title)
meta = plugin_meta.get(title)
info_labels, art, cast = _merge_metadata(title, {}, {}, None, meta)
direct_play = bool(
plugin_name.casefold() == "einschalten"
and _get_setting_bool("einschalten_enable_playback", default=False)
)
_add_directory_item(
handle,
_label_with_playstate(title, playstate),
"play_movie" if direct_play else "seasons",
{"plugin": plugin_name, "title": title, **_series_url_params(plugin, title)},
is_folder=not direct_play,
info_labels=_apply_playstate_to_info(info_labels, playstate),
art=art,
cast=cast,
)
show_next = False
if total_pages is not None:
@@ -1939,16 +2027,16 @@ def _show_genre_titles_page(plugin_name: str, genre: str, page: int = 1) -> None
titles = [str(t).strip() for t in titles if t and str(t).strip()]
titles.sort(key=lambda value: value.casefold())
show_tmdb = _get_setting_bool("tmdb_genre_metadata", default=False)
if titles:
plugin_meta = _collect_plugin_metadata(plugin, titles)
show_tmdb = show_tmdb and _tmdb_enabled()
use_source, show_tmdb, prefer_source = _metadata_policy(
plugin_name, plugin, allow_tmdb=_tmdb_list_enabled()
)
plugin_meta = _collect_plugin_metadata(plugin, titles) if use_source else {}
show_plot = _get_setting_bool("tmdb_show_plot", default=True)
show_art = _get_setting_bool("tmdb_show_art", default=True)
prefer_source = bool(getattr(plugin, "prefer_source_metadata", False))
tmdb_prefetched: dict[str, tuple[dict[str, str], dict[str, str], list[TmdbCastMember]]] = {}
tmdb_titles = list(titles)
if show_tmdb and prefer_source:
tmdb_titles = list(titles) if show_tmdb else []
if show_tmdb and prefer_source and use_source:
tmdb_titles = []
for title in titles:
meta = plugin_meta.get(title)
@@ -2090,13 +2178,30 @@ def _show_alpha_titles_page(plugin_name: str, letter: str, page: int = 1) -> Non
titles = [str(t).strip() for t in titles if t and str(t).strip()]
titles.sort(key=lambda value: value.casefold())
show_tmdb = _get_setting_bool("tmdb_genre_metadata", default=False)
if titles:
if show_tmdb:
with _busy_dialog():
tmdb_prefetched = _tmdb_labels_and_art_bulk(titles)
use_source, show_tmdb, prefer_source = _metadata_policy(
plugin_name, plugin, allow_tmdb=_tmdb_list_enabled()
)
plugin_meta = _collect_plugin_metadata(plugin, titles) if use_source else {}
show_plot = _get_setting_bool("tmdb_show_plot", default=True)
show_art = _get_setting_bool("tmdb_show_art", default=True)
tmdb_prefetched: dict[str, tuple[dict[str, str], dict[str, str], list[TmdbCastMember]]] = {}
tmdb_titles = list(titles) if show_tmdb else []
if show_tmdb and prefer_source and use_source:
tmdb_titles = []
for title in titles:
info_labels, art, cast = tmdb_prefetched.get(title, _tmdb_labels_and_art(title))
meta = plugin_meta.get(title)
meta_labels = meta[0] if meta else {}
meta_art = meta[1] if meta else {}
if _needs_tmdb(meta_labels, meta_art, want_plot=show_plot, want_art=show_art):
tmdb_titles.append(title)
if show_tmdb and tmdb_titles:
with _busy_dialog():
tmdb_prefetched = _tmdb_labels_and_art_bulk(tmdb_titles)
for title in titles:
tmdb_info, tmdb_art, tmdb_cast = tmdb_prefetched.get(title, ({}, {}, [])) if show_tmdb else ({}, {}, [])
meta = plugin_meta.get(title)
info_labels, art, cast = _merge_metadata(title, tmdb_info, tmdb_art, tmdb_cast, meta)
info_labels = dict(info_labels or {})
info_labels.setdefault("mediatype", "tvshow")
if (info_labels.get("mediatype") or "").strip().casefold() == "tvshow":
@@ -2119,21 +2224,6 @@ def _show_alpha_titles_page(plugin_name: str, letter: str, page: int = 1) -> Non
art=art,
cast=cast,
)
else:
for title in titles:
playstate = _title_playstate(plugin_name, title)
direct_play = bool(
plugin_name.casefold() == "einschalten"
and _get_setting_bool("einschalten_enable_playback", default=False)
)
_add_directory_item(
handle,
_label_with_playstate(title, playstate),
"play_movie" if direct_play else "seasons",
{"plugin": plugin_name, "title": title, **_series_url_params(plugin, title)},
is_folder=not direct_play,
info_labels=_apply_playstate_to_info({"title": title}, playstate),
)
show_next = False
if total_pages is not None:
@@ -2200,13 +2290,30 @@ def _show_series_catalog(plugin_name: str, page: int = 1) -> None:
titles = [str(t).strip() for t in titles if t and str(t).strip()]
titles.sort(key=lambda value: value.casefold())
show_tmdb = _get_setting_bool("tmdb_genre_metadata", default=False)
if titles:
if show_tmdb:
with _busy_dialog():
tmdb_prefetched = _tmdb_labels_and_art_bulk(titles)
use_source, show_tmdb, prefer_source = _metadata_policy(
plugin_name, plugin, allow_tmdb=_tmdb_list_enabled()
)
plugin_meta = _collect_plugin_metadata(plugin, titles) if use_source else {}
show_plot = _get_setting_bool("tmdb_show_plot", default=True)
show_art = _get_setting_bool("tmdb_show_art", default=True)
tmdb_prefetched: dict[str, tuple[dict[str, str], dict[str, str], list[TmdbCastMember]]] = {}
tmdb_titles = list(titles) if show_tmdb else []
if show_tmdb and prefer_source and use_source:
tmdb_titles = []
for title in titles:
info_labels, art, cast = tmdb_prefetched.get(title, _tmdb_labels_and_art(title))
meta = plugin_meta.get(title)
meta_labels = meta[0] if meta else {}
meta_art = meta[1] if meta else {}
if _needs_tmdb(meta_labels, meta_art, want_plot=show_plot, want_art=show_art):
tmdb_titles.append(title)
if show_tmdb and tmdb_titles:
with _busy_dialog():
tmdb_prefetched = _tmdb_labels_and_art_bulk(tmdb_titles)
for title in titles:
tmdb_info, tmdb_art, tmdb_cast = tmdb_prefetched.get(title, ({}, {}, [])) if show_tmdb else ({}, {}, [])
meta = plugin_meta.get(title)
info_labels, art, cast = _merge_metadata(title, tmdb_info, tmdb_art, tmdb_cast, meta)
info_labels = dict(info_labels or {})
info_labels.setdefault("mediatype", "tvshow")
if (info_labels.get("mediatype") or "").strip().casefold() == "tvshow":
@@ -2225,17 +2332,6 @@ def _show_series_catalog(plugin_name: str, page: int = 1) -> None:
art=art,
cast=cast,
)
else:
for title in titles:
playstate = _title_playstate(plugin_name, title)
_add_directory_item(
handle,
_label_with_playstate(title, playstate),
"seasons",
{"plugin": plugin_name, "title": title, **_series_url_params(plugin, title)},
is_folder=True,
info_labels=_apply_playstate_to_info({"title": title}, playstate),
)
show_next = False
if total_pages is not None:
@@ -2429,16 +2525,16 @@ def _show_popular(plugin_name: str | None = None, page: int = 1) -> None:
end = start + page_size
page_items = titles[start:end]
show_tmdb = _get_setting_bool("tmdb_genre_metadata", default=False)
if page_items:
plugin_meta = _collect_plugin_metadata(plugin, page_items)
show_tmdb = show_tmdb and _tmdb_enabled()
use_source, show_tmdb, prefer_source = _metadata_policy(
plugin_name, plugin, allow_tmdb=_tmdb_list_enabled()
)
plugin_meta = _collect_plugin_metadata(plugin, page_items) if use_source else {}
show_plot = _get_setting_bool("tmdb_show_plot", default=True)
show_art = _get_setting_bool("tmdb_show_art", default=True)
prefer_source = bool(getattr(plugin, "prefer_source_metadata", False))
tmdb_prefetched: dict[str, tuple[dict[str, str], dict[str, str], list[TmdbCastMember]]] = {}
tmdb_titles = list(page_items)
if show_tmdb and prefer_source:
tmdb_titles = list(page_items) if show_tmdb else []
if show_tmdb and prefer_source and use_source:
tmdb_titles = []
for title in page_items:
meta = plugin_meta.get(title)
@@ -2450,7 +2546,7 @@ def _show_popular(plugin_name: str | None = None, page: int = 1) -> None:
with _busy_dialog():
tmdb_prefetched = _tmdb_labels_and_art_bulk(tmdb_titles)
for title in page_items:
tmdb_info, tmdb_art, tmdb_cast = tmdb_prefetched.get(title, ({}, {}, []))
tmdb_info, tmdb_art, tmdb_cast = tmdb_prefetched.get(title, ({}, {}, [])) if show_tmdb else ({}, {}, [])
meta = plugin_meta.get(title)
info_labels, art, cast = _merge_metadata(title, tmdb_info, tmdb_art, tmdb_cast, meta)
info_labels.setdefault("mediatype", "tvshow")
@@ -2577,13 +2673,30 @@ def _show_new_titles(plugin_name: str, page: int = 1) -> None:
start = (page - 1) * page_size
end = start + page_size
page_items = titles[start:end]
show_tmdb = _get_setting_bool("tmdb_genre_metadata", default=False)
if page_items:
if show_tmdb:
with _busy_dialog():
tmdb_prefetched = _tmdb_labels_and_art_bulk(page_items)
use_source, show_tmdb, prefer_source = _metadata_policy(
plugin_name, plugin, allow_tmdb=_tmdb_list_enabled()
)
plugin_meta = _collect_plugin_metadata(plugin, page_items) if use_source else {}
show_plot = _get_setting_bool("tmdb_show_plot", default=True)
show_art = _get_setting_bool("tmdb_show_art", default=True)
tmdb_prefetched: dict[str, tuple[dict[str, str], dict[str, str], list[TmdbCastMember]]] = {}
tmdb_titles = list(page_items) if show_tmdb else []
if show_tmdb and prefer_source and use_source:
tmdb_titles = []
for title in page_items:
info_labels, art, cast = tmdb_prefetched.get(title, _tmdb_labels_and_art(title))
meta = plugin_meta.get(title)
meta_labels = meta[0] if meta else {}
meta_art = meta[1] if meta else {}
if _needs_tmdb(meta_labels, meta_art, want_plot=show_plot, want_art=show_art):
tmdb_titles.append(title)
if show_tmdb and tmdb_titles:
with _busy_dialog():
tmdb_prefetched = _tmdb_labels_and_art_bulk(tmdb_titles)
for title in page_items:
tmdb_info, tmdb_art, tmdb_cast = tmdb_prefetched.get(title, ({}, {}, [])) if show_tmdb else ({}, {}, [])
meta = plugin_meta.get(title)
info_labels, art, cast = _merge_metadata(title, tmdb_info, tmdb_art, tmdb_cast, meta)
info_labels = dict(info_labels or {})
info_labels.setdefault("mediatype", "movie")
playstate = _title_playstate(plugin_name, title)
@@ -2604,21 +2717,6 @@ def _show_new_titles(plugin_name: str, page: int = 1) -> None:
art=art,
cast=cast,
)
else:
for title in page_items:
playstate = _title_playstate(plugin_name, title)
direct_play = bool(
plugin_name.casefold() == "einschalten"
and _get_setting_bool("einschalten_enable_playback", default=False)
)
_add_directory_item(
handle,
_label_with_playstate(title, playstate),
"play_movie" if direct_play else "seasons",
{"plugin": plugin_name, "title": title, **_series_url_params(plugin, title)},
is_folder=not direct_play,
info_labels=_apply_playstate_to_info({"title": title}, playstate),
)
show_next = False
if callable(paging_getter) and callable(has_more_getter):
@@ -2738,7 +2836,9 @@ def _show_genre_series_group(plugin_name: str, genre: str, group_code: str, page
return
xbmcplugin.setPluginCategory(handle, f"{genre} [{group_code}] ({page})")
show_tmdb = _get_setting_bool("tmdb_genre_metadata", default=False)
use_source, show_tmdb, prefer_source = _metadata_policy(
plugin_name, plugin, allow_tmdb=_tmdb_list_enabled()
)
if page > 1:
_add_directory_item(
handle,
@@ -2748,11 +2848,26 @@ def _show_genre_series_group(plugin_name: str, genre: str, group_code: str, page
is_folder=True,
)
if page_items:
if show_tmdb:
with _busy_dialog():
tmdb_prefetched = _tmdb_labels_and_art_bulk(page_items)
plugin_meta = _collect_plugin_metadata(plugin, page_items) if use_source else {}
show_plot = _get_setting_bool("tmdb_show_plot", default=True)
show_art = _get_setting_bool("tmdb_show_art", default=True)
tmdb_prefetched: dict[str, tuple[dict[str, str], dict[str, str], list[TmdbCastMember]]] = {}
tmdb_titles = list(page_items) if show_tmdb else []
if show_tmdb and prefer_source and use_source:
tmdb_titles = []
for title in page_items:
info_labels, art, cast = tmdb_prefetched.get(title, _tmdb_labels_and_art(title))
meta = plugin_meta.get(title)
meta_labels = meta[0] if meta else {}
meta_art = meta[1] if meta else {}
if _needs_tmdb(meta_labels, meta_art, want_plot=show_plot, want_art=show_art):
tmdb_titles.append(title)
if show_tmdb and tmdb_titles:
with _busy_dialog():
tmdb_prefetched = _tmdb_labels_and_art_bulk(tmdb_titles)
for title in page_items:
tmdb_info, tmdb_art, tmdb_cast = tmdb_prefetched.get(title, ({}, {}, [])) if show_tmdb else ({}, {}, [])
meta = plugin_meta.get(title)
info_labels, art, cast = _merge_metadata(title, tmdb_info, tmdb_art, tmdb_cast, meta)
info_labels = dict(info_labels or {})
info_labels.setdefault("mediatype", "tvshow")
if (info_labels.get("mediatype") or "").strip().casefold() == "tvshow":
@@ -2771,17 +2886,6 @@ def _show_genre_series_group(plugin_name: str, genre: str, group_code: str, page
art=art,
cast=cast,
)
else:
for title in page_items:
playstate = _title_playstate(plugin_name, title)
_add_directory_item(
handle,
_label_with_playstate(title, playstate),
"seasons",
{"plugin": plugin_name, "title": title, **_series_url_params(plugin, title)},
is_folder=True,
info_labels=_apply_playstate_to_info({"title": title}, playstate),
)
show_next = False
if callable(grouped_has_more):
try:
@@ -2827,14 +2931,31 @@ def _show_genre_series_group(plugin_name: str, genre: str, group_code: str, page
start = (page - 1) * page_size
end = start + page_size
page_items = filtered[start:end]
show_tmdb = _get_setting_bool("tmdb_genre_metadata", default=False)
use_source, show_tmdb, prefer_source = _metadata_policy(
plugin_name, plugin, allow_tmdb=_tmdb_list_enabled()
)
if page_items:
if show_tmdb:
with _busy_dialog():
tmdb_prefetched = _tmdb_labels_and_art_bulk(page_items)
plugin_meta = _collect_plugin_metadata(plugin, page_items) if use_source else {}
show_plot = _get_setting_bool("tmdb_show_plot", default=True)
show_art = _get_setting_bool("tmdb_show_art", default=True)
tmdb_prefetched: dict[str, tuple[dict[str, str], dict[str, str], list[TmdbCastMember]]] = {}
tmdb_titles = list(page_items) if show_tmdb else []
if show_tmdb and prefer_source and use_source:
tmdb_titles = []
for title in page_items:
info_labels, art, cast = tmdb_prefetched.get(title, _tmdb_labels_and_art(title))
meta = plugin_meta.get(title)
meta_labels = meta[0] if meta else {}
meta_art = meta[1] if meta else {}
if _needs_tmdb(meta_labels, meta_art, want_plot=show_plot, want_art=show_art):
tmdb_titles.append(title)
if show_tmdb and tmdb_titles:
with _busy_dialog():
tmdb_prefetched = _tmdb_labels_and_art_bulk(tmdb_titles)
for title in page_items:
tmdb_info, tmdb_art, tmdb_cast = tmdb_prefetched.get(title, ({}, {}, [])) if show_tmdb else ({}, {}, [])
meta = plugin_meta.get(title)
info_labels, art, cast = _merge_metadata(title, tmdb_info, tmdb_art, tmdb_cast, meta)
info_labels = dict(info_labels or {})
info_labels.setdefault("mediatype", "tvshow")
if (info_labels.get("mediatype") or "").strip().casefold() == "tvshow":
@@ -2853,17 +2974,6 @@ def _show_genre_series_group(plugin_name: str, genre: str, group_code: str, page
art=art,
cast=cast,
)
else:
for title in page_items:
playstate = _title_playstate(plugin_name, title)
_add_directory_item(
handle,
_label_with_playstate(title, playstate),
"seasons",
{"plugin": plugin_name, "title": title, **_series_url_params(plugin, title)},
is_folder=True,
info_labels=_apply_playstate_to_info({"title": title}, playstate),
)
if total_pages > 1 and page < total_pages:
_add_directory_item(

View File

@@ -31,22 +31,28 @@
</category>
<category label="TopStream">
<setting id="topstream_base_url" type="text" label="Domain (BASE_URL)" default="https://topstreamfilm.live" />
<setting id="topstreamfilm_metadata_source" type="enum" label="Metadatenquelle" default="0" values="Auto|Quelle|TMDB|Mix" />
<setting id="topstream_genre_max_pages" type="number" label="Genres: max. Seiten laden (Pagination)" default="20" />
</category>
<category label="SerienStream">
<setting id="serienstream_base_url" type="text" label="Domain (BASE_URL)" default="https://s.to" />
<setting id="serienstream_metadata_source" type="enum" label="Metadatenquelle" default="0" values="Auto|Quelle|TMDB|Mix" />
</category>
<category label="AniWorld">
<setting id="aniworld_base_url" type="text" label="Domain (BASE_URL)" default="https://aniworld.to" />
<setting id="aniworld_metadata_source" type="enum" label="Metadatenquelle" default="0" values="Auto|Quelle|TMDB|Mix" />
</category>
<category label="Einschalten">
<setting id="einschalten_base_url" type="text" label="Domain (BASE_URL)" default="https://einschalten.in" />
<setting id="einschalten_metadata_source" type="enum" label="Metadatenquelle" default="0" values="Auto|Quelle|TMDB|Mix" />
</category>
<category label="Filmpalast">
<setting id="filmpalast_base_url" type="text" label="Domain (BASE_URL)" default="https://filmpalast.to" />
<setting id="filmpalast_metadata_source" type="enum" label="Metadatenquelle" default="0" values="Auto|Quelle|TMDB|Mix" />
</category>
<category label="Doku-Streams">
<setting id="doku_streams_base_url" type="text" label="Domain (BASE_URL)" default="https://doku-streams.com" />
<setting id="doku_streams_metadata_source" type="enum" label="Metadatenquelle" default="0" values="Auto|Quelle|TMDB|Mix" />
</category>
<category label="TMDB">
<setting id="tmdb_enabled" type="bool" label="TMDB aktivieren" default="true" />