new format and marketplace
This commit is contained in:
137
book/novelfire.js
Normal file
137
book/novelfire.js
Normal file
@@ -0,0 +1,137 @@
|
||||
class NovelFire {
|
||||
constructor() {
|
||||
this.baseUrl = "https://novelfire.net";
|
||||
this.type = "book-board";
|
||||
this.mediaType = "ln";
|
||||
}
|
||||
|
||||
async search(queryObj) {
|
||||
const query = queryObj.query;
|
||||
|
||||
const res = await fetch(
|
||||
`${this.baseUrl}/ajax/searchLive?inputContent=${encodeURIComponent(query)}`,
|
||||
{ headers: { "accept": "application/json" } }
|
||||
);
|
||||
|
||||
const data = await res.json();
|
||||
if (!data.data) return [];
|
||||
|
||||
return data.data.map(item => ({
|
||||
id: item.slug,
|
||||
title: item.title,
|
||||
image: `https://novelfire.net/${item.image}`,
|
||||
rating: item.rank ?? null,
|
||||
type: "book"
|
||||
}));
|
||||
}
|
||||
|
||||
async getMetadata(id) {
|
||||
const url = `https://novelfire.net/book/${id}`;
|
||||
const html = await (await fetch(url)).text();
|
||||
const $ = this.cheerio.load(html);
|
||||
|
||||
const title = $('h1[itemprop="name"]').first().text().trim() || null;
|
||||
const summary = $('meta[itemprop="description"]').attr('content') || null;
|
||||
const image =
|
||||
$('figure.cover img').attr('src') ||
|
||||
$('img.cover').attr('src') ||
|
||||
$('img[src*="server-"]').attr('src') ||
|
||||
null;
|
||||
|
||||
const genres = $('.categories a.property-item')
|
||||
.map((_, el) => $(el).attr('title') || $(el).text().trim())
|
||||
.get();
|
||||
|
||||
let chapters = null;
|
||||
const latest = $('.chapter-latest-container .latest').text();
|
||||
if (latest) {
|
||||
const m = latest.match(/Chapter\s+(\d+)/i);
|
||||
if (m) chapters = Number(m[1]);
|
||||
}
|
||||
|
||||
let status = 'unknown';
|
||||
const statusClass = $('strong.ongoing, strong.completed').attr('class');
|
||||
if (statusClass) {
|
||||
status = statusClass.toLowerCase();
|
||||
}
|
||||
|
||||
return {
|
||||
id,
|
||||
title,
|
||||
format: 'Light Novel',
|
||||
score: 0,
|
||||
genres,
|
||||
status,
|
||||
published: '???',
|
||||
summary,
|
||||
chapters,
|
||||
image
|
||||
};
|
||||
}
|
||||
|
||||
async findChapters(bookId) {
|
||||
const url = `https://novelfire.net/book/${bookId}/chapters`;
|
||||
const html = await (await fetch(url)).text();
|
||||
|
||||
const $ = this.cheerio.load(html);
|
||||
let postId;
|
||||
|
||||
$("script").each((_, el) => {
|
||||
const txt = $(el).html() || "";
|
||||
const m = txt.match(/listChapterDataAjax\?post_id=(\d+)/);
|
||||
if (m) postId = m[1];
|
||||
});
|
||||
|
||||
if (!postId) throw new Error("post_id not found");
|
||||
|
||||
const params = new URLSearchParams({
|
||||
post_id: postId,
|
||||
draw: 1,
|
||||
"columns[0][data]": "title",
|
||||
"columns[0][orderable]": "false",
|
||||
"columns[1][data]": "created_at",
|
||||
"columns[1][orderable]": "true",
|
||||
"order[0][column]": 1,
|
||||
"order[0][dir]": "asc",
|
||||
start: 0,
|
||||
length: 1000
|
||||
});
|
||||
|
||||
const res = await fetch(
|
||||
`https://novelfire.net/listChapterDataAjax?${params}`,
|
||||
{ headers: { "x-requested-with": "XMLHttpRequest" } }
|
||||
);
|
||||
|
||||
const json = await res.json();
|
||||
if (!json?.data) throw new Error("Invalid response");
|
||||
|
||||
return json.data.map((c, i) => ({
|
||||
id: `https://novelfire.net/book/${bookId}/chapter-${c.n_sort}`,
|
||||
title: c.title,
|
||||
number: Number(c.n_sort),
|
||||
release_date: c.created_at ?? null,
|
||||
index: i,
|
||||
language: "en"
|
||||
}));
|
||||
}
|
||||
|
||||
async findChapterPages(url) {
|
||||
const html = await (await fetch(url)).text();
|
||||
const $ = this.cheerio.load(html);
|
||||
|
||||
const $content = $("#content").clone();
|
||||
|
||||
$content.find("script, ins, .nf-ads, img, nfn2a74").remove();
|
||||
|
||||
$content.find("*").each((_, el) => {
|
||||
$(el).removeAttr("id").removeAttr("class").removeAttr("style");
|
||||
});
|
||||
|
||||
return $content.html()
|
||||
.replace(/adsbygoogle/gi, "")
|
||||
.replace(/novelfire/gi, "")
|
||||
.trim();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = NovelFire;
|
||||
Reference in New Issue
Block a user