release: prepare v2.0.83
This commit is contained in:
@@ -3701,10 +3701,11 @@ export class DownloadManager extends EventEmitter {
|
||||
item.speedBps = 0;
|
||||
item.downloadedBytes = 0;
|
||||
item.totalBytes = null;
|
||||
item.progressPercent = 0;
|
||||
item.resumable = true;
|
||||
item.attempts = 0;
|
||||
item.lastError = "";
|
||||
item.progressPercent = 0;
|
||||
item.resumable = true;
|
||||
item.attempts = 0;
|
||||
delete item.archiveRecoveryRedownloads;
|
||||
item.lastError = "";
|
||||
item.fullStatus = "Wartet";
|
||||
item.provider = null;
|
||||
item.updatedAt = nowMs();
|
||||
@@ -6065,10 +6066,11 @@ export class DownloadManager extends EventEmitter {
|
||||
item.downloadedBytes = 0;
|
||||
item.totalBytes = null;
|
||||
item.progressPercent = 0;
|
||||
item.speedBps = 0;
|
||||
item.attempts = 0;
|
||||
item.retries = 0;
|
||||
item.lastError = "";
|
||||
item.speedBps = 0;
|
||||
item.attempts = 0;
|
||||
item.retries = 0;
|
||||
delete item.archiveRecoveryRedownloads;
|
||||
item.lastError = "";
|
||||
item.resumable = true;
|
||||
item.targetPath = "";
|
||||
item.provider = null;
|
||||
@@ -6147,10 +6149,11 @@ export class DownloadManager extends EventEmitter {
|
||||
item.downloadedBytes = 0;
|
||||
item.totalBytes = null;
|
||||
item.progressPercent = 0;
|
||||
item.speedBps = 0;
|
||||
item.attempts = 0;
|
||||
item.retries = 0;
|
||||
item.lastError = "";
|
||||
item.speedBps = 0;
|
||||
item.attempts = 0;
|
||||
item.retries = 0;
|
||||
delete item.archiveRecoveryRedownloads;
|
||||
item.lastError = "";
|
||||
item.resumable = true;
|
||||
item.targetPath = "";
|
||||
item.provider = null;
|
||||
@@ -7819,44 +7822,66 @@ export class DownloadManager extends EventEmitter {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const inspectedArchiveItems = archiveItems
|
||||
.map((item) => ({ item, state: inspectPackageItemDiskState(pkg, item) }));
|
||||
const corruptArchiveItems = inspectedArchiveItems
|
||||
.filter(({ state }) => state.reason !== "ok");
|
||||
|
||||
if (corruptArchiveItems.length === 0) {
|
||||
const firstPart = inspectedArchiveItems.find(({ state }) => state.diskPath);
|
||||
let hasValidSignature = false;
|
||||
if (firstPart?.state.diskPath) {
|
||||
try {
|
||||
const fd = fs.openSync(firstPart.state.diskPath, "r");
|
||||
try {
|
||||
const header = Buffer.alloc(8);
|
||||
fs.readSync(fd, header, 0, 8, 0);
|
||||
hasValidSignature =
|
||||
(header[0] === 0x52 && header[1] === 0x61 && header[2] === 0x72 && header[3] === 0x21 && header[4] === 0x1a && header[5] === 0x07) ||
|
||||
(header[0] === 0x37 && header[1] === 0x7a && header[2] === 0xbc && header[3] === 0xaf) ||
|
||||
(header[0] === 0x50 && header[1] === 0x4b && header[2] === 0x03 && header[3] === 0x04);
|
||||
} finally {
|
||||
fs.closeSync(fd);
|
||||
}
|
||||
} catch { }
|
||||
}
|
||||
|
||||
if (hasValidSignature) {
|
||||
logger.warn(
|
||||
`Auto-Recovery (${scope}): ${failure.archiveName} uebersprungen - ` +
|
||||
`Dateien haben korrekte Groesse und gueltige Archiv-Signatur, ` +
|
||||
`wahrscheinlicher Passwort-/Extractor-Fall statt defektem Download`
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
logger.warn(
|
||||
`Auto-Recovery (${scope}): ${failure.archiveName} - Dateien korrekte Groesse aber ungueltige Archiv-Signatur, ` +
|
||||
`erzwinge Re-Download aller ${archiveItems.length} Parts`
|
||||
);
|
||||
corruptArchiveItems.push(...inspectedArchiveItems);
|
||||
const inspectedArchiveItems = archiveItems
|
||||
.map((item) => ({ item, state: inspectPackageItemDiskState(pkg, item) }));
|
||||
const recoveryRedownloads = Math.max(
|
||||
0,
|
||||
...archiveItems.map((item) => Math.max(0, Math.floor(Number(item.archiveRecoveryRedownloads) || 0)))
|
||||
);
|
||||
if (recoveryRedownloads >= 1) {
|
||||
logger.warn(
|
||||
`Auto-Recovery (${scope}): ${failure.archiveName} nicht erneut heruntergeladen - ` +
|
||||
`automatischer Archiv-Neudownload bereits versucht`
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const corruptArchiveItems = inspectedArchiveItems
|
||||
.filter(({ state }) => state.reason !== "ok");
|
||||
|
||||
if (corruptArchiveItems.length === 0) {
|
||||
if (failure.category === "crc_error") {
|
||||
logger.warn(
|
||||
`Auto-Recovery (${scope}): ${failure.archiveName} meldet CRC-Fehler trotz korrekter Größe und Archiv-Signatur, ` +
|
||||
`erzwinge einmaligen Neu-Download aller ${archiveItems.length} Parts`
|
||||
);
|
||||
corruptArchiveItems.push(...inspectedArchiveItems);
|
||||
}
|
||||
|
||||
if (failure.category !== "crc_error") {
|
||||
const firstPart = inspectedArchiveItems.find(({ state }) => state.diskPath);
|
||||
let hasValidSignature = false;
|
||||
if (firstPart?.state.diskPath) {
|
||||
try {
|
||||
const fd = fs.openSync(firstPart.state.diskPath, "r");
|
||||
try {
|
||||
const header = Buffer.alloc(8);
|
||||
fs.readSync(fd, header, 0, 8, 0);
|
||||
hasValidSignature =
|
||||
(header[0] === 0x52 && header[1] === 0x61 && header[2] === 0x72 && header[3] === 0x21 && header[4] === 0x1a && header[5] === 0x07) ||
|
||||
(header[0] === 0x37 && header[1] === 0x7a && header[2] === 0xbc && header[3] === 0xaf) ||
|
||||
(header[0] === 0x50 && header[1] === 0x4b && header[2] === 0x03 && header[3] === 0x04);
|
||||
} finally {
|
||||
fs.closeSync(fd);
|
||||
}
|
||||
} catch { }
|
||||
}
|
||||
|
||||
if (hasValidSignature) {
|
||||
logger.warn(
|
||||
`Auto-Recovery (${scope}): ${failure.archiveName} übersprungen - ` +
|
||||
`Dateien haben korrekte Größe und gültige Archiv-Signatur, ` +
|
||||
`wahrscheinlicher Passwort-/Extractor-Fall statt defektem Download`
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
logger.warn(
|
||||
`Auto-Recovery (${scope}): ${failure.archiveName} - Dateien korrekte Größe aber ungültige Archiv-Signatur, ` +
|
||||
`erzwinge Neu-Download aller ${archiveItems.length} Parts`
|
||||
);
|
||||
corruptArchiveItems.push(...inspectedArchiveItems);
|
||||
}
|
||||
}
|
||||
|
||||
const queuedAt = nowMs();
|
||||
@@ -7872,13 +7897,19 @@ export class DownloadManager extends EventEmitter {
|
||||
}
|
||||
this.releaseTargetPath(item.id);
|
||||
this.dropItemContribution(item.id);
|
||||
item.targetPath = "";
|
||||
item.status = "queued";
|
||||
item.attempts = 0;
|
||||
item.downloadedBytes = 0;
|
||||
item.progressPercent = 0;
|
||||
item.speedBps = 0;
|
||||
item.lastError = failure.errorText;
|
||||
item.targetPath = "";
|
||||
item.status = "queued";
|
||||
item.attempts = 0;
|
||||
item.archiveRecoveryRedownloads = recoveryRedownloads + 1;
|
||||
item.downloadedBytes = 0;
|
||||
item.totalBytes = null;
|
||||
item.progressPercent = 0;
|
||||
item.speedBps = 0;
|
||||
item.provider = null;
|
||||
item.providerLabel = undefined;
|
||||
item.providerAccountId = undefined;
|
||||
item.providerAccountLabel = undefined;
|
||||
item.lastError = failure.errorText;
|
||||
item.fullStatus = reason;
|
||||
item.updatedAt = queuedAt;
|
||||
changed += 1;
|
||||
|
||||
+5
-2
@@ -1039,8 +1039,11 @@ export function normalizeLoadedSession(raw: unknown): SessionState {
|
||||
targetPath: asText(item.targetPath),
|
||||
metadataRenameTargetPath: asText(item.metadataRenameTargetPath) || undefined,
|
||||
resumable: item.resumable === undefined ? true : Boolean(item.resumable),
|
||||
attempts: clampNumber(item.attempts, 0, 0, 10_000),
|
||||
lastError: asText(item.lastError),
|
||||
attempts: clampNumber(item.attempts, 0, 0, 10_000),
|
||||
archiveRecoveryRedownloads: item.archiveRecoveryRedownloads === undefined
|
||||
? undefined
|
||||
: clampNumber(item.archiveRecoveryRedownloads, 0, 0, 1),
|
||||
lastError: asText(item.lastError),
|
||||
fullStatus: asText(item.fullStatus),
|
||||
onlineStatus: VALID_ONLINE_STATUSES.has(onlineStatusRaw) ? onlineStatusRaw as "online" | "offline" | "checking" : undefined,
|
||||
createdAt: clampNumber(item.createdAt, now, 0, Number.MAX_SAFE_INTEGER),
|
||||
|
||||
+3
-2
@@ -492,8 +492,9 @@ export interface DownloadItem {
|
||||
targetPath: string;
|
||||
metadataRenameTargetPath?: string;
|
||||
resumable: boolean;
|
||||
attempts: number;
|
||||
lastError: string;
|
||||
attempts: number;
|
||||
archiveRecoveryRedownloads?: number;
|
||||
lastError: string;
|
||||
fullStatus: string;
|
||||
createdAt: number;
|
||||
updatedAt: number;
|
||||
|
||||
Reference in New Issue
Block a user