From e760bd1a9bebb5d53c22906ecfc53fc66e0ed973 Mon Sep 17 00:00:00 2001 From: alistair3149 Date: Wed, 2 Aug 2023 14:01:14 -0400 Subject: [PATCH] fix(source): add all pages in the same chapter for Linovelib (#722) --- src/sources/ch/linovelib.js | 101 +++++++++++++++++++++++------------- 1 file changed, 66 insertions(+), 35 deletions(-) diff --git a/src/sources/ch/linovelib.js b/src/sources/ch/linovelib.js index fc20f61c..2b7289b9 100644 --- a/src/sources/ch/linovelib.js +++ b/src/sources/ch/linovelib.js @@ -130,35 +130,13 @@ const parseNovelAndChapters = async novelUrl => { }; const parseChapter = async (novelUrl, chapterUrl) => { - const url = chapterUrl; - const body = await fetchHtml({ url, sourceId }); - - const loadedCheerio = cheerio.load(body); - - // Remove JS - loadedCheerio('#acontent .cgo').remove(); - - // Load lazyloaded images - loadedCheerio('#acontent img.imagecontent').each(function () { - // Sometimes images are either in data-src or src - const imgSrc = - loadedCheerio(this).attr('data-src') || loadedCheerio(this).attr('src'); - if (imgSrc) { - // The original CDN URL is locked behind a CF-like challenge, switch the URL to bypass that - // There are no react-native-url-polyfill lib, can't use URL API - const regex = /\/\/.+\.com\//; - const imgUrl = imgSrc.replace(regex, '//img.linovelib.com/'); - // Clean up img element - loadedCheerio(this) - .attr('src', imgUrl) - .removeAttr('data-src') - .removeClass('lazyload'); - } - }); - - // Recover the original character - let chapterText = loadedCheerio('#acontent').html(); + let chapterName, chapterText, hasNextPage; + let pageNumber = 1; + /* + * TODO: Maybe there are other ways to get the translation table + * It is embed and encrypted inside readtool.js + */ const mapping_dict = { '“': '「', '’': '』', @@ -266,14 +244,67 @@ const parseChapter = async (novelUrl, chapterUrl) => { '': '裸', }; - Object.entries(mapping_dict).forEach(([key, value]) => { - chapterText = chapterText.replaceAll(key, value); - }); + const addPage = async pageCheerio => { + let pageText; - const chapterName = - loadedCheerio('#atitle + h3').text() + - ' — ' + - loadedCheerio('#atitle').text(); + const formatPage = async () => { + // Remove JS + pageCheerio('#acontent .cgo').remove(); + + // Load lazyloaded images + pageCheerio('#acontent img.imagecontent').each(function () { + // Sometimes images are either in data-src or src + const imgSrc = + pageCheerio(this).attr('data-src') || pageCheerio(this).attr('src'); + if (imgSrc) { + // The original CDN URL is locked behind a CF-like challenge, switch the URL to bypass that + // There are no react-native-url-polyfill lib, can't use URL API + const regex = /\/\/.+\.com\//; + const imgUrl = imgSrc.replace(regex, '//img.linovelib.com/'); + // Clean up img element + pageCheerio(this) + .attr('src', imgUrl) + .removeAttr('data-src') + .removeClass('lazyload'); + } + }); + + // Recover the original character + pageText = pageCheerio('#acontent').html(); + pageText = pageText.replace(/./g, char => mapping_dict[char] || char); + + return Promise.resolve(); + }; + + await formatPage(); + chapterName ??= + pageCheerio('#atitle + h3').text() + + ' — ' + + pageCheerio('#atitle').text(); + chapterText += pageText; + }; + + const loadPage = async url => { + const body = await fetchHtml({ url, sourceId }); + const pageCheerio = cheerio.load(body); + addPage(pageCheerio); + pageHasNextPage = + pageCheerio('#footlink > a[onclick$=ReadParams.url_next;]').text() === + '下一页' + ? true + : false; + return { pageCheerio, pageHasNextPage }; + }; + + let url = chapterUrl; + do { + const page = await loadPage(url); + hasNextPage = page.pageHasNextPage; + if (hasNextPage === true) { + pageNumber++; + url = chapterUrl.replace(/\.html/gi, `_${pageNumber}` + '.html'); + } + } while (hasNextPage === true); const chapter = { sourceId,