mirror of
https://github.com/mmahdium/TorrentMax.git
synced 2026-08-14 17:22:49 +03:30
Finished API integration
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
import { getMagnetUrl, parseMagnet } from "~~/server/utils/magnetParser";
|
||||
import { addTrackers, getTrackers } from "~~/server/utils/trackerHelper";
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const body = await readBody<{ magnet?: string }>(event);
|
||||
const magnetUrl = body?.magnet;
|
||||
|
||||
if (!magnetUrl) {
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage: "Missing magnet URL",
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
const maxedMagnet = addTrackers(
|
||||
parseMagnet(magnetUrl),
|
||||
await getTrackers()
|
||||
);
|
||||
return {
|
||||
totalTrackers: maxedMagnet.tr?.length,
|
||||
name: maxedMagnet.dn,
|
||||
id: maxedMagnet.xt.slice(9),
|
||||
maxedMagnet: getMagnetUrl(maxedMagnet),
|
||||
};
|
||||
} catch (error: any) {
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage: error.message || "Invalid magnet URL",
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,68 @@
|
||||
import type { MagnetUrl } from "../../shared/types/magnet";
|
||||
|
||||
export function parseMagnet(magnetUrl: string): MagnetUrl {
|
||||
if (!magnetUrl.startsWith("magnet:?")) {
|
||||
throw new Error('Invalid magnet URL: Must start with "magnet:?"');
|
||||
}
|
||||
|
||||
const params = new URLSearchParams(magnetUrl.substring(8)); // Remove 'magnet:?' prefix
|
||||
const xt = params.get("xt");
|
||||
|
||||
if (!xt) {
|
||||
throw new Error("Invalid magnet URL: Missing required xt parameter");
|
||||
}
|
||||
|
||||
// Validate xt format (btih hash)
|
||||
const btihRegex = /^urn:btih:([a-fA-F0-9]{40}|[A-Z2-7]{32})$/;
|
||||
if (!btihRegex.test(xt)) {
|
||||
throw new Error("Invalid magnet URL: Invalid xt parameter format");
|
||||
}
|
||||
|
||||
const magnet: MagnetUrl = {
|
||||
xt,
|
||||
};
|
||||
|
||||
const dn = params.get("dn");
|
||||
if (dn) {
|
||||
magnet.dn = decodeURIComponent(dn);
|
||||
}
|
||||
|
||||
const tr = params.getAll("tr");
|
||||
if (tr.length > 0) {
|
||||
magnet.tr = tr.map(decodeURIComponent);
|
||||
}
|
||||
|
||||
const as = params.getAll("as");
|
||||
if (as.length > 0) {
|
||||
magnet.as = as.map(decodeURIComponent);
|
||||
}
|
||||
|
||||
const xs = params.getAll("xs");
|
||||
if (xs.length > 0) {
|
||||
magnet.xs = xs.map(decodeURIComponent);
|
||||
}
|
||||
|
||||
const kt = params.get("kt");
|
||||
if (kt) {
|
||||
magnet.kt = decodeURIComponent(kt);
|
||||
}
|
||||
|
||||
const mt = params.get("mt");
|
||||
if (mt) {
|
||||
magnet.mt = decodeURIComponent(mt);
|
||||
}
|
||||
|
||||
return magnet;
|
||||
}
|
||||
|
||||
export function getMagnetUrl(magnet: MagnetUrl): string {
|
||||
const params = new URLSearchParams();
|
||||
Object.entries(magnet).forEach(([key, value]) => {
|
||||
if (Array.isArray(value)) {
|
||||
value.forEach((v) => params.append(`${key}`, v));
|
||||
} else {
|
||||
params.append(`${key}`, value);
|
||||
}
|
||||
});
|
||||
return `magnet:?${params.toString()}`;
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
import type { MagnetUrl } from "../../shared/types/magnet";
|
||||
|
||||
let cachedTrackers: string[] | null = null;
|
||||
let lastFetched = 0;
|
||||
const CACHE_TTL = 1000 * 60 * 10; // 10 minutes
|
||||
|
||||
export async function getTrackers(): Promise<string[]> {
|
||||
const now = Date.now();
|
||||
|
||||
if (cachedTrackers && now - lastFetched < CACHE_TTL) {
|
||||
return cachedTrackers;
|
||||
}
|
||||
|
||||
const TRACKER_URLS = [
|
||||
"https://raw.githubusercontent.com/XIU2/TrackersListCollection/refs/heads/master/all.txt",
|
||||
"https://raw.githubusercontent.com/ngosang/trackerslist/refs/heads/master/trackers_all.txt",
|
||||
];
|
||||
|
||||
for (const url of TRACKER_URLS) {
|
||||
try {
|
||||
const response = await fetch(url);
|
||||
if (response.ok) {
|
||||
const text = await response.text();
|
||||
const trackers = text
|
||||
.split("\n")
|
||||
.map((line) => line.trim())
|
||||
.filter((line) => line !== "");
|
||||
|
||||
// update cache
|
||||
cachedTrackers = trackers;
|
||||
lastFetched = now;
|
||||
return trackers;
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
|
||||
// fallback: return cached even if stale, or empty
|
||||
return cachedTrackers ?? [];
|
||||
}
|
||||
|
||||
export function addTrackers(magnet: MagnetUrl, trackers: string[]): MagnetUrl {
|
||||
if (trackers.length > 0) {
|
||||
// avoid duplicates
|
||||
const existing = new Set(magnet.tr ?? []);
|
||||
for (const tracker of trackers) {
|
||||
if (!existing.has(tracker)) {
|
||||
magnet.tr?.push(tracker);
|
||||
}
|
||||
}
|
||||
}
|
||||
return magnet;
|
||||
}
|
||||
Reference in New Issue
Block a user