diff --git a/lib/v2/npr/radar.js b/lib/v2/npr/radar.js index 08128d4dd..2c062a125 100644 --- a/lib/v2/npr/radar.js +++ b/lib/v2/npr/radar.js @@ -1,9 +1,9 @@ module.exports = { 'npr.org': { - _name: 'NPR', + _name: 'National Public Radio', '.': [ { - title: '全文 RSS', + title: 'News', docs: 'https://docs.rsshub.app/routes/traditional-media#npr', }, ], diff --git a/lib/v2/rfi/maintainer.js b/lib/v2/rfi/maintainer.js index ee48f58b8..73ce08bda 100644 --- a/lib/v2/rfi/maintainer.js +++ b/lib/v2/rfi/maintainer.js @@ -1,3 +1,3 @@ module.exports = { - '/news/:lang?': ['nczitzk'], + '/:path*': ['nczitzk'], }; diff --git a/lib/v2/rfi/news.js b/lib/v2/rfi/news.js index 886579ab5..d230555c8 100644 --- a/lib/v2/rfi/news.js +++ b/lib/v2/rfi/news.js @@ -3,44 +3,53 @@ const cheerio = require('cheerio'); const { parseDate } = require('@/utils/parse-date'); module.exports = async (ctx) => { - const LANGUAGE = new Map([ - ['en', '/en/live-news/'], - ['fr', '/fr/en-bref/'], - ['cn', '/cn/滚动新闻'], - ]); - - const rootUrl = 'https://www.rfi.fr'; - const currentUrl = `${rootUrl}${LANGUAGE.get(ctx.params.lang ?? 'cn')}`; - const response = await got({ - method: 'get', - url: currentUrl, - }); + const rootUrl = 'https://www.rfi.fr/'; + const path = ctx.params.path ?? 'en'; + const currentUrl = `${rootUrl}${path.endsWith('/') ? path : `${path}/`}`; + const response = await got(currentUrl); const $ = cheerio.load(response.data); - let items = $('.article__title') + $('aside[data-org-type="aside-content--highlighted"], aside[data-org-type="aside-content--sponsors"]').remove(); + + let items = $('.article__title a') .toArray() .map((item) => { item = $(item); return { title: item.text(), - link: `${rootUrl}${item.parent().parent().attr('href')}`, - pubDate: parseDate(item.prev().find('time').attr('datetime')), + link: new URL(item.attr('href'), currentUrl).href, }; }); items = await Promise.all( items.map((item) => ctx.cache.tryGet(item.link, async () => { - const detailResponse = await got({ - method: 'get', - url: item.link, - }); - + const detailResponse = await got(item.link); const content = cheerio.load(detailResponse.data); - item.description = content('.t-content__body').html(); + content('.m-interstitial, .m-em-quote svg, .o-self-promo').remove(); + + const ldJson = JSON.parse(content('script[type="application/ld+json"]').text() || '[]').find((x) => x['@type'] === 'NewsArticle'); + + item.description = content('.t-content__chapo').prop('outerHTML') + content('.t-content__main-media').prop('outerHTML') + content('.t-content__body').html(); + item.pubDate = parseDate(ldJson?.datePublished); + item.updated = parseDate(ldJson?.dateModified); + item.author = ldJson?.author.map((author) => author.name).join(', '); + item.category = ldJson?.keywords.split(','); + + if (ldJson?.audio) { + item.itunes_item_image = ldJson.audio.thumbnailUrl; + // TODO: Use Temporal.Duration when https://tc39.es/proposal-temporal/ is GA + item.itunes_duration = ldJson.audio.duration + .match(/P0DT(\d+)H(\d+)M(\d+)S/) + .slice(1) + .map((x) => parseInt(x)) + .reduce((a, b) => a * 60 + b); + item.enclosure_url = ldJson.audio.contentUrl; + item.enclosure_type = 'audio/mpeg'; + } return item; }) @@ -49,8 +58,12 @@ module.exports = async (ctx) => { ctx.state.data = { title: $('title').text(), + description: $('meta[name="description"]').attr('content'), link: currentUrl, + image: $('meta[property="og:image"]').attr('content'), + icon: new URL($('link[rel="apple-touch-icon"]').attr('href'), currentUrl).href, + logo: new URL($('link[rel="apple-touch-icon"]').attr('href'), currentUrl).href, item: items, - language: $("meta[property='og:locale']").attr('content'), + language: $('html').attr('lang'), }; }; diff --git a/lib/v2/rfi/radar.js b/lib/v2/rfi/radar.js index 6891f0266..a78a782e4 100644 --- a/lib/v2/rfi/radar.js +++ b/lib/v2/rfi/radar.js @@ -1,12 +1,12 @@ module.exports = { 'rfi.fr': { - _name: '法国国际广播电台', + _name: 'Radio France Internationale', '.': [ { - title: '滚动新闻', - docs: 'https://docs.rsshub.app/routes/multimedia#fa-guo-guo-ji-guang-bo-dian-tai-gun-dong-xin-wen', - source: ['/'], - target: '/rfi/news', + title: 'Generic News', + docs: 'https://docs.rsshub.app/routes/traditional-media##radio-france-internationale-fa-guo-guo-ji-guang-bo-dian-tai', + source: ['/*path'], + target: '/rfi/:path', }, ], }, diff --git a/lib/v2/rfi/router.js b/lib/v2/rfi/router.js index 84ffb5b53..7cef336a5 100644 --- a/lib/v2/rfi/router.js +++ b/lib/v2/rfi/router.js @@ -1,3 +1,3 @@ module.exports = function (router) { - router.get('/news/:lang?', require('./news')); + router.get('/:path*', require('./news')); }; diff --git a/website/docs/routes/multimedia.md b/website/docs/routes/multimedia.md index 9685aba99..ee9eeb51f 100644 --- a/website/docs/routes/multimedia.md +++ b/website/docs/routes/multimedia.md @@ -1555,20 +1555,6 @@ When `mediaType` is `movie`, `sheet` should be: -## 法国国际广播电台 {#fa-guo-guo-ji-guang-bo-dian-tai} - -### 滚动新闻 {#fa-guo-guo-ji-guang-bo-dian-tai-gun-dong-xin-wen} - - - -**lang** - -| en | cn | fr | -| --- | --- | --- | -| 英文 | 中文 | 法文 | - - - ## 高清电台 {#gao-qing-dian-tai} ### 最新电影 {#gao-qing-dian-tai-zui-xin-dian-ying} diff --git a/website/docs/routes/traditional-media.md b/website/docs/routes/traditional-media.md index b22b5f85e..d54a93084 100644 --- a/website/docs/routes/traditional-media.md +++ b/website/docs/routes/traditional-media.md @@ -391,6 +391,16 @@ Only `s00017` is in English. | s00017 | English | | s00018 | Columnist | +## National Public Radio {#national-public-radio} + +### News {#national-public-radio-news} + + + +Provide full article RSS for CBC topics. + + + ## NHK {#nhk} ### News Web Easy {#nhk-news-web-easy} @@ -447,13 +457,25 @@ Only `s00017` is in English. -## NPR {#npr} +## Radio France Internationale 法国国际广播电台 {#radio-france-internationale-fa-guo-guo-ji-guang-bo-dian-tai} -### News {#npr-news} +### Generic News {#radio-france-internationale-fa-guo-guo-ji-guang-bo-dian-tai-generic-news} - + -Provide full article RSS for CBC topics. +:::tip + +- To subscribe to [English News](https://www.rfi.fr/en/), whose URL is `https://www.rfi.fr/en`, you can get the route as [`/rfi/en`](https://rsshub.app/rfi/en). +- To subscribe to [English Europe News](https://www.rfi.fr/en/europe/), whose URL is `https://www.rfi.fr/en/europe`, you can get the route as [`/rfi/en/europe`](https://rsshub.app/rfi/en/europe). +- To subscribe to topic [Paris Olympics 2024](https://www.rfi.fr/en/tag/paris-olympics-2024/), whose URL is `https://www.rfi.fr/en/tag/paris-olympics-2024`, you can get the route as [`/rfi/en/tag/paris-olympics-2024`](https://rsshub.app/rfi/en/tag/paris-olympics-2024). + +::: + +:::caution + +This route does not support podcasts, please use the Offical RSS feed instead. + +:::