fix(v5): Beta-Key mit @ kommt ganz an; Schlüssel-Stand ehrlich (rot statt „Rips laufen", nicht prüfbar ohne Laufwerk); Zeiten in Ortszeit
WAS: KEY_MUSTER nimmt alles bis Leerraum/HTML-Zeichen (der September-Key „T-…4BI@N5rPp" hat 68 Zeichen mit @; das alte Muster lieferte 62 und MakeMKV lief danach ohne Schlüssel). extractGueltigBis versteht „end of September 2026". Die Kette prüft zuerst den vorhandenen Schlüssel und lässt ihn stehen, wenn MakeMKV ihn annimmt (kein Überschreiben gekaufter Keys mehr); reg add wird auf Erfolg geprüft; 5042 ohne Lizenzzeile heißt „nicht prüfbar" statt „angenommen". Fenster: Ablehnung ist ROT mit dem Satz, dass Blu-rays dann nur noch in MakeMKVs Gnadenfrist laufen; die MakeMKV-Karte sagt, was Rippy in MakeMKVs Einstellungen schreibt. Ein neuer Werkzeug-Pfad wird sofort gesucht, ein neuer eigener Schlüssel sofort geprüft. datumKurz zeigt Ortszeit statt UTC. WARUM: Durchsicht 12.09.2026, Funde F1, F5, F12, F13 und A2 — am echten Forum-HTML und an makemkvcon ohne Laufwerk gemessen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
6f1add480e
commit
12b9720386
@@ -112,7 +112,9 @@ export default function App() {
|
||||
const w = verbindung.werkzeuge
|
||||
const werkzeugTon = w === null ? 'grau' : w.makemkvcon.length > 0 && w.handbrake.length > 0 ? 'gruen' : w.makemkvcon.length > 0 ? 'warn' : 'rot'
|
||||
const s = verbindung.schluessel
|
||||
const schluesselTon = s === null ? 'grau' : s.angenommen === true ? 'gruen' : s.weiterBetrieb ? 'warn' : 'rot'
|
||||
// 5.7.0 (F1/F5): abgelehnt oder fehlend = ROT (Blu-rays laufen nicht),
|
||||
// nicht prüfbar (kein Laufwerk) = grau — nie mehr ein gelbes „läuft".
|
||||
const schluesselTon = s === null ? 'grau' : s.angenommen === true ? 'gruen' : s.angenommen === null ? 'grau' : 'rot'
|
||||
const arbeit = verbindung.speicher?.arbeit ?? null
|
||||
const speicherTon = arbeit === null ? 'grau' : !arbeit.ok ? 'rot' : arbeit.freiBytes < SEHR_WENIG_FREI_BYTES ? 'rot' : arbeit.freiBytes < WENIG_FREI_BYTES ? 'warn' : 'gruen'
|
||||
const updateTon = haupt === null ? 'grau' : haupt.update.neueVersion.length > 0 ? 'warn' : haupt.update.letzteErfolgreichePruefung.length > 0 ? 'gruen' : 'grau'
|
||||
|
||||
@@ -32,9 +32,14 @@ export function dauerGrob(s: number): string {
|
||||
return `${Math.floor(m / 60)} h ${String(m % 60).padStart(2, '0')} min`
|
||||
}
|
||||
|
||||
/** ISO-Zeit → „2026-09-12 21:30" in DEINER Uhrzeit (5.7.0, Durchsicht F12):
|
||||
* vorher wurde der UTC-Text abgeschnitten — 21:30 Uhr stand als 19:30 da. */
|
||||
export function datumKurz(iso: string | null): string {
|
||||
if (iso === null || iso.length < 16) return '—'
|
||||
return iso.slice(0, 16).replace('T', ' ')
|
||||
const d = new Date(iso)
|
||||
if (Number.isNaN(d.getTime())) return iso.slice(0, 16).replace('T', ' ')
|
||||
const z = (n: number): string => String(n).padStart(2, '0')
|
||||
return `${d.getFullYear()}-${z(d.getMonth() + 1)}-${z(d.getDate())} ${z(d.getHours())}:${z(d.getMinutes())}`
|
||||
}
|
||||
|
||||
/** Restzeit in Sekunden als Klartext (5.6.0, HandBrakes ETA): -1/fehlend =
|
||||
|
||||
@@ -22,7 +22,7 @@ import type {
|
||||
TitelRolle,
|
||||
TitelStand,
|
||||
} from '../../gemeinsam/nachrichten'
|
||||
import { DialogRahmen, IconDisc, KNOPF_GOLD, dauerText, gb, gbKurz, posterUrlKlein, sprachenVorbelegt } from '../bausteine'
|
||||
import { DialogRahmen, IconDisc, KNOPF_GOLD, datumKurz, dauerText, gb, gbKurz, posterUrlKlein, sprachenVorbelegt } from '../bausteine'
|
||||
import { metadatenSuchen, ripStarten } from '../kernverbindung'
|
||||
|
||||
/** Sprach-Chips eines Titels — anklickbar, außerhalb des Auswahl-Labels
|
||||
@@ -410,7 +410,7 @@ export function TitelWahlDialog({
|
||||
</label>
|
||||
<p className="min-w-[200px] flex-1 text-[11px] leading-4 text-nebel">
|
||||
{merkerGilt && merker !== null
|
||||
? `Serien-Merker: Die vorige Disc dieser Serie endete mit Folge ${merker.naechsteFolge - 1} (${merker.wann.slice(0, 10)}) — Rippy zählt ab ${merker.naechsteFolge} weiter. Stimmt das nicht, ändere die Zahl.`
|
||||
? `Serien-Merker: Die vorige Disc dieser Serie endete mit Folge ${merker.naechsteFolge - 1} (${datumKurz(merker.wann).slice(0, 10)}) — Rippy zählt ab ${merker.naechsteFolge} weiter. Stimmt das nicht, ändere die Zahl.`
|
||||
: 'Leer heißt: Rippy ordnet die Folgen über die TMDb-Laufzeiten zu, und nur, wenn es eindeutig ist. Weißt du es besser („auf Disc 2 sind die Folgen 3 und 4"), trag es hier ein — dann zählt Rippy fortlaufend in Disc-Reihenfolge.'}
|
||||
{info !== undefined && info.discNr !== null && ` Die Disc nennt sich selbst Disc ${info.discNr}.`}
|
||||
</p>
|
||||
|
||||
@@ -406,16 +406,19 @@ export function MakemkvKarte({ verbindung }: { verbindung: Verbindung }) {
|
||||
<p className="font-mono text-xs text-nebel">Schlüssel wird geprüft …</p>
|
||||
) : (
|
||||
<>
|
||||
{/* 5.7.0 (F1/F5): Ein abgelehnter oder fehlender Schlüssel ist
|
||||
ROT — Blu-rays laufen dann nur noch in MakeMKVs Gnadenfrist.
|
||||
„Nicht prüfbar" (kein Laufwerk) ist grau, kein Erfolg. */}
|
||||
<p className="flex items-center gap-2 font-mono text-[10.5px] tracking-wider">
|
||||
<span className={`inline-block h-2 w-2 rounded-full ${s.angenommen === true ? 'bg-gruen' : s.weiterBetrieb ? 'bg-warn' : 'bg-rot'}`} />
|
||||
<span className={s.angenommen === true ? 'text-gruen' : s.weiterBetrieb ? 'text-warn' : 'text-rot'}>
|
||||
{s.angenommen === true ? 'SCHLÜSSEL ANGENOMMEN' : s.weiterBetrieb ? 'BETA-MODUS — RIPS LAUFEN' : 'AUSFALL'}
|
||||
<span className={`inline-block h-2 w-2 rounded-full ${s.angenommen === true ? 'bg-gruen' : s.angenommen === null ? 'bg-tinte/25' : 'bg-rot'}`} />
|
||||
<span className={s.angenommen === true ? 'text-gruen' : s.angenommen === null ? 'text-nebel' : 'text-rot'}>
|
||||
{s.angenommen === true ? 'SCHLÜSSEL ANGENOMMEN' : s.angenommen === null ? 'NICHT PRÜFBAR — KEIN LAUFWERK' : 'KEIN GÜLTIGER SCHLÜSSEL — BLU-RAY-RIPS LAUFEN NICHT'}
|
||||
</span>
|
||||
{s.version.length > 0 && <span className="ml-auto text-nebel">MakeMKV {s.version}</span>}
|
||||
</p>
|
||||
<p className="mt-1.5 text-xs leading-5 text-dunst">{s.text}</p>
|
||||
<p className="mt-1 font-mono text-[10px] text-nebel">
|
||||
zuletzt geprüft: {s.geholtAm.slice(0, 16).replace('T', ' ')}
|
||||
zuletzt geprüft: {datumKurz(s.geholtAm)}
|
||||
{s.gueltigBis.length > 0 && ` · Key gültig bis ${s.gueltigBis}`}
|
||||
</p>
|
||||
</>
|
||||
@@ -448,11 +451,14 @@ export function MakemkvKarte({ verbindung }: { verbindung: Verbindung }) {
|
||||
)}
|
||||
<Feld
|
||||
name="Eigener Schlüssel (Dauerlizenz)"
|
||||
hinweis="schlägt den automatischen Beta-Key — leer lassen, wenn keiner gekauft ist"
|
||||
hinweis="schlägt den automatischen Beta-Key — leer lassen, wenn keiner gekauft ist; nach dem Eintragen prüft Rippy sofort"
|
||||
geheim
|
||||
wert={werte['makemkvAppKey'] ?? ''}
|
||||
aufAendern={(w) => setzen('makemkvAppKey', w)}
|
||||
/>
|
||||
<p className="text-[11px] leading-4 text-nebel">
|
||||
Rippy schreibt in MakeMKVs eigene Einstellungen: den Schlüssel, die Auswahlregel „alle Spuren behalten" und den Kanal für 4K-Disc-Schlüssel. Deshalb nimmt auch das MakeMKV-Programm seitdem alle Tonspuren und Untertitel mit — die Dateien dort werden größer, verloren geht nichts.
|
||||
</p>
|
||||
</SektionsKarte>
|
||||
)
|
||||
}
|
||||
@@ -571,7 +577,7 @@ export function UpdateKarte({ verbindung, haupt }: { verbindung: Verbindung; hau
|
||||
<p>
|
||||
<span className="text-dunst">Stand:</span> {haupt.update.text}
|
||||
</p>
|
||||
{haupt.update.letzteErfolgreichePruefung.length > 0 && <p>letzte erfolgreiche Prüfung: {haupt.update.letzteErfolgreichePruefung.slice(0, 16).replace('T', ' ')}</p>}
|
||||
{haupt.update.letzteErfolgreichePruefung.length > 0 && <p>letzte erfolgreiche Prüfung: {datumKurz(haupt.update.letzteErfolgreichePruefung)}</p>}
|
||||
{haupt.update.neueVersion.length > 0 && <p className="text-gold-hell">Version {haupt.update.neueVersion} gefunden — die Karte in der Übersicht zeigt, was neu ist.</p>}
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -26,6 +26,7 @@ import {
|
||||
PHASEN_MONO,
|
||||
TYP_NAMEN,
|
||||
backdropUrl,
|
||||
datumKurz,
|
||||
discHerkunft,
|
||||
gb,
|
||||
logoUrl,
|
||||
@@ -294,7 +295,7 @@ export function LaufwerkKachel({
|
||||
)}
|
||||
{erkannt && <Badge text={`${sicherheitsWort(info.confidence)}`} ton={info.confidence >= 0.8 ? 'gruen' : 'gelb'} />}
|
||||
{info !== undefined && discHerkunft(info).length > 0 && <Badge text={discHerkunft(info)} ton="blau" />}
|
||||
{info !== undefined && info.schonGerippt !== null && <Badge text={`schon gerippt am ${info.schonGerippt.slice(0, 10)}`} ton="gelb" />}
|
||||
{info !== undefined && info.schonGerippt !== null && <Badge text={`schon gerippt am ${datumKurz(info.schonGerippt).slice(0, 10)}`} ton="gelb" />}
|
||||
</div>
|
||||
{/* Was Rippy NACH dem Info-Lauf dazugelernt hat (Erkennung v2). */}
|
||||
{erkannt && info.hinweise.length > 0 && (
|
||||
|
||||
Reference in New Issue
Block a user