updated marketplace and extensions

This commit is contained in:
2026-01-01 20:44:41 +01:00
parent 1f52ac678e
commit ff24046f61
9 changed files with 1285 additions and 186 deletions

227
book/weebcentral.js Normal file
View File

@@ -0,0 +1,227 @@
class WeebCentral {
constructor() {
this.baseUrl = "https://weebcentral.com";
this.type = "book-board";
this.version = "1.0";
this.mediaType = "manga";
}
async fetch(url, options = {}) {
return fetch(url, {
...options,
headers: {
"User-Agent": "Mozilla/5.0",
...(options.headers || {}),
},
});
}
async search(queryObj) {
const query = queryObj.query || "";
const form = new URLSearchParams();
form.set("text", query);
const res = await this.fetch(
`${this.baseUrl}/search/simple?location=main`,
{
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
"HX-Request": "true",
"HX-Trigger": "quick-search-input",
"HX-Target": "quick-search-result",
"HX-Current-URL": `${this.baseUrl}/`,
},
body: form.toString(),
}
);
const html = await res.text();
const $ = this.cheerio.load(html);
const results = [];
$("#quick-search-result > div > a").each((_, el) => {
const link = $(el).attr("href");
if (!link) return;
const idMatch = link.match(/\/series\/([^/]+)/);
if (!idMatch) return;
const title = $(el).find(".flex-1").text().trim();
let image =
$(el).find("source").attr("srcset") ||
$(el).find("img").attr("src") ||
null;
results.push({
id: idMatch[1],
title,
image,
rating: null,
type: "book",
});
});
return results;
}
async getMetadata(id) {
const res = await this.fetch(`${this.baseUrl}/series/${id}`, {
headers: { Referer: `${this.baseUrl}/series/${id}` },
});
if (!res.ok) throw new Error("Metadata failed");
const html = await res.text();
const $ = this.cheerio.load(html);
const title =
$("section.md\\:w-8\\/12 h1").first().text().trim() || "";
const genres = [];
$("li strong")
.filter((_, el) => $(el).text().includes("Tags"))
.parent()
.find("a")
.each((_, a) => {
genres.push($(a).text().trim());
});
const status =
$("li strong")
.filter((_, el) => $(el).text().includes("Status"))
.parent()
.find("a")
.first()
.text()
.trim() || "unknown";
const published =
$("li strong")
.filter((_, el) => $(el).text().includes("Released"))
.parent()
.find("span")
.first()
.text()
.trim() || "";
const summary =
$("li strong")
.filter((_, el) => $(el).text().includes("Description"))
.parent()
.find("p")
.text()
.trim() || "";
const image =
$("section.flex picture source").attr("srcset") ||
$("section.flex picture img").attr("src") ||
null;
return {
id,
title,
format: "MANGA",
score: 0,
genres: genres.join(", "),
status,
published,
summary,
chapters: "???",
image,
};
}
async findChapters(mangaId) {
const res = await this.fetch(
`${this.baseUrl}/series/${mangaId}/full-chapter-list`,
{
headers: {
"HX-Request": "true",
"HX-Target": "chapter-list",
"HX-Current-URL": `${this.baseUrl}/series/${mangaId}`,
Referer: `${this.baseUrl}/series/${mangaId}`,
},
}
);
const html = await res.text();
const $ = this.cheerio.load(html);
const chapters = [];
const numRegex = /(\d+(?:\.\d+)?)/;
$("div.flex.items-center").each((_, el) => {
const a = $(el).find("a");
if (!a.length) return;
const href = a.attr("href");
if (!href) return;
const idMatch = href.match(/\/chapters\/([^/]+)/);
if (!idMatch) return;
const title = a.find("span.grow > span").first().text().trim();
const numMatch = title.match(numRegex);
chapters.push({
id: idMatch[1],
title,
number: numMatch ? Number(numMatch[1]) : 0,
releaseDate: null,
index: 0,
});
});
chapters.reverse();
chapters.forEach((c, i) => (c.index = i));
return chapters;
}
async findChapterPages(chapterId) {
const res = await this.fetch(
`${this.baseUrl}/chapters/${chapterId}/images?is_prev=False&reading_style=long_strip`,
{
headers: {
"HX-Request": "true",
"HX-Current-URL": `${this.baseUrl}/chapters/${chapterId}`,
Referer: `${this.baseUrl}/chapters/${chapterId}`,
},
}
);
const html = await res.text();
const $ = this.cheerio.load(html);
const pages = [];
$("section.flex-1 img").each((i, el) => {
const src = $(el).attr("src");
if (src) {
pages.push({
url: src,
index: i,
headers: { Referer: this.baseUrl },
});
}
});
if (pages.length === 0) {
$("img").each((i, el) => {
const src = $(el).attr("src");
if (src) {
pages.push({
url: src,
index: i,
headers: { Referer: this.baseUrl },
});
}
});
}
return pages;
}
}
module.exports = WeebCentral;