Skip to content

Modul API DE

Domekologe edited this page Jul 28, 2026 · 3 revisions

Modul-API

🌐 English · Deutsch

Alles, was ein Modul bei MediaForge registrieren kann, an einer Stelle. Die vollständige Referenz — mit einem lauffähigen Beispielmodul je Einstiegspunkt — steht in .examples/thirdparties/README.md im Repository; diese Seite ist die Übersicht dazu.

Ein Modul ist ein Ordner unter web/thirdparties/<name>/ mit einer Funktion register(app). Alles Folgende wird von dort aufgerufen.

Registrierungsfunktionen

Funktion Modul Was sie hinzufügt
register_thirdparty web.thirdparties.registry Das Modul selbst: Menüeintrag, Einstellungskarte, Dashboard-Widget, extra_settings-Felder, Ein/Aus-Schalter. Siehe „Wo eine Einstellungskarte landet" unten
register_provider providers Eine Inhaltsquelle (Seite) mit eigenen Serien-/Staffel-/Episoden-Klassen
register_search_source search Eine zusätzliche Quelle für die globale Suche
register_home_feed_source home_feed Zeilen und einen Chip für diese Quelle auf der neuen Startseite
register_hoster extractors Einen Hoster/Extractor, der eine Embed-URL zu einem Stream auflöst
register_site_mirrors mirrors Mirror-Domains einer Seite, mit automatischem Failover
register_cineinfo_source web.cineinfo.registry Eine Metadatenquelle neben TMDB
register_monitor_site web.uptime_monitor Eine Karte auf dem UpTime-Dashboard, geprüft wie die eingebauten Seiten
register_notification_channel web.thirdparties.registry Einen Benachrichtigungskanal neben Telegram/Pushover/Discord/ntfy
register_event_hook web.thirdparties.registry Einen Callback auf App-Ereignisse (Download fertig, Queue-Eintrag fehlgeschlagen, …)
register_background_worker web.thirdparties.registry Einen Worker-Thread, der mit dem Modul startet und stoppt
register_backup_category web.backup Eigene Daten im Voll-/Teil-Backup
register_sensitive_keys web.db Einstellungsschlüssel, die verschlüsselt gespeichert werden
register_ui_pref_key web.db Eine UI-Einstellung pro Benutzerkonto

register_restart_handler (web.restart) gehört nicht zu dieser API — die Funktion ist Core-intern und wird nur von web/app.py aufgerufen.

Wo eine Einstellungskarte landet

settings_host wählt die Seite; die Seite wählt den Platz. settings_tab ist ein Wunsch, den der Host überstimmen darf — angewendet bei der Registrierung durch registry._placed_tab(), damit alles Nachgelagerte die tatsächliche Platzierung sieht:

settings_host Karte landet settings_tab
"integrations" (Standard) Immer auf dem Third-Party-Tab Wird ignoriert, stillschweigend
"notifications" Immer ein eigener Tab Eine eingebaute Kanal-Id oder der blanke Standard wird zu module_<item_id>; eine eigene Id bleibt
"monitoring" Immer ein eigener Tab Dieselbe Regel
"settings" Modulmanager → Modul-Einstellungen Wird ignoriert (die Seite gruppiert nach Host)

„Was haben meine Module dieser Seite hinzugefügt?" hat pro Seite genau eine Antwort — und hört auf, eine zu sein, sobald sich ein Modul auf dem CineInfo-Tab oder in Telegrams Panel verstecken kann. Ein Modul, das einen eigenen Tab will, wählt einen Host, der ihm einen gibt, keine Tab-Id.

Unabhängig davon steht jede Modul-Karte zusätzlich unter Modulmanager → Modul-Einstellungen, nach Host gruppiert. Keine Kopie: beide Stellen fahren über dieselbe /api/settings/thirdparty/<id>-API.

Secrets

Ein "secret"-Feld, ein Schlüssel in MODULE_SENSITIVE_SETTINGS und alles, was an register_sensitive_keys() übergeben wird, liegt verschlüsselt in der Datenbank, und die generische Settings-API liefert statt des Werts eine Maske (registry.SECRET_MASK) — ein PUT, das die Maske zurückschickt, bedeutet „unverändert". Das gilt für jeden Schlüssel, den MediaForge als sensibel kennt, nicht nur für Felder mit type="secret": ein als normales Textfeld angezeigtes Secret wird ebenfalls maskiert. Im Modul selbst ändert sich nichts, get_setting() entschlüsselt wie gewohnt. Wer einen solchen Wert auf einer eigenen Seite ausgibt, sollte es genauso halten — ein gespeichertes Secret gehört nie ins HTML.

Frontend-Bausteine

Statt eigenem CSS besser das vorhandene Vokabular nutzen:

  • Formular-Elemente (forms.css): .chb-main für Checkboxen, .toggle für Ein/Aus-Schalter, .mf-segmented, .mf-multiselect, .mf-chip.
  • Layout und Inhalt (mf_components.css, global geladen): .mf-search, .mf-toolbar, .mf-poster-grid, .mf-timeline, .mf-progress, .mf-empty, .mf-pagination-bar.
  • Farben (variables.css): niemals Hex-Werte hart schreiben. Status-Pills nutzen das Paar --success + --success-bg (analog --warning, --error, --info); beide Hälften sind je Theme definiert.
  • Multi-Select (mf_multiselect.js, auf jeder Seite geladen): data-mf-multiselect an ein .mf-multiselect-Wurzelelement schreiben — Öffnen/Schließen, das Zusammenfassungs-Label im Trigger, Klick nach außen bzw. Escape und die Positionierung (wird in scrollenden Containern nicht abgeschnitten) laufen dann von selbst, ohne Init-Aufruf, also auch für später per JS gerendertes Markup. Den Text über data-none-label / data-many-label / data-max-names steuern und auf mf-multiselect-change / mf-multiselect-close am Wurzelelement lauschen (detail: {values, labels}, bubbelnd). Helfer: window.mfMultiSelect.values(), .labels(), .refresh(), .open(), .close(), .closeAll().
  • Escaping (mf_escape.js, auf jeder Seite geladen): window.mfEscape() für alles, was ins HTML geht — quote-sicher, deckt also auch Attribute ab — und window.mfSafeUrl() für href/src. Keinen eigenen Escaper schreiben.
  • Polling (mf_poll.js): window.mfPoll(fn, ms) statt setInterval, damit der Timer pausiert, solange der Tab versteckt ist.

Übersetzungen

Modul-Templates verwenden {{ _('...') }} wie der Core; ein Modul bringt seinen eigenen Katalog unter <modul>/translations/<locale>/LC_MESSAGES/ mit. Nach dem Bearbeiten einer .po muss pybabel compile laufen — ohne diesen Schritt bleibt die Änderung zur Laufzeit wirkungslos.

Clone this wiki locally