From e323cb683085bbf6c29833ba374b73aea3e3895a Mon Sep 17 00:00:00 2001 From: Evan Date: Tue, 26 Jul 2022 07:51:21 -0700 Subject: [PATCH] feat(route): leetcode.com daily question (#10296) * feat: leetcode.com daily question * feat: add docs support * chore(leetcode): use template literal to write GraphQL * feat(leetcode): add en docs * Update docs/en/programming.md Co-authored-by: Tony * chore(leetcode): format graphql string * chore(leetcode): format redundant graphql string --- docs/en/programming.md | 4 + docs/programming.md | 4 + lib/v2/leetcode/dailyquestion-en.js | 116 ++++++++++++++++++ lib/v2/leetcode/maintainer.js | 3 + lib/v2/leetcode/router.js | 3 + .../templates/question-description.art | 6 + 6 files changed, 136 insertions(+) create mode 100644 lib/v2/leetcode/dailyquestion-en.js create mode 100644 lib/v2/leetcode/maintainer.js create mode 100644 lib/v2/leetcode/router.js create mode 100644 lib/v2/leetcode/templates/question-description.art diff --git a/docs/en/programming.md b/docs/en/programming.md index 497943bad8..7dbddce89d 100644 --- a/docs/en/programming.md +++ b/docs/en/programming.md @@ -305,6 +305,10 @@ Subscribe to the updates (threads and submission) from a paritcular Hacker News +### Daily Question + + + ## Linux Patchwork ### Patch Comments diff --git a/docs/programming.md b/docs/programming.md index 756a697fc9..6a7ce49e50 100644 --- a/docs/programming.md +++ b/docs/programming.md @@ -447,6 +447,10 @@ GitHub 官方也提供了一些 RSS: +### 每日一题 + + + ## LinkedKeeper ### 博文 diff --git a/lib/v2/leetcode/dailyquestion-en.js b/lib/v2/leetcode/dailyquestion-en.js new file mode 100644 index 0000000000..b6b81ef436 --- /dev/null +++ b/lib/v2/leetcode/dailyquestion-en.js @@ -0,0 +1,116 @@ +const got = require('@/utils/got'); +const { art } = require('@/utils/render'); +const path = require('path'); + +const host = 'https://leetcode.com'; + +module.exports = async (ctx) => { + const question = { + date: '', + link: '', + titleSlug: '', + content: '', + frontedId: '', + difficulty: '', + tags: '', + }; + const url = host + '/graphql'; + const dailyQuestionPayload = { + query: `query questionOfToday { + activeDailyCodingChallengeQuestion { + date + link + question { + frontendQuestionId: questionFrontendId + titleSlug + } + } + } `, + variables: {}, + }; + const dailyQuestionResponse = await got({ + method: 'post', + url, + headers: { + 'content-type': 'application/json', + }, + body: JSON.stringify(dailyQuestionPayload), + }); + const data = dailyQuestionResponse.data.data.activeDailyCodingChallengeQuestion; + question.date = data.date; + question.link = host + data.link; + question.titleSlug = data.question.titleSlug; + + const detailsPayload = { + operationName: 'questionData', + query: `query questionData($titleSlug: String!) { + question(titleSlug: $titleSlug) { + questionId + questionFrontendId + title + titleSlug + content + translatedTitle + translatedContent + difficulty + topicTags { + name + slug + translatedName + __typename + } + __typename + } + }`, + variables: { + titleSlug: question.titleSlug, + }, + }; + const detailsResponse = await got({ + method: 'post', + url, + headers: { + 'content-type': 'application/json', + }, + body: JSON.stringify(detailsPayload), + }); + const emoji = { + Medium: '🟡', + Easy: '🟢', + Hard: '🔴', + }; + + const details = detailsResponse.data.data.question; + question.content = details.content; + question.frontedId = details.questionFrontendId; + question.difficulty = emoji[details.difficulty]; + + let topicTags = details.topicTags; + topicTags = topicTags.map((item) => { + let slug = '#' + item.slug; + slug = slug.replaceAll('-', '_'); + return slug; + }); + question.tags = topicTags.join(' '); + + const rssData = { + title: question.frontedId + '.' + question.titleSlug, + description: art(path.join(__dirname, 'templates/question-description.art'), { + question, + }), + link: question.link, + }; + + ctx.state.data = { + title: 'LeetCode Daily Question', + link: 'https://leetcode.com', + description: 'Leetcode Daily Question', + item: [ + { + title: rssData.title, + description: rssData.description + question.content, + link: rssData.link, + }, + ], + }; +}; diff --git a/lib/v2/leetcode/maintainer.js b/lib/v2/leetcode/maintainer.js new file mode 100644 index 0000000000..6162804426 --- /dev/null +++ b/lib/v2/leetcode/maintainer.js @@ -0,0 +1,3 @@ +module.exports = { + '/dailyquestion/en': ['NavePnow'], +}; diff --git a/lib/v2/leetcode/router.js b/lib/v2/leetcode/router.js new file mode 100644 index 0000000000..25ef26e010 --- /dev/null +++ b/lib/v2/leetcode/router.js @@ -0,0 +1,3 @@ +module.exports = function (router) { + router.get('/dailyquestion/en', require('./dailyquestion-en')); +}; diff --git a/lib/v2/leetcode/templates/question-description.art b/lib/v2/leetcode/templates/question-description.art new file mode 100644 index 0000000000..a2ee543656 --- /dev/null +++ b/lib/v2/leetcode/templates/question-description.art @@ -0,0 +1,6 @@ +
+ {{question.difficulty}} {{question.date}} +

+ {{question.tags}} +

+