Skip to content

CineInfo Quellen DE

Domekologe edited this page Jul 28, 2026 · 2 revisions

CineInfo-Quellen

CineInfo-Quellen sind der Erweiterungspunkt, über den ein Drittanbieter-Modul eigene CineInfo-Daten (Bewertungen, Provider, eigene Felder, ...) zusätzlich zur eingebauten TMDB-Abfrage liefern kann — ohne Änderung am Core. Während ein Provider-Pill nur ein kleines Verfügbarkeits-Badge zeigt, speist eine Quelle echte Felder in die CineInfo-Abfragen selbst ein.

Der Core bleibt maßgeblich: Quellen werden über das TMDB-Ergebnis gelegt, und ohne registrierte Quelle ist der gesamte Mechanismus ein kostenneutraler Durchlauf.

Die zwei Batch-Formen

Jede Quelle deklariert ein einziges Fähigkeits-Flag; der Orchestrator wählt die Abfrageform automatisch — dafür gibt es keine Nutzer-Einstellung:

supports_bulk Orchestrator ruft Bedeutung Wofür
False fetch_one(item, ctx) je Item „einzeln nach und nach" — eine Anfrage pro Item, geschleift mit begrenzter Parallelität Upstreams mit einer Abfrage pro Anfrage (z. B. TMDB)
True fetch_many(items, ctx) je Chunk „alles in einer Anfrage" — eine Anfrage für bis zu max_bulk Items Upstreams mit echtem Bulk-Endpoint

Beide Formen laufen durch dieselbe Cache-, Rate-Limit- und Dedup-Schicht — eine Quelle implementiert Batching, Caching oder Drosselung also nie selbst.

Eine Quelle schreiben

from ...cineinfo.source import CineInfoSource, QueryContext
from ...db import get_setting

class MySource(CineInfoSource):
    id = "myprovider"            # stabil; zugleich Cache-Namespace + Limiter-Bucket
    label = "My Provider"
    supports_bulk = False        # ← die gesamte Batch-Form-Entscheidung
    rate = 5.0                   # max. Upstream-Anfragen/Sekunde
    cache_ttl = 86400.0          # Provider-Cache-TTL in Sekunden (0 = kein Cache)

    def is_enabled(self) -> bool:
        # Dem eigenen Toggle folgen: ein deaktiviertes Modul trägt sofort
        # nichts mehr bei. (Die Deinstallation regelt die item_id unten.)
        return get_setting("myprovider_enabled", "0") == "1"

    def fetch_one(self, item: dict, ctx: QueryContext) -> dict:
        # item trägt einen stabilen "key" plus Lookup-Felder
        # (title / imdb_id / tmdb_id). ctx.country und ctx.ui_lang sind gesetzt.
        # Nur die Felder zurückgeben, die man tatsächlich kennt.
        ...
        return {"vote_average": 8.1, "myprovider_url": "https://..."}

Eine Bulk-Quelle implementiert stattdessen fetch_many(items, ctx) und gibt {item["key"]: payload} für den ganzen Chunk in einer Anfrage zurück.

Registrieren

Aus dem register(app) des Moduls:

from ...cineinfo.registry import register_cineinfo_source
register_cineinfo_source(MySource(), item_id=MODULE_ID)

Pro Quelle eine Instanz registrieren. Es dürfen mehrere sein (z. B. eine je Batch-Form).

item_id ist die Id, die das Modul ohnehin schon an register_thirdparty() übergeben hat. Sie ist nur deshalb optional, damit Module gegen die erste Fassung dieser API weiterlaufen — sie sollte immer mitgegeben werden. Ohne sie funktioniert die Quelle zwar, aber:

  • der Modulmanager kann sie keinem Modul zuordnen und zeigt deshalb zu wenig an (genau darum stand bei einem reinen CineInfo-Modul früher nur „1 × Einstellungskarte"), und
  • unregister_module() kann sie nicht entfernen: Die Quelle eines deinstallierten Moduls bleibt für den Rest der Prozesslaufzeit registriert — unschädlich nur durch ihr eigenes is_enabled(), das eine Einstellung liest, die es nicht mehr gibt.

Mit item_id zeigt der Modulmanager 1 × CineInfo-Quelle (bzw. 2 ×, wenn ein Modul beide Batch-Formen registriert) und die Deinstallation räumt sie wirklich weg.

Wo die Quelle auftaucht

Eine registrierte Quelle ist keine unsichtbare Verkabelung:

  • Modulmanager: sie erscheint als 1 × CineInfo-Quelle in den Fähigkeiten des Moduls (genau dafür ist die item_id da, siehe oben).
  • Integrationen → CineInfo → „Reihenfolge der Quellen": als verschiebbare Zeile mit „Modul"-Pill, direkt neben den Provider-Pills. Diese Liste ist eine einzige Einstellung (cineinfo_provider_order) mit zwei Arten von Einträgen — ci:<Quell-Id> für eine CineInfo-Quelle, ext:<Name> bzw. blanke Ids für Provider-Pills — und jeder Konsument liest nur sein eigenes Präfix. Die Position bestimmt die Reihenfolge, in der enrich() die Quelle anwendet: die erste Quelle, die ein Feld kennt, füllt es, und die eingebaute TMDB-Basis gewinnt weiterhin gegen jede Quelle. Ohne Konfiguration gilt unverändert die alte alphabetische Reihenfolge nach id.
  • Modul-Einstellungen (unter dem Modulmanager) und Integrationen → Third Party listen die Einstellungskarte des Moduls, obwohl ihr Zuhause der CineInfo-Tab ist — dieselbe Karte, dieselbe API, derselbe Bearbeitungsvorgang.

Wie die Daten ankommen

Die Core-CineInfo-Endpoints (/api/tmdb/info, /api/tmdb/batch) rufen cineinfo.enrich(...) auf, das jede aktivierte Quelle ausführt und deren Payload feldweise auf die TMDB-Basis legt:

  • Die eingebauten TMDB-Daten gewinnen. Eine Quelle füllt nur Felder, die TMDB fehlen oder leer sind — plus eigene Zusatzfelder.
  • Quellen werden in stabiler id-Reihenfolge angewandt (deterministisch).
  • 0 / False sind gültige Werte und bleiben erhalten (nicht „leer").

Was du geschenkt bekommst

Cache-first (nur Cache-Misses gehen ins Netz, über die geteilte provider_cache-Tabelle), ein Token-Bucket-Rate-Limiter pro Quelle, In-Flight- Deduplizierung gleichzeitiger identischer Abfragen, begrenzte Parallelität, Timeouts pro Abfrage und Fehler-Isolation — ein fehlerhaftes Item oder eine fehlerhafte Quelle legt CineInfo nie lahm.

Referenz-Implementierung

Siehe .examples/thirdparties/example_cineinfo_source/ für ein vollständiges, offline-taugliches Modul, das je eine Quelle beider Batch-Formen unter dem CineInfo-Einstellungs-Tab registriert. Das Plug-in-System selbst ist in .examples/thirdparties/README.md dokumentiert.

Clone this wiki locally