Commit Graph

42 Commits

Author SHA1 Message Date
Hitonabi b130eeb967 feat(ui): Master-Panel 'Ripping Operations' DIREKT unter Laufwerke verschoben
Ampel / ampel (push) Successful in 28s
2026-07-24 16:44:33 +02:00
Hitonabi bf80f9dfd4 refactor(ui): Current Job, Ripping Queue und Job-Historie in ein einziges Master-Panel bündig unter Laufwerke zusammengeführt
Ampel / ampel (push) Successful in 27s
2026-07-24 16:43:10 +02:00
Hitonabi e0864828c2 style(ui): Ripping Queue Kachel per flex-1 vertikal gestreckt fuer exakt buendigen unteren Abschluss mit Recently Ripped
Ampel / ampel (push) Successful in 28s
2026-07-24 16:41:26 +02:00
Hitonabi 60abf42359 feat(ui): Laufwerke & im Laufwerk erkannte Disc nach ganz oben verschoben, Ripping Queue exakt nach SC1 aufgebaut
Ampel / ampel (push) Successful in 28s
2026-07-24 16:39:56 +02:00
Hitonabi e18315814c feat(ui): 5-Kachel-Banner ohne schwarze Loecher gefuellt, Vollstaendige Job-Tabelle mit TMDB-Beschreibungen wiederhergestellt
Ampel / ampel (push) Successful in 28s
2026-07-24 16:36:12 +02:00
Hitonabi 9b19b74d39 fix(ui): 100% Dark Mode erzwungen (White Mode entfernt), Echte API-Daten fuer Server Status gebunden & Tabs-Breite/Scrollbalken behoben
Ampel / ampel (push) Successful in 28s
2026-07-24 16:33:50 +02:00
Hitonabi 9bc8ad11b2 fix(ui): Zentrierung fuer Anleitung & Einstellungen gefixt, zufaellige Mockup-Filme durch echte API-Daten ersetzt
Ampel / ampel (push) Successful in 28s
2026-07-24 16:31:45 +02:00
Hitonabi 0f20d9d8f4 feat(ui): Rebuild Layout EXACTLY 1:1 matching SC1 Mockup (Top Header Nav, 5-Panel Movie Wall, 2-Column Dashboard Grid with Sparkline & Recently Ripped)
Ampel / ampel (push) Successful in 28s
2026-07-24 16:25:21 +02:00
Hitonabi f0a8455fc2 style(ui): Visuelle Hero Showcase Banner & Poster Cards Grid auf dem Dashboard
Ampel / ampel (push) Successful in 28s
2026-07-24 16:22:40 +02:00
Hitonabi 3643f74eb1 style(ui): Visuelles High-End Overhaul fuer Cinematic Cinema OS (3D Spin-Disc, Hero Banner, Radial Gauges & Poster Grid)
Ampel / ampel (push) Successful in 27s
2026-07-24 16:18:58 +02:00
Hitonabi bd00d4c728 refactor(ui): Dashboard, DeviceDiscovery & Settings auf Cinematic Cinema OS umgestellt
Ampel / ampel (push) Successful in 27s
2026-07-24 16:04:50 +02:00
Hitonabi 90b708302e refactor(ui): Modals & Unterseiten auf Primitives & dark: umgestellt 2026-07-24 16:04:46 +02:00
Hitonabi 7004d798d6 feat(ui): Primitives & Design Tokens fuer Cinematic Cinema OS 2026-07-24 16:04:41 +02:00
Hitonabi 404a002d5c Windows-Worker: Tray-Symbol + rueckstandsfreie Deinstallation
Ampel / ampel (push) Successful in 27s
- tray.py (nur nativer Windows-Worker; Docker unberuehrt): pystray+Pillow-
  Tray neben der Uhr — Status, Worker starten/stoppen, Rippy oeffnen,
  Log anzeigen, Beenden (stoppt den Worker mit). Celery laeuft als
  Kind-Prozess ohne Konsolenfenster (CREATE_NO_WINDOW), Log in worker.log.
- install.ps1 erzeugt jetzt start-tray.bat (pythonw, empfohlen),
  start-worker.bat (Konsole/Debug) und uninstall.ps1: stoppt alle
  Prozesse aus dem Ordner, loescht die Autostart-Aufgabe, meldet den
  Worker per DELETE /workers/{name} in Rippy ab und entfernt den Ordner
  komplett. -Autostart registriert die Tray-Variante (onlogon).
