feat(v5): Kern 5.4.0 — Vorgaenge, Kompressions-Warteschlange, Roh-Aufraeumen, Sprachen je Titel, Erkennung v2
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>
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
d70a81d194
commit
3f7f962dff
@@ -71,3 +71,59 @@ describe('Datenbank', () => {
|
||||
expect(() => new Datenbank(kaputt)).toThrow()
|
||||
})
|
||||
})
|
||||
|
||||
// ── Vorgänge (5.4.0): welcher Roh-Ordner gehört zu welchem Rip ──────────
|
||||
describe('Datenbank — Vorgänge', () => {
|
||||
const vorgang = {
|
||||
id: 'bluray-2026-09-01T20-00-00',
|
||||
laufwerk: 'G',
|
||||
typ: 'bluray',
|
||||
titel: 'Spartacus',
|
||||
jahr: 2010,
|
||||
phase: 'rippt' as const,
|
||||
begonnen: '2026-09-01T20:00:00.000Z',
|
||||
beendet: null,
|
||||
rohOrdner: 'E:\Rippy\roh\bluray-2026-09-01T20-00-00',
|
||||
rohBytes: 0,
|
||||
rohGeloeschtAm: null,
|
||||
zielOrdner: '',
|
||||
fertigBytes: 0,
|
||||
komprimiert: false,
|
||||
preset: '',
|
||||
fehler: '',
|
||||
auftrag: '{}',
|
||||
lesefehler: false,
|
||||
fertigeDateien: '[]',
|
||||
}
|
||||
|
||||
it('anlegen, lesen, aktualisieren (nur die genannten Felder), listen, löschen', () => {
|
||||
const db = new Datenbank(':memory:')
|
||||
aufraeumen.push(() => db.schliessen())
|
||||
db.vorgangAnlegen(vorgang)
|
||||
expect(db.vorgangLesen(vorgang.id)).toEqual(vorgang)
|
||||
db.vorgangAktualisieren(vorgang.id, { phase: 'fertig', komprimiert: true, fertigBytes: 4800, beendet: '2026-09-01T21:00:00.000Z' })
|
||||
const neu = db.vorgangLesen(vorgang.id)!
|
||||
expect(neu.phase).toBe('fertig')
|
||||
expect(neu.komprimiert).toBe(true)
|
||||
expect(neu.fertigBytes).toBe(4800)
|
||||
expect(neu.titel).toBe('Spartacus')
|
||||
expect(neu.rohGeloeschtAm).toBeNull()
|
||||
db.vorgangAnlegen({ ...vorgang, id: 'dvd-2026-09-02T10-00-00', begonnen: '2026-09-02T10:00:00.000Z' })
|
||||
expect(db.vorgangListe().map((v) => v.id)).toEqual(['dvd-2026-09-02T10-00-00', vorgang.id])
|
||||
db.vorgangLoeschen(vorgang.id)
|
||||
expect(db.vorgangLesen(vorgang.id)).toBeNull()
|
||||
expect(db.vorgangAktualisieren('gibt-es-nicht', { phase: 'fertig' })).toBeUndefined()
|
||||
})
|
||||
|
||||
it('Schema 3 → 4: eine Bestands-Datenbank bekommt die Tabelle ohne Datenverlust', () => {
|
||||
const pfad = frischerPfad()
|
||||
const alt = new Datenbank(pfad)
|
||||
alt.einstellungSchreiben('ablage', 'E:\Rippy')
|
||||
alt.schliessen()
|
||||
const neu = new Datenbank(pfad)
|
||||
aufraeumen.push(() => neu.schliessen())
|
||||
expect(neu.einstellungLesen('ablage')).toBe('E:\Rippy')
|
||||
expect(neu.vorgangListe()).toEqual([])
|
||||
expect(neu.schemaVersion()).toBe(SCHEMA_VERSION)
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user