fix(windows): Zweiter Rip startete waehrend der Kompression ins leere Laufwerk

Der Commander meldete einen Rip-Fehlschlag „bei der Komprimierung", obwohl
der Rip laengst durch war:

    makemkvcon endete mit Code 11 — letzte Meldung:
    Das Öffnen der Disk schlug fehl  — keine MKV-Datei entstanden

Auffaellig war, was FEHLTE: kein „Ursache:". Waere der Geraetepfad schuld
gewesen, stuende dort MSG 2024. Bleibt: kein Datentraeger im Laufwerk.

Der Ablauf dahinter:
  1. Rip fertig → Rippy wirft die Disc aus (Standardeinstellung)
  2. Status wird auf `transcoding` gesetzt — ab hier sagte `has_active_job`
     NEIN, das Laufwerk sei frei; es kennt nur pending/running
  3. Die Disc-Wache sieht beim Auswurf einen Statuswechsel → „eingelegt"
  4. Die Vollautomatik startet einen ZWEITEN Rip — auf ein Laufwerk, dessen
     Schublade gerade herausfaehrt

Der zweite Rip lief in ein leeres Laufwerk. Auf dem Bildschirm sah das aus,
als sei die Kompression gescheitert — sie lief ungestoert weiter.

Drei Aenderungen:

* `store.job_offen` — der weitere Riegel (pending/running/transcoding/
  canceling) fuer die Vollautomatik. `has_active_job` bleibt unveraendert:
  Das fragt „haelt gerade jemand das Laufwerk?", und waehrend der Kompression
  tut das niemand — ein Auswurf von Hand bleibt erlaubt.
* `ripping.disc_fehlt` — vor dem makemkvcon-Start nachsehen, ob ueberhaupt
  eine Disc drin liegt. Statt zwei Minuten Warten und Code 11 gibt es einen
  Satz, den man versteht. Ein FEHLGESCHLAGENER Blick verweigert nichts:
  „ich weiss es nicht" darf nie zu „es geht nicht" werden.
* MSG 5010 in KRITISCHE_CODES — MakeMKVs Sammelmeldung sagt fuer sich nichts.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Hitonabi
2026-08-29 20:36:59 +02:00
co-authored by Claude Opus 5
parent f6f0a4ccb6
commit f0f719ca12
6 changed files with 215 additions and 1 deletions
+11
View File
@@ -119,6 +119,17 @@ def text_von(roh) -> str:
#: Aktivierungsschlüssel …"
KRITISCHE_CODES = {
2024: "MakeMKV kennt dieses Laufwerk nicht",
# 5010 stand bis zum 29.08.2026 NICHT hier — und genau das war das
# Problem: Der Commander bekam „makemkvcon endete mit Code 11 — letzte
# Meldung: Das Öffnen der Disk schlug fehl". Das ist MakeMKVs
# Sammelmeldung für „ging nicht" und sagt für sich genommen nichts.
#
# Auffällig war, was FEHLTE: kein „Ursache:" davor. Wäre der Gerätepfad
# schuld gewesen, stünde dort 2024. Bleibt: kein Datenträger, oder ein
# anderes Programm hält das Laufwerk. Nach einem fertigen Rip wirft Rippy
# die Disc aus — ein zweiter Versuch trifft dann ein leeres Laufwerk.
5010: "Das Laufwerk liess sich nicht öffnen — liegt die Disc noch drin? "
"Nach einem fertigen Rip wirft Rippy sie aus",
5020: "Der hinterlegte MakeMKV-Schlüssel wird nicht angenommen",
5021: "MakeMKV ist zu alt für den aktuellen Beta-Schlüssel — bitte MakeMKV "
"aktualisieren",
+41
View File
@@ -361,6 +361,47 @@ def has_active_job(device: str) -> bool:
return zeile is not None
# Ein Job ist erst fertig, wenn er FERTIG ist. Die Kompression gehoert dazu.
#
# ⚠️ Nicht dasselbe wie `has_active_job`. Das fragt „haelt gerade jemand das
# Laufwerk?" — waehrend der Kompression tut das niemand, ein Auswurf ist dann
# erlaubt. Hier wird gefragt „ist der Vorgang durch?", und das ist er nicht.
JOB_OFFEN = ("pending", "running", "transcoding", "canceling")
def job_offen(device: str) -> bool:
"""True, solange auf dem Geraet ein Job noch nicht abgeschlossen ist.
## Warum es diese zweite Frage gibt (Befund 29.08.2026)
Der Commander meldete einen Rip-Fehlschlag „bei der Komprimierung", obwohl
der Rip laengst durch war. Der Ablauf dahinter:
1. Rip fertig → Rippy wirft die Disc aus (Standardeinstellung)
2. Status wird auf `transcoding` gesetzt — und ab hier sagte
`has_active_job` NEIN, das Laufwerk sei frei
3. Die Disc-Wache sieht beim Auswurf einen Statuswechsel und meldet
„eingelegt"
4. Die Vollautomatik (`autoRipStart`) startet einen ZWEITEN Rip — auf
ein Laufwerk, dessen Schublade gerade herausfaehrt
Der zweite Rip lief in ein leeres Laufwerk und endete mit „Das Oeffnen der
Disk schlug fehl". Auf dem Bildschirm sah das aus, als sei die Kompression
gescheitert — sie lief in Wahrheit ungestoert weiter.
Solange ein Vorgang auf diesem Laufwerk laeuft, faengt die Automatik
keinen zweiten an. Von Hand darf der Commander weiterhin alles.
"""
with engine_holen().connect() as conn:
zeile = conn.execute(
select(jobs.c.id)
.where(jobs.c.device == device)
.where(jobs.c.status.in_(JOB_OFFEN))
.limit(1)
).first()
return zeile is not None
def meta_merken(job_id: str, **felder) -> None:
"""Ergänzt EINZELNE Schlüssel in den Job-Metadaten. Wirft nie.