diff --git a/tasks/download.ts b/tasks/download.ts index ea2b5f2..baee540 100644 --- a/tasks/download.ts +++ b/tasks/download.ts @@ -16,11 +16,12 @@ import { asyncFilter, promiseState, PromiseStatus, + replaceExtname, sleep, sure_dir, TimeoutError, } from "../utils.ts"; -import { join, resolve } from "@std/path"; +import { basename, extname, join, resolve } from "@std/path"; import { exists } from "@std/fs/exists"; import { ProgressReadable } from "../utils/progress_readable.ts"; @@ -162,6 +163,11 @@ class DownloadManager { } this.#sendEvent(); } + set_details_name(index: number, name: string) { + const d = this.#progress.details.find((v) => v.index === index); + if (d) d.name = name; + this.#sendEvent(); + } set_details_started(index: number) { const d = this.#progress.details.find((v) => v.index === index); if (d) { @@ -369,6 +375,20 @@ export async function download_task( pr.addEventListener("progress", (e) => { m.set_details_downloaded(i.index, e.detail); }); + if (!download_original) { + const ext = extname(path); + const u = new URL(re.url); + const uext = extname(u.pathname); + if (ext != uext) { + path = replaceExtname(path, uext); + if (f) { + f.path = path; + } else { + throw Error("Failed to get file."); + } + m.set_details_name(i.index, basename(path)); + } + } try { const f = await Deno.open(path, { create: true, diff --git a/utils.ts b/utils.ts index c53e18e..2481e9b 100644 --- a/utils.ts +++ b/utils.ts @@ -335,21 +335,27 @@ export function compareNum(num1: number | bigint, num2: number | bigint) { const HASH_PATTERN = /^\/h\/([0-9a-f]+)/; const FHASH_PATTERN = /([0-9a-f]{40})-(\d+)-(\d+)-(\d+)-([^\/]+)/g; +const EXT_MAP: Record = { + ".jpg": "jpg", + ".png": "png", + ".webp": "wbp", +}; export function getHashFromUrl(url: string | URL) { const u = typeof url === "string" ? new URL(url) : url; const m = u.pathname.match(HASH_PATTERN); if (m) return m[1]; if (u.pathname.startsWith("/om/")) { + const ext = EXT_MAP[extname(u.pathname)]; const ma = Array.from(u.pathname.matchAll(FHASH_PATTERN)); const comps = u.pathname.split("/"); if (ma.length && comps.length > 3) { - const width = comps[comps.length - 3]; - if (width == "0") { + const width = parseInt(comps[comps.length - 3]); + if (width === 0) { return ma[0][1]; } for (const f of ma) { - if (f[3] == width) { + if (parseInt(f[3]) <= width && f[5] == ext) { return f[1]; } } @@ -357,3 +363,17 @@ export function getHashFromUrl(url: string | URL) { } throw Error(`URL ${url} not contains hash info.`); } + +/** + * Replaces the file extension of a given path with a new extension. + * + * @param path - The original file path from which the extension will be replaced. + * @param ext - The new extension to be used. If it does not start with a dot, one will be added. + * @returns The modified file path with the new extension. + */ +export function replaceExtname(path: string, ext: string) { + if (ext && !ext.startsWith(".")) { + ext = "." + ext; + } + return path.slice(0, path.length - extname(path).length) + ext; +} diff --git a/utils_test.ts b/utils_test.ts index 075e3f9..8cd1a74 100644 --- a/utils_test.ts +++ b/utils_test.ts @@ -14,6 +14,7 @@ import { parseBigInt, promiseState, PromiseStatus, + replaceExtname, sleep, sure_dir, toJSON, @@ -227,4 +228,18 @@ Deno.test("getHashFromUrl_test", () => { ), "4038f0c078b59736aeaa5b1ce38a44b701238363", ); + assertEquals( + getHashFromUrl( + "https://zurswtyclg.hath.network/om/160618900/ff92f8c044e42cdcadcc0bb35d4bc957d1b00c93-3221277-2419-3482-png/109caa716cd3ac3b8ccf4e1e6c1290cc40e72984-100408-2419-3482-wbp/2560/eoqq7x49z16j8q1jeha/12.webp", + ), + "109caa716cd3ac3b8ccf4e1e6c1290cc40e72984", + ); +}); + +Deno.test("replaceExtname_test", () => { + assertEquals(replaceExtname("test.ts", "js"), "test.js"); + assertEquals(replaceExtname("test", "js"), "test.js"); + assertEquals(replaceExtname("test.ts", ""), "test"); + assertEquals(replaceExtname("test", ""), "test"); + assertEquals(replaceExtname("test", "."), "test."); });