mirror of
https://github.com/DIYgod/RSSHub.git
synced 2025-12-10 23:34:38 +08:00
feat: add algocasts.io 视频更新 (#2210)
* feat: add algocasts.io 视频更新 * fix: 修复 AlgoCasts 缓存问题 * fix: AlgoCasts 默认输出全文 * feat: 补上 AlgoCasts 不抓取列表代码中忘记的返回 * fix: 删去 AlgoCasts 中多余的缓存代码
This commit is contained in:
@@ -4,6 +4,14 @@ pageClass: routes
|
||||
|
||||
# 编程
|
||||
|
||||
## AlgoCasts
|
||||
|
||||
### 视频更新
|
||||
|
||||
<Route author="ImSingee" example="/algocasts" path="/algocasts"></Route>
|
||||
|
||||
> AlgoCasts 需要付费订阅, RSS 仅做更新提醒, 不含付费内容.
|
||||
|
||||
## Dockone
|
||||
|
||||
### 周报
|
||||
|
||||
@@ -1345,6 +1345,9 @@ router.get('/steamgifts/discussions/:category?', require('./routes/steamgifts/di
|
||||
// Steamgifts
|
||||
router.get('/zzz', require('./routes/zzz/index'));
|
||||
|
||||
// AlgoCasts
|
||||
router.get('/algocasts', require('./routes/algocasts/all'));
|
||||
|
||||
// aqicn
|
||||
router.get('/aqicn/:city', require('./routes/aqicn/index'));
|
||||
|
||||
|
||||
98
lib/routes/algocasts/all.js
Normal file
98
lib/routes/algocasts/all.js
Normal file
@@ -0,0 +1,98 @@
|
||||
const axios = require('@/utils/axios');
|
||||
const cheerio = require('cheerio');
|
||||
|
||||
const getCacheParsed = async (ctx, key) => {
|
||||
const value = await ctx.cache.get(key);
|
||||
if (value) {
|
||||
return JSON.parse(value);
|
||||
}
|
||||
};
|
||||
|
||||
const generateResponse = async (ctx, items) => ({
|
||||
// 源标题
|
||||
title: 'AlgoCasts',
|
||||
// 源链接
|
||||
link: `https://www.algocasts.com`,
|
||||
// 源说明
|
||||
description: `AlgoCasts 旨在用心做好每一个算法讲解视频。每个视频包含两个部分:题目的剖析讲解以及编码,力求在讲解清楚到位的基础上,尽可能地保持视频精简短小,让大家可以在碎片时间里进行学习,并收获这些算法题背后的思想与乐趣。`,
|
||||
item: await Promise.all(
|
||||
items.map(async (item) => ({
|
||||
// 文章标题
|
||||
title: `${item.title} | AlgoCasts 视频更新`,
|
||||
// 文章正文
|
||||
description: item.description || '',
|
||||
// 文章链接
|
||||
link: item.link,
|
||||
}))
|
||||
),
|
||||
});
|
||||
|
||||
const makeFull = async (ctx, infos) => {
|
||||
const limit = 10; // 仅获取最近十条信息(避免无意义请求)
|
||||
infos = infos.slice(0, limit);
|
||||
|
||||
return await Promise.all(
|
||||
infos.map(async (item) => {
|
||||
const cacheKey = `episode-${item.episode}`;
|
||||
|
||||
// 尝试从缓存查找相关数据
|
||||
let info = await getCacheParsed(ctx, cacheKey);
|
||||
// console.log(info);
|
||||
if (info) {
|
||||
// 找到 -> 直接返回
|
||||
return info;
|
||||
} else {
|
||||
// 未找到 -> 返回
|
||||
info = item;
|
||||
}
|
||||
// 抓取详细信息
|
||||
const response = await axios({
|
||||
method: 'get',
|
||||
url: info.link,
|
||||
});
|
||||
const $ = cheerio.load(response.data);
|
||||
|
||||
const badges = [];
|
||||
$('.badge').each((index, badge) => {
|
||||
badges.push($(badge).text());
|
||||
});
|
||||
|
||||
info.description = `<h1>${info.title}</h1><div>${badges.join(' | ')}</div><div>${$('#my-content p').html()}</div>`;
|
||||
ctx.cache.set(cacheKey, info);
|
||||
|
||||
// console.log(info);
|
||||
|
||||
return info;
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const response = await axios({
|
||||
method: 'get',
|
||||
url: 'http://algocasts.io/episodes',
|
||||
});
|
||||
|
||||
const $ = cheerio.load(response.data);
|
||||
const infos = [];
|
||||
|
||||
$('tr')
|
||||
.slice(1)
|
||||
.each((i, e) => {
|
||||
const id = parseInt(
|
||||
$(e)
|
||||
.find('th')
|
||||
.text()
|
||||
);
|
||||
const titleLabel = $(e).find('td a');
|
||||
const title = `${id}. ${titleLabel.text()}`;
|
||||
const episode = titleLabel
|
||||
.attr('href')
|
||||
.trim()
|
||||
.split('/')[2];
|
||||
const link = `http://algocasts.io/episodes/${episode}`;
|
||||
|
||||
infos.push({ id, title, episode, link });
|
||||
});
|
||||
ctx.state.data = await generateResponse(ctx, await makeFull(ctx, infos));
|
||||
};
|
||||
Reference in New Issue
Block a user