fix: leetcode.com题解展示 (#10515)

* fix: leetcode.com题解展示

* fix: dynamic uuid

* fix: spacing
This commit is contained in:
Albert Cai
2022-08-18 07:31:16 +08:00
committed by GitHub
parent 108c784a11
commit 0896c39c31

View File

@@ -2,6 +2,7 @@ const got = require('@/utils/got');
const showdown = require('showdown'); const showdown = require('showdown');
const { parseDate } = require('@/utils/parse-date'); const { parseDate } = require('@/utils/parse-date');
const timezone = require('@/utils/timezone'); const timezone = require('@/utils/timezone');
const path = require('path');
module.exports = async (ctx) => { module.exports = async (ctx) => {
const baseurl = `https://leetcode.com`; const baseurl = `https://leetcode.com`;
const url = `${baseurl}/graphql/`; const url = `${baseurl}/graphql/`;
@@ -106,12 +107,89 @@ module.exports = async (ctx) => {
headers, headers,
}) })
).data.data.question.solution; ).data.data.question.solution;
if (article.content === null) {
article.content = 'Sorry, the solution of this question may be locked.';
}
const converter = new showdown.Converter(); const converter = new showdown.Converter();
const handleText = (s) => { // 图片处理
// 处理多语言代码展示问题 const parsePngSlide = async (s) => {
s = s.replace(/(```)([a-zA-Z0-9-+#]+)\s*?(\[.*?\])?\n/g, '\r\n###$2\r\n$1$2\r\n'); const pattern = /!\?!(.+)!\?!/;
if (!pattern.test(s)) {
return s;
}
const matched = s.match(new RegExp(pattern, 'g'));
const fn = async (m) => {
const relaurl = m.match(pattern)[1].split(':')[0];
const fullurl = path.resolve('/' + questionUrl + 'solution/', relaurl).slice(1);
const pngList = (
await got({
url: fullurl,
method: 'get',
headers,
})
).data.timeline;
return pngList.map((v) => `![pic](${path.resolve(`/problems/${questionTitle}/solution/`, v.image)})`).join('\n');
};
const strs = await Promise.all(matched.map((v) => fn(v)));
for (let i = 0; i < matched.length; i++) {
s = s.replace(matched[i], strs[i]);
}
return s; return s;
}; };
// iframe代码框处理
const parseIframe = async (s) => {
const pattern = new RegExp('<iframe.*? src=".*?playground/(.*?)/shared".*</iframe>');
if (!pattern.test(s)) {
return s;
}
const matched = s.match(new RegExp(pattern, 'g'));
const fn = async (m) => {
const uuid = m.match(pattern)[1];
const code = (
await got({
method: 'post',
url,
json: {
operationName: 'fetchPlayground',
query: `query fetchPlayground {
playground(uuid: "${uuid}") {
testcaseInput
name
isUserOwner
isLive
showRunCode
showOpenInPlayground
selectedLangSlug
isShared
__typename
}
allPlaygroundCodes(uuid: "${uuid}") {
code
langSlug
__typename
}
}`,
variables: {},
},
headers,
})
).data.data.allPlaygroundCodes;
return code.map((c) => `###${c.langSlug}\n\r \`\`\`${c.langSlug}\n ${c.code}\n\`\`\``).join('\n\r');
};
const strs = await Promise.all(matched.map((v) => fn(v)));
for (let i = 0; i < matched.length; i++) {
s = s.replace(matched[i], strs[i]);
}
return s;
};
const handleText = async (s) => {
// 处理代码iframe嵌入问题
s = await parseIframe(s);
// 处理图片展示问题
s = await parsePngSlide(s);
return s;
};
article.content = await handleText(article.content);
ctx.state.data = { ctx.state.data = {
title: 'LeetCode DailyQuestion Solution', title: 'LeetCode DailyQuestion Solution',
description: 'LeetCode DailyQuestion Solution', description: 'LeetCode DailyQuestion Solution',
@@ -126,7 +204,7 @@ module.exports = async (ctx) => {
{ {
title: `Solution-${question.title}`, title: `Solution-${question.title}`,
link: `${questionUrl}solution/`, link: `${questionUrl}solution/`,
description: converter.makeHtml(handleText(article.content)), description: converter.makeHtml(article.content),
pubDate: timezone(parseDate(data.activeDailyCodingChallengeQuestion.date), +8), pubDate: timezone(parseDate(data.activeDailyCodingChallengeQuestion.date), +8),
author: 'leetcode', author: 'leetcode',
}, },