fix: Novel Fire Chapter Parsing (#2131)

* fix: convert page mode to switch

* fix: remove unicode spacing from chapter names
This commit is contained in:
K1ngfish3r
2026-04-22 08:26:32 +05:00
committed by GitHub
parent e97519ec67
commit 068d71c357
+37 -44
View File
@@ -9,7 +9,7 @@ import { storage } from '@libs/storage';
class NovelFire implements Plugin.PluginBase { class NovelFire implements Plugin.PluginBase {
id = 'novelfire'; id = 'novelfire';
name = 'Novel Fire'; name = 'Novel Fire';
version = '1.3.1'; version = '1.4.1';
icon = 'src/en/novelfire/icon.png'; icon = 'src/en/novelfire/icon.png';
site = 'https://novelfire.net/'; site = 'https://novelfire.net/';
webStorageUtilized = true; webStorageUtilized = true;
@@ -18,15 +18,9 @@ class NovelFire implements Plugin.PluginBase {
pluginSettings = { pluginSettings = {
pageLength: { pageLength: {
value: '-1', value: '',
label: 'Page Mode (Change if Broken)', label: 'Page Mode (Change if Broken)',
type: 'Select', type: 'Switch',
options: [
{ label: '100 (Fallback Mode)', value: '100' },
{ label: '200', value: '200' },
{ label: '500', value: '500' },
{ label: 'All', value: '-1' },
],
}, },
singlePage: { singlePage: {
value: '', value: '',
@@ -36,7 +30,7 @@ class NovelFire implements Plugin.PluginBase {
}, },
}; };
singlePage = storage.get('singlePage'); singlePage = storage.get('singlePage');
pageLength = storage.get('pageLength') ?? '-1'; pageLength = storage.get('pageLength');
async getCheerio(url: string, search: boolean): Promise<CheerioAPI> { async getCheerio(url: string, search: boolean): Promise<CheerioAPI> {
const r = await fetchApi(url); const r = await fetchApi(url);
@@ -139,7 +133,7 @@ class NovelFire implements Plugin.PluginBase {
post_id: string, post_id: string,
page: string, page: string,
): Promise<Plugin.ChapterItem[]> { ): Promise<Plugin.ChapterItem[]> {
const length = parseInt(this.pageLength) || -1; const length = this.pageLength ? 100 : -1;
const url = `${this.site}ajax/listChapterDataAjax`; const url = `${this.site}ajax/listChapterDataAjax`;
const start = length === -1 ? 0 : (parseInt(page) - 1) * length; const start = length === -1 ? 0 : (parseInt(page) - 1) * length;
this.draw++; this.draw++;
@@ -176,38 +170,34 @@ class NovelFire implements Plugin.PluginBase {
if (result.status === 429) throw new NovelFireThrottlingError(); if (result.status === 429) throw new NovelFireThrottlingError();
const body = await result.text(); const body = await result.text();
if (body.includes('You are being rate limited'))
if (body.includes('You are being rate limited')) {
throw new NovelFireThrottlingError(); throw new NovelFireThrottlingError();
} if (body.includes('Page Not Found 404')) throw new NovelFireAjaxNotFound();
if (body.includes('Page Not Found 404')) { return (JSON.parse(body).data || [])
throw new NovelFireAjaxNotFound(); .flatMap(
} (idx: { title?: string; slug: string; n_sort: string | number }) => {
const name = load(idx.title || idx.slug)
.text()
.replace(/[\u200B-\u200D\uFEFF]/g, '')
.trim();
const num = Number(idx.n_sort);
const json = JSON.parse(body); return name && !isNaN(num)
const chapters = (json.data || []) ? [
.map((index: { title?: string; slug: string; n_sort: number }) => { {
const chapterName = load(index.title || index.slug).text(); name,
const chapterPath = `${novelPath}/chapter-${index.n_sort}`; path: `${novelPath}/chapter-${num}`,
const sortNumber = index.n_sort; chapterNumber: num,
},
if (!chapterPath) return null; ]
: [];
return { },
name: chapterName, )
path: chapterPath, .sort(
chapterNumber: Number(sortNumber), (a: Plugin.ChapterItem, b: Plugin.ChapterItem) =>
}; (a.chapterNumber || 0) - (b.chapterNumber || 0),
}) );
.filter(
(chapter: Plugin.ChapterItem | null) => chapter !== null,
) as Plugin.ChapterItem[];
const sortedChapters = chapters.sort(function (a, b) {
return (a.chapterNumber || 0) - (b.chapterNumber || 0);
});
return sortedChapters;
} }
async getAllChaptersForce( async getAllChaptersForce(
@@ -282,7 +272,7 @@ class NovelFire implements Plugin.PluginBase {
const post_id = $('#novel-report').attr('report-post_id'); const post_id = $('#novel-report').attr('report-post_id');
if (post_id) { if (post_id) {
storage.set(`novelfire_postid_${novelPath}`, post_id); storage.set(`${this.id}_${novelPath.split('/').pop()}`, post_id);
} }
const novel: Partial<Plugin.SourceNovel & { totalPages: number }> = { const novel: Partial<Plugin.SourceNovel & { totalPages: number }> = {
@@ -344,9 +334,12 @@ class NovelFire implements Plugin.PluginBase {
.parent() .parent()
.text() .text()
.trim(); .trim();
const length = parseInt(this.pageLength) || -1; const length = this.pageLength ? 100 : -1;
novel.totalPages = novel.totalPages =
length === -1 ? 1 : Math.ceil(parseInt(totalChapters) / length) || 1; length === -1 ? 1 : Math.ceil(parseInt(totalChapters) / length) || 1;
if (novel.totalPages === 1 && post_id) {
novel.chapters = await this.getAllChapters(novelPath, post_id, '1');
}
if (length === 100 && this.singlePage) { if (length === 100 && this.singlePage) {
novel.chapters = await this.getAllChaptersForce( novel.chapters = await this.getAllChaptersForce(
novel.path as string, novel.path as string,
@@ -359,7 +352,7 @@ class NovelFire implements Plugin.PluginBase {
} }
async parsePage(novelPath: string, page: string): Promise<Plugin.SourcePage> { async parsePage(novelPath: string, page: string): Promise<Plugin.SourcePage> {
const post_id = storage.get(`novelfire_postid_${novelPath}`); const post_id = storage.get(`${this.id}_${novelPath.split('/').pop()}`);
if (post_id && !isNaN(Number(post_id))) { if (post_id && !isNaN(Number(post_id))) {
try { try {
@@ -371,7 +364,7 @@ class NovelFire implements Plugin.PluginBase {
} }
// Fallback only works for multiples of 100 // Fallback only works for multiples of 100
const length = parseInt(this.pageLength) || -1; const length = this.pageLength ? 100 : -1;
if (length === 100) { if (length === 100) {
const url = `${this.site}${novelPath}/chapters?page=${page}`; const url = `${this.site}${novelPath}/chapters?page=${page}`;
const result = await fetchApi(url); const result = await fetchApi(url);