Compare commits

..

No commits in common. "fba05d2add7da456a666031dee349046ef6db7b4" and "3e2d70485cd5e4e4d88f2da092a6e987021803a6" have entirely different histories.

5 changed files with 5 additions and 39 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "real-debrid-downloader", "name": "real-debrid-downloader",
"version": "1.6.97", "version": "1.6.96",
"description": "Desktop downloader", "description": "Desktop downloader",
"main": "build/main/main/main.js", "main": "build/main/main/main.js",
"author": "Sucukdeluxe", "author": "Sucukdeluxe",

View File

@ -5231,7 +5231,6 @@ export class DownloadManager extends EventEmitter {
// Unrestrict succeeded - reset provider failure counter // Unrestrict succeeded - reset provider failure counter
this.recordProviderSuccess(this.getProviderFailureKeyForItem(item, unrestricted.provider)); this.recordProviderSuccess(this.getProviderFailureKeyForItem(item, unrestricted.provider));
item.provider = unrestricted.provider; item.provider = unrestricted.provider;
item.providerLabel = unrestricted.providerLabel;
item.retries += unrestricted.retriesUsed; item.retries += unrestricted.retriesUsed;
item.fileName = sanitizeFilename(unrestricted.fileName || filenameFromUrl(item.url)); item.fileName = sanitizeFilename(unrestricted.fileName || filenameFromUrl(item.url));
try { try {

View File

@ -1637,15 +1637,11 @@ export function buildExternalExtractArgs(
conflictMode: ConflictMode, conflictMode: ConflictMode,
password = "", password = "",
usePerformanceFlags = true, usePerformanceFlags = true,
hybridMode = false, hybridMode = false
flatMode = false
): string[] { ): string[] {
const mode = effectiveConflictMode(conflictMode); const mode = effectiveConflictMode(conflictMode);
const lower = command.toLowerCase(); const lower = command.toLowerCase();
if (lower.includes("unrar") || lower.includes("winrar")) { if (lower.includes("unrar") || lower.includes("winrar")) {
// "e" extracts without paths (flat). Used as fallback when the archive stores paths with a
// leading \ (absolute-style), which causes UnRAR to produce invalid \\ double-separators.
const extractCmd = flatMode ? "e" : "x";
const overwrite = mode === "overwrite" ? "-o+" : mode === "rename" ? "-or" : "-o-"; const overwrite = mode === "overwrite" ? "-o+" : mode === "rename" ? "-or" : "-o-";
// NOTE: The password is passed as a CLI argument (-p<password>), which means it may be // NOTE: The password is passed as a CLI argument (-p<password>), which means it may be
// visible via process listing tools (e.g. `ps aux` on Unix). This is unavoidable because // visible via process listing tools (e.g. `ps aux` on Unix). This is unavoidable because
@ -1655,7 +1651,7 @@ export function buildExternalExtractArgs(
const perfArgs = usePerformanceFlags && shouldUseExtractorPerformanceFlags() const perfArgs = usePerformanceFlags && shouldUseExtractorPerformanceFlags()
? ["-idc", extractorThreadSwitch(hybridMode, currentExtractCpuPriority)] ? ["-idc", extractorThreadSwitch(hybridMode, currentExtractCpuPriority)]
: []; : [];
return [extractCmd, overwrite, pass, "-y", ...perfArgs, archivePath, `${targetDir}${path.sep}`]; return ["x", overwrite, pass, "-y", ...perfArgs, archivePath, `${targetDir}${path.sep}`];
} }
const overwrite = mode === "overwrite" ? "-aoa" : mode === "rename" ? "-aou" : "-aos"; const overwrite = mode === "overwrite" ? "-aoa" : mode === "rename" ? "-aou" : "-aos";
@ -1937,34 +1933,6 @@ async function runExternalExtractInner(
lastError = result.errorText; lastError = result.errorText;
} }
// Some archives (e.g. created by certain scene groups) store internal paths with a leading \,
// causing UnRAR to construct invalid \\ double-separator paths on Windows. Retry in flat mode
// ("e" instead of "x") which strips all archive paths and extracts files directly to targetDir.
const isAbsoluteArchivePath = lastError.includes("Cannot create") && lastError.includes("\\\\");
if (isAbsoluteArchivePath) {
logger.warn(`Entpack-Pfadfehler: absoluter Archivpfad erkannt, Wiederholung mit flachem Modus: ${path.basename(archivePath)}`);
bestPercent = 0;
passwordAttempt = 0;
for (const password of passwords) {
if (signal?.aborted) throw new Error("aborted:extract");
passwordAttempt += 1;
const quotedPw = password === "" ? '""' : `"${password}"`;
logger.info(`Flach-Extraktion Versuch ${passwordAttempt}/${passwords.length} für ${path.basename(archivePath)}: ${quotedPw}`);
const args = buildExternalExtractArgs(command, archivePath, targetDir, conflictMode, password, usePerformanceFlags, hybridMode, true);
const result = await runExtractCommand(command, args, (chunk) => {
const parsed = parseProgressPercent(chunk);
if (parsed === null) return;
const next = nextArchivePercent(bestPercent, parsed);
if (next !== bestPercent) { bestPercent = next; onArchiveProgress?.(bestPercent); }
}, signal, timeoutMs);
logger.info(`Flach-Extraktion Versuch ${passwordAttempt}/${passwords.length}: ok=${result.ok}, bestPercent=${bestPercent}`);
if (result.ok) { onArchiveProgress?.(100); return password; }
if (result.aborted) throw new Error("aborted:extract");
if (result.timedOut || result.missingCommand) break;
lastError = result.errorText;
}
}
throw new Error(lastError || "Entpacken fehlgeschlagen"); throw new Error(lastError || "Entpacken fehlgeschlagen");
} }

View File

@ -4829,7 +4829,7 @@ const PackageCard = memo(function PackageCard({ pkg, items, packageSpeed, isFirs
return <span key={col} className="pkg-col pkg-col-hoster" title={hosterText}>{hosterText}</span>; return <span key={col} className="pkg-col pkg-col-hoster" title={hosterText}>{hosterText}</span>;
} }
case "account": { case "account": {
const accountText = [...new Set(items.map((item) => item.providerLabel || (item.provider ? providerLabels[item.provider] : null)).filter(Boolean))].join(", "); const accountText = [...new Set(items.map((item) => item.provider).filter(Boolean))].map((p) => providerLabels[p!] || p).join(", ");
return <span key={col} className="pkg-col pkg-col-account" title={accountText}>{accountText}</span>; return <span key={col} className="pkg-col pkg-col-account" title={accountText}>{accountText}</span>;
} }
case "prio": return ( case "prio": return (
@ -4890,7 +4890,7 @@ const PackageCard = memo(function PackageCard({ pkg, items, packageSpeed, isFirs
</span> </span>
); );
case "hoster": { const h = extractHoster(item.url) || ""; return <span key={col} className="pkg-col pkg-col-hoster" title={h}>{h}</span>; } case "hoster": { const h = extractHoster(item.url) || ""; return <span key={col} className="pkg-col pkg-col-hoster" title={h}>{h}</span>; }
case "account": return <span key={col} className="pkg-col pkg-col-account">{item.providerLabel || (item.provider ? providerLabels[item.provider] : "")}</span>; case "account": return <span key={col} className="pkg-col pkg-col-account">{item.provider ? providerLabels[item.provider] : ""}</span>;
case "prio": return <span key={col} className="pkg-col pkg-col-prio"></span>; case "prio": return <span key={col} className="pkg-col pkg-col-prio"></span>;
case "status": return ( case "status": return (
<span key={col} className="pkg-col pkg-col-status" title={item.retries > 0 ? `${item.fullStatus} · R${item.retries}` : item.fullStatus}> <span key={col} className="pkg-col pkg-col-status" title={item.retries > 0 ? `${item.fullStatus} · R${item.retries}` : item.fullStatus}>

View File

@ -118,7 +118,6 @@ export interface DownloadItem {
packageId: string; packageId: string;
url: string; url: string;
provider: DebridProvider | null; provider: DebridProvider | null;
providerLabel?: string;
status: DownloadStatus; status: DownloadStatus;
retries: number; retries: number;
speedBps: number; speedBps: number;