From b6265c2245a5022fb487f6b80a83a8bb0486447e Mon Sep 17 00:00:00 2001 From: Afraaz Ali Date: Wed, 28 Jul 2021 08:09:58 -0700 Subject: [PATCH] [FEATURE] - Allow daemon mode to search for torrents via hash * Fixes #118 --- src/pipeline.ts | 10 ++++++++++ src/server.ts | 30 +++++++++++++++++++++++------- src/torrent.ts | 13 +++++++++++++ 3 files changed, 46 insertions(+), 7 deletions(-) diff --git a/src/pipeline.ts b/src/pipeline.ts index 0293bd58..aeb8c10a 100755 --- a/src/pipeline.ts +++ b/src/pipeline.ts @@ -12,6 +12,7 @@ import { Searchee } from "./searchee"; import { getInfoHashesToExclude, getTorrentByName, + getTorrentByHash, loadTorrentDirLight, saveTorrentFile, } from "./torrent"; @@ -145,6 +146,15 @@ export async function searchForSingleTorrentByName( return findOnOtherSites(meta, hashesToExclude); } +export async function searchForSingleTorrentByHash( + hash: string +): Promise { + const meta = await getTorrentByHash(hash); + const hashesToExclude = getInfoHashesToExclude(); + if (!filterByContent(meta)) return null; + return findOnOtherSites(meta, hashesToExclude); +} + async function findSearchableTorrents() { const { offset } = getRuntimeConfig(); const parsedTorrents: Searchee[] = await loadTorrentDirLight(); diff --git a/src/server.ts b/src/server.ts index 735ca895..b37e77ec 100644 --- a/src/server.ts +++ b/src/server.ts @@ -3,7 +3,10 @@ import http from "http"; import qs from "querystring"; import { validateJackettApi } from "./jackett"; import { Label, logger } from "./logger"; -import { searchForSingleTorrentByName } from "./pipeline"; +import { + searchForSingleTorrentByName, + searchForSingleTorrentByHash, +} from "./pipeline"; import { getRuntimeConfig } from "./runtimeConfig"; function getData(req) { @@ -23,7 +26,7 @@ function parseData(data) { return JSON.parse(data); } catch (_) { const parsed = qs.parse(data); - if ("name" in parsed) return parsed; + if ("name" in parsed || "hash" in parsed) return parsed; throw new Error(`Unable to parse request body: "${data}"`); } } @@ -40,21 +43,34 @@ async function handleRequest(req, res) { return; } const dataStr = await getData(req); - const { name } = parseData(dataStr); + const { name, hash } = parseData(dataStr); + const criteria = name ? name : hash; + const message = `Received ${name ? "name" : "hash"} ${criteria}`; res.writeHead(204); res.end(); - logger.info({ label: Label.SERVER, message: `Received name ${name}` }); + + logger.info({ label: Label.SERVER, message }); + try { - const numFound = await searchForSingleTorrentByName(name); + let numFound = null; + if (name) { + numFound = await searchForSingleTorrentByName(name); + } + + // Just in case both name and hash are passed. + if (hash && !numFound) { + numFound = await searchForSingleTorrentByHash(hash); + } + if (numFound === null) { logger.info({ label: Label.SERVER, - message: `Did not search for ${name}`, + message: `Did not search for ${criteria}`, }); } else { logger.info({ label: Label.SERVER, - message: `Found ${numFound} torrents for ${name}`, + message: `Found ${numFound} torrents for ${criteria}`, }); } } catch (e) { diff --git a/src/torrent.ts b/src/torrent.ts index f8d7d3e6..1c54b083 100644 --- a/src/torrent.ts +++ b/src/torrent.ts @@ -156,3 +156,16 @@ export async function getTorrentByName(name: string): Promise { } return parseTorrentFromFilename(findResult.filepath); } + +export async function getTorrentByHash(hash: string): Promise { + await indexNewTorrents(); + const findResult = db + .get(INDEXED_TORRENTS) + .value() + .find((e) => e.infoHash === hash); + if (findResult === undefined) { + const message = `could not find a torrent with the hash ${hash}`; + throw new Error(message); + } + return parseTorrentFromFilename(findResult.filepath); +}