From f14dad2808712ebf70258bb3b0be6af10e10355d Mon Sep 17 00:00:00 2001 From: K1ngfish3r Date: Mon, 18 Mar 2024 15:48:01 +0800 Subject: [PATCH] Added ranboes, indowebnovel & Fixed Pawread, NovelUpdates (#829) * pwaread * novelupdates search * ranobes * quick fix + indowebnovel --- icons/src/en/ranobes/icon.png | Bin 0 -> 12633 bytes plugins/english/novelupdates.ts | 19 ++- plugins/english/pawread.ts | 19 +-- plugins/english/ranobes.ts | 184 ++++++++++++++++++++++ plugins/indonesian/indowebnovel.broken.ts | 146 ----------------- plugins/indonesian/indowebnovel.ts | 119 ++++++++++++++ 6 files changed, 327 insertions(+), 160 deletions(-) create mode 100644 icons/src/en/ranobes/icon.png create mode 100644 plugins/english/ranobes.ts delete mode 100644 plugins/indonesian/indowebnovel.broken.ts create mode 100644 plugins/indonesian/indowebnovel.ts diff --git a/icons/src/en/ranobes/icon.png b/icons/src/en/ranobes/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..55f4b9fdb808ef87b4c7f28483744da4630cbce8 GIT binary patch literal 12633 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 Hu0mjf0}uXA literal 0 HcmV?d00001 diff --git a/plugins/english/novelupdates.ts b/plugins/english/novelupdates.ts index 88ba4fa..5be0dfc 100644 --- a/plugins/english/novelupdates.ts +++ b/plugins/english/novelupdates.ts @@ -6,7 +6,7 @@ import { Plugin } from "@typings/plugin"; class NovelUpdates implements Plugin.PluginBase { id = "novelupdates"; name = "Novel Updates"; - version = "0.5.0"; + version = "0.5.1"; icon = "src/en/novelupdates/icon.png"; site = "https://www.novelupdates.com/"; @@ -90,11 +90,15 @@ class NovelUpdates implements Plugin.PluginBase { const novel: Plugin.SourceNovel = { path: novelPath, name: loadedCheerio(".seriestitlenu").text() || "Untitled", - cover: loadedCheerio(".seriesimg > img").attr("src"), - author: loadedCheerio("#showauthors").text().trim(), + cover: loadedCheerio('.wpb_wrapper img').attr('src'), chapters: [], }; + novel.author = loadedCheerio('#authtag') + .map((i, el) => loadedCheerio(el).text().trim()) + .toArray() + .join(', '); + novel.genres = loadedCheerio("#seriesgenre") .children("a") .map((i, el) => loadedCheerio(el).text()) @@ -180,6 +184,8 @@ class NovelUpdates implements Plugin.PluginBase { let isAnomalously = result.url.toLowerCase().includes('anotivereads'); + let kofi = result.url.toLowerCase().includes('ko-fi'); + let isBlossomTranslation = result.url .toLowerCase() .includes('blossomtranslation'); @@ -248,6 +254,10 @@ class NovelUpdates implements Plugin.PluginBase { chapterText = loadedCheerio('.manga-child-content').html()!; } else if (isAnomalously) { chapterText = loadedCheerio('#comic').html()!; + } else if (kofi) { + chapterText = loadedCheerio('script:contains("shadowDom.innerHTML")') + .html() + ?.match(/shadowDom\.innerHTML \+= '( r.json()); @@ -320,10 +330,9 @@ class NovelUpdates implements Plugin.PluginBase { } async searchNovels(searchTerm: string, page: number): Promise { - const url =`${this.site}page/${page}/?s=${searchTerm}&post_type=seriesplans`; + const url = this.site + '?s=' + searchTerm.replace(/\s+/g, '+') + '&post_type=seriesplans'; const result = await fetchApi(url); const body = await result.text(); - const loadedCheerio = parseHTML(body); return this.parseNovels(loadedCheerio); } diff --git a/plugins/english/pawread.ts b/plugins/english/pawread.ts index a890523..6f6c75f 100644 --- a/plugins/english/pawread.ts +++ b/plugins/english/pawread.ts @@ -1,4 +1,4 @@ -import { CheerioAPI, load, load as parseHTML } from "cheerio"; +import { CheerioAPI, load as parseHTML } from "cheerio"; import { fetchApi, fetchFile } from "@libs/fetch"; import { Plugin } from "@typings/plugin"; import { Filters, FilterTypes } from "@libs/filterInputs"; @@ -6,7 +6,7 @@ import { Filters, FilterTypes } from "@libs/filterInputs"; class PawRead implements Plugin.PluginBase { id = "pawread"; name = "PawRead"; - version = "1.1.0"; + version = "2.0.0"; icon = "src/en/pawread/icon.png"; site = "https://m.pawread.com/"; @@ -15,7 +15,7 @@ class PawRead implements Plugin.PluginBase { loadedCheerio(".list-comic, .itemBox").each((idx, ele) => { loadedCheerio(ele).find('.serialise').remove(); - const novelName = loadedCheerio(ele).find('a').text(); + const novelName = loadedCheerio(ele).find('a').text().trim(); const novelCover = loadedCheerio(ele).find('img').attr('src'); const novelUrl = loadedCheerio(ele).find('a').attr('href')?.slice(1); @@ -55,7 +55,7 @@ class PawRead implements Plugin.PluginBase { link += filters.sort.value; link += `/?page=${page}`; - const body = await fetchApi(link).then((r) => r.text()); + const body = await fetchApi(link).then((r) => r.text()); const loadedCheerio = parseHTML(body); return this.parseNovels(loadedCheerio); @@ -91,16 +91,17 @@ class PawRead implements Plugin.PluginBase { const chapter: Plugin.ChapterItem[] = []; loadedCheerio(".item-box").each((idx, ele) => { - const releaseDate = loadedCheerio(ele).find('span:last').text().trim(); - if (releaseDate === "Advanced Chapter") return; + const smallText = loadedCheerio(ele).find('span:last').text().trim(); + if (smallText === "Advanced Chapter") return; + const releaseDate = smallText.split('.').map(x => Number(x)); const chapterName = loadedCheerio(ele).find("span:first").text().trim(); - const chapterUrl = loadedCheerio(ele).attr("onclick")?.match(/\d+/); + const chapterUrl = loadedCheerio(ele).attr("onclick")?.match(/\d+/)![0]; if (!chapterUrl) return; chapter.push({ name: chapterName, - path: `${novelPath}${chapterUrl[0]}.html`, - releaseTime: new Date(releaseDate).toISOString(), + path: `${novelPath}${chapterUrl}.html`, + releaseTime: new Date(releaseDate[0], releaseDate[1], releaseDate[2]).toISOString(), }); }); diff --git a/plugins/english/ranobes.ts b/plugins/english/ranobes.ts new file mode 100644 index 0000000..13e82e9 --- /dev/null +++ b/plugins/english/ranobes.ts @@ -0,0 +1,184 @@ +import { CheerioAPI, load as parseHTML } from "cheerio"; +import { fetchApi, fetchFile } from "@libs/fetch"; +import { FilterTypes, Filters } from "@libs/filterInputs"; +import { Plugin } from "@typings/plugin"; + +interface ChapterEntry { + id: number; + title: string; + date: string; + link: string; +} + +class RanobesPlugin implements Plugin.PagePlugin { + id = 'ranobes'; + name = 'Ranobes'; + icon = 'src/en/ranobes/icon.png'; + site = 'https://ranobes.top'; + filters?: Filters | undefined; + version = '1.0.0'; + + async sleep (ms: number) { + return new Promise(resolve => setTimeout(resolve, ms)) + } + + parseNovels(loadedCheerio: CheerioAPI){ + const novels: Plugin.NovelItem[] = []; + + loadedCheerio('.short-cont').each((i,el) => { + const novelName = loadedCheerio(el).find('h2.title').text(); + const novelUrl = loadedCheerio(el).find('h2.title a').attr('href'); + const novelCover = loadedCheerio(el) + .find('figure') + .attr('style') + ?.replace(/.*url\((.*?)\)./g, '$1'); + + if (!novelUrl) return; + + const novel = { + name: novelName, + cover: novelCover, + path: novelUrl?.replace(this.site, ''), + } + novels.push(novel); + }); + return novels; + } + + parseChapters(data: {chapters: ChapterEntry[]}){ + const chapter: Plugin.ChapterItem[] = []; + data.chapters.map((item: ChapterEntry) => { + chapter.push({ + name: item.title, + releaseTime: new Date(item.date).toISOString(), + path: item.link.replace(this.site, ''), + }); + }); + return chapter.reverse(); + } + + async popularNovels( + page: number, + { showLatestNovels, filters }: Plugin.PopularNovelsOptions + ): Promise { + let link = `${this.site}/novels/page/${page}/`; + const body = await fetchApi(link).then((result) => + result.text() + ); + + const loadedCheerio = parseHTML(body); + return this.parseNovels(loadedCheerio); + } + + async parseNovel(novelPath: string): Promise { + const url = this.site + novelPath; + const result = await fetchApi(url); + const body = await result.text(); + + let loadedCheerio = parseHTML(body); + + const novel: Plugin.SourceNovel & { totalPages: number; } = { + path: novelPath, + name: loadedCheerio('.poster img').attr('alt') || "Untitled", + cover: this.site + loadedCheerio('.poster img').attr('src'), + author: loadedCheerio('[itemprop="creator"]').text(), + chapters: [], + totalPages: 1, + }; + + novel.summary = loadedCheerio('.moreless') + .find('br') + .replaceWith('\n') + .end() + .text() + .trim(); + + novel.status = loadedCheerio('li:contains("Status") span') + .text() === 'Ongoing' + ? 'Ongoing' + : 'Completed'; + + novel.genres = loadedCheerio('div#mc-fs-genre').text().trim(); + + let chapterListUrl = loadedCheerio('.read-continue:last').attr('href'); + + if (!chapterListUrl?.startsWith('http')) { + chapterListUrl = this.site + chapterListUrl; + } + + const chaptersHtmlToString = await fetchApi(chapterListUrl).then(r => r.text()); + const pageCheerio = parseHTML(chaptersHtmlToString); + + const json = pageCheerio('#dle-content main').next().html()!; + const data = JSON.parse(json.replace('window.__DATA__ =', '')); + novel.totalPages = Number(data.pages_count); + novel.chapters = this.parseChapters(data); + + return novel; + }; + + async parsePage(novelPath: string, page: string): Promise { + const pagePath = novelPath.split('-')[0]; + const firstUrl = this.site + + '/chapters' + + pagePath.replace('novels/', ''); + const pageUrl = firstUrl + '/page/' + page; + + const body = await fetchApi(firstUrl).then(r => r.text()); + + let loadedCheerio = parseHTML(body); + let json = loadedCheerio('#dle-content main').next().html()!; + let data = JSON.parse(json.replace('window.__DATA__ =', '')); + + const latestChapterUrl = data.chapters[0].link; + const latestChapterName = data.chapters[0].title; + const latestChapterDate = data.chapters[0].date; + + const latestChapter: Plugin.ChapterItem | undefined = latestChapterUrl ? { + path: latestChapterUrl.replace(this.site, ''), + name: latestChapterName, + releaseTime: new Date(latestChapterDate).toISOString(), + } : undefined + + await this.sleep(1000); + + const pageBody = await fetchApi(pageUrl).then(r => r.text()); + loadedCheerio = parseHTML(pageBody); + json = loadedCheerio('#dle-content main').next().html()!; + data = JSON.parse(json.replace('window.__DATA__ =', '')); + const chapters = this.parseChapters(data); + return { + chapters, + latestChapter + } + } + + async parseChapter(chapterPath: string): Promise { + const result = await fetchApi(this.site + chapterPath); + const body = await result.text(); + + const loadedCheerio = parseHTML(body); + + const chapterText = loadedCheerio('#arrticle').html() || ""; + + return chapterText; + }; + + async searchNovels( + searchTerm: string, + page: number + ): Promise { + let link = `${this.site}/search/${searchTerm}/page/${page}`; + + const body = await fetchApi(link).then(r => r.text()); + + const loadedCheerio = parseHTML(body); + return this.parseNovels(loadedCheerio) + }; + + async fetchImage(url: string): Promise { + return await fetchFile(url); + } + +} +export default new RanobesPlugin(); diff --git a/plugins/indonesian/indowebnovel.broken.ts b/plugins/indonesian/indowebnovel.broken.ts deleted file mode 100644 index 0126e06..0000000 --- a/plugins/indonesian/indowebnovel.broken.ts +++ /dev/null @@ -1,146 +0,0 @@ -import { load as parseHTML } from "cheerio"; -import { fetchApi, fetchFile } from "@libs/fetch"; -import { Plugin } from "@typings/plugin"; -import { defaultCover } from "@libs/defaultCover"; -import { Filters } from "@libs/filterInputs"; - -class IndoWebNovel implements Plugin.PluginBase { - id = "IDWN.id"; - name = "IndoWebNovel"; - icon = "src/id/indowebnovel/icon.png"; - site = "https://indowebnovel.id/id/"; - filters?: Filters | undefined; - version = "1.0.0"; - baseUrl = this.site - async popularNovels(pageNo: number, options: Plugin.PopularNovelsOptions): Promise { - const url = `${this.baseUrl}daftar-novel/`; - - const result = await fetchApi(url); - const body = await result.text(); - - const loadedCheerio = parseHTML(body); - - let novels: Plugin.NovelItem[] = []; - - loadedCheerio(".novellist-blc li").each(function () { - const novelName = loadedCheerio(this).find("a").text(); - const novelCover = defaultCover; - const novelUrl = loadedCheerio(this).find("a").attr("href"); - - if (!novelUrl || !novelName) return; - - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; - } - async parseNovelAndChapters(novelUrl: string): Promise { - const url = novelUrl; - - const result = await fetchApi(url); - const body = await result.text(); - - let loadedCheerio = parseHTML(body); - - let novel: Plugin.SourceNovel = { - url, - name: "", - cover: "", - author: "", - status: "", - genres: "", - summary: "", - chapters: [], - }; - - novel.name = loadedCheerio(".series-title").text().trim(); - - novel.cover = loadedCheerio(".series-thumb > img").attr("src"); - - novel.summary = loadedCheerio(".series-synops").text().trim(); - - novel.status = loadedCheerio(".status").text().trim(); - - const genres: string[] = []; - - loadedCheerio(".series-genres").each(function () { - genres.push(loadedCheerio(this).find("a").text().trim()); - }); - - novel.genres = genres.join(","); - - let chapters: Plugin.ChapterItem[] = []; - - loadedCheerio(".series-chapterlist li").each(function () { - const chapterName = loadedCheerio(this).find("a").text().trim(); - const releaseDate = null; - const chapterUrl = loadedCheerio(this).find("a").attr("href"); - - if (!chapterUrl) return; - - chapters.push({ - name: chapterName, - releaseTime: releaseDate, - url: chapterUrl, - }); - }); - - novel.chapters = chapters.reverse(); - - return novel; - } - async parseChapter(chapterUrl: string): Promise { - const url = chapterUrl; - - const result = await fetchApi(url); - const body = await result.text(); - - let loadedCheerio = parseHTML(body); - - const chapterText = loadedCheerio(".readerss").html() || ''; - - return chapterText; - } - async searchNovels(searchTerm: string, pageNo: number): Promise { - const url = `${this.baseUrl}daftar-novel/`; - - const result = await fetchApi(url); - const body = await result.text(); - - const loadedCheerio = parseHTML(body); - - let novels: Plugin.NovelItem[] = []; - - loadedCheerio(".novellist-blc li").each(function () { - const novelName = loadedCheerio(this).find("a").text(); - const novelCover = defaultCover; - const novelUrl = loadedCheerio(this).find("a").attr("href"); - - if (!novelUrl) return; - - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - if (novelName.toLowerCase().includes(searchTerm.toLowerCase())) { - novels.push(novel); - } - }); - - return novels; - } - async fetchImage(url: string): Promise { - return fetchFile(url); - } - -} - -export default new IndoWebNovel(); diff --git a/plugins/indonesian/indowebnovel.ts b/plugins/indonesian/indowebnovel.ts new file mode 100644 index 0000000..2f5e838 --- /dev/null +++ b/plugins/indonesian/indowebnovel.ts @@ -0,0 +1,119 @@ +import { CheerioAPI, load, load as parseHTML } from "cheerio"; +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Plugin } from "@typings/plugin"; +import { defaultCover } from "@libs/defaultCover"; +import { Filters } from "@libs/filterInputs"; + +class IndoWebNovel implements Plugin.PluginBase { + id = "IDWN.id"; + name = "IndoWebNovel"; + icon = "src/id/indowebnovel/icon.png"; + site = "https://indowebnovel.id/id/"; + filters?: Filters | undefined; + version = "1.0.0"; + parseNovels(loadedCheerio:CheerioAPI, searchTerm?: string) { + let novels: Plugin.NovelItem[] = []; + + loadedCheerio(".novellist-blc li").each((i,el) => { + const novelName = loadedCheerio(el).find("a").text(); + const novelCover = defaultCover; + const novelUrl = loadedCheerio(el).find("a").attr("href"); + + if (!novelUrl || !novelName) return; + + const novel = { + name: novelName, + cover: novelCover, + path: novelUrl.replace(this.site, ''), + }; + + novels.push(novel); + }); + + if (searchTerm) { + novels = novels.filter((novel) => + novel.name.toLowerCase().includes(searchTerm.toLowerCase()) + ); + } + return novels; + }; + + async popularNovels(pageNo: number, options: Plugin.PopularNovelsOptions): Promise { + const url = `${this.site}daftar-novel/`; + + const result = await fetchApi(url); + const body = await result.text(); + + const loadedCheerio = parseHTML(body); + return this.parseNovels(loadedCheerio) + } + + async parseNovel(novelPath: string): Promise { + const result = await fetchApi(this.site + novelPath); + const body = await result.text(); + + const loadedCheerio = parseHTML(body); + loadedCheerio(".series-synops div").remove(); + + const novel: Plugin.SourceNovel = { + path: novelPath, + name: loadedCheerio(".series-title").text().trim() || "Untitled", + cover: loadedCheerio(".series-thumb img").attr("src"), + author: loadedCheerio("ul.series-infolist b:contains('Author') +").text().trim(), + status: loadedCheerio(".status").text().trim(), + summary: loadedCheerio(".series-synops").text().trim(), + chapters: [], + }; + + novel.genres = loadedCheerio(".series-genres a") + .map((i,el) => loadedCheerio(el).text().trim()) + .toArray() + .join(','); + + const chapters: Plugin.ChapterItem[] = []; + + loadedCheerio(".series-chapterlist li").each((i,el) => { + const chapterName = loadedCheerio(el).find("a").text().trim(); + const chapterUrl = loadedCheerio(el).find("a").attr("href"); + + if (!chapterUrl) return; + + chapters.push({ + name: chapterName, + path: chapterUrl.replace(this.site, ''), + }); + }); + + novel.chapters = chapters.reverse(); + + return novel; + } + + async parseChapter(chapterPath: string): Promise { + const result = await fetchApi(this.site + chapterPath); + const body = await result.text(); + + const loadedCheerio = parseHTML(body); + + const chapterText = loadedCheerio(".readerss").html() || ''; + + return chapterText; + } + + async searchNovels(searchTerm: string, pageNo: number): Promise { + const url = `${this.site}daftar-novel/`; + + const result = await fetchApi(url); + const body = await result.text(); + + const loadedCheerio = parseHTML(body); + return this.parseNovels(loadedCheerio, searchTerm) + } + + async fetchImage(url: string): Promise { + return fetchFile(url); + } + +} + +export default new IndoWebNovel();