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", }; // Функция для расчёта рейтинга из rates_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 { 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 { weightedScore: "N/A", characters: [] }; } // Получаем рейтинг из rates_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.rates_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 { weightedScore, characters: mainCharacters, }; } catch { return { 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 || ""; try { const shikiData = await getShikimoriData(title, year); const shikiScore = shikiData.weightedScore !== "N/A" ? `Рейтинг Shikimori: ${shikiData.weightedScore}★` : ""; const malScoreRaw = await getMALScore(title); const malScore = malScoreRaw !== "N/A" ? `Рейтинг MyAnimeList: ${malScoreRaw}` : ""; const characters = shikiData.characters.length ? `Главные персонажи: ` + shikiData.characters.map(c => `${c.name}`).join(", ") : ""; // Собираем рейтинг и персонажей, фильтруя пустые строки const ratingParts = [shikiScore, malScore].filter(Boolean).join("
"); const charsPart = characters ? characters : ""; // Примечание от Anixart (без лишних br если пустое) const originalNote = release.note?.trim(); let finalNote = ""; if (ratingParts) finalNote += ratingParts; if (charsPart) finalNote += (finalNote ? "
" : "") + charsPart; if (originalNote) finalNote += (finalNote ? "

" : "") + `Примечание от Anixart:
${originalNote}`; release.note = finalNote || null; } catch { release.note = null; } return { code: 0, release }; } catch { return { code: 2, release: null }; } } // HTTP сервер serve(async (req) => { const url = new URL(req.url); const path = url.pathname; const token = url.searchParams.get("token"); 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 }); });