Skip to content

Commit 64d2fc2

Browse files
committed
Initial commit
0 parents  commit 64d2fc2

File tree

6 files changed

+385
-0
lines changed

6 files changed

+385
-0
lines changed

.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
node_modules/
2+
target/
3+
4+
### VS Code ###
5+
.vscode/
6+
7+
### MacOS ###
8+
.DS_Store

action.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
name: "leetcode-box"
2+
author: puiiyuen
3+
description: "Update a pinned gist to show your LeetCode stats"
4+
branding:
5+
icon: code
6+
color: blue
7+
runs:
8+
using: "node12"
9+
main: "./index.js"

index.js

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
require('dotenv').config()
2+
3+
const { getLeetCodeStats } = require('./leetcode')
4+
const { Octokit } = require('@octokit/rest')
5+
6+
const {
7+
GH_TOKEN: github_token,
8+
GIST_ID: gist_id
9+
} = process.env
10+
11+
const octokit = new Octokit({
12+
auth: `token ${github_token}`
13+
})
14+
15+
async function main() {
16+
const leetcode = await getLeetCodeStats()
17+
await updateLeetCodeGist(leetcode)
18+
}
19+
20+
async function updateLeetCodeGist(leetcode) {
21+
let gist
22+
try {
23+
gist = await octokit.gists.get({
24+
gist_id
25+
})
26+
} catch (error) {
27+
console.error(
28+
`leetcode-box cannot resolve your gist:\n${error}`
29+
)
30+
}
31+
32+
const lines = []
33+
34+
const title = [
35+
"Difficulty".padEnd(12),
36+
"Solved".padEnd(10),
37+
"Accepted Rate".padEnd(8)
38+
]
39+
lines.push(title.join(" "))
40+
41+
for (let i = 0; i < leetcode.solved.length; i++) {
42+
const difficulty = leetcode.solved[i].difficulty
43+
const acceptedRate = leetcode.solved[i].acceptedRate
44+
const solvedRadio = leetcode.solved[i].solvedRadio
45+
46+
const line = [
47+
difficulty.padEnd(12),
48+
solvedRadio.padEnd(10),
49+
generateBarChart(acceptedRate, 21),
50+
String(acceptedRate.toFixed(1)).padStart(5) + "%"
51+
]
52+
lines.push(line.join(" "))
53+
}
54+
55+
try {
56+
const filename = Object.keys(gist.data.files)[0]
57+
await octokit.gists.update({
58+
gist_id: gist_id,
59+
files: {
60+
[filename]: {
61+
filename: `💻 My LeetCode Stats ✨`,
62+
content: lines.join("\n")
63+
}
64+
}
65+
})
66+
} catch (error) {
67+
console.error(`Unable to update gist\n${error}`)
68+
}
69+
70+
}
71+
72+
function generateBarChart(percent, size) {
73+
const syms = "░▏▎▍▌▋▊▉█";
74+
75+
const frac = Math.floor((size * 8 * percent) / 100);
76+
const barsFull = Math.floor(frac / 8);
77+
if (barsFull >= size) {
78+
return syms.substring(8, 9).repeat(size);
79+
}
80+
const semi = frac % 8;
81+
82+
return [syms.substring(8, 9).repeat(barsFull), syms.substring(semi, semi + 1)]
83+
.join("")
84+
.padEnd(size, syms.substring(0, 1));
85+
}
86+
87+
(async() => {
88+
await main()
89+
})()

leetcode.js

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
require('dotenv').config();
2+
3+
const axios = require('axios').default;
4+
5+
const {
6+
LEETCODE_USERNAME: username
7+
} = process.env
8+
9+
const leetcodeURL = 'https://leetcode.com/graphql'
10+
11+
const getOriginalLeetCodeStats = async() => {
12+
const response = await axios.post(leetcodeURL, {
13+
query: `
14+
query getUserProfile($username: String!) {
15+
allQuestionsCount {
16+
difficulty
17+
count
18+
}
19+
matchedUser(username: $username) {
20+
username
21+
submitStats: submitStatsGlobal {
22+
acSubmissionNum {
23+
difficulty
24+
count
25+
submissions
26+
}
27+
totalSubmissionNum {
28+
difficulty
29+
count
30+
submissions
31+
}
32+
}
33+
}
34+
}`,
35+
variables: {
36+
username: username
37+
}
38+
})
39+
return response.data.data
40+
}
41+
42+
exports.getLeetCodeStats = async function getLeetCodeStats() {
43+
const originStat = await getOriginalLeetCodeStats()
44+
const matchedUser = originStat.matchedUser
45+
let result = {
46+
"username": null,
47+
"solved": []
48+
}
49+
if (matchedUser !== null) {
50+
result.username = matchedUser.username
51+
for (let i = 0; i < 4; i++) {
52+
const difficulty = matchedUser.submitStats.acSubmissionNum[i].difficulty
53+
const accepted = matchedUser.submitStats.acSubmissionNum[i].count
54+
const allQuestion = originStat.allQuestionsCount[i].count
55+
const acSubmission = matchedUser.submitStats.acSubmissionNum[i].submissions
56+
const totalSubmission = matchedUser.submitStats.totalSubmissionNum[i].submissions
57+
let question = {
58+
"difficulty": difficulty,
59+
"acceptedRate": (acSubmission / totalSubmission * 100),
60+
"solvedRadio": accepted + "/" + allQuestion
61+
}
62+
result.solved.push(question)
63+
}
64+
}
65+
return result;
66+
}

package-lock.json

Lines changed: 197 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"name": "leetcode-box",
3+
"version": "0.1.0",
4+
"description": "Update a gist to contain your leetcode stats",
5+
"main": "index.js",
6+
"scripts": {
7+
"test": "echo \"Error: no test specified\" && exit 1"
8+
},
9+
"author": "puiiyuen",
10+
"license": "MIT",
11+
"dependencies": {
12+
"@octokit/rest": "^18.12.0",
13+
"axios": "^0.24.0",
14+
"dotenv": "^10.0.0"
15+
}
16+
}

0 commit comments

Comments
 (0)