Files

44 lines
1.9 KiB
JavaScript

'use strict';
const normalize = value => String(value || '').normalize('NFKD').toLowerCase().replace(/[^a-z0-9]+/g, '');
function seriesLink(value) {
let url;
try { url = new URL(String(value || '')); } catch { return null; }
if (url.protocol !== 'https:') return null;
const weeb = /^\/series\/([A-Z0-9]{26})(?:\/[^/?#]+)?\/?$/i.exec(url.pathname);
if (url.hostname === 'weebcentral.com' && weeb) return {
source: 'weebcentral', label: 'WeebCentral', seriesId: weeb[1].toUpperCase(),
url: `https://weebcentral.com${url.pathname.replace(/\/$/, '')}`,
};
const dex = /^\/title\/([0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12})(?:\/[^/?#]+)?\/?$/i.exec(url.pathname);
if (['mangadex.org', 'www.mangadex.org'].includes(url.hostname) && dex) return {
source: 'mangadex', label: 'MangaDex', seriesId: dex[1].toLowerCase(),
url: `https://mangadex.org/title/${dex[1].toLowerCase()}`,
};
return null;
}
const keyOf = link => `${link.source}:${link.seriesId}`;
function hosterLinks(entry, owned, queue = []) {
const names = new Set([entry.title, ...(entry.aliases || [])].map(normalize));
const known = new Map();
for (const source of owned?.meta?.sources || []) {
const link = seriesLink(source.url);
if (link) known.set(keyOf(link), { ...link, origin: 'library' });
}
const jobs = [];
for (const item of queue) {
const link = seriesLink(item.url);
if (!link) continue;
if (item.libraryMangaId && owned && item.libraryMangaId !== owned.id) continue;
if (!(owned && item.libraryMangaId === owned.id) && !names.has(normalize(item.title)) && !known.has(keyOf(link))) continue;
if (!known.has(keyOf(link))) known.set(keyOf(link), { ...link, origin: 'queue title match' });
jobs.push({ id: item.id, source: link.source, seriesId: link.seriesId, kind: item.kind, status: item.status });
}
return { links: [...known.values()], jobs };
}
module.exports = { seriesLink, hosterLinks };