dev: gruppierte Suchergebnisse mit Quellenauswahl (Issue #2)
- _show_search_results() gruppiert Treffer über alle Plugins nach Titel - Titel in einem Plugin: direkt zur Staffel-Ansicht (kein Plugin-Suffix) - Titel in mehreren Plugins: Zwischenstufe 'Quelle wählen' - Neue Funktion _show_choose_source() und Route 'choose_source'
This commit is contained in:
@@ -1958,7 +1958,8 @@ def _show_search_results(query: str) -> None:
|
|||||||
xbmcgui.Dialog().notification("Suche", "Keine Quellen gefunden.", xbmcgui.NOTIFICATION_INFO, 3000)
|
xbmcgui.Dialog().notification("Suche", "Keine Quellen gefunden.", xbmcgui.NOTIFICATION_INFO, 3000)
|
||||||
xbmcplugin.endOfDirectory(handle)
|
xbmcplugin.endOfDirectory(handle)
|
||||||
return
|
return
|
||||||
list_items: list[dict[str, object]] = []
|
# grouped: casefold-key → Liste der Plugin-Einträge für diesen Titel
|
||||||
|
grouped: dict[str, list[dict[str, object]]] = {}
|
||||||
canceled = False
|
canceled = False
|
||||||
plugin_entries = list(plugins.items())
|
plugin_entries = list(plugins.items())
|
||||||
total_plugins = max(1, len(plugin_entries))
|
total_plugins = max(1, len(plugin_entries))
|
||||||
@@ -2029,31 +2030,61 @@ def _show_search_results(query: str) -> None:
|
|||||||
merged_info = _apply_playstate_to_info(dict(info_labels), playstate)
|
merged_info = _apply_playstate_to_info(dict(info_labels), playstate)
|
||||||
label = _label_with_duration(title, info_labels)
|
label = _label_with_duration(title, info_labels)
|
||||||
label = _label_with_playstate(label, playstate)
|
label = _label_with_playstate(label, playstate)
|
||||||
label = f"{label} [{plugin_name}]"
|
|
||||||
direct_play = bool(
|
direct_play = bool(
|
||||||
plugin_name.casefold() == "einschalten" and _get_setting_bool("einschalten_enable_playback", default=False)
|
plugin_name.casefold() == "einschalten" and _get_setting_bool("einschalten_enable_playback", default=False)
|
||||||
)
|
)
|
||||||
extra_params = _series_url_params(plugin, title)
|
extra_params = _series_url_params(plugin, title)
|
||||||
list_items.append(
|
key = title.casefold()
|
||||||
{
|
grouped.setdefault(key, []).append({
|
||||||
"label": label,
|
"title": title,
|
||||||
"action": "play_movie" if direct_play else "seasons",
|
"plugin_name": plugin_name,
|
||||||
"params": {"plugin": plugin_name, "title": title, **extra_params},
|
"extra_params": extra_params,
|
||||||
"is_folder": (not direct_play),
|
"label_base": label,
|
||||||
|
"direct_play": direct_play,
|
||||||
"info_labels": merged_info,
|
"info_labels": merged_info,
|
||||||
"art": art,
|
"art": art,
|
||||||
"cast": cast,
|
"cast": cast,
|
||||||
}
|
})
|
||||||
)
|
|
||||||
if canceled:
|
if canceled:
|
||||||
break
|
break
|
||||||
if not canceled:
|
if not canceled:
|
||||||
progress(100, "Suche fertig")
|
progress(100, "Suche fertig")
|
||||||
if canceled and not list_items:
|
if canceled and not grouped:
|
||||||
xbmcgui.Dialog().notification("Suche", "Suche abgebrochen.", xbmcgui.NOTIFICATION_INFO, 2500)
|
xbmcgui.Dialog().notification("Suche", "Suche abgebrochen.", xbmcgui.NOTIFICATION_INFO, 2500)
|
||||||
xbmcplugin.endOfDirectory(handle)
|
xbmcplugin.endOfDirectory(handle)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# Gruppierte Einträge alphabetisch ausgeben
|
||||||
|
list_items: list[dict[str, object]] = []
|
||||||
|
for key in sorted(grouped):
|
||||||
|
entries = grouped[key]
|
||||||
|
first = entries[0]
|
||||||
|
canonical_title = str(first["title"])
|
||||||
|
if len(entries) == 1:
|
||||||
|
# Nur ein Plugin → direkt zur Staffel-Ansicht
|
||||||
|
direct_play = bool(first["direct_play"])
|
||||||
|
list_items.append({
|
||||||
|
"label": first["label_base"],
|
||||||
|
"action": "play_movie" if direct_play else "seasons",
|
||||||
|
"params": {"plugin": first["plugin_name"], "title": canonical_title, **dict(first["extra_params"])},
|
||||||
|
"is_folder": not direct_play,
|
||||||
|
"info_labels": first["info_labels"],
|
||||||
|
"art": first["art"],
|
||||||
|
"cast": first["cast"],
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
# Mehrere Plugins → Zwischenstufe "Quelle wählen"
|
||||||
|
plugin_list = ",".join(str(e["plugin_name"]) for e in entries)
|
||||||
|
list_items.append({
|
||||||
|
"label": first["label_base"],
|
||||||
|
"action": "choose_source",
|
||||||
|
"params": {"title": canonical_title, "plugins": plugin_list},
|
||||||
|
"is_folder": True,
|
||||||
|
"info_labels": first["info_labels"],
|
||||||
|
"art": first["art"],
|
||||||
|
"cast": first["cast"],
|
||||||
|
})
|
||||||
|
|
||||||
for item in list_items:
|
for item in list_items:
|
||||||
_add_directory_item(
|
_add_directory_item(
|
||||||
handle,
|
handle,
|
||||||
@@ -2068,6 +2099,31 @@ def _show_search_results(query: str) -> None:
|
|||||||
xbmcplugin.endOfDirectory(handle)
|
xbmcplugin.endOfDirectory(handle)
|
||||||
|
|
||||||
|
|
||||||
|
def _show_choose_source(title: str, plugins_str: str) -> None:
|
||||||
|
"""Zeigt Quellenauswahl wenn ein Titel in mehreren Plugins verfügbar ist."""
|
||||||
|
handle = _get_handle()
|
||||||
|
title = (title or "").strip()
|
||||||
|
plugin_names = [p.strip() for p in (plugins_str or "").split(",") if p.strip()]
|
||||||
|
all_plugins = _discover_plugins()
|
||||||
|
|
||||||
|
xbmcplugin.setPluginCategory(handle, title)
|
||||||
|
_set_content(handle, "tvshows")
|
||||||
|
|
||||||
|
for plugin_name in plugin_names:
|
||||||
|
plugin = all_plugins.get(plugin_name)
|
||||||
|
if not plugin:
|
||||||
|
continue
|
||||||
|
extra_params = _series_url_params(plugin, title)
|
||||||
|
_add_directory_item(
|
||||||
|
handle,
|
||||||
|
plugin_name,
|
||||||
|
"seasons",
|
||||||
|
{"plugin": plugin_name, "title": title, **extra_params},
|
||||||
|
is_folder=True,
|
||||||
|
)
|
||||||
|
xbmcplugin.endOfDirectory(handle)
|
||||||
|
|
||||||
|
|
||||||
def _movie_seed_for_title(plugin: BasisPlugin, title: str, seasons: list[str]) -> tuple[str, str] | None:
|
def _movie_seed_for_title(plugin: BasisPlugin, title: str, seasons: list[str]) -> tuple[str, str] | None:
|
||||||
"""Ermittelt ein Film-Seed (Season/Episode), um direkt Provider anzeigen zu können."""
|
"""Ermittelt ein Film-Seed (Season/Episode), um direkt Provider anzeigen zu können."""
|
||||||
if not seasons or len(seasons) != 1:
|
if not seasons or len(seasons) != 1:
|
||||||
@@ -4728,6 +4784,11 @@ def _route_install_resolveurl(params: dict[str, str]) -> None:
|
|||||||
_ensure_resolveurl_installed(force=True, silent=False)
|
_ensure_resolveurl_installed(force=True, silent=False)
|
||||||
|
|
||||||
|
|
||||||
|
@_router.route("choose_source")
|
||||||
|
def _route_choose_source(params: dict[str, str]) -> None:
|
||||||
|
_show_choose_source(params.get("title", ""), params.get("plugins", ""))
|
||||||
|
|
||||||
|
|
||||||
@_router.route("seasons")
|
@_router.route("seasons")
|
||||||
def _route_seasons(params: dict[str, str]) -> None:
|
def _route_seasons(params: dict[str, str]) -> None:
|
||||||
_show_seasons(params.get("plugin", ""), params.get("title", ""), params.get("series_url", ""))
|
_show_seasons(params.get("plugin", ""), params.get("title", ""), params.get("series_url", ""))
|
||||||
|
|||||||
Reference in New Issue
Block a user