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