2474b683e2
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>
86 lines
3.4 KiB
Python
86 lines
3.4 KiB
Python
"""Tests für ripping.py: Kommando-Bau und Fortschritts-Parsing.
|
|
|
|
Deckt genau die Stellen ab, an denen Reviews erfundene Schnittstellen fanden
|
|
(abcde-Flags, Celery-API, HandBrake-Regex) — damit so etwas nie wieder still liegt.
|
|
Das PRGV-Format stammt aus der MakeMKV-Doku (makemkv.com/developers/usage.txt).
|
|
"""
|
|
|
|
import os
|
|
|
|
from ripping import (
|
|
build_abcde_cmd,
|
|
build_handbrake_cmd,
|
|
build_makemkv_cmd,
|
|
get_progress_from_line,
|
|
get_progress_from_prgv,
|
|
write_abcde_config,
|
|
)
|
|
|
|
|
|
def test_makemkv_cmd_vollstaendig():
|
|
cmd = build_makemkv_cmd("/dev/sr0", "/app/media/dvd/x")
|
|
assert cmd[0] == "makemkvcon"
|
|
assert "-r" in cmd # Robot-Mode: maschinenlesbar
|
|
assert "--noscan" in cmd # Scan hängt/crasht im Container (23.07.)
|
|
assert "--progress=-same" in cmd # Fortschritt im selben Stream
|
|
assert "mkv" in cmd
|
|
assert "dev:/dev/sr0" in cmd # Geräte-Notation laut Doku
|
|
assert cmd[-2:] == ["all", "/app/media/dvd/x"]
|
|
|
|
|
|
def test_handbrake_cmd_arbeitet_auf_datei_nicht_geraet():
|
|
"""HandBrake kann AACS nicht — es bekommt IMMER die MKV-Datei aus dem
|
|
MakeMKV-Rip, nie das Laufwerk (die alte Direkt-am-Gerät-Pipeline war
|
|
für Blu-rays prinzipiell funktionsunfähig)."""
|
|
cmd = build_handbrake_cmd("/app/temp/raw/x/t00.mkv", "/app/media/bluray/x/t00.mkv")
|
|
assert cmd[0] == "HandBrakeCLI"
|
|
assert cmd[cmd.index("--input") + 1] == "/app/temp/raw/x/t00.mkv"
|
|
assert cmd[cmd.index("--output") + 1] == "/app/media/bluray/x/t00.mkv"
|
|
assert "--preset" in cmd
|
|
assert "--all-audio" in cmd # alle Sprachen behalten
|
|
assert "--all-subtitles" in cmd
|
|
|
|
|
|
def test_handbrake_progress_parsing():
|
|
# Testfund 22.07.: echtes HandBrake schreibt „45.50 %" MIT Leerzeichen
|
|
assert get_progress_from_line("Encoding: task 1 of 1, 45.50 %") == 45
|
|
assert get_progress_from_line("Encoding: task 1 of 1, 100.00 %") == 100
|
|
assert get_progress_from_line("kein Fortschritt hier") == 0
|
|
|
|
|
|
def test_prgv_parsing():
|
|
# PRGV:current,total,max — total/max ist der Gesamtfortschritt
|
|
assert get_progress_from_prgv("PRGV:100,32768,65536") == 50
|
|
assert get_progress_from_prgv("PRGV:0,65536,65536") == 100
|
|
assert get_progress_from_prgv("PRGV:0,0,65536") == 0
|
|
|
|
|
|
def test_prgv_parsing_ignoriert_fremde_zeilen():
|
|
# -1 heißt „keine Fortschrittszeile" — MSG-Zeilen dürfen NIE als 0% gelten,
|
|
# sonst springt die Anzeige ständig auf null zurück.
|
|
assert get_progress_from_prgv('MSG:1005,0,1,"MakeMKV gestartet","%1","x"') == -1
|
|
assert get_progress_from_prgv("irgendwas") == -1
|
|
assert get_progress_from_prgv("PRGV:kaputt") == -1
|
|
|
|
|
|
def test_abcde_cmd_hat_genau_ein_ausgabeformat():
|
|
"""Review-Fund 22.07.: '-o' stand doppelt (Format UND Verzeichnis) — abcde
|
|
parste das Verzeichnis als Format, CD-Ripping war nie funktionsfähig."""
|
|
cmd = build_abcde_cmd("/dev/sr0", "/tmp/test.abcde.conf")
|
|
assert cmd.count("-o") == 1
|
|
assert cmd[cmd.index("-o") + 1] == "flac"
|
|
assert "-c" in cmd
|
|
assert cmd[cmd.index("-c") + 1] == "/tmp/test.abcde.conf"
|
|
assert "-N" in cmd # nicht-interaktiv, sonst hängt der Worker
|
|
|
|
|
|
def test_abcde_config_enthaelt_zielverzeichnis():
|
|
pfad = write_abcde_config("/app/media/cd/test123")
|
|
try:
|
|
with open(pfad, encoding="utf-8") as f:
|
|
inhalt = f.read()
|
|
assert "OUTPUTDIR='/app/media/cd/test123'" in inhalt
|
|
assert "INTERACTIVE=n" in inhalt
|
|
finally:
|
|
os.unlink(pfad)
|