From 1b06d82b7e9875a685760d475a98bc21dcb8ce0c Mon Sep 17 00:00:00 2001 From: Rojikku Date: Tue, 23 Dec 2025 05:19:13 -0500 Subject: [PATCH] fix: Novelfire URL Parsing + Chapter Sorting (#1927) * Add handling for extra slashes * Add chapterNumber data * Remove unused lib * NovelFire Version Bump * Sort chapters array * Decode characters --- plugins/english/novelfire.ts | 50 ++++++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 14 deletions(-) diff --git a/plugins/english/novelfire.ts b/plugins/english/novelfire.ts index 3d9a4c8..5c19088 100644 --- a/plugins/english/novelfire.ts +++ b/plugins/english/novelfire.ts @@ -4,12 +4,11 @@ import { Plugin } from '@/types/plugin'; import { NovelStatus } from '@libs/novelStatus'; import { Filters, FilterTypes } from '@libs/filterInputs'; import { defaultCover } from '@/types/constants'; -import { storage } from '@libs/storage'; class NovelFire implements Plugin.PluginBase { id = 'novelfire'; name = 'Novel Fire'; - version = '1.1.3'; + version = '1.1.4'; icon = 'src/en/novelfire/icon.png'; site = 'https://novelfire.net/'; @@ -65,9 +64,12 @@ class NovelFire implements Plugin.PluginBase { const novelName = loadedCheerio(ele).find('.novel-title > a').text() || 'No Title Found'; - const novelCover = loadedCheerio(ele) - .find('.novel-cover > img') - .attr('data-src'); + const novelCover = + this.site + + deSlash( + loadedCheerio(ele).find('.novel-cover > img').attr('data-src') || + '', + ); const novelPath = loadedCheerio(ele) .find('.novel-title > a') .attr('href'); @@ -77,7 +79,7 @@ class NovelFire implements Plugin.PluginBase { return { name: novelName, cover: novelCover, - path: novelPath.replace(this.site, ''), + path: deSlash(novelPath.replace(this.site, '')), }; }) .get() @@ -105,28 +107,34 @@ class NovelFire implements Plugin.PluginBase { const json = JSON.parse(body); const chapters = json.data .map(index => { - const chapterName = index.title || index.slug; + const chapterName = load(index.title || index.slug).text(); const chapterPath = `${novelPath}/chapter-${index.n_sort}`; + const sortNumber = index.n_sort; if (!chapterPath) return null; return { name: chapterName, path: chapterPath, + chapterNumber: Number(sortNumber), }; }) .filter(chapter => chapter !== null) as Plugin.ChapterItem[]; + const sortedChapters = chapters.sort(function (a, b) { + return a.chapterNumber - b.chapterNumber; + }); - return chapters; + return sortedChapters; } - async parseNovel(novelPath: string): Promise { + async parseNovel(novelPathRaw: string): Promise { + const novelPath = deSlash(novelPathRaw); const $ = await this.getCheerio(this.site + novelPath, false); const baseUrl = this.site; let post_id = '0'; - const novel: Partial = { + const novel: Partial = { path: novelPath, }; @@ -207,9 +215,11 @@ class NovelFire implements Plugin.PluginBase { .map((index, ele) => { const novelName = loadedCheerio(ele).find('a').attr('title') || 'No Title Found'; - const novelCover = loadedCheerio(ele) - .find('.novel-cover > img') - .attr('src'); + const novelCover = + this.site + + deSlash( + loadedCheerio(ele).find('.novel-cover > img').attr('src') || '', + ); const novelPath = loadedCheerio(ele).find('a').attr('href'); if (!novelPath) return null; @@ -217,7 +227,7 @@ class NovelFire implements Plugin.PluginBase { return { name: novelName, cover: novelCover, - path: novelPath.replace(this.site, ''), + path: deSlash(novelPath.replace(this.site, '')), }; }) .get() @@ -393,3 +403,15 @@ class NovelFireAjaxNotFound extends Error { this.name = 'NovelFireAjaxError'; } } + +function deSlash(url: string): string { + let clean: string; + + if (url.charAt(0) == '/') { + clean = url.substring(1); + } else { + clean = url; + } + + return clean; +}