101 lines
3.7 KiB
JavaScript
101 lines
3.7 KiB
JavaScript
'use strict';
|
|
|
|
const { runArchive } = require('../jobs/weebcentral-archive');
|
|
const { runMangaDexArchive } = require('../jobs/mangadex-archive');
|
|
const { SlowHttp } = require('../lib/http');
|
|
const { createWeebHttp } = require('../plugins/broker');
|
|
const { discoverWeebCatalog } = require('./weebcentral');
|
|
const { mangaDexInfo, discoverMangaDexCatalog } = require('./mangadex');
|
|
const { ArchiveControlError } = require('../lib/control');
|
|
const { adapterForPeer } = require('../../peering/adapter');
|
|
|
|
function controlledHttp(http, shouldStop) {
|
|
return { async get(...args) {
|
|
const check = () => { const reason = shouldStop?.(); if (reason) throw new ArchiveControlError(reason === true ? 'paused' : String(reason)); };
|
|
check(); const response = await http.get(...args); check(); return response;
|
|
} };
|
|
}
|
|
|
|
function weebCentralInfo(value) {
|
|
let url;
|
|
try { url = new URL(String(value)); } catch { return null; }
|
|
if (url.protocol !== 'https:' || url.hostname !== 'weebcentral.com') return null;
|
|
const match = /^\/series\/([A-Z0-9]+)(?:\/([^/?#]+))?\/?$/i.exec(url.pathname);
|
|
if (!match) return null;
|
|
const title = decodeURIComponent(match[2] || match[1]).replace(/[-_]+/g, ' ').trim();
|
|
return { source: 'weebcentral', id: match[1].toUpperCase(), title, url: `https://weebcentral.com/series/${match[1]}${match[2] ? `/${match[2]}` : ''}` };
|
|
}
|
|
|
|
const adapters = [{
|
|
id: 'weebcentral',
|
|
label: 'WeebCentral',
|
|
match: weebCentralInfo,
|
|
async discover(item, options) {
|
|
const httpOptions = {
|
|
minMs: options.settings.minMs, maxMs: options.settings.maxMs, maxRetries: 2,
|
|
onEvent: options.onEvent,
|
|
};
|
|
const http = process.env.SOURCE_PLUGIN_URL ? createWeebHttp(httpOptions) : new SlowHttp(httpOptions);
|
|
return discoverWeebCatalog(item.url, controlledHttp(http, options.shouldStop));
|
|
},
|
|
run(item, options) {
|
|
return runArchive({
|
|
seriesUrl: item.url,
|
|
libraryRoot: options.libraryRoot,
|
|
metadataSearch: item.metadataSearch || item.title,
|
|
minMs: options.settings.minMs,
|
|
maxMs: options.settings.maxMs,
|
|
chapterMinMs: options.settings.chapterMinMs,
|
|
chapterMaxMs: options.settings.chapterMaxMs,
|
|
shouldStop: options.shouldStop,
|
|
scope: item.scope,
|
|
existingPolicy: item.existingPolicy,
|
|
libraryMangaId: item.libraryMangaId,
|
|
onPublished: options.onPublished,
|
|
onCatalog: options.onCatalog,
|
|
});
|
|
},
|
|
}, {
|
|
id: 'mangadex',
|
|
label: 'MangaDex',
|
|
match: mangaDexInfo,
|
|
async discover(item, options) {
|
|
const http = new SlowHttp({
|
|
minMs: options.settings.minMs, maxMs: options.settings.maxMs, maxRetries: 2,
|
|
userAgent: 'MangaCircus-Scraper/1.0 (personal archival; sequential MangaDex requests)',
|
|
onEvent: options.onEvent,
|
|
});
|
|
return discoverMangaDexCatalog(item.url, controlledHttp(http, options.shouldStop));
|
|
},
|
|
run(item, options) {
|
|
return runMangaDexArchive({
|
|
seriesUrl: item.url,
|
|
title: item.title,
|
|
libraryRoot: options.libraryRoot,
|
|
metadataSearch: item.metadataSearch || item.title,
|
|
minMs: options.settings.minMs,
|
|
maxMs: options.settings.maxMs,
|
|
chapterMinMs: options.settings.chapterMinMs,
|
|
chapterMaxMs: options.settings.chapterMaxMs,
|
|
shouldStop: options.shouldStop,
|
|
scope: item.scope,
|
|
existingPolicy: item.existingPolicy,
|
|
libraryMangaId: item.libraryMangaId,
|
|
onPublished: options.onPublished,
|
|
onCatalog: options.onCatalog,
|
|
});
|
|
},
|
|
}];
|
|
|
|
function adapterFor(url) {
|
|
const peer = adapterForPeer(url);
|
|
if (peer) return peer;
|
|
for (const adapter of adapters) {
|
|
const info = adapter.match(url);
|
|
if (info) return { adapter, info };
|
|
}
|
|
return null;
|
|
}
|
|
|
|
module.exports = { adapters, adapterFor, weebCentralInfo, mangaDexInfo };
|