UNPKG

@houdoku/extension-mangadex

Version:

{"id":"6b4e9df1-b369-4adc-8d36-fe954dd793e3","name":"MangaDex","url":"https://mangadex.org","version":"1.6.1","translatedLanguage":"MULTI","hasSettings":true}

326 lines 16.7 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ExtensionClient = exports.METADATA = void 0; const houdoku_extension_lib_1 = require("houdoku-extension-lib"); const metadata_json_1 = __importDefault(require("./metadata.json")); const configuring_1 = require("../../util/configuring"); const filters_1 = require("./filters"); exports.METADATA = (0, configuring_1.parseMetadata)(metadata_json_1.default); const SERIES_STATUS_MAP = { ongoing: houdoku_extension_lib_1.SeriesStatus.ONGOING, completed: houdoku_extension_lib_1.SeriesStatus.COMPLETED, hiatus: houdoku_extension_lib_1.SeriesStatus.ONGOING, cancelled: houdoku_extension_lib_1.SeriesStatus.CANCELLED, }; const LANGUAGE_MAP = { ar: houdoku_extension_lib_1.LanguageKey.ARABIC, bg: houdoku_extension_lib_1.LanguageKey.BULGARIAN, ca: houdoku_extension_lib_1.LanguageKey.CATALAN, zh: houdoku_extension_lib_1.LanguageKey.CHINESE_SIMP, "zh-ro": houdoku_extension_lib_1.LanguageKey.CHINESE_TRAD, cs: houdoku_extension_lib_1.LanguageKey.CZECH, da: houdoku_extension_lib_1.LanguageKey.DANISH, nl: houdoku_extension_lib_1.LanguageKey.DUTCH, en: houdoku_extension_lib_1.LanguageKey.ENGLISH, fi: houdoku_extension_lib_1.LanguageKey.FINNISH, fr: houdoku_extension_lib_1.LanguageKey.FRENCH, de: houdoku_extension_lib_1.LanguageKey.GERMAN, el: houdoku_extension_lib_1.LanguageKey.GREEK, he: houdoku_extension_lib_1.LanguageKey.HEBREW, hi: houdoku_extension_lib_1.LanguageKey.HINDI, hu: houdoku_extension_lib_1.LanguageKey.HUNGARIAN, id: houdoku_extension_lib_1.LanguageKey.INDONESIAN, it: houdoku_extension_lib_1.LanguageKey.ITALIAN, ja: houdoku_extension_lib_1.LanguageKey.JAPANESE, "ja-ro": houdoku_extension_lib_1.LanguageKey.JAPANESE, ko: houdoku_extension_lib_1.LanguageKey.KOREAN, "ko-ro": houdoku_extension_lib_1.LanguageKey.KOREAN, lt: houdoku_extension_lib_1.LanguageKey.LITHUANIAN, ms: houdoku_extension_lib_1.LanguageKey.MALAY, pl: houdoku_extension_lib_1.LanguageKey.POLISH, pt: houdoku_extension_lib_1.LanguageKey.PORTUGUESE_PT, "pt-br": houdoku_extension_lib_1.LanguageKey.PORTUGUESE_BR, ro: houdoku_extension_lib_1.LanguageKey.ROMANIAN, ru: houdoku_extension_lib_1.LanguageKey.RUSSIAN, es: houdoku_extension_lib_1.LanguageKey.SPANISH_ES, "es-la": houdoku_extension_lib_1.LanguageKey.SPANISH_LATAM, sv: houdoku_extension_lib_1.LanguageKey.SWEDISH, th: houdoku_extension_lib_1.LanguageKey.THAI, tr: houdoku_extension_lib_1.LanguageKey.TURKISH, uk: houdoku_extension_lib_1.LanguageKey.UKRAINIAN, vi: houdoku_extension_lib_1.LanguageKey.VIETNAMESE, }; var SETTING_NAMES; (function (SETTING_NAMES) { SETTING_NAMES["USE_DATA_SAVER"] = "Use data saver"; })(SETTING_NAMES || (SETTING_NAMES = {})); const SETTING_TYPES = { [SETTING_NAMES.USE_DATA_SAVER]: houdoku_extension_lib_1.SettingType.BOOLEAN, }; const DEFAULT_SETTINGS = { [SETTING_NAMES.USE_DATA_SAVER]: false, }; const PAGE_SIZE = 48; const _parseManga = (json) => { const tags = json.attributes.tags.map((tag) => tag.attributes.name.en); if (json.attributes.publicationDemographic !== null) { tags.push(json.attributes.publicationDemographic); } const title = json.attributes.title.en !== undefined ? json.attributes.title.en : Object.values(json.attributes.title)[0]; const coverRelationship = json.relationships.find((relationship) => relationship.type === "cover_art" && relationship.attributes !== undefined); const remoteCoverUrl = coverRelationship !== undefined ? `https://uploads.mangadex.org/covers/${json.id}/${coverRelationship.attributes.fileName}.512.jpg` : ""; const series = { id: undefined, extensionId: exports.METADATA.id, sourceId: json.id, title, altTitles: json.attributes.altTitles.map((altTitleCont) => altTitleCont.en), description: json.attributes.description.en, authors: json.relationships .filter((relationship) => relationship.type === "author" && relationship.attributes !== undefined) .map((relationship) => relationship.attributes.name), artists: json.relationships .filter((relationship) => relationship.type === "artist" && relationship.attributes !== undefined) .map((relationship) => relationship.attributes.name), tags: tags, status: SERIES_STATUS_MAP[json.attributes.status], originalLanguageKey: LANGUAGE_MAP[json.attributes.originalLanguage], numberUnread: 0, remoteCoverUrl, }; return series; }; const _parseMangaResults = (json) => { if (!("data" in json) || json.data === undefined || json.data.length === 0) { return { seriesList: [], hasMore: false }; } const seriesList = json.data.map((data) => _parseManga(data)); const hasMore = json.total > json.offset + seriesList.length; return { seriesList, hasMore, }; }; class ExtensionClient extends houdoku_extension_lib_1.ExtensionClientAbstract { constructor(utilFns) { super(utilFns); this.getMetadata = () => { return exports.METADATA; }; this.getSeries = (id) => { return this.utilFns .fetchFn(`https://api.mangadex.org/manga/${id}?includes[]=artist&includes[]=author&includes[]=cover_art`) .then((response) => response.json()) .then((json) => { if (!("data" in json) || json.data === undefined) return undefined; return _parseManga(json.data); }); }; this.getChapters = async (id) => { const chapterList = []; let gotAllChapters = false; let offset = 0; while (!gotAllChapters) { const params = new URLSearchParams({ offset: `${offset}`, limit: "500", "includes[]": "scanlation_group", }); filters_1.FIELDS_CONTENT_RATINGS.forEach((contentRating) => { params.append("contentRating[]", contentRating.key); }); const response = await this.utilFns.fetchFn(`https://api.mangadex.org/manga/${id}/feed?` + params); const json = await response.json(); json.data.forEach((result) => { const groupRelationship = result.relationships.find((relationship) => relationship.type === "scanlation_group" && relationship.attributes !== undefined); const groupName = groupRelationship !== undefined ? groupRelationship.attributes.name : ""; chapterList.push({ id: undefined, seriesId: undefined, sourceId: result.id, title: result.attributes.title || "", chapterNumber: result.attributes.chapter || "0", volumeNumber: result.attributes.volume || "", languageKey: LANGUAGE_MAP[result.attributes.translatedLanguage], groupName, time: new Date(result.attributes.updatedAt).getTime(), read: false, }); }); if (json.total > offset + 500) { offset += 500; } else { gotAllChapters = true; } } return chapterList; }; this.getPageRequesterData = (seriesSourceId, chapterSourceId) => { return this.utilFns .fetchFn(`https://api.mangadex.org/at-home/server/${chapterSourceId}`) .then((response) => response.json()) .then((json) => { const pageFilenames = this.settings[SETTING_NAMES.USE_DATA_SAVER] ? json.chapter.dataSaver : json.chapter.data; return { server: json.baseUrl, hash: json.chapter.hash, numPages: pageFilenames.length, pageFilenames, }; }); }; this.getPageUrls = (pageRequesterData) => { const dataStr = this.settings[SETTING_NAMES.USE_DATA_SAVER] ? "data-saver" : "data"; return pageRequesterData.pageFilenames.map((filename) => { return `${pageRequesterData.server}/${dataStr}/${pageRequesterData.hash}/${filename}`; }); }; this.getImage = (series, url) => { return new Promise((resolve, reject) => { resolve(url); }); }; this.getDirectory = (page, filterValues) => { return this.getSearch("", page, filterValues); }; this.getSearch = (text, page, filterValues) => { const params = new URLSearchParams({ title: text, offset: `${(page - 1) * PAGE_SIZE}`, limit: `${PAGE_SIZE}`, }); ["artist", "author", "cover_art"].forEach((name) => params.append("includes[]", name)); const _applyTags = (controlId) => { if (controlId in filterValues) { Object.entries(filterValues[controlId]).forEach(([tagId, value]) => { if (value === houdoku_extension_lib_1.TriState.INCLUDE) params.append("includedTags[]", tagId); if (value === houdoku_extension_lib_1.TriState.EXCLUDE) params.append("excludedTags[]", tagId); }); } }; _applyTags(filters_1.FilterControlIds.Formats); _applyTags(filters_1.FilterControlIds.Genres); _applyTags(filters_1.FilterControlIds.Themes); _applyTags(filters_1.FilterControlIds.ContentWarnings); if (filters_1.FilterControlIds.ContentRating in filterValues) { Object.entries(filterValues[filters_1.FilterControlIds.ContentRating]).forEach(([contentRating, value]) => { if (value === houdoku_extension_lib_1.TriState.INCLUDE) params.append("contentRating[]", contentRating); }); } if (filters_1.FilterControlIds.Status in filterValues) { Object.entries(filterValues[filters_1.FilterControlIds.Status]).forEach(([status, value]) => { if (value === houdoku_extension_lib_1.TriState.INCLUDE) params.append("status[]", status); }); } if (filters_1.FilterControlIds.Sort in filterValues) { const sort = filterValues[filters_1.FilterControlIds.Sort]; params.append(`order[${sort.key}]`, { [houdoku_extension_lib_1.SortDirection.ASCENDING]: "asc", [houdoku_extension_lib_1.SortDirection.DESCENDING]: "desc" }[sort.direction]); } if (filters_1.FilterControlIds.Demographic in filterValues) { Object.entries(filterValues[filters_1.FilterControlIds.Demographic]).forEach(([demo, value]) => { if (value === houdoku_extension_lib_1.TriState.INCLUDE) params.append("publicationDemographic[]", demo); }); } if (filters_1.FilterControlIds.OriginalLanguage in filterValues) { Object.entries(filterValues[filters_1.FilterControlIds.OriginalLanguage]).forEach(([lang, value]) => { if (value === houdoku_extension_lib_1.TriState.INCLUDE) { params.append("originalLanguage[]", lang); if (lang === "zh") params.append("originalLanguage[]", "zh-hk"); } }); } if (filters_1.FilterControlIds.HasAvailableChapters in filterValues) { if (filterValues[filters_1.FilterControlIds.HasAvailableChapters] === true) { params.append("hasAvailableChapters", "true"); } } return this.utilFns .fetchFn("https://api.mangadex.org/manga?" + params) .then((response) => response.json()) .then((json) => { const results = _parseMangaResults(json); return { seriesList: results.seriesList, hasMore: results.hasMore, }; }); }; this.getSettingTypes = () => { return SETTING_TYPES; }; this.getSettings = () => { return this.settings; }; this.setSettings = (newSettings) => { Object.keys(newSettings).forEach((key) => { if (key in this.settings && typeof (this.settings[key] === newSettings[key])) { this.settings[key] = newSettings[key]; } }); }; this.getFilterOptions = () => { return [ new houdoku_extension_lib_1.FilterCheckbox(filters_1.FilterControlIds.HasAvailableChapters, "Has available chapters", false), new houdoku_extension_lib_1.FilterSort(filters_1.FilterControlIds.Sort, "Sort", { key: "relevance", direction: houdoku_extension_lib_1.SortDirection.DESCENDING, }) .withFields(filters_1.FIELDS_SORT) .withSupportsBothDirections(true), new houdoku_extension_lib_1.FilterSeparator("separator1", "", ""), new houdoku_extension_lib_1.FilterMultiToggle(filters_1.FilterControlIds.Formats, "Format", {}) .withFields(filters_1.FIELDS_FORMATS) .withIsTriState(true), new houdoku_extension_lib_1.FilterMultiToggle(filters_1.FilterControlIds.Themes, "Theme", {}) .withFields(filters_1.FIELDS_THEMES) .withIsTriState(true), new houdoku_extension_lib_1.FilterMultiToggle(filters_1.FilterControlIds.Genres, "Genre", {}) .withFields(filters_1.FIELDS_GENRES) .withIsTriState(true), new houdoku_extension_lib_1.FilterMultiToggle(filters_1.FilterControlIds.ContentWarnings, "Content Warning", {}) .withFields(filters_1.FIELDS_CONTENT_WARNINGS) .withIsTriState(true), new houdoku_extension_lib_1.FilterSeparator("separator2", "", ""), new houdoku_extension_lib_1.FilterMultiToggle(filters_1.FilterControlIds.OriginalLanguage, "Original Language", {}) .withFields(filters_1.FIELDS_ORIGINAL_LANGUAGES) .withIsTriState(false), new houdoku_extension_lib_1.FilterMultiToggle(filters_1.FilterControlIds.Demographic, "Demographic", {}) .withFields(filters_1.FIELDS_DEMOGRAPHICS) .withIsTriState(false), new houdoku_extension_lib_1.FilterMultiToggle(filters_1.FilterControlIds.ContentRating, "Content Rating", { safe: houdoku_extension_lib_1.TriState.INCLUDE, suggestive: houdoku_extension_lib_1.TriState.INCLUDE, erotica: houdoku_extension_lib_1.TriState.INCLUDE, }) .withFields(filters_1.FIELDS_CONTENT_RATINGS) .withIsTriState(false), new houdoku_extension_lib_1.FilterMultiToggle(filters_1.FilterControlIds.Status, "Status", {}) .withFields(filters_1.FIELDS_STATUS) .withIsTriState(false), new houdoku_extension_lib_1.FilterSeparator("separator3", "", ""), new houdoku_extension_lib_1.FilterCycle(filters_1.FilterControlIds.IncludedTagsMode, "Included Tags Mode", "AND").withOptions(filters_1.OPTIONS_TAG_MODE), new houdoku_extension_lib_1.FilterCycle(filters_1.FilterControlIds.ExcludedTagsMode, "Excluded Tags Mode", "OR").withOptions(filters_1.OPTIONS_TAG_MODE), ]; }; this.settings = DEFAULT_SETTINGS; } } exports.ExtensionClient = ExtensionClient; //# sourceMappingURL=index.js.map