@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
JavaScript
;
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