diff --git a/docs/programming.md b/docs/programming.md index b76e86e99a..f6744470ca 100644 --- a/docs/programming.md +++ b/docs/programming.md @@ -115,6 +115,10 @@ GitHub 官方也提供了一些 RSS: +### 打卡 + + + ## LinkedKeeper ### 博文 diff --git a/lib/router.js b/lib/router.js index 0610968f9f..0f13bd9b1d 100644 --- a/lib/router.js +++ b/lib/router.js @@ -1062,6 +1062,7 @@ router.get('/aisixiang/ranking/:type?/:range?', require('./routes/aisixiang/rank // LeetCode router.get('/leetcode/articles', require('./routes/leetcode/articles')); +router.get('/leetcode/submission/:country/:user', require('./routes/leetcode/submission')); // segmentfault router.get('/segmentfault/channel/:name', require('./routes/segmentfault/channel')); diff --git a/lib/routes/leetcode/submission.js b/lib/routes/leetcode/submission.js new file mode 100644 index 0000000000..d244faa805 --- /dev/null +++ b/lib/routes/leetcode/submission.js @@ -0,0 +1,66 @@ +const axios = require('@/utils/axios'); +const cheerio = require('cheerio'); +const util = require('./utils'); + +module.exports = async (ctx) => { + const country = ctx.params.country; + const user = ctx.params.user; + let url, state, description; + if (country === 'cn') { + url = 'https://leetcode-cn.com/'; + } else { + url = 'https://leetcode.com/'; + } + const response = await axios({ + method: 'get', + url: url + `${user}`, + headers: { + Referer: url, + }, + }); + const data = response.data; + const $ = cheerio.load(data); + const username = $('div.panel-body') + .find('h4') + .text(); + const img = $('div.panel-body') + .find('img') + .attr('src'); // 用户的头像 + const src = ``; + const solvedQuestion = $('ul.list-group') + .eq(2) + .children() + .eq(0) + .find('span') + .text(); // 解决的题目 + const acceptedSubmission = $('ul.list-group') + .eq(2) + .children() + .eq(1) + .find('span') + .text(); // 通过的提交 + const acceptanceRate = $('ul.list-group') + .eq(2) + .children() + .eq(2) + .find('span') + .text(); // 通过率 + if (country === 'cn') { + state = ' 的刷题动态'; + description = '解决的题目: ' + solvedQuestion + '
通过的提交: ' + acceptedSubmission + '
通过率: ' + acceptanceRate + '
' + src; + } else { + state = ' Most recent submissions'; + description = 'Solved Question: ' + solvedQuestion + '
Accepted Submission: ' + acceptedSubmission + '
Acceptance Rate: ' + acceptanceRate + '
' + src; + } + + const list = $('ul.list-group') + .eq(-1) + .children() + .get(); + const result = await util.ProcessFeed(list, country); + ctx.state.data = { + title: username + state, + description: description, + item: result, + }; +}; diff --git a/lib/routes/leetcode/utils.js b/lib/routes/leetcode/utils.js new file mode 100644 index 0000000000..a0717946f5 --- /dev/null +++ b/lib/routes/leetcode/utils.js @@ -0,0 +1,82 @@ +const cheerio = require('cheerio'); + +const ProcessFeed = async (list, country) => { + let host; + if (country === 'us') { + host = 'https://leetcode.com'; + } else { + host = 'https://leetcode-cn.com'; + } + return await Promise.all( + list.map(async (item) => { + const $ = cheerio.load(item); + const $title = $('b'); + const description = + $('span') + .eq(0) + .text() + + $('span') + .eq(1) + .text(); + // 还原相对链接为绝对链接 + + const pubDate = $('span') + .eq(2) + .text(); + const bb = $('a[href]').get()[0]; + const itemUrl = host + $(bb).attr('href'); + let n = 0, + h = 0; + let n1, n2, n3, n4, n5, n6; + if (country === 'us') { + n1 = pubDate.search(/year/); + n2 = pubDate.search(/month/); + n3 = pubDate.search(/week/); + n4 = pubDate.search(/day/); + n5 = pubDate.search(/hour/); + n6 = pubDate.search(/minute/); + } else { + n1 = pubDate.search(/年/); + n2 = pubDate.search(/月/); + n3 = pubDate.search(/周/); + n4 = pubDate.search(/日/); + n5 = pubDate.search(/小时/); + n6 = pubDate.search(/分钟/); + } + + if (n1 !== -1) { + n = n + parseInt(pubDate[n1 - 2]) * 365; + } + if (n2 !== -1) { + n = n + parseInt(pubDate[n2 - 2]) * 30; + } + if (n3 !== -1) { + n = n + parseInt(pubDate[n3 - 2]) * 7; + } + if (n4 !== -1) { + n = n + parseInt(pubDate[n4 - 2]) * 1; + } + if (n5 !== -1) { + h = h + parseInt(pubDate[n5 - 2]) * 3600; + } + if (n6 !== -1) { + h = h + parseInt(pubDate[n6 - 2]) * 60; + } + const now = new Date(); + const Datenow = new Date(now.getTime() - n * 24 * 3600 * 1000 - h * 1000).toISOString(); + // 列表上提取到的信息 + const single = { + title: $title.text(), + description: description, + link: itemUrl, + guid: itemUrl, + pubDate: Datenow, + }; + return Promise.resolve(Object.assign({}, single)); + }) + ); +}; + +module.exports = { + ProcessFeed, +};