From cdb2f994a58c491542af438f169aee9c995d1ef1 Mon Sep 17 00:00:00 2001 From: walter <108946347+walterz-eth@users.noreply.github.com> Date: Tue, 25 Aug 2026 14:46:27 -0300 Subject: [PATCH 1/7] Add getTorrent function to Store interface --- src/ui/store.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ui/store.ts b/src/ui/store.ts index b96eeaf5..a6af4e85 100644 --- a/src/ui/store.ts +++ b/src/ui/store.ts @@ -77,6 +77,9 @@ export interface Store { // Fetches the .torrent metadata for a search result (via magnet if not yet // cached) and exports it to the configured download folder. fetchAndExportTorrent: (input: { id: string; name: string; magnet: string }) => void; + // Fetches the .torrent metadata for a search result (via magnet if not yet + // cached) and exports it to the configured download folder without downloading. + getTorrent: (input: { id: string; name: string; magnet: string }) => void; notice: string | null; setNotice: (s: string | null) => void; From 0708c1428ae6678caa146296563e3c3b7d1aa779 Mon Sep 17 00:00:00 2001 From: walter Date: Tue, 25 Aug 2026 15:04:24 -0300 Subject: [PATCH 2/7] feat: add torrent-only export functionality and update keymap hints --- src/ui/App.tsx | 2 +- src/ui/components/Results.test.tsx | 21 +++++++++++++++++++++ src/ui/components/Results.tsx | 10 ++++++++++ src/ui/keymap.test.ts | 6 ++++++ src/ui/keymap.ts | 5 ++++- 5 files changed, 42 insertions(+), 2 deletions(-) diff --git a/src/ui/App.tsx b/src/ui/App.tsx index 441dd469..c39f1e6c 100644 --- a/src/ui/App.tsx +++ b/src/ui/App.tsx @@ -564,7 +564,7 @@ export function App({ setEditingFolder(true); return; } - if (input === "t") { + if (input === "t" && !(region === "content" && section !== "downloads" && section !== "seeding")) { setShowHelp(false); setEditingTrackers(true); return; diff --git a/src/ui/components/Results.test.tsx b/src/ui/components/Results.test.tsx index 7cfa2515..986ed681 100644 --- a/src/ui/components/Results.test.tsx +++ b/src/ui/components/Results.test.tsx @@ -184,4 +184,25 @@ describe("Results filter UI", () => { await vi.waitFor(() => expect(u.frame()).not.toContain("Filter")); expect(u.frame()).toContain("Results (8)"); }); + + it("t exports the selected result without starting a download", async () => { + const fetchAndExportTorrent = vi.fn(); + searchState.current = settled(LIST); + ui = renderUI( + + + , + ); + const u = ui; + await vi.waitFor(() => expect(u.frame()).toContain("Results (8)")); + + u.press("t"); + await vi.waitFor(() => expect(fetchAndExportTorrent).toHaveBeenCalledTimes(1)); + expect(fetchAndExportTorrent).toHaveBeenCalledWith({ + id: "a1", + name: "ubuntu 24.04 desktop amd64 iso", + magnet: "magnet:?xt=urn:btih:a1", + }); + expect(u.frame()).toContain("Results (8)"); + }); }); diff --git a/src/ui/components/Results.tsx b/src/ui/components/Results.tsx index c28623e6..bcf827bc 100644 --- a/src/ui/components/Results.tsx +++ b/src/ui/components/Results.tsx @@ -108,6 +108,11 @@ function Detail({ r, width }: { r: TorrentResult; width: number }) { Export {` ${ICON.dot} `} + + t + + .torrent only + {` ${ICON.dot} `} esc back @@ -253,6 +258,9 @@ export function Results() { } else if (input === "y") { const r = results[clamped]; if (r) copyResultMagnet(r); + } else if (input === "t") { + const r = results[clamped]; + if (r) fetchAndExportTorrent({ id: r.infoHash, name: r.name, magnet: r.magnet }); } }, { isActive: focused && mode === "list" }, @@ -268,6 +276,8 @@ export function Results() { else if (input === "y" && detail) copyResultMagnet(detail); else if (input === "e" && detail) fetchAndExportTorrent({ id: detail.infoHash, name: detail.name, magnet: detail.magnet }); + else if (input === "t" && detail) + fetchAndExportTorrent({ id: detail.infoHash, name: detail.name, magnet: detail.magnet }); }, { isActive: focused && mode === "detail" }, ); diff --git a/src/ui/keymap.test.ts b/src/ui/keymap.test.ts index ad6d2c1e..51b4909d 100644 --- a/src/ui/keymap.test.ts +++ b/src/ui/keymap.test.ts @@ -23,6 +23,12 @@ describe("downloads/seeding key vocabulary", () => { expect(seeding.find((h) => h.keys === "c")?.label).toBe("Remove from list"); }); + it("shows the torrent-only action in the results footer", () => { + const row = footerHints("content", "all", null, null); + expect(row.some((h) => h.keys === "t")).toBe(true); + expect(row.find((h) => h.keys === "t")?.label).toBe(".torrent only"); + }); + // The results row carries a known pre-existing overflow (f Filter), so the // budget is pinned only for the rows this vocabulary owns. it("keeps the downloads and seeding footer rows inside the 80-col budget", () => { diff --git a/src/ui/keymap.ts b/src/ui/keymap.ts index 48b56e75..6fa918b8 100644 --- a/src/ui/keymap.ts +++ b/src/ui/keymap.ts @@ -19,7 +19,7 @@ export const HELP_GROUPS: HelpGroup[] = [ { keys: "tab", label: "Switch pane" }, { keys: "esc", label: "Back" }, { keys: "o", label: "Default download folder" }, - { keys: "t", label: "Extra trackers" }, + { keys: "t", label: "Trackers / .torrent only in results" }, { keys: "q", label: "Quit" }, ], }, @@ -73,6 +73,8 @@ const TORRENT: Hint = { keys: "s", label: "Export" }; const EXPORT: Hint = { keys: "e", label: "Export" }; +const TORRENT_ONLY: Hint = { keys: "t", label: ".torrent only" }; + export function footerHints( region: Region, section: Section, @@ -122,6 +124,7 @@ export function footerHints( { keys: "d", label: "Download" }, { keys: "y", label: "Copy" }, resultFocus === "detail" ? EXPORT : { keys: "s", label: "Sort" }, + TORRENT_ONLY, { keys: "/", label: "Search" }, { keys: "f", label: "Filter" }, SWITCH, From 75cc5f8cd0a978ef67dda2839280d034703decfa Mon Sep 17 00:00:00 2001 From: walter Date: Fri, 4 Sep 2026 10:23:56 -0300 Subject: [PATCH 3/7] feat: implement debug logging for torrent export and metadata fetching --- src/download/queue.ts | 19 +++++++++++++++++-- src/ui/App.tsx | 7 +++++++ src/util/crashlog.ts | 11 +++++++++++ 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/download/queue.ts b/src/download/queue.ts index 21c990eb..74adf956 100644 --- a/src/download/queue.ts +++ b/src/download/queue.ts @@ -17,6 +17,7 @@ import { deleteSeedData } from "./delete-data"; import { disarmBootMarker } from "./bootguard"; import type { QueueItem, SeedItem } from "./types"; import type { SourceId } from "../sources/types"; +import { logDebug } from "../util/crashlog"; /** * A real seed never pulls data off the network: verifying on-disk files reads @@ -419,13 +420,19 @@ export class DownloadQueue extends EventEmitter { input: { id: string; name: string; magnet: string }, exportDir: string, ): Promise { + logDebug("torrent-only", `request id=${input.id} name=${JSON.stringify(input.name)} exportDir=${JSON.stringify(exportDir)}`); // Fast path: cached from a previous download. if (torrentMetaExists(input.id)) { - return exportTorrentMeta(input.id, input.name, exportDir); + logDebug("torrent-only", `cached hit id=${input.id}`); + return exportTorrentMeta(input.id, input.name, exportDir).then((file) => { + logDebug("torrent-only", `cached export id=${input.id} file=${JSON.stringify(file)}`); + return file; + }); } // If this torrent is already in the engine (downloading / seeding), its // metadata will arrive through the normal queue flow; don't double-add it. if (this.items.has(input.id) || this.seeds.has(input.id)) { + logDebug("torrent-only", `blocked existing live torrent id=${input.id}`); return Promise.resolve(null); } return new Promise((resolve) => { @@ -434,6 +441,7 @@ export class DownloadQueue extends EventEmitter { const timer = setTimeout(() => { if (done) return; done = true; + logDebug("torrent-only", `metadata timeout id=${input.id}`); this.engine.remove(tempKey); resolve(null); }, FETCH_METADATA_TIMEOUT_MS); @@ -442,17 +450,24 @@ export class DownloadQueue extends EventEmitter { if (done) return; done = true; clearTimeout(timer); + logDebug( + "torrent-only", + `metadata arrived id=${input.id} name=${JSON.stringify(meta.name)} total=${meta.total} files=${meta.files} hasTorrentFile=${Boolean(meta.torrentFile)}`, + ); // Tear down synchronously before any file data can be written. this.engine.remove(tempKey); void (async () => { if (meta.torrentFile) await saveTorrentMeta(input.id, meta.torrentFile); - resolve(await exportTorrentMeta(input.id, input.name, exportDir)); + const file = await exportTorrentMeta(input.id, input.name, exportDir); + logDebug("torrent-only", `export result id=${input.id} file=${JSON.stringify(file)}`); + resolve(file); })(); }, onError: () => { if (done) return; done = true; clearTimeout(timer); + logDebug("torrent-only", `metadata error id=${input.id}`); this.engine.remove(tempKey); resolve(null); }, diff --git a/src/ui/App.tsx b/src/ui/App.tsx index c39f1e6c..e6d0b7fa 100644 --- a/src/ui/App.tsx +++ b/src/ui/App.tsx @@ -20,6 +20,7 @@ import { resolveTorrentPath } from "../sources/torrentPath"; import { readClipboard, writeClipboard } from "../util/clipboard"; import { openFolder } from "../util/openFolder"; import { cleanText, formatBytes, truncate } from "../util/format"; +import { logDebug } from "../util/crashlog"; import { StoreContext, type CaptureMode, @@ -358,11 +359,14 @@ export function App({ (input: { id: string; name: string }) => { if (!queue) return; void (async () => { + logDebug("export", `cached-request id=${input.id} name=${JSON.stringify(input.name)}`); const file = await queue.exportTorrentFile(input.id); if (file) { + logDebug("export", `cached-success id=${input.id} file=${JSON.stringify(file)}`); setNotice(`Exported torrent file: ${truncate(file, 48)}`); return; } + logDebug("export", `cached-miss id=${input.id}`); setNotice(`No torrent file yet for ${truncate(cleanText(input.name), 32)}.`); })(); }, @@ -373,12 +377,15 @@ export function App({ (input: { id: string; name: string; magnet: string }) => { if (!queue || !config) return; setNotice("Fetching torrent metadata…"); + logDebug("torrent-only", `ui-request id=${input.id} name=${JSON.stringify(input.name)} downloadDir=${JSON.stringify(config.downloadDir)}`); void (async () => { const file = await queue.fetchAndExportTorrent(input, config.downloadDir); if (file) { + logDebug("torrent-only", `ui-success id=${input.id} file=${JSON.stringify(file)}`); setNotice(`Exported torrent file: ${truncate(file, 48)}`); return; } + logDebug("torrent-only", `ui-failure id=${input.id}`); setNotice(`Couldn't export torrent file for ${truncate(cleanText(input.name), 32)}.`); })(); }, diff --git a/src/util/crashlog.ts b/src/util/crashlog.ts index 281e2b94..c28a1c4b 100644 --- a/src/util/crashlog.ts +++ b/src/util/crashlog.ts @@ -3,6 +3,7 @@ import path from "node:path"; import { logsDir } from "../config/paths"; export const crashLogFile = path.join(logsDir, "crash.log"); +export const debugLogFile = path.join(logsDir, "debug.log"); // Append one timestamped entry. Returns false when even logging failed: a // crash logger must never become a crash source itself. @@ -17,6 +18,16 @@ export function logCrash(kind: string, err: unknown): boolean { } } +export function logDebug(kind: string, message: string): boolean { + try { + mkdirSync(logsDir, { recursive: true }); + appendFileSync(debugLogFile, `${new Date().toISOString()} [${kind}] ${message}\n`); + return true; + } catch { + return false; + } +} + // Node kills the process on any unhandled promise rejection, and webtorrent // can produce one from inside its own async internals with no error event and // nothing a caller's try/catch can reach (its fire-and-forget _onTorrentId is From 26c3d9a6a5757441f9aaf57ced433640a69197b7 Mon Sep 17 00:00:00 2001 From: walter Date: Wed, 16 Sep 2026 09:56:19 -0300 Subject: [PATCH 4/7] feat: add search functionality with ranking and result normalization --- search.js | 14 +++ src/cli/search-cli.ts | 124 +++++++++++++++++++++ src/cli/search-rank.test.ts | 85 ++++++++++++++ src/cli/search-rank.ts | 214 ++++++++++++++++++++++++++++++++++++ src/download/persist.ts | 4 +- 5 files changed, 439 insertions(+), 2 deletions(-) create mode 100644 search.js create mode 100644 src/cli/search-cli.ts create mode 100644 src/cli/search-rank.test.ts create mode 100644 src/cli/search-rank.ts diff --git a/search.js b/search.js new file mode 100644 index 00000000..0ec10925 --- /dev/null +++ b/search.js @@ -0,0 +1,14 @@ +import { spawn } from "node:child_process"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; + +const here = path.dirname(fileURLToPath(import.meta.url)); +const entry = path.join(here, "src", "cli", "search-cli.ts"); +const child = spawn(process.execPath, ["--import", "tsx", entry, ...process.argv.slice(2)], { + stdio: "inherit", +}); + +child.on("exit", (code, signal) => { + if (signal) process.kill(process.pid, signal); + process.exitCode = code ?? 1; +}); diff --git a/src/cli/search-cli.ts b/src/cli/search-cli.ts new file mode 100644 index 00000000..f138e783 --- /dev/null +++ b/src/cli/search-cli.ts @@ -0,0 +1,124 @@ +import { mkdtemp, copyFile, mkdir, rm, stat } from "node:fs/promises"; +import os from "node:os"; +import path from "node:path"; +import { SOURCES } from "../sources/registry"; +import { cachedSearch } from "../sources/cache"; +import { torrentExportName } from "../download/persist"; +import { DownloadQueue } from "../download/queue"; +import { formatBytes } from "../util/format"; +import { normalizeSearchResult, rankSearchResults } from "./search-rank"; + +const MAX_SIZE_GB = Number(process.env.MAX_TORRENT_SIZE_GB ?? "6"); +const MAX_SIZE_BYTES = Math.max(1, MAX_SIZE_GB) * 1024 ** 3; + +function readWatchDir(): string | null { + return process.env.QBIT_WATCH_DIR?.trim() || null; +} + +function cleanFilename(name: string): string { + return name + .replace(/[<>:"/\\|?*\x00-\x1f]/g, " ") + .replace(/\s+/g, " ") + .trim() + .replace(/[. ]+$/g, ""); +} + +async function uniqueCopy(source: string, watchDir: string, name: string): Promise { + await mkdir(watchDir, { recursive: true }); + const base = cleanFilename(name) || "torrent"; + const targetBase = path.join(watchDir, base.endsWith(".torrent") ? base : `${base}.torrent`); + const ext = path.extname(targetBase); + const stem = targetBase.slice(0, -ext.length); + let target = targetBase; + for (let i = 0; i < 1000; i++) { + try { + await copyFile(source, target, 1); + return target; + } catch (e) { + if (i === 999) throw e; + target = `${stem} (${i + 1})${ext}`; + } + } + return targetBase; +} + +async function fetchSearchResults(query: string) { + const settled = await Promise.allSettled( + SOURCES.map(async (source) => { + const results = await cachedSearch(source, query); + return results.map((r) => + normalizeSearchResult({ + infoHash: r.infoHash, + title: r.name, + seeders: r.seeders, + sizeBytes: r.sizeBytes, + torrentUrl: r.magnet, + source: r.source, + }), + ); + }), + ); + const all = []; + for (const item of settled) { + if (item.status === "fulfilled") all.push(...item.value); + } + return all; +} + +async function main(): Promise { + const query = process.argv.slice(2).join(" ").trim(); + if (!query) { + console.error("Usage: node search.js \"content name\""); + return 1; + } + + const watchDir = readWatchDir(); + if (!watchDir) { + console.error("QBIT_WATCH_DIR is not set."); + return 1; + } + + console.log(`Search: ${query}`); + const ranked = rankSearchResults(query, await fetchSearchResults(query), { maxSizeBytes: MAX_SIZE_BYTES }); + if (ranked.length === 0) { + console.log("No acceptable torrent found."); + return 0; + } + + for (const [idx, r] of ranked.slice(0, 5).entries()) { + console.log( + `${idx + 1}. ${r.title} | ${formatBytes(r.sizeBytes)} | ${r.seeders} seeders${r.source ? ` | ${r.source}` : ""}`, + ); + } + + const selected = ranked[0]!; + console.log(`Selected: ${selected.title}`); + + const queue = new DownloadQueue(); + const tmpDir = await mkdtemp(path.join(os.tmpdir(), "torlink-search-")); + try { + const torrentPath = await queue.fetchAndExportTorrent( + { id: selected.infoHash, name: selected.title, magnet: selected.torrentUrl, source: selected.source }, + tmpDir, + ); + if (!torrentPath) { + console.error("Failed to fetch torrent metadata."); + return 1; + } + const finalName = torrentExportName(selected.title, selected.torrentUrl); + const finalPath = await uniqueCopy(torrentPath, watchDir, finalName); + const size = (await stat(finalPath)).size; + console.log(`Wrote: ${finalPath} (${formatBytes(size)})`); + return 0; + } finally { + await rm(tmpDir, { recursive: true, force: true }).catch(() => {}); + queue.suspend(); + } +} + +main() + .then((code) => process.exitCode = code) + .catch((e) => { + console.error(e instanceof Error ? e.message : String(e)); + process.exitCode = 1; + }); diff --git a/src/cli/search-rank.test.ts b/src/cli/search-rank.test.ts new file mode 100644 index 00000000..094c570d --- /dev/null +++ b/src/cli/search-rank.test.ts @@ -0,0 +1,85 @@ +import { describe, expect, it } from "vitest"; +import { rankSearchResults } from "./search-rank"; + +const opts = { maxSizeBytes: 6 * 1024 ** 3 }; + +describe("rankSearchResults", () => { + it("prefers an exact title match over a partial unrelated match", () => { + const ranked = rankSearchResults( + "The Example Movie", + [ + { infoHash: "a", title: "The.Example.Movie.2025.1080p", seeders: 20, sizeBytes: 2e9, torrentUrl: "a" }, + { infoHash: "b", title: "Example.Movie.Collection", seeders: 999, sizeBytes: 2e9, torrentUrl: "b" }, + ], + opts, + ); + + expect(ranked[0]?.title).toBe("The.Example.Movie.2025.1080p"); + }); + + it("normalizes dots, hyphens, and underscores", () => { + const ranked = rankSearchResults( + "Spider Man No Way Home", + [ + { infoHash: "a", title: "Spider-Man.No_Way_Home.2021.1080p", seeders: 50, sizeBytes: 3e9, torrentUrl: "a" }, + ], + opts, + ); + + expect(ranked).toHaveLength(1); + expect(ranked[0]?.title).toContain("Spider-Man.No_Way_Home"); + }); + + it("> 6 GB results are excluded", () => { + const ranked = rankSearchResults( + "Big Movie", + [ + { infoHash: "a", title: "Big.Movie.7GB", seeders: 999, sizeBytes: 7 * 1024 ** 3, torrentUrl: "a" }, + { infoHash: "b", title: "Big.Movie.5GB", seeders: 100, sizeBytes: 5 * 1024 ** 3, torrentUrl: "b" }, + ], + opts, + ); + + expect(ranked).toHaveLength(1); + expect(ranked[0]?.sizeBytes).toBe(5 * 1024 ** 3); + }); + + it("prefers higher seeder counts", () => { + const ranked = rankSearchResults( + "Example Movie", + [ + { infoHash: "a", title: "Example.Movie.1080p", seeders: 20, sizeBytes: 2e9, torrentUrl: "a" }, + { infoHash: "b", title: "Example.Movie.720p", seeders: 100, sizeBytes: 1e9, torrentUrl: "b" }, + ], + opts, + ); + + expect(ranked[0]?.seeders).toBe(100); + }); + + it("uses file size as a tie breaker when seeders are similar", () => { + const ranked = rankSearchResults( + "Example Movie", + [ + { infoHash: "a", title: "Example.Movie.Small", seeders: 50, sizeBytes: 1e9, torrentUrl: "a" }, + { infoHash: "b", title: "Example.Movie.Big", seeders: 50, sizeBytes: 3e9, torrentUrl: "b" }, + ], + opts, + ); + + expect(ranked[0]?.sizeBytes).toBe(3e9); + }); + + it("returns no valid results when nothing matches cleanly", () => { + const ranked = rankSearchResults( + "The Example Movie", + [ + { infoHash: "a", title: "Another Film", seeders: 500, sizeBytes: 2e9, torrentUrl: "a" }, + { infoHash: "b", title: "Example Movie Sample Pack", seeders: 5, sizeBytes: 0, torrentUrl: "b" }, + ], + opts, + ); + + expect(ranked).toHaveLength(0); + }); +}); diff --git a/src/cli/search-rank.ts b/src/cli/search-rank.ts new file mode 100644 index 00000000..5e4732bc --- /dev/null +++ b/src/cli/search-rank.ts @@ -0,0 +1,214 @@ +export interface NormalizedSearchResult { + infoHash: string; + title: string; + seeders: number; + sizeBytes: number; + torrentUrl: string; + source?: string; + rawTitle?: string; +} + +export interface RankedSearchResult extends NormalizedSearchResult { + score: number; + match: { + ok: boolean; + ratio: number; + queryTokens: string[]; + titleTokens: string[]; + }; +} + +export interface RankOptions { + maxSizeBytes: number; +} + +const STOPWORDS = new Set([ + "a", + "an", + "and", + "at", + "bd", + "blu", + "bluray", + "brrip", + "cam", + "complete", + "ddp", + "digital", + "dolby", + "dub", + "dvdrip", + "episode", + "episodes", + "hdr", + "hevc", + "h264", + "h265", + "hdrip", + "internal", + "limited", + "mkv", + "mp4", + "proper", + "repack", + "remastered", + "season", + "subs", + "tc", + "the", + "uhd", + "webrip", + "web", + "x264", + "x265", + "1080p", + "720p", + "2160p", + "480p", + "480i", + "5.1", + "7.1", +]); + +const META_TOKENS = new Set([ + "ac3", + "aac", + "av1", + "blu", + "bluray", + "brrip", + "cam", + "complete", + "ddp", + "digital", + "dub", + "dvdrip", + "encoded", + "extended", + "hdr", + "hevc", + "hdrip", + "imax", + "internal", + "limited", + "proper", + "repack", + "remastered", + "remux", + "repack", + "season", + "web", + "webrip", + "x264", + "x265", +]); + +function splitTokens(value: string): string[] { + return value + .toLowerCase() + .normalize("NFKD") + .replace(/[\u0300-\u036f]/g, " ") + .replace(/[\[\]().,_\-+/|:]+/g, " ") + .replace(/[^a-z0-9\s]+/g, " ") + .split(/\s+/) + .filter(Boolean); +} + +function normalizeTokens(value: string): string[] { + return splitTokens(value).filter((tok) => !STOPWORDS.has(tok)); +} + +function normalizedPhrase(value: string): string { + return normalizeTokens(value).join(" "); +} + +function isMetadataToken(tok: string): boolean { + return META_TOKENS.has(tok) || /^\d{4}$/.test(tok) || /^\d+(?:p|k)$/.test(tok); +} + +function tokenSet(tokens: string[]): Set { + return new Set(tokens); +} + +function titleMatch( + query: string, + queryTokens: string[], + title: string, + titleTokens: string[], +): { ok: boolean; ratio: number; phrase: boolean } { + if (queryTokens.length === 0 || titleTokens.length === 0) return { ok: false, ratio: 0 }; + const titleSet = tokenSet(titleTokens); + let hits = 0; + for (const tok of queryTokens) { + if (titleSet.has(tok)) hits++; + } + const ratio = hits / queryTokens.length; + const queryPhrase = normalizedPhrase(query); + const titlePhrase = normalizedPhrase(title); + const phrase = titlePhrase.includes(queryPhrase); + const tail = titleTokens.slice(queryTokens.length); + const tailAcceptable = tail.length === 0 || tail.every(isMetadataToken); + return { ok: (phrase && tailAcceptable) || (ratio >= 0.85 && tailAcceptable), ratio, phrase }; +} + +function compare(a: RankedSearchResult, b: RankedSearchResult): number { + if (b.match.phrase !== a.match.phrase) return Number(b.match.phrase) - Number(a.match.phrase); + if (b.match.ratio !== a.match.ratio) return b.match.ratio - a.match.ratio; + if (b.seeders !== a.seeders) return b.seeders - a.seeders; + if (b.sizeBytes !== a.sizeBytes) return b.sizeBytes - a.sizeBytes; + return a.title.localeCompare(b.title); +} + +export function normalizeSearchResult(input: { + infoHash: string; + title: string; + seeders?: number; + sizeBytes?: number; + torrentUrl: string; + source?: string; +}): NormalizedSearchResult { + return { + infoHash: input.infoHash.toLowerCase(), + title: input.title.trim(), + seeders: Number.isFinite(input.seeders ?? NaN) ? Math.max(0, Math.floor(input.seeders ?? 0)) : 0, + sizeBytes: Number.isFinite(input.sizeBytes ?? NaN) ? Math.max(0, Math.floor(input.sizeBytes ?? 0)) : 0, + torrentUrl: input.torrentUrl, + source: input.source, + rawTitle: input.title, + }; +} + +export function rankSearchResults( + query: string, + results: NormalizedSearchResult[], + opts: RankOptions, +): RankedSearchResult[] { + const qTokens = normalizeTokens(query); + const out = results + .map((r) => { + const titleTokens = normalizeTokens(r.title); + const match = titleMatch(query, qTokens, r.title, titleTokens); + return { + ...r, + score: 0, + match: { + ok: match.ok, + ratio: match.ratio, + queryTokens: qTokens, + titleTokens, + }, + }; + }) + .filter((r) => r.sizeBytes > 0 && r.sizeBytes <= opts.maxSizeBytes && r.torrentUrl && r.match.ok); + + out.sort(compare); + return out.map((r, idx) => ({ ...r, score: out.length - idx })); +} + +export function isAcceptableSearchResult( + query: string, + result: NormalizedSearchResult, + opts: RankOptions, +): boolean { + return rankSearchResults(query, [result], opts).length > 0; +} diff --git a/src/download/persist.ts b/src/download/persist.ts index 537a38a9..29c9ab95 100644 --- a/src/download/persist.ts +++ b/src/download/persist.ts @@ -1,4 +1,4 @@ -import { promises as fs, mkdirSync, writeFileSync, renameSync, existsSync, rmSync } from "node:fs"; +import { promises as fs, mkdirSync, writeFileSync, renameSync, existsSync, rmSync, constants as fsConstants } from "node:fs"; import path from "node:path"; import { queueFile, seedsFile, torrentsDir } from "../config/paths"; import { serializeWrites, writeJsonAtomic } from "../util/atomic"; @@ -98,7 +98,7 @@ export async function exportTorrentMeta(id: string, name: string, dir: string): if (!existsSync(source)) return null; await fs.mkdir(dir, { recursive: true }); const target = path.join(dir, torrentExportName(name, id)); - await fs.copyFile(source, target); + await fs.copyFile(source, target, fsConstants.COPYFILE_EXCL); return target; } catch { return null; From 443701173270120b542565c8dabf507e70860c66 Mon Sep 17 00:00:00 2001 From: walter Date: Wed, 16 Sep 2026 10:08:03 -0300 Subject: [PATCH 5/7] feat: enhance logging for search operations and error handling --- src/cli/search-cli.ts | 56 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 50 insertions(+), 6 deletions(-) diff --git a/src/cli/search-cli.ts b/src/cli/search-cli.ts index f138e783..5d283b3b 100644 --- a/src/cli/search-cli.ts +++ b/src/cli/search-cli.ts @@ -10,6 +10,20 @@ import { normalizeSearchResult, rankSearchResults } from "./search-rank"; const MAX_SIZE_GB = Number(process.env.MAX_TORRENT_SIZE_GB ?? "6"); const MAX_SIZE_BYTES = Math.max(1, MAX_SIZE_GB) * 1024 ** 3; +const DEBUG = process.env.TORLINK_SEARCH_DEBUG !== "0"; + +function ts(): string { + return new Date().toISOString(); +} + +function log(message: string): void { + if (!DEBUG) return; + console.error(`[${ts()}] ${message}`); +} + +function logError(message: string): void { + console.error(`[${ts()}] ${message}`); +} function readWatchDir(): string | null { return process.env.QBIT_WATCH_DIR?.trim() || null; @@ -43,9 +57,13 @@ async function uniqueCopy(source: string, watchDir: string, name: string): Promi } async function fetchSearchResults(query: string) { + log(`searching ${SOURCES.length} sources`); const settled = await Promise.allSettled( SOURCES.map(async (source) => { + log(`source start: ${source.id}`); + const started = Date.now(); const results = await cachedSearch(source, query); + log(`source done: ${source.id} (${results.length} results, ${Date.now() - started}ms)`); return results.map((r) => normalizeSearchResult({ infoHash: r.infoHash, @@ -60,26 +78,46 @@ async function fetchSearchResults(query: string) { ); const all = []; for (const item of settled) { - if (item.status === "fulfilled") all.push(...item.value); + if (item.status === "fulfilled") { + all.push(...item.value); + continue; + } + logError(`source failed: ${item.reason instanceof Error ? item.reason.message : String(item.reason)}`); } + log(`search collected ${all.length} normalized results`); return all; } async function main(): Promise { + process.on("unhandledRejection", (reason) => { + logError(`unhandledRejection: ${reason instanceof Error ? reason.stack ?? reason.message : String(reason)}`); + }); + process.on("uncaughtException", (err) => { + logError(`uncaughtException: ${err.stack ?? err.message}`); + }); + const query = process.argv.slice(2).join(" ").trim(); + log(`argv: ${JSON.stringify(process.argv.slice(2))}`); if (!query) { - console.error("Usage: node search.js \"content name\""); + logError("Usage: node search.js \"content name\""); return 1; } const watchDir = readWatchDir(); if (!watchDir) { - console.error("QBIT_WATCH_DIR is not set."); + logError("QBIT_WATCH_DIR is not set."); return 1; } + log(`query: ${query}`); + log(`watch dir: ${watchDir}`); + log(`max size: ${MAX_SIZE_BYTES} bytes (${MAX_SIZE_GB} GB)`); + console.log(`Search: ${query}`); - const ranked = rankSearchResults(query, await fetchSearchResults(query), { maxSizeBytes: MAX_SIZE_BYTES }); + const results = await fetchSearchResults(query); + log(`ranking ${results.length} candidates`); + const ranked = rankSearchResults(query, results, { maxSizeBytes: MAX_SIZE_BYTES }); + log(`ranked ${ranked.length} acceptable candidates`); if (ranked.length === 0) { console.log("No acceptable torrent found."); return 0; @@ -97,28 +135,34 @@ async function main(): Promise { const queue = new DownloadQueue(); const tmpDir = await mkdtemp(path.join(os.tmpdir(), "torlink-search-")); try { + log(`export staging dir: ${tmpDir}`); + log(`fetching torrent metadata for ${selected.infoHash}`); const torrentPath = await queue.fetchAndExportTorrent( { id: selected.infoHash, name: selected.title, magnet: selected.torrentUrl, source: selected.source }, tmpDir, ); if (!torrentPath) { - console.error("Failed to fetch torrent metadata."); + logError("Failed to fetch torrent metadata."); return 1; } + log(`torrent staged at ${torrentPath}`); const finalName = torrentExportName(selected.title, selected.torrentUrl); + log(`copying to watch folder as ${finalName}`); const finalPath = await uniqueCopy(torrentPath, watchDir, finalName); const size = (await stat(finalPath)).size; console.log(`Wrote: ${finalPath} (${formatBytes(size)})`); return 0; } finally { + log(`cleaning up staging dir ${tmpDir}`); await rm(tmpDir, { recursive: true, force: true }).catch(() => {}); queue.suspend(); + log("shutdown complete"); } } main() .then((code) => process.exitCode = code) .catch((e) => { - console.error(e instanceof Error ? e.message : String(e)); + logError(e instanceof Error ? e.stack ?? e.message : String(e)); process.exitCode = 1; }); From b4b07f4dc7e25e7766d1898d00a8106c593a0d2c Mon Sep 17 00:00:00 2001 From: walter Date: Wed, 16 Sep 2026 10:14:53 -0300 Subject: [PATCH 6/7] feat: add handling for sequel markers in search ranking --- src/cli/search-rank.test.ts | 13 +++++++ src/cli/search-rank.ts | 71 +++++++++++++++++++++++++++++++++---- 2 files changed, 78 insertions(+), 6 deletions(-) diff --git a/src/cli/search-rank.test.ts b/src/cli/search-rank.test.ts index 094c570d..cc2d1a5a 100644 --- a/src/cli/search-rank.test.ts +++ b/src/cli/search-rank.test.ts @@ -30,6 +30,19 @@ describe("rankSearchResults", () => { expect(ranked[0]?.title).toContain("Spider-Man.No_Way_Home"); }); + it("handles sequel markers like part ii / 2", () => { + const ranked = rankSearchResults( + "back to the future 2", + [ + { infoHash: "a", title: "Back.To.The.Future.Part.II.1989.1080p", seeders: 200, sizeBytes: 2e9, torrentUrl: "a" }, + { infoHash: "b", title: "Back.To.The.Future.1985.1080p", seeders: 300, sizeBytes: 2e9, torrentUrl: "b" }, + ], + opts, + ); + + expect(ranked[0]?.title).toContain("Part.II"); + }); + it("> 6 GB results are excluded", () => { const ranked = rankSearchResults( "Big Movie", diff --git a/src/cli/search-rank.ts b/src/cli/search-rank.ts index 5e4732bc..36077a52 100644 --- a/src/cli/search-rank.ts +++ b/src/cli/search-rank.ts @@ -103,6 +103,25 @@ const META_TOKENS = new Set([ "x265", ]); +const SEQUEL_TOKENS = new Set([ + "part", + "pt", + "episode", + "chapter", + "volume", + "vol", + "book", + "ii", + "iii", + "iv", + "v", + "vi", + "vii", + "viii", + "ix", + "x", +]); + function splitTokens(value: string): string[] { return value .toLowerCase() @@ -126,6 +145,38 @@ function isMetadataToken(tok: string): boolean { return META_TOKENS.has(tok) || /^\d{4}$/.test(tok) || /^\d+(?:p|k)$/.test(tok); } +function isSequelToken(tok: string): boolean { + return SEQUEL_TOKENS.has(tok) || /^\d+$/.test(tok); +} + +function canonicalToken(tok: string): string { + if (/^\d+$/.test(tok)) return tok; + switch (tok) { + case "i": + return "1"; + case "ii": + return "2"; + case "iii": + return "3"; + case "iv": + return "4"; + case "v": + return "5"; + case "vi": + return "6"; + case "vii": + return "7"; + case "viii": + return "8"; + case "ix": + return "9"; + case "x": + return "10"; + default: + return tok; + } +} + function tokenSet(tokens: string[]): Set { return new Set(tokens); } @@ -137,18 +188,26 @@ function titleMatch( titleTokens: string[], ): { ok: boolean; ratio: number; phrase: boolean } { if (queryTokens.length === 0 || titleTokens.length === 0) return { ok: false, ratio: 0 }; - const titleSet = tokenSet(titleTokens); + const queryCanonical = queryTokens.map(canonicalToken); + const titleCanonical = titleTokens.map(canonicalToken); + const titleSet = tokenSet(titleCanonical); let hits = 0; - for (const tok of queryTokens) { + for (const tok of queryCanonical) { if (titleSet.has(tok)) hits++; } - const ratio = hits / queryTokens.length; + const ratio = hits / queryCanonical.length; const queryPhrase = normalizedPhrase(query); const titlePhrase = normalizedPhrase(title); const phrase = titlePhrase.includes(queryPhrase); - const tail = titleTokens.slice(queryTokens.length); - const tailAcceptable = tail.length === 0 || tail.every(isMetadataToken); - return { ok: (phrase && tailAcceptable) || (ratio >= 0.85 && tailAcceptable), ratio, phrase }; + const titleCore = titleTokens.filter((tok) => !isMetadataToken(tok) && !isSequelToken(tok)); + const queryCore = queryTokens.filter((tok) => !isMetadataToken(tok) && !isSequelToken(tok)); + const coreSet = tokenSet(titleCore.map(canonicalToken)); + let coreHits = 0; + for (const tok of queryCore.map(canonicalToken)) { + if (coreSet.has(tok)) coreHits++; + } + const coreRatio = queryCore.length > 0 ? coreHits / queryCore.length : ratio; + return { ok: phrase || ratio >= 0.75 || coreRatio >= 0.7, ratio: Math.max(ratio, coreRatio), phrase }; } function compare(a: RankedSearchResult, b: RankedSearchResult): number { From 040a633a9f2c08d5e7062828d6c805cd50763b0a Mon Sep 17 00:00:00 2001 From: W Date: Thu, 17 Sep 2026 18:01:10 -0300 Subject: [PATCH 7/7] feat: implement torrent classification and handling for audio/video directories --- .env | 2 + .env.example | 4 + README.md | 4 + search.js | 10 ++- src/cli/search-cli.ts | 19 ++++- src/cli/torrent-classify.test.ts | 76 ++++++++++++++++++ src/cli/torrent-classify.ts | 64 +++++++++++++++ src/download/queue.test.ts | 3 + src/download/queue.ts | 24 ++++-- src/parse-torrent.d.ts | 6 ++ ...080p.BluRay.DDP5.1.x265.10bit-Gala.torrent | Bin 0 -> 36275 bytes ...019) [WEBRip] [1080p] [YTS] [YIFY].torrent | Bin 0 -> 92209 bytes 12 files changed, 201 insertions(+), 11 deletions(-) create mode 100644 .env create mode 100644 .env.example create mode 100644 src/cli/torrent-classify.test.ts create mode 100644 src/cli/torrent-classify.ts create mode 100644 test/movies/Ghostbusters.1984.REMASTERED.1080p.BluRay.DDP5.1.x265.10bit-Gala.torrent create mode 100644 test/movies/Terminator Dark Fate (2019) [WEBRip] [1080p] [YTS] [YIFY].torrent diff --git a/.env b/.env new file mode 100644 index 00000000..0ff3622e --- /dev/null +++ b/.env @@ -0,0 +1,2 @@ +QBIT_WATCH_DIR=C:\_dev\torlink_\test\movies +QBIT_MUSIC_WATCH_DIR=C:\_dev\torlink_\test\music \ No newline at end of file diff --git a/.env.example b/.env.example new file mode 100644 index 00000000..d18dacff --- /dev/null +++ b/.env.example @@ -0,0 +1,4 @@ +# qBittorrent watched folder for video and unclassified torrents. +QBIT_WATCH_DIR= +# Optional qBittorrent watched folder for audio torrents. Falls back to QBIT_WATCH_DIR. +QBIT_MUSIC_WATCH_DIR= diff --git a/README.md b/README.md index 4c9ab736..36183612 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,10 @@ torlink also runs without the TUI, for servers and seedboxes: Add `--daemon` to keep watch, serve, or files running after you log out; `torlnk --help` has the full list of modes and flags. +### qBittorrent watched folders + +The standalone `node search.js "query"` helper writes video and unclassified torrents to `QBIT_WATCH_DIR`. Set `QBIT_MUSIC_WATCH_DIR` to send torrents whose metainfo files are predominantly audio to a separate qBittorrent watched folder; if it is unset, audio uses `QBIT_WATCH_DIR` too. + ## Contributing To run or work on torlink locally: diff --git a/search.js b/search.js index 0ec10925..e1ca302f 100644 --- a/search.js +++ b/search.js @@ -3,8 +3,16 @@ import path from "node:path"; import { fileURLToPath } from "node:url"; const here = path.dirname(fileURLToPath(import.meta.url)); +// Node 22's built-in loader keeps this helper dependency-free. Environment +// variables supplied by the shell still take precedence over .env values. +try { + process.loadEnvFile(path.join(here, ".env")); +} catch (e) { + if (e?.code !== "ENOENT") throw e; +} const entry = path.join(here, "src", "cli", "search-cli.ts"); -const child = spawn(process.execPath, ["--import", "tsx", entry, ...process.argv.slice(2)], { +const systemCa = process.platform === "win32" ? ["--use-system-ca"] : []; +const child = spawn(process.execPath, [...systemCa, "--import", "tsx", entry, ...process.argv.slice(2)], { stdio: "inherit", }); diff --git a/src/cli/search-cli.ts b/src/cli/search-cli.ts index 5d283b3b..105526ae 100644 --- a/src/cli/search-cli.ts +++ b/src/cli/search-cli.ts @@ -7,6 +7,7 @@ import { torrentExportName } from "../download/persist"; import { DownloadQueue } from "../download/queue"; import { formatBytes } from "../util/format"; import { normalizeSearchResult, rankSearchResults } from "./search-rank"; +import { classificationSummary, classifyTorrentFile, watchDirForClassification } from "./torrent-classify"; const MAX_SIZE_GB = Number(process.env.MAX_TORRENT_SIZE_GB ?? "6"); const MAX_SIZE_BYTES = Math.max(1, MAX_SIZE_GB) * 1024 ** 3; @@ -103,14 +104,14 @@ async function main(): Promise { return 1; } - const watchDir = readWatchDir(); - if (!watchDir) { + const defaultWatchDir = readWatchDir(); + if (!defaultWatchDir) { logError("QBIT_WATCH_DIR is not set."); return 1; } log(`query: ${query}`); - log(`watch dir: ${watchDir}`); + log(`watch dir: ${defaultWatchDir}`); log(`max size: ${MAX_SIZE_BYTES} bytes (${MAX_SIZE_GB} GB)`); console.log(`Search: ${query}`); @@ -138,14 +139,24 @@ async function main(): Promise { log(`export staging dir: ${tmpDir}`); log(`fetching torrent metadata for ${selected.infoHash}`); const torrentPath = await queue.fetchAndExportTorrent( - { id: selected.infoHash, name: selected.title, magnet: selected.torrentUrl, source: selected.source }, + { id: selected.infoHash, name: selected.title, magnet: selected.torrentUrl }, tmpDir, + (reason) => logError(`Torrent metadata retrieval failed: ${reason}`), ); if (!torrentPath) { logError("Failed to fetch torrent metadata."); return 1; } log(`torrent staged at ${torrentPath}`); + let classification; + try { + classification = await classifyTorrentFile(torrentPath); + } catch (e) { + logError(`Torrent metadata inspection failed: ${e instanceof Error ? e.stack ?? e.message : String(e)}`); + classification = { type: "unknown" as const, audioBytes: 0, videoBytes: 0, totalBytes: 0 }; + } + const watchDir = watchDirForClassification(classification, defaultWatchDir); + log(`${classificationSummary(classification)} -> ${watchDir}`); const finalName = torrentExportName(selected.title, selected.torrentUrl); log(`copying to watch folder as ${finalName}`); const finalPath = await uniqueCopy(torrentPath, watchDir, finalName); diff --git a/src/cli/torrent-classify.test.ts b/src/cli/torrent-classify.test.ts new file mode 100644 index 00000000..7e73501c --- /dev/null +++ b/src/cli/torrent-classify.test.ts @@ -0,0 +1,76 @@ +import { describe, expect, it } from "vitest"; +import { mkdtemp, rm, writeFile } from "node:fs/promises"; +import os from "node:os"; +import path from "node:path"; +import { classificationSummary, classifyTorrent, classifyTorrentFile, watchDirForClassification } from "./torrent-classify"; + +const file = (name: string, length: number) => ({ name, length }); +const bstr = (value: string) => `${Buffer.byteLength(value)}:${value}`; + +function torrentFile(files: Array<{ name: string; length: number }>): Buffer { + const single = files[0]!; + const entries = files.length === 1 + ? `6:lengthi${single.length}e4:name${bstr(single.name)}` + : `5:filesl${files.map((f) => `d6:lengthi${f.length}e4:pathl${bstr(f.name)}ee`).join("")}e`; + const rootName = files.length === 1 ? "" : `4:name${bstr("fixture")}`; + return Buffer.from(`d4:infod${entries}${rootName}12:piece lengthi16384e6:pieces20:xxxxxxxxxxxxxxxxxxxxee`); +} + +describe("classifyTorrent", () => { + it("classifies a single movie file", () => { + expect(classifyTorrent({ files: [file("Movie.mkv", 8_000)] }).type).toBe("video"); + }); + + it("ignores movie subtitles and artwork", () => { + expect(classifyTorrent({ files: [file("Movie.mp4", 8_000), file("cover.jpg", 20), file("sub.srt", 10)] })).toMatchObject({ type: "video", videoBytes: 8_000, totalBytes: 8_030 }); + }); + + it("classifies a multi-file FLAC album", () => { + expect(classifyTorrent({ files: [file("01.flac", 2_000), file("02.flac", 2_100)] }).type).toBe("audio"); + }); + + it("classifies a multi-file MP3 album", () => { + expect(classifyTorrent({ files: [file("01.mp3", 200), file("02.mp3", 210)] }).type).toBe("audio"); + }); + + it("ignores album cover art and cue sheets", () => { + const result = classifyTorrent({ files: [file("01.flac", 2_000), file("cover.jpg", 20), file("album.cue", 3)] }); + expect(result).toMatchObject({ type: "audio", audioBytes: 2_000, totalBytes: 2_023 }); + }); + + it("uses byte totals for mixed content and makes ties unknown", () => { + expect(classifyTorrent({ files: [file("clip.mp4", 900), file("song.flac", 1_000)] }).type).toBe("audio"); + expect(classifyTorrent({ files: [file("clip.mp4", 1_000), file("song.flac", 1_000)] }).type).toBe("unknown"); + }); + + it("returns unknown for unavailable or malformed metadata", () => { + expect(classifyTorrent({}).type).toBe("unknown"); + expect(classifyTorrent({ files: [file("broken.mp3", -1)] }).type).toBe("unknown"); + }); + + it("parses actual single-file and multi-file torrent metainfo", async () => { + const dir = await mkdtemp(path.join(os.tmpdir(), "torlink-classify-")); + try { + const movie = path.join(dir, "movie.torrent"); + const album = path.join(dir, "album.torrent"); + await writeFile(movie, torrentFile([file("Movie.mkv", 8_000)])); + await writeFile(album, torrentFile([file("01.flac", 2_000), file("02.flac", 2_100)])); + await expect(classifyTorrentFile(movie)).resolves.toMatchObject({ type: "video", videoBytes: 8_000 }); + await expect(classifyTorrentFile(album)).resolves.toMatchObject({ type: "audio", audioBytes: 4_100 }); + await writeFile(movie, "not torrent metadata"); + await expect(classifyTorrentFile(movie)).rejects.toThrow(); + } finally { + await rm(dir, { recursive: true, force: true }); + } + }); + + it("falls back to the default watch folder when music watch is absent", () => { + const audio = classifyTorrent({ files: [file("track.opus", 1)] }); + expect(watchDirForClassification(audio, "C:/movies", "")).toBe("C:/movies"); + expect(watchDirForClassification(audio, "C:/movies", "C:/music")).toBe("C:/music"); + }); + + it("formats a concise routing log message", () => { + expect(classificationSummary(classifyTorrent({ files: [file("track.mp3", 978), file("cover.jpg", 22)] }))).toBe("Torrent classified AUDIO (97.8% audio)"); + }); +}); diff --git a/src/cli/torrent-classify.ts b/src/cli/torrent-classify.ts new file mode 100644 index 00000000..5f992da8 --- /dev/null +++ b/src/cli/torrent-classify.ts @@ -0,0 +1,64 @@ +import { readFile } from "node:fs/promises"; +import path from "node:path"; +import parseTorrent from "parse-torrent"; + +export type TorrentType = "video" | "audio" | "unknown"; + +export interface TorrentClassification { + type: TorrentType; + audioBytes: number; + videoBytes: number; + totalBytes: number; +} + +type TorrentMetadata = { + files?: Array<{ name?: string; path?: string; length: number }>; + name?: string; + length?: number; +}; + +const VIDEO_EXTENSIONS = new Set([".mkv", ".mp4", ".avi", ".m4v", ".mov", ".wmv", ".ts", ".m2ts"]); +const AUDIO_EXTENSIONS = new Set([".mp3", ".flac", ".m4a", ".aac", ".ogg", ".opus", ".wav", ".wma"]); + +export function classifyTorrent(metadata: TorrentMetadata): TorrentClassification { + let audioBytes = 0; + let videoBytes = 0; + let totalBytes = 0; + for (const file of metadata.files ?? []) { + const bytes = Number(file.length); + if (!Number.isFinite(bytes) || bytes < 0) continue; + totalBytes += bytes; + const extension = path.extname(file.path ?? file.name ?? "").toLowerCase(); + if (VIDEO_EXTENSIONS.has(extension)) videoBytes += bytes; + else if (AUDIO_EXTENSIONS.has(extension)) audioBytes += bytes; + } + const type: TorrentType = videoBytes > audioBytes && videoBytes > 0 + ? "video" + : audioBytes > videoBytes && audioBytes > 0 + ? "audio" + : "unknown"; + return { type, audioBytes, videoBytes, totalBytes }; +} + +export async function classifyTorrentFile(torrentPath: string): Promise { + const metadata = await parseTorrent(new Uint8Array(await readFile(torrentPath))); + if (!Array.isArray(metadata.files) || metadata.files.length === 0) { + throw new Error("Torrent metadata contains no file list"); + } + return classifyTorrent(metadata); +} + +export function watchDirForClassification( + classification: TorrentClassification, + defaultWatchDir: string, + musicWatchDir = process.env.QBIT_MUSIC_WATCH_DIR?.trim(), +): string { + return classification.type === "audio" && musicWatchDir ? musicWatchDir : defaultWatchDir; +} + +export function classificationSummary(classification: TorrentClassification): string { + if (classification.type === "unknown") return "Torrent classification UNKNOWN"; + const bytes = classification.type === "audio" ? classification.audioBytes : classification.videoBytes; + const percent = classification.totalBytes > 0 ? (bytes / classification.totalBytes) * 100 : 0; + return `Torrent classified ${classification.type.toUpperCase()} (${percent.toFixed(1)}% ${classification.type})`; +} diff --git a/src/download/queue.test.ts b/src/download/queue.test.ts index ea8a34a0..e8c35417 100644 --- a/src/download/queue.test.ts +++ b/src/download/queue.test.ts @@ -163,6 +163,7 @@ describe("DownloadQueue.fetchAndExportTorrent", () => { const q = new DownloadQueue(); const outDir = await fs.mkdtemp(path.join(os.tmpdir(), "torlink-fetch-export-")); const removed: string[] = []; + const failures: string[] = []; const fakeEngine = ( q as unknown as { engine: { @@ -183,9 +184,11 @@ describe("DownloadQueue.fetchAndExportTorrent", () => { magnet: "magnet:?xt=urn:btih:dddddddddddddddddddddddddddddddddddddddd", }, outDir, + (reason) => failures.push(reason), ); expect(file).toBeNull(); expect(removed).toEqual(["__meta__gone1"]); + expect(failures).toEqual(["no peers"]); } finally { await fs.rm(outDir, { recursive: true, force: true }); q.suspend(); diff --git a/src/download/queue.ts b/src/download/queue.ts index 74adf956..2c12951e 100644 --- a/src/download/queue.ts +++ b/src/download/queue.ts @@ -419,6 +419,7 @@ export class DownloadQueue extends EventEmitter { fetchAndExportTorrent( input: { id: string; name: string; magnet: string }, exportDir: string, + onFailure?: (reason: string) => void, ): Promise { logDebug("torrent-only", `request id=${input.id} name=${JSON.stringify(input.name)} exportDir=${JSON.stringify(exportDir)}`); // Fast path: cached from a previous download. @@ -433,6 +434,7 @@ export class DownloadQueue extends EventEmitter { // metadata will arrive through the normal queue flow; don't double-add it. if (this.items.has(input.id) || this.seeds.has(input.id)) { logDebug("torrent-only", `blocked existing live torrent id=${input.id}`); + onFailure?.("torrent is already active in the download queue"); return Promise.resolve(null); } return new Promise((resolve) => { @@ -443,6 +445,7 @@ export class DownloadQueue extends EventEmitter { done = true; logDebug("torrent-only", `metadata timeout id=${input.id}`); this.engine.remove(tempKey); + onFailure?.("timed out waiting for torrent metadata"); resolve(null); }, FETCH_METADATA_TIMEOUT_MS); this.engine.add(tempKey, input.magnet, exportDir, { @@ -457,18 +460,27 @@ export class DownloadQueue extends EventEmitter { // Tear down synchronously before any file data can be written. this.engine.remove(tempKey); void (async () => { - if (meta.torrentFile) await saveTorrentMeta(input.id, meta.torrentFile); - const file = await exportTorrentMeta(input.id, input.name, exportDir); - logDebug("torrent-only", `export result id=${input.id} file=${JSON.stringify(file)}`); - resolve(file); + try { + if (meta.torrentFile) await saveTorrentMeta(input.id, meta.torrentFile); + const file = await exportTorrentMeta(input.id, input.name, exportDir); + logDebug("torrent-only", `export result id=${input.id} file=${JSON.stringify(file)}`); + if (!file) onFailure?.("torrent metadata arrived but no .torrent file was available"); + resolve(file); + } catch (e) { + const reason = message(e); + logDebug("torrent-only", `metadata export failed id=${input.id} reason=${JSON.stringify(reason)}`); + onFailure?.(`could not save torrent metadata: ${reason}`); + resolve(null); + } })(); }, - onError: () => { + onError: (reason) => { if (done) return; done = true; clearTimeout(timer); - logDebug("torrent-only", `metadata error id=${input.id}`); + logDebug("torrent-only", `metadata error id=${input.id} reason=${JSON.stringify(reason)}`); this.engine.remove(tempKey); + onFailure?.(reason); resolve(null); }, }); diff --git a/src/parse-torrent.d.ts b/src/parse-torrent.d.ts index c7a11259..12e664e7 100644 --- a/src/parse-torrent.d.ts +++ b/src/parse-torrent.d.ts @@ -3,6 +3,12 @@ declare module "parse-torrent" { infoHash: string; name?: string; announce?: string[]; + length?: number; + files?: Array<{ + name?: string; + path?: string; + length: number; + }>; } export default function parseTorrent( torrentId: Uint8Array | string, diff --git a/test/movies/Ghostbusters.1984.REMASTERED.1080p.BluRay.DDP5.1.x265.10bit-Gala.torrent b/test/movies/Ghostbusters.1984.REMASTERED.1080p.BluRay.DDP5.1.x265.10bit-Gala.torrent new file mode 100644 index 0000000000000000000000000000000000000000..e1e5be31b15dbbd4a46dab1b60b467ba8bbd8002 GIT binary patch literal 36275 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 FWo3|!CV&6{ literal 0 HcmV?d00001 diff --git a/test/movies/Terminator Dark Fate (2019) [WEBRip] [1080p] [YTS] [YIFY].torrent b/test/movies/Terminator Dark Fate (2019) [WEBRip] [1080p] [YTS] [YIFY].torrent new file mode 100644 index 0000000000000000000000000000000000000000..3aa85889e7152c86a2d9d1a1f5f2d58c60183fa6 GIT binary patch literal 92209 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

8D17#B&Hb8nNF>}5(*6X2^iz3Gah(lE)3yFe{ z49<+E@byrZ^>rhF^VlR{Z(7pIrvjk3$Sl6@np~g0rl0Ovu_9v!pnJ@@&oC#cl}v1( z4?#l|JIXyLX<quyBm3 z)`f zT0!Roc4)E#SOfq5Vvb~&=e$?eIB7;&R)~LUOvyB!ZpU?K|?>r%jN(^82Ny$cvZx%ZT!wFiQ=VUmtMYzuhtT=)hBSoHO zmCFAcE`0rW)vdUbNTm-u4<^>J+JxchmIt5-2A@TjSIsa-=Wm-jqw6cFdkhJgm2yk} z#ycD{*kt!%^)Apg+u3xAwwyxSuuHtx#3L{`SE^>DPb5d4yAE+eGsv6(-Bh91Ix)y! zdU;m8;&f#Pl=|1WU77KK0}>zK;<2EE9ZoD06+dq*i1xYSDK{lhKVdReC~!knQX;x4 zHN7ZhMv#0x#Xi>&&0tnTm+f|zJ?h!NkjZuG1!{Ay71@S;wk@0Xn`7Cxr>u)9SI7lm zpF_^)(!2XY3HhCw8*wiwHczg+AvhOo5uI8q_T{j4Hw1Om7u~4#pZ5i3zNPClaDLA{ z-v$n%sAXap{1*c$H7x1vMISS==TI5u#LZ&U#7xO;=qWw6bjSe1$M=>8cY7(6oI=$hz zW+28#$9wQeoM*byOkr4#;~6BTgNT^HwINb#EX4A9<0_9}Ik?W`<$97S z74CZERi_X5vTW4uFWjzz3!O2CYYH*7%v7Z|MnS-0PZK2T8(*!j* zfLa4$Zc--bG=(n=8*bvT5c5rz&RcC?>RFQCSj{)XOTkSJu3=?m42arDUHO7lgHjtktb2jn^%G%Iiecw^YzfP(DnjjqYR$w zLqH@QOBl zH&Yc`blMlr-!j4te=DU;B%(WKQ0fdNLROM_;tGvZg6$3wi=A)ycqd`={0)0F zGWi`XuV-TU5*juV!&51RCWp%s=b7qIp#BQQHul`{_RC1)@P zld?~Azta@r10kci1=>2#y9&xpq=uzwk&y5@Op1fo)bu(hk}=&*XE_>Hy+&Bb|G>)F zz-j|nkfvP&xg903lheY8L!D)Z_Y(c43YgrolwnZGekHp4CWeoq*CO53$gnFu!WT&` z9p78nrQfI-gi%)|vOg(IOXDDaxyixhmA^&GqwvP?@>V^RLcv+D5Yn+-3l^9hBan+l z?*OlmP5D9wRcR?GMjj{pTpr`q6siQ?yLnaQFe@o_wxS^1O?v2kAAqDBber3NE^_o3 zr$Qez2~V*dV+Ba!jg4&Ks~977?~HL7IQ1_^90Xzb8e|t#1iBgT7mI7e1=R5GJw?)8 zh>(Ajwwob6EM>~$GVev(G{&ZxKR8?_(hNhrndi0WQ7G!4WL-bl!MC1*b>n`cboD!& z9J0Owe3q9wcm3vZSq?pBYV2EU`8hTfB&Eo#+p_@?4+bt|MiZi*2oTuSc3B%y)Hz;WT zBQ9Qdr!3s7@ih7Kqt0QNADkY$3D{c{YL#^VE z^o?&DDFo&eqZdQ{;Z}t9lDqWx_@2@q5OP?2bO@6zgR~!<3aDTe%SS@+N?Wm2PHA+# zG#|#4Uy99n>Yh-=LqA;tclv0UQYTiV#{JKgXts%6>H4mEFN>b5HwP|d;)w!D;6TK# z^3WMz=B%qtR%#q4%s`G7ALs^W@L8PDebi0E7QoLxw7tti!Ct8kZB6eKT^ni4O7#i^ zV3aiED(Qhy(N?BU&G*zjg-2>mgQQ651&tnn25B%Zje#gCGAVY;+r_Lumw?5)MJUKn7TvzAi>6(3cSDl1Ck|{Y3jkC$dp%a~>hW7liFu87)Z^KQ z>@!nYVcRU8a=7b|helA#V&a?CNrb^jg&r{tqu{j$viyeykoNnSDZxFsjyN~G z+CkM@h8aCaH{XaHi>Yl$0O6NLMYw75F37&(i3q{NV}X^4Iq@F4Ud%|-9lOZ_Xd zc5QY^eV1`t?d`LgpFc4fK7~#H&tVx$$>7l=6kr!vtH;2)iM8Km25568ZUX0(`otsI zv=tMM3J}yMHXzlPjkPmJl6bNwwz0$}a#HMl+Sy@nB;YWNkeSS3KMI_r80~Js-IVc5 z+uE+cTWHU4Oadv{DWr>)zy|jPJ(_rxEr@zKNJJZ=FwMJN>c2YJDDlh%T@liLLADfZ z1SmofHo%EEd!~X{0I(fQc&^-aJaHI3+hX5=aIW&Or|}Ct26Gm%+jf7qi-vUx_vLyK z2xZd}Ros5gBiJRw9m_GnF?kIivcF!lIjGkZ-wQ|=Cf-Y}hBunK}h~bBBvacDj@FY zyD#0NP947FFr&*1FVsCoc@?QyIB{jCH~*z%!TooMuTLbm2HtmP2DZg>8iqPt1g1l_ zT0_;>eU0KPd?u|q6SFdV`9d?LC#%b^kPn(*m~stdh5?&;k6kfT0_ zrEzuCBC+LKD{b)v*kyKDdp%qV6c^e?m8%^-&RUJX&YsJy57msg{4B`Ii4riCRA{lO zK0&;vsCUe7CEqg|VJA%RO?Znv3=F0-bq|}cj+7`WJ-|g+4HLODA$dH-l?PX~48-bA z_ASwP`a2--{q)RxuN0eY3|u{JSf!WxkY?n(E7oEfsZIMY7o%s5O(}aVd94k~!a64B z4$!7eRCTb|=P3U}hm7qFHBIVVaH&iX!8cz7o8^y(2;{J+fqWmP>k*Drr5<6sB#x#I z#+rcn{`;2u=~&4KVJB9M88gw>v)!-)no+Ev!|k(Ffs5L^GXq(Q_uz0xQ*evY^6PDv zC@ltwTGzhl?}L#S;@^N)(Z3TH1dc`H8lJ#THYAL7FP`Z_0(dDhlV~ILJHx-qsC`+LC^e4(Jj=5%4Ml0hLa`LRLKX^9fW4qff0iDb zcVlIM*_F+B0U3Dj=#i0U!BSIOEJ^n$OtWPv6W`h5=Vw7h#M`3#y+% z2?i;OT*32GrLKcA+2!$Oi0py;>a?lw)aq)ega-QUR(B6$4pW_U^evqipw^k&bsZ-q?5o(OT02j z!B%@_qM+ey_~gBD*< zkJIyK{}8UyZ!|I&rm(Ip^D*sO4I)pHf^{c>#tg`f_AlvX zC5xXKqcIdBkXM>gY4$LSa8B(nU3d=y1PEQIm#49~M{|J-C?GeeQB z>!Mtvh|o8{&XdybUP~S3Loq2TfnyV1qzC&=)C{50ig==bhWX5|SE3d2^Cbcmr>Jk= z)RmDPX4hff#zYb>i&Ki?Fo-{VpX+y10ip*8l6W)XMc@;H!85uPBs#F%Wy@ELAatZp zWhK%|o9Ms>o!DpdtpXJWv6nlJG3{EE$)UG1V6D1&3mwUYx@k zuYE84{tc#V$}3ZvA*_cP zgSwx?$(9w_bEdj=COEGwGWvv}^TPkl&Au=4fhjRe9ac#*-eZ3TZMQPDJxy3FHi4ET zVEUB5g`Rmu7wkOM=0TQWgFE=}I2I0nXlRFxlY_|!6HPkoF8an_lCsY5E2&tIjuUcJTj-e;yGsCI2TeV6LHWJ~nfneNfwEi?&;v6P*y*N>18)yM~+Y+B)XbaE~;s z+G3NCe}d$o172BLLu8eg5b%%R6$85oA1vo2;02xY#$?2)aQ6BATn8$Z6?&BLRyU+< zsZcGfE|A7i${9-dICJ?a;&a%{kT~83vD}x`4yNC$Gv@f70ySin?ARx=v^$ZbF7}M{ zX-xbE1nAif)B&=?ZSiO0JcFkIl8Yy0lwDhXj%(h|F_*9m)fJ5Dz|FM{bBo&o^`QEx zy&{n%nM~+-MdcL-!)(Q&Lo%~2_9-H^7M{k0^pdxr!8h2!qCcCA%Y*o-LpxY?C3=Q4 z2ybAOx|tCVzs9{gx2{VYRT_?@2&Tnw~j_ z@#OET1#OpIy{54ZbbkJMu5KQ_kljD=B80N$3Gh+T4t({_t$RIy`sin>7kxNsQI5CZ zz>>y%K5!k^49O^a4FT7{x0o#L6*CNKZ4HTzSM{^wQ3)M-g^+9`FBSz0j4%)gWIh(E zzBCR*CITP%Sxa2zAi5A1q(dGlZ6_cx^%L%eEC1+^^uW6y$xO(IhgQG%h`exDuc6-| zM}J#^oMPV74F$?ZK}3DIILvW&O*jK7#JJ;{=c$=k`#HJbikuGt`Zz|9{2@ajd2&jr zv>e%fQ@_)v&w;NsPj*MOq_-CEE-+gP0HO+Dp?)FR0gg;B<_*_@jwvDnqDIYZOX1qetZHuD3i~J)fS18z-mNyxl>sw z3CO4KNTRYMMo0>C!^aXcldmuXvR!p#C3Yp#q7U6ZE#ssUu8r0zu$Aa>=~2uPD5IwI zaV+i#M{X$ZKmex3-O$gU)t(Vfk?<%jN5iHxXvBt4B&AM~hhKd@u`pf>e`g+Ev$()z0;zV-Y|Zy) z%)v|X7W?T&h7YR-d}r23$CD&=0XaWZYki=(z@AU)=r*`lg;IaV=?ED=7-^JT+jHaL z5W?SRzr7<&f6U*uNCoz8@`a5coJ-ujI#$EiIDi|lK`@D zi71If;k=c~s!%+YBNd?T0bFWgv~ZGH7Iw~{tsSrUl<9&UiwU{+dSl5uwS0X)ih|f! z#Z|eR3oJxg2;efG2S%`th&xKW1Raa&vQcdYSU`wkBWk}-Y)@#x{bQdmECqysiPs{; zDMgF3-?LI=g1-Hl58qa-T6Z%SVLBxW$NHI~m@+Q>pXLS}g;P@`?>FFj`FiQJI=dIB$xY-|QRGft+Q{KjuIrMT|S;AYFnL3xnk z$h!*&^WxH(Nto! zKBak9Vdkm|o2*tQnbcj=q`=tB>*z_iN5SsY_k8)BbE@A!!lmT2e%tupCWHVzUm95g zl*DmQ@f!YX#N3p2V)X;NoKj(UF2`7*d;>Tl6$Av;pc6MsLiVdi9#Iy-d`I>8Ki)hL z=C!%n1T@9BzTCoo`C;dIa+uDO`epW*Lx*vIk>mv+AAG1ts8M%geo9JTF%I4NVX5z+ z-`ToKo%5?A6)2v37Uj@IOPKG5km

*Puv3ZA;6uRsnV=Jl1|PS5l{4h-=F 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 C;x}vn literal 0 HcmV?d00001