new format and marketplace

This commit is contained in:
2025-12-19 22:35:35 +01:00
parent 9fe48f93fe
commit 9aea0f1551
19 changed files with 1482 additions and 1327 deletions

83
image/gelbooru.js Normal file
View File

@@ -0,0 +1,83 @@
class Gelbooru {
baseUrl = "https://gelbooru.com";
constructor() {
this.type = "image-board";
}
async search(query = "thighs", page = 1, perPage = 42) {
const url = `${this.baseUrl}/index.php?page=post&s=list&tags=${encodeURIComponent(query)}&pid=${(page - 1) * perPage}`;
const html = await fetch(url, {
headers: { "User-Agent": "Mozilla/5.0" }
}).then(r => r.text());
const $ = this.cheerio.load(html);
const results = [];
$("article.thumbnail-preview > a[id^='p']").each((_, el) => {
const id = $(el).attr("id")?.slice(1); // p13123834 → 13123834
if (!id) return;
const img = $(el).find("img");
const image = img.attr("src");
const tags = img.attr("alt")
?.replace(/^Rule 34 \|\s*/, "")
?.split(",")
?.map(t => t.trim())
?.filter(Boolean) || [];
results.push({ id, image, tags });
});
// pagination
const totalPages = Math.max(
page,
...$("a[href*='pid=']")
.map((_, el) =>
Math.floor(
parseInt($(el).attr("href")?.match(/pid=(\d+)/)?.[1] || 0) / perPage
) + 1
)
.get()
);
return {
results,
page,
hasNextPage: page < totalPages
};
}
async getInfo(id) {
const html = await fetch(
`${this.baseUrl}/index.php?page=post&s=view&id=${id}`,
{ headers: { "User-Agent": "Mozilla/5.0" } }
).then(r => r.text());
const $ = this.cheerio.load(html);
const container = $("section.image-container");
let image =
container.find("#image").attr("src") ||
container.attr("data-file-url") ||
container.attr("data-large-file-url") ||
null;
// tags
const tags = container
.attr("data-tags")
?.trim()
?.split(/\s+/)
?.filter(Boolean) || [];
return {
id,
image,
tags
};
}
}
module.exports = Gelbooru;