feat: add AEON & SA 60-Second Science (#3213)

This commit is contained in:
Enoch Ma
2019-10-09 11:09:18 +08:00
committed by DIYgod
parent c13e55a4ff
commit 4a7693fab6
5 changed files with 160 additions and 0 deletions

View File

@@ -4,6 +4,12 @@ pageClass: routes
# 音视频
## 60-Second Science - Scientific American
### Transcript
<Route author="emdoe" example="/60s-science/transcript" path="/60s-science/transcript"/>
## 99% Invisible
### Transcript

View File

@@ -27,6 +27,20 @@ pageClass: routes
</Route>
## AEON
<Route author="emdoe" example="/aeon/ideas" path="/aeon/:category" :paramsDesc="['类别']"></Route>
支持以文体分类:
| Ideas | Essays | Videos |
| ----- | ------ | ------ |
| ideas | essays | videos |
同样支持以话题分类:
| Culture | Philosophy | Psychology | Society | Science |
| ------- | ---------- | ---------- | ------- | ------- |
| culture | philosophy | psychology | society | science |
## BOF
### 首页

View File

@@ -782,6 +782,9 @@ router.get('/laosiji/hot', require('./routes/laosiji/hot'));
router.get('/laosiji/feed', require('./routes/laosiji/feed'));
router.get('/laosiji/hotshow/:id', require('./routes/laosiji/hotshow'));
// Scientific American 60-Second Science
router.get('/60s-science/transcript', require('./routes/60s-science/transcript'));
// 99% Invisible
router.get('/99percentinvisible/transcript', require('./routes/99percentinvisible/transcript'));
@@ -1422,6 +1425,9 @@ router.get('/ningmeng/song', require('./routes/ningmeng/song'));
// 紫竹张
router.get('/zzz', require('./routes/zzz/index'));
// AEON
router.get('/aeon/:cid', require('./routes/aeon/category'));
// AlgoCasts
router.get('/algocasts', require('./routes/algocasts/all'));

View File

@@ -0,0 +1,48 @@
const cheerio = require('cheerio');
const got = require('@/utils/got');
module.exports = async (ctx) => {
const url = `https://www.scientificamerican.com/podcast/60-second-science/`;
const res = await got.get(url);
const $ = cheerio.load(res.data);
const list = $('.underlined_text.t_small').get();
const out = await Promise.all(
list.map(async (item) => {
const $ = cheerio.load(item);
const title = $(item).attr('aria-label');
const address = $(item).attr('href');
const cache = await ctx.cache.get(address);
if (cache) {
return Promise.resolve(JSON.parse(cache));
}
const res = await got.get(address);
const capture = cheerio.load(res.data);
const tStr = '.article-header__divider > ul > li > span:nth-child(2)';
const time = capture(tStr).text();
const aStr = '.article-header__divider > ul > li > span:nth-child(1) > span';
const author = capture(aStr).text();
capture('.transcript__close').remove();
const intro = capture('.article-media__object').html() + '<br><br>';
const contents = intro + capture('.transcript__inner').html();
const single = {
title,
description: contents,
link: address,
guid: address,
author: author,
pubDate: new Date(time).toUTCString(),
};
ctx.cache.set(address, JSON.stringify(single));
return Promise.resolve(single);
})
);
ctx.state.data = {
title: 'Transcripts of SA 60-Second Science',
link: url,
item: out,
};
};

View File

@@ -0,0 +1,86 @@
const cheerio = require('cheerio');
const got = require('@/utils/got');
module.exports = async (ctx) => {
const url = `https://aeon.co/${ctx.params.cid}`;
const res = await got.get(url);
const $ = cheerio.load(res.data);
const list = $('.article-card').get();
const out = await Promise.all(
list.map(async (item) => {
const $ = cheerio.load(item);
const title = $('.article-card__title').text();
const partial = $('.article-card__title').attr('href');
const address = `https://aeon.co${partial}`;
const author = $('.article-card__authors__inner').text();
const cache = await ctx.cache.get(address);
if (cache) {
return Promise.resolve(JSON.parse(cache));
}
const res = await got.get(address);
const capture = cheerio.load(res.data);
const time = capture('.article__date.published').text();
capture('div.newsletter-signup').remove();
capture('div.pullquote').remove();
capture('div.article__related').remove();
capture('div.article__shares').remove();
let bio;
const authorInfo = '.article__body__author-details > p:nth-child(2)';
if (capture(authorInfo).html() !== null) {
bio =
`<br><br><br><br><hr><br><b>` +
author.trim() +
'</b> ' +
capture(authorInfo)
.html()
.trim() +
`<p><hr>`;
capture('.article__inline-sidebar').remove();
} else {
bio = '';
}
let banner;
if (capture('.article-card__image-wrap').html() !== null) {
const imgSty = capture('figure.responsive-image').attr('style');
const imgLink = imgSty.match(/url\(["']?([^"']*)["']?\)/)[1];
banner = `<img src="${imgLink}">`;
}
if (capture('.article__image__wrapper').html() !== null) {
banner = '';
capture('img').each((index, item) => {
item = $(item);
item.removeAttr('alt');
});
capture('.display-article').remove;
}
if (capture('.video__embed').html() !== null) {
banner = capture('div.video__embed').html();
capture('.article__header__subtitle').remove();
}
const contents = banner + capture('.article__body__content').html() + bio;
const single = {
title,
author: author,
pubDate: new Date(time).toUTCString(),
description: contents,
link: address,
guid: address,
};
ctx.cache.set(address, JSON.stringify(single));
return Promise.resolve(single);
})
);
ctx.state.data = {
title: $('title').text(),
link: url,
item: out,
};
};