diff --git a/lib/v2/56kog/class.js b/lib/v2/56kog/class.js new file mode 100644 index 0000000000..b3e0b678e0 --- /dev/null +++ b/lib/v2/56kog/class.js @@ -0,0 +1,10 @@ +const { rootUrl, fetchItems } = require('./util'); + +module.exports = async (ctx) => { + const { category = '1_1' } = ctx.params; + const limit = ctx.query.limit ? Number.parseInt(ctx.query.limit, 10) : 30; + + const currentUrl = new URL(`class/${category}.html`, rootUrl).href; + + ctx.state.data = await fetchItems(limit, currentUrl, ctx.cache.tryGet); +}; diff --git a/lib/v2/56kog/maintainer.js b/lib/v2/56kog/maintainer.js new file mode 100644 index 0000000000..7ad76cbaa9 --- /dev/null +++ b/lib/v2/56kog/maintainer.js @@ -0,0 +1,4 @@ +module.exports = { + '/class/:category?': ['nczitzk'], + '/top/:category?': ['nczitzk'], +}; diff --git a/lib/v2/56kog/radar.js b/lib/v2/56kog/radar.js new file mode 100644 index 0000000000..84bac8db17 --- /dev/null +++ b/lib/v2/56kog/radar.js @@ -0,0 +1,85 @@ +module.exports = { + '56kog.com': { + _name: '明月中文网', + '.': [ + { + title: '玄幻魔法', + docs: 'https://docs.rsshub.app/routes/reading#ming-yue-zhong-wen-wang-fen-lei', + source: ['/class/1_1.html'], + target: '/56kog/class/1_1', + }, + { + title: '武侠修真', + docs: 'https://docs.rsshub.app/routes/reading#ming-yue-zhong-wen-wang-fen-lei', + source: ['/class/2_1.html'], + target: '/56kog/class/2_1', + }, + { + title: '历史军事', + docs: 'https://docs.rsshub.app/routes/reading#ming-yue-zhong-wen-wang-fen-lei', + source: ['/class/4_1.html'], + target: '/56kog/class/4_1', + }, + { + title: '侦探推理', + docs: 'https://docs.rsshub.app/routes/reading#ming-yue-zhong-wen-wang-fen-lei', + source: ['/class/5_1.html'], + target: '/56kog/class/5_1', + }, + { + title: '网游动漫', + docs: 'https://docs.rsshub.app/routes/reading#ming-yue-zhong-wen-wang-fen-lei', + source: ['/class/6_1.html'], + target: '/56kog/class/6_1', + }, + { + title: '恐怖灵异', + docs: 'https://docs.rsshub.app/routes/reading#ming-yue-zhong-wen-wang-fen-lei', + source: ['/class/8_1.html'], + target: '/56kog/class/8_1', + }, + { + title: '都市言情', + docs: 'https://docs.rsshub.app/routes/reading#ming-yue-zhong-wen-wang-fen-lei', + source: ['/class/3_1.html'], + target: '/56kog/class/3_1', + }, + { + title: '科幻', + docs: 'https://docs.rsshub.app/routes/reading#ming-yue-zhong-wen-wang-fen-lei', + source: ['/class/7_1.html'], + target: '/56kog/class/7_1', + }, + { + title: '女生小说', + docs: 'https://docs.rsshub.app/routes/reading#ming-yue-zhong-wen-wang-fen-lei', + source: ['/class/9_1.html'], + target: '/56kog/class/9_1', + }, + { + title: '其他', + docs: 'https://docs.rsshub.app/routes/reading#ming-yue-zhong-wen-wang-fen-lei', + source: ['/class/10_1.html'], + target: '/56kog/class/10_1', + }, + { + title: '周点击榜', + docs: 'https://docs.rsshub.app/routes/reading#ming-yue-zhong-wen-wang-bang-dan', + source: ['/top/weekvisit_1.html'], + target: '/56kog/top/weekvisit', + }, + { + title: '总收藏榜', + docs: 'https://docs.rsshub.app/routes/reading#ming-yue-zhong-wen-wang-bang-dan', + source: ['/top/goodnum_1.html'], + target: '/56kog/top/goodnum', + }, + { + title: '最新入库', + docs: 'https://docs.rsshub.app/routes/reading#ming-yue-zhong-wen-wang-bang-dan', + source: ['/top/postdate_1.html'], + target: '/56kog/top/postdate', + }, + ], + }, +}; diff --git a/lib/v2/56kog/router.js b/lib/v2/56kog/router.js new file mode 100644 index 0000000000..1ddc345841 --- /dev/null +++ b/lib/v2/56kog/router.js @@ -0,0 +1,4 @@ +module.exports = (router) => { + router.get('/class/:category?', require('./class')); + router.get('/top/:category?', require('./top')); +}; diff --git a/lib/v2/56kog/templates/description.art b/lib/v2/56kog/templates/description.art new file mode 100644 index 0000000000..dccde741ae --- /dev/null +++ b/lib/v2/56kog/templates/description.art @@ -0,0 +1,32 @@ +{{ if images }} + {{ each images image }} + {{ if image?.src }} +
+ {{ image.alt }} +
+ {{ /if }} + {{ /each }} +{{ /if }} + +{{ if details }} + + + {{ each details detail }} + + + + + {{ /each }} + +
{{ detail.label }} + {{ if detail.value?.href && detail.value?.text }} + {{ detail.value.text }} + {{ else }} + {{ detail.value }} + {{ /if }} +
+{{ /if }} \ No newline at end of file diff --git a/lib/v2/56kog/top.js b/lib/v2/56kog/top.js new file mode 100644 index 0000000000..fa90ff4a57 --- /dev/null +++ b/lib/v2/56kog/top.js @@ -0,0 +1,10 @@ +const { rootUrl, fetchItems } = require('./util'); + +module.exports = async (ctx) => { + const { category = 'weekvisit' } = ctx.params; + const limit = ctx.query.limit ? Number.parseInt(ctx.query.limit, 10) : 30; + + const currentUrl = new URL(`top/${category.split(/_/)[0]}_1.html`, rootUrl).href; + + ctx.state.data = await fetchItems(limit, currentUrl, ctx.cache.tryGet); +}; diff --git a/lib/v2/56kog/util.js b/lib/v2/56kog/util.js new file mode 100644 index 0000000000..bacb4353e7 --- /dev/null +++ b/lib/v2/56kog/util.js @@ -0,0 +1,111 @@ +const got = require('@/utils/got'); +const cheerio = require('cheerio'); +const iconv = require('iconv-lite'); +const timezone = require('@/utils/timezone'); +const { parseDate } = require('@/utils/parse-date'); +const { art } = require('@/utils/render'); +const path = require('path'); + +const rootUrl = 'https://www.56kog.com'; + +const fetchItems = async (limit, currentUrl, tryGet) => { + const { data: response } = await got(currentUrl, { + responseType: 'buffer', + }); + + const $ = cheerio.load(iconv.decode(response, 'gbk')); + + let items = $('p.line') + .toArray() + .map((item) => { + item = $(item); + + const a = item.find('a'); + + return { + title: a.text(), + link: new URL(a.prop('href'), rootUrl).href, + author: item.find('span').last().text(), + }; + }); + + items = await Promise.all( + items.map((item) => + tryGet(item.link, async () => { + try { + const { data: detailResponse } = await got(item.link, { + responseType: 'buffer', + }); + + const content = cheerio.load(iconv.decode(detailResponse, 'gbk')); + + const details = content('div.mohe-content p') + .toArray() + .map((detail) => { + detail = content(detail); + const as = detail.find('a'); + + return { + label: detail.find('span.c-l-depths').text().split(/:/)[0], + value: + as.length === 0 + ? content( + detail + .contents() + .toArray() + .find((c) => c.nodeType === 3) + ) + .text() + .trim() + : { + href: new URL(as.first().prop('href'), rootUrl).href, + text: as.first().text().trim(), + }, + }; + }); + + const pubDate = details.find((detail) => detail.label === '更新').value; + + item.title = content('h1').contents().first().text(); + item.description = art(path.join(__dirname, 'templates/description.art'), { + images: [ + { + src: new URL(content('a.mohe-imgs img').prop('src'), rootUrl).href, + alt: item.title, + }, + ], + details, + }); + item.author = details.find((detail) => detail.label === '作者').value; + item.category = [details.find((detail) => detail.label === '状态').value, details.find((detail) => detail.label === '类型').value.text].filter(Boolean); + item.guid = `56kog-${item.link.match(/\/(\d+)\.html$/)[1]}#${pubDate}`; + item.pubDate = timezone(parseDate(pubDate), +8); + } catch { + // no-empty + } + + return item; + }) + ) + ); + + const icon = new URL('favicon.ico', rootUrl).href; + + return { + item: items.filter((item) => item.description).slice(0, limit), + title: $('title').text(), + link: currentUrl, + description: $('meta[name="description"]').prop('content'), + language: $('html').prop('lang'), + icon, + logo: icon, + subtitle: $('meta[name="keywords"]').prop('content'), + author: $('div.uni_footer a').text(), + allowEmpty: true, + }; +}; + +module.exports = { + rootUrl, + fetchItems, +}; diff --git a/website/docs/routes/reading.mdx b/website/docs/routes/reading.mdx index 553f8c2d13..858142e864 100644 --- a/website/docs/routes/reading.mdx +++ b/website/docs/routes/reading.mdx @@ -289,6 +289,28 @@ +## 明月中文网 {#ming-yue-zhong-wen-wang} + +### 分类 {#ming-yue-zhong-wen-wang-fen-lei} + + + | [玄幻魔法](https://www.56kog.com/class/1_1.html) | [武侠修真](https://www.56kog.com/class/2_1.html) | [历史军事](https://www.56kog.com/class/4_1.html) | [侦探推理](https://www.56kog.com/class/5_1.html) | [网游动漫](https://www.56kog.com/class/6_1.html) | + | ------------------------------------------------ | ------------------------------------------------ | ------------------------------------------------ | ------------------------------------------------ | ------------------------------------------------ | + | 1\_1 | 2\_1 | 4\_1 | 5\_1 | 6\_1 | + + | [恐怖灵异](https://www.56kog.com/class/8_1.html) | [都市言情](https://www.56kog.com/class/3_1.html) | [科幻](https://www.56kog.com/class/7_1.html) | [女生小说](https://www.56kog.com/class/9_1.html) | [其他](https://www.56kog.com/class/10_1.html) | + | ------------------------------------------------ | ------------------------------------------------ | -------------------------------------------- | ------------------------------------------------ | --------------------------------------------- | + | 8\_1 | 3\_1 | 7\_1 | 9\_1 | 10\_1 | + + +### 榜单 {#ming-yue-zhong-wen-wang-bang-dan} + + + | [周点击榜](https://www.56kog.com/top/weekvisit.html) | [总收藏榜](https://www.56kog.com/top/goodnum.html) | [最新 入库](https://www.56kog.com/top/postdate.html) | + | ---------------------------------------------------- | -------------------------------------------------- | ---------------------------------------------------- | + | weekvisit | goodnum | postdate | + + ## 起点 {#qi-dian} ### 章节 {#qi-dian-zhang-jie}