Skip to content

Commit 3566893

Browse files
Rojikkuerror7404
andcommitted
Novelfire: Add monopage option
Co-authored-by: From: Justin COLLON <48163201+error7404@users.noreply.github.com>
1 parent 6b924a2 commit 3566893

1 file changed

Lines changed: 83 additions & 0 deletions

File tree

plugins/english/novelfire.ts

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { Plugin } from '@/types/plugin';
44
import { NovelStatus } from '@libs/novelStatus';
55
import { Filters, FilterTypes } from '@libs/filterInputs';
66
import { defaultCover } from '@/types/constants';
7+
import { storage } from '@libs/storage';
78

89
class NovelFire implements Plugin.PluginBase {
910
id = 'novelfire';
@@ -12,6 +13,16 @@ class NovelFire implements Plugin.PluginBase {
1213
icon = 'src/en/novelfire/icon.png';
1314
site = 'https://novelfire.net/';
1415

16+
singlePage = storage.get('singlePage');
17+
pluginSettings = {
18+
singlePage: {
19+
value: '',
20+
label:
21+
'Force load all chapters on a single page (Slower & use more data)',
22+
type: 'Switch',
23+
},
24+
};
25+
1526
async getCheerio(url: string, search: boolean): Promise<CheerioAPI> {
1627
const r = await fetchApi(url);
1728
if (!r.ok && search != true)
@@ -127,6 +138,69 @@ class NovelFire implements Plugin.PluginBase {
127138
return sortedChapters;
128139
}
129140

141+
async getAllChaptersForce(
142+
novelPath: string,
143+
pages: number,
144+
): Promise<Plugin.ChapterItem[]> {
145+
const pagesArray = Array.from({ length: pages }, (_, i) => i + 1);
146+
const allChapters: Plugin.ChapterItem[] = [];
147+
148+
// When pages > ~30, we get rate limited. To mitigate, split into chunks and retry chunk on rate limit with delay.
149+
const chunkSize = 5; // 5 pages per chunk was tested to be a good balance between speed and rate limiting.
150+
const retryCount = 10;
151+
const sleepTime = 3.5; // Rate limit seems to be around ~10s, so usually 3 retries should be enough for another ~30 pages.
152+
153+
const chaptersArray: Plugin.ChapterItem[][] = [];
154+
155+
for (let i = 0; i < pagesArray.length; i += chunkSize) {
156+
const pagesArrayChunk = pagesArray.slice(i, i + chunkSize);
157+
158+
const firstPage = pagesArrayChunk[0];
159+
const lastPage = pagesArrayChunk[pagesArrayChunk.length - 1];
160+
161+
let attempt = 0;
162+
163+
while (attempt < retryCount) {
164+
try {
165+
// Parse all pages in chunk in parallel
166+
const chaptersArrayChunk = await Promise.all(
167+
pagesArrayChunk.map(page =>
168+
this.parsePage(novelPath, page.toString()),
169+
),
170+
);
171+
172+
chaptersArray.push(...chaptersArrayChunk);
173+
break;
174+
} catch (err) {
175+
if (err instanceof NovelFireThrottlingError) {
176+
attempt += 1;
177+
console.warn(
178+
`[pages=${firstPage}-${lastPage}] Novel Fire is rate limiting requests. Retry attempt ${attempt + 1} in ${sleepTime} seconds...`,
179+
);
180+
if (attempt === retryCount) {
181+
throw err;
182+
}
183+
184+
// Sleep for X second before retrying
185+
await new Promise(resolve => setTimeout(resolve, sleepTime * 1000));
186+
} else {
187+
throw err;
188+
}
189+
}
190+
}
191+
}
192+
193+
// Merge all chapters into a single array
194+
for (let chapters of chaptersArray) {
195+
// For some reason it's formatted this way, this fixes it.
196+
chapters = chapters.chapters;
197+
for (let i = 0; i < Object.keys(chapters).length; i++) {
198+
allChapters.push(chapters[i]);
199+
}
200+
}
201+
return allChapters;
202+
}
203+
130204
async parseNovel(
131205
novelPathRaw: string,
132206
): Promise<Plugin.SourceNovel & { totalPages: number }> {
@@ -196,6 +270,15 @@ class NovelFire implements Plugin.PluginBase {
196270
.text()
197271
.trim();
198272
novel.totalPages = Math.ceil(parseInt(totalChapters) / 100);
273+
if (this.singlePage) {
274+
novel.chapters = await this.getAllChaptersForce(
275+
novelPath,
276+
novel.totalPages,
277+
);
278+
if (novel.totalPages > 1 && novel.chapters.length > 100) {
279+
novel.totalPages = 1;
280+
}
281+
}
199282
}
200283

201284
return novel as Plugin.SourceNovel & { totalPages: number };

0 commit comments

Comments
 (0)