8eb5653848
Ampel / ampel (push) Successful in 55s
AUTH ENTFERNT (Commander-Entscheid 24.07., KONZEPT §10): /token- und /api-keys-Endpoints, auth.py, test_auth.py, passlib/bcrypt/PyJWT/ python-multipart, JWT_SECRET_KEY-Pflicht. Heimnetz-only, das UI hatte nie einen Login — die Auth-Oberflaeche war Placebo und die passlib/bcrypt- Falle brach die Ampel. Rate-Limit pro IP bleibt. Schnellstart laeuft jetzt ganz ohne .env-Pflichtwerte. Serien-Flow (Etappe-12-Kern, ARM-Wunde #395): - Rip-Dialog: Serienname + Staffel -> Ablage <Serie>/Season NN (jellyfin.org/docs Naming-Schema); tvshow.nfo + poster.jpg im Serien-Ordner, bei Staffel 2 nicht ueberschrieben. - Episoden-Matching per Laufzeitabgleich: HandBrakeCLI --scan ('+ duration:', handbrake.fr/docs) je MKV gegen TMDB-Staffel-Laufzeiten (GET /metadata/tv/{id}/season/{n}; tv-season-details-API). Ordnungserhaltend; komplette Staffel auf einer Disc klappt auch bei uniformen Anime-Laufzeiten (Sequenz-Stufe). Umbenannt wird NUR bei eindeutiger Zuordnung — sonst ehrliches Log. Mit Tests. Weitere Punkte: - Jellyfin/Emby-Bibliotheks-Refresh nach jedem fertigen Rip (POST /Library/Refresh, X-Emby-Token lt. jellyfin.org/docs) — URL/Key + Test-Knopf in Einstellungen -> Ripping. - Duplikat-Warnung: Disc-Fingerabdruck (jetzt Teil des Prescan-Ergebnisses + der Job-Metadaten) gegen die Historie; Karte zeigt 'bereits gerippt', Vollautomatik ueberspringt Duplikate. - 'Nur Hauptfilm' ECHT: makemkvcon info -> TINFO-Attr-9-Laufzeiten (usage.txt) -> laengster Titel -> mkv dev:X <nr>. Vorher wirkungsloses Setting; pro Rip im Dialog uebersteuerbar. Mit Tests. - OMDb-Treffer eingedeutscht via TMDB /find (external_source=imdb_id, de-DE; find-by-id-API). - Dashboard: Speicherplatz-Anzeige (amber < 60 GB) + CSV-Export (GET /jobs/export, Semikolon+BOM fuer deutsches Excel). - Metadaten-Seite entfernt (Abnahme durch Commander-Auftrag) inkl. Placebo-Endpoints /metadata/lookup (scannte Dummy-Device) und /metadata/confirm (schrieb nie gelesenen Cache-Key). - Doppel-Jahr-Fix: 'X (2009) (2009)' in Log und Ordnernamen. - Remote-Worker-Blocker: redis (6379) + postgres (5432) waren NIE veroeffentlicht — kein Remote-Worker konnte sich je verbinden. Ports jetzt offen (Heimnetz-Kompromiss, kommentiert) + API_URL fuer Worker. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
169 lines
8.1 KiB
Markdown
169 lines
8.1 KiB
Markdown
# Rippy — die All-in-one Disc-Ripping-Maschine
|
|
|
|
Disc rein → automatisch erkannt (Titel, Poster, Metadaten) → verlustfrei
|
|
gerippt (MakeMKV) → auf Arbeitsgröße komprimiert (HandBrake) → fertig
|
|
abgelegt, wo DU willst (lokal, NAS, jede Freigabe). Modernes Web-UI,
|
|
Echtzeit-Fortschritt, komplett in Docker, komplett lokal.
|
|
|
|
## Schnellstart
|
|
|
|
Voraussetzungen: Docker + Docker Compose, ein optisches Laufwerk am Host.
|
|
|
|
```bash
|
|
git clone <repo-url> rippy && cd rippy
|
|
cp .env.example .env # optional: API-Keys — geht auch später im UI
|
|
mkdir -p /srv/rippy/media # Ablage-Basis (anpassbar in docker-compose.yml)
|
|
docker compose up -d --build
|
|
```
|
|
|
|
Dann `http://<host>` öffnen — der **Einrichtungs-Assistent** startet beim
|
|
ersten Mal automatisch (API-Keys, Verarbeitung, erkannte Hardware).
|
|
|
|
### Laufwerk anpassen
|
|
|
|
Standard ist `/dev/sr0` (+ `/dev/sg1` für den Worker — MakeMKV spricht
|
|
Laufwerke über die SCSI-Generic-Schicht an). Andere Geräte? Lege eine
|
|
`docker-compose.override.yml` an:
|
|
|
|
```yaml
|
|
services:
|
|
api:
|
|
devices: ["/dev/sr1:/dev/sr0"]
|
|
worker:
|
|
devices: ["/dev/sr1:/dev/sr0", "/dev/sg2:/dev/sg1"]
|
|
```
|
|
|
|
Welche sg-Nummer dein Laufwerk hat, verrät `lsscsi -g` oder
|
|
`ls -la /sys/class/scsi_generic/`.
|
|
|
|
**Laufwerk in einer VM?** Per USB-Passthrough anhand der Vendor-ID
|
|
durchreichen (Proxmox: `qm set <vmid> -usb0 host=xxxx:yyyy,usb3=1`) —
|
|
NICHT als emuliertes CD-ROM (`media=cdrom`), das kann keine SCSI-Kommandos.
|
|
|
|
## Wie es funktioniert
|
|
|
|
1. **Disc-Wache** (ioctl-Polling, kein udev-Gefrickel) erkennt Einlegen,
|
|
identifiziert die Disc (Volume-Label → TMDB → OMDb-Fallback) und zeigt
|
|
sie mit Poster auf dem Dashboard. Klick auf einen Job-Titel öffnet die
|
|
Detail-Ansicht (Poster, Jahr, Beschreibung, Ablagepfad).
|
|
2. **Rip** (MakeMKV, verlustfrei — der einzige Weg durch AACS): Ziel wählst
|
|
du beim Start (Filme/Serien/Musik/eigener Pfad, inkl. Netzwerk-Ziele) —
|
|
oder du stellst die **Vollautomatik** an (Einstellungen → Ripping) und
|
|
der Rip startet ohne Nachfrage in den passenden Schnellwahl-Ordner.
|
|
Optional **nur Hauptfilm** (längster Titel, Extras bleiben weg). Bereits
|
|
gerippte Discs erkennt Rippy am Fingerabdruck und warnt. Vor dem Start
|
|
prüft Rippy den freien Platz gegen die Disc-Größe. Alle Tonspuren und
|
|
Untertitel bleiben erhalten (wichtig für Anime/O-Ton). Audio-CDs laufen
|
|
über abcde → FLAC + MusicBrainz.
|
|
**Serien**: Im Dialog „Serien" wählen → Serienname + Staffel angeben —
|
|
Ablage wird `<Serie>/Season NN`, und die Episoden werden nach dem Rip
|
|
per Laufzeitabgleich (TMDB) automatisch zu „Serie S01E02.mkv" benannt
|
|
(nur bei eindeutiger Zuordnung — sonst bleiben die Namen, mit Log).
|
|
3. **Kompression** (HandBrake, eigener Job auf eigener Queue): x265/x264,
|
|
Preset im UI wählbar; Rohdatei wird erst nach Erfolg gelöscht
|
|
(„Original behalten" als Option). Fehlgeschlagene Kompressionen lassen
|
|
sich ohne Neu-Rip neu anstoßen.
|
|
4. **Media-Server-Ablage**: Unter Einstellungen → Ripping (oder im
|
|
Einrichtungs-Assistenten) wählst du dein System — Jellyfin, Emby, Kodi,
|
|
Plex oder keins. Fertige Rips heißen dann „Titel (Jahr)" statt
|
|
Job-UUID; für Jellyfin/Emby/Kodi legt Rippy zusätzlich movie.nfo +
|
|
poster.jpg dazu (Kodi-NFO-Schema, lesen alle drei nativ). Plex nutzt
|
|
nur die Benennung. **Jellyfin/Emby**: Server-URL + API-Key eintragen,
|
|
dann stößt Rippy nach jedem fertigen Rip sofort einen Bibliotheks-Scan
|
|
an — Disc rein, Film erscheint im Server.
|
|
5. **4K-UHD**: braucht ein LibreDrive-fähiges Laufwerk (MakeMKV-Forum:
|
|
„Ultimate UHD Drives Flashing Guide"). Normale BD/DVD gehen mit jedem
|
|
Laufwerk. ⚠️ UHD-Rohdaten sind bis 100 GB groß — wenn die Platte der
|
|
Rippy-Maschine dafür zu klein ist, lege das **Arbeitsverzeichnis**
|
|
(Einstellungen → Verarbeitung) auf eine eingehängte Freigabe, z. B.
|
|
`/app/media/nas-arbeit`. Rippy bricht sonst VOR dem Rip mit einer
|
|
Klartext-Meldung ab statt nach 40 GB mit voller Platte.
|
|
|
|
## Speicherziele (NAS, Freigaben)
|
|
|
|
Unter **Einstellungen → Speicherziele** hängst du NFS- oder SMB-Freigaben
|
|
direkt aus dem UI ein — sie erscheinen sofort in der Ziel-Auswahl beim
|
|
Rippen und werden beim Start automatisch wieder verbunden.
|
|
Technik: der api-Container läuft mit `CAP_SYS_ADMIN` und einem
|
|
rshared-Bind auf `/srv/rippy/media`, Mounts propagieren zu allen
|
|
Containern. ⚠️ Zugangsdaten liegen unverschlüsselt in der lokalen
|
|
Postgres-DB — bewusster Heimnetz-Kompromiss; lege fürs NAS einen eigenen,
|
|
eingeschränkten Benutzer an.
|
|
|
|
## Benachrichtigungen
|
|
|
|
**Einstellungen → Benachrichtigungen**: eine Webhook-URL eintragen, „Test
|
|
senden" drücken, speichern — fertig. Rippy meldet Job-Ende (fertig,
|
|
fehlgeschlagen, abgebrochen) und erkennt den Dienst an der URL selbst:
|
|
|
|
| Dienst | URL-Beispiel | Format |
|
|
|---|---|---|
|
|
| Discord | `https://discord.com/api/webhooks/…` | `{"content": …}` |
|
|
| Slack | `https://hooks.slack.com/services/…` | `{"text": …}` |
|
|
| ntfy (Handy-Push) | `https://ntfy.sh/mein-geheimes-thema` | Roh-Text + Titel |
|
|
| Eigenes (HA, n8n, …) | beliebige HTTPS-URL | `{"title","message","level"}` |
|
|
|
|
## System & MakeMKV-Beta-Key
|
|
|
|
**Einstellungen → System** zeigt die Werkzeug-Versionen jedes Workers
|
|
(MakeMKV, HandBrake), den Key-Status und den freien Speicherplatz. Der
|
|
MakeMKV-Beta-Key (wechselt ~monatlich, Forum-Thread t=1053) wird hier im
|
|
UI eingetragen und gilt ab dem **nächsten Rip** — ohne Rebuild, ohne
|
|
Neustart; er schlägt den Key aus der `.env`. Nur die MakeMKV-*Version*
|
|
steckt im Image: `docker compose build worker && docker compose up -d worker`.
|
|
|
|
## Verarbeitung & Hardware
|
|
|
|
**Einstellungen → Verarbeitung** zeigt ehrlich an, welche Encoder deine
|
|
Worker WIRKLICH haben (CPU x264/x265, VAAPI bei AMD/Intel-GPU, NVENC bei
|
|
NVIDIA) — jeder Worker meldet seine Fähigkeiten selbst beim Start.
|
|
|
|
### Optional: GPU-Maschine im Netz als Transcode-Worker
|
|
|
|
Die Kompression läuft als eigener Celery-Task auf der Queue `transcode` —
|
|
JEDE Maschine im Netz kann sie übernehmen (siehe
|
|
`deploy/remote-transcode-worker.yml`). Ohne Zusatz-Worker macht der
|
|
eingebaute CPU-Worker alles selbst — Rippy bleibt All-in-one.
|
|
|
|
## Umgebungsvariablen (.env)
|
|
|
|
| Variable | Pflicht | Zweck |
|
|
|---|---|---|
|
|
| `TMDB_API_KEY` | empfohlen | Metadaten (deutsche Texte) — alternativ im UI/Wizard; beide Key-Arten gehen (v3-Schlüssel und v4-Token) |
|
|
| `WORKER_NAME` | optional | Anzeigename des eingebauten Workers (Standard: rippy-hauptworker) |
|
|
| `OMDB_API_KEY` | optional | zweite Metadaten-Quelle (Fallback) |
|
|
| `THETVDB_API_KEY` | optional | Serien-Fallback |
|
|
| `MAKEMKV_APP_KEY` | optional | MakeMKV-Beta-Key (Forum); DVDs gehen ohne — bequemer: im UI unter Einstellungen → System pflegen |
|
|
| `MAKEMKV_URL_BASE` | optional | alternative Download-Quelle für den Image-Build |
|
|
|
|
UI-Einstellungen (Wizard/Settings) überstimmen die Env-Variablen.
|
|
|
|
## Rippy woanders bereitstellen
|
|
|
|
Rippy ist reines Docker Compose — es läuft auf **jedem Linux-Host mit
|
|
Docker**, nicht nur auf der Original-VM. Es gibt (noch) keine fertigen
|
|
Registry-Images; gebaut wird beim ersten `up` direkt aus dem Repo.
|
|
|
|
Voraussetzungen auf dem Ziel-Host:
|
|
1. Linux (x86_64) mit Docker + Compose-Plugin.
|
|
2. Ein optisches Laufwerk, das der Host sieht (`ls /dev/sr* /dev/sg*`).
|
|
In einer VM: per **USB-Passthrough** (Vendor-ID) durchreichen, NICHT
|
|
als emuliertes CD-ROM — siehe „Laufwerk anpassen" oben.
|
|
3. Ablage-Basis anlegen: `mkdir -p /srv/rippy/media` (oder Pfad in
|
|
`docker-compose.yml` anpassen — muss ein rshared-fähiger Bind sein).
|
|
|
|
Dann wie im Schnellstart: klonen, `.env` füllen, `docker compose up -d
|
|
--build`, `http://<host>` öffnen — der Einrichtungs-Assistent führt durch
|
|
den Rest (API-Keys, Media-Server, Verarbeitung). Updates: `git pull &&
|
|
docker compose up -d --build`.
|
|
|
|
Nicht mitnehmen musst du: Gitea, Arcane, den CI-Runner — das ist die
|
|
Entwicklungs-Infrastruktur DIESER Installation, nicht Teil von Rippy.
|
|
|
|
## Entwicklung
|
|
|
|
CI („Ampel") läuft bei jedem Push: Ruff, pytest, Vite-Build. Grün auf
|
|
`main` wird automatisch auf `stable` befördert — deploye von `stable`.
|
|
Regeln für Beiträge: [AGENTS.md](AGENTS.md) · Konzept: [KONZEPT.md](KONZEPT.md) ·
|
|
Fahrplan: [ROADMAP.md](ROADMAP.md)
|