From e0746ff092137ca1fc03cceac9832c23658ee157 Mon Sep 17 00:00:00 2001 From: Rajarshee Chatterjee Date: Sun, 14 Nov 2021 11:15:49 +0530 Subject: [PATCH] Add BestLightNovel (Closes LNReader/lnreader-sources#121) --- src/sources/en/bestlightnovel.js | 148 +++++++++++++++++++++++++++++++ src/sources/en/novelpub.js | 5 +- src/sources/sources.js | 2 + src/sources/sources.json | 7 ++ 4 files changed, 159 insertions(+), 3 deletions(-) create mode 100644 src/sources/en/bestlightnovel.js diff --git a/src/sources/en/bestlightnovel.js b/src/sources/en/bestlightnovel.js new file mode 100644 index 00000000..0bfc54d8 --- /dev/null +++ b/src/sources/en/bestlightnovel.js @@ -0,0 +1,148 @@ +import cheerio from 'react-native-cheerio'; +import {Status} from '../helpers/constants'; + +const sourceId = 95; +const sourceName = 'BestLightNovel'; + +const baseUrl = 'https://bestlightnovel.com/'; + +const popularNovels = async page => { + const totalPages = 2156; + const url = + baseUrl + 'novel_list?type=topview&category=all&state=all&page=1' + page; + + const result = await fetch(url); + const body = await result.text(); + + const loadedCheerio = cheerio.load(body); + + let novels = []; + + loadedCheerio('.update_item.list_category').each(function () { + const novelName = loadedCheerio(this).find('h3 > a').text(); + const novelCover = loadedCheerio(this).find('img').attr('src'); + const novelUrl = loadedCheerio(this).find('h3 > a').attr('href'); + + const novel = {sourceId, novelName, novelCover, novelUrl}; + + novels.push(novel); + }); + + return {totalPages, novels}; +}; + +const parseNovelAndChapters = async novelUrl => { + const url = novelUrl; + + const result = await fetch(url); + const body = await result.text(); + + let loadedCheerio = cheerio.load(body); + + let novel = { + sourceId, + sourceName, + url, + novelUrl, + novelName: '', + novelCover: '', + author: '', + status: Status.UNKNOWN, + genre: '', + summary: '', + chapters: [], + }; + + novel.novelName = loadedCheerio('.truyen_info_right h1').text().trim(); + novel.novelCover = loadedCheerio('.info_image img').attr('src'); + novel.summary = loadedCheerio('#noidungm').text()?.trim(); + novel.author = loadedCheerio( + '#main_body > div.cotgiua > div.truyen_info_wrapper > div.truyen_info > div.entry-header > div.truyen_if_wrap > ul > li:nth-child(2) > a', + ) + .text() + ?.trim(); + + let status = loadedCheerio( + '#main_body > div.cotgiua > div.truyen_info_wrapper > div.truyen_info > div.entry-header > div.truyen_if_wrap > ul > li:nth-child(4) > a', + ) + .text() + ?.trim(); + + novel.status = + status === 'ONGOING' + ? Status.ONGOING + : status === 'COMPLETED' + ? Status.COMPLETED + : Status.UNKNOWN; + + let novelChapters = []; + + loadedCheerio('.chapter-list div.row').each(function () { + const chapterName = loadedCheerio(this).find('a').text().trim(); + const releaseDate = loadedCheerio(this) + .find('span:nth-child(2)') + .text() + .trim(); + const chapterUrl = loadedCheerio(this).find('a').attr('href'); + + novelChapters.push({chapterName, releaseDate, chapterUrl}); + }); + + novel.chapters = novelChapters.reverse(); + + return novel; +}; + +const parseChapter = async (novelUrl, chapterUrl) => { + const url = chapterUrl; + + const result = await fetch(url); + const body = await result.text(); + + let loadedCheerio = cheerio.load(body); + + const chapterName = loadedCheerio('h1.name_chapter').text(); + const chapterText = loadedCheerio('#vung_doc').html(); + + const chapter = { + sourceId, + novelUrl, + chapterUrl, + chapterName, + chapterText, + }; + + return chapter; +}; + +const searchNovels = async searchTerm => { + const url = `${baseUrl}search_novels/${searchTerm}`; + + const result = await fetch(url); + const body = await result.text(); + + let loadedCheerio = cheerio.load(body); + + let novels = []; + + loadedCheerio('.update_item.list_category').each(function () { + const novelName = loadedCheerio(this).find('h3 > a').text(); + const novelCover = loadedCheerio(this).find('img').attr('src'); + const novelUrl = loadedCheerio(this).find('h3 > a').attr('href'); + + const novel = {sourceId, novelName, novelCover, novelUrl}; + + novels.push(novel); + }); + + return novels; +}; + +const BestLightNovel = { + popularNovels, + parseNovelAndChapters, + parseChapter, + searchNovels, +}; + +export default BestLightNovel; diff --git a/src/sources/en/novelpub.js b/src/sources/en/novelpub.js index 03782586..056eae6b 100644 --- a/src/sources/en/novelpub.js +++ b/src/sources/en/novelpub.js @@ -97,7 +97,6 @@ const parseNovelAndChapters = async novelUrl => { for (let i = 1; i <= lastPage; i++) { const chaptersUrl = `${baseUrl}novel/the-legendary-mechanic-novel/chapters/page-${i}`; - console.log(chaptersUrl); const chaptersRequest = await fetch(chaptersUrl); const chaptersHtml = await chaptersRequest.text(); @@ -118,9 +117,9 @@ const parseNovelAndChapters = async novelUrl => { baseUrl + loadedCheerio(this).find('a').attr('href').substring(1); novelChapters.push({chapterName, releaseDate, chapterUrl}); - - delay(1000); }); + + delay(1000); } novel.chapters = novelChapters; diff --git a/src/sources/sources.js b/src/sources/sources.js index 3bd76756..ac08077d 100644 --- a/src/sources/sources.js +++ b/src/sources/sources.js @@ -93,6 +93,7 @@ import NitroScansScraper from './en/nitroscans'; import NovelForestScraper from './en/novelforest'; import RanobeLibScraper from './ru/ranobelib'; import NovelPubScraper from './en/novelpub'; +import BestLightNovel from './en/bestlightnovel'; export const getSource = sourceId => { const scrapers = { @@ -189,6 +190,7 @@ export const getSource = sourceId => { 92: NovelForestScraper, 93: RanobeLibScraper, 94: NovelPubScraper, + 95: BestLightNovel, }; return scrapers[sourceId]; diff --git a/src/sources/sources.json b/src/sources/sources.json index 455f43cb..0b3db3e9 100644 --- a/src/sources/sources.json +++ b/src/sources/sources.json @@ -649,5 +649,12 @@ "sourceName": "NovelPub", "icon": "https://github.com/LNReader/lnreader-sources/blob/main/src/en/novelpub/icon.png?raw=true", "lang": "English" + }, + { + "sourceId": 95, + "url": "https://www.bestlightnovel.com/", + "sourceName": "BestLightNovel", + "icon": "https://github.com/LNReader/lnreader-sources/blob/main/src/en/bestlightnovel/icon.png?raw=true", + "lang": "English" } ]