- UI-Beschreibung + Anleitung entsprechend ergaenzt.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 15:44:29 +02:00
Hitonabi 3987c31b1e Update-Check im System-Tab, Worker-Adressfeld mit Heimnetz-Warnung, Save-Knopf raus aus dem Worker-Tab
Ampel / ampel (push) Successful in 28s
1. Update-Erkennung (Commander-Frage 'wie kriegen wir Updates mit?'):
   GET /system/updates vergleicht installierte Versionen (Worker-Info) mit
   makemkv.com (Versionsnummer der Download-Seite) und der HandBrake-
   GitHub-Release-API (releases/latest), 12 h gecacht. Einstellungen ->
   System: 'Auf Updates prüfen' + fertiger Update-Befehl bei MakeMKV.
   Selbst-Update gibt es bewusst NICHT (waere Docker-Socket-Zugriff);
   dafuer ist MAKEMKV_VERSION jetzt per .env uebersteuerbar — Update ohne
   Code-Aenderung. HandBrake-Abweichung wird als Info dargestellt
   (Debian-Paket hinkt der offiziellen Version bewusst hinterher).
2. Worker-Anbindung: editierbares Adressfeld statt stillschweigend
   window.location.hostname — Befund: ueber die externe Domain kopierte
   Befehle liefen in den Reverse-Proxy (401) und Worker koennen Redis/
   Postgres eh nur im Heimnetz erreichen. Amber-Warnung bei oeffentlich
   aussehender Adresse, Anleitung ergaenzt.
3. 'Einstellungen speichern' ist im Worker-Tab ausgeblendet — dort gibt
   es nichts zu speichern, der Knopf verwirrte nur.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 15:39:20 +02:00
Hitonabi 76b4286ad3 Windows-Worker: Pfad-Mapping fuer echte Transcodes + leere-Titel-Meldung + E2E-Beweis dokumentiert
Ampel / ampel (push) Successful in 27s
- pfad_lokal (tasks.py, mit Tests): RIPPY_PATH_MAP uebersetzt
  Container-Pfade (/app/temp, /app/media) auf Netzlaufwerke des nativen
  Workers — ohne Mapping unveraendert (Docker-Worker).
- Rip-Dialog: 'done' mit 0 Titeln bekommt Klartext (Disc vermutlich
  nicht entschluesselbar) statt leerer Tabelle.
- SAVEPOINT: E2E-Beweis des nativen Windows-Workers dokumentiert
  (test-windows-nativ online, HandBrake 1.9.2, echte LAN-IP).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 15:29:56 +02:00
Hitonabi 3a4eb25392 Track-Auswahl-Tabelle, nativer Windows-Worker (via UI angeboten), Anleitungs-Tab
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>
2026-07-24 15:18:08 +02:00
Hitonabi 8eb5653848 Restefeger: Auth komplett raus, Serien-Flow + Episoden-Matching, Jellyfin-Refresh, Duplikat-Warnung, echtes Nur-Hauptfilm
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>
2026-07-24 14:22:19 +02:00
Hitonabi 5778ac4645 Praxis-Feedback-Runde: CIFS-Cap-Fix, TMDB v3-Keys, 4K-UHD-Typ, Vollautomatik, Job-Verwaltung, Worker-Namen
Ampel / ampel (push) Successful in 29s
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
Hitonabi ab75134931 feat: Download-Knopf fuer fertige Rips — Dateien direkt im Browser statt scp
Ampel / ampel (push) Successful in 29s
- GET /jobs/{id}/files: Dateiliste aus job.output_path (Name + Groesse)
- GET /jobs/{id}/files/{name}: FileResponse-Stream; Validierung strikt —
  output_path muss unter /app/media liegen, nackter Dateiname (kein
  Slash/.., kein Dotfile), realpath-Check gegen Symlink-Ausbrueche.
  Mit Test (test_dateiname_validierung_blockt_pfad_tricks).
- UI: 'Download'-Knopf in der Aktion-Spalte bei fertigen Jobs; die
  Dateiliste mit Groessen + Download-Links lebt im Job-Detail-Popup
  (ein Dropdown wuerde im overflow-x-auto-Tabellencontainer clippen).
