Skip to content

Commit

Permalink
feat(route): add cls hot articles 添加财联社热门文章排行榜 (DIYgod#12044)
Browse files Browse the repository at this point in the history
* feat/add cls hot articles

* rename router to one word

* Apply suggestions from code review

* import crypto

* add heading 3

* refactor: migrate to v2

---------
  • Loading branch information
5upernova-heng authored Mar 6, 2023
1 parent ca9efda commit dae0b25
Show file tree
Hide file tree
Showing 12 changed files with 232 additions and 76 deletions.
20 changes: 12 additions & 8 deletions docs/finance.md
Original file line number Diff line number Diff line change
Expand Up @@ -224,24 +224,28 @@ TokenInsight 官方亦有提供 RSS,可参考 <https://api.tokeninsight.com/re

### 电报

<Route author="nczitzk" example="/cls/telegraph" path="/cls/telegraph/:category?" :paramsDesc="['分类,见下表']">
<Route author="nczitzk" example="/cls/telegraph" path="/cls/telegraph/:category?" :paramsDesc="['分类,见下表,默认为全部']" radar="1">

| 看盘 | 公告 | 解读 | 加红 | 推送 | 提醒 | 基金 |
| ----- | ------------ | ------- | --- | ----- | ------ | ---- |
| watch | announcement | explain | red | jpush | remind | fund |
| 看盘 | 公司 | 解读 | 加红 | 推送 | 提醒 | 基金 | 港股 |
| ----- | ------------ | ------- | --- | ----- | ------ | ---- | -- |
| watch | announcement | explain | red | jpush | remind | fund | hk |

</Route>

### 深度

<Route author="nczitzk" example="/cls/depth/1000" path="/cls/depth/:category?" :paramsDesc="['分类代码,可在首页导航栏的目标网址 URL 中找到']">
<Route author="nczitzk" example="/cls/depth/1000" path="/cls/depth/:category?" :paramsDesc="['分类代码,可在首页导航栏的目标网址 URL 中找到']" radar="1">

| 要闻 | 股市 | 环球 | 公司 | 地产 | 券商 | 金融 | 汽车 | 科创版 |
| ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- |
| 1000 | 1003 | 1007 | 1005 | 1006 | 1118 | 1032 | 1119 | 1111 |
| 头条 | 股市 | 港股 | 环球 | 公司 | 券商 | 基金 | 地产 | 金融 | 汽车 | 科创版 | 品见 | 期货 | 投教 |
| ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- |
| 1000 | 1003 | 1135 | 1007 | 1005 | 1118 | 1110 | 1006 | 1032 | 1119 | 1111 | 1160 | 1124 | 1176 |

</Route>

### 热门文章排行榜

<Route author="5upernova-heng" example="/cls/hot" path="/cls/hot" radar="1"/>

## 第一财经杂志

### 首页
Expand Down
4 changes: 2 additions & 2 deletions lib/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -2862,8 +2862,8 @@ router.get('/gov/caict/caictgd', lazyloadRouteHandler('./routes/gov/caict/caictg
router.get('/cs/news/:caty', lazyloadRouteHandler('./routes/cs/news'));

// 财联社
router.get('/cls/depth/:category?', lazyloadRouteHandler('./routes/cls/depth'));
router.get('/cls/telegraph/:category?', lazyloadRouteHandler('./routes/cls/telegraph'));
// router.get('/cls/depth/:category?', lazyloadRouteHandler('./routes/cls/depth'));
// router.get('/cls/telegraph/:category?', lazyloadRouteHandler('./routes/cls/telegraph'));

// hentai-cosplays
router.get('/hentai-cosplays/:type?/:name?', lazyloadRouteHandler('./routes/hentai-cosplays/hentai-cosplays'));
Expand Down
63 changes: 0 additions & 63 deletions lib/routes/cls/depth.js

This file was deleted.

82 changes: 82 additions & 0 deletions lib/v2/cls/depth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
const got = require('@/utils/got');
const cheerio = require('cheerio');
const { app, os, sv, getSignedSearchParams } = require('./utils');
const { art } = require('@/utils/render');
const path = require('path');

const config = {
1000: '头条',
1003: '股市',
1135: '港股',
1007: '环球',
1005: '公司',
1118: '券商',
1110: '基金',
1006: '地产',
1032: '金融',
1119: '汽车',
1111: '科创版',
1160: '品见',
1124: '期货',
1176: '投教',
};

module.exports = async (ctx) => {
const category = ctx.params.category || '1000';
const title = config[category];
if (!title) {
throw Error('Bad category. See <a href="https://docs.rsshub.app/finance.html#cai-lian-she-shen-du">docs</a>');
}
const searchParams = getSignedSearchParams({
app,
os,
sv,
});
const baseUrl = 'https://www.cls.cn';
const link = `${baseUrl}/v3/depth/home/assembled/${category}`;
const response = await got({
method: 'get',
url: link,
searchParams,
});

let list =
response.data.data.depth_list?.map((item) => ({
title: item.title || item.brief,
link: `${baseUrl}/detail/${item.id}`,
pubDate: new Date(item.ctime * 1000).toUTCString(),
})) || [];

list = list.concat(
response.data.data.top_article.map((item) => ({
title: item.title || item.brief,
link: `${baseUrl}/detail/${item.id}`,
pubDate: new Date(item.ctime * 1000).toUTCString(),
}))
);

const items = await Promise.all(
list.map((item) =>
ctx.cache.tryGet(item.link, async () => {
const detailResponse = await got({
method: 'get',
url: item.link,
});
const content = cheerio.load(detailResponse.data);
const nextData = JSON.parse(content('script#__NEXT_DATA__').text());
const articleDetail = nextData.props.initialState.detail.articleDetail;

item.description = art(path.join(__dirname, 'templates/depth.art'), { articleDetail });
item.author = articleDetail.author?.name;

return item;
})
)
);

ctx.state.data = {
title: `财联社 - ${title}`,
link: `${baseUrl}/depth?id=${category}`,
item: items,
};
};
45 changes: 45 additions & 0 deletions lib/v2/cls/hot.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
const got = require('@/utils/got');
const cheerio = require('cheerio');
const { app, os, sv, getSignedSearchParams } = require('./utils');

async function getDescription(link, ctx) {
const description = await ctx.cache.tryGet(link, async () => {
const detailResponse = await got({
method: 'get',
url: link,
});
const content = cheerio.load(detailResponse.data);

return content('div.detail-content').html();
});
return description;
}

module.exports = async (ctx) => {
const searchParams = getSignedSearchParams({
app,
os,
sv,
});

const link = 'https://www.cls.cn/v2/article/hot/list';
const response = await got({
method: 'get',
url: link,
searchParams,
});
const items = await Promise.all(
response.data.data.map(async (item) => ({
title: item.title || item.brief,
link: `https://www.cls.cn/detail/${item.id}`,
pubDate: new Date(item.ctime * 1000).toUTCString(),
description: await getDescription(`https://www.cls.cn/detail/${item.id}`, ctx),
}))
);

ctx.state.data = {
title: '财联社 - 热门文章排行榜',
link: 'https://www.cls.cn/',
item: items,
};
};
5 changes: 5 additions & 0 deletions lib/v2/cls/maintainer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
'/depth/:category?': ['nczitzk'],
'/hot': ['5upernova-heng'],
'/telegraph/:category?': ['nczitzk'],
};
25 changes: 25 additions & 0 deletions lib/v2/cls/radar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
module.exports = {
'cls.cn': {
_name: '财联社',
'.': [
{
title: '电报',
docs: 'https://docs.rsshub.app/finance.html#cai-lian-she',
sources: ['/telegraph', '/'],
target: '/cls/telegraph',
},
{
title: '深度',
docs: 'https://docs.rsshub.app/finance.html#cai-lian-she',
sources: ['/depth'],
target: (_, url) => `/cls/depth/${new URL(url).searchParams.get('id')}`,
},
{
title: '热门文章排行榜',
docs: 'https://docs.rsshub.app/finance.html#cai-lian-she',
sources: ['/'],
target: '/cls/hot',
},
],
},
};
5 changes: 5 additions & 0 deletions lib/v2/cls/router.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = (router) => {
router.get('/depth/:category?', require('./depth'));
router.get('/hot', require('./hot'));
router.get('/telegraph/:category?', require('./telegraph'));
};
24 changes: 21 additions & 3 deletions lib/routes/cls/telegraph.js → lib/v2/cls/telegraph.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,47 @@
const got = require('@/utils/got');
const { app, os, sv, getSignedSearchParams } = require('./utils');
const { art } = require('@/utils/render');
const path = require('path');

const titles = {
watch: '看盘',
announcement: '公告',
announcement: '公司',
explain: '解读',
red: '加红',
jpush: '推送',
remind: '提醒',
fund: '基金',
hk: '港股',
};

module.exports = async (ctx) => {
const category = ctx.params.category || '';
const limit = ctx.query.limit ? parseInt(ctx.query.limit) : 30;

const link = `https://www.cls.cn/nodeapi/updateTelegraphList?app=CailianpressWeb&category=${category}&hasFirstVipArticle=1&rn=30`;
const searchParams = getSignedSearchParams({
app,
category,
hasFirstVipArticle: 1,
os,
rn: limit,
sv,
});
let link = 'https://www.cls.cn/nodeapi/updateTelegraphList';
if (category) {
link = 'https://www.cls.cn/v1/roll/get_roll_list';
}
const response = await got({
method: 'get',
url: link,
searchParams,
});

const list = response.data.data.roll_data.map((item) => ({
title: item.title || item.content,
link: item.shareurl,
description: item.content,
description: art(path.join(__dirname, 'templates/telegraph.art'), { item }),
pubDate: new Date(item.ctime * 1000).toUTCString(),
category: item.subjects?.map((s) => s.subject_name),
}));

ctx.state.data = {
Expand Down
10 changes: 10 additions & 0 deletions lib/v2/cls/templates/depth.art
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{{ if articleDetail.images }}
{{ each articleDetail.images i }}
<img src="{{ i }}">
{{ /each }}
<br>
{{ /if }}

{{ if articleDetail.content }}
{{@ articleDetail.content }}
{{ /if }}
10 changes: 10 additions & 0 deletions lib/v2/cls/templates/telegraph.art
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{{ if item.content }}
{{ item.content }}
{{ /if }}

{{ if item.images }}
<br>
{{ each item.images i }}
<img src="{{ i }}">
{{ /each }}
{{ /if }}
15 changes: 15 additions & 0 deletions lib/v2/cls/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const CryptoJS = require('crypto-js');

const getSignedSearchParams = (searchParams) => {
searchParams = new URLSearchParams(searchParams);
searchParams.sort();
searchParams.append('sign', CryptoJS.MD5(CryptoJS.SHA1(searchParams.toString()).toString()).toString());
return searchParams;
};

module.exports = {
appName: 'CailianpressWeb',
os: 'web',
sv: '7.7.5',
getSignedSearchParams,
};

0 comments on commit dae0b25

Please sign in to comment.