diff --git a/api/v1/src/release.ts b/api/v1/src/release.ts
index 9ecab4f..46251df 100644
--- a/api/v1/src/release.ts
+++ b/api/v1/src/release.ts
@@ -5,10 +5,27 @@ const baseHeaders = {
"Accept": "application/json",
};
-// Получение информации с Shikimori
+// Взвешенное среднее из 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", characters: [] };
+ return { score: "N/A", weightedScore: "N/A", characters: [] };
}
const animeUrl = `https://shikimori.one/api/animes?search=${encodeURIComponent(search)}&limit=1${year ? `&year=${year}` : ""}`;
@@ -19,9 +36,16 @@ async function getShikimoriData(search, year) {
const anime = animeData?.[0];
if (!anime || !anime.id) {
- return { score: "N/A", characters: [] };
+ 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();
@@ -36,14 +60,15 @@ async function getShikimoriData(search, year) {
return {
score: anime.score || "N/A",
+ weightedScore,
characters: mainCharacters,
};
} catch {
- return { score: "N/A", characters: [] };
+ return { score: "N/A", weightedScore: "N/A", characters: [] };
}
}
-// Получение рейтинга с MyAnimeList (через Jikan)
+// Рейтинг с MyAnimeList через Jikan
async function getMALScore(title) {
const url = `https://api.jikan.moe/v4/anime?q=${encodeURIComponent(title)}&limit=1`;
@@ -62,7 +87,7 @@ async function getMALScore(title) {
}
}
-// Получение релиза и формирование итоговой заметки
+// Получение и сборка данных о релизе
async function getReleaseFromAnixart(releaseId, token = "") {
const url = `https://api.anixart.tv/release/${releaseId}${token ? `?token=${token}` : ""}`;
@@ -82,6 +107,7 @@ async function getReleaseFromAnixart(releaseId, token = "") {
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";
@@ -89,13 +115,15 @@ async function getReleaseFromAnixart(releaseId, token = "") {
const malScore = await getMALScore(title);
noteExtra =
- `Рейтинг Shikimori: ${shikiScore}
` +
- `Рейтинг MyAnimeList: ${malScore}
` +
+ `Shikimori (официальный): ${shikiScore}
` +
+ `Shikimori (взвешенный): ${shikiWeighted}
` +
+ `MyAnimeList: ${malScore}
` +
`Главные персонажи: ${characters}
`;
} catch {
noteExtra =
- `Рейтинг Shikimori: N/A
` +
- `Рейтинг MyAnimeList: N/A
` +
+ `Shikimori (официальный): N/A
` +
+ `Shikimori (взвешенный): N/A
` +
+ `MyAnimeList: N/A
` +
`Главные персонажи: N/A
`;
}
@@ -113,7 +141,7 @@ async function getReleaseFromAnixart(releaseId, token = "") {
}
}
-// Серверный эндпоинт
+// Серверный роутинг
serve(async (req) => {
const url = new URL(req.url);
const path = url.pathname;