- nginx: proxy_buffering off + proxy_read_timeout 3600s waren fuer SSE
  schon gesetzt — grosse Downloads brauchen keine Aenderung.

Wunsch aus der Uebernahme-Session (Commander-Sammelliste 24.07.).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 09:01:38 +02:00
Hitonabi 13c1ae6064 feat(ui): Toast-Feedback ueberall, Job-Detail-Popup, System-Tab, Wizard-Media-Server, Favicon, Footer
- ToastContext: jede Aktion quittiert sichtbar ('Erfolgreich aktualisiert'
  ploppt oben rechts rein) — Refresh-Knoepfe drehen jetzt wirklich
  (Laufwerke, Logs, Worker, Speicherziele).
- JobDetailModal: Klick auf Titel in 'Neueste Jobs' -> Poster, Jahr,
  Beschreibung, Genres, Ablagepfad, Fehler.
- Logs: Filter-Pills um Warnung + Fehler ergaenzt (vorher nur
  Alle/Info/Erfolg).
- Speicherziele: Benutzer/Passwort VOR dem 'Freigaben auflisten'-Knopf
  (Windows/NAS lehnen Gast-Abfragen ab — genau daher kam das
  NT_STATUS_ACCESS_DENIED), Hinweistext, Toasts beim Einhaengen/Entfernen.
- Datei-Browser (Speicherziele + Rip-Ziel-Dialog) zeigt Dateien grau mit
  Groesse — Ordner wirkten faelschlich leer.
- Einstellungen: neuer System-Tab (Werkzeug-Versionen je Worker, Key-Status,
  Plattenplatz, MakeMKV-Beta-Key-Feld), Media-Server-Wahl im Ripping-Tab,
  Arbeitsverzeichnis im Verarbeitung-Tab, Benachrichtigungs-Anleitung
  (Discord/ntfy/Slack) + 'Test senden'.
- First-Run-Wizard: Media-Server-Schritt (Jellyfin/Emby/Kodi/Plex/Keins).
- Favicon (Disc im Logo-Verlauf, public/favicon.svg — /vite.svg war 404)
  + Footer 'Created with (Herz) by LucyAI, Claude and KrBrZ'.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 08:55:42 +02:00
Hitonabi 6517644d1f Dashboard-Korrektur-Popup, Worker-Tab mit Live-Ping, Herzschlag, Anzeige-Fixes
Ampel / ampel (push) Failing after 29s
Commander-Wuensche (23.07. Nacht):
- "Nicht korrekt?!"-Knopf direkt an der Disc-Karte: Korrektur-Suche als
  Popup (MetadataKorrektur) — kein Seitenwechsel mehr noetig; Wahl gilt
  per Disc-Fingerabdruck weiter 30 Tage
- Einstellungen -> Worker: verbundene Encoding-Maschinen mit ECHTER
  Erreichbarkeit (Celery-Ping + minuetlicher Herzschlag/last_seen),
  Encoder-Badges, Copy-Paste-Anbindung fuer neue Maschinen
  (Linux/Docker + Docker Desktop; SSH-Ein-Klick als Ausbaustufe)
- JSX-0-Falle gefixt: {0 && ...} renderte nackte "0" unter GENRE/LAUFZEIT
- ruff.toml: Regelsatz gepinnt — lokal aktualisierte Ruff-Version zog
  ploetzlich Stilregeln und faerbte den Baum rot; Ampel und lokal
  urteilen jetzt identisch

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 08:18:44 +02:00
Hitonabi 6b7d391737 Korrektur-Flow + Freigaben-Auswahl + Schreibtest + Schnellwahl-Klartext
Ampel / ampel (push) Failing after 52s
Commander-Befunde (23.07. spaet):
- MANUELLE KORREKTUR (KONZEPT Schritt 5 endlich komplett): Metadaten-Seite
  hat jetzt Titelsuche ueber ALLE Quellen (GET /metadata/search) mit
  Poster-Kacheln; ein Klick uebernimmt den Treffer (POST /metadata/override)
  fuer Karte, Jobs UND merkt ihn sich 30 Tage per Disc-Fingerabdruck —
  dieselbe Disc wird beim naechsten Einlegen sofort richtig erkannt
