Etappe 10: Worker rippt wirklich — MakeMKV 1.18.4 + ioctl-Disc-Erkennung
Vorher: Dockerfile unbaubar (makepkg ist ein Arch-Paket, existiert in Debian nicht) und KEIN einziges Ripping-Tool im Image — jeder Rip endete sofort. Disc-Erkennung via `file -L` konnte auf Block-Devices strukturell nie etwas erkennen; ihr Test mockte sich die Ausgabe passend. - makemkv-oss/bin 1.18.4 multi-stage (bookworm-gepinnt), EULA via tmp/eula_accepted, Beta-Key aus MAKEMKV_APP_KEY (entrypoint.sh) - makemkvcon-Aufruf + PRGV-Parsing laut makemkv.com/developers/usage.txt (AGENTS Regel D), HandBrake raus aus dem Ripp-Pfad (KONZEPT: lossless=Muss) - detection.py: CDROM_DISC_STATUS + BLKGETSIZE64 (cd/dvd/bluray), pure classify() mit ehrlichen Tests - tasks.py: rip_disc als einziger Celery-Task, schreibt Status/Fortschritt nach Postgres (db.py), Ausgabe auf /app/media (Volume) statt totem /output Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,25 +1,43 @@
|
||||
"""Tests für ripping.py: Fortschritts-Parsing, Kommando-Bau, Disc-Erkennung.
|
||||
"""Tests für ripping.py: Kommando-Bau und Fortschritts-Parsing.
|
||||
|
||||
Deckt genau die Stellen ab, an denen im Review 22.07. erfundene Schnittstellen
|
||||
gefunden wurden (abcde-Flags, Celery-API) — damit so etwas nie wieder still liegt.
|
||||
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
|
||||
|
||||
import ripping
|
||||
from ripping import (
|
||||
build_abcde_cmd,
|
||||
build_handbrake_cmd,
|
||||
detect_disc_type,
|
||||
get_progress_from_line,
|
||||
build_makemkv_cmd,
|
||||
get_progress_from_prgv,
|
||||
write_abcde_config,
|
||||
)
|
||||
|
||||
|
||||
def test_progress_parsing():
|
||||
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_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 "--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_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():
|
||||
@@ -34,46 +52,11 @@ def test_abcde_cmd_hat_genau_ein_ausgabeformat():
|
||||
|
||||
|
||||
def test_abcde_config_enthaelt_zielverzeichnis():
|
||||
pfad = write_abcde_config("/output/cd/test123")
|
||||
pfad = write_abcde_config("/app/media/cd/test123")
|
||||
try:
|
||||
with open(pfad, encoding="utf-8") as f:
|
||||
inhalt = f.read()
|
||||
assert "OUTPUTDIR='/output/cd/test123'" in inhalt
|
||||
assert "OUTPUTDIR='/app/media/cd/test123'" in inhalt
|
||||
assert "INTERACTIVE=n" in inhalt
|
||||
finally:
|
||||
os.unlink(pfad)
|
||||
|
||||
|
||||
def test_handbrake_cmd_vollstaendig():
|
||||
cmd = build_handbrake_cmd("/dev/sr0", "/output/dvd/x/film.mkv")
|
||||
assert cmd[0] == "HandBrakeCLI"
|
||||
assert cmd[cmd.index("--input") + 1] == "/dev/sr0"
|
||||
assert cmd[cmd.index("--output") + 1] == "/output/dvd/x/film.mkv"
|
||||
assert "--preset" in cmd
|
||||
|
||||
|
||||
class _FakeResult:
|
||||
def __init__(self, stdout):
|
||||
self.stdout = stdout
|
||||
|
||||
|
||||
def test_disc_typ_erkennung(monkeypatch):
|
||||
faelle = [
|
||||
("UDF filesystem data 'MEIN_FILM' DVD Video", "dvd"),
|
||||
("data, BDMV bluray structure", "bluray"),
|
||||
("Audio CD, cda tracks", "cd"),
|
||||
("irgendwas anderes", "unknown"),
|
||||
]
|
||||
for ausgabe, erwartet in faelle:
|
||||
monkeypatch.setattr(
|
||||
ripping.subprocess, "run", lambda *a, _out=ausgabe, **k: _FakeResult(_out)
|
||||
)
|
||||
assert detect_disc_type("/dev/sr0") == erwartet
|
||||
|
||||
|
||||
def test_disc_typ_erkennung_fehler_gibt_unknown(monkeypatch):
|
||||
def kaputt(*a, **k):
|
||||
raise OSError("kein Geraet")
|
||||
|
||||
monkeypatch.setattr(ripping.subprocess, "run", kaputt)
|
||||
assert detect_disc_type("/dev/sr0") == "unknown"
|
||||
|
||||
Reference in New Issue
Block a user