Upload files to "/"

This commit is contained in:
2025-11-23 23:23:51 +01:00
parent 591b664375
commit c59ba1d556
5 changed files with 683 additions and 0 deletions

154
novelfire.js Normal file
View File

@@ -0,0 +1,154 @@
class novelfire {
constructor(fetchPath, cheerioPath, browser) {
this.browser = browser;
this.fetch = require(fetchPath);
this.cheerio = require(cheerioPath);
this.baseUrl = "https://novelfire.net";
this.type = "book-board";
}
async fetchSearchResult(query = "", page = 1) {
let html;
if (query.trim() === "") {
const res = await this.fetch(`${this.baseUrl}/home`);
html = await res.text();
} else {
const res = await this.fetch(
`${this.baseUrl}/ajax/searchLive?inputContent=${encodeURIComponent(query)}`
);
const data = await res.json();
html = data.html;
}
const $ = this.cheerio.load(html);
const results = [];
$(".novel-item").each((_, el) => {
const a = $(el).find("a");
const href = a.attr("href") || "";
const title = $(el).find(".novel-title").text().trim();
const img = $(el).find("img");
const image = img.attr("data-src") || img.attr("src") || "";
const id = href.replace("https://novelfire.net/book/", "").replace(/\/$/, "");
results.push({
id,
title,
image,
sampleImageUrl: image,
tags: [],
type: "book"
});
});
return {
results,
hasNextPage: false,
page
};
}
async findChapters(bookId) {
const base = `https://novelfire.net/book/${bookId}/chapters`;
const chapters = [];
const firstRes = await this.fetch(base);
const firstHtml = await firstRes.text();
let $ = this.cheerio.load(firstHtml);
let totalPages = 1;
const pageLinks = $(".pagination a.page-link");
pageLinks.each((_, el) => {
const num = parseInt($(el).text().trim(), 10);
if (!isNaN(num) && num > totalPages) totalPages = num;
});
for (let page = 1; page <= totalPages; page++) {
const url = page === 1 ? base : `${base}?page=${page}`;
const res = await this.fetch(url);
const html = await res.text();
$ = this.cheerio.load(html);
$(".chapter-list li").each((_, el) => {
const a = $(el).find("a");
const href = a.attr("href");
const title = a.find(".chapter-title").text().trim();
const chapterNumber = parseInt(a.find(".chapter-no").text().trim(), 10);
chapters.push({
id: href,
title,
chapter: chapterNumber,
language: "en"
});
});
}
return chapters;
}
async findChapterPages(chapterId) {
const res = await this.fetch(chapterId);
const html = await res.text();
const $ = this.cheerio.load(html);
const contentDiv = $("#content");
if (!contentDiv || contentDiv.length === 0) {
return [{
type: "text",
content: "<p>Error: content not found</p>",
index: 0
}];
}
contentDiv.find("script").remove();
contentDiv.find("ins").remove();
contentDiv.find("[id^='pf-']").remove();
contentDiv.find(".ads").remove();
contentDiv.find(".adsbygoogle").remove();
contentDiv.find("div[style*='text-align:center']").remove();
contentDiv.find("div[align='center']").remove();
contentDiv.find(".nf-ads").remove();
contentDiv.find("nfne597").remove();
const paragraphs = contentDiv.find("p");
let cleanHtml = "";
paragraphs.each((_, el) => {
const p = $(el);
let text = p.text() || "";
text = text.replace(/△▼△▼△▼△/g, "");
text = text.replace(/[※]+/g, "");
text = text.replace(/\s{2,}/g, " ");
const htmlP = p.html()?.trim() || "";
const isEmpty = htmlP === "" || htmlP === "&nbsp;" || text.trim() === "";
const isAd = text.includes("Remove Ads") || text.includes("Buy no ads") || text.includes("novelfire");
if (!isEmpty && !isAd) {
if (p.text() !== text) p.text(text);
cleanHtml += $.html(p);
}
});
if (!cleanHtml.trim()) { cleanHtml = contentDiv.html(); }
return [
{
type: "text",
content: cleanHtml.trim(),
index: 0
}
];
}
}
module.exports = { novelupdates: novelfire };