- PC/NAS per Klick: SMB-Freigaben eines Rechners auflisten
  (GET /storage-mounts/shares via smbclient) statt //host/share raten
- Berechtigungs-PRUEFUNG beim Einhaengen: Schreibtest, Warnung bei
  nur-lesbaren Zielen (API + UI + Log)
- "Standard-Unterordner" verstaendlich gemacht: heisst jetzt "Schnellwahl
  beim Rippen" mit Erklaertext; kryptisches Basis-Feld raus
- Preview zeigt Poster; Fingerprint fuer Cache/Override vereinheitlicht
  (billiges Label+Groesse statt Mount-Titel)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 21:34:34 +02:00
Hitonabi 07be54e62a Jikan/MAL-Quelle + Job-Titel + Abbrechen-Knopf + Dark-Hover + Ordner-Verwaltung
Ampel / ampel (push) Failing after 38s
Commander-Befunde (Screenshots 23.07. abends):
- Jikan (MyAnimeList, kostenlos OHNE Key) als Anime-Quelle vor OMDb —
  waehlt per Titel-Aehnlichkeit (SequenceMatcher, Schwelle 0.55) statt
  blind Treffer 1; damit trifft "Evangelion 2.22" den exakten Film
- Job-Titel: POST /jobs uebernimmt den erkannten Disc-Titel aus dem
  DISC_CACHE — Schluss mit "Unbekannt" in der Queue
- Kooperativer Job-Abbruch: POST /jobs/{id}/cancel setzt canceling,
  der Worker prueft das Flag bei jedem Fortschritts-Update und killt
  den Encoder-Prozess sauber (RipAbbruch); UI-Knopf "Abbrechen" fuer
  laufende, Status-Badge "Wird abgebrochen"
- Dark-Mode: Job-Zeilen-Hover war hart hell (hover:bg-slate-50)
- Speicherziele: lokaler Ordner-Browser mit "Ordner anlegen"
  (GET /browse + POST /browse/mkdir, nur unter /app/media)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 21:22:57 +02:00
Hitonabi 90eb17d407 UX-Runde: echte Disc-Titel via BD-Metadaten, Preview-Crash, Dashboard, Ziele
Ampel / ampel (push) Failing after 38s
Commander-Befunde 23.07. abends:
1. Metadaten "klappen nicht": Wurzel = kryptisches Volume-Label + kein
   TMDB-Key. Jetzt: API mountet die Disc read-only (CAP_SYS_ADMIN ist da)
   und liest den KLARTEXT-Titel aus BDMV/META/DL/bdmt_*.xml; dazu
   progressive Suchdegradation (Titel-Varianten) und OMDb-Unscharf-Suche
   (s= + imdbID-Nachladen) — mit dem vorhandenen OMDb-Key gibt es damit
   Titel/Jahr/Poster auch ohne TMDB
2. Weisses Fenster beim Pre-Scan: Lucide-Icons sind forwardRef —
   Direktaufruf getIcon(...)({size}) crashte die Seite; als JSX gerendert
3. Dashboard sortiert: System-Leiste (Encoder + aktiver Job) oben,
   Disc/Geraete -> Stats -> Jobs, Live-Log ans Ende
4. Ziel-Dialog mit ORDNER-BROWSER (GET /browse, nur unter /app/media);
   Schnellwahl nutzt die Settings-Unterordner statt Hartkodierung;
   Tab "Verzeichnisse" in "Speicherziele" aufgegangen (redundant)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 21:07:55 +02:00
Hitonabi b584cc29ad Universal-Sprint: Wizard, UI-Mounts, Encoder-Erkennung, Task-Split, README
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>
2026-07-23 20:49:08 +02:00
Hitonabi e350523f7e Dashboard-Disc-Karte: Auto-Pre-Scan beim Einlegen — man SIEHT was drinliegt
Ampel / ampel (push) Successful in 41s
Commander-Befund: Disc wurde erkannt, aber das UI verriet nicht WAS.
- Watcher stoesst beim Einlegen (und beim Start mit bereits eingelegter
  Disc) automatisch den Pre-Scan an, Ergebnis landet im DISC_CACHE und
  im Log ("Disc erkannt: Titel (Jahr) [typ, Confidence]")
