From 9b991a561d649dea5713bc0fceed1e44d08066e1 Mon Sep 17 00:00:00 2001 From: Ethan Shen Date: Sat, 22 Jan 2022 20:04:49 +0800 Subject: [PATCH] feat(route): add cnBeta (#8909) --- docs/new-media.md | 30 ++++++++++++++- lib/router.js | 4 +- lib/routes/cnbeta/home.js | 53 -------------------------- lib/routes/cnbeta/topic.js | 75 ------------------------------------- lib/v2/cnbeta/index.js | 15 ++++++++ lib/v2/cnbeta/maintainer.js | 5 +++ lib/v2/cnbeta/radar.js | 25 +++++++++++++ lib/v2/cnbeta/router.js | 4 ++ lib/v2/cnbeta/type.js | 42 +++++++++++++++++++++ lib/v2/cnbeta/utils.js | 27 +++++++++++++ 10 files changed, 148 insertions(+), 132 deletions(-) delete mode 100644 lib/routes/cnbeta/home.js delete mode 100644 lib/routes/cnbeta/topic.js create mode 100644 lib/v2/cnbeta/index.js create mode 100644 lib/v2/cnbeta/maintainer.js create mode 100644 lib/v2/cnbeta/radar.js create mode 100644 lib/v2/cnbeta/router.js create mode 100644 lib/v2/cnbeta/type.js create mode 100644 lib/v2/cnbeta/utils.js diff --git a/docs/new-media.md b/docs/new-media.md index 36d11458a..11af7ae7d 100644 --- a/docs/new-media.md +++ b/docs/new-media.md @@ -166,11 +166,37 @@ pageClass: routes ### 最新 - + + +::: tip 提示 + +最新的内容来源于 [官方 RSS](https://www.cnbeta.com/backend.php) + +::: + + + +### 分类 + + + +| 影视 | 音乐 | 游戏 | 动漫 | 趣闻 | 科学 | 软件 | +| ----- | ----- | ---- | ----- | ----- | ------- | ---- | +| movie | music | game | comic | funny | science | soft | + + ### 主题 - + + +::: tip 提示 + +完整的主题列表参见 [主题列表](https://www.cnbeta.com/topics.htm) + +::: + + ## Common App diff --git a/lib/router.js b/lib/router.js index ed658e7b1..624bdd175 100644 --- a/lib/router.js +++ b/lib/router.js @@ -1824,8 +1824,8 @@ router.get('/maoyan/upcoming', lazyloadRouteHandler('./routes/maoyan/upcoming')) router.get('/maoyan/hotComplete/:orderby?/:ascOrDesc?/:top?', lazyloadRouteHandler('./routes/maoyan/hotComplete')); // cnBeta -router.get('/cnbeta', lazyloadRouteHandler('./routes/cnbeta/home')); -router.get('/cnbeta/topic/:topic_id', lazyloadRouteHandler('./routes/cnbeta/topic')); +// router.get('/cnbeta', lazyloadRouteHandler('./routes/cnbeta/home')); +// router.get('/cnbeta/topic/:topic_id', lazyloadRouteHandler('./routes/cnbeta/topic')); // 国家退伍士兵信息 router.get('/gov/veterans/:type', lazyloadRouteHandler('./routes/gov/veterans/china')); diff --git a/lib/routes/cnbeta/home.js b/lib/routes/cnbeta/home.js deleted file mode 100644 index 2fbabc280..000000000 --- a/lib/routes/cnbeta/home.js +++ /dev/null @@ -1,53 +0,0 @@ -const got = require('@/utils/got'); -const cheerio = require('cheerio'); -const parser = require('@/utils/rss-parser'); - -module.exports = async (ctx) => { - const feed = await parser.parseURL('https://rss.cnbeta.com/'); - - const ProcessFeed = (data) => { - const $ = cheerio.load(data); - - // 移除6.18广告 - $('.article-global').remove(); - $('.article-topic').remove(); - - // 提取内容 - return $('.article-summary p').html() + '
' + $('.article-content').html(); - }; - - const items = await Promise.all( - feed.items - .filter((item) => item.author !== 'adam') - .map(async (item) => { - const cache = await ctx.cache.get(item.link); - if (cache) { - return Promise.resolve(JSON.parse(cache)); - } - - const response = await got({ - method: 'get', - url: item.link, - }); - - const description = ProcessFeed(response.data); - - const single = { - title: item.title, - description, - pubDate: item.pubDate, - link: item.link, - author: item.author, - }; - ctx.cache.set(item.link, JSON.stringify(single)); - return Promise.resolve(single); - }) - ); - - ctx.state.data = { - title: 'cnBeta', - link: 'https://www.cnbeta.com/', - description: feed.description, - item: items, - }; -}; diff --git a/lib/routes/cnbeta/topic.js b/lib/routes/cnbeta/topic.js deleted file mode 100644 index 9481b4ad8..000000000 --- a/lib/routes/cnbeta/topic.js +++ /dev/null @@ -1,75 +0,0 @@ -const got = require('@/utils/got'); -const cheerio = require('cheerio'); -const date = require('@/utils/date'); -module.exports = async (ctx) => { - const topicUrl = `https://www.cnbeta.com/topics/${ctx.params.topic_id}.htm`; - const response = await got({ - method: 'get', - url: topicUrl, - }); - const $ = cheerio.load(response.data); - - const topicInfo = $('div.cate-brief h2 b').text(); - const news_list = $('div.item') - .map((i, item) => { - const title = $(item).find('dl dt a').text(); - let href = $(item).find('dl dt a').attr('href'); - if (href === undefined) { - return null; - } - if (href.startsWith('//')) { - href = 'https:' + href; - } - const status = $(item).find('div.meta-data ul.status li')['0'].children[0].data; - const info = status.split(' '); - const author = info[0]; - const pubDate = info[1] + ' ' + info[2]; - return { title, href, author, pubDate }; - }) - .filter((x) => x) - .map((i, e) => e) - .get(); - - const ProcessFeed = (data) => { - const $ = cheerio.load(data); - - // 移除6.18广告 - $('.article-global').remove(); - $('.article-topic').remove(); - - // 提取内容 - return $('.article-summary p').html() + '
' + $('.article-content').html(); - }; - - const out = await Promise.all( - news_list.map(async (item) => { - const cache = await ctx.cache.get(item.href); - if (cache) { - return Promise.resolve(JSON.parse(cache)); - } - - const response = await got({ - method: 'get', - url: item.href, - }); - - const description = ProcessFeed(response.data); - const single = { - title: item.title, - description, - pubDate: date(item.pubDate, +8), - link: item.href, - author: item.author, - }; - ctx.cache.set(item.href, JSON.stringify(single)); - return Promise.resolve(single); - }) - ); - - ctx.state.data = { - title: `cnBeta专题 - ${topicInfo}`, - link: topicUrl, - item: out ?? [], - description: `cnBeta专题 - ${topicInfo}`, - }; -}; diff --git a/lib/v2/cnbeta/index.js b/lib/v2/cnbeta/index.js new file mode 100644 index 000000000..68acdd594 --- /dev/null +++ b/lib/v2/cnbeta/index.js @@ -0,0 +1,15 @@ +const parser = require('@/utils/rss-parser'); + +const { rootUrl, ProcessItems } = require('./utils'); + +module.exports = async (ctx) => { + const currentUrl = `${rootUrl}/backend.php`; + + const { items } = await parser.parseURL(currentUrl); + + ctx.state.data = { + title: 'cnBeta', + link: currentUrl, + item: await ProcessItems(items, ctx.query.limit, ctx.cache.tryGet), + }; +}; diff --git a/lib/v2/cnbeta/maintainer.js b/lib/v2/cnbeta/maintainer.js new file mode 100644 index 000000000..33741b6cd --- /dev/null +++ b/lib/v2/cnbeta/maintainer.js @@ -0,0 +1,5 @@ +module.exports = { + '/': ['nczitzk'], + '/category/:id': ['nczitzk'], + '/topics/:id': ['nczitzk'], +}; diff --git a/lib/v2/cnbeta/radar.js b/lib/v2/cnbeta/radar.js new file mode 100644 index 000000000..458e2cde1 --- /dev/null +++ b/lib/v2/cnbeta/radar.js @@ -0,0 +1,25 @@ +module.exports = { + 'cnbeta.com': { + _name: 'cnBeta', + '.': [ + { + title: '最新', + docs: 'https://docs.rsshub.app/new-media.html#cnbeta-zuixin', + source: ['/'], + target: '/cnbeta', + }, + { + title: '分类', + docs: 'https://docs.rsshub.app/new-media.html#cnbeta-fenlei', + source: ['/category/:id', '/'], + target: '/cnbeta/category/:id', + }, + { + title: '主题', + docs: 'https://docs.rsshub.app/new-media.html#cnbeta-zhuti', + source: ['/topics/:id', '/'], + target: '/cnbeta/topics/:id', + }, + ], + }, +}; diff --git a/lib/v2/cnbeta/router.js b/lib/v2/cnbeta/router.js new file mode 100644 index 000000000..95cb0b6f9 --- /dev/null +++ b/lib/v2/cnbeta/router.js @@ -0,0 +1,4 @@ +module.exports = function (router) { + router.get('/:type/:id', require('./type')); + router.get('/', require('./index')); +}; diff --git a/lib/v2/cnbeta/type.js b/lib/v2/cnbeta/type.js new file mode 100644 index 000000000..5eaa636a1 --- /dev/null +++ b/lib/v2/cnbeta/type.js @@ -0,0 +1,42 @@ +const got = require('@/utils/got'); +const cheerio = require('cheerio'); +const timezone = require('@/utils/timezone'); +const { parseDate } = require('@/utils/parse-date'); + +const { rootUrl, ProcessItems } = require('./utils'); + +module.exports = async (ctx) => { + const type = ctx.params.type; + const id = ctx.params.id; + + const currentUrl = `${rootUrl}/${type}/${id}.htm`; + + let response = await got({ + method: 'get', + url: currentUrl, + }); + + const $ = cheerio.load(response.data); + + const token = encodeURI($('meta[name="csrf-token"]').attr('content')); + const apiUrl = `${rootUrl}/home/more?&type=${$('div[data-type]').attr('data-type')}&page=1&_csrf=${token}&_=${new Date().getTime()}`; + + response = await got({ + method: 'get', + url: apiUrl, + }); + + const items = response.data.result.list.map((item) => ({ + title: item.title, + description: item.hometext, + author: item.source.split('@http')[0], + pubDate: timezone(parseDate(item.inputtime), +8), + link: item.url_show.indexOf('//') === 0 ? `https:${item.url_show}` : item.url_show, + })); + + ctx.state.data = { + title: $('title').text(), + link: currentUrl, + item: await ProcessItems(items, ctx.query.limit, ctx.cache.tryGet), + }; +}; diff --git a/lib/v2/cnbeta/utils.js b/lib/v2/cnbeta/utils.js new file mode 100644 index 000000000..0c3d68d53 --- /dev/null +++ b/lib/v2/cnbeta/utils.js @@ -0,0 +1,27 @@ +const got = require('@/utils/got'); +const cheerio = require('cheerio'); + +const rootUrl = 'https://www.cnbeta.com'; + +module.exports = { + rootUrl, + ProcessItems: async (items, limit, tryGet) => + await Promise.all( + items.slice(0, limit ? parseInt(limit) : 50).map((item) => + tryGet(item.link, async () => { + const detailResponse = await got({ + method: 'get', + url: item.link, + }); + + const content = cheerio.load(detailResponse.data); + + content('.topic, .article-topic, .article-global').remove(); + + item.description = content('.article-summary').html() + content('.article-content').html(); + + return item; + }) + ) + ), +};