From 35ed8c064e5abb300118011d54c9cbccbf06b221 Mon Sep 17 00:00:00 2001 From: K1ngfish3r Date: Wed, 11 Oct 2023 16:49:19 +0800 Subject: [PATCH 01/41] dev woopread --- src/sources/en/woopread.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sources/en/woopread.js b/src/sources/en/woopread.js index ea3cabc87..2c650dcdd 100644 --- a/src/sources/en/woopread.js +++ b/src/sources/en/woopread.js @@ -119,7 +119,7 @@ const parseChapter = async (novelUrl, chapterUrl) => { const loadedCheerio = cheerio.load(body); - const chapterName = loadedCheerio('h1#chapter-heading').text(); + const chapterName = loadedCheerio('.reading-content b:first').text(); let chapterText = loadedCheerio('.reading-content').html(); @@ -144,11 +144,11 @@ const searchNovels = async searchTerm => { let novels = []; - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.h4 > a').text(); - const novelCover = loadedCheerio(this).find('img').attr('src'); + loadedCheerio('.tab-thumb').each(function () { + const novelName = loadedCheerio(this).find('a').attr('title'); + const novelCover = loadedCheerio(this).find('img').attr('data-src'); - let novelUrl = loadedCheerio(this).find('.h4 > a').attr('href'); + let novelUrl = loadedCheerio(this).find('a').attr('href'); novelUrl = novelUrl.replace(`${baseUrl}series/`, ''); const novel = { From 5d61671c6e76f54f30f49779c4751d8da62c0c2d Mon Sep 17 00:00:00 2001 From: K1ngfish3r Date: Wed, 11 Oct 2023 17:29:34 +0800 Subject: [PATCH 02/41] check if input breaks chapterText --- src/sources/en/woopread.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sources/en/woopread.js b/src/sources/en/woopread.js index 2c650dcdd..531560344 100644 --- a/src/sources/en/woopread.js +++ b/src/sources/en/woopread.js @@ -120,7 +120,7 @@ const parseChapter = async (novelUrl, chapterUrl) => { const loadedCheerio = cheerio.load(body); const chapterName = loadedCheerio('.reading-content b:first').text(); - + loadedCheerio('input, .reading-content b:first').remove(); let chapterText = loadedCheerio('.reading-content').html(); const chapter = { From b505ad3131b6f257a21622964146d3cb6c4a0938 Mon Sep 17 00:00:00 2001 From: K1ngfish3r Date: Wed, 11 Oct 2023 21:04:24 +0800 Subject: [PATCH 03/41] AsuraLightNovel dev --- src/sources/multisrc/madara/MadaraGenerator.ts | 8 ++++---- src/sources/multisrc/madara/MadaraSources.json | 6 +++--- src/sources/sourceManager.ts | 4 ++-- src/sources/sources.json | 8 ++++---- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/sources/multisrc/madara/MadaraGenerator.ts b/src/sources/multisrc/madara/MadaraGenerator.ts index fbaca553f..76d7e29ef 100644 --- a/src/sources/multisrc/madara/MadaraGenerator.ts +++ b/src/sources/multisrc/madara/MadaraGenerator.ts @@ -187,11 +187,11 @@ export const HizoMangaScraper = new MadaraScraper( }, ); -export const ArMTLScraper = new MadaraScraper( +export const AsuraLightNovelScraper = new MadaraScraper( 101, - 'https://ar-mtl.club/', - 'ArMTL', - { 'useNewChapterEndpoint': true, 'lang': 'Arabic' }, + 'https://asuralightnovel.com/', + 'Asura Light Novel', + { 'useNewChapterEndpoint': true, 'lang': 'English' }, ); export const Novel4UpScraper = new MadaraScraper( diff --git a/src/sources/multisrc/madara/MadaraSources.json b/src/sources/multisrc/madara/MadaraSources.json index c8461468d..af2d2cf9f 100644 --- a/src/sources/multisrc/madara/MadaraSources.json +++ b/src/sources/multisrc/madara/MadaraSources.json @@ -187,11 +187,11 @@ }, { "sourceId": 101, - "baseUrl": "https://ar-mtl.club/", - "sourceName": "ArMTL", + "baseUrl": "https://asuralightnovel.com/", + "sourceName": "Asura Light Novel", "options": { "useNewChapterEndpoint": true, - "lang": "Arabic" + "lang": "English" } }, { diff --git a/src/sources/sourceManager.ts b/src/sources/sourceManager.ts index 65bfa091d..154c4483f 100644 --- a/src/sources/sourceManager.ts +++ b/src/sources/sourceManager.ts @@ -30,7 +30,7 @@ import SyosetuScraper from './jp/syosetu'; import LNMTLScraper from './en/lnmtl'; import LightNovelFullScraper from './en/lightnovelfull'; import { - ArMTLScraper, + AsuraLightNovelScraper, BoxNovelScraper, ClickNovelScraper, DaoNovelScraper, @@ -275,7 +275,7 @@ export const sourceManager = (sourceId: number): Scraper => { 98: LightNovelFullScraper, // @ts-ignore 99: NovelmtScraper, // @ts-ignore 100: LtnovelScraper, // @ts-ignore - 101: ArMTLScraper, // @ts-ignore + 101: AsuraLightNovelScraper, // @ts-ignore 103: SakuraNovelScraper, // @ts-ignore 104: Novel4UpScraper, // @ts-ignore 107: TeamXNovelScraper, // @ts-ignore diff --git a/src/sources/sources.json b/src/sources/sources.json index 0f43e13a1..597db101e 100644 --- a/src/sources/sources.json +++ b/src/sources/sources.json @@ -603,10 +603,10 @@ }, { "sourceId": 101, - "url": "https://ar-mtl.club/", - "sourceName": "ArMTL", - "icon": "https://github.com/LNReader/lnreader-sources/blob/main/icons/multisrc/madara/icons/armtl.png?raw=true", - "lang": "Arabic" + "url": "AsuraLightNovelScraper", + "sourceName": "Asura Light Novel", + "icon": "https://asuralightnovel.com/wp-content/uploads/2021/06/favicon-asura-2.png", + "lang": "English" }, { "sourceId": 103, From 07b9e19ca5f19a0fd828026e6dfd42ed37c16f74 Mon Sep 17 00:00:00 2001 From: K1ngfish3r Date: Thu, 12 Oct 2023 21:08:52 +0800 Subject: [PATCH 04/41] add Titan.wf to novelupdates --- src/sources/en/novelupdates.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/sources/en/novelupdates.js b/src/sources/en/novelupdates.js index 63b092bc5..4509e8b89 100644 --- a/src/sources/en/novelupdates.js +++ b/src/sources/en/novelupdates.js @@ -238,10 +238,12 @@ const parseChapter = async (novelUrl, chapterUrl) => { let isScribbleHub = result.url.toLowerCase().includes('scribblehub'); + let isTitanWF = result.url.toLowerCase().includes('titan.wf'); + if (isWuxiaWorld) { chapterText = loadedCheerio('#chapter-content').html(); } else if (isRainOfSnow) { - chapterText = loadedCheerio('div.content').html(); + chapterText = loadedCheerio('.content').html(); } else if (isTumblr) { chapterText = loadedCheerio('.post').html(); } else if (isBlogspot) { @@ -250,11 +252,13 @@ const parseChapter = async (novelUrl, chapterUrl) => { } else if (isHostedNovel) { chapterText = loadedCheerio('.chapter').html(); } else if (isScribbleHub) { - chapterText = loadedCheerio('div.chp_raw').html(); + chapterText = loadedCheerio('.chp_raw').html(); } else if (isWattpad) { chapterText = loadedCheerio('.container pre').html(); } else if (isTravisTranslation) { chapterText = loadedCheerio('.reader-content').html(); + } else if (isTitanWF) { + chapterText = loadedCheerio('.reading-content').html(); } else if (isLightNovelsTls) { chapterText = loadedCheerio('.text_story').html(); } else if (isiNovelTranslation) { From eeb84d6042e061bb926b37c24135611169de3bc6 Mon Sep 17 00:00:00 2001 From: K1ngfish3r Date: Fri, 13 Oct 2023 10:52:51 +0800 Subject: [PATCH 05/41] rough fix novelpub --- src/sources/en/novelpub.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/sources/en/novelpub.js b/src/sources/en/novelpub.js index fb600f6e9..59586dada 100644 --- a/src/sources/en/novelpub.js +++ b/src/sources/en/novelpub.js @@ -6,11 +6,13 @@ const baseUrl = 'https://www.novelpub.com/'; const sourceName = 'NovelPub'; const sourceId = 94; +const userAgent = + 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36'; + const headers = new Headers({ Accept: 'application/json', 'Content-Type': 'application/json', - 'User-Agent': - 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36', + 'User-Agent': userAgent, }); const popularNovels = async page => { From 7d0b1fb337f6baeab989b29e43f823813eb2ec6f Mon Sep 17 00:00:00 2001 From: K1ngfish3r Date: Fri, 13 Oct 2023 11:16:23 +0800 Subject: [PATCH 06/41] remove userAgent check --- src/sources/en/novelpub.js | 26 +++++--------------------- 1 file changed, 5 insertions(+), 21 deletions(-) diff --git a/src/sources/en/novelpub.js b/src/sources/en/novelpub.js index 59586dada..8cc6f6f3b 100644 --- a/src/sources/en/novelpub.js +++ b/src/sources/en/novelpub.js @@ -6,23 +6,15 @@ const baseUrl = 'https://www.novelpub.com/'; const sourceName = 'NovelPub'; const sourceId = 94; -const userAgent = - 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36'; - const headers = new Headers({ Accept: 'application/json', 'Content-Type': 'application/json', - 'User-Agent': userAgent, }); const popularNovels = async page => { let url = baseUrl + 'browse/all/popular/all/' + page; - const body = await fetchHtml({ - url, - sourceId, - init: { headers: { 'User-Agent': userAgent } }, - }); + const body = await fetchHtml({ url, sourceId }); const loadedCheerio = cheerio.load(body); @@ -62,14 +54,14 @@ const parseNovelAndChapters = async novelUrl => { novel.novelCover = loadedCheerio('figure.cover > img').attr('data-src'); - loadedCheerio('div.categories > ul > li').each(function () { + loadedCheerio('.categories > ul > li').each(function () { novel.genre += loadedCheerio(this) .text() .replace(/[\t\n]/g, '') + ','; }); - loadedCheerio('div.header-stats > span').each(function () { + loadedCheerio('.header-stats > span').each(function () { if (loadedCheerio(this).find('small').text() === 'Status') { novel.status = loadedCheerio(this).find('strong').text(); } @@ -135,11 +127,7 @@ const parseNovelAndChapters = async novelUrl => { const parseChapter = async (novelUrl, chapterUrl) => { const url = chapterUrl; - const body = await fetchHtml({ - url, - sourceId, - init: { headers: { 'User-Agent': userAgent } }, - }); + const body = await fetchHtml({ url, sourceId }); const loadedCheerio = cheerio.load(body); @@ -154,11 +142,7 @@ const parseChapter = async (novelUrl, chapterUrl) => { const searchNovels = async searchTerm => { const url = `${baseUrl}lnwsearchlive?inputContent=${searchTerm}`; - const body = await fetchHtml({ - url, - sourceId, - init: { headers: { 'User-Agent': userAgent } }, - }); + const body = await fetchHtml({ url, sourceId }); let loadedCheerio = cheerio.load(body); From c93e62eb8d711cdf07b10ef03494f46eb73df35c Mon Sep 17 00:00:00 2001 From: K1ngfish3r Date: Fri, 13 Oct 2023 11:35:29 +0800 Subject: [PATCH 07/41] i forgot one --- src/sources/en/novelpub.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/sources/en/novelpub.js b/src/sources/en/novelpub.js index 8cc6f6f3b..5d1149242 100644 --- a/src/sources/en/novelpub.js +++ b/src/sources/en/novelpub.js @@ -40,11 +40,7 @@ const popularNovels = async page => { const parseNovelAndChapters = async novelUrl => { const url = novelUrl; - const body = await fetchHtml({ - url, - sourceId, - init: { headers: { 'User-Agent': userAgent } }, - }); + const body = await fetchHtml({ url, sourceId }); let loadedCheerio = cheerio.load(body); From a441dcf7b54b0d0fff984f5f7d3ed5a1e293cfe4 Mon Sep 17 00:00:00 2001 From: K1ngfish3r Date: Sun, 15 Oct 2023 01:20:43 +0800 Subject: [PATCH 08/41] lnmtl ChapterText fix --- src/sources/en/lnmtl.js | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/sources/en/lnmtl.js b/src/sources/en/lnmtl.js index 50411368d..9cb543140 100644 --- a/src/sources/en/lnmtl.js +++ b/src/sources/en/lnmtl.js @@ -1,6 +1,5 @@ import * as cheerio from 'cheerio'; import { showToast } from '../../hooks/showToast'; -import { htmlToText } from '../helpers/htmlToText'; const baseUrl = 'https://lnmtl.com/'; @@ -56,26 +55,29 @@ const parseNovelAndChapters = async novelUrl => { novel.novelName = loadedCheerio('.novel-name').text(); - novel.novelCover = loadedCheerio('div.novel').find('img').attr('src'); + novel.novelCover = loadedCheerio('.novel').find('img').attr('src'); - novel.summary = loadedCheerio('div.description').text().trim(); + novel.summary = loadedCheerio('.description').text().trim(); - novel.author = loadedCheerio( - 'main > div:nth-child(3) > div > div.col-lg-3.col-md-4 > div:nth-child(2) > div.panel-body > dl:nth-child(1) > dd > a > span', - ).text(); + loadedCheerio(".panel-body > dl").each(function () { + let detailName = loadedCheerio(this).find("dt").text().trim(); + let detail = loadedCheerio(this).find("dd").text().trim(); - novel.status = loadedCheerio( - 'main > div:nth-child(3) > div > div.col-lg-3.col-md-4 > div:nth-child(2) > div.panel-body > dl:last-child > dd', - ) - .text() - .trim(); + switch (detailName) { + case "Authors": + novel.author = detail; + break; + case "Current status": + novel.status = detail; + break; + } + }); - novel.genre = loadedCheerio( - 'main > div.container > div > div.col-lg-3.col-md-4 > div:nth-child(4) > div.panel-body > ul', - ) + novel.genre = loadedCheerio('.panel-heading:contains(" Genres ")') + .next() .text() .trim() - .replace(/\s\s/g, ','); + .replace(/\s\s/g, ","); let volumes = JSON.parse( loadedCheerio('main') @@ -128,7 +130,8 @@ const parseChapter = async (novelUrl, chapterUrl) => { let chapterName = loadedCheerio('h3 > span.chapter-title').text().trim(); - loadedCheerio('.original').remove(); + loadedCheerio('.original, script').remove(); + loadedCheerio('sentence.translated').wrap('

') let chapterText = loadedCheerio('.chapter-body').html(); @@ -136,9 +139,6 @@ const parseChapter = async (novelUrl, chapterUrl) => { chapterText = loadedCheerio('.alert.alert-warning').text(); } - chapterText = - chapterName + '\n\n' + htmlToText(chapterText, { removeLineBreaks: false }); - const chapter = { sourceId: 37, novelUrl, From 223b510fc02067fe4b99b8c4316bc9f6c4cafacf Mon Sep 17 00:00:00 2001 From: K1ngfish3r Date: Sun, 15 Oct 2023 01:37:42 +0800 Subject: [PATCH 09/41] fix author, genre and status lnmtl --- src/sources/en/lnmtl.js | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/sources/en/lnmtl.js b/src/sources/en/lnmtl.js index 9cb543140..18f7b9454 100644 --- a/src/sources/en/lnmtl.js +++ b/src/sources/en/lnmtl.js @@ -59,17 +59,17 @@ const parseNovelAndChapters = async novelUrl => { novel.summary = loadedCheerio('.description').text().trim(); - loadedCheerio(".panel-body > dl").each(function () { - let detailName = loadedCheerio(this).find("dt").text().trim(); - let detail = loadedCheerio(this).find("dd").text().trim(); + loadedCheerio('.panel-body > dl').each(function () { + let detailName = loadedCheerio(this).find('dt').text().trim(); + let detail = loadedCheerio(this).find('dd').text().trim(); switch (detailName) { - case "Authors": - novel.author = detail; - break; - case "Current status": - novel.status = detail; - break; + case 'Authors': + novel.author = detail; + break; + case 'Current status': + novel.status = detail; + break; } }); @@ -77,7 +77,7 @@ const parseNovelAndChapters = async novelUrl => { .next() .text() .trim() - .replace(/\s\s/g, ","); + .replace(/\s\s/g, ','); let volumes = JSON.parse( loadedCheerio('main') @@ -131,7 +131,7 @@ const parseChapter = async (novelUrl, chapterUrl) => { let chapterName = loadedCheerio('h3 > span.chapter-title').text().trim(); loadedCheerio('.original, script').remove(); - loadedCheerio('sentence.translated').wrap('

') + loadedCheerio('sentence.translated').wrap('

'); let chapterText = loadedCheerio('.chapter-body').html(); From e7231729f03a4b55457c075bba1b01fea14707f7 Mon Sep 17 00:00:00 2001 From: K1ngfish3r Date: Sun, 15 Oct 2023 19:01:42 +0800 Subject: [PATCH 10/41] xperimental --- src/sources/en/lnmtl.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/sources/en/lnmtl.js b/src/sources/en/lnmtl.js index 18f7b9454..e83704b75 100644 --- a/src/sources/en/lnmtl.js +++ b/src/sources/en/lnmtl.js @@ -151,7 +151,7 @@ const parseChapter = async (novelUrl, chapterUrl) => { }; const searchNovels = async searchTerm => { - const url = 'https://lnmtl.com/term'; + const url = 'https://lnmtl.com/'; const result = await fetch(url); const body = await result.text(); @@ -162,8 +162,7 @@ const searchNovels = async searchTerm => { .next() .next() .html() - .match(/local: \[(.*?)\]/)[0] - .replace('local: ', ''); + .match(/prefetch: '\/(.*json)/)[1]; novels = JSON.parse(novels); From 0c42b383cb37dada2d94258c6199d141745b81a4 Mon Sep 17 00:00:00 2001 From: K1ngfish3r Date: Sun, 15 Oct 2023 20:03:55 +0800 Subject: [PATCH 11/41] grounded quotation marks lnmtl --- src/sources/en/lnmtl.js | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/src/sources/en/lnmtl.js b/src/sources/en/lnmtl.js index e83704b75..1438e3d5d 100644 --- a/src/sources/en/lnmtl.js +++ b/src/sources/en/lnmtl.js @@ -133,7 +133,7 @@ const parseChapter = async (novelUrl, chapterUrl) => { loadedCheerio('.original, script').remove(); loadedCheerio('sentence.translated').wrap('

'); - let chapterText = loadedCheerio('.chapter-body').html(); + let chapterText = loadedCheerio('.chapter-body').html().replace(/„/g, '“'); if (!chapterText) { chapterText = loadedCheerio('.alert.alert-warning').text(); @@ -151,31 +151,35 @@ const parseChapter = async (novelUrl, chapterUrl) => { }; const searchNovels = async searchTerm => { - const url = 'https://lnmtl.com/'; - - const result = await fetch(url); + const result = await fetch(baseUrl); const body = await result.text(); const loadedCheerio = cheerio.load(body); - let novels = loadedCheerio('footer') + const list = loadedCheerio('footer') .next() .next() .html() .match(/prefetch: '\/(.*json)/)[1]; - novels = JSON.parse(novels); + const search = await fetch(`${baseUrl}${list}`); + const data = await search.json(); - novels = novels.filter(novel => - novel.name.toLowerCase().includes(searchTerm.toLowerCase()), + let nov = data.filter(res => + res.name.toLowerCase().includes(searchTerm.toLowerCase()), ); - novels = novels.map(novel => ({ - sourceId: 37, - novelName: novel.name, - novelUrl: novel.slug, - novelCover: novel.image, - })); + const novels = []; + + nov.map(res => { + const novelName = res.name; + const novelUrl = res.slug; + const novelCover = res.image; + + const novel = { sourceId: 37, novelName, novelUrl, novelCover }; + + novels.push(novel); + }); return novels; }; From b0c85473c1c1640dcac8013abc769b5908c34840 Mon Sep 17 00:00:00 2001 From: K1ngfish3r Date: Mon, 16 Oct 2023 23:27:12 +0800 Subject: [PATCH 12/41] fix woopread missing chapter --- src/sources/en/woopread.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sources/en/woopread.js b/src/sources/en/woopread.js index 531560344..218c76840 100644 --- a/src/sources/en/woopread.js +++ b/src/sources/en/woopread.js @@ -112,8 +112,8 @@ const parseNovelAndChapters = async novelUrl => { }; const parseChapter = async (novelUrl, chapterUrl) => { - const url = `${baseUrl}series/${novelUrl}/${chapterUrl}/`; - + const url = `${baseUrl}series/${novelUrl}${chapterUrl}`; + console.log(url); const result = await fetch(url); const body = await result.text(); From e198ec21f70dad78815b885064ed7269566cc1b4 Mon Sep 17 00:00:00 2001 From: K1ngfish3r Date: Tue, 17 Oct 2023 00:17:14 +0800 Subject: [PATCH 13/41] refactor wuxia.blog --- src/sources/en/woopread.js | 2 +- src/sources/en/wuxiablog.js | 75 +++++++++---------------------------- 2 files changed, 19 insertions(+), 58 deletions(-) diff --git a/src/sources/en/woopread.js b/src/sources/en/woopread.js index 218c76840..05486c595 100644 --- a/src/sources/en/woopread.js +++ b/src/sources/en/woopread.js @@ -113,7 +113,7 @@ const parseNovelAndChapters = async novelUrl => { const parseChapter = async (novelUrl, chapterUrl) => { const url = `${baseUrl}series/${novelUrl}${chapterUrl}`; - console.log(url); + const result = await fetch(url); const body = await result.text(); diff --git a/src/sources/en/wuxiablog.js b/src/sources/en/wuxiablog.js index 4f85eb52c..497d6b246 100644 --- a/src/sources/en/wuxiablog.js +++ b/src/sources/en/wuxiablog.js @@ -23,12 +23,12 @@ const popularNovels = async page => { if (novelName) { const novelId = loadedCheerio(this).find('td:nth-child(1)').text(); - const novelCover = baseUrl + '/data/image/' + novelId + '.jpg'; + const novelCover = baseUrl + 'data/image/' + novelId + '.jpg'; let novelUrl = loadedCheerio(this) .find('td.novel > a') .attr('href') - .replace('/novel/', ''); + .replace('/book/', ''); const novel = { sourceId, @@ -45,7 +45,7 @@ const popularNovels = async page => { }; const parseNovelAndChapters = async novelUrl => { - const url = `${baseUrl}novel/${novelUrl}/`; + const url = `${baseUrl}book/${novelUrl}/`; const result = await fetch(url); const body = await result.text(); @@ -59,25 +59,19 @@ const parseNovelAndChapters = async novelUrl => { novelUrl, }; - novel.novelName = loadedCheerio( - 'body > div.container-fluid.text-center > div.row.content > div.col-sm-8.text-left > div:nth-child(6) > div.panel-heading.clearfix > h4', - ).text(); + novel.novelName = loadedCheerio('h4[itemprop="name>"]:first').text(); - novel.novelCover = loadedCheerio('img[itemprop="image"]').attr('src'); + novel.novelCover = loadedCheerio('.img-thumbnail').attr('src'); - novel.author = loadedCheerio( - 'div.col-md-6 > div > div:nth-child(2) > div > div:nth-child(2) > a', - ).text(); + novel.author = loadedCheerio('h4:contains("Author:")').next().text(); - novel.genre = loadedCheerio( - 'div.row > div.col-md-6 > div > a:nth-child(4)', - ).text(); - - novel.summary = loadedCheerio('div[itemprop="description"]') - .find('p') - .text() - .trim(); + novel.genre = loadedCheerio('h4:contains("Genre:")') + .nextUntil('h4') + .map((i, el) => loadedCheerio(el).text()) + .toArray() + .join(','); + novel.summary = loadedCheerio('h4:contains("Description:")').next().text(); let novelChapters = []; loadedCheerio('table#chplist > #chapters > tr').each(function () { @@ -137,20 +131,18 @@ const parseNovelAndChapters = async novelUrl => { }; const parseChapter = async (novelUrl, chapterUrl) => { - const url = `${baseUrl}novel/${novelUrl}/${chapterUrl}`; + const url = `${baseUrl}book/${novelUrl}/${chapterUrl}`; const result = await fetch(url); const body = await result.text(); const loadedCheerio = cheerio.load(body); - let chapterName = loadedCheerio('div.panel-body.article').find('h4').text(); + let chapterName = loadedCheerio('.panel-body.article').find('h4').text(); - loadedCheerio('ul.pager').remove(); + loadedCheerio('ul.pager, .panel-body.article div,button,span').remove(); - let chapterText = loadedCheerio('div.panel-body.article') - .html() - .replace(/(.*?)<\/span>/g, ''); + let chapterText = loadedCheerio('.panel-body.article').html(); const chapter = { sourceId, @@ -164,40 +156,9 @@ const parseChapter = async (novelUrl, chapterUrl) => { }; const searchNovels = async searchTerm => { - const url = `${baseUrl}?search=${searchTerm}`; - - const result = await fetch(url); - const body = await result.text(); - - const loadedCheerio = cheerio.load(body); - - let novels = []; - - loadedCheerio('#table') - .find('tr') - .each(function () { - const novelName = loadedCheerio(this).find('a').text().trim(); - - if (novelName) { - const novelCover = loadedCheerio(this).find('img').attr('src'); - - let novelUrl = loadedCheerio(this) - .find('a') - .attr('href') - .replace(baseUrl + 'novel/', ''); - - const novel = { - sourceId, - novelName, - novelCover, - novelUrl, - }; - - novels.push(novel); - } - }); + showToast('Search is not available in this source'); - return novels; + return; }; const WuxiaBlogScraper = { From a7e47c250e3e41f60801ab38b910ba0eed44e916 Mon Sep 17 00:00:00 2001 From: K1ngfish3r Date: Tue, 17 Oct 2023 00:54:06 +0800 Subject: [PATCH 14/41] copypasta lightnovelpub --- src/sources/en/lightnovelpub.js | 1 + src/sources/en/novelpub.js | 63 ++++++++++++++++++++------------- 2 files changed, 39 insertions(+), 25 deletions(-) diff --git a/src/sources/en/lightnovelpub.js b/src/sources/en/lightnovelpub.js index 72906eaed..4bfb5af4d 100644 --- a/src/sources/en/lightnovelpub.js +++ b/src/sources/en/lightnovelpub.js @@ -87,6 +87,7 @@ const parseNovelAndChapters = async novelUrl => { const chaptersHtml = await fetchHtml({ url: chaptersUrl, init: { headers }, + sourceId, }); loadedCheerio = cheerio.load(chaptersHtml); diff --git a/src/sources/en/novelpub.js b/src/sources/en/novelpub.js index 5d1149242..992e38e24 100644 --- a/src/sources/en/novelpub.js +++ b/src/sources/en/novelpub.js @@ -1,5 +1,5 @@ import * as cheerio from 'cheerio'; -import { fetchHtml } from '@utils/fetch/fetch'; +import { fetchApi, fetchHtml } from '@utils/fetch/fetch'; const baseUrl = 'https://www.novelpub.com/'; @@ -44,40 +44,35 @@ const parseNovelAndChapters = async novelUrl => { let loadedCheerio = cheerio.load(body); - let novel = { url, novelUrl, sourceId, sourceName, genre: '' }; + let novel = { + sourceId, + url: novelUrl, + novelUrl, + sourceName, + }; novel.novelName = loadedCheerio('h1.novel-title').text().trim(); novel.novelCover = loadedCheerio('figure.cover > img').attr('data-src'); - loadedCheerio('.categories > ul > li').each(function () { - novel.genre += - loadedCheerio(this) - .text() - .replace(/[\t\n]/g, '') + ','; - }); - - loadedCheerio('.header-stats > span').each(function () { - if (loadedCheerio(this).find('small').text() === 'Status') { - novel.status = loadedCheerio(this).find('strong').text(); - } - }); + novel.genre = loadedCheerio('.categories li') + .find('a') + .map((i, el) => loadedCheerio(el).text()) + .toArray() + .join(','); - novel.genre = novel.genre.slice(0, -1); + novel.status = loadedCheerio('small:contains("Status")').prev().text().trim(); novel.author = loadedCheerio('.author > a > span').text(); + loadedCheerio('.expand').remove(); novel.summary = loadedCheerio('.summary > .content').text().trim(); const delay = ms => new Promise(res => setTimeout(res, ms)); let lastPage = 1; - lastPage = loadedCheerio( - '#novel > header > div.header-body.container > div.novel-info > div.header-stats > span:nth-child(1) > strong', - ) - .text() - ?.trim(); + lastPage = loadedCheerio('small:contains("Chapters")').prev().text().trim(); lastPage = Math.ceil(lastPage / 100); @@ -87,8 +82,11 @@ const parseNovelAndChapters = async novelUrl => { for (let i = 1; i <= lastPage; i++) { const chaptersUrl = `${novelUrl}/chapters/page-${i}`; - const chaptersRequest = await fetch(chaptersUrl, { headers }); - const chaptersHtml = await chaptersRequest.text(); + const chaptersHtml = await fetchHtml({ + url: chaptersUrl, + init: { headers }, + sourceId, + }); loadedCheerio = cheerio.load(chaptersHtml); @@ -136,9 +134,24 @@ const parseChapter = async (novelUrl, chapterUrl) => { }; const searchNovels = async searchTerm => { - const url = `${baseUrl}lnwsearchlive?inputContent=${searchTerm}`; - - const body = await fetchHtml({ url, sourceId }); + const url = `${baseUrl}lnsearchlive`; + const link = `${baseUrl}search`; + const response = await fetchApi({ url: link, sourceId }).then(r => r.text()); + const token = cheerio.load(response); + let verifytoken = token('#novelSearchForm > input').attr('value'); + + let formData = new FormData(); + formData.append('inputContent', searchTerm); + + const body = await fetchHtml({ + url, + init: { + method: 'POST', + headers: { 'LNRequestVerifyToken': verifytoken }, + body: formData, + }, + sourceId, + }); let loadedCheerio = cheerio.load(body); From 9d4e2bd4b9c4a95954aa30841c998f2adacb06e2 Mon Sep 17 00:00:00 2001 From: K1ngfish3r Date: Tue, 17 Oct 2023 01:42:10 +0800 Subject: [PATCH 15/41] until stylesheets are added --- src/sources/en/novelupdates.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/sources/en/novelupdates.js b/src/sources/en/novelupdates.js index 4509e8b89..0bdb1d662 100644 --- a/src/sources/en/novelupdates.js +++ b/src/sources/en/novelupdates.js @@ -238,8 +238,6 @@ const parseChapter = async (novelUrl, chapterUrl) => { let isScribbleHub = result.url.toLowerCase().includes('scribblehub'); - let isTitanWF = result.url.toLowerCase().includes('titan.wf'); - if (isWuxiaWorld) { chapterText = loadedCheerio('#chapter-content').html(); } else if (isRainOfSnow) { @@ -257,8 +255,6 @@ const parseChapter = async (novelUrl, chapterUrl) => { chapterText = loadedCheerio('.container pre').html(); } else if (isTravisTranslation) { chapterText = loadedCheerio('.reader-content').html(); - } else if (isTitanWF) { - chapterText = loadedCheerio('.reading-content').html(); } else if (isLightNovelsTls) { chapterText = loadedCheerio('.text_story').html(); } else if (isiNovelTranslation) { @@ -331,7 +327,7 @@ const parseChapter = async (novelUrl, chapterUrl) => { `href="${getLocation(result.url)}/`, ); } - + console.log(chapterText); const chapter = { sourceId, novelUrl, From df2a13aa59ab4c38a1fce5e639e96e7b628b06c6 Mon Sep 17 00:00:00 2001 From: K1ngfish3r Date: Tue, 17 Oct 2023 01:42:57 +0800 Subject: [PATCH 16/41] remove console.log --- src/sources/en/novelupdates.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sources/en/novelupdates.js b/src/sources/en/novelupdates.js index 0bdb1d662..8c9308742 100644 --- a/src/sources/en/novelupdates.js +++ b/src/sources/en/novelupdates.js @@ -327,7 +327,7 @@ const parseChapter = async (novelUrl, chapterUrl) => { `href="${getLocation(result.url)}/`, ); } - console.log(chapterText); + const chapter = { sourceId, novelUrl, From 487bd69e86c6a26336faf3e7c36e840859795e18 Mon Sep 17 00:00:00 2001 From: K1ngfish3r Date: Wed, 18 Oct 2023 16:44:26 +0800 Subject: [PATCH 17/41] revert armtl and wuxiablog search delete --- src/sources/en/wuxiablog.js | 35 +++++++++++++++++-- .../multisrc/madara/MadaraGenerator.ts | 15 +++++--- .../multisrc/madara/MadaraSources.json | 15 ++++++-- src/sources/sourceManager.ts | 4 ++- src/sources/sources.json | 15 +++++--- 5 files changed, 70 insertions(+), 14 deletions(-) diff --git a/src/sources/en/wuxiablog.js b/src/sources/en/wuxiablog.js index 497d6b246..562a573f9 100644 --- a/src/sources/en/wuxiablog.js +++ b/src/sources/en/wuxiablog.js @@ -156,9 +156,40 @@ const parseChapter = async (novelUrl, chapterUrl) => { }; const searchNovels = async searchTerm => { - showToast('Search is not available in this source'); + const url = `${baseUrl}?search=${searchTerm}`; - return; + const result = await fetch(url); + const body = await result.text(); + + const loadedCheerio = cheerio.load(body); + + let novels = []; + + loadedCheerio('#table') + .find('tr') + .each(function () { + const novelName = loadedCheerio(this).find('a').text().trim(); + + if (novelName) { + const novelCover = loadedCheerio(this).find('img').attr('src'); + + let novelUrl = loadedCheerio(this) + .find('a') + .attr('href') + .replace(baseUrl + 'book/', ''); + + const novel = { + sourceId, + novelName, + novelCover, + novelUrl, + }; + + novels.push(novel); + } + }); + + return novels; }; const WuxiaBlogScraper = { diff --git a/src/sources/multisrc/madara/MadaraGenerator.ts b/src/sources/multisrc/madara/MadaraGenerator.ts index 76d7e29ef..a66ef9acd 100644 --- a/src/sources/multisrc/madara/MadaraGenerator.ts +++ b/src/sources/multisrc/madara/MadaraGenerator.ts @@ -187,11 +187,11 @@ export const HizoMangaScraper = new MadaraScraper( }, ); -export const AsuraLightNovelScraper = new MadaraScraper( +export const ArMTLScraper = new MadaraScraper( 101, - 'https://asuralightnovel.com/', - 'Asura Light Novel', - { 'useNewChapterEndpoint': true, 'lang': 'English' }, + 'https://ar-mtl.club/', + 'ArMTL', + { 'useNewChapterEndpoint': true, 'lang': 'Arabic' }, ); export const Novel4UpScraper = new MadaraScraper( @@ -350,3 +350,10 @@ export const WebNovelOkuScraper = new MadaraScraper( 'WebNovelOku ', { 'lang': 'Turkish' }, ); + +export const AsuraLightNovelScraper = new MadaraScraper( + 169, + 'https://asuralightnovel.com/', + 'Asura Light Novel', + { 'useNewChapterEndpoint': true, 'lang': 'English' }, +); \ No newline at end of file diff --git a/src/sources/multisrc/madara/MadaraSources.json b/src/sources/multisrc/madara/MadaraSources.json index af2d2cf9f..2fa0a6925 100644 --- a/src/sources/multisrc/madara/MadaraSources.json +++ b/src/sources/multisrc/madara/MadaraSources.json @@ -187,11 +187,11 @@ }, { "sourceId": 101, - "baseUrl": "https://asuralightnovel.com/", - "sourceName": "Asura Light Novel", + "baseUrl": "https://ar-mtl.club/", + "sourceName": "ArMTL", "options": { "useNewChapterEndpoint": true, - "lang": "English" + "lang": "Arabic" } }, { @@ -361,5 +361,14 @@ "options": { "lang": "Turkish" } + }, + { + "sourceId": 169, + "baseUrl": "https://asuralightnovel.com/", + "sourceName": "Asura Light Novel", + "options": { + "useNewChapterEndpoint": true, + "lang": "English" + } } ] diff --git a/src/sources/sourceManager.ts b/src/sources/sourceManager.ts index 154c4483f..46c77650e 100644 --- a/src/sources/sourceManager.ts +++ b/src/sources/sourceManager.ts @@ -31,6 +31,7 @@ import LNMTLScraper from './en/lnmtl'; import LightNovelFullScraper from './en/lightnovelfull'; import { AsuraLightNovelScraper, + ArMTLScraper, BoxNovelScraper, ClickNovelScraper, DaoNovelScraper, @@ -275,7 +276,7 @@ export const sourceManager = (sourceId: number): Scraper => { 98: LightNovelFullScraper, // @ts-ignore 99: NovelmtScraper, // @ts-ignore 100: LtnovelScraper, // @ts-ignore - 101: AsuraLightNovelScraper, // @ts-ignore + 101: ArMTLScraper, // @ts-ignore 103: SakuraNovelScraper, // @ts-ignore 104: Novel4UpScraper, // @ts-ignore 107: TeamXNovelScraper, // @ts-ignore @@ -336,6 +337,7 @@ export const sourceManager = (sourceId: number): Scraper => { 166: NOVAScraper, // @ts-ignore 167: SmakolykyTlScraper, // @ts-ignore 168: LitSpaceScraper, // @ts-ignore + 169: AsuraLightNovelScraper, // @ts-ignore }; return scrapers[sourceId]; diff --git a/src/sources/sources.json b/src/sources/sources.json index 597db101e..16efdceff 100644 --- a/src/sources/sources.json +++ b/src/sources/sources.json @@ -603,10 +603,10 @@ }, { "sourceId": 101, - "url": "AsuraLightNovelScraper", - "sourceName": "Asura Light Novel", - "icon": "https://asuralightnovel.com/wp-content/uploads/2021/06/favicon-asura-2.png", - "lang": "English" + "url": "https://ar-mtl.club/", + "sourceName": "ArMTL", + "icon": "https://github.com/LNReader/lnreader-sources/blob/main/icons/multisrc/madara/icons/armtl.png?raw=true", + "lang": "Arabic" }, { "sourceId": 103, @@ -1027,5 +1027,12 @@ "url": "https://freedlit.space/", "lang": "Russian", "icon": "https://freedlit.space/images/fav/apple-touch-icon.png" + }, + { + "sourceId": 169, + "url": "AsuraLightNovelScraper", + "sourceName": "Asura Light Novel", + "icon": "https://asuralightnovel.com/wp-content/uploads/2021/06/favicon-asura-2.png", + "lang": "English" } ] From 8f6fab074900720dafd4fd3f1989880ad6aa6ba2 Mon Sep 17 00:00:00 2001 From: K1ngfish3r Date: Wed, 18 Oct 2023 16:47:55 +0800 Subject: [PATCH 18/41] fix eslint check? --- src/sources/multisrc/madara/MadaraGenerator.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sources/multisrc/madara/MadaraGenerator.ts b/src/sources/multisrc/madara/MadaraGenerator.ts index a66ef9acd..5901aeb35 100644 --- a/src/sources/multisrc/madara/MadaraGenerator.ts +++ b/src/sources/multisrc/madara/MadaraGenerator.ts @@ -356,4 +356,4 @@ export const AsuraLightNovelScraper = new MadaraScraper( 'https://asuralightnovel.com/', 'Asura Light Novel', { 'useNewChapterEndpoint': true, 'lang': 'English' }, -); \ No newline at end of file +); From 5af4b4b202bbba44669ba4166e16c224a6d182c3 Mon Sep 17 00:00:00 2001 From: K1ngfish3r Date: Wed, 18 Oct 2023 18:25:38 +0800 Subject: [PATCH 19/41] fastnovel to novelbin --- src/sources/en/{fastnovel.js => novelbin.js} | 10 +++++----- src/sources/sourceManager.ts | 4 ++-- src/sources/sources.json | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) rename src/sources/en/{fastnovel.js => novelbin.js} (95%) diff --git a/src/sources/en/fastnovel.js b/src/sources/en/novelbin.js similarity index 95% rename from src/sources/en/fastnovel.js rename to src/sources/en/novelbin.js index 057ae9e01..9bb0959ba 100644 --- a/src/sources/en/fastnovel.js +++ b/src/sources/en/novelbin.js @@ -2,8 +2,8 @@ import { fetchHtml } from '@utils/fetch/fetch'; import * as cheerio from 'cheerio'; const sourceId = 3; -const baseUrl = 'https://fastnovel.org'; -const searchUrl = 'https://fastnovel.org/search/'; +const baseUrl = 'https://novelbin.org'; +const searchUrl = 'https://novelbin.org/search/'; const popularNovels = async page => { const url = `${baseUrl}/sort/p/?page=${page}`; @@ -42,7 +42,7 @@ const parseNovelAndChapters = async novelUrl => { let novel = { sourceId, - sourceName: 'FastNovel', + sourceName: 'NovelBin', url, novelUrl, }; @@ -158,11 +158,11 @@ const searchNovels = async searchTerm => { return novels; }; -const fastNovelScraper = { +const NovelBinScraper = { popularNovels, parseNovelAndChapters, parseChapter, searchNovels, }; -export default fastNovelScraper; +export default NovelBinScraper; diff --git a/src/sources/sourceManager.ts b/src/sources/sourceManager.ts index 46c77650e..b1cdf7464 100644 --- a/src/sources/sourceManager.ts +++ b/src/sources/sourceManager.ts @@ -1,7 +1,7 @@ import EPubSource from './local/epubSource'; import ComradeMaoScraper from './en/comrademao'; import ReadLightNovelScraper from './en/readlightnovel'; -import fastNovelScraper from './en/fastnovel'; +import NovelBinScraper from './en/novelbin'; import readNovelFullScraper from './en/readnovelfull'; import mtlNovelScraper from './en/mtlnovel'; import novelhallScraper from './en/novelhall'; @@ -192,7 +192,7 @@ export const sourceManager = (sourceId: number): Scraper => { 0: EPubSource, // @ts-ignore 1: BoxNovelScraper, // @ts-ignore 2: ReadLightNovelScraper, // @ts-ignore - 3: fastNovelScraper, // @ts-ignore + 3: NovelBinScraper, // @ts-ignore 4: readNovelFullScraper, // @ts-ignore 5: mtlNovelScraper, // @ts-ignore 6: novelhallScraper, // @ts-ignore diff --git a/src/sources/sources.json b/src/sources/sources.json index 16efdceff..7c750a59d 100644 --- a/src/sources/sources.json +++ b/src/sources/sources.json @@ -15,8 +15,8 @@ }, { "sourceId": 3, - "url": "https://fastnovel.org/", - "sourceName": "FastNovel", + "url": "https://novelbin.org/", + "sourceName": "NovelBin", "icon": "https://github.com/LNReader/lnreader-sources/blob/main/icons/src/en/fastnovel/icon.png?raw=true", "lang": "English" }, From 8b9a199bcd557fc5b2d91c1dc6aa041cbdd860b9 Mon Sep 17 00:00:00 2001 From: K1ngfish3r Date: Thu, 26 Oct 2023 17:35:36 +0800 Subject: [PATCH 20/41] Blossom Translation Dev --- CONTRIBUTING.md | 4 ++-- src/sources/en/novelupdates.js | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 09bd36b69..d207d5c0c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -8,8 +8,8 @@ After forking to your own github org or account, do the following steps to get s ```bash # prerequisites -node --version <= 16.13.1 (for version management, get nvm [recommended]) -java sdk --version <= 11 (for version management, get jenv [optional]) +node --version = 18.17.1 (for version management, get nvm [recommended]) +java sdk --version = 11 (for version management, get jenv [optional]) android sdk (https://developer.android.com/studio) # clone your fork to your local machine diff --git a/src/sources/en/novelupdates.js b/src/sources/en/novelupdates.js index 8c9308742..ca65c8ec6 100644 --- a/src/sources/en/novelupdates.js +++ b/src/sources/en/novelupdates.js @@ -204,6 +204,10 @@ const parseChapter = async (novelUrl, chapterUrl) => { let isWattpad = result.url.toLowerCase().includes('wattpad'); + let isBlossomTranslation = result.url + .toLowerCase() + .includes('blossomtranslation'); + let isLightNovelsTls = result.url .toLowerCase() .includes('lightnovelstranslations'); @@ -257,6 +261,8 @@ const parseChapter = async (novelUrl, chapterUrl) => { chapterText = loadedCheerio('.reader-content').html(); } else if (isLightNovelsTls) { chapterText = loadedCheerio('.text_story').html(); + } else if (isBlossomTranslation) { + chapterText = loadedCheerio('.manga-child-content').html(); } else if (isiNovelTranslation) { const link = 'https://api.' + result.url.slice(8); const json = await fetchApi({ From 14b1d8e34e6e9f1976125c497c8ac3266f1457f5 Mon Sep 17 00:00:00 2001 From: K1ngfish3r Date: Sun, 29 Oct 2023 15:07:41 +0800 Subject: [PATCH 21/41] skynovel fix chapter spacing --- scrcpy | 1 + src/sources/es/skynovels.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 160000 scrcpy diff --git a/scrcpy b/scrcpy new file mode 160000 index 000000000..90ca46ee4 --- /dev/null +++ b/scrcpy @@ -0,0 +1 @@ +Subproject commit 90ca46ee415514513da9dff8c558d726c8e34318 diff --git a/src/sources/es/skynovels.js b/src/sources/es/skynovels.js index 1830533b1..8f96cfd4b 100644 --- a/src/sources/es/skynovels.js +++ b/src/sources/es/skynovels.js @@ -91,7 +91,7 @@ const parseChapter = async (novUrl, chapUrl) => { let chapterName = item.chp_index_title; - let chapterText = item.chp_content; + let chapterText = item.chp_content.replace(/\n/g, '
'); novelUrl = novelId + '/' + novelUrl + '/'; chapterUrl = item.id + '/' + item.chp_name; From f4892db6ff5b3b9bde74dd2d27a67300cb22e8fb Mon Sep 17 00:00:00 2001 From: K1ngfish3r Date: Sun, 29 Oct 2023 15:13:41 +0800 Subject: [PATCH 22/41] oops --- scrcpy | 1 - 1 file changed, 1 deletion(-) delete mode 160000 scrcpy diff --git a/scrcpy b/scrcpy deleted file mode 160000 index 90ca46ee4..000000000 --- a/scrcpy +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 90ca46ee415514513da9dff8c558d726c8e34318 From 1eded4d95d929867dd97550f4c7cbd1a20c2518d Mon Sep 17 00:00:00 2001 From: K1ngfish3r Date: Sun, 29 Oct 2023 15:32:24 +0800 Subject: [PATCH 23/41] linovelib fix? --- src/sources/ch/linovelib.js | 119 ++++++++++++++++++------------------ 1 file changed, 59 insertions(+), 60 deletions(-) diff --git a/src/sources/ch/linovelib.js b/src/sources/ch/linovelib.js index 2b7289b9c..00e602cfd 100644 --- a/src/sources/ch/linovelib.js +++ b/src/sources/ch/linovelib.js @@ -130,8 +130,10 @@ const parseNovelAndChapters = async novelUrl => { }; const parseChapter = async (novelUrl, chapterUrl) => { - let chapterName, chapterText, hasNextPage; - let pageNumber = 1; + const body = await fetchHtml({ url: chapterUrl, sourceId }); + const pageCheerio = cheerio.load(body); + let pageText; + // let hasNextPage, pageNumber = 1; /* * TODO: Maybe there are other ways to get the translation table @@ -244,67 +246,64 @@ const parseChapter = async (novelUrl, chapterUrl) => { '': '裸', }; - const addPage = async pageCheerio => { - let pageText; - - 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 addPage = async pageCheerio => { + + const formatPage = async () => { + // Remove JS + pageCheerio('#ccacontent .cgo').remove(); + + // Load lazyloaded images + pageCheerio('#ccacontent 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'); + } + }); - 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 }; + // Recover the original character + pageText = pageCheerio('#ccacontent').html(); + pageText = pageText.replace(/./g, char => mapping_dict[char] || char); + + return Promise.resolve(); }; - 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); + await formatPage(); + const chapterName = + pageCheerio('#atitle + h3').text() + ' — ' + pageCheerio('#atitle').text(); + const 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, From b9f29e3701b01e05ef5188c506912169092a7e7f Mon Sep 17 00:00:00 2001 From: K1ngfish3r Date: Sun, 29 Oct 2023 18:40:46 +0800 Subject: [PATCH 24/41] search fix linovelib --- src/sources/ch/linovelib.js | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/src/sources/ch/linovelib.js b/src/sources/ch/linovelib.js index 00e602cfd..1dd34ae3e 100644 --- a/src/sources/ch/linovelib.js +++ b/src/sources/ch/linovelib.js @@ -1,4 +1,6 @@ +import { showToast } from '@hooks/showToast'; import { fetchHtml } from '@utils/fetch/fetch'; + import * as cheerio from 'cheerio'; const sourceId = 165; @@ -319,7 +321,7 @@ const parseChapter = async (novelUrl, chapterUrl) => { const searchNovels = async searchTerm => { const url = `${baseUrl}/search.html?searchkey=` + encodeURI(searchTerm); const body = await fetchHtml({ url, sourceId }); - + console.log(url); const loadedCheerio = cheerio.load(body); const novels = []; @@ -335,25 +337,38 @@ const searchNovels = async searchTerm => { .attr('data-src'); novelUrl = baseUrl + novelUrl; - const novel = { - url: novelUrl, - name: novelName, - cover: novelCover, - }; + const novel = { sourceId, novelUrl, novelName, novelCover }; novels.push(novel); } }); }; - const novelResults = loadedCheerio('.book-ol .book-layout'); + const novelResults = loadedCheerio('.book-ol a.book-layout'); if (novelResults.length === 0) { - // console.log('Challenge'); + showToast('Bypass check by searching in Webview'); } else { loadSearchResults(); } + const singlenovel = loadedCheerio('div.book-layout'); + + if (singlenovel.length !== 0) { + novels.length = 0; + const novelName = loadedCheerio('#bookDetailWrapper .book-title').text(); + + const novelCover = loadedCheerio('#bookDetailWrapper img.book-cover').attr( + 'src', + ); + const novelUrl = + baseUrl + + loadedCheerio('#btnReadBook').attr('href').slice(0, -8) + + '.html'; + const novel = { sourceId, novelUrl, novelName, novelCover }; + novels.push(novel); + } + console.log(novels); return novels; }; From 3e4e4ebf7c4bf07b5ca0847d456b7f78aeef14ac Mon Sep 17 00:00:00 2001 From: K1ngfish3r Date: Sun, 29 Oct 2023 19:48:14 +0800 Subject: [PATCH 25/41] update dictionary linovelib --- src/sources/ch/linovelib.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/sources/ch/linovelib.js b/src/sources/ch/linovelib.js index 1dd34ae3e..218b35ffe 100644 --- a/src/sources/ch/linovelib.js +++ b/src/sources/ch/linovelib.js @@ -146,7 +146,7 @@ const parseChapter = async (novelUrl, chapterUrl) => { '’': '』', '': '是', '': '不', - '': '他', + '': '好', '': '个', '': '来', '': '大', @@ -162,9 +162,9 @@ const parseChapter = async (novelUrl, chapterUrl) => { '': '去', '': '小', '': '于', - '': '么', - '': '好', - '': '发', + '': '舔', + '': '他', + '': '只', '': '成', '': '事', '': '用', @@ -197,10 +197,10 @@ const parseChapter = async (novelUrl, chapterUrl) => { '': '能', '': '多', '': '心', - '': '之', + '': '都', '': '看', '': '当', - '': '只', + '': '发', '': '把', '': '第', '': '想', @@ -232,7 +232,7 @@ const parseChapter = async (novelUrl, chapterUrl) => { '': '对', '': '然', '': '学', - '': '都', + '': '之', '': '起', '': '没', '': '如', @@ -244,7 +244,7 @@ const parseChapter = async (novelUrl, chapterUrl) => { '': '呻', '': '性', '': '穴', - '': '舔', + '': '么', '': '裸', }; @@ -318,7 +318,7 @@ const parseChapter = async (novelUrl, chapterUrl) => { return chapter; }; -const searchNovels = async searchTerm => { +const searchNovels = async (searchTerm, page) => { const url = `${baseUrl}/search.html?searchkey=` + encodeURI(searchTerm); const body = await fetchHtml({ url, sourceId }); console.log(url); From 3f7926faf7990d2441bd248b9f815451737529b4 Mon Sep 17 00:00:00 2001 From: K1ngfish3r Date: Sun, 29 Oct 2023 20:26:18 +0800 Subject: [PATCH 26/41] update dictionary 2: electric bugaloo --- src/sources/ch/linovelib.js | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/sources/ch/linovelib.js b/src/sources/ch/linovelib.js index 218b35ffe..7b7a91d99 100644 --- a/src/sources/ch/linovelib.js +++ b/src/sources/ch/linovelib.js @@ -148,8 +148,8 @@ const parseChapter = async (novelUrl, chapterUrl) => { '': '不', '': '好', '': '个', - '': '来', - '': '大', + '': '开', + '': '样', '': '子', '': '说', '': '年', @@ -165,8 +165,8 @@ const parseChapter = async (novelUrl, chapterUrl) => { '': '舔', '': '他', '': '只', - '': '成', - '': '事', + '': '看', + '': '来', '': '用', '': '道', '': '种', @@ -175,11 +175,11 @@ const parseChapter = async (novelUrl, chapterUrl) => { '': '肉', '': '胸', '': '淫', - '': '射', + '': '性', '': '骚', '”': '」', '': '的', - '': '了', + '': '当', '': '人', '': '有', '': '上', @@ -198,13 +198,13 @@ const parseChapter = async (novelUrl, chapterUrl) => { '': '多', '': '心', '': '都', - '': '看', - '': '当', - '': '发', - '': '把', + '': '成', + '': '了', + '': '把', + '': '发', '': '第', '': '想', - '': '开', + '': '事', '': '阴', '': '欲', '': '交', @@ -226,7 +226,7 @@ const parseChapter = async (novelUrl, chapterUrl) => { '': '要', '': '也', '': '后', - '': '会', + '': '没', '': '下', '': '天', '': '对', @@ -237,12 +237,12 @@ const parseChapter = async (novelUrl, chapterUrl) => { '': '没', '': '如', '': '还', - '': '样', + '': '大', '': '作', '': '美', '': '液', '': '呻', - '': '性', + '': '射', '': '穴', '': '么', '': '裸', @@ -314,11 +314,11 @@ const parseChapter = async (novelUrl, chapterUrl) => { chapterName, chapterText, }; - + console.log(chapter); return chapter; }; -const searchNovels = async (searchTerm, page) => { +const searchNovels = async searchTerm => { const url = `${baseUrl}/search.html?searchkey=` + encodeURI(searchTerm); const body = await fetchHtml({ url, sourceId }); console.log(url); From a93682565c1a729557a66210243bf5e5fa8d2a33 Mon Sep 17 00:00:00 2001 From: K1ngfish3r Date: Mon, 30 Oct 2023 01:34:38 +0800 Subject: [PATCH 27/41] skillgg dict and multipage chapter + search fix --- src/sources/ch/linovelib.js | 540 ++++++++++++++++++++++-------------- 1 file changed, 334 insertions(+), 206 deletions(-) diff --git a/src/sources/ch/linovelib.js b/src/sources/ch/linovelib.js index 7b7a91d99..77125c4ff 100644 --- a/src/sources/ch/linovelib.js +++ b/src/sources/ch/linovelib.js @@ -132,180 +132,285 @@ const parseNovelAndChapters = async novelUrl => { }; const parseChapter = async (novelUrl, chapterUrl) => { - const body = await fetchHtml({ url: chapterUrl, sourceId }); - const pageCheerio = cheerio.load(body); - let pageText; - // let hasNextPage, pageNumber = 1; + let chapterName, chapterText, hasNextPage, pageHasNextPage, pageText; + let pageNumber = 1; /* * TODO: Maybe there are other ways to get the translation table * It is embed and encrypted inside readtool.js + * UPDATE: Decrypted, see skillgg */ - const mapping_dict = { - '“': '「', - '’': '』', - '': '是', - '': '不', - '': '好', - '': '个', - '': '开', - '': '样', - '': '子', - '': '说', - '': '年', - '': '那', - '': '她', - '': '得', - '': '自', - '': '家', - '': '而', - '': '去', - '': '小', - '': '于', - '': '舔', - '': '他', - '': '只', - '': '看', - '': '来', - '': '用', - '': '道', - '': '种', - '': '乳', - '': '茎', - '': '肉', - '': '胸', - '': '淫', - '': '性', - '': '骚', - '”': '」', - '': '的', - '': '当', - '': '人', - '': '有', - '': '上', - '': '到', - '': '地', - '': '中', - '': '生', - '': '着', - '': '和', - '': '出', - '': '里', - '': '以', - '': '可', - '': '过', - '': '能', - '': '多', - '': '心', - '': '都', - '': '成', - '': '了', - '': '把', - '': '发', - '': '第', - '': '想', - '': '事', - '': '阴', - '': '欲', - '': '交', - '': '私', - '': '臀', - '': '脱', - '': '唇', - '‘': '『', - '': '一', - '': '我', - '': '在', - '': '这', - '': '们', - '': '时', - '': '为', - '': '你', - '': '国', - '': '就', - '': '要', - '': '也', - '': '后', - '': '没', - '': '下', - '': '天', - '': '对', - '': '然', - '': '学', - '': '之', - '': '起', - '': '没', - '': '如', - '': '还', - '': '大', - '': '作', - '': '美', - '': '液', - '': '呻', - '': '射', - '': '穴', - '': '么', - '': '裸', + // const mapping_dict = { + // '“': '「', + // '’': '』', + // '': '是', + // '': '不', + // '': '好', + // '': '个', + // '': '开', + // '': '样', + // '': '想', + // '': '说', + // '': '年', + // '': '那', + // '': '她', + // '': '美', + // '': '自', + // '': '家', + // '': '而', + // '': '去', + // '': '都', + // '': '于', + // '': '舔', + // '': '他', + // '': '只', + // '': '看', + // '': '来', + // '': '用', + // '': '道', + // '': '得', + // '': '乳', + // '': '茎', + // '': '肉', + // '': '胸', + // '': '淫', + // '': '性', + // '': '骚', + // '”': '」', + // '': '的', + // '': '当', + // '': '人', + // '': '有', + // '': '上', + // '': '到', + // '': '地', + // '': '中', + // '': '生', + // '': '着', + // '': '和', + // '': '起', + // '': '交', + // '': '以', + // '': '可', + // '': '过', + // '': '能', + // '': '多', + // '': '心', + // '': '小', + // '': '成', + // '': '了', + // '': '把', + // '': '发', + // '': '第', + // '': '子', + // '': '事', + // '': '阴', + // '': '欲', + // '': '里', + // '': '私', + // '': '臀', + // '': '脱', + // '': '唇', + // '‘': '『', + // '': '一', + // '': '我', + // '': '在', + // '': '这', + // '': '们', + // '': '时', + // '': '为', + // '': '你', + // '': '国', + // '': '就', + // '': '要', + // '': '也', + // '': '后', + // '': '没', + // '': '下', + // '': '天', + // '': '对', + // '': '然', + // '': '学', + // '': '之', + // '': '出', + // '': '没', + // '': '如', + // '': '还', + // '': '大', + // '': '作', + // '': '种', + // '': '液', + // '': '呻', + // '': '射', + // '': '穴', + // '': '么', + // '': '裸', + // }; + const skillgg = { + '\u201c': '\u300c', + '\u201d': '\u300d', + '\u2018': '\u300e', + '\u2019': '\u300f', + '\ue82c': '\u7684', + '\ue852': '\u4e00', + '\ue82d': '\u662f', + '\ue819': '\u4e86', + '\ue856': '\u6211', + '\ue857': '\u4e0d', + '\ue816': '\u4eba', + '\ue83c': '\u5728', + '\ue830': '\u4ed6', + '\ue82e': '\u6709', + '\ue836': '\u8fd9', + '\ue859': '\u4e2a', + '\ue80a': '\u4e0a', + '\ue855': '\u4eec', + '\ue842': '\u6765', + '\ue858': '\u5230', + '\ue80b': '\u65f6', + '\ue81f': '\u5927', + '\ue84a': '\u5730', + '\ue853': '\u4e3a', + '\ue81e': '\u5b50', + '\ue822': '\u4e2d', + '\ue813': '\u4f60', + '\ue85b': '\u8bf4', + '\ue807': '\u751f', + '\ue818': '\u56fd', + '\ue810': '\u5e74', + '\ue812': '\u7740', + '\ue851': '\u5c31', + '\ue801': '\u90a3', + '\ue80c': '\u548c', + '\ue815': '\u8981', + '\ue84c': '\u5979', + '\ue840': '\u51fa', + '\ue848': '\u4e5f', + '\ue835': '\u5f97', + '\ue800': '\u91cc', + '\ue826': '\u540e', + '\ue863': '\u81ea', + '\ue861': '\u4ee5', + '\ue854': '\u4f1a', + '\ue827': '\u5bb6', + '\ue83b': '\u53ef', + '\ue85d': '\u4e0b', + '\ue84d': '\u800c', + '\ue862': '\u8fc7', + '\ue81c': '\u5929', + '\ue81d': '\u53bb', + '\ue860': '\u80fd', + '\ue843': '\u5bf9', + '\ue82f': '\u5c0f', + '\ue802': '\u591a', + '\ue831': '\u7136', + '\ue84b': '\u4e8e', + '\ue837': '\u5fc3', + '\ue829': '\u5b66', + '\ue85e': '\u4e48', + '\ue83a': '\u4e4b', + '\ue832': '\u90fd', + '\ue808': '\u597d', + '\ue841': '\u770b', + '\ue821': '\u8d77', + '\ue845': '\u53d1', + '\ue803': '\u5f53', + '\ue828': '\u6ca1', + '\ue81b': '\u6210', + '\ue83e': '\u53ea', + '\ue820': '\u5982', + '\ue84e': '\u4e8b', + '\ue85a': '\u628a', + '\ue806': '\u8fd8', + '\ue83f': '\u7528', + '\ue833': '\u7b2c', + '\ue811': '\u6837', + '\ue804': '\u9053', + '\ue814': '\u60f3', + '\ue80f': '\u4f5c', + '\ue84f': '\u79cd', + '\ue80e': '\u5f00', + '\ue823': '\u7f8e', + '\ue849': '\u4e73', + '\ue805': '\u9634', + '\ue809': '\u6db2', + '\ue81a': '\u830e', + '\ue844': '\u6b32', + '\ue847': '\u547b', + '\ue850': '\u8089', + '\ue824': '\u4ea4', + '\ue85f': '\u6027', + '\ue817': '\u80f8', + '\ue85c': '\u79c1', + '\ue838': '\u7a74', + '\ue82a': '\u6deb', + '\ue83d': '\u81c0', + '\ue82b': '\u8214', + '\ue80d': '\u5c04', + '\ue839': '\u8131', + '\ue834': '\u88f8', + '\ue846': '\u9a9a', + '\ue825': '\u5507', }; - - // const addPage = async pageCheerio => { - - const formatPage = async () => { - // Remove JS - pageCheerio('#ccacontent .cgo').remove(); - - // Load lazyloaded images - pageCheerio('#ccacontent 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('#ccacontent').html(); - pageText = pageText.replace(/./g, char => mapping_dict[char] || char); - - return Promise.resolve(); + const addPage = async pageCheerio => { + const formatPage = async () => { + // Remove JS + pageCheerio('#ccacontent .cgo').remove(); + + // Load lazyloaded images + pageCheerio('#ccacontent 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('#ccacontent').html(); + pageText = pageText.replace(/./g, char => skillgg[char] || char); + + return Promise.resolve(); + }; + + await formatPage(); + chapterName = + pageCheerio('#atitle + h3').text() + + ' — ' + + pageCheerio('#atitle').text(); + if (chapterText === undefined) { + chapterText = '' + chapterName + ''; + } + chapterText += pageText; }; - await formatPage(); - const chapterName = - pageCheerio('#atitle + h3').text() + ' — ' + pageCheerio('#atitle').text(); - const 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 }; - // }; + const loadPage = async url => { + const body = await fetchHtml({ url, sourceId }); + const pageCheerio = cheerio.load(body); + await addPage(pageCheerio); + pageHasNextPage = + pageCheerio('#footlink a:last').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); + 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, @@ -314,60 +419,83 @@ const parseChapter = async (novelUrl, chapterUrl) => { chapterName, chapterText, }; - console.log(chapter); + return chapter; }; const searchNovels = async searchTerm => { - const url = `${baseUrl}/search.html?searchkey=` + encodeURI(searchTerm); - const body = await fetchHtml({ url, sourceId }); - console.log(url); - const loadedCheerio = cheerio.load(body); - + const searchUrl = `${baseUrl}/search/`; + const Term = encodeURI(searchTerm); + let NextPage, NoNextPage, DeadEnd; + let pageNumber = 1; const novels = []; - const loadSearchResults = function () { - loadedCheerio('.book-ol .book-layout').each(function () { - let novelUrl = loadedCheerio(this).attr('href'); + const addPage = async (pageCheerio, redirect) => { + const loadSearchResults = function () { + pageCheerio('.book-ol .book-layout').each(function () { + let novelUrl = pageCheerio(this).attr('href'); - if (novelUrl) { - const novelName = loadedCheerio(this).find('.book-title').text(); - const novelCover = loadedCheerio(this) - .find('img.book-cover') - .attr('data-src'); - novelUrl = baseUrl + novelUrl; + if (novelUrl) { + const novelName = pageCheerio(this).find('.book-title').text(); + const novelCover = pageCheerio(this) + .find('img.book-cover') + .attr('data-src'); + novelUrl = baseUrl + novelUrl; - const novel = { sourceId, novelUrl, novelName, novelCover }; + const novel = { sourceId, novelUrl, novelName, novelCover }; - novels.push(novel); - } - }); + novels.push(novel); + } + }); + }; + + const novelResults = pageCheerio('.book-ol a.book-layout'); + if (novelResults.length === 0) { + showToast('Bypass check by searching in Webview'); + } else { + loadSearchResults(); + } + + if (redirect.length) { + novels.length = 0; + const novelName = pageCheerio('#bookDetailWrapper .book-title').text(); + + const novelCover = pageCheerio('#bookDetailWrapper img.book-cover').attr( + 'src', + ); + const novelUrl = + baseUrl + + pageCheerio('#btnReadBook').attr('href').slice(0, -8) + + '.html'; + const novel = { sourceId, novelUrl, novelName, novelCover }; + novels.push(novel); + } }; - const novelResults = loadedCheerio('.book-ol a.book-layout'); + const loadPage = async url => { + const body = await fetchHtml({ url, sourceId }); + const pageCheerio = cheerio.load(body); + const redirect = pageCheerio('div.book-layout'); + await addPage(pageCheerio, redirect); + NextPage = pageCheerio('.next').attr('href'); + if (!NextPage) { + NoNextPage === true; + } else { + NoNextPage = NextPage === '#' ? true : false; + } + return { pageCheerio, NoNextPage }; + }; - if (novelResults.length === 0) { - showToast('Bypass check by searching in Webview'); - } else { - loadSearchResults(); - } + let url = `${searchUrl}${Term}_${pageNumber}.html`; + do { + const page = await loadPage(url); + DeadEnd = page.NoNextPage; + if (DeadEnd === false) { + pageNumber++; + url = `${searchUrl}${Term}_${pageNumber}.html`; + } + } while (DeadEnd === false); - const singlenovel = loadedCheerio('div.book-layout'); - - if (singlenovel.length !== 0) { - novels.length = 0; - const novelName = loadedCheerio('#bookDetailWrapper .book-title').text(); - - const novelCover = loadedCheerio('#bookDetailWrapper img.book-cover').attr( - 'src', - ); - const novelUrl = - baseUrl + - loadedCheerio('#btnReadBook').attr('href').slice(0, -8) + - '.html'; - const novel = { sourceId, novelUrl, novelName, novelCover }; - novels.push(novel); - } console.log(novels); return novels; }; From efcf49e87b92f6c9751130798082bcbce31f5938 Mon Sep 17 00:00:00 2001 From: K1ngfish3r Date: Wed, 1 Nov 2023 22:16:18 +0800 Subject: [PATCH 28/41] fix sakuranovel again --- src/sources/id/sakuranovel.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sources/id/sakuranovel.js b/src/sources/id/sakuranovel.js index fb6becf18..f2064b2df 100644 --- a/src/sources/id/sakuranovel.js +++ b/src/sources/id/sakuranovel.js @@ -101,7 +101,7 @@ const parseChapter = async (novelUrl, chapterUrl) => { let loadedCheerio = cheerio.load(body); const chapterName = loadedCheerio('.title-chapter').text(); - const chapterText = loadedCheerio('.readers').html(); + const chapterText = loadedCheerio('.reader-setting').next().next().html(); const chapter = { sourceId, From c2d499ecab31010b4802708d56ee305c3bcdd342 Mon Sep 17 00:00:00 2001 From: K1ngfish3r Date: Fri, 3 Nov 2023 18:08:29 +0800 Subject: [PATCH 29/41] The_Lazy_Guy Dev + TuNovelaLigera Dev --- src/sources/en/icantreadjapanese.js | 139 ++++++++++++++++++++++++++++ src/sources/es/tunovelaligera.js | 77 ++++++++------- src/sources/sourceManager.ts | 2 + src/sources/sources.json | 9 +- 4 files changed, 186 insertions(+), 41 deletions(-) create mode 100644 src/sources/en/icantreadjapanese.js diff --git a/src/sources/en/icantreadjapanese.js b/src/sources/en/icantreadjapanese.js new file mode 100644 index 000000000..22caf3778 --- /dev/null +++ b/src/sources/en/icantreadjapanese.js @@ -0,0 +1,139 @@ +import { fetchHtml } from '@utils/fetch/fetch'; +import * as cheerio from 'cheerio'; +import { FilterInputs } from '../types/filterTypes'; + +const sourceId = 170; +const sourceName = 'I cant read japanese tl'; + +const baseUrl = 'https://icantreadjapanese.wordpress.com/'; + +const popularNovels = async (page, { filters }) => { + let link = `${baseUrl}`; + + if (page === 1) { + link += (filters?.storyStatus ? filters.storyStatus : 'projects') + '/'; + } + + console.log(link); + + const body = await fetchHtml({ url: link, sourceId }); + + const loadedCheerio = cheerio.load(body); + + let novels = []; + + loadedCheerio('figure.wp-block-image').each(function () { + const novelName = loadedCheerio(this).find('a').text(); + const novelCover = loadedCheerio(this).find('img').attr('src'); + const novelUrl = loadedCheerio(this).find('a').attr('href'); + + const novel = { sourceId, novelName, novelCover, novelUrl }; + + novels.push(novel); + }); + + return { novels }; +}; + +const parseNovelAndChapters = async novelUrl => { + const body = await fetchHtml({ url: novelUrl, sourceId: sourceId }); + + let loadedCheerio = cheerio.load(body); + + let novel = { + sourceId, + sourceName, + url: novelUrl, + novelUrl, + }; + + novel.novelName = loadedCheerio('h1.entry-title').text().trim(); + + novel.novelCover = loadedCheerio('figure.wp-block-image > img').attr('src'); + + novel.author = loadedCheerio('.has-text-align-left') + .text() + .replace(/.*Author: (.*) \|.*/g, '$1'); + + novel.summary = loadedCheerio('.entry-content > p:first') + .nextUntil('hr:first') + .text(); + + let chapters = []; + + loadedCheerio('.wp-block-column li a').each(function () { + let chapterName = loadedCheerio(this).text(); + const releaseDate = null; + const chapterUrl = loadedCheerio(this).attr('href'); + + const volumeName = loadedCheerio(this) + .parent() + .prop('innerHTML') + .replace(//g, '') + .replace(/
/g, ' ') + .trim(); + if (volumeName.length) { + chapterName = volumeName + ' - ' + chapterName; + } + + chapters.push({ chapterName, releaseDate, chapterUrl }); + }); + + novel.chapters = chapters; + return novel; +}; + +const parseChapter = async (novelUrl, chapterUrl) => { + const body = await fetchHtml({ + url: chapterUrl, + sourceId: sourceId, + }); + + let loadedCheerio = cheerio.load(body); + + const chapterName = loadedCheerio('h1.entry-title').text(); + + const chapterText = loadedCheerio('.entry-content').html(); + + const chapter = { + sourceId, + novelUrl, + chapterUrl, + chapterName, + chapterText, + }; + + return chapter; +}; + +const searchNovels = async () => { + showToast('Search is not implemented for this source'); + return; +}; + +const filters = [ + { + key: 'storyStatus', + label: 'Translation Status', + values: [ + { label: 'Ongoing Projects', value: 'projects' }, + { + label: 'Maybe Will Read Again, Caught Up', + value: 'maybe-will-read-again-caught-up', + }, + { label: 'Dropped', value: 'dropped' }, + { label: 'Finished', value: 'finished' }, + ], + inputType: FilterInputs.Picker, + }, +]; + +const ICantReadJPTLScraper = { + popularNovels, + parseNovelAndChapters, + parseChapter, + searchNovels, + filters, +}; + +export default ICantReadJPTLScraper; diff --git a/src/sources/es/tunovelaligera.js b/src/sources/es/tunovelaligera.js index 19d425a3d..efb397e35 100644 --- a/src/sources/es/tunovelaligera.js +++ b/src/sources/es/tunovelaligera.js @@ -1,6 +1,7 @@ import * as cheerio from 'cheerio'; import { defaultCoverUri, Status } from '../helpers/constants'; import { fetchHtml } from '@utils/fetch/fetch'; +import { showToast } from '@hooks/showToast'; const sourceId = 23; const sourceName = 'TuNovelaLigera'; @@ -92,51 +93,46 @@ const parseNovelAndChapters = async novelUrl => { novel.summary = loadedCheerio('div.summary__content > p').text().trim(); - let novelChapters = []; - - const novelId = - loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id'); - - let formData = new FormData(); - formData.append('action', 'manga_get_chapters'); - formData.append('manga', novelId); - - const text = await fetchHtml({ - url: 'https://tunovelaligera.com/wp-admin/admin-ajax.php', - init: { - method: 'POST', - body: formData, - }, - }); - - loadedCheerio = cheerio.load(text); - - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this) - .find('a') - .text() - .replace(/[\t\n]/g, '') - .trim(); - - const releaseDate = loadedCheerio(this).find('span').text().trim(); - - let chapterUrl = loadedCheerio(this).find('a').attr('href').split('/'); - - chapterUrl[6] - ? (chapterUrl = chapterUrl[5] + '/' + chapterUrl[6]) - : (chapterUrl = chapterUrl[5]); - - novelChapters.push({ chapterName, releaseDate, chapterUrl }); - }); + const delay = ms => new Promise(res => setTimeout(res, ms)); + let lastPage = 1; + lastPage = loadedCheerio('.lcp_paginator li:last').prev().text().trim(); + + const getChapters = async () => { + let novelChapters = []; + for (let i = 1; i <= lastPage; i++) { + const chaptersUrl = `${baseUrl}novelas/${novelUrl}?lcp_page0=${i}`; + showToast(`Getting Chapters Page ${i}/${lastPage}...`); + const chaptersHtml = await fetchHtml({ + url: chaptersUrl, + sourceId, + }); + + loadedCheerio = cheerio.load(chaptersHtml); + loadedCheerio('.lcp_catlist li').each((i, el) => { + const chapterName = loadedCheerio(el) + .find('a') + .text() + .replace(/[\t\n]/g, '') + .trim(); + + const releaseDate = loadedCheerio(el).find('span').text().trim(); + + const chapterUrl = loadedCheerio(el).find('a').attr('href'); + + novelChapters.push({ chapterName, releaseDate, chapterUrl }); + }); + await delay(1000); + } + return novelChapters.reverse(); + }; - novel.chapters = novelChapters.reverse(); + novel.chapters = await getChapters(); return novel; }; const parseChapter = async (novelUrl, chapterUrl) => { - const url = `${baseUrl}novelas/${novelUrl}/${chapterUrl}`; + const url = chapterUrl; const body = await fetchHtml({ url }); @@ -144,7 +140,8 @@ const parseChapter = async (novelUrl, chapterUrl) => { let chapterName = loadedCheerio('h1#chapter-heading').text(); - let chapterText = loadedCheerio('.text-left').html(); + loadedCheerio('#hola_siguiente').next().find('div').remove(); + let chapterText = loadedCheerio('#hola_siguiente').next().html(); novelUrl = novelUrl + '/'; const chapter = { diff --git a/src/sources/sourceManager.ts b/src/sources/sourceManager.ts index b1cdf7464..61e106873 100644 --- a/src/sources/sourceManager.ts +++ b/src/sources/sourceManager.ts @@ -29,6 +29,7 @@ import ScribbleHubScraper from './en/scribblehub'; import SyosetuScraper from './jp/syosetu'; import LNMTLScraper from './en/lnmtl'; import LightNovelFullScraper from './en/lightnovelfull'; +import ICantReadJPTLScraper from './en/icantreadjapanese'; import { AsuraLightNovelScraper, ArMTLScraper, @@ -338,6 +339,7 @@ export const sourceManager = (sourceId: number): Scraper => { 167: SmakolykyTlScraper, // @ts-ignore 168: LitSpaceScraper, // @ts-ignore 169: AsuraLightNovelScraper, // @ts-ignore + 170: ICantReadJPTLScraper, // @ts-ignore }; return scrapers[sourceId]; diff --git a/src/sources/sources.json b/src/sources/sources.json index 7c750a59d..5ecd2c1bc 100644 --- a/src/sources/sources.json +++ b/src/sources/sources.json @@ -1030,9 +1030,16 @@ }, { "sourceId": 169, - "url": "AsuraLightNovelScraper", + "url": "https://asuralightnovel.com/", "sourceName": "Asura Light Novel", "icon": "https://asuralightnovel.com/wp-content/uploads/2021/06/favicon-asura-2.png", "lang": "English" + }, + { + "sourceId": 170, + "url": "https://icantreadjapanese.wordpress.com/", + "sourceName": "I Cant Read Japanese TL", + "icon": "https://icantreadjapanese.files.wordpress.com/2021/03/cropped-cropped-site-icon-1.png?w=16", + "lang": "English" } ] From dce4f87afc857bafcd8e6cbaadea95b660bf1aa8 Mon Sep 17 00:00:00 2001 From: K1ngfish3r Date: Fri, 3 Nov 2023 21:44:37 +0800 Subject: [PATCH 30/41] TuNovelaLigera, ch cleanup --- src/sources/es/tunovelaligera.js | 77 +++++++++++++++++++++++++++----- 1 file changed, 65 insertions(+), 12 deletions(-) diff --git a/src/sources/es/tunovelaligera.js b/src/sources/es/tunovelaligera.js index efb397e35..a9f746785 100644 --- a/src/sources/es/tunovelaligera.js +++ b/src/sources/es/tunovelaligera.js @@ -93,15 +93,52 @@ const parseNovelAndChapters = async novelUrl => { novel.summary = loadedCheerio('div.summary__content > p').text().trim(); + let novelChapters = []; + const delay = ms => new Promise(res => setTimeout(res, ms)); let lastPage = 1; lastPage = loadedCheerio('.lcp_paginator li:last').prev().text().trim(); const getChapters = async () => { - let novelChapters = []; + const chaptersAjax = `${baseUrl}wp-admin/admin-ajax.php`; + showToast('Cargando desde Archivo...'); + + let formData = new FormData(); + formData.append('action', 'madara_load_more'); + formData.append('page', '0'); + formData.append('template', 'html/loop/content'); + formData.append('vars[category_name]', novelUrl.slice(0, -1)); + formData.append('vars[posts_per_page]', '10000'); + + const formBody = await fetchHtml({ + url: chaptersAjax, + init: { + method: 'POST', + body: formData, + }, + sourceId, + }); + + const loadedCheerio = cheerio.load(formBody); + + loadedCheerio('.heading').each((i, el) => { + const chapterName = loadedCheerio(el) + .text() + .replace(/[\t\n]/g, '') + .trim(); + const releaseDate = null; + let chapterUrl = loadedCheerio(el).find('a').attr('href'); + chapterUrl = chapterUrl.replace(`${baseUrl}${novelUrl}`, ''); + + novelChapters.push({ chapterName, releaseDate, chapterUrl }); + }); + return novelChapters.reverse(); + }; + + const getPageChapters = async () => { for (let i = 1; i <= lastPage; i++) { const chaptersUrl = `${baseUrl}novelas/${novelUrl}?lcp_page0=${i}`; - showToast(`Getting Chapters Page ${i}/${lastPage}...`); + showToast(`Cargando desde la página ${i}/${lastPage}...`); const chaptersHtml = await fetchHtml({ url: chaptersUrl, sourceId, @@ -127,22 +164,38 @@ const parseNovelAndChapters = async novelUrl => { }; novel.chapters = await getChapters(); + if (!novel.chapters.length) { + showToast('¡Archivo no encontrado!'); + await delay(1000); + novel.chapters = await getPageChapters(); + } return novel; }; const parseChapter = async (novelUrl, chapterUrl) => { - const url = chapterUrl; + const url = `${baseUrl}${novelUrl}${chapterUrl}`; - const body = await fetchHtml({ url }); + const body = await fetchHtml({ url, sourceId }); - let loadedCheerio = cheerio.load(body); + const loadedCheerio = cheerio.load(body); + + const chapterName = loadedCheerio('h1#chapter-heading').text(); - let chapterName = loadedCheerio('h1#chapter-heading').text(); + const cleanup = [ + '.clear', + '.code-block', + '.ai-viewport-2', + '.cbxwpbkmarkwrap', + '.flagcontent-form-container', + 'a:last', + 'strong:last', + ]; + cleanup.map(tag => + loadedCheerio('#hola_siguiente').next().find(tag).remove(), + ); - loadedCheerio('#hola_siguiente').next().find('div').remove(); - let chapterText = loadedCheerio('#hola_siguiente').next().html(); - novelUrl = novelUrl + '/'; + const chapterText = loadedCheerio('#hola_siguiente').next().html(); const chapter = { sourceId, @@ -158,11 +211,11 @@ const parseChapter = async (novelUrl, chapterUrl) => { const searchNovels = async searchTerm => { const url = `${baseUrl}?s=${searchTerm}&post_type=wp-manga`; - const body = await fetchHtml({ url }); + const body = await fetchHtml({ url, sourceId }); - let loadedCheerio = cheerio.load(body); + const loadedCheerio = cheerio.load(body); - let novels = []; + const novels = []; loadedCheerio('.c-tabs-item__content').each(function () { const novelName = loadedCheerio(this).find('.h4 > a').text(); From 4d19cb246bb5447a0496d8d8c376f8b6f0bf8902 Mon Sep 17 00:00:00 2001 From: K1ngfish3r Date: Mon, 13 Nov 2023 02:36:13 +0800 Subject: [PATCH 31/41] under review --- CONTRIBUTING.md | 6 +-- src/sources/ch/linovelib.js | 75 +++++++++++++++++------------ src/sources/en/icantreadjapanese.js | 2 - src/sources/en/lightnovelpub.js | 7 ++- src/sources/en/royalroad.js | 2 +- 5 files changed, 50 insertions(+), 42 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d207d5c0c..bb824dee0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -8,9 +8,9 @@ After forking to your own github org or account, do the following steps to get s ```bash # prerequisites -node --version = 18.17.1 (for version management, get nvm [recommended]) -java sdk --version = 11 (for version management, get jenv [optional]) -android sdk (https://developer.android.com/studio) +node --version <= 16.13.1 or 18+ (for version management, get nvm [recommended]) +java sdk --version <= 17 (for version management, get jenv [optional]) +android sdk (https://developer.android.com/studio) # clone your fork to your local machine git clone https://github.com//lnreader.git diff --git a/src/sources/ch/linovelib.js b/src/sources/ch/linovelib.js index 77125c4ff..81be7915e 100644 --- a/src/sources/ch/linovelib.js +++ b/src/sources/ch/linovelib.js @@ -1,5 +1,5 @@ import { showToast } from '@hooks/showToast'; -import { fetchHtml } from '@utils/fetch/fetch'; +import { fetchApi, fetchHtml } from '@utils/fetch/fetch'; import * as cheerio from 'cheerio'; @@ -246,7 +246,7 @@ const parseChapter = async (novelUrl, chapterUrl) => { // '': '么', // '': '裸', // }; - const skillgg = { + const skillgg_dictionary = { '\u201c': '\u300c', '\u201d': '\u300d', '\u2018': '\u300e', @@ -355,29 +355,36 @@ const parseChapter = async (novelUrl, chapterUrl) => { const addPage = async pageCheerio => { const formatPage = async () => { // Remove JS - pageCheerio('#ccacontent .cgo').remove(); + pageCheerio('.atitle').next().find('.cgo').remove(); // Load lazyloaded images - pageCheerio('#ccacontent 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'); - } - }); + pageCheerio('.atitle') + .next() + .find('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') + .addClass('delayed-src'); + } + }); // Recover the original character - pageText = pageCheerio('#ccacontent').html(); - pageText = pageText.replace(/./g, char => skillgg[char] || char); + pageText = pageCheerio('.atitle').next().html(); + pageText = pageText?.replace( + /./g, + char => skillgg_dictionary[char] || char, + ); return Promise.resolve(); }; @@ -388,7 +395,7 @@ const parseChapter = async (novelUrl, chapterUrl) => { ' — ' + pageCheerio('#atitle').text(); if (chapterText === undefined) { - chapterText = '' + chapterName + ''; + chapterText = '

' + chapterName + '

'; } chapterText += pageText; }; @@ -426,7 +433,7 @@ const parseChapter = async (novelUrl, chapterUrl) => { const searchNovels = async searchTerm => { const searchUrl = `${baseUrl}/search/`; const Term = encodeURI(searchTerm); - let NextPage, NoNextPage, DeadEnd; + let nextPage, noNextPage, deadEnd; let pageNumber = 1; const novels = []; @@ -477,34 +484,38 @@ const searchNovels = async searchTerm => { const pageCheerio = cheerio.load(body); const redirect = pageCheerio('div.book-layout'); await addPage(pageCheerio, redirect); - NextPage = pageCheerio('.next').attr('href'); - if (!NextPage) { - NoNextPage === true; + nextPage = pageCheerio('.next').attr('href'); + if (!nextPage) { + noNextPage === true; } else { - NoNextPage = NextPage === '#' ? true : false; + noNextPage = nextPage === '#' ? true : false; } - return { pageCheerio, NoNextPage }; + return { pageCheerio, noNextPage }; }; let url = `${searchUrl}${Term}_${pageNumber}.html`; do { const page = await loadPage(url); - DeadEnd = page.NoNextPage; - if (DeadEnd === false) { + deadEnd = page.noNextPage; + if (deadEnd === false) { pageNumber++; url = `${searchUrl}${Term}_${pageNumber}.html`; } - } while (DeadEnd === false); + } while (deadEnd === false); - console.log(novels); return novels; }; +const headers = { + Referer: 'https://w.linovelib.com', +}; + const LinovelibScraper = { popularNovels, parseNovelAndChapters, parseChapter, searchNovels, + headers, }; export default LinovelibScraper; diff --git a/src/sources/en/icantreadjapanese.js b/src/sources/en/icantreadjapanese.js index 22caf3778..ab1192f37 100644 --- a/src/sources/en/icantreadjapanese.js +++ b/src/sources/en/icantreadjapanese.js @@ -14,8 +14,6 @@ const popularNovels = async (page, { filters }) => { link += (filters?.storyStatus ? filters.storyStatus : 'projects') + '/'; } - console.log(link); - const body = await fetchHtml({ url: link, sourceId }); const loadedCheerio = cheerio.load(body); diff --git a/src/sources/en/lightnovelpub.js b/src/sources/en/lightnovelpub.js index 4bfb5af4d..d5e518165 100644 --- a/src/sources/en/lightnovelpub.js +++ b/src/sources/en/lightnovelpub.js @@ -93,10 +93,9 @@ const parseNovelAndChapters = async novelUrl => { loadedCheerio = cheerio.load(chaptersHtml); loadedCheerio('.chapter-list li').each(function () { - const chapterName = loadedCheerio(this) - .find('.chapter-title') - .text() - .trim(); + const chapterName = 'Chapter '; + loadedCheerio(this).find('.chapter-no').text.trim() + ' - '; + loadedCheerio(this).find('.chapter-title').text().trim(); const releaseDate = loadedCheerio(this) .find('.chapter-update') diff --git a/src/sources/en/royalroad.js b/src/sources/en/royalroad.js index 42b71d0de..5abc72846 100644 --- a/src/sources/en/royalroad.js +++ b/src/sources/en/royalroad.js @@ -127,7 +127,7 @@ const parseChapter = async (novelUrl, chapterUrl) => { const loadedCheerio = cheerio.load(body); - let chapterName = loadedCheerio('div.chapter-content').find('strong').text(); + let chapterName = loadedCheerio('h1.font-white').text(); let chapterText = loadedCheerio('div.chapter-content').html(); From 1fd5e92871a9ff323459e5101e0125989e71ffd0 Mon Sep 17 00:00:00 2001 From: K1ngfish3r Date: Mon, 13 Nov 2023 02:53:41 +0800 Subject: [PATCH 32/41] remove green dictionary --- CONTRIBUTING.md | 2 +- src/sources/ch/linovelib.js | 117 ++---------------------------------- 2 files changed, 6 insertions(+), 113 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index bb824dee0..19c6db621 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -8,7 +8,7 @@ After forking to your own github org or account, do the following steps to get s ```bash # prerequisites -node --version <= 16.13.1 or 18+ (for version management, get nvm [recommended]) +node --version <= 16.13.1 (for version management, get nvm [recommended]) java sdk --version <= 17 (for version management, get jenv [optional]) android sdk (https://developer.android.com/studio) diff --git a/src/sources/ch/linovelib.js b/src/sources/ch/linovelib.js index 81be7915e..bff2cb239 100644 --- a/src/sources/ch/linovelib.js +++ b/src/sources/ch/linovelib.js @@ -138,115 +138,10 @@ const parseChapter = async (novelUrl, chapterUrl) => { /* * TODO: Maybe there are other ways to get the translation table * It is embed and encrypted inside readtool.js - * UPDATE: Decrypted, see skillgg + * UPDATE: Decrypted, by skillgg */ - // const mapping_dict = { - // '“': '「', - // '’': '』', - // '': '是', - // '': '不', - // '': '好', - // '': '个', - // '': '开', - // '': '样', - // '': '想', - // '': '说', - // '': '年', - // '': '那', - // '': '她', - // '': '美', - // '': '自', - // '': '家', - // '': '而', - // '': '去', - // '': '都', - // '': '于', - // '': '舔', - // '': '他', - // '': '只', - // '': '看', - // '': '来', - // '': '用', - // '': '道', - // '': '得', - // '': '乳', - // '': '茎', - // '': '肉', - // '': '胸', - // '': '淫', - // '': '性', - // '': '骚', - // '”': '」', - // '': '的', - // '': '当', - // '': '人', - // '': '有', - // '': '上', - // '': '到', - // '': '地', - // '': '中', - // '': '生', - // '': '着', - // '': '和', - // '': '起', - // '': '交', - // '': '以', - // '': '可', - // '': '过', - // '': '能', - // '': '多', - // '': '心', - // '': '小', - // '': '成', - // '': '了', - // '': '把', - // '': '发', - // '': '第', - // '': '子', - // '': '事', - // '': '阴', - // '': '欲', - // '': '里', - // '': '私', - // '': '臀', - // '': '脱', - // '': '唇', - // '‘': '『', - // '': '一', - // '': '我', - // '': '在', - // '': '这', - // '': '们', - // '': '时', - // '': '为', - // '': '你', - // '': '国', - // '': '就', - // '': '要', - // '': '也', - // '': '后', - // '': '没', - // '': '下', - // '': '天', - // '': '对', - // '': '然', - // '': '学', - // '': '之', - // '': '出', - // '': '没', - // '': '如', - // '': '还', - // '': '大', - // '': '作', - // '': '种', - // '': '液', - // '': '呻', - // '': '射', - // '': '穴', - // '': '么', - // '': '裸', - // }; - const skillgg_dictionary = { + + const mapping_dict = { '\u201c': '\u300c', '\u201d': '\u300d', '\u2018': '\u300e', @@ -352,6 +247,7 @@ const parseChapter = async (novelUrl, chapterUrl) => { '\ue846': '\u9a9a', '\ue825': '\u5507', }; + const addPage = async pageCheerio => { const formatPage = async () => { // Remove JS @@ -381,10 +277,7 @@ const parseChapter = async (novelUrl, chapterUrl) => { // Recover the original character pageText = pageCheerio('.atitle').next().html(); - pageText = pageText?.replace( - /./g, - char => skillgg_dictionary[char] || char, - ); + pageText = pageText?.replace(/./g, char => mapping_dict[char] || char); return Promise.resolve(); }; From 9c124e13b69ee7b8eb295c26df33f6d79a85787e Mon Sep 17 00:00:00 2001 From: K1ngfish3r Date: Mon, 13 Nov 2023 03:04:16 +0800 Subject: [PATCH 33/41] text() --- src/sources/en/lightnovelpub.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sources/en/lightnovelpub.js b/src/sources/en/lightnovelpub.js index d5e518165..8e22b788f 100644 --- a/src/sources/en/lightnovelpub.js +++ b/src/sources/en/lightnovelpub.js @@ -94,7 +94,7 @@ const parseNovelAndChapters = async novelUrl => { loadedCheerio('.chapter-list li').each(function () { const chapterName = 'Chapter '; - loadedCheerio(this).find('.chapter-no').text.trim() + ' - '; + loadedCheerio(this).find('.chapter-no').text().trim() + ' - '; loadedCheerio(this).find('.chapter-title').text().trim(); const releaseDate = loadedCheerio(this) From 670d2ec32449b22d3a7969171a088e1a106b3080 Mon Sep 17 00:00:00 2001 From: K1ngfish3r Date: Mon, 13 Nov 2023 04:33:27 +0800 Subject: [PATCH 34/41] add delay --- src/sources/ch/linovelib.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/sources/ch/linovelib.js b/src/sources/ch/linovelib.js index bff2cb239..9f6c0e8d8 100644 --- a/src/sources/ch/linovelib.js +++ b/src/sources/ch/linovelib.js @@ -134,6 +134,7 @@ const parseNovelAndChapters = async novelUrl => { const parseChapter = async (novelUrl, chapterUrl) => { let chapterName, chapterText, hasNextPage, pageHasNextPage, pageText; let pageNumber = 1; + const delay = ms => new Promise(res => setTimeout(res, ms)); /* * TODO: Maybe there are other ways to get the translation table @@ -251,6 +252,7 @@ const parseChapter = async (novelUrl, chapterUrl) => { const addPage = async pageCheerio => { const formatPage = async () => { // Remove JS + pageCheerio('.atitle').next().find('p:first').remove(); pageCheerio('.atitle').next().find('.cgo').remove(); // Load lazyloaded images @@ -305,6 +307,7 @@ const parseChapter = async (novelUrl, chapterUrl) => { let url = chapterUrl; do { const page = await loadPage(url); + await delay(1000); hasNextPage = page.pageHasNextPage; if (hasNextPage === true) { pageNumber++; From ec6a93f7ddc2595bd58b85c05322c4e9bff7e3ce Mon Sep 17 00:00:00 2001 From: K1ngfish3r Date: Mon, 13 Nov 2023 15:06:55 +0800 Subject: [PATCH 35/41] cleanup --- src/sources/ch/linovelib.js | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/sources/ch/linovelib.js b/src/sources/ch/linovelib.js index 9f6c0e8d8..eae3e6477 100644 --- a/src/sources/ch/linovelib.js +++ b/src/sources/ch/linovelib.js @@ -132,7 +132,7 @@ const parseNovelAndChapters = async novelUrl => { }; const parseChapter = async (novelUrl, chapterUrl) => { - let chapterName, chapterText, hasNextPage, pageHasNextPage, pageText; + let chapterName, chapterText, hasNextPage, pageHasNextPage, pageText, urlNext; let pageNumber = 1; const delay = ms => new Promise(res => setTimeout(res, ms)); @@ -252,8 +252,10 @@ const parseChapter = async (novelUrl, chapterUrl) => { const addPage = async pageCheerio => { const formatPage = async () => { // Remove JS - pageCheerio('.atitle').next().find('p:first').remove(); - pageCheerio('.atitle').next().find('.cgo').remove(); + let style = pageCheerio('style:first').prop('innerHTML'); + style = style.replace(/(.*?)\{.*?\}/g, '$1,').split(','); + style.push(style.pop().replace(/\}/, '.cgo')); + style.map(tag => pageCheerio(tag).remove()); // Load lazyloaded images pageCheerio('.atitle') @@ -286,21 +288,23 @@ const parseChapter = async (novelUrl, chapterUrl) => { await formatPage(); chapterName = - pageCheerio('#atitle + h3').text() + - ' — ' + - pageCheerio('#atitle').text(); + pageCheerio('.atitle h3').text() + ' — ' + pageCheerio('#atitle').text(); if (chapterText === undefined) { chapterText = '

' + chapterName + '

'; } - chapterText += pageText; + chapterText += + pageText || + 'Chapter not found, Report at lnreader github/discord if you see this message'; }; const loadPage = async url => { const body = await fetchHtml({ url, sourceId }); const pageCheerio = cheerio.load(body); await addPage(pageCheerio); - pageHasNextPage = - pageCheerio('#footlink a:last').text() === '下一页' ? true : false; + urlNext = pageCheerio('#aread script:first') + .prop('innerHTML') + .replace(/.*next:'(.*?)'.*/g, '$1'); + pageHasNextPage = urlNext.match(/_/) ? true : false; return { pageCheerio, pageHasNextPage }; }; From b11626afd19477fe6c4434be5a2ad38b4276aa73 Mon Sep 17 00:00:00 2001 From: K1ngfish3r Date: Thu, 16 Nov 2023 12:12:13 +0800 Subject: [PATCH 36/41] allnovelfull cleanup --- src/sources/en/allnovelfull.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sources/en/allnovelfull.ts b/src/sources/en/allnovelfull.ts index 09fed86b6..05fee33a9 100644 --- a/src/sources/en/allnovelfull.ts +++ b/src/sources/en/allnovelfull.ts @@ -127,6 +127,7 @@ const parseChapter = async (novelUrl: string, chapterUrl: string) => { const body = await result.text(); const loadedCheerio = cheerio.load(body); + loadedCheerio('#chapter-content div').remove(); const chapterName = loadedCheerio('.chapter-title').attr('title'); const chapterText = loadedCheerio('#chapter-content').html() || ''; From e24171505d13a2f584fd212fe73431faa19d1ad0 Mon Sep 17 00:00:00 2001 From: K1ngfish3r Date: Sat, 18 Nov 2023 11:38:01 +0800 Subject: [PATCH 37/41] update selector --- src/sources/es/tunovelaligera.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/sources/es/tunovelaligera.js b/src/sources/es/tunovelaligera.js index a9f746785..e734c664d 100644 --- a/src/sources/es/tunovelaligera.js +++ b/src/sources/es/tunovelaligera.js @@ -183,6 +183,7 @@ const parseChapter = async (novelUrl, chapterUrl) => { const chapterName = loadedCheerio('h1#chapter-heading').text(); const cleanup = [ + 'center', '.clear', '.code-block', '.ai-viewport-2', @@ -192,10 +193,17 @@ const parseChapter = async (novelUrl, chapterUrl) => { 'strong:last', ]; cleanup.map(tag => - loadedCheerio('#hola_siguiente').next().find(tag).remove(), + loadedCheerio('.entry-header') + .next() + .children('div:last') + .find(tag) + .remove(), ); - const chapterText = loadedCheerio('#hola_siguiente').next().html(); + const chapterText = loadedCheerio('.entry-header') + .next() + .children('div:last') + .html(); const chapter = { sourceId, From b567c5cd87985ec419335ca1d5cea75ca412d516 Mon Sep 17 00:00:00 2001 From: K1ngfish3r Date: Sat, 18 Nov 2023 14:59:36 +0000 Subject: [PATCH 38/41] update selectors SUPER --- src/sources/es/tunovelaligera.js | 40 ++++++++++++++++---------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/sources/es/tunovelaligera.js b/src/sources/es/tunovelaligera.js index e734c664d..7d4b71512 100644 --- a/src/sources/es/tunovelaligera.js +++ b/src/sources/es/tunovelaligera.js @@ -145,19 +145,23 @@ const parseNovelAndChapters = async novelUrl => { }); loadedCheerio = cheerio.load(chaptersHtml); - loadedCheerio('.lcp_catlist li').each((i, el) => { - const chapterName = loadedCheerio(el) - .find('a') - .text() - .replace(/[\t\n]/g, '') - .trim(); - - const releaseDate = loadedCheerio(el).find('span').text().trim(); - - const chapterUrl = loadedCheerio(el).find('a').attr('href'); - - novelChapters.push({ chapterName, releaseDate, chapterUrl }); - }); + loadedCheerio('h2:contains("Resumen")') + .closest('div') + .next() + .find('ul:first li') + .each((i, el) => { + const chapterName = loadedCheerio(el) + .find('a') + .text() + .replace(/[\t\n]/g, '') + .trim(); + + const releaseDate = loadedCheerio(el).find('span').text().trim(); + + const chapterUrl = loadedCheerio(el).find('a').attr('href'); + + novelChapters.push({ chapterName, releaseDate, chapterUrl }); + }); await delay(1000); } return novelChapters.reverse(); @@ -193,16 +197,12 @@ const parseChapter = async (novelUrl, chapterUrl) => { 'strong:last', ]; cleanup.map(tag => - loadedCheerio('.entry-header') - .next() - .children('div:last') - .find(tag) - .remove(), + loadedCheerio('li:contains("A")').closest('div').next().find(tag).remove(), ); - const chapterText = loadedCheerio('.entry-header') + const chapterText = loadedCheerio('li:contains("A")') + .closest('div') .next() - .children('div:last') .html(); const chapter = { From 7bbbbbd674d82431953fe119d161f1e81978b308 Mon Sep 17 00:00:00 2001 From: K1ngfish3r Date: Mon, 20 Nov 2023 02:57:31 +0800 Subject: [PATCH 39/41] fix chapter name lightnovelpub --- src/sources/en/lightnovelpub.js | 6 ++++-- src/sources/es/tunovelaligera.js | 25 ++++++++++++++++--------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/sources/en/lightnovelpub.js b/src/sources/en/lightnovelpub.js index 8e22b788f..90c747650 100644 --- a/src/sources/en/lightnovelpub.js +++ b/src/sources/en/lightnovelpub.js @@ -93,8 +93,10 @@ const parseNovelAndChapters = async novelUrl => { loadedCheerio = cheerio.load(chaptersHtml); loadedCheerio('.chapter-list li').each(function () { - const chapterName = 'Chapter '; - loadedCheerio(this).find('.chapter-no').text().trim() + ' - '; + const chapterName = + 'Chapter ' + + loadedCheerio(this).find('.chapter-no').text().trim() + + ' - '; loadedCheerio(this).find('.chapter-title').text().trim(); const releaseDate = loadedCheerio(this) diff --git a/src/sources/es/tunovelaligera.js b/src/sources/es/tunovelaligera.js index 7d4b71512..068a4d4eb 100644 --- a/src/sources/es/tunovelaligera.js +++ b/src/sources/es/tunovelaligera.js @@ -186,24 +186,31 @@ const parseChapter = async (novelUrl, chapterUrl) => { const chapterName = loadedCheerio('h1#chapter-heading').text(); - const cleanup = [ + let pageText = loadedCheerio('li:contains("A")').closest('div').next(); + + let cleanup = []; + pageText.find('div').each((i, el) => { + let hb = loadedCheerio(el).attr('id')?.match(/hb.*/); + if (!hb) { + return; + } + let idAttr = `div[id="${hb}"]`; + cleanup.push(idAttr); + }); + + cleanup.push( 'center', '.clear', '.code-block', '.ai-viewport-2', '.cbxwpbkmarkwrap', '.flagcontent-form-container', - 'a:last', 'strong:last', - ]; - cleanup.map(tag => - loadedCheerio('li:contains("A")').closest('div').next().find(tag).remove(), ); - const chapterText = loadedCheerio('li:contains("A")') - .closest('div') - .next() - .html(); + cleanup.map(tag => pageText.find(tag).remove()); + + const chapterText = pageText.html(); const chapter = { sourceId, From 90d0caf465f9e583023d18ea22b662430d541e99 Mon Sep 17 00:00:00 2001 From: K1ngfish3r Date: Mon, 20 Nov 2023 21:15:10 +0800 Subject: [PATCH 40/41] update dictionary 3: revenge of the dict --- src/sources/ch/linovelib.js | 198 +++++++++++++++---------------- src/sources/es/tunovelaligera.js | 1 + 2 files changed, 100 insertions(+), 99 deletions(-) diff --git a/src/sources/ch/linovelib.js b/src/sources/ch/linovelib.js index eae3e6477..52110450f 100644 --- a/src/sources/ch/linovelib.js +++ b/src/sources/ch/linovelib.js @@ -148,105 +148,105 @@ const parseChapter = async (novelUrl, chapterUrl) => { '\u2018': '\u300e', '\u2019': '\u300f', '\ue82c': '\u7684', - '\ue852': '\u4e00', - '\ue82d': '\u662f', - '\ue819': '\u4e86', - '\ue856': '\u6211', - '\ue857': '\u4e0d', - '\ue816': '\u4eba', - '\ue83c': '\u5728', - '\ue830': '\u4ed6', - '\ue82e': '\u6709', - '\ue836': '\u8fd9', - '\ue859': '\u4e2a', - '\ue80a': '\u4e0a', - '\ue855': '\u4eec', - '\ue842': '\u6765', - '\ue858': '\u5230', - '\ue80b': '\u65f6', - '\ue81f': '\u5927', - '\ue84a': '\u5730', - '\ue853': '\u4e3a', - '\ue81e': '\u5b50', - '\ue822': '\u4e2d', - '\ue813': '\u4f60', - '\ue85b': '\u8bf4', - '\ue807': '\u751f', - '\ue818': '\u56fd', - '\ue810': '\u5e74', - '\ue812': '\u7740', - '\ue851': '\u5c31', - '\ue801': '\u90a3', - '\ue80c': '\u548c', - '\ue815': '\u8981', - '\ue84c': '\u5979', - '\ue840': '\u51fa', - '\ue848': '\u4e5f', - '\ue835': '\u5f97', - '\ue800': '\u91cc', - '\ue826': '\u540e', - '\ue863': '\u81ea', - '\ue861': '\u4ee5', - '\ue854': '\u4f1a', - '\ue827': '\u5bb6', - '\ue83b': '\u53ef', - '\ue85d': '\u4e0b', - '\ue84d': '\u800c', - '\ue862': '\u8fc7', - '\ue81c': '\u5929', - '\ue81d': '\u53bb', - '\ue860': '\u80fd', - '\ue843': '\u5bf9', - '\ue82f': '\u5c0f', - '\ue802': '\u591a', - '\ue831': '\u7136', - '\ue84b': '\u4e8e', - '\ue837': '\u5fc3', - '\ue829': '\u5b66', - '\ue85e': '\u4e48', - '\ue83a': '\u4e4b', - '\ue832': '\u90fd', - '\ue808': '\u597d', - '\ue841': '\u770b', - '\ue821': '\u8d77', - '\ue845': '\u53d1', - '\ue803': '\u5f53', - '\ue828': '\u6ca1', - '\ue81b': '\u6210', - '\ue83e': '\u53ea', - '\ue820': '\u5982', - '\ue84e': '\u4e8b', - '\ue85a': '\u628a', - '\ue806': '\u8fd8', - '\ue83f': '\u7528', - '\ue833': '\u7b2c', - '\ue811': '\u6837', - '\ue804': '\u9053', - '\ue814': '\u60f3', - '\ue80f': '\u4f5c', - '\ue84f': '\u79cd', - '\ue80e': '\u5f00', - '\ue823': '\u7f8e', - '\ue849': '\u4e73', - '\ue805': '\u9634', - '\ue809': '\u6db2', - '\ue81a': '\u830e', - '\ue844': '\u6b32', - '\ue847': '\u547b', - '\ue850': '\u8089', - '\ue824': '\u4ea4', - '\ue85f': '\u6027', - '\ue817': '\u80f8', - '\ue85c': '\u79c1', - '\ue838': '\u7a74', - '\ue82a': '\u6deb', - '\ue83d': '\u81c0', - '\ue82b': '\u8214', - '\ue80d': '\u5c04', - '\ue839': '\u8131', - '\ue834': '\u88f8', - '\ue846': '\u9a9a', - '\ue825': '\u5507', + '\ue836': '\u4e00', + '\ue852': '\u662f', + '\ue850': '\u4e86', + '\ue832': '\u6211', + '\ue812': '\u4e0d', + '\ue833': '\u4eba', + '\ue849': '\u5728', + '\ue821': '\u4ed6', + '\ue810': '\u6709', + '\ue84c': '\u8fd9', + '\ue815': '\u4e2a', + '\ue842': '\u4e0a', + '\ue82e': '\u4eec', + '\ue817': '\u6765', + '\ue835': '\u5230', + '\ue837': '\u65f6', + '\ue82d': '\u5927', + '\ue859': '\u5730', + '\ue85c': '\u4e3a', + '\ue82f': '\u5b50', + '\ue84d': '\u4e2d', + '\ue854': '\u4f60', + '\ue81e': '\u8bf4', + '\ue853': '\u751f', + '\ue80f': '\u56fd', + '\ue80e': '\u5e74', + '\ue813': '\u7740', + '\ue802': '\u5c31', + '\ue81a': '\u90a3', + '\ue83b': '\u548c', + '\ue851': '\u8981', + '\ue82a': '\u5979', + '\ue838': '\u51fa', + '\ue808': '\u4e5f', + '\ue83a': '\u5f97', + '\ue814': '\u91cc', + '\ue857': '\u540e', + '\ue855': '\u81ea', + '\ue800': '\u4ee5', + '\ue81b': '\u4f1a', + '\ue85f': '\u5bb6', + '\ue816': '\u53ef', + '\ue83e': '\u4e0b', + '\ue84f': '\u800c', + '\ue80b': '\u8fc7', + '\ue828': '\u5929', + '\ue843': '\u53bb', + '\ue806': '\u80fd', + '\ue81f': '\u5bf9', + '\ue834': '\u5c0f', + '\ue81c': '\u591a', + '\ue848': '\u7136', + '\ue830': '\u4e8e', + '\ue84b': '\u5fc3', + '\ue84a': '\u5b66', + '\ue85d': '\u4e48', + '\ue861': '\u4e4b', + '\ue809': '\u90fd', + '\ue80c': '\u597d', + '\ue84e': '\u770b', + '\ue858': '\u8d77', + '\ue840': '\u53d1', + '\ue85b': '\u5f53', + '\ue863': '\u6ca1', + '\ue839': '\u6210', + '\ue827': '\u53ea', + '\ue841': '\u5982', + '\ue805': '\u4e8b', + '\ue845': '\u628a', + '\ue820': '\u8fd8', + '\ue83c': '\u7528', + '\ue847': '\u7b2c', + '\ue819': '\u6837', + '\ue82b': '\u9053', + '\ue80a': '\u60f3', + '\ue822': '\u4f5c', + '\ue85e': '\u79cd', + '\ue801': '\u5f00', + '\ue856': '\u7f8e', + '\ue811': '\u4e73', + '\ue860': '\u9634', + '\ue80d': '\u6db2', + '\ue83f': '\u830e', + '\ue803': '\u6b32', + '\ue804': '\u547b', + '\ue825': '\u8089', + '\ue846': '\u4ea4', + '\ue85a': '\u6027', + '\ue831': '\u80f8', + '\ue81d': '\u79c1', + '\ue826': '\u7a74', + '\ue818': '\u6deb', + '\ue823': '\u81c0', + '\ue829': '\u8214', + '\ue807': '\u5c04', + '\ue862': '\u8131', + '\ue83d': '\u88f8', + '\ue824': '\u9a9a', + '\ue844': '\u5507', }; const addPage = async pageCheerio => { diff --git a/src/sources/es/tunovelaligera.js b/src/sources/es/tunovelaligera.js index 068a4d4eb..064caddd0 100644 --- a/src/sources/es/tunovelaligera.js +++ b/src/sources/es/tunovelaligera.js @@ -209,6 +209,7 @@ const parseChapter = async (novelUrl, chapterUrl) => { ); cleanup.map(tag => pageText.find(tag).remove()); + pageText.find('a, span').removeAttr(); const chapterText = pageText.html(); From f18c23c09b25e473af5877c4b2ee7daf8f6f5512 Mon Sep 17 00:00:00 2001 From: K1ngfish3r Date: Wed, 22 Nov 2023 22:27:28 +0800 Subject: [PATCH 41/41] indowebnovel --- src/sources/es/tunovelaligera.js | 16 +++++++++------- src/sources/id/indowebnovel.js | 2 +- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/sources/es/tunovelaligera.js b/src/sources/es/tunovelaligera.js index 064caddd0..8d3263a99 100644 --- a/src/sources/es/tunovelaligera.js +++ b/src/sources/es/tunovelaligera.js @@ -162,17 +162,19 @@ const parseNovelAndChapters = async novelUrl => { novelChapters.push({ chapterName, releaseDate, chapterUrl }); }); - await delay(1000); + await delay(2000); } return novelChapters.reverse(); }; - novel.chapters = await getChapters(); - if (!novel.chapters.length) { - showToast('¡Archivo no encontrado!'); - await delay(1000); - novel.chapters = await getPageChapters(); - } + // novel.chapters = await getChapters(); + // if (!novel.chapters.length) { + // showToast('¡Archivo no encontrado!'); + // await delay(1000); + // + // } + + novel.chapters = await getPageChapters(); return novel; }; diff --git a/src/sources/id/indowebnovel.js b/src/sources/id/indowebnovel.js index 26f8780e1..040f2c92c 100644 --- a/src/sources/id/indowebnovel.js +++ b/src/sources/id/indowebnovel.js @@ -106,7 +106,7 @@ const parseChapter = async (novelUrl, chapterUrl) => { let loadedCheerio = cheerio.load(body); const chapterName = loadedCheerio('.title-chapter').text(); - const chapterText = loadedCheerio('.reader').html(); + const chapterText = loadedCheerio('.entry-pagination').next().html(); const chapter = { sourceId,