- GET /devices liefert das disc-Feld mit Titel/Jahr/Typ/Confidence/Poster
- UI: prominente Karte "Im Laufwerk erkannt" mit Poster (TMDB relativ
  oder OMDb absolut), Beschreibung und Rippen-Start (Ziel-Dialog)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 19:55:18 +02:00
Hitonabi dfef585ec8 Speicherziel-Wahl: Rip-Ziel pro Job frei waehlbar (Etappe 16 / Task 16)
Ampel / ampel (push) Successful in 28s
- POST /jobs nimmt target_dir (validiert unter /app/media, .. fliegt raus)
- GET /storage-targets: Verzeichnisse unter /app/media inkl. Mount-Flag
  und freiem Platz — NFS/SMB-Shares unter /srv/rippy/media erscheinen
  dank rslave-Bind automatisch
- jobs.target_dir (Mini-Migration via ADD COLUMN IF NOT EXISTS)
- Worker: rip_disc(target_dir) mit eigener Validierung; CD/Video/
  Transcode-Pfade legen im gewaehlten Ziel ab
- UI: "Rippen starten" oeffnet den Ziel-Dialog (Filme/Serien/Musik oder
  eigener Pfad); Modal-Bugfix: customPath wurde still ignoriert

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 16:20:36 +02:00
Hitonabi 2474b683e2 Transcode-Stufe: HandBrake komprimiert NACH dem MakeMKV-Rip + --noscan-Fix
Ampel / ampel (push) Successful in 34s
Commander-Entscheid 23.07.: 40-GB-Rohdateien sind kein brauchbares
Endprodukt. Architektur bleibt zweistufig, weil HandBrake AACS nicht
lesen kann: MakeMKV rippt verlustfrei nach /app/temp/raw, HandBrake
macht daraus x265 auf Arbeitsgroesse in /app/media, Roh-Verzeichnis
wird erst NACH komplettem Erfolg geloescht (keepOriginal behaelt es).

- Worker: handbrake-cli im Image, run_handbrake + _komprimiere,
  Job-Status "transcoding", Settings aus Postgres (transcodeEnabled/
  Preset/keepOriginal), Fortschritt je Datei aggregiert
- makemkvcon: --noscan im Kommando verankert — der Geraete-Scan haengt
  (1.18.4) bzw. crasht (1.17.7) im Container, mit --noscan + dev:-Pfad
  laeuft es (Befund 23.07., DRV-Zeile beweist Laufwerks-Erkennung)
- UI: Settings-Tab "Verarbeitung" (Toggle/Preset/Original behalten),
  Status-Badge "Komprimieren", LiveLog erkennt transcoding als aktiv
- KONZEPT/ROADMAP entsprechend aktualisiert; Tests fuer HandBrake-Cmd
  (arbeitet auf DATEI, nie am Geraet) und Progress-Regex

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 15:56:37 +02:00
Hitonabi 1aa51ca943 UI-Feinschliff: Settings-Tabs funktionieren, Details-Knopf tut etwas
Ampel / ampel (push) Successful in 33s
- Settings: Tabs waren reine Dekoration (kein onClick, isActive fest) —
  jetzt echte Tab-Navigation (Ripping/Verzeichnisse/APIs/Benachrichtigungen)
  + OMDb-Key-Feld im APIs-Tab
- Laufwerk-Details: aufklappbares Panel (Pfad/Modell/Seriennummer/Disc)
  mit "Rippen starten" (POST /jobs) und "Auswerfen" (Eject-Endpoint)
- Placebos raus: 4 tote Schnellaktionen, doppelte Geraete-Sektion mit
  zweitem totem Details-Knopf, toter Abmelden-Knopf

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 15:30:09 +02:00
Hitonabi ef84392848 Fix: .gitignore-Venv-Muster lib/ verschluckte docker/ui/src/lib/
Ampel / ampel (push) Successful in 30s
Der Ampel-Rot-Lauf 23 zeigte es: api.ts (der neue API-Client) kam nie im
Commit an — das Python-venv-Muster `lib/` galt fuer JEDES lib-Verzeichnis
im Baum. Jetzt auf Root verankert (/lib/), Datei nachgereicht.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 15:04:56 +02:00
Hitonabi f2da1ad525 UI: echter Build hinter nginx, relative API-Pfade, Logs-Seite ehrlich
Vorher lief der Vite-ENTWICKLUNGSSERVER als Produktion, und vier Dateien
riefen hartkodiert http://localhost:8000 auf — vom PC aus fragte der Browser
damit den PC selbst nach Laufwerken (deshalb blieb das UI immer leer);
Settings nutzte ein nie gesetztes VITE_API_URL. Die Logs-Seite zeigte fest
einprogrammierte Fantasie-Einträge ("The Matrix gerippt").

