diff --git a/docs/programming.md b/docs/programming.md index c66e9acce..05d8a16c6 100644 --- a/docs/programming.md +++ b/docs/programming.md @@ -653,6 +653,20 @@ GitHub 官方也提供了一些 RSS: +## 蓝桥云课 + +### 最新发布的课程 + + + +### 作者发布的课程 + + + +### 社区最新技术问答 + + + ## 洛谷 ### 日报 diff --git a/lib/v2/lanqiao/author.js b/lib/v2/lanqiao/author.js new file mode 100644 index 000000000..76719b08f --- /dev/null +++ b/lib/v2/lanqiao/author.js @@ -0,0 +1,63 @@ +const got = require('@/utils/got'); +const utils = require('./utils'); +const dateParser = require('@/utils/dateParser'); +const MarkdownIt = require('markdown-it'); + +async function getUserName(uid) { + // 获取用户信息 + const response = await got({ + method: 'get', + url: `https://www.lanqiao.cn/api/v2/users/${uid}/`, + headers: { + Referer: `https://www.lanqiao.cn/users/${uid}/`, + }, + }); + + return response.data.name; +} + +module.exports = async (ctx) => { + const uid = ctx.params.uid; + const userName = await getUserName(uid); + // 发起 HTTP GET 请求 + const response = await got({ + method: 'get', + url: `https://www.lanqiao.cn/api/v2/users/${uid}/courses/?type=published`, + headers: { + Referer: `https://www.lanqiao.cn/users/${uid}/`, + }, + }); + + const data = response.data.results; // response.data 为 HTTP GET 请求返回的数据对象 + + const md = new MarkdownIt(); + const items = await Promise.all( + data.map((item) => + ctx.cache.tryGet(`https://www.lanqiao.cn/api/v2/courses/${item.id}/`, async () => { + const courseResponse = await got({ + method: 'get', + url: `https://www.lanqiao.cn/api/v2/courses/${item.id}/`, + }); + const course = courseResponse.data; + + item.title = course.name; + item.description = utils.courseDesc(course.picture_url, md.render(course.long_description)); + item.author = course.teacher.name; + item.pubDate = dateParser(course.end_time); + item.link = `https://www.lanqiao.cn/courses/${course.id}/`; + return item; + }) + ) + ); + + ctx.state.data = { + // 源标题 + title: `${userName} 发布的课程`, + // 源链接 + link: `https://www.lanqiao.cn/users/${uid}`, + // 源说明 + description: `${userName} 发布的课程`, + // 遍历此前获取的数据 + item: items, + }; +}; diff --git a/lib/v2/lanqiao/courses.js b/lib/v2/lanqiao/courses.js new file mode 100644 index 000000000..b204a4e23 --- /dev/null +++ b/lib/v2/lanqiao/courses.js @@ -0,0 +1,45 @@ +const got = require('@/utils/got'); +const utils = require('./utils'); +const dateParser = require('@/utils/dateParser'); +const MarkdownIt = require('markdown-it'); + +module.exports = async (ctx) => { + const tag = ctx.params.tag; + // 发起 HTTP GET 请求 + const response = await got({ + method: 'get', + url: `https://www.lanqiao.cn/api/v2/courses/?sort=latest&tag=${tag}&include=name,description,picture_url,id`, + }); + + const data = response.data.results; // response.data 为 HTTP GET 请求返回的数据对象 + const md = new MarkdownIt(); + const items = await Promise.all( + data.map((item) => + ctx.cache.tryGet(`https://www.lanqiao.cn/api/v2/courses/${item.id}/`, async () => { + const courseResponse = await got({ + method: 'get', + url: `https://www.lanqiao.cn/api/v2/courses/${item.id}/`, + }); + const course = courseResponse.data; + + item.title = course.name; + item.description = utils.courseDesc(course.picture_url, md.render(course.long_description)); + item.author = course.teacher.name; + item.pubDate = dateParser(course.end_time); + item.link = `https://www.lanqiao.cn/courses/${course.id}/`; + return item; + }) + ) + ); + + ctx.state.data = { + // 源标题 + title: `蓝桥云课最新发布的课程(${tag})`, + // 源链接 + link: `https://www.lanqiao.cn/courses/?tag=${tag}`, + // 源说明 + description: `蓝桥云课 ${tag} 标签下最新发布的课程`, + // 遍历此前获取的数据 + item: items, + }; +}; diff --git a/lib/v2/lanqiao/maintainer.js b/lib/v2/lanqiao/maintainer.js new file mode 100644 index 000000000..c92e611a0 --- /dev/null +++ b/lib/v2/lanqiao/maintainer.js @@ -0,0 +1,5 @@ +module.exports = { + '/author/:uid': ['huhuhang'], + '/courses/:tag': ['huhuhang'], + '/questions/:id': ['huhuhang'], +}; diff --git a/lib/v2/lanqiao/questions.js b/lib/v2/lanqiao/questions.js new file mode 100644 index 000000000..ebf3c92f5 --- /dev/null +++ b/lib/v2/lanqiao/questions.js @@ -0,0 +1,52 @@ +const got = require('@/utils/got'); +const dateParser = require('@/utils/dateParser'); +const MarkdownIt = require('markdown-it'); + +module.exports = async (ctx) => { + const id = ctx.params.id; + // 发起 HTTP GET 请求 + const response = await got({ + method: 'get', + url: `https://www.lanqiao.cn/api/v2/questions/?sort=created_time&topic_id=${id}`, + headers: { + Referer: `https://www.lanqiao.cn/questions/topic_id=${id}`, + }, + }); + + const data = response.data.results; // response.data 为 HTTP GET 请求返回的数据对象 + + function filterToped(arr) { + // 过滤置顶的帖子 + return arr.is_toped === false; + } + // 将 markdown 转换为 HTML + const md = new MarkdownIt(); + const items = await Promise.all( + data.filter(filterToped).map((item) => + ctx.cache.tryGet(`https://www.lanqiao.cn/api/v2/questions/${item.id}/`, async () => { + const questionResponse = await got({ + method: 'get', + url: `https://www.lanqiao.cn/api/v2/questions/${item.id}/`, + }); + const question = questionResponse.data; + + item.title = question.title; + item.description = md.render(question.content); + item.author = question.author.name; + item.pubDate = dateParser(question.created_at); + item.link = `https://www.lanqiao.cn/questions/${question.id}/`; + return item; + }) + ) + ); + ctx.state.data = { + // 源标题 + title: '蓝桥云课社区技术', + // 源链接 + link: `https://www.lanqiao.cn/questions/topics/${id}/`, + // 源说明 + description: '蓝桥云课技术社区主题帖', + // 遍历此前获取的数据 + item: items, + }; +}; diff --git a/lib/v2/lanqiao/radar.js b/lib/v2/lanqiao/radar.js new file mode 100644 index 000000000..16adb26be --- /dev/null +++ b/lib/v2/lanqiao/radar.js @@ -0,0 +1,25 @@ +module.exports = { + 'lanqiao.cn': { + _name: '蓝桥云课', + '.': [ + { + title: '作者发布的课程', + docs: 'https://docs.rsshub.app/programming.html#lan-qiao-yun-ke-zuo-zhe-fa-bu-de-ke-cheng', + source: ['/users/:uid'], + target: '/lanqiao/author/:uid', + }, + { + title: '最新发布的课程', + docs: 'https://docs.rsshub.app/programming.html#lan-qiao-yun-ke-zuo-zhe-fa-bu-de-ke-cheng', + source: ['/courses/'], + target: '/lanqiao/courses/all', + }, + { + title: '最新发布的课程', + docs: 'https://docs.rsshub.app/programming.html#lan-qiao-yun-ke-she-qu-zui-xin-ji-shu-wen-da', + source: ['/questions/', '/questions/topics/:id'], + target: '/lanqiao/questions/:id', + }, + ], + }, +}; diff --git a/lib/v2/lanqiao/router.js b/lib/v2/lanqiao/router.js new file mode 100644 index 000000000..bd2030a6e --- /dev/null +++ b/lib/v2/lanqiao/router.js @@ -0,0 +1,5 @@ +module.exports = function (router) { + router.get('/author/:uid', require('./author')); + router.get('/courses/:tag', require('./courses')); + router.get('/questions/:id', require('./questions')); +}; diff --git a/lib/v2/lanqiao/templates/courseDesc.art b/lib/v2/lanqiao/templates/courseDesc.art new file mode 100644 index 000000000..702d0e9d5 --- /dev/null +++ b/lib/v2/lanqiao/templates/courseDesc.art @@ -0,0 +1 @@ +
{{ desc }} \ No newline at end of file diff --git a/lib/v2/lanqiao/utils.js b/lib/v2/lanqiao/utils.js new file mode 100644 index 000000000..e43ff4826 --- /dev/null +++ b/lib/v2/lanqiao/utils.js @@ -0,0 +1,12 @@ +const { art } = require('@/utils/render'); +const path = require('path'); + +const courseDesc = (picurl, desc) => + art(path.join(__dirname, 'templates/courseDesc.art'), { + picurl, + desc, + }); + +module.exports = { + courseDesc, +};