fix(windows): Rippen ging nicht — drei Container-Annahmen im Rip-Pfad

Commander: „Das Rippen der disk funktioniert nicht. makemkvcon endete mit
Code 11 — letzte Meldung: Das Öffnen der Disk schlug fehl — keine MKV-Datei
entstanden"

In diesem einen Satz steckten drei Fehler. Alle drei an seinem Laufwerk
gemessen, nicht hergeleitet.

## 1. Die Quellenangabe — das war der Abbruch

    dev:\.\G:  MSG:2024 „Unknown device" -> MSG:5010 Öffnen schlug fehl
    dev:G:      68 TINFO-Zeilen, „Die Aufgabe wurde erfolgreich abgeschlossen"

`f"dev:{device_path}"` stand an VIER Stellen. Unter Linux richtig (/dev/sr0),
unter Windows nicht: `rippy.drives.windows` meldet den Geraete-Namensraum
`\.\G:`, den `CreateFileW` fuer die IOCTLs braucht — MakeMKV kennt ihn
nicht.

## 2. „Ö" statt „Ö"

`Ö` als UTF-8 (C3 96), gelesen als cp1252. `subprocess` stand auf `text=True`
ohne `encoding=`, nahm also die Gebietsschema-Kodierung; Rippy stellt seine
Konsole beim Start aber auf UTF-8 (sonst stirbt der Start an einer
Umlaut-Logzeile). Direkt gemessen kommen die Bytes je nach Umgebung als UTF-8
ODER cp1252 — deshalb wird jetzt bestimmt statt behauptet.

## 3. Die Ursache fehlte im Fehlertext

Gesucht wurde nach ENGLISCHEN Textbausteinen („evaluation period has
expired"). Auf einem deutschen Windows trifft keiner. Jetzt zaehlen die
Meldungs-NUMMERN, die sprachunabhaengig sind.

⚠️ Beim ersten Anlauf hatte ich 5021 aus dem Kopf mit „Volume-Key unbekannt"
beschriftet — falsch. Meine eigene Ausgabe zeigte nur meine Beschriftung
statt MakeMKVs Text, sodass es fast durchgegangen waere. Der echte Wortlaut
steht jetzt im Code.

## Nebenbefund: der Beta-Key lag zweimal am falschen Ort

`makemkv_daten.DATEN_DIR` war fest `/root/.MakeMKV`. Nach der Reparatur des
Ordners blieb MSG:5051 trotzdem stehen — weil MakeMKV unter Windows seine
Einstellungen in der REGISTRY haelt (HKCU\Software\MakeMKV), nicht in einer
settings.conf. Nachgesehen statt vermutet.

Und der wichtigste Teil davon: **Ein abgelehnter Schluessel ist schlimmer als
gar keiner.** Ohne Key las MakeMKV die Disc noch (68 TINFO), mit dem
abgelehnten verweigerte es alles (0 Titel). Deshalb wird jetzt geprueft und
bei Ablehnung zurueckgenommen.

## Beweis

Echter Rip ueber `ripping.run_makemkv`, kuerzester Titel:

    Status success, Code 0, „Evangelion 2.22_t03.mkv" 217,9 MB
    5036 „Das Kopieren wurde abgeschlossen. 1 Titel wurden gesichert."

828 Tests gruen, ruff sauber.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Hitonabi
2026-08-29 13:52:06 +02:00
co-authored by Claude Opus 5
parent 73ed104bbc
commit 954f293871
9 changed files with 693 additions and 39 deletions
+20 -4
View File
@@ -2445,14 +2445,30 @@ async def makemkv_key_holen():
detail="Im Forum-Beitrag stand kein Key im erwarteten Format. "
"Vermutlich hat sich die Seite geändert.")
geaendert = await asyncio.to_thread(key_modul._apply_key, key)
# Nimmt MakeMKV ihn an? Nur MakeMKV selbst weiss das.
#
# Am 29.08.2026 auf dem Rechner des Commanders: der frische Schluessel
# wurde mit MSG 5020 („ungueltig") und 5021 („Programmversion zu alt")
# abgelehnt — sein MakeMKV 1.18.4 ist aelter als der Schluessel verlangt.
# Ohne diese Rueckfrage haette hier „erfolgreich geholt" gestanden, und
# der naechste Rip waere trotzdem gescheitert.
from rippy.rip import makemkv_aufruf
from rippy.tools import katalog as werkzeug_katalog
urteil = await asyncio.to_thread(
makemkv_aufruf.key_setzen_und_pruefen, key,
werkzeug_katalog.finden("makemkv"))
await asyncio.to_thread(
db.add_log, "success", "makemkv-key",
"Beta-Key aus dem Forum geholt (…%s)%s"
% (key[-6:], "" if geaendert else " — war schon der aktuelle"))
db.add_log, "success" if urteil["ok"] else "warning", "makemkv-key",
"Beta-Key aus dem Forum geholt (…%s)%s%s"
% (key[-6:], "" if geaendert else " — war schon der aktuelle",
"" if urteil["ok"] else " — ABGELEHNT: " + urteil["grund"]))
# Der Key selbst wird NICHT zurueckgegeben: Er steht in den Einstellungen,
# und ein zweiter Weg zu demselben Wert ist ein zweiter Weg, ihn zu
# verlieren.
return {"geholt": True, "geaendert": geaendert, "endet_auf": key[-6:]}
return {"geholt": True, "geaendert": geaendert, "endet_auf": key[-6:],
"angenommen": urteil["ok"], "grund": urteil["grund"]}
@app.post("/system/keydb")
+5 -4
View File
@@ -10,6 +10,8 @@ import subprocess
from typing import Dict, List, Optional
from rippy import drives as _laufwerks_schicht
from rippy.rip.makemkv_aufruf import quelle as makemkv_quelle
from rippy.rip.makemkv_aufruf import text_von
from rippy.tools import katalog as werkzeug_katalog
from clients.tmdb import TMDBClient
from clients.jikan import JikanClient
@@ -365,12 +367,11 @@ class PreScan:
makemkv = werkzeug_katalog.finden("makemkv")
if makemkv:
result = subprocess.run(
[makemkv, "-r", "--noscan", "--minlength=300", "info", f"dev:{device_path}"],
[makemkv, "-r", "--noscan", "--minlength=300", "info", makemkv_quelle(device_path)],
capture_output=True,
text=True,
timeout=120
timeout=120 # binaer lesen — Begruendung in text_von
)
for line in result.stdout.split('\n'):
for line in text_von(result.stdout).split('\n'):
if line.startswith('TINFO:'):
parts = line.split(',')
if len(parts) >= 5: