Feature: Tonspur-Ergebnis sichtbar am Paket (audioStripSummary)
Die Antwort auf "warum hat Paket X noch .DL.?" steht bisher nur in den Rename-/Item-Logs — "kein Deutsch-Tag" ist INFO-Level und taucht nirgends im UI auf. Jetzt speichert keepGermanAudioOnlyImpl pro Paket eine Zusammenfassung (remuxed/kept-single/ohne-DE-Tag/ffmpeg-fehlt/Fehler + bis zu 100 Datei-Details mit Aktion, Grund und erkannten Sprachen) direkt am PackageEntry: - Status-Spalte zeigt "Tonspur: 5 OK / 1 ohne DE-Tag / ffmpeg fehlt" (rot bei Auffaelligkeiten, flacher Stil), Datei-Details als Tooltip. - Auch der ffmpeg-nicht-gefunden-Fruehausstieg schreibt die Summary. - pkg.updatedAt wird gesetzt + Feld im Paket-Delta-Hash, damit der Snapshot die Aenderung pusht; normalizeLoadedSession whitelistet das Feld mit Shape-Validierung, sonst waere es nach jedem App-Neustart weg. - 2 neue Integrationstests (Summary-Zaehler + ffmpeg-fehlt-Pfad).
This commit is contained in:
+33
-1
@@ -3,7 +3,7 @@ import fsp from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { getDebridLinkApiKeyIds } from "../shared/debrid-link-keys";
|
||||
import { getMegaDebridAccountIds } from "../shared/mega-debrid-accounts";
|
||||
import { AppSettings, BandwidthScheduleEntry, DebridAccountStatus, DebridFallbackProvider, DebridProvider, DownloadItem, DownloadStatus, HistoryEntry, HistoryRetentionMode, PackageEntry, PackagePriority, SessionState } from "../shared/types";
|
||||
import { AppSettings, AudioStripSummary, BandwidthScheduleEntry, DebridAccountStatus, DebridFallbackProvider, DebridProvider, DownloadItem, DownloadStatus, HistoryEntry, HistoryRetentionMode, PackageEntry, PackagePriority, SessionState } from "../shared/types";
|
||||
import { getProviderUsageDayKey } from "../shared/provider-daily-limits";
|
||||
import { defaultSettings } from "./constants";
|
||||
import { logger } from "./logger";
|
||||
@@ -589,6 +589,37 @@ function asRecord(value: unknown): Record<string, unknown> | null {
|
||||
return value as Record<string, unknown>;
|
||||
}
|
||||
|
||||
function normalizeAudioStripSummary(raw: unknown): AudioStripSummary | undefined {
|
||||
const parsed = asRecord(raw);
|
||||
if (!parsed) {
|
||||
return undefined;
|
||||
}
|
||||
const files = Array.isArray(parsed.files)
|
||||
? parsed.files.slice(0, 100).flatMap((entry) => {
|
||||
const file = asRecord(entry);
|
||||
if (!file) {
|
||||
return [];
|
||||
}
|
||||
const name = asText(file.name);
|
||||
if (!name) {
|
||||
return [];
|
||||
}
|
||||
const languages = asText(file.languages);
|
||||
return [{ name, action: asText(file.action), reason: asText(file.reason), ...(languages ? { languages } : {}) }];
|
||||
})
|
||||
: [];
|
||||
return {
|
||||
at: clampNumber(parsed.at, 0, 0, Number.MAX_SAFE_INTEGER),
|
||||
candidates: clampNumber(parsed.candidates, 0, 0, 1_000_000),
|
||||
remuxed: clampNumber(parsed.remuxed, 0, 0, 1_000_000),
|
||||
keptSingle: clampNumber(parsed.keptSingle, 0, 0, 1_000_000),
|
||||
skippedNoGerman: clampNumber(parsed.skippedNoGerman, 0, 0, 1_000_000),
|
||||
skippedNoTool: clampNumber(parsed.skippedNoTool, 0, 0, 1_000_000),
|
||||
failed: clampNumber(parsed.failed, 0, 0, 1_000_000),
|
||||
files
|
||||
};
|
||||
}
|
||||
|
||||
function readSettingsFile(filePath: string): AppSettings | null {
|
||||
try {
|
||||
const parsed = JSON.parse(fs.readFileSync(filePath, "utf8")) as AppSettings;
|
||||
@@ -689,6 +720,7 @@ export function normalizeLoadedSession(raw: unknown): SessionState {
|
||||
cancelled: Boolean(pkg.cancelled),
|
||||
enabled: pkg.enabled === undefined ? true : Boolean(pkg.enabled),
|
||||
priority: VALID_PACKAGE_PRIORITIES.has(asText(pkg.priority)) ? asText(pkg.priority) as PackagePriority : "normal",
|
||||
audioStripSummary: normalizeAudioStripSummary(pkg.audioStripSummary),
|
||||
downloadStartedAt: clampNumber(pkg.downloadStartedAt, 0, 0, Number.MAX_SAFE_INTEGER),
|
||||
downloadCompletedAt: clampNumber(pkg.downloadCompletedAt, 0, 0, Number.MAX_SAFE_INTEGER),
|
||||
createdAt: clampNumber(pkg.createdAt, now, 0, Number.MAX_SAFE_INTEGER),
|
||||
|
||||
Reference in New Issue
Block a user