Add Greatest of All Time manga dashboard
This commit is contained in:
1 parent
c8dd46d0fb
commit
5df94db9a3
16 files changed
+2717
-1
No files matched your search
@@ -0,0 +1,70 @@
|
||||
'use strict';
|
||||
// Optional, manually run metadata pass. The reader never contacts AniList at runtime.
|
||||
// This intentionally only enriches an exact first-serialization-year match; a sequel,
|
||||
// remake, or similarly named work is worse than a missing cover.
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { normalize } = require('../greatest');
|
||||
|
||||
const file = path.join(__dirname, '..', 'greatest', 'catalog.json');
|
||||
const catalog = JSON.parse(fs.readFileSync(file, 'utf8'));
|
||||
const wait = ms => new Promise(resolve => setTimeout(resolve, ms));
|
||||
const query = `query ($search: String) {
|
||||
Page(perPage: 10) {
|
||||
media(search: $search, type: MANGA, format: MANGA, sort: POPULARITY_DESC) {
|
||||
id title { english romaji native } startDate { year } chapters status siteUrl
|
||||
coverImage { large }
|
||||
}
|
||||
}
|
||||
}`;
|
||||
const aliases = {
|
||||
'kitaro-gegege-no-kitaro-1960': 'Hakaba Kitarou',
|
||||
'the-legend-of-kamui-kamui-den-1964': 'Kamui Den',
|
||||
'the-poem-of-wind-and-trees-1976': 'Kaze to Ki no Uta',
|
||||
'the-heart-of-thomas-1974': 'Thomas no Shinzou',
|
||||
'gto-great-teacher-onizuka-1997': 'Great Teacher Onizuka',
|
||||
'someone-hertz-2025': 'Samawan Hertz',
|
||||
'home-at-the-horizon-2025': 'Okaeri Suiheisen',
|
||||
'war-of-the-adults-2025': 'Otona Taisen',
|
||||
'frieren-beyond-journey-s-end-2020': 'Sousou no Frieren',
|
||||
};
|
||||
|
||||
async function search(title) {
|
||||
for (let attempt = 0; attempt < 3; attempt++) {
|
||||
const response = await fetch('https://graphql.anilist.co', {
|
||||
method: 'POST', headers: { 'content-type': 'application/json' },
|
||||
body: JSON.stringify({ query, variables: { search: title } }), signal: AbortSignal.timeout(12000),
|
||||
});
|
||||
if (response.status === 429 || response.status >= 500) { await wait(10000 * (attempt + 1)); continue; }
|
||||
const body = await response.json();
|
||||
return body.data?.Page?.media || [];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
(async () => {
|
||||
let matched = 0;
|
||||
for (const [index, entry] of catalog.entries.entries()) {
|
||||
const title = aliases[entry.id] || entry.title.split(' / ')[0].split(': ')[0];
|
||||
try {
|
||||
const results = await search(title);
|
||||
const target = normalize(title);
|
||||
const match = results.find(item => item.startDate?.year === entry.year &&
|
||||
[item.title?.english, item.title?.romaji, item.title?.native].some(name => normalize(name) === target)) ||
|
||||
results.find(item => item.startDate?.year === entry.year &&
|
||||
[item.title?.english, item.title?.romaji].some(name => normalize(name).includes(target) || target.includes(normalize(name))));
|
||||
if (match) {
|
||||
entry.cover = /^https:\/\//.test(match.coverImage?.large || '') ? match.coverImage.large : null;
|
||||
entry.chapters = Number.isInteger(match.chapters) && match.chapters > 0 ? match.chapters : null;
|
||||
entry.status = match.status === 'RELEASING' ? 'ongoing' : match.status === 'FINISHED' ? 'completed' : 'unknown';
|
||||
entry.metadata = { provider: 'AniList', id: match.id, url: match.siteUrl };
|
||||
matched++;
|
||||
} else process.stderr.write(`No exact year/title match: ${entry.title} (${entry.year})\n`);
|
||||
} catch (error) { process.stderr.write(`Metadata unavailable: ${entry.title}: ${error.message}\n`); }
|
||||
if ((index + 1) % 10 === 0) process.stderr.write(`Checked ${index + 1}/${catalog.entries.length}; matched ${matched}\n`);
|
||||
await wait(1500);
|
||||
}
|
||||
fs.writeFileSync(file + '.tmp', JSON.stringify(catalog, null, 2) + '\n');
|
||||
fs.renameSync(file + '.tmp', file);
|
||||
process.stderr.write(`Saved ${matched}/${catalog.entries.length} exact matches\n`);
|
||||
})().catch(error => { console.error(error); process.exitCode = 1; });
|
||||
Reference in new issue
Block a user