rsshub
Version:
Make RSS Great Again!
202 lines (198 loc) • 7.32 kB
text/typescript
import { Route } from '@/types';
import got from '@/utils/got';
import MarkdownIt from 'markdown-it';
const md = MarkdownIt({
html: true,
breaks: true,
});
import { parseDate } from '@/utils/parse-date';
import timezone from '@/utils/timezone';
export const route: Route = {
path: '/dailyquestion/solution/cn',
radar: [
{
source: ['leetcode.cn/'],
},
],
name: 'Unknown',
maintainers: [],
handler,
url: 'leetcode.cn/',
};
async function handler() {
const baseurl = `https://leetcode.cn`;
const url = `${baseurl}/graphql/`;
const headers = {
'content-type': 'application/json',
};
const emoji = {
Medium: '🟡',
Easy: '🟢',
Hard: '🔴',
};
// 获取每日一题
const data = (
await got({
method: 'post',
url,
json: {
operationName: 'questionOfToday',
query: `query questionOfToday {
todayRecord {
date
userStatus
question {
questionId
frontendQuestionId: questionFrontendId
difficulty
title
titleCn: translatedTitle
titleSlug
}
}
}`,
variables: {},
},
headers,
})
).data.data;
const questionTitle = data.todayRecord[0].question.titleSlug;
const questionUrl = `${baseurl}/problems/${questionTitle}/`;
// 获取题目内容
const question = (
await got({
method: 'post',
url,
json: {
operationName: 'questionData',
query: `query questionData($titleSlug: String!) {
question(titleSlug: $titleSlug) {
questionId
questionFrontendId
categoryTitle
boundTopicId
title
titleSlug
content
translatedTitle
translatedContent
isPaidOnly
difficulty
likes
}
}`,
variables: {
titleSlug: questionTitle,
},
},
headers,
})
).data.data.question;
const diffEmoji = emoji[question.difficulty] || '';
// 获取题解(点赞前3)
const articles = (
await got({
method: 'post',
url,
json: {
operationName: 'questionSolutionArticles',
query: `query questionSolutionArticles($questionSlug: String!, $skip: Int, $first: Int, $orderBy: SolutionArticleOrderBy, $userInput: String, $tagSlugs: [String!]) {
questionSolutionArticles(questionSlug: $questionSlug, skip: $skip, first: $first, orderBy: $orderBy, userInput: $userInput, tagSlugs: $tagSlugs) {
totalNum
edges {
node {
...solutionArticle
__typename
}
__typename
}
__typename
}
}
fragment solutionArticle on SolutionArticleNode {
uuid
title
slug
createdAt
thumbnail
author {
username
}
summary
}`,
variables: {
questionSlug: questionTitle,
first: 3,
skip: 0,
orderBy: 'MOST_UPVOTE',
},
},
headers,
})
).data.data.questionSolutionArticles.edges;
// 获取题解内容
const articleContent = (
await Promise.all(
articles.map((art) =>
got({
method: 'post',
url,
json: {
operationName: 'solutionDetailArticle',
query: `query solutionDetailArticle($slug: String!, $orderBy: SolutionArticleOrderBy!) {
solutionArticle(slug: $slug, orderBy: $orderBy) {
...solutionArticle
content
question {
questionTitleSlug
__typename
}
}
}
fragment solutionArticle on SolutionArticleNode {
uuid
title
slug
createdAt
thumbnail
author {
username
}
summary
}`,
variables: {
slug: art.node.slug,
orderBy: 'DEFAULT',
},
},
headers,
})
)
)
).map((v) => v.data.data.solutionArticle);
const handleText = (s) => {
// 处理多语言代码展示问题
s = s.replaceAll(/(```)([\d#+A-Za-z-]+)\s*?(\[.*?])?\n/g, '\r\n###$2\r\n$1$2\r\n');
return s;
};
return {
title: 'LeetCode 每日一题题解',
description: 'LeetCode 每日一题题解',
link: questionUrl,
item: [
{
title: `每日一题-${question.translatedTitle}${diffEmoji}`,
link: questionUrl,
description: question.translatedContent,
pubDate: timezone(parseDate(data.todayRecord[0].date), +8),
},
...articleContent.map((art, i) => ({
title: art.title,
link: `${questionUrl}/solution/${art.slug}`,
description: md.render(handleText(art.content)),
pubDate: timezone(parseDate(articles[i].node.createdAt), +8),
author: art.author.username,
})),
],
};
}