From a5f90eaf8be8743195bbef2deb6616eef24f19d0 Mon Sep 17 00:00:00 2001 From: Rajarshee Chatterjee Date: Wed, 21 Jul 2021 20:32:30 +0530 Subject: [PATCH] Add new sources --- src/redux/history/history.reducer.js | 14 +---- src/screens/Browse/BrowseSettings.js | 9 ++- src/screens/Chapter/Chapter.js | 15 ++++- src/screens/Chapter/readerStyleController.js | 6 -- .../components/Info/NovelDetailsComponents.js | 5 +- src/sources/helpers/constants.js | 5 ++ src/sources/helpers/parseDate.js | 28 +++++++++ .../multisrc/madara/MadaraGenerator.js | 58 +++++++++++++++++++ src/sources/multisrc/madara/MadaraScraper.js | 30 ++++++---- src/sources/sources.js | 14 +++++ src/sources/sources.json | 49 ++++++++++++++++ 11 files changed, 196 insertions(+), 37 deletions(-) create mode 100644 src/sources/helpers/constants.js create mode 100644 src/sources/helpers/parseDate.js diff --git a/src/redux/history/history.reducer.js b/src/redux/history/history.reducer.js index f0e49f76..b79e5dbe 100644 --- a/src/redux/history/history.reducer.js +++ b/src/redux/history/history.reducer.js @@ -1,9 +1,4 @@ -import { - CLEAR_HISTORY, - CLEAR_NOVEL_HISTORY, - GET_HISTORY, - LOAD_HISTORY, -} from "./history.types"; +import { CLEAR_HISTORY, GET_HISTORY, LOAD_HISTORY } from "./history.types"; const initialState = { history: [], @@ -18,13 +13,6 @@ const historyReducer = (state = initialState, action) => { return { ...state, loading: true }; case GET_HISTORY: return { ...state, history: payload, loading: false }; - // case CLEAR_NOVEL_HISTORY: - // return { - // ...state, - // history: state.history.filter( - // (item) => item.novelId !== payload.novelId - // ), - // }; case CLEAR_HISTORY: return { ...state, loading: false, history: [] }; default: diff --git a/src/screens/Browse/BrowseSettings.js b/src/screens/Browse/BrowseSettings.js index 0730f7da..b21df140 100644 --- a/src/screens/Browse/BrowseSettings.js +++ b/src/screens/Browse/BrowseSettings.js @@ -22,7 +22,14 @@ const BrowseSettings = ({ navigation }) => { const { filters = [], showMyAnimeList = true } = useSelector( (state) => state.sourceReducer ); - const languages = ["English", "Spanish", "Japanese", "Chinese", "Arabic"]; + const languages = [ + "English", + "Spanish", + "Japanese", + "Chinese", + "Arabic", + "Indonesia", + ]; const { searchAllSources = false } = useSettings(); diff --git a/src/screens/Chapter/Chapter.js b/src/screens/Chapter/Chapter.js index dae700aa..131294ab 100644 --- a/src/screens/Chapter/Chapter.js +++ b/src/screens/Chapter/Chapter.js @@ -299,13 +299,20 @@ const Chapter = ({ route, navigation }) => { { getChapter(chapterId); setLoading(true); @@ -314,7 +321,9 @@ const Chapter = ({ route, navigation }) => { /> Retry diff --git a/src/screens/Chapter/readerStyleController.js b/src/screens/Chapter/readerStyleController.js index 1a8ba040..2582b54c 100644 --- a/src/screens/Chapter/readerStyleController.js +++ b/src/screens/Chapter/readerStyleController.js @@ -31,9 +31,3 @@ export const readerLineHeight = (fontSize, lineHeightMultiplier) => { return lineHeight; }; - -export const errorTextColor = (val) => { - const textColor = val === 1 ? "rgba(255,255,255,0.7)" : "rgba(0,0,0,0.54)"; - - return textColor; -}; diff --git a/src/screens/Novel/components/Info/NovelDetailsComponents.js b/src/screens/Novel/components/Info/NovelDetailsComponents.js index f099f311..d392a48e 100644 --- a/src/screens/Novel/components/Info/NovelDetailsComponents.js +++ b/src/screens/Novel/components/Info/NovelDetailsComponents.js @@ -57,10 +57,7 @@ const NovelAuthor = ({ theme, children }) => ( const NovelInfo = ({ theme, children }) => ( {children} diff --git a/src/sources/helpers/constants.js b/src/sources/helpers/constants.js new file mode 100644 index 00000000..8762cf89 --- /dev/null +++ b/src/sources/helpers/constants.js @@ -0,0 +1,5 @@ +export const Status = { + ONGOING: "Ongoing", + COMPLETED: "Completed", + UNKNOWN: "Unknown", +}; diff --git a/src/sources/helpers/parseDate.js b/src/sources/helpers/parseDate.js new file mode 100644 index 00000000..b8bf19a4 --- /dev/null +++ b/src/sources/helpers/parseDate.js @@ -0,0 +1,28 @@ +import moment from "moment"; + +export const parseMadaraDate = (date) => { + let releaseDate = date; + + if (date.includes("ago")) { + let timeAgo = date; + releaseDate = new Date(); + + timeAgo = timeAgo.match(/\d+/)[0]; + + if (timeAgo.includes("hours ago") || timeAgo.includes("hour ago")) { + releaseDate.setHours(releaseDate.getHours() - timeAgo); + } + + if (timeAgo.includes("days ago") || timeAgo.includes("day ago")) { + releaseDate.setDate(releaseDate.getDate() - timeAgo); + } + + if (timeAgo.includes("months ago") || timeAgo.includes("month ago")) { + releaseDate.setMonth(releaseDate.getMonth() - timeAgo); + } + + releaseDate = moment(releaseDate).format("MMMM DD, YYYY"); + } + + return releaseDate; +}; diff --git a/src/sources/multisrc/madara/MadaraGenerator.js b/src/sources/multisrc/madara/MadaraGenerator.js index 3f3c6a6d..1e5edb03 100644 --- a/src/sources/multisrc/madara/MadaraGenerator.js +++ b/src/sources/multisrc/madara/MadaraGenerator.js @@ -12,6 +12,15 @@ const getPath = (extensionId) => { 45: { novels: "novel", novel: "novel", chapter: "novel" }, 46: { novels: "novel", novel: "novel", chapter: "novel" }, 47: { novels: "novel-list", novel: "novel", chapter: "novel" }, + 55: { novels: "manga", novel: "manga", chapter: "manga" }, + 56: { novels: "novel", novel: "novel", chapter: "novel" }, + 57: { novels: "series", novel: "series", chapter: "series" }, + 58: { novels: "novel", novel: "novel", chapter: "novel" }, + 59: { novels: "novel", novel: "novel", chapter: "novel" }, + 60: { novels: "novel", novel: "novel", chapter: "novel" }, + 61: { novels: "novel", novel: "novel", chapter: "novel" }, + 62: { novels: "novel", novel: "novel", chapter: "novel" }, + 63: { novels: "novel", novel: "novel", chapter: "novel" }, }; return path[extensionId]; @@ -86,3 +95,52 @@ export const DaoNovelScraper = new MadaraScraper( "DaoNovel", getPath(47) ); + +export const MostNovelScraper = new MadaraScraper( + 55, + "https://mostnovel.com/", + "MostNovel", + getPath(55) +); + +export const NovelMultiverseScraper = new MadaraScraper( + 56, + "https://www.novelmultiverse.com/", + "NovelMultiverse", + getPath(56) +); + +export const LightNovelHeavenScraper = new MadaraScraper( + 57, + "https://lightnovelheaven.com/", + "LightNovelHeaven", + getPath(57) +); + +export const LightNovelsHubScraper = new MadaraScraper( + 58, + "https://lightnovelshub.com/", + "LightNovelsHub", + getPath(58) +); + +export const ArNovelScraper = new MadaraScraper( + 59, + "https://arnovel.me/", + "ArNovel", + getPath(59) +); + +export const MeionNovelScraper = new MadaraScraper( + 60, + "https://meionovel.id/", + "MeionNovel", + getPath(60) +); + +export const WebNovelLoverScraper = new MadaraScraper( + 61, + "https://www.webnovelover.com/", + "WebNovelLover", + getPath(61) +); diff --git a/src/sources/multisrc/madara/MadaraScraper.js b/src/sources/multisrc/madara/MadaraScraper.js index 0a573910..bb590f56 100644 --- a/src/sources/multisrc/madara/MadaraScraper.js +++ b/src/sources/multisrc/madara/MadaraScraper.js @@ -1,5 +1,7 @@ import cheerio from "react-native-cheerio"; +import { Status } from "../../helpers/constants"; import { htmlToText } from "../../helpers/htmlToText"; +import { parseMadaraDate } from "../../helpers/parseDate"; class MadaraScraper { constructor(sourceId, baseUrl, sourceName, path) { @@ -28,7 +30,7 @@ class MadaraScraper { $(".manga-title-badges").remove(); - $(".page-item-detail").each(function (result) { + $(".page-item-detail").each(function () { const novelName = $(this).find(".post-title").text().trim(); let image = $(this).find("img"); const novelCover = image.attr("data-src") || image.attr("src"); @@ -76,9 +78,10 @@ class MadaraScraper { novel.novelCover = $(".summary_image > a > img").attr("data-src") || - $(".summary_image > a > img").attr("src"); + $(".summary_image > a > img").attr("src") || + "https://github.com/LNReader/lnreader-sources/blob/main/src/coverNotAvailable.png?raw=true"; - $(".post-content_item").each(function (result) { + $(".post-content_item").each(function () { const detailName = $(this) .find(".summary-heading > h5") .text() @@ -93,7 +96,9 @@ class MadaraScraper { novel.author = detail; break; case "Status": - novel.status = detail; + novel.status = detail.includes("OnGoing") + ? Status.ONGOING + : Status.COMPLETED; break; } }); @@ -116,21 +121,26 @@ class MadaraScraper { }); const text = await data.text(); - $ = cheerio.load(text); + if (text !== "0") { + $ = cheerio.load(text); + } - $(".wp-manga-chapter").each(function (result) { + $(".wp-manga-chapter").each(function () { const chapterName = $(this) .find("a") .text() .replace(/[\t\n]/g, "") .trim(); - const releaseDate = $(this) - .find("span") + let releaseDate = $(this) + .find("span.chapter-release-date") .text() - .replace("Free", "") .trim(); + if (releaseDate) { + releaseDate = parseMadaraDate(releaseDate); + } + const chapterUrl = $(this).find("a").attr("href").split("/")[5]; novelChapters.push({ chapterName, releaseDate, chapterUrl }); @@ -179,7 +189,7 @@ class MadaraScraper { let novels = []; let sourceId = this.sourceId; - $(".c-tabs-item__content").each(function (result) { + $(".c-tabs-item__content").each(function () { const novelName = $(this).find(".post-title").text().trim(); let image = $(this).find("img"); diff --git a/src/sources/sources.js b/src/sources/sources.js index d2aa4dd8..f5f2fb56 100644 --- a/src/sources/sources.js +++ b/src/sources/sources.js @@ -35,15 +35,22 @@ import ScribbleHubScraper from "./en/scribblehub"; import SyosetuScraper from "./jp/syosetu"; import LNMTLScraper from "./en/lnmtl"; import { + ArNovelScraper, DaoNovelScraper, FirstKissNovelScraper, FreeNovelScraper, + LightNovelHeavenScraper, + LightNovelsHubScraper, LunarLettersScraper, + MeionNovelScraper, + MostNovelScraper, NovelCakeScraper, + NovelMultiverseScraper, NovelsRockScraper, NovelTranslateScraper, SkyNovelScraper, SleepyTranslationsScraper, + WebNovelLoverScraper, ZinnNovelScraper, } from "./multisrc/madara/MadaraGenerator"; import WuxiaBlogScraper from "./en/wuxiablog"; @@ -111,6 +118,13 @@ export const getSource = (sourceId) => { 52: YushuboScraper, 53: KolNovelScraper, 54: RewayatArScraper, + 55: MostNovelScraper, + 56: NovelMultiverseScraper, + 57: LightNovelHeavenScraper, + 58: LightNovelsHubScraper, + 59: ArNovelScraper, + 60: MeionNovelScraper, + 61: WebNovelLoverScraper, }; return scrapers[sourceId]; diff --git a/src/sources/sources.json b/src/sources/sources.json index 964e3e60..76e016e3 100644 --- a/src/sources/sources.json +++ b/src/sources/sources.json @@ -369,5 +369,54 @@ "sourceName": "RewayatAr", "icon": "https://github.com/LNReader/lnreader-sources/blob/main/multisrc/wpmangastream/icons/rewayatar.png?raw=true", "lang": "Arabic" + }, + { + "sourceId": 55, + "url": "https://mostnovel.com/", + "sourceName": "MostNovel", + "icon": "https://github.com/LNReader/lnreader-sources/blob/main/multisrc/madara/icons/mostnovel.png?raw=true", + "lang": "English" + }, + { + "sourceId": 56, + "url": "https://www.novelmultiverse.com/", + "sourceName": "NovelMultiverse", + "icon": "https://github.com/LNReader/lnreader-sources/blob/main/multisrc/madara/icons/novelmultiverse.png?raw=true", + "lang": "English" + }, + { + "sourceId": 57, + "url": "https://lightnovelheaven.com/", + "sourceName": "LightNovelHeaven", + "icon": "https://github.com/LNReader/lnreader-sources/blob/main/multisrc/madara/icons/lightnovelHeaven.png?raw=true", + "lang": "English" + }, + { + "sourceId": 58, + "url": "https://lightnovelshub.com/", + "sourceName": "LightNovelsHub", + "icon": "https://github.com/LNReader/lnreader-sources/blob/main/multisrc/madara/icons/lightnovelshub.png?raw=true", + "lang": "English" + }, + { + "sourceId": 59, + "url": "https://arnovel.me/", + "sourceName": "ArNovel", + "icon": "https://github.com/LNReader/lnreader-sources/blob/main/multisrc/madara/icons/arnovel.png?raw=true", + "lang": "Arabic" + }, + { + "sourceId": 60, + "url": "https://meionovel.id/", + "sourceName": "MeioNovel", + "icon": "https://github.com/LNReader/lnreader-sources/blob/main/multisrc/madara/icons/meionovel.png?raw=true", + "lang": "Indonesia" + }, + { + "sourceId": 61, + "url": "https://www.webnovelover.com/", + "sourceName": "WebNovelLover", + "icon": "https://github.com/LNReader/lnreader-sources/blob/main/multisrc/madara/icons/webnovellovers.png?raw=true", + "lang": "English" } ]