mirror of
https://github.com/venera-app/venera-configs.git
synced 2025-12-16 17:31:16 +00:00
新增GoDa漫画和18漫画 (#193)
This commit is contained in:
332
goda.js
Normal file
332
goda.js
Normal file
@@ -0,0 +1,332 @@
|
|||||||
|
/** @type {import('./_venera_.js')} */
|
||||||
|
class Goda extends ComicSource {
|
||||||
|
// Note: The fields which are marked as [Optional] should be removed if not used
|
||||||
|
|
||||||
|
// name of the source
|
||||||
|
name = "GoDa漫画"
|
||||||
|
|
||||||
|
// unique id of the source
|
||||||
|
key = "goda"
|
||||||
|
|
||||||
|
version = "1.0.0"
|
||||||
|
|
||||||
|
minAppVersion = "1.4.0"
|
||||||
|
|
||||||
|
// update url
|
||||||
|
url = "https://git.nyne.dev/nyne/venera-configs/raw/branch/main/goda.js"
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
domains: {
|
||||||
|
title: "域名",
|
||||||
|
type: "input",
|
||||||
|
default: "godamh.com"
|
||||||
|
},
|
||||||
|
api: {
|
||||||
|
title: "API域名",
|
||||||
|
type: "input",
|
||||||
|
default: "api-get-v3.mgsearcher.com"
|
||||||
|
},
|
||||||
|
image: {
|
||||||
|
title: "图片域名",
|
||||||
|
type: "input",
|
||||||
|
default: "t40-1-4.g-mh.online"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get baseUrl() {
|
||||||
|
return `https://${this.loadSetting("domains")}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
get apiUrl() {
|
||||||
|
return `https://${this.loadSetting("api")}/api`;
|
||||||
|
}
|
||||||
|
|
||||||
|
get imageUrl() {
|
||||||
|
return `https://${this.loadSetting("image")}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
get headers() {
|
||||||
|
return {
|
||||||
|
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:144.0) Gecko/20100101 Firefox/144.0",
|
||||||
|
"Referer": this.baseUrl
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
parseComics(doc) {
|
||||||
|
console.warn(doc)
|
||||||
|
const result = [];
|
||||||
|
for (let item of doc.querySelectorAll(".pb-2")) {
|
||||||
|
result.push(new Comic({
|
||||||
|
id: item.querySelector("a").attributes["href"],
|
||||||
|
title: item.querySelector("h3").text,
|
||||||
|
cover: item.querySelector("img").attributes["src"]
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// explore page list
|
||||||
|
explore = [
|
||||||
|
{
|
||||||
|
// title of the page.
|
||||||
|
// title is used to identify the page, it should be unique
|
||||||
|
title: this.name,
|
||||||
|
|
||||||
|
/// multiPartPage or multiPageComicList or mixed
|
||||||
|
type: "multiPartPage",
|
||||||
|
|
||||||
|
load: async () => {
|
||||||
|
const res = await Network.get(this.baseUrl, this.headers);
|
||||||
|
const document = new HtmlDocument(res.body);
|
||||||
|
const result = [{ title: "近期更新", comics: [], viewMore: null }];
|
||||||
|
for (let item of document.querySelector(".pb-unit-md").querySelectorAll(".slicarda")) {
|
||||||
|
result[0].comics.push(new Comic({
|
||||||
|
id: item.attributes["href"],
|
||||||
|
title: item.querySelector("h3").text,
|
||||||
|
cover: item.querySelector("img").attributes["src"]
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
const cardlists = document.querySelectorAll(".cardlist");
|
||||||
|
const hometitles = document.querySelectorAll(".hometitle");
|
||||||
|
for (let i = 0; i < hometitles.length; i++) {
|
||||||
|
result.push({
|
||||||
|
title: hometitles[i].querySelector("h2").text,
|
||||||
|
comics: this.parseComics(cardlists[i]),
|
||||||
|
viewMore: {
|
||||||
|
page: "category",
|
||||||
|
attributes: {
|
||||||
|
category: hometitles[i].querySelector("h2").text,
|
||||||
|
param: hometitles[i].attributes["href"]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
// categories
|
||||||
|
category = {
|
||||||
|
/// title of the category page, used to identify the page, it should be unique
|
||||||
|
title: this.name,
|
||||||
|
parts: [
|
||||||
|
{
|
||||||
|
name: "类型",
|
||||||
|
type: "fixed",
|
||||||
|
categories: [
|
||||||
|
"全部",
|
||||||
|
"韩漫",
|
||||||
|
"热门漫画",
|
||||||
|
"国漫",
|
||||||
|
"其他",
|
||||||
|
"日漫",
|
||||||
|
"欧美"
|
||||||
|
],
|
||||||
|
itemType: "category",
|
||||||
|
categoryParams: [
|
||||||
|
"/manga",
|
||||||
|
"/manga-genre/kr",
|
||||||
|
"/manga-genre/hots",
|
||||||
|
"/manga-genre/cn",
|
||||||
|
"/manga-genre/qita",
|
||||||
|
"/manga-genre/jp",
|
||||||
|
"/manga-genre/ou-mei"
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "标签",
|
||||||
|
type: "fixed",
|
||||||
|
categories: [
|
||||||
|
"复仇",
|
||||||
|
"古风",
|
||||||
|
"奇幻",
|
||||||
|
"逆袭",
|
||||||
|
"异能",
|
||||||
|
"宅向",
|
||||||
|
"穿越",
|
||||||
|
"热血",
|
||||||
|
"纯爱",
|
||||||
|
"系统",
|
||||||
|
"重生",
|
||||||
|
"冒险",
|
||||||
|
"灵异",
|
||||||
|
"大女主",
|
||||||
|
"剧情",
|
||||||
|
"恋爱",
|
||||||
|
"玄幻",
|
||||||
|
"女神",
|
||||||
|
"科幻",
|
||||||
|
"魔幻",
|
||||||
|
"推理",
|
||||||
|
"猎奇",
|
||||||
|
"治愈",
|
||||||
|
"都市",
|
||||||
|
"异形",
|
||||||
|
"青春",
|
||||||
|
"末日",
|
||||||
|
"悬疑",
|
||||||
|
"修仙",
|
||||||
|
"战斗"
|
||||||
|
],
|
||||||
|
itemType: "category",
|
||||||
|
categoryParams: [
|
||||||
|
"/manga-tag/fuchou",
|
||||||
|
"/manga-tag/gufeng",
|
||||||
|
"/manga-tag/qihuan",
|
||||||
|
"/manga-tag/nixi",
|
||||||
|
"/manga-tag/yineng",
|
||||||
|
"/manga-tag/zhaixiang",
|
||||||
|
"/manga-tag/chuanyue",
|
||||||
|
"/manga-tag/rexue",
|
||||||
|
"/manga-tag/chunai",
|
||||||
|
"/manga-tag/xitong",
|
||||||
|
"/manga-tag/zhongsheng",
|
||||||
|
"/manga-tag/maoxian",
|
||||||
|
"/manga-tag/lingyi",
|
||||||
|
"/manga-tag/danvzhu",
|
||||||
|
"/manga-tag/juqing",
|
||||||
|
"/manga-tag/lianai",
|
||||||
|
"/manga-tag/xuanhuan",
|
||||||
|
"/manga-tag/nvshen",
|
||||||
|
"/manga-tag/kehuan",
|
||||||
|
"/manga-tag/mohuan",
|
||||||
|
"/manga-tag/tuili",
|
||||||
|
"/manga-tag/lieqi",
|
||||||
|
"/manga-tag/zhiyu",
|
||||||
|
"/manga-tag/doushi",
|
||||||
|
"/manga-tag/yixing",
|
||||||
|
"/manga-tag/qingchun",
|
||||||
|
"/manga-tag/mori",
|
||||||
|
"/manga-tag/xuanyi",
|
||||||
|
"/manga-tag/xiuxian",
|
||||||
|
"/manga-tag/zhandou"
|
||||||
|
],
|
||||||
|
}
|
||||||
|
],
|
||||||
|
// enable ranking page
|
||||||
|
enableRankingPage: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// category comic loading related
|
||||||
|
categoryComics = {
|
||||||
|
load: async (category, params, options, page) => {
|
||||||
|
const res = await Network.get(`${this.baseUrl}${params}/page/${page}`, this.headers);
|
||||||
|
if (res.status !== 200) {
|
||||||
|
throw `Invalid status code: ${res.status}`;
|
||||||
|
}
|
||||||
|
const document = new HtmlDocument(res.body);
|
||||||
|
let maxPage = null;
|
||||||
|
try {
|
||||||
|
maxPage = parseInt(document.querySelectorAll("button.text-small").pop().text.replaceAll("\n", "").replaceAll(" ", ""));
|
||||||
|
} catch(_) {
|
||||||
|
maxPage = 1;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
comics: this.parseComics(document),
|
||||||
|
maxPage: maxPage
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// search related
|
||||||
|
search = {
|
||||||
|
load: async (keyword, options, page) => {
|
||||||
|
const res = await Network.get(`${this.baseUrl}/s/${keyword}?page=${page}`);
|
||||||
|
if (res.status !== 200) {
|
||||||
|
throw `Invalid status code: ${res.status}`;
|
||||||
|
}
|
||||||
|
const document = new HtmlDocument(res.body);
|
||||||
|
let maxPage = null;
|
||||||
|
try {
|
||||||
|
maxPage = parseInt(document.querySelectorAll("button.text-small").pop().text.replaceAll("\n", "").replaceAll(" ", ""));
|
||||||
|
} catch(_) {
|
||||||
|
maxPage = 1;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
comics: this.parseComics(document),
|
||||||
|
maxPage: maxPage
|
||||||
|
};
|
||||||
|
},
|
||||||
|
// enable tags suggestions
|
||||||
|
enableTagsSuggestions: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// single comic related
|
||||||
|
comic = {
|
||||||
|
onThumbnailLoad: (url) => {
|
||||||
|
return {
|
||||||
|
headers: this.headers
|
||||||
|
}
|
||||||
|
},
|
||||||
|
loadInfo: async (id) => {
|
||||||
|
const res = await Network.get(this.baseUrl + id);
|
||||||
|
if (res.status !== 200) {
|
||||||
|
throw `Invalid status code: ${res.status}`;
|
||||||
|
}
|
||||||
|
const document = new HtmlDocument(res.body);
|
||||||
|
const title = document.querySelector(".text-xl").text.trim().split(" ")[0]
|
||||||
|
const cover = document.querySelector(".object-cover").attributes["src"];
|
||||||
|
const description = document.querySelector("p.text-medium").text;
|
||||||
|
const infos = document.querySelectorAll("div.py-1");
|
||||||
|
const tags = { "作者": [], "类型": [], "标签": [] };
|
||||||
|
for (let author of infos[0].querySelectorAll("a > span")) {
|
||||||
|
let author_name = author.text.trim();
|
||||||
|
if (author_name.endsWith(",")) {
|
||||||
|
author_name = author_name.slice(0, -1).trim();
|
||||||
|
}
|
||||||
|
tags["作者"].push(author_name);
|
||||||
|
}
|
||||||
|
for (let category of infos[1].querySelectorAll("a > span")) {
|
||||||
|
let category_name = category.text.trim();
|
||||||
|
if (category_name.endsWith(",")) {
|
||||||
|
category_name = category_name.slice(0, -1).trim();
|
||||||
|
}
|
||||||
|
tags["类型"].push(category_name);
|
||||||
|
}
|
||||||
|
for (let tag of infos[2].querySelectorAll("a")) {
|
||||||
|
tags["标签"].push(tag.text.replace("\n", "").replaceAll(" ", "").replace("#", ""));
|
||||||
|
}
|
||||||
|
const mangaId = document.querySelector("#mangachapters").attributes["data-mid"];
|
||||||
|
const jsonRes = await Network.get(`${this.apiUrl}/manga/get?mid=${mangaId}&mode=all&t=${Date.now()}`, this.headers);
|
||||||
|
const jsonData = JSON.parse(jsonRes.body);
|
||||||
|
const chapters = {};
|
||||||
|
for (let ch of jsonData["data"]["chapters"]) {
|
||||||
|
chapters[`${mangaId}@${ch["id"]}`] = ch["attributes"]["title"];
|
||||||
|
}
|
||||||
|
const recommend = [];
|
||||||
|
for (let item of document.querySelectorAll("div.cardlist > div.pb-2")) {
|
||||||
|
recommend.push(new Comic({
|
||||||
|
id: item.querySelector("a").attributes["href"],
|
||||||
|
title: item.querySelector("h3").text,
|
||||||
|
cover: item.querySelector("img").attributes["src"]
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
return new ComicDetails({
|
||||||
|
title: title,
|
||||||
|
cover: cover,
|
||||||
|
description: description,
|
||||||
|
tags: tags,
|
||||||
|
chapters: chapters,
|
||||||
|
recommend: recommend,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
loadEp: async (comicId, epId) => {
|
||||||
|
const ids = epId.split("@");
|
||||||
|
const res = await Network.get(`${this.apiUrl}/chapter/getinfo?m=${ids[0]}&c=${ids[1]}`, this.headers);
|
||||||
|
if (res.status !== 200) {
|
||||||
|
throw `Invalid status code: ${res.status}`;
|
||||||
|
}
|
||||||
|
const jsonData = JSON.parse(res.body);
|
||||||
|
const images = [];
|
||||||
|
for (let i of jsonData["data"]["info"]["images"]["images"]) {
|
||||||
|
images.push(this.imageUrl + i["url"]);
|
||||||
|
}
|
||||||
|
return { images };
|
||||||
|
},
|
||||||
|
|
||||||
|
// enable tags translate
|
||||||
|
enableTagsTranslate: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
12
index.json
12
index.json
@@ -133,5 +133,17 @@
|
|||||||
"fileName": "ccc.js",
|
"fileName": "ccc.js",
|
||||||
"key": "ccc",
|
"key": "ccc",
|
||||||
"version": "1.0.0"
|
"version": "1.0.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "GoDa漫画",
|
||||||
|
"fileName": "goda.js",
|
||||||
|
"key": "goda",
|
||||||
|
"version": "1.0.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "18漫画",
|
||||||
|
"fileName": "mh18.js",
|
||||||
|
"key": "mh18",
|
||||||
|
"version": "1.0.0"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
316
mh18.js
Normal file
316
mh18.js
Normal file
@@ -0,0 +1,316 @@
|
|||||||
|
/** @type {import('./_venera_.js')} */
|
||||||
|
class MH18 extends ComicSource {
|
||||||
|
// Note: The fields which are marked as [Optional] should be removed if not used
|
||||||
|
|
||||||
|
// name of the source
|
||||||
|
name = "18漫画"
|
||||||
|
|
||||||
|
// unique id of the source
|
||||||
|
key = "mh18"
|
||||||
|
|
||||||
|
version = "1.0.0"
|
||||||
|
|
||||||
|
minAppVersion = "1.4.0"
|
||||||
|
|
||||||
|
// update url
|
||||||
|
url = "https://git.nyne.dev/nyne/venera-configs/raw/branch/main/mh18.js"
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
domains: {
|
||||||
|
title: "域名",
|
||||||
|
type: "input",
|
||||||
|
default: "18mh.org"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get baseUrl() {
|
||||||
|
return `https://${this.loadSetting("domains")}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
get headers() {
|
||||||
|
return {
|
||||||
|
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:144.0) Gecko/20100101 Firefox/144.0",
|
||||||
|
"Referer": this.baseUrl
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
parseComics(doc) {
|
||||||
|
console.warn(doc)
|
||||||
|
const result = [];
|
||||||
|
for (let item of doc.querySelectorAll(".pb-2")) {
|
||||||
|
result.push(new Comic({
|
||||||
|
id: item.querySelector("a").attributes["href"],
|
||||||
|
title: item.querySelector("h3").text,
|
||||||
|
cover: item.querySelector("img").attributes["src"]
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// explore page list
|
||||||
|
explore = [
|
||||||
|
{
|
||||||
|
// title of the page.
|
||||||
|
// title is used to identify the page, it should be unique
|
||||||
|
title: this.name,
|
||||||
|
|
||||||
|
/// multiPartPage or multiPageComicList or mixed
|
||||||
|
type: "multiPartPage",
|
||||||
|
|
||||||
|
load: async () => {
|
||||||
|
const res = await Network.get(this.baseUrl, this.headers);
|
||||||
|
const document = new HtmlDocument(res.body);
|
||||||
|
const result = [{ title: "近期更新", comics: [], viewMore: null }];
|
||||||
|
for (let item of document.querySelector(".pb-unit-md").querySelectorAll(".slicarda")) {
|
||||||
|
result[0].comics.push(new Comic({
|
||||||
|
id: item.attributes["href"],
|
||||||
|
title: item.querySelector("h3").text,
|
||||||
|
cover: item.querySelector("img").attributes["src"]
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
const cardlists = document.querySelectorAll(".cardlist");
|
||||||
|
const hometitles = document.querySelectorAll(".hometitle");
|
||||||
|
for (let i = 0; i < hometitles.length; i++) {
|
||||||
|
result.push({
|
||||||
|
title: hometitles[i].querySelector("h2").text,
|
||||||
|
comics: this.parseComics(cardlists[i]),
|
||||||
|
viewMore: {
|
||||||
|
page: "category",
|
||||||
|
attributes: {
|
||||||
|
category: hometitles[i].querySelector("h2").text,
|
||||||
|
param: hometitles[i].attributes["href"]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
// categories
|
||||||
|
category = {
|
||||||
|
/// title of the category page, used to identify the page, it should be unique
|
||||||
|
title: this.name,
|
||||||
|
parts: [
|
||||||
|
{
|
||||||
|
name: "类型",
|
||||||
|
type: "fixed",
|
||||||
|
categories: [
|
||||||
|
"全部",
|
||||||
|
"韓漫",
|
||||||
|
"真人寫真",
|
||||||
|
"日漫",
|
||||||
|
"AI寫真",
|
||||||
|
"熱門漫畫"
|
||||||
|
],
|
||||||
|
itemType: "category",
|
||||||
|
categoryParams: [
|
||||||
|
"/manga",
|
||||||
|
"/manga-genre/hanman",
|
||||||
|
"/manga-genre/zhenrenxiezhen",
|
||||||
|
"/manga-genre/riman",
|
||||||
|
"/manga-genre/aixiezhen",
|
||||||
|
"/manga-genre/hots"
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "标签",
|
||||||
|
type: "fixed",
|
||||||
|
categories: [
|
||||||
|
"多人",
|
||||||
|
"慾望",
|
||||||
|
"正妹",
|
||||||
|
"同居",
|
||||||
|
"女學生",
|
||||||
|
"劇情",
|
||||||
|
"偷情",
|
||||||
|
"校园",
|
||||||
|
"逆襲",
|
||||||
|
"办公室",
|
||||||
|
"誘惑",
|
||||||
|
"反转",
|
||||||
|
"熟女",
|
||||||
|
"人妻",
|
||||||
|
"初戀",
|
||||||
|
"少妇",
|
||||||
|
"刺激",
|
||||||
|
"女大学生",
|
||||||
|
"治疗",
|
||||||
|
"超能力",
|
||||||
|
"浪漫校园",
|
||||||
|
"戏剧",
|
||||||
|
"学姐",
|
||||||
|
"大学生",
|
||||||
|
"泳衣",
|
||||||
|
"暧昧",
|
||||||
|
"写真",
|
||||||
|
"女神",
|
||||||
|
"大尺度",
|
||||||
|
"纯情警察"
|
||||||
|
],
|
||||||
|
itemType: "category",
|
||||||
|
categoryParams: [
|
||||||
|
"/manga-tag/duoren",
|
||||||
|
"/manga-tag/yuwang",
|
||||||
|
"/manga-tag/zhengmei",
|
||||||
|
"/manga-tag/tongju",
|
||||||
|
"/manga-tag/nxuesheng",
|
||||||
|
"/manga-tag/juqing",
|
||||||
|
"/manga-tag/touqing",
|
||||||
|
"/manga-tag/xiaoyuan",
|
||||||
|
"/manga-tag/nixi",
|
||||||
|
"/manga-tag/bangongshi",
|
||||||
|
"/manga-tag/youhuo",
|
||||||
|
"/manga-tag/fanzhuan",
|
||||||
|
"/manga-tag/shun",
|
||||||
|
"/manga-tag/renqi",
|
||||||
|
"/manga-tag/chulian",
|
||||||
|
"/manga-tag/shaofu",
|
||||||
|
"/manga-tag/ciji",
|
||||||
|
"/manga-tag/ndaxuesheng",
|
||||||
|
"/manga-tag/zhiliao",
|
||||||
|
"/manga-tag/chaonengli",
|
||||||
|
"/manga-tag/langmanxiaoyuan",
|
||||||
|
"/manga-tag/xiju",
|
||||||
|
"/manga-tag/xuejie",
|
||||||
|
"/manga-tag/daxuesheng",
|
||||||
|
"/manga-tag/yongyi",
|
||||||
|
"/manga-tag/aimei",
|
||||||
|
"/manga-tag/xiezhen",
|
||||||
|
"/manga-tag/nshen",
|
||||||
|
"/manga-tag/dachidu",
|
||||||
|
"/manga-tag/chunqingjingcha"
|
||||||
|
],
|
||||||
|
}
|
||||||
|
],
|
||||||
|
// enable ranking page
|
||||||
|
enableRankingPage: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// category comic loading related
|
||||||
|
categoryComics = {
|
||||||
|
load: async (category, params, options, page) => {
|
||||||
|
const res = await Network.get(`${this.baseUrl}${params}/page/${page}`, this.headers);
|
||||||
|
if (res.status !== 200) {
|
||||||
|
throw `Invalid status code: ${res.status}`;
|
||||||
|
}
|
||||||
|
const document = new HtmlDocument(res.body);
|
||||||
|
let maxPage = null;
|
||||||
|
try {
|
||||||
|
maxPage = parseInt(document.querySelectorAll("button.text-small").pop().text.replaceAll("\n", "").replaceAll(" ", ""));
|
||||||
|
} catch (_) {
|
||||||
|
maxPage = 1;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
comics: this.parseComics(document),
|
||||||
|
maxPage: maxPage
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// search related
|
||||||
|
search = {
|
||||||
|
load: async (keyword, options, page) => {
|
||||||
|
const res = await Network.get(`${this.baseUrl}/s/${keyword}?page=${page}`);
|
||||||
|
if (res.status !== 200) {
|
||||||
|
throw `Invalid status code: ${res.status}`;
|
||||||
|
}
|
||||||
|
const document = new HtmlDocument(res.body);
|
||||||
|
let maxPage = null;
|
||||||
|
try {
|
||||||
|
maxPage = parseInt(document.querySelectorAll("button.text-small").pop().text.replaceAll("\n", "").replaceAll(" ", ""));
|
||||||
|
} catch (_) {
|
||||||
|
maxPage = 1;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
comics: this.parseComics(document),
|
||||||
|
maxPage: maxPage
|
||||||
|
};
|
||||||
|
},
|
||||||
|
// enable tags suggestions
|
||||||
|
enableTagsSuggestions: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// single comic related
|
||||||
|
comic = {
|
||||||
|
onThumbnailLoad: (url) => {
|
||||||
|
return {
|
||||||
|
headers: this.headers
|
||||||
|
}
|
||||||
|
},
|
||||||
|
loadInfo: async (id) => {
|
||||||
|
if (!id.startsWith("http")) {
|
||||||
|
id = this.baseUrl + id;
|
||||||
|
}
|
||||||
|
const res = await Network.get(id);
|
||||||
|
if (res.status !== 200) {
|
||||||
|
throw `Invalid status code: ${res.status}`;
|
||||||
|
}
|
||||||
|
const document = new HtmlDocument(res.body);
|
||||||
|
const title = document.querySelector(".text-xl").text.trim().split(" ")[0]
|
||||||
|
const cover = document.querySelector(".object-cover").attributes["src"];
|
||||||
|
const description = document.querySelector("p.text-medium").text;
|
||||||
|
const infos = document.querySelectorAll("div.py-1");
|
||||||
|
const tags = { "作者": [], "类型": [], "标签": [] };
|
||||||
|
for (let author of infos[0].querySelectorAll("a > span")) {
|
||||||
|
let author_name = author.text.trim();
|
||||||
|
if (author_name.endsWith(",")) {
|
||||||
|
author_name = author_name.slice(0, -1).trim();
|
||||||
|
}
|
||||||
|
tags["作者"].push(author_name);
|
||||||
|
}
|
||||||
|
for (let category of infos[1].querySelectorAll("a > span")) {
|
||||||
|
let category_name = category.text.trim();
|
||||||
|
if (category_name.endsWith(",")) {
|
||||||
|
category_name = category_name.slice(0, -1).trim();
|
||||||
|
}
|
||||||
|
tags["类型"].push(category_name);
|
||||||
|
}
|
||||||
|
for (let tag of infos[2].querySelectorAll("a")) {
|
||||||
|
tags["标签"].push(tag.text.replace("\n", "").replaceAll(" ", "").replace("#", ""));
|
||||||
|
}
|
||||||
|
const mangaId = document.querySelector("#mangachapters").attributes["data-mid"];
|
||||||
|
const chapterRes = await Network.get(`${this.baseUrl}/manga/get?mid=${mangaId}&mode=all&t=${Date.now()}`, this.headers);
|
||||||
|
const chapterDoc = new HtmlDocument(chapterRes.body);
|
||||||
|
const chapters = {};
|
||||||
|
for (let ch of chapterDoc.querySelectorAll(".chapteritem")) {
|
||||||
|
const info = ch.querySelector("a");
|
||||||
|
chapters[`${info.attributes["data-ms"]}@${info.attributes["data-cs"]}`] = ch.querySelector(".chaptertitle").text;
|
||||||
|
}
|
||||||
|
const recommend = [];
|
||||||
|
for (let item of document.querySelectorAll("div.cardlist > div.pb-2")) {
|
||||||
|
recommend.push(new Comic({
|
||||||
|
id: item.querySelector("a").attributes["href"],
|
||||||
|
title: item.querySelector("h3").text,
|
||||||
|
cover: item.querySelector("img").attributes["src"]
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
return new ComicDetails({
|
||||||
|
title: title,
|
||||||
|
cover: cover,
|
||||||
|
description: description,
|
||||||
|
tags: tags,
|
||||||
|
chapters: chapters,
|
||||||
|
recommend: recommend,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
loadEp: async (comicId, epId) => {
|
||||||
|
const ids = epId.split("@");
|
||||||
|
const res = await Network.get(`${this.baseUrl}/chapter/getcontent?m=${ids[0]}&c=${ids[1]}`, this.headers);
|
||||||
|
if (res.status !== 200) {
|
||||||
|
throw `Invalid status code: ${res.status}`;
|
||||||
|
}
|
||||||
|
const document = new HtmlDocument(res.body);
|
||||||
|
const images = [];
|
||||||
|
for (let i of document.querySelector("#chapcontent").querySelectorAll("img")) {
|
||||||
|
images.push(i.attributes["data-src"] ? i.attributes["data-src"] : i.attributes["src"]);
|
||||||
|
}
|
||||||
|
return { images };
|
||||||
|
},
|
||||||
|
|
||||||
|
// enable tags translate
|
||||||
|
enableTagsTranslate: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user