UNPKG

@houdoku/extension-mangalife

Version:

{"id":"859e5a3d-8ee4-4e38-b270-c8c3c80771d2","name":"MangaLife","url":"https://manga4life.com","version":"1.4.2","translatedLanguage":"ENGLISH","hasSettings":false}

281 lines 13.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.NepClient = void 0; const houdoku_extension_lib_1 = require("houdoku-extension-lib"); const parsing_1 = require("../../util/parsing"); const filters_1 = require("./filters"); const util_1 = require("./util"); const SERIES_STATUS_MAP = { Cancelled: houdoku_extension_lib_1.SeriesStatus.CANCELLED, Complete: houdoku_extension_lib_1.SeriesStatus.COMPLETED, Discontinued: houdoku_extension_lib_1.SeriesStatus.CANCELLED, Hiatus: houdoku_extension_lib_1.SeriesStatus.ONGOING, Ongoing: houdoku_extension_lib_1.SeriesStatus.ONGOING, }; const ORIGINAL_LANGUAGE_MAP = { Manga: houdoku_extension_lib_1.LanguageKey.JAPANESE, Manhua: houdoku_extension_lib_1.LanguageKey.CHINESE_SIMP, Manhwa: houdoku_extension_lib_1.LanguageKey.KOREAN, Doujinshi: houdoku_extension_lib_1.LanguageKey.JAPANESE, OEL: houdoku_extension_lib_1.LanguageKey.ENGLISH, "One-shot": houdoku_extension_lib_1.LanguageKey.JAPANESE, }; const PAGE_SIZE = 24; class NepClient { constructor(extensionId, baseUrl, utilFns) { this._getDirectoryList = () => { return this.util.webviewFn(`${this.baseUrl}/search`).then((response) => { let contentStr = response.text .split("vm.Directory = ") .pop() .split("vm.GetIntValue=")[0] .trim(); contentStr = contentStr.substring(0, contentStr.length - 1); const content = JSON.parse(contentStr); this.fullDirectoryList = content.map((entry) => { const parsed = { indexName: entry.i, seriesName: entry.s, official: entry.o === "yes", scanStatus: entry.ss, publishStatus: entry.ps, type: entry.t, year: parseInt(entry.y), popularity: parseInt(entry.v), lastScanReleased: new Date(entry.ls).getTime(), genres: entry.g, }; return parsed; }); }); }; this._parseDirectoryList = (directoryList) => { return directoryList.map((entry) => { return { id: undefined, extensionId: this.extensionId, sourceId: entry.indexName, title: entry.seriesName, altTitles: [], description: "", authors: [], artists: [], tags: [], status: houdoku_extension_lib_1.SeriesStatus.ONGOING, originalLanguageKey: houdoku_extension_lib_1.LanguageKey.JAPANESE, numberUnread: 0, remoteCoverUrl: `https://temp.compsci88.com/cover/${entry.indexName}.jpg`, }; }); }; this._decodeChapterId = (id) => { let index = ""; let t = id.substring(0, 1); if (t !== "1") { index = `-index-${t}`; } let dgt; if (parseInt(id) < 100100) dgt = 4; else if (parseInt(id) < 101000) dgt = 3; else if (parseInt(id) < 110000) dgt = 2; else dgt = 1; let n = id.substring(dgt, id.length - 1); let suffix = ""; let path = id.substring(id.length - 1); if (path !== "0") suffix = `.${path}`; return { path: `-chapter-${n}${suffix}${index}.html`, number: parseFloat(`${n}${suffix}`), }; }; this._chapterImage = (id) => { let str = id.slice(1, -1); let odd = id[id.length - 1]; if (odd == "0") { return str; } else { return str + "." + odd; } }; this.getSeries = (id) => { return this.util.webviewFn(`${this.baseUrl}/manga/${id}`).then((response) => { // some list item tags are incorrectly closed with </i> instead of </li>, // so we manually replace them here const fixedData = response.text.replace(/\<\/i>/g, "</li>"); const doc = this.util.docFn(fixedData); const title = doc.querySelector("h1").textContent.trim(); const detailLabels = doc.getElementsByClassName("mlabel"); const authors = Array.from((0, parsing_1.findElementWithText)(detailLabels, "Author(s)").parentElement.getElementsByTagName("a")).map((element) => element.textContent.trim()); const genreStrings = Array.from((0, parsing_1.findElementWithText)(detailLabels, "Genre(s)").parentElement.getElementsByTagName("a")).map((element) => element.textContent.trim()); const typeStr = (0, parsing_1.findElementWithText)(detailLabels, "Type") .parentElement.getElementsByTagName("a")[0] .getAttribute("href") .split("=") .pop(); const originalLanguage = ORIGINAL_LANGUAGE_MAP[typeStr]; const statusStr = (0, parsing_1.findElementWithText)(detailLabels, "Status") .parentElement.getElementsByTagName("a")[0] .getAttribute("href") .split("=") .pop(); const status = SERIES_STATUS_MAP[statusStr]; const description = (0, parsing_1.findElementWithText)(detailLabels, "Description") .parentElement.getElementsByClassName("Content")[0] .textContent.trim(); const series = { id: undefined, extensionId: this.extensionId, sourceId: id, title: title || "", altTitles: [], description: description, authors: authors, artists: [], tags: genreStrings, status: status, originalLanguageKey: originalLanguage, numberUnread: 0, remoteCoverUrl: `https://temp.compsci88.com/cover/${id}.jpg`, }; return series; }); }; this.getChapters = (id) => { return this.util.webviewFn(`${this.baseUrl}/manga/${id}`).then((response) => { const contentStr = response.text.split("vm.Chapters = ").pop().split(";")[0]; const content = JSON.parse(contentStr); return content.map((entry) => { const chapterNumber = this._decodeChapterId(entry.Chapter).number.toString(); return { id: undefined, seriesId: undefined, sourceId: this._decodeChapterId(entry.Chapter).path, title: entry.ChapterName || `${entry.Type} ${chapterNumber}`, chapterNumber: chapterNumber, volumeNumber: "", languageKey: houdoku_extension_lib_1.LanguageKey.ENGLISH, groupName: "", time: new Date(entry.Date).getTime(), read: false, }; }); }); }; this.getPageRequesterData = (seriesSourceId, chapterSourceId) => { return this.util .webviewFn(`${this.baseUrl}/read-online/${seriesSourceId}${chapterSourceId}`) .then((response) => { const host = JSON.parse('"' + response.text.split('vm.CurPathName = "').pop().split(";")[0]); const curChapter = JSON.parse("{" + response.text.split("vm.CurChapter = {").pop().split(";")[0]); const indexName = JSON.parse(response.text.split("vm.IndexName = ").pop().split(";")[0]); const dir = curChapter.Directory === "" ? "" : `${curChapter.Directory}/`; const chNum = this._chapterImage(curChapter.Chapter); const numPages = parseInt(curChapter.Page); const pageFilenames = []; for (let i = 1; i <= numPages; i++) { const iStr = i.toLocaleString("en-US", { minimumIntegerDigits: 3, useGrouping: false, }); pageFilenames.push(`${chNum}-${iStr}.png`); } return { server: host, hash: `${indexName}/${dir}`, pageFilenames: pageFilenames, numPages, }; }); }; this.getPageUrls = (pageRequesterData) => { return pageRequesterData.pageFilenames.map((fname) => { return `https://${pageRequesterData.server}/manga/${pageRequesterData.hash}${fname}`; }); }; this.getImage = (series, url) => { return new Promise((resolve, reject) => { resolve(url); }); }; this.getDirectory = async (page, filterValues) => { return this.getSearch("", page, filterValues); }; this.getSearch = async (text, page, filterValues) => { if (this.fullDirectoryList.length === 0) await this._getDirectoryList(); let results = this.fullDirectoryList.filter((entry) => entry.seriesName.toLowerCase().includes(text.toLowerCase())); if (filters_1.FilterControlIds.Genres in filterValues) { results = (0, util_1.applyTriStateFilter)(results, "genres", filterValues[filters_1.FilterControlIds.Genres]); } if (filters_1.FilterControlIds.ScanStatus in filterValues) { results = (0, util_1.applyTriStateFilter)(results, "scanStatus", filterValues[filters_1.FilterControlIds.ScanStatus]); } if (filters_1.FilterControlIds.Type in filterValues) { results = (0, util_1.applyTriStateFilter)(results, "type", filterValues[filters_1.FilterControlIds.Type]); } if (filters_1.FilterControlIds.Official in filterValues) { const officialValue = filterValues[filters_1.FilterControlIds.Official]; if (officialValue === houdoku_extension_lib_1.TriState.INCLUDE) results = results.filter((entry) => entry.official); else if (officialValue === houdoku_extension_lib_1.TriState.EXCLUDE) results = results.filter((entry) => !entry.official); } if (filters_1.FilterControlIds.Sort in filterValues) { results = (0, util_1.applySort)(results, filterValues[filters_1.FilterControlIds.Sort]); } else { results = (0, util_1.applySort)(results, { key: filters_1.SortType.POPULARITY, direction: houdoku_extension_lib_1.SortDirection.DESCENDING, }); } const startIndex = (page - 1) * PAGE_SIZE; return { seriesList: this._parseDirectoryList(results.slice(startIndex, startIndex + PAGE_SIZE)), hasMore: results.length > startIndex + PAGE_SIZE, }; }; this.getSettingTypes = () => { return {}; }; this.getSettings = () => { return {}; }; this.setSettings = (newSettings) => { }; this.getFilterOptions = () => { return [ new houdoku_extension_lib_1.FilterSort(filters_1.FilterControlIds.Sort, "Sort", { key: filters_1.SortType.POPULARITY, direction: houdoku_extension_lib_1.SortDirection.DESCENDING, }) .withFields(filters_1.FIELDS_SORT) .withSupportsBothDirections(true), new houdoku_extension_lib_1.FilterTriStateCheckbox(filters_1.FilterControlIds.Official, "Official translation", houdoku_extension_lib_1.TriState.IGNORE), 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.ScanStatus, "Scan Status", {}) .withFields(filters_1.FIELDS_STATUS) .withIsTriState(true), new houdoku_extension_lib_1.FilterMultiToggle(filters_1.FilterControlIds.PublishStatus, "Publish Status", {}) .withFields(filters_1.FIELDS_STATUS) .withIsTriState(true), new houdoku_extension_lib_1.FilterMultiToggle(filters_1.FilterControlIds.Type, "Type", {}) .withFields(filters_1.FIELDS_TYPES) .withIsTriState(true), ]; }; this.extensionId = extensionId; this.baseUrl = baseUrl; this.util = utilFns; this.fullDirectoryList = []; } } exports.NepClient = NepClient; //# sourceMappingURL=nep.js.map