feat(v5): Etappe W-2 — Rippen: Parser, makemkvcon-Lauf, Werkzeug-Katalog
Ampel / ampel (push) Failing after 1m22s
Ampel / ampel (push) Failing after 1m22s
rip/parser.ts: die reine Textverarbeitung mit allen bezahlten Fallen aus dem Docker-Zweig — quelle() (dev:G: statt dev:\.\G:, der 404-Verwandte), textVon() (UTF-8 streng, sonst cp1252 — nie wieder 'Öffnen'), parseMsg (Regex statt split — Meldungen mit Komma), PRGV (-1 vs. echtes 0 %), TINFO/SINFO (Sprache aus Attr 3/4, NICHT 28/29), laengsterTitel mit Play-All-Schutz, episodenTitel, KRITISCHE_CODES (sprachfeste NUMMERN). rip/makemkv.ts: Kommandobau + Lauf — ZeilenLeser (binaer, halbe Zeilen, je Zeile dekodiert), RipAuswertung (pur), rippen() mit AbortSignal, Lesefehler-Flag AUCH bei Rueckgabewert 0. werkzeuge/katalog.ts: die Suchreihenfolge samt %VAR%-Gross/Klein-Falle und Registry-Rueckfall. ablauf/rippen.ts: ein Rip je Laufwerk, Status-Push, 'erst nachsehen, dann rippen' (unbekannt heisst trotzdem rippen). Fenster: Rippen-Knopf, Fortschrittsbalken, Abbrechen; Auswurf waehrend des Rips abgelehnt. Gemessen am echten System (30.08.2026): Katalog findet makemkvcon64 (Program Files x86), HandBrakeCLI und flac (beide im rc11-Werkzeugordner LOCALAPPDATA\Rippy\tools). NEUER BEFUND: Nach dem abgebrochenen rc11-Rip vom Mittag sieht MakeMKV GAR KEIN Laufwerk mehr (MSG 5042, leere DRV-Liste, mit und ohne --noscan), waehrend die Storage-IOCTLs sauber antworten — MakeMKV spricht SCSI direkt. 5042 ist jetzt ein KRITISCHER_CODE mit Klartext-Abhilfe. Der volle Rip-Beweis (messung.rip.test.ts liegt bereit) braucht deshalb erst eine Hand am Geraet: Disc neu einlegen oder USB ab-/anstecken. 96 Tests gruen, Smoke gruen. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
a45069af5e
commit
844bca37ff
@@ -0,0 +1,57 @@
|
||||
// MESSUNG an echter Hardware: makemkvcon finden und die eingelegte Disc
|
||||
// befragen (Titel + Sprachen). Läuft nur auf Verlangen:
|
||||
//
|
||||
// RIPPY_MESSUNG=1 npx vitest run test/messung.makemkv.test.ts
|
||||
//
|
||||
// Der VOLLE Rip ist ein eigener Lauf (messung.rip.test.ts) — er dauert
|
||||
// je Disc 30–90 Minuten.
|
||||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
const messen = process.env.RIPPY_MESSUNG === '1' && process.platform === 'win32'
|
||||
|
||||
describe.skipIf(!messen)('makemkvcon am echten System', () => {
|
||||
it('wird über den Katalog gefunden', async () => {
|
||||
const { finden } = await import('../src/kern/werkzeuge/katalog')
|
||||
const pfad = finden('makemkv')
|
||||
console.log(`MESSUNG makemkvcon: ${pfad.length > 0 ? pfad : 'NICHT GEFUNDEN'}`)
|
||||
const handbrake = finden('handbrake')
|
||||
console.log(`MESSUNG HandBrakeCLI: ${handbrake.length > 0 ? handbrake : 'NICHT GEFUNDEN'}`)
|
||||
const flac = finden('flac')
|
||||
console.log(`MESSUNG flac: ${flac.length > 0 ? flac : 'NICHT GEFUNDEN'}`)
|
||||
expect(pfad.length).toBeGreaterThan(0)
|
||||
})
|
||||
|
||||
it('liest Titel und Sprachen der eingelegten Disc', { timeout: 360_000 }, async () => {
|
||||
const { finden } = await import('../src/kern/werkzeuge/katalog')
|
||||
const { titelInfoLesen } = await import('../src/kern/rip/makemkv')
|
||||
const { win32Api } = await import('../src/kern/laufwerk/win32')
|
||||
const { listOptischeLaufwerke } = await import('../src/kern/laufwerk/disc')
|
||||
|
||||
const programm = finden('makemkv')
|
||||
expect(programm.length).toBeGreaterThan(0)
|
||||
const geraete = listOptischeLaufwerke(win32Api())
|
||||
expect(geraete.length).toBeGreaterThan(0)
|
||||
|
||||
const info = await titelInfoLesen(programm, geraete[0])
|
||||
console.log(`MESSUNG Titel: ${info.titel.length}`)
|
||||
for (const t of info.titel.slice(0, 12)) {
|
||||
console.log(
|
||||
`MESSUNG #${t.nr}: ${Math.floor(t.dauerS / 60)}min ${t.dauerS % 60}s · ` +
|
||||
`${(t.groesseBytes / 1e9).toFixed(2)} GB · ${t.kapitel} Kapitel`,
|
||||
)
|
||||
}
|
||||
console.log(
|
||||
`MESSUNG Sprachen Ton: ${info.sprachen.audio.map((s) => `${s.lang}(${s.spuren})`).join(', ') || '—'}`,
|
||||
)
|
||||
console.log(
|
||||
`MESSUNG Sprachen Untertitel: ${info.sprachen.untertitel.map((s) => `${s.lang}(${s.spuren})`).join(', ') || '—'}`,
|
||||
)
|
||||
expect(info.titel.length).toBeGreaterThan(0)
|
||||
})
|
||||
})
|
||||
|
||||
describe.skipIf(messen)('Messung übersprungen', () => {
|
||||
it('läuft nur mit RIPPY_MESSUNG=1 unter Windows', () => {
|
||||
expect(true).toBe(true)
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user