mirror of
https://github.com/DIYgod/RSSHub.git
synced 2026-09-01 14:57:14 +08:00
feat(route): add NPR (#12827)
* feat(route): add NPR * fix(route/npr): docs * fix(route/npr): remove duplicate images * fix(route/npr): ignore item until audio is available * fix(route/npr): remove duplicate captions * fix(route/npr): caption * fix(route/npr): handle multiple audios
This commit is contained in:
@@ -784,3 +784,15 @@ Free articles only.
|
||||
| 皇室 | koushitsu |
|
||||
|
||||
</RouteEn>
|
||||
|
||||
## NPR
|
||||
|
||||
### News
|
||||
|
||||
<RouteEn author="bennyyip" example="/npr/1001" path="/npr/:endpoint?" :paramsDesc="['Channel ID, can be found in Official RSS URL, `1001` by default']">
|
||||
|
||||
Provide full article RSS for CBC topics.
|
||||
|
||||
</RouteEn>
|
||||
|
||||
|
||||
|
||||
@@ -2715,3 +2715,13 @@ category 对应的关键词有
|
||||
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
|
||||
|
||||
</Route>
|
||||
|
||||
## NPR
|
||||
|
||||
### 新闻
|
||||
|
||||
<Route author="bennyyip" example="/npr/1001" path="/npr/:endpoint?" :paramsDesc="['频道 ID,可在官方频道 RSS URL 中找到,默认为 `1001`']">
|
||||
|
||||
通过提取文章全文,以提供比官方源更佳的阅读体验。
|
||||
|
||||
</Route>
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
const parser = require('@/utils/rss-parser');
|
||||
const got = require('@/utils/got');
|
||||
const cheerio = require('cheerio');
|
||||
|
||||
const getArticleDetail = (link, ctx) =>
|
||||
ctx.cache.tryGet(link, async () => {
|
||||
const response = await got(link);
|
||||
const $ = cheerio.load(response.data);
|
||||
|
||||
const categories = $('.slug').text().trim();
|
||||
|
||||
// ignore item until audio is available
|
||||
if ($('.audio-availability-message').length > 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// handle multiple audios
|
||||
$('.audio-module')
|
||||
.toArray()
|
||||
.forEach((x) => {
|
||||
const audioLink = $($(x).find('.audio-tool-download a')).attr('href');
|
||||
const audio_tag = `<audio controls><source src="${audioLink}" type="audio/mp3"></audio>`;
|
||||
$(x).replaceWith(audio_tag);
|
||||
});
|
||||
|
||||
// primaryaudio is not in `.storytext`, prepend to it
|
||||
const primaryaudio = $('#primaryaudio');
|
||||
const audio = primaryaudio.length > 0 ? $('#primaryaudio').html() : '';
|
||||
|
||||
// replace video
|
||||
const regex = /\?storyId=(\d+)&mediaId=(\d+)/;
|
||||
const m = $.html().match(regex);
|
||||
if (m) {
|
||||
const storyId = m[1];
|
||||
const mediaId = m[2];
|
||||
const video_tag = `<iframe width="740" height="416" src="https://www.npr.org/embedded-video?storyId=${storyId}&mediaId=${mediaId}&jwMediaType=music" frameborder="0" scrolling="no"></iframe>`;
|
||||
const nprVideo = $('.npr-video');
|
||||
if (nprVideo.length === 1) {
|
||||
nprVideo.replaceWith(video_tag);
|
||||
}
|
||||
}
|
||||
|
||||
// remove duplicate caption and images
|
||||
$('.enlarge_measure').remove();
|
||||
$('.enlarge_html').remove();
|
||||
$('.hide-caption').remove();
|
||||
$('.toggle-caption').remove();
|
||||
$('.credit-caption b.credit').remove();
|
||||
$('.credit-caption span.credit').wrap('<figcaption></figcaption>');
|
||||
$('.caption > p').wrap('<figcaption></figcaption>');
|
||||
|
||||
const article =
|
||||
audio +
|
||||
$('.storytext')
|
||||
.toArray()
|
||||
.map((el) => $(el).html())
|
||||
.join('');
|
||||
|
||||
return { article, categories };
|
||||
});
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const endpoint = ctx.params.endpoint || '1001';
|
||||
const feed = await parser.parseURL(`https://feeds.npr.org/${endpoint}/rss.xml`);
|
||||
|
||||
const items = (
|
||||
await Promise.all(
|
||||
feed.items.map(async (item) => {
|
||||
const itemDetails = await getArticleDetail(item.link, ctx);
|
||||
if (itemDetails === null) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
...item,
|
||||
description: itemDetails.article,
|
||||
category: itemDetails.categories,
|
||||
};
|
||||
})
|
||||
)
|
||||
).filter(Boolean);
|
||||
|
||||
ctx.state.data = {
|
||||
title: feed.title,
|
||||
link: feed.link,
|
||||
description: feed.description,
|
||||
icon: 'https://media.npr.org/images/podcasts/primary/npr_generic_image_300.jpg?s=200',
|
||||
item: items,
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,3 @@
|
||||
module.exports = {
|
||||
'/:endpoint?': ['bennyyip'],
|
||||
};
|
||||
@@ -0,0 +1,11 @@
|
||||
module.exports = {
|
||||
'npr.org': {
|
||||
_name: 'NPR',
|
||||
'.': [
|
||||
{
|
||||
title: '全文 RSS',
|
||||
docs: 'https://docs.rsshub.app/traditional-media.html#npr',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,3 @@
|
||||
module.exports = (router) => {
|
||||
router.get('/:endpoint?', require('./full'));
|
||||
};
|
||||
Reference in New Issue
Block a user