diff --git a/docs/en/finance.md b/docs/en/finance.md index 2e63d0d0cf..cdefe8ecc1 100644 --- a/docs/en/finance.md +++ b/docs/en/finance.md @@ -16,6 +16,16 @@ pageClass: routes +## FX Markets + + + +| Trading | Infrastructure | Tech and Data | Regulation | +| ------- | -------------- | ------------- | ---------- | +| trading | infrastructure | tech-and-data | regulation | + + + ## TokenInsight ### Blogs diff --git a/docs/finance.md b/docs/finance.md index 8da5887ad6..e9cc31459c 100644 --- a/docs/finance.md +++ b/docs/finance.md @@ -44,6 +44,16 @@ pageClass: routes +## FX Markets + + + +| Trading | Infrastructure | Tech and Data | Regulation | +| ------- | -------------- | ------------- | ---------- | +| trading | infrastructure | tech-and-data | regulation | + + + ## TokenInsight ### 博客 diff --git a/lib/v2/fx-markets/channel.js b/lib/v2/fx-markets/channel.js new file mode 100644 index 0000000000..2cd7140961 --- /dev/null +++ b/lib/v2/fx-markets/channel.js @@ -0,0 +1,56 @@ +const cheerio = require('cheerio'); +const got = require('@/utils/got'); +const { parseDate } = require('@/utils/parse-date'); + +module.exports = async (ctx) => { + const channel = ctx.params.channel; + const link = `https://www.fx-markets.com/${channel}`; + const html = (await got(link)).data; + const $ = cheerio.load(html); + const pageTitle = $('header.select-header > h1').text(); + const title = `FX-Markets ${pageTitle}`; + + const items = $('div#listings').children(); + const articles = items + .map((i, el) => { + const $el = $(el); + const $titleEl = $el.find('h5 > a'); + const articleURL = `https://www.fx-markets.com${$titleEl.attr('href')}`; + const articleTitle = $titleEl.attr('title'); + return { + title: articleTitle, + link: articleURL, + pubDate: parseDate($el.find('time').text()), + }; + }) + .get(); + + const result = await Promise.all( + articles.map((item) => + ctx.cache.tryGet(item.link, async () => { + const res = await got(item.link); + const doc = cheerio.load(res.data); + // This script holds publish datetime info {"datePublished": "2022-05-12T08:45:04+01:00"} + const dateScript = doc('script[type="application/ld+json"]').get()[0].children[0].data; + const re = /"datePublished": "(?.*)"/; + const dateStr = re.exec(dateScript).groups.dateTimePub; + const pubDateTime = parseDate(dateStr, 'YYYY-MM-DDTHH:mm:ssZ'); + // Exclude hidden print message + item.description = doc('div.article-page-body-content:not(.print-access-info)').html(); + return { + title: item.title, + link: item.link, + description: item.description, + // if we fail to get accurate publish date time, show date only from article link on index page. + pubDate: pubDateTime ? pubDateTime : item.pubDate, + }; + }) + ) + ); + + ctx.state.data = { + title, + link, + item: result, + }; +}; diff --git a/lib/v2/fx-markets/maintainer.js b/lib/v2/fx-markets/maintainer.js new file mode 100644 index 0000000000..d564c76968 --- /dev/null +++ b/lib/v2/fx-markets/maintainer.js @@ -0,0 +1,3 @@ +module.exports = { + '/fx-markets/:channel': ['mikkkee'], +}; diff --git a/lib/v2/fx-markets/radar.js b/lib/v2/fx-markets/radar.js new file mode 100644 index 0000000000..68cdeabc7d --- /dev/null +++ b/lib/v2/fx-markets/radar.js @@ -0,0 +1,31 @@ +module.exports = { + 'fx-markets.com': { + _name: 'FX-Markets', + '.': [ + { + title: 'Trading', + docs: 'https://docs.rsshub.app/finance.html#fx-markets', + source: '/trading', + target: '/fx-markets/trading', + }, + { + title: 'Infrastructure', + docs: 'https://docs.rsshub.app/finance.html#fx-markets', + source: '/infrastructure', + target: '/fx-markets/infrastructure', + }, + { + title: 'Tech and Data', + docs: 'https://docs.rsshub.app/finance.html#fx-markets', + source: '/tech-and-data', + target: '/fx-markets/tech-and-data', + }, + { + title: 'Regulation', + docs: 'https://docs.rsshub.app/finance.html#fx-markets', + source: '/regulation', + target: '/fx-markets/regulation', + }, + ], + }, +}; diff --git a/lib/v2/fx-markets/router.js b/lib/v2/fx-markets/router.js new file mode 100644 index 0000000000..df3e882749 --- /dev/null +++ b/lib/v2/fx-markets/router.js @@ -0,0 +1,3 @@ +module.exports = (router) => { + router.get('/:channel', require('./channel')); +};