feat(route): add cnBeta (#8909)

This commit is contained in:
Ethan Shen 2022-01-22 20:04:49 +08:00 committed by GitHub
parent c0229da7da
commit 9b991a561d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 148 additions and 132 deletions

View File

@ -166,11 +166,37 @@ pageClass: routes
### 最新
<Route author="kt286 HaitianLiu" example="/cnbeta" path="/cnbeta"/>
<Route author="kt286 HaitianLiu nczitzk" example="/cnbeta" path="/cnbeta">
::: tip 提示
最新的内容来源于 [官方 RSS](https://www.cnbeta.com/backend.php)
:::
</Route>
### 分类
<Route author="nczitzk" example="/cnbeta/category/movie" path="/cnbeta/category/:id" :paramsDesc="['分类 id可在对应分类页的 URL 中找到']">
| 影视 | 音乐 | 游戏 | 动漫 | 趣闻 | 科学 | 软件 |
| ----- | ----- | ---- | ----- | ----- | ------- | ---- |
| movie | music | game | comic | funny | science | soft |
</Route>
### 主题
<Route author="cczhong11" example="/cnbeta/topic/453" path="/cnbeta/topic/:topic_id"/>
<Route author="cczhong11 nczitzk" example="/cnbeta/topics/453" path="/cnbeta/topics/:id" :paramsDesc="['主题 id可在对应主题页的 URL 中找到']">
::: tip 提示
完整的主题列表参见 [主题列表](https://www.cnbeta.com/topics.htm)
:::
</Route>
## Common App

View File

@ -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'));

View File

@ -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() + '<br>' + $('.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,
};
};

View File

@ -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() + '<br>' + $('.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}`,
};
};

15
lib/v2/cnbeta/index.js Normal file
View File

@ -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),
};
};

View File

@ -0,0 +1,5 @@
module.exports = {
'/': ['nczitzk'],
'/category/:id': ['nczitzk'],
'/topics/:id': ['nczitzk'],
};

25
lib/v2/cnbeta/radar.js Normal file
View File

@ -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',
},
],
},
};

4
lib/v2/cnbeta/router.js Normal file
View File

@ -0,0 +1,4 @@
module.exports = function (router) {
router.get('/:type/:id', require('./type'));
router.get('/', require('./index'));
};

42
lib/v2/cnbeta/type.js Normal file
View File

@ -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),
};
};

27
lib/v2/cnbeta/utils.js Normal file
View File

@ -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;
})
)
),
};