updated marketplace and extensions
This commit is contained in:
182
book/mangapill.js
Normal file
182
book/mangapill.js
Normal file
@@ -0,0 +1,182 @@
|
||||
class MangaPill {
|
||||
constructor() {
|
||||
this.baseUrl = "https://mangapill.com";
|
||||
this.type = "book-board";
|
||||
this.version = "1.0";
|
||||
this.mediaType = "manga";
|
||||
}
|
||||
|
||||
async fetch(url) {
|
||||
return fetch(url, {
|
||||
headers: {
|
||||
"User-Agent": "Mozilla/5.0",
|
||||
Referer: this.baseUrl,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async search(queryObj) {
|
||||
const q = queryObj.query || "";
|
||||
const res = await this.fetch(
|
||||
`${this.baseUrl}/search?q=${encodeURIComponent(q)}`
|
||||
);
|
||||
const html = await res.text();
|
||||
const $ = this.cheerio.load(html);
|
||||
|
||||
const results = [];
|
||||
|
||||
$("div.container div.my-3.justify-end > div").each((_, el) => {
|
||||
const link = $(el).find("a").attr("href");
|
||||
if (!link) return;
|
||||
|
||||
const id = link.split("/manga/")[1].replace(/\//g, "$");
|
||||
const title = $(el).find("div > a > div.mt-3").text().trim();
|
||||
const image = $(el).find("a img").attr("data-src") || null;
|
||||
|
||||
results.push({
|
||||
id,
|
||||
title,
|
||||
image,
|
||||
rating: null,
|
||||
type: "book",
|
||||
});
|
||||
});
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
async getMetadata(id) {
|
||||
const uriId = id.replace(/\$/g, "/");
|
||||
let res = await fetch(`${this.baseUrl}/manga/${uriId}`, {
|
||||
headers: this.headers,
|
||||
redirect: "manual",
|
||||
});
|
||||
|
||||
// follow redirect manually
|
||||
if (res.status === 301 || res.status === 302) {
|
||||
const loc = res.headers.get("location");
|
||||
if (loc) {
|
||||
res = await fetch(`${this.baseUrl}${loc}`, {
|
||||
headers: this.headers,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (!res.ok) {
|
||||
return {
|
||||
id,
|
||||
title: "",
|
||||
format: "MANGA",
|
||||
score: 0,
|
||||
genres: "",
|
||||
status: "unknown",
|
||||
published: "",
|
||||
summary: "",
|
||||
chapters: "???",
|
||||
image: null,
|
||||
};
|
||||
}
|
||||
|
||||
const html = await res.text();
|
||||
const $ = this.cheerio.load(html);
|
||||
|
||||
const title = $("h1.font-bold").first().text().trim();
|
||||
|
||||
const summary =
|
||||
$("div.mb-3 p.text-sm").first().text().trim() || "";
|
||||
|
||||
const status =
|
||||
$("label:contains('Status')")
|
||||
.next("div")
|
||||
.text()
|
||||
.trim() || "unknown";
|
||||
|
||||
const published =
|
||||
$("label:contains('Year')")
|
||||
.next("div")
|
||||
.text()
|
||||
.trim() || "";
|
||||
|
||||
const genres = [];
|
||||
$("label:contains('Genres')")
|
||||
.parent()
|
||||
.find("a")
|
||||
.each((_, a) => genres.push($(a).text().trim()));
|
||||
|
||||
const image =
|
||||
$("img[data-src]").first().attr("data-src") || null;
|
||||
|
||||
return {
|
||||
id,
|
||||
title,
|
||||
format: "MANGA",
|
||||
score: 0,
|
||||
genres: genres.join(", "),
|
||||
status,
|
||||
published,
|
||||
summary,
|
||||
chapters: "???",
|
||||
image
|
||||
};
|
||||
}
|
||||
|
||||
async findChapters(mangaId) {
|
||||
const uriId = mangaId.replace(/\$/g, "/");
|
||||
const res = await this.fetch(`${this.baseUrl}/manga/${uriId}`);
|
||||
const html = await res.text();
|
||||
const $ = this.cheerio.load(html);
|
||||
|
||||
const chapters = [];
|
||||
|
||||
$("div#chapters a").each((_, el) => {
|
||||
const href = $(el).attr("href");
|
||||
if (!href) return;
|
||||
|
||||
const id = href.split("/chapters/")[1].replace(/\//g, "$");
|
||||
const title = $(el).text().trim();
|
||||
const match = title.match(/Chapter\s+([\d.]+)/);
|
||||
const number = match ? Number(match[1]) : 0;
|
||||
|
||||
chapters.push({
|
||||
id,
|
||||
title,
|
||||
number,
|
||||
releaseDate: null,
|
||||
index: 0,
|
||||
});
|
||||
});
|
||||
|
||||
chapters.reverse();
|
||||
chapters.forEach((c, i) => (c.index = i));
|
||||
return chapters;
|
||||
}
|
||||
|
||||
async findChapterPages(chapterId) {
|
||||
const uriId = chapterId.replace(/\$/g, "/");
|
||||
const res = await this.fetch(`${this.baseUrl}/chapters/${uriId}`);
|
||||
const html = await res.text();
|
||||
const $ = this.cheerio.load(html);
|
||||
|
||||
const pages = [];
|
||||
|
||||
$("chapter-page").each((i, el) => {
|
||||
const img = $(el).find("div picture img").attr("data-src");
|
||||
if (!img) return;
|
||||
|
||||
pages.push({
|
||||
url: img,
|
||||
index: i,
|
||||
headers: {
|
||||
Referer: "https://mangapill.com/",
|
||||
Origin: "https://mangapill.com",
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
|
||||
Accept: "image/avif,image/webp,image/apng,image/*,*/*;q=0.8",
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
return pages;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = MangaPill;
|
||||
Reference in New Issue
Block a user