fix(prescan): makemkvcon ueber den Katalog suchen, nicht ueber shutil.which
Ampel / ampel (push) Successful in 55s

Auf die Frage des Commanders: "du hast jetzt nur mein laufwerk analysiert
oder? wenn ich rippy weitergebe wie laeuft es dort?"

Berechtigt -- und beim Nachsehen fiel derselbe Fehler auf wie heute Vormittag
im Werkzeug-Katalog:

    shutil.which("makemkvcon")   ->  None, auch bei installiertem MakeMKV

`which` sucht nur im PATH. Windows-Programme liegen in "Programme". Der
Zweig, der die Titelliste von makemkvcon holt, lief unter Windows also NIE --
unabhaengig vom Laufwerk, auf jedem Rechner. Jetzt ueber
`katalog.finden("makemkv")`, das genau dafuer da ist.

Dazu vier Tests fuer Disc-Arten, die ICH NICHT HABE, damit die Zusage nicht
an einer einzigen Disc haengt:

    Blu-ray ohne BDMV/META   -> None (sehr haeufig; Rueckfall aufs Label)
    DVD (nur VIDEO_TS)       -> None
    bdmt_deu.xml vorhanden   -> Titel wird gelesen
    deu + eng vorhanden      -> eng gewinnt (APIs suchen damit besser)

Und ein Waechter gegen shutil.which in prescan.py. Der erste Anlauf davon
fiel ueber den eigenen Erklaertext, in dem der alte Aufruf zitiert wird --
er prueft jetzt nur Code, keine Kommentare.

Ampel lokal: 774 gruen, ruff sauber.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Hitonabi
2026-08-28 16:05:25 +02:00
co-authored by Claude Opus 5
parent 878b24c43b
commit be3fac53af
2 changed files with 82 additions and 4 deletions
+13 -4
View File
@@ -6,11 +6,11 @@ lieferte seitdem immer „Unknown Disc". Dies ist die echte Logik, bereinigt.
"""
import os
import shutil
import subprocess
from typing import Dict, List, Optional
from rippy import drives as _laufwerks_schicht
from rippy.tools import katalog as werkzeug_katalog
from clients.tmdb import TMDBClient
from clients.jikan import JikanClient
from clients.musicbrainz import MusicBrainzClient
@@ -346,10 +346,19 @@ class PreScan:
if label:
toc["title"] = normalize_disc_label(label)
# Titel-Quelle 2 (optional, falls makemkvcon doch da ist):
if shutil.which("makemkvcon"):
# Titel-Quelle 3: die Titelliste von makemkvcon (optional).
#
# ⚠️ Über den Werkzeug-Katalog, NICHT über `shutil.which`
# (Befund 28.08.2026). `which` sucht nur im PATH — unter
# Windows liegen Programme in „Programme", nicht im PATH.
# Gemessen: `shutil.which("makemkvcon")` gibt dort auch bei
# installiertem MakeMKV None zurück, und dieser Zweig lief
# NIE. Genau derselbe Fehler, für den es `tools/katalog.py`
# gibt.
makemkv = werkzeug_katalog.finden("makemkv")
if makemkv:
result = subprocess.run(
["makemkvcon", "-r", "--noscan", "--minlength=300", "info", f"dev:{device_path}"],
[makemkv, "-r", "--noscan", "--minlength=300", "info", f"dev:{device_path}"],
capture_output=True,
text=True,
timeout=120
+69
View File
@@ -144,3 +144,72 @@ def test_ohne_jede_quelle_bleibt_es_unbekannt(monkeypatch):
assert ergebnis.confidence == 0.3
assert ergebnis.metadata["type"] == "unknown"
assert ergebnis.title == "Nix Da"
# ── Was auf FREMDEN Rechnern gilt (Befund 28.08.2026) ───────────────────
#
# Der Commander: "du hast jetzt nur mein laufwerk analysiert oder? wenn ich
# rippy weitergebe wie laeuft es dort?"
#
# Berechtigt. Gemessen wurde an EINEM Laufwerk (LG BU40N) und EINER Disc
# (BD-50 mit BDMV/META). Diese Tests halten fest, was bei ANDEREN Discs
# passieren muss -- ohne dass eine davon vorhanden sein muss.
def test_bluray_ohne_metadaten_gibt_ehrlich_nichts_zurueck(tmp_path):
"""Sehr viele Blu-rays haben kein BDMV/META. Dann greift der Rueckfall
auf das Volume-Label -- aber diese Funktion darf nichts erfinden."""
from prescan.prescan import titel_aus_bdmt
(tmp_path / "BDMV" / "STREAM").mkdir(parents=True)
assert titel_aus_bdmt(str(tmp_path)) is None
def test_dvd_hat_kein_bdmv(tmp_path):
from prescan.prescan import titel_aus_bdmt
(tmp_path / "VIDEO_TS").mkdir()
assert titel_aus_bdmt(str(tmp_path)) is None
def test_bdmt_wird_gelesen_wenn_da(tmp_path):
"""Der Weg, der bei der Disc des Commanders 'Evangelion 2.22' lieferte —
hier ohne Disc nachgestellt."""
from prescan.prescan import titel_aus_bdmt
meta = tmp_path / "BDMV" / "META" / "DL"
meta.mkdir(parents=True)
(meta / "bdmt_deu.xml").write_text(
'<?xml version="1.0"?><disclib><di:discinfo>'
'<di:title><di:name>Evangelion 2.22</di:name></di:title>'
'</di:discinfo></disclib>', encoding="utf-8")
assert titel_aus_bdmt(str(tmp_path)) == "Evangelion 2.22"
def test_englisch_wird_bevorzugt(tmp_path):
"""Die APIs suchen mit englischen Titeln besser."""
from prescan.prescan import titel_aus_bdmt
meta = tmp_path / "BDMV" / "META" / "DL"
meta.mkdir(parents=True)
for datei, name in (("bdmt_deu.xml", "Deutscher Titel"),
("bdmt_eng.xml", "English Title")):
(meta / datei).write_text(
"<x><di:name>%s</di:name></x>" % name, encoding="utf-8")
assert titel_aus_bdmt(str(tmp_path)) == "English Title"
def test_makemkvcon_wird_ueber_den_katalog_gesucht():
"""DER Fehler: `shutil.which("makemkvcon")` gibt unter Windows auch bei
installiertem MakeMKV None zurueck -- Windows-Programme liegen in
„Programme", nicht im PATH. Dieser Zweig lief dort also NIE."""
import os
hier = os.path.dirname(os.path.abspath(__file__))
with open(os.path.join(hier, "prescan", "prescan.py"), encoding="utf-8") as f:
# NUR Code, keine Kommentare: Der erste Anlauf dieses Tests fiel ueber
# den eigenen Erklaertext, in dem der alte Aufruf zitiert wird. Ein
# Waechter, der an einer Erklaerung scheitert, prueft das Falsche.
code = [z for z in f if not z.strip().startswith("#")]
quelle = "".join(code)
assert "shutil.which(" not in quelle, (
"shutil.which findet unter Windows keine Programme aus 'Programme'")
assert 'werkzeug_katalog.finden("makemkv")' in quelle