WAS: Der Rip endet, sobald die Roh-Dateien liegen; die Kompression laeuft danach in einer Warteschlange (eine zur Zeit), das Laufwerk ist frei fuer die naechste Disc. Jeder Rip ist jetzt ein Datensatz (Tabelle vorgaenge, Schema 4): Roh-Ordner, Zielordner, Phase, Auftrag als JSON. Darauf bauen: Roh-Aufraeumen nach Regel (Vorgabe 7 Tage, nur bei gelungener Kompression und nur wenn jede fertige Datei da und nicht leer ist), Wiederholen ab Kompression, Aufraeumen halber Dateien nach Abbruch/Fehler, Wiederaufnahme nach Neustart. Unkomprimierte Rips (4K, kein HandBrake) werden in den Zielordner VERSCHOBEN statt unter roh\ liegen zu bleiben. Sprachen je Titel reisen vom Info-Lauf (SINFO) bis in HandBrake; fremder Ton schaltet den deutschen Untertitel vor (--subtitle-default=1). Vor der Kompression prueft ein HandBrake-Scan die Roh-Datei. MakeMKVs Auswahlregel wird gesetzt, wenn keine steht, damit alle Sprachen in die Roh-Datei kommen. Staffel und erste Folge von Hand schlagen die Laufzeit-Raterei. Durchgehender Fortschritt, nach Groesse gewichtet. Erkennung v2: leere TMDb-Eintraege (Stubs) zaehlen nicht, Laufzeit wird nach dem Info-Lauf gegen TMDb gehalten, Titel-Struktur als Fingerabdruck, bdmt_deu als zweite Titel-Variante. TMDb liefert Logo, Tagline, Bewertung, FSK und Besetzung in derselben Anfrage. Laufwerks-Gesundheit aus dem Windows-Ereignisprotokoll (wevtutil): Disc oder Hardware. WARUM: Uebergabe-Punkte 1-5, 8-12 des SAVEPOINT vom 01.09.2026 — vom Commander gutgeheissen (7 Tage / Untertitel vorgewaehlt / entkoppelte Kompression waren seine Wahl). GEMESSEN (Regel D): HandBrake 1.11 Sprach-Schalter an einer ffmpeg- Testdatei (jpn/deu/deu/eng + deu/eng), HandBrake --scan --json Format, TMDb movie/149 + tv/46296 mit append_to_response, wevtutil /f:xml an diesem PC (338x cdrom 7, 8x cdrom 11 in 30 Tagen), makemkvcon --minlength, MakeMKV-Auswahlregel laut forum.makemkv.com t=4386. 348 Tests gruen (vorher 261), Typpruefung und Bau gruen. Oberflaeche folgt im naechsten Schritt. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
71 lines
3.5 KiB
TypeScript
71 lines
3.5 KiB
TypeScript
// Tests der Laufwerks-Gesundheit (kern/laufwerk/ereignisse.ts, 5.4.0) —
|
|
// an der ECHTEN wevtutil-Ausgabe dieses PCs (01.09.2026): cdrom 7
|
|
// (fehlerhafter Block, der Spartacus-Defekt), cdrom 11 (Controllerfehler,
|
|
// der USB-Aussetzer).
|
|
import { describe, expect, it } from 'vitest'
|
|
import { beurteilen, buildWevtutilArgs, ereignisseAusXml, xpathFuer } from '../src/kern/laufwerk/ereignisse'
|
|
|
|
/** Drei Ereignisse, so wie wevtutil /f:xml sie schreibt — ohne Zeilenumbrüche. */
|
|
const XML =
|
|
"<Event xmlns='http://schemas.microsoft.com/win/2004/08/events/event'><System><Provider Name='cdrom'/><EventID Qualifiers='49156'>7</EventID><Version>0</Version><Level>2</Level><TimeCreated SystemTime='2026-09-01T18:32:42.3868580Z'/><EventRecordID>135751</EventRecordID><Channel>System</Channel><Computer>TobisNicerPC</Computer></System><EventData><Data>\\Device\\CdRom0</Data><Binary>0300</Binary></EventData></Event>" +
|
|
"<Event xmlns='http://schemas.microsoft.com/win/2004/08/events/event'><System><Provider Name='cdrom'/><EventID Qualifiers='49156'>7</EventID><TimeCreated SystemTime='2026-09-01T18:32:39.6629681Z'/><Channel>System</Channel></System><EventData><Data>\\Device\\CdRom0</Data></EventData></Event>" +
|
|
"<Event xmlns='http://schemas.microsoft.com/win/2004/08/events/event'><System><Provider Name='cdrom'/><EventID Qualifiers='49156'>11</EventID><TimeCreated SystemTime='2026-09-01T18:17:39.6632548Z'/><Channel>System</Channel></System><EventData><Data>\\Device\\CdRom0</Data></EventData></Event>"
|
|
|
|
describe('ereignisseAusXml', () => {
|
|
it('liest Provider, ID, Zeit und Gerät je Ereignis', () => {
|
|
const e = ereignisseAusXml(XML)
|
|
expect(e).toHaveLength(3)
|
|
expect(e[0]).toEqual({ zeit: '2026-09-01T18:32:42.3868580Z', provider: 'cdrom', id: 7, geraet: '\\Device\\CdRom0' })
|
|
expect(e[2].id).toBe(11)
|
|
})
|
|
it('leere Ausgabe = keine Ereignisse', () => {
|
|
expect(ereignisseAusXml('')).toEqual([])
|
|
expect(ereignisseAusXml('\r\n')).toEqual([])
|
|
})
|
|
})
|
|
|
|
describe('beurteilen — Disc oder Hardware?', () => {
|
|
const alle = ereignisseAusXml(XML)
|
|
|
|
it('ein Controllerfehler dabei: Hardware — Port am Mainboard probieren', () => {
|
|
const b = beurteilen(alle, 24)
|
|
expect(b.urteil).toBe('hardware')
|
|
expect(b.controllerfehler).toBe(1)
|
|
expect(b.fehlerhafteBloecke).toBe(2)
|
|
expect(b.text).toContain('Mainboard')
|
|
expect(b.letzte).toHaveLength(3)
|
|
expect(b.letzte[0]).toContain('fehlerhafter Block')
|
|
})
|
|
|
|
it('nur fehlerhafte Blöcke: die Disc', () => {
|
|
const b = beurteilen(alle.filter((e) => e.id === 7), 24)
|
|
expect(b.urteil).toBe('disc')
|
|
expect(b.text).toContain('DISC')
|
|
})
|
|
|
|
it('nichts: ruhig', () => {
|
|
const b = beurteilen([], 24)
|
|
expect(b.urteil).toBe('ruhig')
|
|
expect(b.text).toContain('nichts')
|
|
})
|
|
|
|
it('seit einem Zeitpunkt: nur die jüngeren zählen', () => {
|
|
const b = beurteilen(alle, 24, new Date('2026-09-01T18:30:00Z'))
|
|
expect(b.controllerfehler).toBe(0)
|
|
expect(b.urteil).toBe('disc')
|
|
})
|
|
})
|
|
|
|
describe('die wevtutil-Argumente (Regel D: so gemessen)', () => {
|
|
it('XPath auf cdrom/disk mit Zeitfenster, XML, neueste zuerst', () => {
|
|
expect(xpathFuer(24)).toBe("*[System[Provider[@Name='cdrom' or @Name='disk'] and TimeCreated[timediff(@SystemTime) <= 86400000]]]")
|
|
const args = buildWevtutilArgs(24, 50)
|
|
expect(args[0]).toBe('qe')
|
|
expect(args[1]).toBe('System')
|
|
expect(args[2]).toBe(`/q:${xpathFuer(24)}`)
|
|
expect(args).toContain('/f:xml')
|
|
expect(args).toContain('/c:50')
|
|
expect(args).toContain('/rd:true')
|
|
})
|
|
})
|