94 lines
3.3 KiB
Python
94 lines
3.3 KiB
Python
from __future__ import annotations
|
|
|
|
import re
|
|
|
|
from plugin_interface import BasisPlugin
|
|
from tmdb import TmdbCastMember
|
|
|
|
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,
|
|
get_setting_int=None,
|
|
) -> tuple[bool, bool, bool]:
|
|
if not callable(get_setting_int):
|
|
return plugin_supports_metadata(plugin), allow_tmdb, bool(getattr(plugin, "prefer_source_metadata", False))
|
|
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 collect_plugin_metadata(
|
|
plugin: BasisPlugin,
|
|
titles: list[str],
|
|
) -> dict[str, tuple[dict[str, str], dict[str, str], list[TmdbCastMember] | None]]:
|
|
getter = getattr(plugin, "metadata_for", None)
|
|
if not callable(getter):
|
|
return {}
|
|
collected: dict[str, tuple[dict[str, str], dict[str, str], list[TmdbCastMember] | None]] = {}
|
|
for title in titles:
|
|
try:
|
|
labels, art, cast = getter(title)
|
|
except Exception:
|
|
continue
|
|
if isinstance(labels, dict) or isinstance(art, dict) or cast:
|
|
label_map = {str(k): str(v) for k, v in dict(labels or {}).items() if v}
|
|
art_map = {str(k): str(v) for k, v in dict(art or {}).items() if v}
|
|
collected[title] = (label_map, art_map, cast if isinstance(cast, list) else None)
|
|
return collected
|
|
|
|
|
|
def needs_tmdb(labels: dict[str, str], art: dict[str, str], *, want_plot: bool, want_art: bool) -> bool:
|
|
if want_plot and not labels.get("plot"):
|
|
return True
|
|
if want_art and not (art.get("thumb") or art.get("poster") or art.get("fanart") or art.get("landscape")):
|
|
return True
|
|
return False
|
|
|
|
|
|
def merge_metadata(
|
|
title: str,
|
|
tmdb_labels: dict[str, str] | None,
|
|
tmdb_art: dict[str, str] | None,
|
|
tmdb_cast: list[TmdbCastMember] | None,
|
|
plugin_meta: tuple[dict[str, str], dict[str, str], list[TmdbCastMember] | None] | None,
|
|
) -> tuple[dict[str, str], dict[str, str], list[TmdbCastMember] | None]:
|
|
labels = dict(tmdb_labels or {})
|
|
art = dict(tmdb_art or {})
|
|
cast = tmdb_cast
|
|
if plugin_meta is not None:
|
|
meta_labels, meta_art, meta_cast = plugin_meta
|
|
labels.update({k: str(v) for k, v in dict(meta_labels or {}).items() if v})
|
|
art.update({k: str(v) for k, v in dict(meta_art or {}).items() if v})
|
|
if meta_cast is not None:
|
|
cast = meta_cast
|
|
if "title" not in labels:
|
|
labels["title"] = title
|
|
return labels, art, cast
|