mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 16:02:26 +00:00
Merge pull request #1774 from PR0M3TH3AN/codex/add-helper-to-extract-btih-from-magnets
Add BTIH extraction helper and normalize infohash handling
This commit is contained in:
5 files changed
+107
-63
No files matched your search
@@ -13,7 +13,7 @@ import {
|
||||
ALLOW_NSFW_CONTENT,
|
||||
} from "./config.js";
|
||||
import { accessControl } from "./accessControl.js";
|
||||
import { safeDecodeMagnet } from "./magnetUtils.js";
|
||||
import { extractBtihFromMagnet, safeDecodeMagnet } from "./magnetUtils.js";
|
||||
import { deriveTorrentPlaybackConfig } from "./playbackUtils.js";
|
||||
import {
|
||||
URL_FIRST_ENABLED,
|
||||
@@ -8571,9 +8571,9 @@ class Application {
|
||||
typeof video.infoHash === "string" ? video.infoHash.trim().toLowerCase() : "";
|
||||
const fallbackMagnetForCandidate = fallbackMagnetCandidate || "";
|
||||
if (!legacyInfoHash && fallbackMagnetForCandidate) {
|
||||
const match = fallbackMagnetForCandidate.match(/xt=urn:btih:([0-9a-z]+)/i);
|
||||
if (match && match[1]) {
|
||||
legacyInfoHash = match[1].toLowerCase();
|
||||
const extracted = extractBtihFromMagnet(fallbackMagnetForCandidate);
|
||||
if (extracted) {
|
||||
legacyInfoHash = extracted;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+92
-1
@@ -5,9 +5,11 @@ import {
|
||||
} from "./utils/safeDecode.js";
|
||||
|
||||
const HEX_INFO_HASH = /^[0-9a-f]{40}$/i;
|
||||
const BASE32_INFO_HASH = /^[a-z2-7]{32}$/i;
|
||||
const BTIH_PREFIX = "urn:btih:";
|
||||
const MAGNET_SCHEME = "magnet:";
|
||||
const ENCODED_BTih_PATTERN = /xt=urn%3Abtih%3A([0-9a-z]+)/gi;
|
||||
const BASE32_ALPHABET = "abcdefghijklmnopqrstuvwxyz234567";
|
||||
|
||||
export function safeDecodeMagnet(value) {
|
||||
if (typeof value !== "string") {
|
||||
@@ -56,6 +58,96 @@ export function normalizeForComparison(value) {
|
||||
}
|
||||
}
|
||||
|
||||
function decodeBase32ToHex(value) {
|
||||
if (typeof value !== "string" || !value) {
|
||||
return "";
|
||||
}
|
||||
|
||||
const normalized = value.toLowerCase();
|
||||
let bits = 0;
|
||||
let buffer = 0;
|
||||
const bytes = [];
|
||||
|
||||
for (const char of normalized) {
|
||||
const index = BASE32_ALPHABET.indexOf(char);
|
||||
if (index === -1) {
|
||||
return "";
|
||||
}
|
||||
buffer = (buffer << 5) | index;
|
||||
bits += 5;
|
||||
if (bits >= 8) {
|
||||
bits -= 8;
|
||||
const byte = (buffer >> bits) & 0xff;
|
||||
bytes.push(byte);
|
||||
}
|
||||
}
|
||||
|
||||
if (!bytes.length) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return bytes.map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
||||
}
|
||||
|
||||
export function normalizeInfoHash(value) {
|
||||
const trimmed = typeof value === "string" ? value.trim() : "";
|
||||
if (!trimmed) {
|
||||
return "";
|
||||
}
|
||||
if (HEX_INFO_HASH.test(trimmed)) {
|
||||
return trimmed.toLowerCase();
|
||||
}
|
||||
if (BASE32_INFO_HASH.test(trimmed)) {
|
||||
const hex = decodeBase32ToHex(trimmed);
|
||||
return hex ? hex.toLowerCase() : "";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
function extractInfoHashFromXt(value) {
|
||||
if (typeof value !== "string") {
|
||||
return "";
|
||||
}
|
||||
const trimmed = value.trim();
|
||||
if (!trimmed) {
|
||||
return "";
|
||||
}
|
||||
const lower = trimmed.toLowerCase();
|
||||
if (!lower.startsWith(BTIH_PREFIX)) {
|
||||
return "";
|
||||
}
|
||||
return normalizeInfoHash(trimmed.slice(BTIH_PREFIX.length));
|
||||
}
|
||||
|
||||
export function extractBtihFromMagnet(rawValue) {
|
||||
const decoded = safeDecodeMagnet(rawValue);
|
||||
const { initial, isMagnet, params } = normalizeMagnetInput(decoded);
|
||||
|
||||
if (!initial) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (!isMagnet) {
|
||||
if (initial.toLowerCase().startsWith(BTIH_PREFIX)) {
|
||||
return normalizeInfoHash(initial.slice(BTIH_PREFIX.length));
|
||||
}
|
||||
return normalizeInfoHash(initial);
|
||||
}
|
||||
|
||||
for (const param of params) {
|
||||
if (param.lowerKey !== "xt") {
|
||||
continue;
|
||||
}
|
||||
const candidate = param.decoded || param.value;
|
||||
const normalized = extractInfoHashFromXt(candidate);
|
||||
if (normalized) {
|
||||
return normalized;
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
function createParam(key, value) {
|
||||
const trimmedValue = typeof value === "string" ? value.trim() : "";
|
||||
const decoded = safeDecodeURIComponentLoose(trimmedValue);
|
||||
@@ -342,4 +434,3 @@ export function extractMagnetHints(rawValue) {
|
||||
}
|
||||
return hints;
|
||||
}
|
||||
|
||||
@@ -6,13 +6,17 @@ import {
|
||||
ensureTrackers,
|
||||
ensureTorrentHint,
|
||||
ensureWebSeeds,
|
||||
extractBtihFromMagnet as sharedExtractBtihFromMagnet,
|
||||
normalizeMagnetInput,
|
||||
normalizeInfoHash as sharedNormalizeInfoHash,
|
||||
resolveAppProtocol,
|
||||
safeDecodeMagnet as sharedSafeDecodeMagnet,
|
||||
} from "./magnetShared.js";
|
||||
|
||||
export { WSS_TRACKERS };
|
||||
export const safeDecodeMagnet = sharedSafeDecodeMagnet;
|
||||
export const extractBtihFromMagnet = sharedExtractBtihFromMagnet;
|
||||
export const normalizeInfoHash = sharedNormalizeInfoHash;
|
||||
|
||||
export function normalizeAndAugmentMagnet(
|
||||
rawValue,
|
||||
|
||||
+3
-54
@@ -1,35 +1,4 @@
|
||||
const BASE32_ALPHABET = "abcdefghijklmnopqrstuvwxyz234567";
|
||||
|
||||
function decodeBase32ToHex(value) {
|
||||
if (typeof value !== "string" || !value) {
|
||||
return "";
|
||||
}
|
||||
|
||||
const normalized = value.toLowerCase();
|
||||
let bits = 0;
|
||||
let buffer = 0;
|
||||
const bytes = [];
|
||||
|
||||
for (const char of normalized) {
|
||||
const index = BASE32_ALPHABET.indexOf(char);
|
||||
if (index === -1) {
|
||||
return "";
|
||||
}
|
||||
buffer = (buffer << 5) | index;
|
||||
bits += 5;
|
||||
if (bits >= 8) {
|
||||
bits -= 8;
|
||||
const byte = (buffer >> bits) & 0xff;
|
||||
bytes.push(byte);
|
||||
}
|
||||
}
|
||||
|
||||
if (bytes.length === 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return bytes.map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
||||
}
|
||||
import { extractBtihFromMagnet, normalizeInfoHash } from "./magnetShared.js";
|
||||
|
||||
function extractInfoHashFromXt(value) {
|
||||
if (typeof value !== "string") {
|
||||
@@ -50,32 +19,12 @@ function extractInfoHashFromXt(value) {
|
||||
return normalizeInfoHash(payload);
|
||||
}
|
||||
|
||||
function normalizeInfoHash(candidate) {
|
||||
const trimmed = typeof candidate === "string" ? candidate.trim() : "";
|
||||
if (!trimmed) {
|
||||
return null;
|
||||
}
|
||||
if (/^[0-9a-f]{40}$/i.test(trimmed)) {
|
||||
return trimmed.toLowerCase();
|
||||
}
|
||||
if (/^[a-z2-7]{32}$/i.test(trimmed)) {
|
||||
const hex = decodeBase32ToHex(trimmed);
|
||||
return hex ? hex.toLowerCase() : null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export function infoHashFromMagnet(magnet) {
|
||||
if (typeof magnet !== "string") {
|
||||
return null;
|
||||
}
|
||||
const direct = normalizeInfoHash(magnet);
|
||||
if (direct) {
|
||||
return direct;
|
||||
}
|
||||
const parsed = parseMagnetLite(magnet);
|
||||
const hash = typeof parsed.infoHash === "string" ? parsed.infoHash : "";
|
||||
return hash ? hash.toLowerCase() : null;
|
||||
const extracted = extractBtihFromMagnet(magnet);
|
||||
return extracted || null;
|
||||
}
|
||||
|
||||
export function trackersFromMagnet(magnet) {
|
||||
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
import { deriveTitleFromEvent } from "../videoEventUtils.js";
|
||||
import { extractMagnetHints } from "../magnetShared.js";
|
||||
import { extractBtihFromMagnet, extractMagnetHints } from "../magnetShared.js";
|
||||
import { devLogger } from "../utils/logger.js";
|
||||
import { getCachedNostrTools } from "./toolkit.js";
|
||||
|
||||
@@ -1432,9 +1432,9 @@ export function convertEventToVideo(event = {}) {
|
||||
const originalFileSha256 = normalizeSha256(parsedContent.originalFileSha256);
|
||||
|
||||
if (!infoHash && magnet) {
|
||||
const match = magnet.match(/xt=urn:btih:([0-9a-z]+)/i);
|
||||
if (match && match[1]) {
|
||||
pushInfoHash(match[1]);
|
||||
const extracted = extractBtihFromMagnet(magnet);
|
||||
if (extracted) {
|
||||
infoHash = extracted;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user