Universal-Sprint: Wizard, UI-Mounts, Encoder-Erkennung, Task-Split, README
Ampel / ampel (push) Successful in 29s
Ampel / ampel (push) Successful in 29s
Commander-Ziel: All-in-one, universell, weitergebbar.
- First-Run-Wizard: startet automatisch bei neuer Installation (Keys,
Verarbeitung, erkannte Hardware); /setup + /setup/complete
- Data-Mounts via UI: Einstellungen -> Speicherziele haengt NFS/SMB direkt
ein (mounts.py, CAP_SYS_ADMIN + rshared-Propagation, Auto-Remount beim
Start, CIFS-Creds via Datei statt Kommandozeile); nfs-common/cifs-utils
im api-Image
- Encoder-Erkennung: jeder Worker meldet beim Start ehrlich seine
Faehigkeiten (caps.py -> workers-Tabelle), GET /capabilities, Anzeige
in Wizard + Verarbeitung-Tab
- Task-Split: transcode_files als eigener Task auf Queue "transcode"
(Basis fuer optionale Remote-GPU-Worker, deploy/remote-transcode-worker.yml
EXPERIMENTELL) + POST /jobs/{id}/retry-transcode + UI-Knopf
"Neu komprimieren" bei fehlgeschlagenen Jobs
- API-Keys aus der DB: Settings-UI/Wizard ueberstimmen Env — vorher waren
die Key-Felder im UI reine Dekoration (Clients lasen nur Env)
- README komplett neu: generischer Schnellstart, Laufwerk-Override via
docker-compose.override.yml, Architektur, Env-Tabelle
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,119 +1,101 @@
|
||||
# README — Rippy
|
||||
# Rippy — die All-in-one Disc-Ripping-Maschine
|
||||
|
||||
> **Moderner Ripping-Daemon mit Metadaten-Preview, Jellyfin-Formatierung und JWT-Auth.**
|
||||
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
|
||||
|
||||
## Features
|
||||
|
||||
| Feature | Status |
|
||||
|---------|--------|
|
||||
| Disc-Erkennung (CD/DVD/Blu-ray) | ✅ |
|
||||
| Metadaten-Lookup (TMDB/MusicBrainz/TheTVDB) | ✅ |
|
||||
| Pre-Scan ohne Ripping | ✅ |
|
||||
| Jellyfin-Formatierung (NFO + Images) | ✅ |
|
||||
| JWT-Auth + Rate-Limiting | ✅ |
|
||||
| React-UI mit Dashboard | ✅ |
|
||||
| SQLite-Cache für API-Rate-Limits | ✅ |
|
||||
| Multi-Disc-Set-Handling | ✅ |
|
||||
|
||||
---
|
||||
|
||||
## Architektur
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ Proxmox LXC (Debian 12) │
|
||||
│ │
|
||||
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
||||
│ │ API │ │ Worker │ │ UI │ │
|
||||
│ │ FastAPI │◄─►│ Celery+ │ │ React+ │ │
|
||||
│ │ │ │ Redis │ │ Nginx │ │
|
||||
│ └──────────┘ └──────────┘ └──────────┘ │
|
||||
│ │ │ │ │
|
||||
│ ▼ ▼ ▼ │
|
||||
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
||||
│ │ PostgreSQL│ │ udev │ │ Media │ │
|
||||
│ │ │ │ Daemon │ │ Store │ │
|
||||
│ └──────────┘ └──────────┘ └──────────┘ │
|
||||
└─────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Installation
|
||||
|
||||
### Docker Compose
|
||||
Voraussetzungen: Docker + Docker Compose, ein optisches Laufwerk am Host.
|
||||
|
||||
```bash
|
||||
git clone https://git.tobisniceshomelab.ddnsfree.com/Hitonabi/rippy.git
|
||||
cd rippy
|
||||
docker compose up -d
|
||||
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
|
||||
```
|
||||
|
||||
### Port-Übersicht
|
||||
Dann `http://<host>` öffnen — der **Einrichtungs-Assistent** startet beim
|
||||
ersten Mal automatisch (API-Keys, Verarbeitung, erkannte Hardware).
|
||||
|
||||
| Service | Port | URL |
|
||||
|---------|------|-----|
|
||||
| UI | 80 | http://localhost:80 |
|
||||
| API | 8000 | http://localhost:8000 |
|
||||
| PostgreSQL | 5432 | localhost:5432 |
|
||||
| Redis | 6379 | localhost:6379 |
|
||||
### 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:
|
||||
|
||||
## API
|
||||
```yaml
|
||||
services:
|
||||
api:
|
||||
devices: ["/dev/sr1:/dev/sr0"]
|
||||
worker:
|
||||
devices: ["/dev/sr1:/dev/sr0", "/dev/sg2:/dev/sg1"]
|
||||
```
|
||||
|
||||
### Endpoints
|
||||
Welche sg-Nummer dein Laufwerk hat, verrät `lsscsi -g` oder
|
||||
`ls -la /sys/class/scsi_generic/`.
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
|----------|--------|-------------|
|
||||
| `/health` | GET | Health check |
|
||||
| `/jobs` | GET | Alle Jobs |
|
||||
| `/devices` | GET | Alle Geräte |
|
||||
| `/prescan` | POST | Pre-Scan durchführen |
|
||||
| `/metadata/lookup` | POST | Metadaten lookup |
|
||||
| `/metadata/confirm` | POST | Metadaten bestätigen |
|
||||
| `/jellyfin/format` | POST | Für Jellyfin formatieren |
|
||||
| `/token` | POST | Login (JWT) |
|
||||
| `/token/refresh` | POST | Refresh Token |
|
||||
| `/api-keys` | POST/GET/DELETE | API-Key Management |
|
||||
**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
|
||||
|
||||
## Tech-Stack
|
||||
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.
|
||||
2. **Rip** (MakeMKV, verlustfrei — der einzige Weg durch AACS): Ziel wählst
|
||||
du beim Start (Filme/Serien/Musik/eigener Pfad, inkl. Netzwerk-Ziele).
|
||||
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. **4K-UHD**: braucht ein LibreDrive-fähiges Laufwerk (MakeMKV-Forum:
|
||||
„Ultimate UHD Drives Flashing Guide"). Normale BD/DVD gehen mit jedem
|
||||
Laufwerk.
|
||||
|
||||
| Layer | Tech |
|
||||
|-------|------|
|
||||
| Backend | Python, FastAPI, Celery |
|
||||
| Database | PostgreSQL, SQLite, Redis |
|
||||
| Frontend | React, Vite, TailwindCSS |
|
||||
| Ripping | MakeMKV, abcde, FFmpeg, HandBrake |
|
||||
| Auth | JWT, OAuth2 |
|
||||
## 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.
|
||||
|
||||
## Roadmap
|
||||
## Verarbeitung & Hardware
|
||||
|
||||
- [x] Etappe 1: Container-Infrastruktur
|
||||
- [x] Etappe 2: Ripping-Pipeline
|
||||
- [x] Etappe 3: Metadaten-Lookup + Pre-Scan
|
||||
- [x] Etappe 4: Jellyfin-Formatierung
|
||||
- [x] Etappe 5: API + Auth + WebUI
|
||||
- [x] Etappe 6: Sicherheit + Compliance
|
||||
- [x] Etappe 7: API UI Modernisiert
|
||||
- [x] Etappe 8: Dark Mode & Separation of Concerns
|
||||
- [ ] Etappe 9: Proxmox-Integration
|
||||
**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
|
||||
|
||||
## License
|
||||
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.
|
||||
|
||||
GPL-v3
|
||||
## Umgebungsvariablen (.env)
|
||||
|
||||
---
|
||||
| Variable | Pflicht | Zweck |
|
||||
|---|---|---|
|
||||
| `JWT_SECRET_KEY` | ✔ | Signierschlüssel (openssl rand -hex 32) |
|
||||
| `TMDB_API_KEY` | empfohlen | Metadaten — alternativ im UI/Wizard eintragbar |
|
||||
| `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 |
|
||||
| `MAKEMKV_URL_BASE` | optional | alternative Download-Quelle für den Image-Build |
|
||||
|
||||
## Credits
|
||||
UI-Einstellungen (Wizard/Settings) überstimmen die Env-Variablen.
|
||||
|
||||
- **Commander**: Projekt-Idee, Anforderungen, Testing
|
||||
- **AI-Box**: Entwicklung, Architektur, Dokumentation
|
||||
## 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)
|
||||
|
||||
Reference in New Issue
Block a user