From 13fc0b90db03fc59369b355482d48a2d8259c04e Mon Sep 17 00:00:00 2001 From: Abdessamad Derraz <3028866+Abdess@users.noreply.github.com> Date: Tue, 27 Oct 2026 20:56:14 +0100 Subject: [PATCH] feat: gate pasted hashes in the site search A pasted MD5, CRC32 or SHA256 of scph5501.bin goes through the search box's hash lookup to the card on the PlayStation page. 54 queries. --- website/tools/measure.mjs | 21 +++++++++++++++++++++ website/tools/search_gate.py | 6 ++++++ 2 files changed, 27 insertions(+) diff --git a/website/tools/measure.mjs b/website/tools/measure.mjs index 26f65b541..0e0212060 100644 --- a/website/tools/measure.mjs +++ b/website/tools/measure.mjs @@ -68,6 +68,27 @@ if (mode === 'weight') { if (n === 0) await page.click('button[data-open-modal]'); const input = page.locator('dialog input[type="text"], dialog input[type="search"]').first(); await input.fill(query); + if (/^[0-9a-f]+$/.test(query) && [8, 32, 40, 64].includes(query.length)) { + // A pasted hash: the search offers "Look up this hash" first, and + // the lookup names the cards that hold the value. Its results + // are those cards. + const lookup = await page.waitForSelector('.rb-search-hash a', { timeout: 15000 }); + const found = await context.newPage(); + await found.goto(await lookup.evaluate((a) => a.href), { waitUntil: 'networkidle' }); + await found.waitForFunction(() => /^Found|^No file/.test(document.getElementById('rb-file-lookup-status')?.textContent ?? ''), null, { timeout: 15000 }); + results = await found.evaluate(() => { + const cards = [...document.querySelectorAll('#rb-file-lookup-result a')].filter((a) => a.textContent === 'Open its card'); + return { + count: document.getElementById('rb-file-lookup-status')?.textContent ?? '', + top: cards.slice(0, 5).map((a) => `Open its card | ${new URL(a.href).pathname}${new URL(a.href).hash}`), + }; + }); + await found.close(); + await page.waitForTimeout(300); + const transfer = sum(rows.slice(mark), () => true); + console.log(JSON.stringify({ query, transfer_kb: (transfer / 1024).toFixed(1), ...results })); + continue; + } await page.waitForSelector('.pagefind-ui__result', { timeout: 15000 }); await page.waitForTimeout(1200); results = await page.evaluate(() => { diff --git a/website/tools/search_gate.py b/website/tools/search_gate.py index ee8d04060..78a5bf932 100644 --- a/website/tools/search_gate.py +++ b/website/tools/search_gate.py @@ -112,6 +112,12 @@ QUERIES: dict[str, tuple[tuple[str, ...], int]] = { "r36s": (("platforms/", "which-pack/"), 3), "steam deck": (("platforms/emudeck/", "platforms/retrodeck/", "which-pack/"), 1), "knulli": (("platforms/knulli/",), 1), + # A pasted hash of any kind finds the file's card, its hashes now in a + # closed fold: the MD5, CRC32 and SHA256 of scph5501.bin. The search box + # offers "Look up this hash", and the lookup opens the card. + "490f666e1afb15b7362b406ed1cea246": (("systems/sony-playstation/",), 1), + "8d8cb7e4": (("systems/sony-playstation/",), 1), + "11052b6499e466bbf0a709b1f9cb6834a9418e66680387912451e971cf8a1fef": (("systems/sony-playstation/",), 1), }