Track-Auswahl-Tabelle, nativer Windows-Worker (via UI angeboten), Anleitungs-Tab
Ampel / ampel (push) Successful in 29s
Ampel / ampel (push) Successful in 29s
Volle Titel-Auswahl vor dem Rip (Etappe-12-Rest):
- worker.tasks.scan_tracks: makemkvcon info -> Titel-Liste (Dauer/Groesse/
Kapitel, apdefs-Attr 8/9/11) in die settings-Tabelle 'tracks:<device>';
API: POST /devices/{n}/scan-tracks + GET /devices/{n}/tracks (Polling).
- Rip-Dialog: 'Disc scannen' -> Tabelle mit Checkboxen, Vorauswahl ab
5 min, Groessen-Summe; gewaehlte Titel als meta.titles in den Job.
- rip_titel_auswahl: ein makemkvcon-Aufruf je Titel (mkv kann nur einen
Titel oder all), Fortschritt anteilig. Parser-Tests dabei.
Nativer Windows-Worker OHNE Docker (Commander-Wunsch):
- Die Rippy-Instanz versorgt sich selbst: GET /worker-setup/windows
liefert install.ps1, /worker-setup/paket den Worker-Code als Zip
(api-Dockerfile kopiert docker/worker/*.py als worker_dist/ ins Image).
- install.ps1: Python-Check, venv + requirements, HandBrakeCLI 1.9.2 vom
offiziellen GitHub-Release (URL per HEAD verifiziert), start-worker.bat
mit celery -Q transcode --pool=solo (Celery-Doku: Windows nur solo),
optional -Autostart via schtasks onlogon.
- tasks.py laedt jetzt auch ohne fcntl (Import-Guard) — rip_disc ist auf
solchen Workern hart verriegelt (Klartext-Fehler statt Crash).
- Einstellungen -> Worker: Varianten-Umschalter Linux(Docker)/Windows(nativ)
mit passenden Copy-Paste-Befehlen.
Anleitungs-Tab: Rippy erklaert sich selbst (Disc-Weg, Serien, NAS,
Media-Server, Benachrichtigungen, Key, Worker, Downloads, FAQ).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,162 @@
|
||||
import { ReactNode } from 'react'
|
||||
import { BookOpen, Disc, Tv, HardDrive, Bell, Wrench, Cpu, Download, HelpCircle } from 'lucide-react'
|
||||
import { useDarkMode } from '../context/ThemeContext'
|
||||
|
||||
// Anleitungs-Tab (Commander-Wunsch 24.07.): Rippy erklärt sich selbst —
|
||||
// keine externen Wikis, keine README-Suche. Reiner Text, keine API-Aufrufe.
|
||||
|
||||
function Abschnitt({ icon: Icon, titel, children }: { icon: any, titel: string, children: ReactNode }) {
|
||||
const { theme } = useDarkMode()
|
||||
return (
|
||||
<section className={`rounded-xl border p-6 ${theme === 'dark' ? 'bg-slate-800 border-slate-700' : 'bg-white border-slate-200'}`}>
|
||||
<h2 className={`text-lg font-semibold mb-3 flex items-center gap-2 ${theme === 'dark' ? 'text-slate-100' : 'text-slate-900'}`}>
|
||||
<Icon size={20} className={theme === 'dark' ? 'text-indigo-400' : 'text-indigo-600'} />
|
||||
{titel}
|
||||
</h2>
|
||||
<div className={`space-y-2 text-sm leading-relaxed ${theme === 'dark' ? 'text-slate-300' : 'text-slate-600'}`}>
|
||||
{children}
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
export default function AnleitungPage() {
|
||||
const { theme } = useDarkMode()
|
||||
const fett = theme === 'dark' ? 'text-slate-100 font-medium' : 'text-slate-900 font-medium'
|
||||
|
||||
return (
|
||||
<div className="space-y-6 max-w-4xl transition-colors duration-300">
|
||||
<div className="flex flex-col gap-2">
|
||||
<h1 className={`text-3xl font-bold ${theme === 'dark' ? 'text-slate-100' : 'text-slate-900'}`}>Anleitung</h1>
|
||||
<p className={`text-sm ${theme === 'dark' ? 'text-slate-400' : 'text-slate-500'}`}>
|
||||
So funktioniert Rippy — vom Einlegen bis zum fertigen Film in deinem Media-Server.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<Abschnitt icon={Disc} titel="Der normale Weg: Disc rein, fertig">
|
||||
<p>
|
||||
<span className={fett}>1. Disc einlegen.</span> Rippy erkennt sie automatisch (Titel, Poster,
|
||||
Beschreibung) und zeigt sie oben im Dashboard. Stimmt der Titel nicht → „Nicht korrekt?"
|
||||
klicken und den richtigen wählen — Rippy merkt sich das für diese Disc.
|
||||
</p>
|
||||
<p>
|
||||
<span className={fett}>2. „Rippen starten"</span> und das Ziel wählen: 🎥 Filme, 📺 Serien,
|
||||
🎵 Musik oder ein eigener Ordner (auch NAS-Freigaben). Optional: „Nur Hauptfilm" (längster
|
||||
Titel) oder per <span className={fett}>„Disc scannen"</span> einzelne Titel an-/abwählen.
|
||||
</p>
|
||||
<p>
|
||||
<span className={fett}>3. Warten.</span> Rippy sichert verlustfrei (MakeMKV) und komprimiert
|
||||
danach auf Arbeitsgröße (HandBrake) — alle Tonspuren und Untertitel bleiben erhalten.
|
||||
Fertige Jobs haben einen Download-Knopf; Klick auf den Titel zeigt alle Details.
|
||||
</p>
|
||||
<p>
|
||||
<span className={fett}>Vollautomatik:</span> Unter Einstellungen → Ripping einschaltbar —
|
||||
dann startet der Rip ohne Nachfrage, sobald eine Disc erkannt wurde. Bereits gerippte
|
||||
Discs (Fingerabdruck) werden übersprungen.
|
||||
</p>
|
||||
</Abschnitt>
|
||||
|
||||
<Abschnitt icon={Tv} titel="Serien rippen">
|
||||
<p>
|
||||
Im „Rippen starten"-Dialog <span className={fett}>„Serien"</span> wählen, Serienname und
|
||||
Staffel angeben. Die Ablage wird automatisch <code>Serie/Season 02/…</code>, und nach dem
|
||||
Rip ordnet Rippy die Episoden über einen Laufzeit-Abgleich mit TMDB zu und benennt sie
|
||||
(„Serie S02E03.mkv"). Das passiert nur bei <span className={fett}>eindeutiger</span> Zuordnung —
|
||||
im Zweifel bleiben die Original-Namen und das Log sagt warum.
|
||||
</p>
|
||||
<p>
|
||||
Eine komplette Staffel auf einer Disc klappt auch, wenn alle Episoden gleich lang sind
|
||||
(Anime-Boxen). Bei Teil-Discs mit lauter gleich langen Episoden ist eine automatische
|
||||
Zuordnung prinzipiell nicht möglich — dann von Hand umbenennen.
|
||||
</p>
|
||||
</Abschnitt>
|
||||
|
||||
<Abschnitt icon={HardDrive} titel="NAS & Speicherziele">
|
||||
<p>
|
||||
Einstellungen → Speicherziele: Rechner/NAS eintragen, <span className={fett}>Benutzer +
|
||||
Passwort</span> angeben (Windows und die meisten NAS lehnen Gast-Zugriffe ab!), „Freigaben
|
||||
auflisten", Freigabe wählen, „Einhängen & speichern". Danach taucht das Ziel im
|
||||
„Rippen starten"-Dialog auf und wird beim Start automatisch wieder verbunden.
|
||||
</p>
|
||||
<p>
|
||||
<span className={fett}>4K-UHD-Tipp:</span> Rohdaten sind bis 100 GB groß. Wenn die
|
||||
Rippy-Platte knapp ist (Dashboard zeigt den freien Platz), das Arbeitsverzeichnis unter
|
||||
Einstellungen → Verarbeitung auf eine große Freigabe legen. Rippy prüft den Platz vor
|
||||
jedem Rip und bricht sonst mit Klartext ab.
|
||||
</p>
|
||||
</Abschnitt>
|
||||
|
||||
<Abschnitt icon={Tv} titel="Jellyfin, Emby, Kodi, Plex">
|
||||
<p>
|
||||
Einstellungen → Ripping → Media-Server: Rippy benennt fertige Rips als „Titel (Jahr)" und
|
||||
legt für Jellyfin/Emby/Kodi zusätzlich <code>movie.nfo</code> + <code>poster.jpg</code> dazu —
|
||||
dein Server erkennt alles ohne Nacharbeit (Plex nutzt nur die Benennung).
|
||||
</p>
|
||||
<p>
|
||||
<span className={fett}>Null-Klick-Kette:</span> Bei Jellyfin/Emby zusätzlich Server-URL und
|
||||
API-Key eintragen (Administration → API-Schlüssel) — dann stößt Rippy nach jedem fertigen
|
||||
Rip sofort einen Bibliotheks-Scan an. Disc rein → Film erscheint im Server.
|
||||
</p>
|
||||
</Abschnitt>
|
||||
|
||||
<Abschnitt icon={Bell} titel="Benachrichtigungen">
|
||||
<p>
|
||||
Einstellungen → Benachrichtigungen: eine Webhook-URL eintragen (Discord-Webhook, ntfy-Thema
|
||||
für Handy-Push, Slack oder eigenes JSON), „Test senden", speichern. Rippy meldet sich, wenn
|
||||
ein Job fertig ist, fehlschlägt oder abgebrochen wird. Die Schritt-für-Schritt-Anleitung je
|
||||
Dienst steht direkt auf der Einstellungs-Seite.
|
||||
</p>
|
||||
</Abschnitt>
|
||||
|
||||
<Abschnitt icon={Cpu} titel="Weitere Maschinen als Encoding-Worker">
|
||||
<p>
|
||||
Die Kompression kann jede Maschine im Netz übernehmen — Einstellungen → Worker zeigt für
|
||||
<span className={fett}> Linux (Docker)</span> und <span className={fett}>Windows (nativ,
|
||||
ohne Docker — nur Python nötig)</span> je einen Copy-Paste-Befehl. Die Maschine taucht
|
||||
danach unter ihrem Namen in der Worker-Liste auf und zieht sich Kompressions-Jobs
|
||||
automatisch. Gerippt wird immer auf der Rippy-Hauptmaschine (dort hängt das Laufwerk).
|
||||
</p>
|
||||
</Abschnitt>
|
||||
|
||||
<Abschnitt icon={Wrench} titel="MakeMKV-Beta-Key & System">
|
||||
<p>
|
||||
Blu-ray-Ripping braucht den MakeMKV-Beta-Key, der etwa <span className={fett}>monatlich
|
||||
wechselt</span> (MakeMKV-Forum, Thread „MakeMKV is free while in beta"). Neuen Key unter
|
||||
Einstellungen → System eintragen — gilt ab dem nächsten Rip, ohne Neustart. DVDs gehen
|
||||
immer auch ohne Key. Dort stehen auch die Werkzeug-Versionen und der freie Speicherplatz.
|
||||
</p>
|
||||
</Abschnitt>
|
||||
|
||||
<Abschnitt icon={Download} titel="Fertige Dateien herunterladen">
|
||||
<p>
|
||||
Bei fertigen Jobs: „Download" in der Aktion-Spalte (oder Klick auf den Titel) → Dateiliste
|
||||
mit „Alle herunterladen". Die Job-Liste lässt sich per Papierkorb bzw. „Erledigte aufräumen"
|
||||
leeren — <span className={fett}>die gerippten Dateien bleiben dabei immer liegen</span>.
|
||||
„CSV" exportiert die komplette Historie für Excel.
|
||||
</p>
|
||||
</Abschnitt>
|
||||
|
||||
<Abschnitt icon={HelpCircle} titel="Häufige Fragen">
|
||||
<p>
|
||||
<span className={fett}>„Diese Disc wurde bereits gerippt"?</span> Rippy erkennt Discs am
|
||||
Fingerabdruck. Nochmal rippen geht trotzdem — der Hinweis verhindert nur Versehen.
|
||||
</p>
|
||||
<p>
|
||||
<span className={fett}>4K-UHD schlägt fehl mit „volume key is unknown"?</span> Das Laufwerk
|
||||
liest die Disc (LibreDrive), aber MakeMKV kennt den Schlüssel dieser (zu neuen) Pressung
|
||||
noch nicht. Den automatisch gespeicherten AACS-Dump im MakeMKV-Forum einreichen — mit einem
|
||||
der nächsten Updates ist die Disc rippbar.
|
||||
</p>
|
||||
<p>
|
||||
<span className={fett}>„Neu komprimieren" fehlt bei einem Fehl-Job?</span> Der Knopf
|
||||
erscheint nur, wenn die Rohdaten noch daliegen — bei einem Job, der nie gerippt hat, gäbe
|
||||
es nichts zu komprimieren.
|
||||
</p>
|
||||
<p>
|
||||
<span className={fett}>Kein Laufwerk sichtbar?</span> In einer VM muss das Laufwerk per
|
||||
USB-Passthrough durchgereicht sein (nicht als emuliertes CD-ROM) — Details in der README.
|
||||
</p>
|
||||
</Abschnitt>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user