From b26d1129dede72f0a74ec937b921fa8163931ec5 Mon Sep 17 00:00:00 2001 From: uy/sun Date: Sun, 28 Jan 2024 20:22:43 +0800 Subject: [PATCH] Chinese: support showLatestNovels (#733) * improve: better chapterText * feat: support latest page --- plugins/chinese/69shu.ts | 50 ++++++++++++++++-------------------- plugins/chinese/69xinshu.ts | 46 ++++++++++++--------------------- plugins/chinese/linovelib.ts | 29 ++++++++++----------- 3 files changed, 53 insertions(+), 72 deletions(-) diff --git a/plugins/chinese/69shu.ts b/plugins/chinese/69shu.ts index 9fbb21a..d2ab6a9 100644 --- a/plugins/chinese/69shu.ts +++ b/plugins/chinese/69shu.ts @@ -9,21 +9,26 @@ class Shu69 implements Plugin.PluginBase { name = "69书吧"; icon = "src/cn/69shu/icon.png"; site = "https://www.69shu.xyz"; - version = "0.1.0"; + version = "0.2.0"; async popularNovels( pageNo: number, - { filters }: Plugin.PopularNovelsOptions + { + showLatestNovels, + filters, + }: Plugin.PopularNovelsOptions ): Promise { let url: string; - if (filters.sort.value === 'none') { + if (showLatestNovels) { + url = `${this.site}/rank/lastupdate/${pageNo}.html`; + } else if (filters.sort.value === 'none') { url = `${this.site}/rank/${filters.rank.value}/${pageNo}.html`; } else { url = `${this.site}/sort/${filters.sort.value}/${pageNo}.html`; } const body = await fetchText(url); - if (body === '') throw Error('无法获取小说内容,请检查网络'); + if (body === '') throw Error('无法获取小说列表,请检查网络'); const loadedCheerio = parseHTML(body); @@ -116,20 +121,28 @@ class Shu69 implements Plugin.PluginBase { } async parseChapter(chapterUrl: string): Promise { - const url = chapterUrl; - const body = await fetchText(url); + const body = await fetchText(chapterUrl); const loadedCheerio = parseHTML(body); - const chapterText = loadedCheerio('#chaptercontent').html() || ''; + const chapterText = loadedCheerio('#chaptercontent p') + .map((i, el) => loadedCheerio(el).text()) + .get() + // remove empty lines and 69shu ads + .map((line: string) => line.trim()) + .filter((line: string) => line !== '' && !line.includes('69书吧')) + .map((line: string) => `

${line}

`) + .join('\n'); return chapterText; }; async searchNovels( searchTerm: string, - pageNo?: number | undefined + pageNo: number ): Promise { + if (pageNo > 1) return []; + const searchUrl = `${this.site}/search`; const formData = new FormData(); formData.append('searchkey', searchTerm); @@ -138,8 +151,7 @@ class Shu69 implements Plugin.PluginBase { method: 'post', body: formData, }); - if (body === '') throw Error('无法获取小说内容,请检查网络'); - + if (body === '') throw Error('无法获取搜索结果,请检查网络'); let loadedCheerio = parseHTML(body); @@ -174,21 +186,13 @@ class Shu69 implements Plugin.PluginBase { value: "allvisit", options: [ { label: "总排行榜", value: "allvisit" }, - { label: "月排行榜", value: "monthvisit" }, - { label: "周排行榜", value: "weekvisit" }, - { label: "日排行榜", value: "dayvisit" }, - { label: "收藏榜", value: "goodnum" }, - { label: "字数榜", value: "words" }, - { label: "推荐榜", value: "allvote" }, - { label: "新书榜", value: "postdate" }, - { label: "更新榜", value: "lastupdate" }, ], type: FilterTypes.Picker, @@ -198,25 +202,15 @@ class Shu69 implements Plugin.PluginBase { value: "none", options: [ { label: "无", value: "none" }, - { label: "全部", value: "all" }, - { label: "玄幻", value: "xuanhuan" }, - { label: "仙侠", value: "xianxia" }, - { label: "都市", value: "dushi" }, - { label: "历史", value: "lishi" }, - { label: "游戏", value: "youxi" }, - { label: "科幻", value: "kehuan" }, - { label: "灵异", value: "kongbu" }, - { label: "言情", value: "nvsheng" }, - { label: "其它", value: "qita" }, ], type: FilterTypes.Picker, diff --git a/plugins/chinese/69xinshu.ts b/plugins/chinese/69xinshu.ts index 14a0179..133a8a8 100644 --- a/plugins/chinese/69xinshu.ts +++ b/plugins/chinese/69xinshu.ts @@ -10,7 +10,7 @@ class XinShu69 implements Plugin.PluginBase { name = "69书吧"; icon = "src/cn/69xinshu/icon.png"; site = "https://www.69xinshu.com"; - version = "0.1.0"; + version = "0.1.1"; async popularNovels( pageNo: number, @@ -24,7 +24,7 @@ class XinShu69 implements Plugin.PluginBase { } const body = await fetchText(url, {}, 'gbk'); - if (body === '') throw Error('无法获取小说内容,请检查网络'); + if (body === '') throw Error('无法获取小说列表,请检查网络'); const loadedCheerio = parseHTML(body); @@ -119,36 +119,36 @@ class XinShu69 implements Plugin.PluginBase { } async parseChapter(chapterUrl: string): Promise { - const url = chapterUrl; - const body = await fetchText(url, {}, 'gbk'); + const body = await fetchText(chapterUrl, {}, 'gbk'); const loadedCheerio = parseHTML(body); - const chapterText = loadedCheerio('div.txtnav').prop('innerText') ?? ''; - // remove empty lines - let lines = chapterText.split('\n').map((line: string) => line.trim()).filter((line: string) => line.length > 0); - // remove the first two lines which are the chapter name and author name - lines = lines.slice(2); + const chapterText = (loadedCheerio('div.txtnav').prop('innerText') ?? '') + .split('\n') + // remove empty lines + .map((line: string) => line.trim()) + .filter((line: string) => line !== '') + // remove the first two lines which are the chapter name and author name + .slice(2) + .map((line: string) => `

${line}

`) + .join('\n'); - let parsedText = ''; - for (let line of lines) { - parsedText += `

${line}

`; - } - - return parsedText; + return chapterText; }; async searchNovels( searchTerm: string, - pageNo?: number | undefined + pageNo: number ): Promise { + if (pageNo > 1) return []; + const searchUrl = `${this.site}/modules/article/search.php`; const formData = new FormData(); formData.append('searchkey', encode(searchTerm, 'gbk')); formData.append('searchtype', 'all'); const body = await fetchText(searchUrl, { method: 'post', body: formData, }, 'gbk'); - if (body === '') throw Error('无法获取小说内容,请检查网络'); + if (body === '') throw Error('无法获取搜索结果,请检查网络'); let loadedCheerio = parseHTML(body); @@ -179,29 +179,17 @@ class XinShu69 implements Plugin.PluginBase { value: "0", options: [ { label: "全部分类", value: "0" }, - { label: "言情小说", value: "3" }, - { label: "玄幻魔法", value: "1" }, - { label: "修真武侠", value: "2" }, - { label: "穿越时空", value: "11" }, - { label: "都市小说", value: "9" }, - { label: "历史军事", value: "4" }, - { label: "游戏竞技", value: "5" }, - { label: "科幻空间", value: "6" }, - { label: "悬疑惊悚", value: "7" }, - { label: "同人小说", value: "8" }, - { label: "官场职场", value: "10" }, - { label: "青春校园", value: "12" }, ], type: FilterTypes.Picker, diff --git a/plugins/chinese/linovelib.ts b/plugins/chinese/linovelib.ts index afac987..77e2395 100644 --- a/plugins/chinese/linovelib.ts +++ b/plugins/chinese/linovelib.ts @@ -9,14 +9,20 @@ class Linovelib implements Plugin.PluginBase { name = "Linovelib"; icon = "src/cn/linovelib/icon.png"; site = "https://www.bilinovel.com"; - version = "1.0.2"; + version = "1.1.0"; async popularNovels( pageNo: number, - { filters }: Plugin.PopularNovelsOptions + { + showLatestNovels, + filters, + }: Plugin.PopularNovelsOptions ): Promise { - const url = `${this.site}/top/${filters.rank.value}/${pageNo}.html`; + const rank = showLatestNovels ? 'lastupdate' : filters.rank.value; + const url = `${this.site}/top/${rank}/${pageNo}.html`; + const body = await fetchText(url); + if (body === '') throw Error('无法获取小说列表,请检查网络'); const loadedCheerio = parseHTML(body); @@ -47,7 +53,9 @@ class Linovelib implements Plugin.PluginBase { async parseNovelAndChapters(novelUrl: string): Promise { const url = novelUrl; + const body = await fetchText(url); + if (body === '') throw Error('无法获取小说内容,请检查网络'); let loadedCheerio = parseHTML(body); @@ -427,10 +435,12 @@ class Linovelib implements Plugin.PluginBase { async searchNovels( searchTerm: string, - pageNo?: number | undefined + pageNo: number ): Promise { const url = `${this.site}/search/${encodeURI(searchTerm)}_${pageNo}.html`; + const body = await fetchText(url); + if (body === '') throw Error('无法获取搜索结果,请检查网络'); const pageCheerio = parseHTML(body); @@ -529,27 +539,16 @@ class Linovelib implements Plugin.PluginBase { value: "monthvisit", options: [ { label: "月点击榜", value: "monthvisit" }, - { label: "周点击榜", value: "weekvisit" }, - { label: "月推荐榜", value: "monthvote" }, - { label: "周推荐榜", value: "weekvote" }, - { label: "月鲜花榜", value: "monthflower" }, - { label: "周鲜花榜", value: "weekflower" }, - { label: "月鸡蛋榜", value: "monthegg" }, - { label: "周鸡蛋榜", value: "weekegg" }, - { label: "最近更新", value: "lastupdate" }, - { label: "最新入库", value: "postdate" }, - { label: "收藏榜", value: "goodnum" }, - { label: "新书榜", value: "newhot" }, ], type: FilterTypes.Picker,