From 36bf7d683ca1d5d8c5a25e074127384100a2a04d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=82=BC=E3=83=BC=E3=83=AC?= Date: Mon, 12 May 2025 14:47:30 +0500 Subject: [PATCH] Create release.ts --- api/v1/src/release.ts | 106 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 api/v1/src/release.ts diff --git a/api/v1/src/release.ts b/api/v1/src/release.ts new file mode 100644 index 0000000..bdf80f3 --- /dev/null +++ b/api/v1/src/release.ts @@ -0,0 +1,106 @@ +import { serve } from "https://deno.land/std@0.140.0/http/server.ts"; + +const baseHeaders = { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)", + "Accept": "application/json", +}; + +async function getShikimoriData(search, year) { + if (!search) { + return { score: "N/A", characters: [] }; + } + + const animeUrl = `https://shikimori.one/api/animes?search=${encodeURIComponent(search)}&limit=1${year ? `&year=${year}` : ""}`; + + try { + const animeRes = await fetch(animeUrl, { headers: baseHeaders }); + const animeData = await animeRes.json(); + const anime = animeData?.[0]; + + if (!anime || !anime.id) { + return { score: "N/A", characters: [] }; + } + + const rolesUrl = `https://shikimori.one/api/animes/${anime.id}/roles`; + const rolesRes = await fetch(rolesUrl, { headers: baseHeaders }); + const roles = await rolesRes.json(); + + const mainCharacters = roles + .filter((c) => c.roles.includes("Main")) + .slice(0, 5) + .map((c) => ({ + name: c.character.russian, + url: `https://shikimori.one${c.character.url}`, + })); + + return { + score: anime.score || "N/A", + characters: mainCharacters, + }; + } catch { + return { score: "N/A", characters: [] }; + } +} + +async function getReleaseFromAnixart(releaseId, token = "") { + const url = `https://api.anixart.tv/release/${releaseId}${token ? `?token=${token}` : ""}`; + + try { + const response = await fetch(url, { headers: baseHeaders }); + const data = await response.json(); + const release = data?.release; + + if (!release) { + return { code: 2, release: null }; + } + + const title = release.title_original || release.title_ru || ""; + const year = release.year || ""; + let noteExtra = ""; + + try { + const shikiData = await getShikimoriData(title, year); + const score = shikiData.score || "N/A"; + const characters = shikiData.characters.length + ? shikiData.characters.map((c) => `${c.name}`).join(", ") + : "N/A"; + + noteExtra = `Оценки из Shikimori: ${score}
Главные персонажи: ${characters}
`; + } catch { + noteExtra = `Оценки из Shikimori: N/A
Главные персонажи: N/A
`; + } + + const originalNote = release.note?.trim(); + let finalNote = noteExtra; + if (originalNote) { + finalNote += `
Примечание от Anixart:
${originalNote}`; + } + + release.note = finalNote; + + return { code: 0, release }; + } catch { + return { code: 2, release: null }; + } +} + +serve(async (req) => { + const url = new URL(req.url); + const path = url.pathname; + const token = url.searchParams.get("token"); + + // Эндпоинт: /api/release/{releaseId} + const releaseMatch = path.match(/^\/api\/release\/([^\/]+)/); + if (releaseMatch) { + const releaseId = releaseMatch[1]; + const result = await getReleaseFromAnixart(releaseId, token); + return new Response(JSON.stringify(result), { + headers: { + "Content-Type": "application/json", + "Access-Control-Allow-Origin": "*", + }, + }); + } + + return new Response("Invalid endpoint", { status: 404 }); +});