diff --git a/src/sources/id/sakuranovel.js b/src/sources/id/sakuranovel.js new file mode 100644 index 00000000..e20c0e34 --- /dev/null +++ b/src/sources/id/sakuranovel.js @@ -0,0 +1,143 @@ +import cheerio from 'react-native-cheerio'; + +const sourceId = 103; +const sourceName = 'SakuraNovel'; + +const baseUrl = 'https://sakuranovel.id/'; + +const popularNovels = async page => { + const totalPages = 8; + const url = `${baseUrl}advanced-search/page/${page}/?title&author&yearx&status&type&order=rating&country%5B0%5D=china&country%5B1%5D=jepang&country%5B2%5D=unknown`; + + const result = await fetch(url); + const body = await result.text(); + + const loadedCheerio = cheerio.load(body); + + let novels = []; + + loadedCheerio('.flexbox2-item').each(function () { + const novelName = loadedCheerio(this) + .find('.flexbox2-title span') + .first() + .text(); + const novelCover = loadedCheerio(this).find('img').attr('data-src'); + const novelUrl = loadedCheerio(this) + .find('.flexbox2-content > a') + .attr('href'); + + const novel = {sourceId, novelName, novelCover, novelUrl}; + + novels.push(novel); + }); + + return {totalPages, novels}; +}; + +const parseNovelAndChapters = async novelUrl => { + const result = await fetch(novelUrl); + const body = await result.text(); + + let loadedCheerio = cheerio.load(body); + + let novel = { + sourceId, + sourceName, + url: novelUrl, + novelUrl, + novelName: '', + novelCover: '', + author: null, + status: null, + genre: null, + summary: null, + chapters: [], + }; + + novel.novelName = loadedCheerio('.series-title h2').text().trim(); + + novel.novelCover = loadedCheerio('.series-thumb img').attr('data-src'); + + novel.summary = loadedCheerio('.series-synops').text().trim(); + + let chapters = []; + + loadedCheerio('.series-chapterlist li').each(function () { + const chapterName = loadedCheerio(this) + .find('a span') + .first() + .text() + .replace(`${novel.novelName} – `, '') + .replace('Bahasa Indonesia', '') + .trim(); + const releaseDate = loadedCheerio(this) + .find('a span') + .first() + .next() + .text(); + const chapterUrl = loadedCheerio(this).find('a').attr('href'); + + chapters.push({chapterName, releaseDate, chapterUrl}); + }); + + novel.chapters = chapters.reverse(); + + return novel; +}; + +const parseChapter = async (novelUrl, chapterUrl) => { + const result = await fetch(chapterUrl); + const body = await result.text(); + + let loadedCheerio = cheerio.load(body); + + const chapterName = loadedCheerio('.title-chapter').text(); + const chapterText = loadedCheerio('.reader-areas').html(); + + const chapter = { + sourceId, + novelUrl, + chapterUrl, + chapterName, + chapterText, + }; + + return chapter; +}; + +const searchNovels = async searchTerm => { + const url = `${baseUrl}?s=${searchTerm}`; + + const result = await fetch(url); + const body = await result.text(); + + let loadedCheerio = cheerio.load(body); + + let novels = []; + + loadedCheerio('.flexbox2-item').each(function () { + const novelName = loadedCheerio(this) + .find('.flexbox2-title span') + .first() + .text(); + const novelCover = loadedCheerio(this).find('img').attr('data-src'); + const novelUrl = loadedCheerio(this) + .find('.flexbox2-content > a') + .attr('href'); + + const novel = {sourceId, novelName, novelCover, novelUrl}; + + novels.push(novel); + }); + + return novels; +}; + +const SakuraNovelScraper = { + popularNovels, + parseNovelAndChapters, + parseChapter, + searchNovels, +}; + +export default SakuraNovelScraper; diff --git a/src/sources/sources.js b/src/sources/sources.js index fc2df10e..a5114718 100644 --- a/src/sources/sources.js +++ b/src/sources/sources.js @@ -102,6 +102,7 @@ import { NovelmtScraper, ReadwnScraper, } from './multisrc/readwn/ReadwnGenerator'; +import SakuraNovelScraper from './id/sakuranovel'; export const getSource = sourceId => { const scrapers = { @@ -205,6 +206,7 @@ export const getSource = sourceId => { 99: NovelmtScraper, 100: LtnovelScraper, 101: ArMTLScraper, + 103: SakuraNovelScraper, }; return scrapers[sourceId]; diff --git a/src/sources/sources.json b/src/sources/sources.json index 3cc84aa0..0152014b 100644 --- a/src/sources/sources.json +++ b/src/sources/sources.json @@ -698,5 +698,12 @@ "sourceName": "ArMTL", "icon": "https://github.com/LNReader/lnreader-sources/blob/main/multisrc/madara/icons/armtl.png?raw=true", "lang": "Arabic" + }, + { + "sourceId": 103, + "url": "https://sakuranovel.id/", + "sourceName": "SakuraNovel", + "icon": "https://github.com/LNReader/lnreader-sources/blob/main/src/id/sakuranovel/icon.png?raw=true", + "lang": "Indonesian" } ]