- lib/api.ts: axios-Instanz mit baseURL /api; nginx proxied /api → api:8000
  (ein Origin, kein CORS), SSE-tauglich (proxy_buffering off)
- Dockerfile: Vite-Build → nginx:alpine statt npm run dev
- Logs + LiveLog von echtem /logs-Endpoint; MetadataPreview: echte Laufwerke
  aus /devices statt erfundener /dev/bluray-Optionen, startet echten Job

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 15:02:39 +02:00
Hitonabi e9652a428c feat(ui): implement Discovery, Logs, and Live Log
Ampel / ampel (push) Successful in 29s
- DeviceDiscovery: auto device detection with type and status
- LogsPage: comprehensive logs view with filters and stats
- RipTargetModal: target directory selection wizard
- ConfirmDialog: generic confirmation dialog component
- LiveLogSection: real-time job progress and logs
- Update App.tsx to include new pages
2026-07-23 12:38:16 +02:00
Hitonabi 12c67aee27 fix: use dark class instead of data-theme for Tailwind 2026-07-22 17:12:32 +02:00
Hitonabi 85e072a7dd fix: use Tailwind dark: prefix instead of conditional classes 2026-07-22 17:11:02 +02:00
Hitonabi 886cf4398e fix: Dashboard.tsx useEffect syntax error 2026-07-22 17:04:18 +02:00
Hitonabi d2fb281342 fix: complete dark mode implementation with all UI components 2026-07-22 17:00:49 +02:00
Hitonabi 95c1f9b105 feat(ui): SoC Refactoring & Config Validation
- Theme Context ausgelagert (ThemeContext.tsx + useDarkMode.ts)
- Config Validation mit TMDB-API-Key Pflicht (config_validation.py)
- Cache Key Centralization (cache/keys.py)
- CD-Ripping mit abcde implementiert (Worker)
- Docker Compose mit Healthchecks & LOG_LEVEL
- ROADMAP.md & SAVEPOINT.md aktualisiert
2026-07-22 16:38:19 +02:00
Hitonabi 43dfce5233 feat(ui): implement dark mode with theme toggle
- Add global theme state in App.tsx with localStorage persistence
- Implement dark mode CSS variables in index.css
- Add theme toggle button in sidebar navigation
- Update Dashboard with dark mode support for stats cards and badges
- Update Settings page with dark mode for main layout and toggles

This implements the core dark mode functionality with separation of
concerns - theme state is managed globally in App.tsx and passed down
to child components as props.
2026-07-21 22:18:59 +02:00
Hitonabi ba2429612a rippy-ui-modern: API UI Modernisiert & Import-Fixes
- Doppelte Arcane-Einträge behoben (rippy statt Rippy) - Import-Fixes: relative → absolute imports in main.py, cache/__init__.py, prescan/__init__.py, clients/__init__.py - Neue Dateien: cache.py, prescan.py, Settings.tsx - API-Port 8000 in docker-compose.yml gemappt - UI mit Sidebar, Dark Mode, Einstellungen-Tabs

Fixes: #2978 (doppelte Einträge), #2888 (Import-Fehler)
2026-07-21 22:08:03 +02:00
Hitonabi 518155051f Etappe 3: Metadaten-Lookup + Pre-Scan
- SQLite-Cache für API-Rate-Limits (LRU, 10k Einträge)
- TMDB/MusicBrainz/TheTVDB Clients
- Pre-Scan-Modul für TOC-Lesung ohne Ripping
- Metadaten-Preview UI
- Jellyfin-Formatierung (NFO + Images)
- API Endpoints für Lookup, Confirm, Format
2026-07-21 17:17:35 +02:00
Hitonabi 4d1f613a1c Etappe 5: API + Auth + WebUI — Erste Implementierung
- React-UI: Dashboard mit Stats, Geräte, Jobs
- API: /jobs und /devices endpoints
- CORS aktiviert für UI-Kommunikation
2026-07-21 16:52:30 +02:00