fix(route): Tradingview Blog (#14191)

* fix(route): Tradingview Blog

* fix: use tiny-async-pool
This commit is contained in:
Ethan Shen 2024-01-07 20:37:07 +08:00 committed by GitHub
parent ee19f9e987
commit 51168fe8e0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 186 additions and 31 deletions

View File

@ -6,55 +6,98 @@ const { art } = require('@/utils/render');
const path = require('path');
module.exports = async (ctx) => {
const language = ctx.params.language ?? 'en';
const { category = 'en' } = ctx.params;
const limit = ctx.query.limit ? parseInt(ctx.query.limit, 10) : 22;
const rootUrl = 'https://www.tradingview.com';
const currentUrl = `${rootUrl}/blog/${language}`;
const currentUrl = new URL(`blog/${category.endsWith('/') ? category : `${category}/`}`, rootUrl).href;
const response = await got({
method: 'get',
url: currentUrl,
});
const { data: response } = await got(currentUrl);
const $ = cheerio.load(response.data);
const $ = cheerio.load(response);
const list = $('.articles-grid-item a[rel="bookmark"]')
.slice(0, ctx.query.limit ? parseInt(ctx.query.limit) : 20)
const items = $('article[id]')
.slice(0, limit)
.toArray()
.map((item) => {
item = $(item);
const title = item.find('div.title').text();
return {
title: item.find('.title').text(),
link: item.attr('href'),
pubDate: parseDate(item.find('.date').text(), 'MMMM D, YYYY'),
title,
link: item.find('a.articles-grid-link').prop('href'),
description: art(path.join(__dirname, 'templates/description.art'), {
image: {
src: item
.find('div.articles-grid-img img')
.prop('src')
.replace(/-\d+x\d+\./, '.'),
alt: title,
},
}),
category: item
.find('a.section')
.toArray()
.map((c) => $(c).text()),
guid: `tradingview-blog-${category}-${item.prop('id')}`,
pubDate: parseDate(item.find('div.date').text(), 'MMM D, YYYY'),
};
});
const items = [];
for await (const item of asyncPool(3, list, (item) =>
for await (const item of asyncPool(3, items, (item) =>
ctx.cache.tryGet(item.link, async () => {
const detailResponse = await got({
method: 'get',
url: item.link,
});
const { data: detailResponse } = await got(item.link);
const content = cheerio.load(detailResponse.data);
const content = cheerio.load(detailResponse);
content('div.entry-content')
.find('img')
.each((_, e) => {
content(e).replaceWith(
art(path.join(__dirname, 'templates/description.art'), {
image: {
src: content(e)
.prop('src')
.replace(/-\d+x\d+\./, '.'),
width: content(e).prop('width'),
height: content(e).prop('height'),
},
})
);
});
item.title = content('meta[property="og:title"]').prop('content');
item.description = art(path.join(__dirname, 'templates/description.art'), {
image: content('.single-img img').attr('src'),
description: content('.entry-content').html(),
image: {
src: content('meta[property="og:image"]').prop('content'),
alt: item.title,
},
description: content('div.entry-content').html(),
});
item.author = content('meta[property="og:site_name"]').prop('content');
item.category = content('div.sections a.section')
.toArray()
.map((c) => content(c).text());
item.pubDate = parseDate(content('div.single-date').text(), 'MMM D, YYYY');
return item;
})
)) {
items.shift();
items.push(item);
}
const icon = new URL($('link[rel="icon"]').prop('href'), rootUrl).href;
ctx.state.data = {
item: items,
title: $('title').text(),
link: currentUrl,
item: items,
description: $('div.site-subtitle').text(),
language: $('html').prop('lang'),
icon,
logo: icon,
subtitle: $('h1.site-title').text(),
};
};

View File

@ -1,3 +1,3 @@
module.exports = {
'/blog/:language?': ['nczitzk'],
'/blog/:language?/category/:category?': ['nczitzk'],
};

View File

@ -5,8 +5,92 @@ module.exports = {
{
title: 'Blog',
docs: 'https://docs.rsshub.app/routes/program-update#tradingview-blog',
source: ['/blog/:language', '/'],
target: '/tradingview/blog',
source: ['/blog/:language/'],
target: '/tradingview/blog/:language/',
},
{
title: 'Blog - Alerts',
docs: 'https://docs.rsshub.app/routes/program-update#tradingview-blog',
source: ['/blog/:language/category/alerts/'],
target: '/tradingview/blog/:language/category/alerts',
},
{
title: 'Blog - Bitcoin and Crypto',
docs: 'https://docs.rsshub.app/routes/program-update#tradingview-blog',
source: ['/blog/:language/category/bitcoin-charts/'],
target: '/tradingview/blog/:language/category/bitcoin-charts',
},
{
title: 'Blog - Business Updates',
docs: 'https://docs.rsshub.app/routes/program-update#tradingview-blog',
source: ['/blog/:language/category/business-updates/'],
target: '/tradingview/blog/:language/category/business-updates',
},
{
title: 'Blog - Charting',
docs: 'https://docs.rsshub.app/routes/program-update#tradingview-blog',
source: ['/blog/:language/category/charts/'],
target: '/tradingview/blog/:language/category/charts',
},
{
title: 'Blog - Charting Library',
docs: 'https://docs.rsshub.app/routes/program-update#tradingview-blog',
source: ['/blog/:language/category/charting-library/'],
target: '/tradingview/blog/:language/category/charting-library',
},
{
title: 'Blog - Data Feeds and Exchanges',
docs: 'https://docs.rsshub.app/routes/program-update#tradingview-blog',
source: ['/blog/:language/category/data-feeds-exchanges/'],
target: '/tradingview/blog/:language/category/data-feeds-exchanges',
},
{
title: 'Blog - Desktop',
docs: 'https://docs.rsshub.app/routes/program-update#tradingview-blog',
source: ['/blog/:language/category/desktop/'],
target: '/tradingview/blog/:language/category/desktop',
},
{
title: 'Blog - Market Analysis',
docs: 'https://docs.rsshub.app/routes/program-update#tradingview-blog',
source: ['/blog/:language/category/market-analysis/'],
target: '/tradingview/blog/:language/category/market-analysis',
},
{
title: 'Blog - Mobile',
docs: 'https://docs.rsshub.app/routes/program-update#tradingview-blog',
source: ['/blog/:language/category/mobile/'],
target: '/tradingview/blog/:language/category/mobile',
},
{
title: 'Blog - Pine Script®',
docs: 'https://docs.rsshub.app/routes/program-update#tradingview-blog',
source: ['/blog/:language/category/pine/'],
target: '/tradingview/blog/:language/category/pine',
},
{
title: 'Blog - Screener',
docs: 'https://docs.rsshub.app/routes/program-update#tradingview-blog',
source: ['/blog/:language/category/stock-screener/'],
target: '/tradingview/blog/:language/category/stock-screener',
},
{
title: 'Blog - Social',
docs: 'https://docs.rsshub.app/routes/program-update#tradingview-blog',
source: ['/blog/:language/category/social/'],
target: '/tradingview/blog/:language/category/social',
},
{
title: 'Blog - Trading and Brokerage',
docs: 'https://docs.rsshub.app/routes/program-update#tradingview-blog',
source: ['/blog/:language/category/trading/'],
target: '/tradingview/blog/:language/category/trading',
},
{
title: 'Blog - Widgets',
docs: 'https://docs.rsshub.app/routes/program-update#tradingview-blog',
source: ['/blog/:language/category/widgets/'],
target: '/tradingview/blog/:language/category/widgets',
},
],
},

View File

@ -1,3 +1,3 @@
module.exports = function (router) {
router.get('/blog/:language?', require('./blog'));
router.get('/blog/:category*', require('./blog'));
};

View File

@ -1,4 +1,13 @@
{{ if image }}
<img src="{{ image }}">
{{ if image?.src }}
<figure>
<img
{{ if image.alt }}
alt="{{ image.alt }}"
{{ /if }}
src="{{ image.src }}">
</figure>
{{ /if }}
{{@ description }}
{{ if description }}
{{@ description }}
{{ /if }}

View File

@ -570,8 +570,8 @@ Logseq 开发团队已经放弃了 [旧网站](https://logseq.com/blog)。
### Blog {#tradingview-blog}
<Route author="nczitzk" example="/tradingview/blog/en" path="/tradingview/blog/:language?" paramsDesc={['Language, see below, `en` as English by default']}>
Language
<Route author="nczitzk" example="/tradingview/blog/en" path="/tradingview/blog/:language?/category/:category?" paramsDesc={['Language, see below, `en` as English by default', 'Category, see below, all by default']} radar="1">
#### Language
| Id | Language |
| -- | ------------------- |
@ -595,6 +595,25 @@ Logseq 开发团队已经放弃了 [旧网站](https://logseq.com/blog)。
| sv | Svenska |
| ar | العربية |
| il | Hebrew |
#### Category
| Category | ID |
| ---------------------------------------------------------------------------------------------- | ----------------------------- |
| [Alerts](https://www.tradingview.com/blog/en/category/alerts/) | category/alerts |
| [Bitcoin and Crypto](https://www.tradingview.com/blog/en/category/bitcoin-charts/) | category/bitcoin-charts |
| [Business Updates](https://www.tradingview.com/blog/en/category/business-updates/) | category/business-updates |
| [Charting](https://www.tradingview.com/blog/en/category/charts/) | category/charts |
| [Charting Library](https://www.tradingview.com/blog/en/category/charting-library/) | category/charting-library |
| [Data Feeds and Exchanges](https://www.tradingview.com/blog/en/category/data-feeds-exchanges/) | category/data-feeds-exchanges |
| [Desktop](https://www.tradingview.com/blog/en/category/desktop/) | category/desktop |
| [Market Analysis](https://www.tradingview.com/blog/en/category/market-analysis/) | category/market-analysis |
| [Mobile](https://www.tradingview.com/blog/en/category/mobile/) | category/mobile |
| [Pine Script®](https://www.tradingview.com/blog/en/category/pine/) | category/pine |
| [Screener](https://www.tradingview.com/blog/en/category/stock-screener/) | category/stock-screener |
| [Social](https://www.tradingview.com/blog/en/category/social/) | category/social |
| [Trading and Brokerage](https://www.tradingview.com/blog/en/category/trading/) | category/trading |
| [Widgets](https://www.tradingview.com/blog/en/category/widgets/) | category/widgets |
</Route>
## Typora {#typora}