Checkpoint opt-in MangaDex parser worker

This commit is contained in:
Codex committed 2026-10-13 21:57:59 +02:00
1 parent 93f07e838e
commit 1c61686c9b
11 files changed
+298 -24

No files matched your search

+25 -8
View File
@@ -2,6 +2,7 @@
const API = 'https://api.mangadex.org';
const { specialKey } = require('../../chapter-identity');
const { parseSource } = require('../plugins/client');
function mangaDexInfo(value) {
let url;
@@ -94,6 +95,10 @@ async function discoverMangaDexCatalog(seriesUrl, http) {
if (!info) throw new Error('Invalid MangaDex title URL');
const manga = (await jsonGet(http, `${API}/manga/${info.id}`)).data;
if (!manga || manga.type !== 'manga') throw new Error('MangaDex title was not found');
const isolated = !!process.env.MANGADEX_PLUGIN_URL;
const pluginMetadata = isolated
? await parseSource('mangadex', 'metadata', { html: JSON.stringify(manga), url: `${API}/manga/${info.id}` })
: null;
const releases = [];
let offset = 0;
@@ -103,28 +108,37 @@ async function discoverMangaDexCatalog(seriesUrl, http) {
params.append('includes[]', 'scanlation_group');
params.append('order[chapter]', 'asc');
const page = await jsonGet(http, `${API}/manga/${info.id}/feed?${params}`);
releases.push(...(page.data || []));
if (isolated) {
const parsed = await parseSource('mangadex', 'feed', { html: JSON.stringify(page.data || []), url: `${API}/manga/${info.id}/feed` });
releases.push(...parsed.releases);
} else releases.push(...(page.data || []));
offset += page.data?.length || 0;
if (!page.data?.length || offset >= Number(page.total || 0)) break;
}
const title = localizedTitle(manga.attributes);
const specialLabel = /pre.serialization|pilot/i.test(title) ? 'Pilot'
const title = isolated ? pluginMetadata.title : localizedTitle(manga.attributes);
const specialLabel = isolated ? pluginMetadata.specialLabel : /pre.serialization|pilot/i.test(title) ? 'Pilot'
: (manga.attributes?.tags || []).some(tag => tag.attributes?.name?.en === 'Oneshot') ? 'One-shot' : 'Special';
const chapters = selectChapterReleases(releases, specialLabel);
const pluginCatalog = async externalReleases => parseSource('mangadex', 'catalog', {
html: JSON.stringify({ attributes: pluginMetadata.availabilityAttributes, releases, specialLabel, externalReleases }),
url: `${API}/manga/${info.id}`,
});
let parsed = isolated ? await pluginCatalog(null) : null;
const chapters = isolated ? parsed.chapters : selectChapterReleases(releases, specialLabel);
// External-only is a separate feed mode, not a combined hosted+external catalog.
let externalReleases = null;
if (!chapters.length) {
const params = new URLSearchParams({ limit: '1', includeFutureUpdates: '0', includeExternalUrl: '1' });
params.append('translatedLanguage[]', 'en');
externalReleases = Number((await jsonGet(http, `${API}/manga/${info.id}/feed?${params}`)).total || 0);
if (isolated) parsed = await pluginCatalog(externalReleases);
}
return {
id: info.id,
title,
originalLanguage: manga.attributes?.originalLanguage || null,
links: manga.attributes?.links || {},
availability: availabilitySummary(manga.attributes || {}, releases, chapters, externalReleases),
originalLanguage: isolated ? pluginMetadata.originalLanguage : manga.attributes?.originalLanguage || null,
links: isolated ? pluginMetadata.links : manga.attributes?.links || {},
availability: isolated ? parsed.availability : availabilitySummary(manga.attributes || {}, releases, chapters, externalReleases),
chapters,
};
}
@@ -147,11 +161,14 @@ function pageUrls(atHome, chapterUrl, expectedPages) {
async function discoverMangaDexChapter(ref, http) {
const atHome = await jsonGet(http, `${API}/at-home/server/${ref.id}?forcePort443=true`);
const groupName = ref.group?.name ? ` · ${ref.group.name}` : '';
const parsed = process.env.MANGADEX_PLUGIN_URL
? await parseSource('mangadex', 'atHome', { html: JSON.stringify({ response: atHome, chapterUrl: ref.url, expectedPages: ref.pages }), url: `${API}/at-home/server/${ref.id}` })
: null;
return {
number: ref.number, title: ref.title || '', added: ref.added,
...(ref.special ? { special: true, label: ref.label, sourceId: ref.id, sourceNumber: ref.sourceNumber ?? null } : {}),
source: { name: `MangaDex${groupName}`, url: ref.url },
pages: pageUrls(atHome, ref.url, ref.pages),
pages: parsed ? parsed.pages : pageUrls(atHome, ref.url, ref.pages),
};
}