Files
rippy/README.md
T
Hitonabi 5778ac4645
Ampel / ampel (push) Successful in 29s
Praxis-Feedback-Runde: CIFS-Cap-Fix, TMDB v3-Keys, 4K-UHD-Typ, Vollautomatik, Job-Verwaltung, Worker-Namen
Zwei bewiesene Bug-Fixes:
- SMB-Mount 'Unable to apply new capability set': mount.cifs hebt
  CAP_DAC_READ_SEARCH an, die in Dockers Default-Caps fehlt (auf der VM
  reproduziert: Bounding-Set a82425fb ohne Bit 2; mit der Capability
  verschwindet der Fehler). Fix: cap_add DAC_READ_SEARCH fuer den
  api-Container.
- TMDB fiel still aus: Client konnte nur v4-Bearer-Tokens, der uebliche
  32-Hex-v3-Key bekam 401 und die Suche lieferte nur OMDb. Jetzt beide
  Key-Arten (ist_v4_token + api_key-Query-Param lt.
  developer.themoviedb.org, mit Tests) — damit kommen auch die deutschen
  Texte an (language=de-DE war ueberall schon gesetzt). Neu:
  GET /metadata/status + 'Verbindung pruefen' in Einstellungen -> APIs
  (Live-Check am Cache vorbei).

Features aus dem Commander-Feedback:
- 4K UHD als eigener Disc-Typ: classify >= 55 GiB (BD-66/BD-100; BD-50
  bleibt bluray), beide detection.py + Tests, eigene Badge-Farbe in
  Dashboard/Laufwerken, Prescan-Label '4K UHD'. UHD-Rip-Fehler 'Failed to
  open disc' (Code 11) bekommt Klartext: LibreDrive-Firmware noetig.
- Vollautomatik (Setting autoRipStart): Disc erkannt -> Rip startet ohne
  Popup in den Schnellwahl-Ordner (Serie->Serien, sonst Filme, CD->Musik).
- Job-Verwaltung: 'Neu komprimieren' nur noch mit can_retry (Rohdaten
  liegen wirklich da), DELETE /jobs/{id} + 'Erledigte aufraeumen'
  (Dateien bleiben immer), 'Alle herunterladen' im Job-Detail
  (gestaffelte Einzel-Downloads statt Server-Zip von 40-GB-Dateien).
- Worker zuordenbar: WORKER_NAME-Env als stabiler Anzeigename (fixt auch
  die Offline-Leichen nach Rebuilds), info.hostname/ip gemeldet,
  Online-Abgleich ueber hostname, DELETE /workers/{name} + Papierkorb im
  UI, Quelle-Anzeige an der Disc-Karte ('Quelle: TMDB - 99 % sicher').
- Ripping-Tab nach Medium gegliedert (Video/Audio-CD/Allgemein) +
  Untertitel-Klartext (--all-audio/--all-subtitles bleiben komplett),
  CD -> Musik-Vorauswahl im Ziel-Dialog, Ordner-Verwaltung beschriftet
  und standardmaessig eingeklappt.
- Docs: SAVEPOINT v3.3, ROADMAP Etappe 14 + Ideen (nativer
  Windows-Worker, deutsche OMDb-Texte via TMDB-Find), README.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 13:29:10 +02:00

162 lines
7.6 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 # JWT_SECRET_KEY eintragen (openssl rand -hex 32)
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.
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.
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.
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 |
|---|---|---|
| `JWT_SECRET_KEY` | ✔ | Signierschlüssel (openssl rand -hex 32) |
| `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)