Skip to content

Architektur DE

TheMRX13 edited this page Jul 5, 2026 · 4 revisions

Architektur

🌐 English · Deutsch

Projektstruktur

src/mediaforge/
├── __main__.py / entry.py     # Einstieg: startet immer die WebUI
├── arguments.py               # CLI-Flags (-wP, -wH, -wN, -d)
├── config.py                  # Globale Konfiguration, HTTP-Session, Sprach-/URL-Patterns
├── env.py                     # Legacy-.env-Merge (nur falls Datei existiert)
├── logger.py                  # Logging-Setup
├── autodeps.py                # Auto-Download von Abhängigkeiten (Chromium, mpv, …)
├── providers.py               # Quellen-Registry (AniWorld, SerienStream, FilmPalast, MegaKino, hanime)
├── search.py                  # Suche + Browse-Listen (neue/beliebte Animes & Serien)
├── extractors/
│   └── provider/              # Ein Modul pro Video-Hoster (voe.py, vidoza.py, …)
├── models/
│   ├── aniworld_to/           # Series / Season / Episode für aniworld.to
│   ├── s_to/                  # Series / Season / Episode für serienstream.to
│   ├── filmpalast_to/         # Episode (Film) für filmpalast.to
│   └── common/                # Download-Logik: yt-dlp + FFmpeg, Fortschritt
├── playwright/
│   └── captcha.py             # Captcha-Erkennung & interaktive Lösung (Patchright-Chromium)
├── anime4k/                   # Upscaling (mpv/libplacebo) + mitgelieferte GLSL-Shader
└── web/
    ├── app.py                 # Flask-App: alle Routen, Worker, create_app()
    ├── auth.py                # Login, Setup, OIDC, Benutzerverwaltung, Rate-Limit
    ├── db.py                  # SQLite-Zugriff, Schema, Settings (inkl. Verschlüsselung)
    ├── notifications.py       # Web Push, Telegram, Discord, Pushover, ntfy, WhatsApp
    ├── transcoder.py          # HLS-Live-Transcoding für den Browser-Player
    ├── library_watcher.py     # watchdog-basierte Bibliotheksüberwachung
    ├── templates/             # Jinja2-Templates (eine Datei pro Seite)
    ├── static/                # CSS/JS (eine CSS/JS-Datei pro Seite) + PWA-Assets
    └── translations/          # Flask-Babel (de)

Startablauf

  1. mediaforgeentry.mediaforge(): Terminal-Titel, ensure_patchright_chromium() (lädt Chromium bei Bedarf), Argumente parsen.
  2. start_web_ui()create_app():
    • Datenbank-Initialisierung (alle Tabellen, Migrationen)
    • Setup-Token-Generierung, falls kein Admin existiert
    • Einmalige .env-→-DB-Migration, dann Sync aller DB-Settings nach os.environ
    • DNS-Patch gemäß gespeicherter Einstellung
    • Start der Hintergrund-Worker (siehe unten)
  3. Produktiv-Server: Waitress (16 Threads) mit sauberem Signal-Handling (Ctrl+C killt laufende FFmpeg-/Chromium-Subprozesse); im Debug-Modus Flask-Devserver.

Hintergrund-Worker (Daemon-Threads)

Worker Aufgabe Takt
Queue-Worker Downloads sequenziell abarbeiten (mit Watchdog) poll 3 s
AutoSync-Worker Fällige Sync-Jobs ausführen poll 10 s
Upscale-Worker Anime4K-Aufträge abarbeiten poll 4 s
Browse-Prefetch Browse-Listen, Poster und TMDB-Daten vorwärmen alle 15 min
Update-Checker GitHub-Releases / models-Branch prüfen alle 24 h
MediaScan-Scheduler Plex/Jellyfin-Bestand neu laden alle 24 h
TMDB-Keyword-Sync Keyword-Export für erweiterte Suche laden stündlich geprüft
TMDB-Cache-Eviction Abgelaufene Cache-Einträge löschen stündlich
Kalender-Watcher TMDB-Termindaten für AutoSync-/Seerr-/Mediathek-Titel (zweisprachig) in calendar_media/calendar_episodes cachen Poll 10 s, 1 Titel/Zyklus
Library-Watcher Dateisystem-Events → gezielte Rescans ereignisgesteuert

Alle Worker sind über _ensure_*-Funktionen idempotent gestartet; im Flask-Debug-Modus nur im Reloader-Kindprozess (verhindert doppelte Downloads).

Settings-System

Drei Schichten, die create_app() beim Start zusammenführt:

  1. DB (app_settings) — führende Quelle, von der UI geschrieben (sensible Keys verschlüsselt, siehe Datenbank).
  2. os.environ — beim Start aus der DB befüllt (_sync_db_settings_to_env); ermöglicht, dass alter Code überall os.environ.get("MEDIAFORGE_*") nutzt.
  3. Legacy .env — wird nur noch einmalig importiert (_migrate_dotenv_to_db, bewacht durch env_migrated-Flag).

HTTP-Schicht

  • niquests mit thread-lokalem Session-Pool (GLOBAL_SESSION), Standard-DNS über DoH (Google), per Einstellung umschaltbar (rebuild_global_session).
  • curl_cffi (Chrome-Impersonation) als Fallback/Ergänzung beim Auflösen von Hoster-Redirects (Cloudflare-Umgehung).
  • Verfügbarkeitserkennung: is_source_unavailable() erkennt 404/410/451 sowie typische „Video gelöscht“-Marker im HTML.

Sicherheit (Web-Schicht)

  • Auth-Decorator-Wrapping: Alle Routen außer Auth/Static/v1-API erhalten automatisch login_required; eine definierte Liste (_admin_only) erhält admin_required.
  • CSRF: Formulare über Flask-WTF; JSON-APIs sind exempt, dafür wird Content-Type: application/json für POST/PUT/DELETE erzwungen.
  • SSRF-Schutz: Benutzerkonfigurierte Server-URLs (Jellyfin/Plex/Seerr) werden gegen Cloud-Metadata-Endpoints und Link-Local-Netze validiert.
  • Security-Header inkl. CSP auf jeder Antwort.

Datenfluss eines Downloads

UI (/api/download) ──> download_queue (SQLite)
                            │ claim_next_queued()
                            ▼
                      Queue-Worker
                            │ resolve_provider(url) → Episode-Klasse
                            ▼
                  episode.download()
                   │ provider_data → Extraktor (z. B. VOE) → Direktlink
                   │ ggf. Captcha (playwright/captcha.py, interaktiv via UI)
                   ▼
              yt-dlp + FFmpeg → .mkv gemäß Naming-Template
                            │
                            ▼
   Status (completed/partial/failed) → Notifications → Plex/Jellyfin-Refresh
                                          → optional Upscale-Queue

Clone this wiki locally