Release v1.4.37 with DLC filenames, instant delete, version display
- Parse <filename> tags from DLC XML for proper file names instead of
deriving from opaque URLs (fixes download.bin display)
- Optimistic UI removal for package/item delete (instant feedback)
- Show app version in header ("Multi Debrid Downloader vX.X.X")
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
a0c58aad2c
commit
d491c21b97
@@ -165,7 +165,8 @@ export class AppController {
|
||||
const packages = await importDlcContainers(filePaths);
|
||||
const merged: ParsedPackageInput[] = packages.map((pkg) => ({
|
||||
name: pkg.name,
|
||||
links: pkg.links
|
||||
links: pkg.links,
|
||||
...(pkg.fileNames ? { fileNames: pkg.fileNames } : {})
|
||||
}));
|
||||
const result = this.manager.addPackages(merged);
|
||||
return result;
|
||||
|
||||
+43
-7
@@ -94,24 +94,60 @@ function parsePackagesFromDlcXml(xml: string): ParsedPackageInput[] {
|
||||
}
|
||||
|
||||
const links: string[] = [];
|
||||
const urlRegex = /<url>(.*?)<\/url>/gi;
|
||||
for (let um = urlRegex.exec(packageBody); um; um = urlRegex.exec(packageBody)) {
|
||||
const fileNames: string[] = [];
|
||||
const fileRegex = /<file>([\s\S]*?)<\/file>/gi;
|
||||
for (let fm = fileRegex.exec(packageBody); fm; fm = fileRegex.exec(packageBody)) {
|
||||
const fileBody = fm[1] || "";
|
||||
const urlMatch = fileBody.match(/<url>(.*?)<\/url>/i);
|
||||
if (!urlMatch) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
const url = Buffer.from((um[1] || "").trim(), "base64").toString("utf8").trim();
|
||||
if (isHttpLink(url)) {
|
||||
links.push(url);
|
||||
const url = Buffer.from((urlMatch[1] || "").trim(), "base64").toString("utf8").trim();
|
||||
if (!isHttpLink(url)) {
|
||||
continue;
|
||||
}
|
||||
let fileName = "";
|
||||
const fnMatch = fileBody.match(/<filename>(.*?)<\/filename>/i);
|
||||
if (fnMatch?.[1]) {
|
||||
try {
|
||||
fileName = Buffer.from(fnMatch[1].trim(), "base64").toString("utf8").trim();
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
links.push(url);
|
||||
fileNames.push(sanitizeFilename(fileName));
|
||||
} catch {
|
||||
// skip broken entries
|
||||
}
|
||||
}
|
||||
|
||||
if (links.length === 0) {
|
||||
const urlRegex = /<url>(.*?)<\/url>/gi;
|
||||
for (let um = urlRegex.exec(packageBody); um; um = urlRegex.exec(packageBody)) {
|
||||
try {
|
||||
const url = Buffer.from((um[1] || "").trim(), "base64").toString("utf8").trim();
|
||||
if (isHttpLink(url)) {
|
||||
links.push(url);
|
||||
}
|
||||
} catch {
|
||||
// skip broken entries
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const uniqueLinks = uniquePreserveOrder(links);
|
||||
const hasFileNames = fileNames.some((fn) => fn.length > 0);
|
||||
if (uniqueLinks.length > 0) {
|
||||
packages.push({
|
||||
const pkg: ParsedPackageInput = {
|
||||
name: sanitizeFilename(packageName || inferPackageNameFromLinks(uniqueLinks) || `Paket-${packages.length + 1}`),
|
||||
links: uniqueLinks
|
||||
});
|
||||
};
|
||||
if (hasFileNames) {
|
||||
pkg.fileNames = fileNames;
|
||||
}
|
||||
packages.push(pkg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -974,9 +974,11 @@ export class DownloadManager extends EventEmitter {
|
||||
updatedAt: nowMs()
|
||||
};
|
||||
|
||||
for (const link of links) {
|
||||
for (let linkIdx = 0; linkIdx < links.length; linkIdx += 1) {
|
||||
const link = links[linkIdx];
|
||||
const itemId = uuidv4();
|
||||
const fileName = filenameFromUrl(link);
|
||||
const hintName = pkg.fileNames?.[linkIdx];
|
||||
const fileName = (hintName && !looksLikeOpaqueFilename(hintName)) ? sanitizeFilename(hintName) : filenameFromUrl(link);
|
||||
const item: DownloadItem = {
|
||||
id: itemId,
|
||||
packageId,
|
||||
|
||||
Reference in New Issue
Block a user