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", }; // Взвешенное среднее из scores_stats function calculateWeightedScore(stats) { if (!stats?.length) return null; let total = 0; let count = 0; for (const item of stats) { const score = parseInt(item.name); const votes = item.value; total += score * votes; count += votes; } return count ? (total / count).toFixed(2) : null; } // Получение данных с Shikimori async function getShikimoriData(search, year) { if (!search) { return { score: "N/A", weightedScore: "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", weightedScore: "N/A", characters: [] }; } // Взвешенный рейтинг из scores_stats const statsUrl = `https://shikimori.one/api/animes/${anime.id}`; const statsRes = await fetch(statsUrl, { headers: baseHeaders }); const statsData = await statsRes.json(); const weightedScore = calculateWeightedScore(statsData.scores_stats) || "N/A"; // Главные персонажи 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", weightedScore, characters: mainCharacters, }; } catch { return { score: "N/A", weightedScore: "N/A", characters: [] }; } } // Рейтинг с MyAnimeList через Jikan async function getMALScore(title) { const url = `https://api.jikan.moe/v4/anime?q=${encodeURIComponent(title)}&limit=1`; try { const response = await fetch(url); const data = await response.json(); const anime = data?.data?.[0]; if (!anime || !anime.score) { return "N/A"; } return `${anime.score}★`; } catch { return "N/A"; } } // Получение и сборка данных о релизе 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 shikiScore = shikiData.score || "N/A"; const shikiWeighted = shikiData.weightedScore || "N/A"; const characters = shikiData.characters.length ? shikiData.characters.map((c) => `${c.name}`).join(", ") : "N/A"; const malScore = await getMALScore(title); noteExtra = `Shikimori (официальный): ${shikiScore}
` + `Shikimori (взвешенный): ${shikiWeighted}
` + `MyAnimeList: ${malScore}
` + `Главные персонажи: ${characters}
`; } catch { noteExtra = `Shikimori (официальный): N/A
` + `Shikimori (взвешенный): N/A
` + `MyAnimeList: 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 }); });