Skip to content

Commit 5b3d951

Browse files
committedDec 27, 2022
Create daily workflow for updateSiteData.js and verifySiteData.js
1 parent 55561bc commit 5b3d951

File tree

3 files changed

+291
-0
lines changed

3 files changed

+291
-0
lines changed
 

Diff for: ‎.github/workflows/rename-and-update.yml

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
name: Rename and Update
2+
3+
on:
4+
#push:
5+
workflow_dispatch:
6+
schedule:
7+
- cron: '0 0 * * *'
8+
9+
jobs:
10+
Build:
11+
runs-on: ubuntu-latest
12+
13+
steps:
14+
- uses: actions/checkout@v3
15+
with:
16+
ref: ${{ github.head_ref }}
17+
fetch-depth: 1
18+
19+
- name: Use Node.js (dependency)
20+
uses: actions/setup-node@v3
21+
with:
22+
node-version: 16
23+
24+
- name: Update Site Data
25+
run: node ./.github/workflows/updateSiteData.js;
26+
27+
- name: Verify New Site Data
28+
run: node ./.github/workflows/verifySiteData.js;
29+
30+
- name: Check for modified files
31+
id: git-check
32+
run: echo modified=$(if git diff-index --quiet HEAD --; then echo "false"; else echo "true"; fi) >> $GITHUB_OUTPUT
33+
34+
- name: Push
35+
if: steps.git-check.outputs.modified == 'true'
36+
run: |
37+
git config --global user.email "71089234+Ahmad-A0@users.noreply.github.com"
38+
git config --global user.name "Bot-A0"
39+
git add .
40+
git commit -am "🌐 Update Site Data (🛠️ from Github Actions)" || true
41+
git push || git pull --rebase && git push
42+
43+

Diff for: ‎.github/workflows/updateSiteData.js

+151
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
/** Script to update ./.problemSiteData.json contains code for solutions hosted on neetcode.io */
2+
3+
const fs = require('fs');
4+
5+
const PROBLEMS_OBJ = JSON.parse(fs.readFileSync('./.problemList.json', 'utf8'));
6+
const PROBLEMS_SITE_DATA = JSON.parse(fs.readFileSync('./.problemSiteData.json', 'utf8'));
7+
8+
const languages = [
9+
{
10+
name: 'C',
11+
directory: 'c',
12+
extension: 'c'
13+
},
14+
{
15+
name: 'C++',
16+
directory: 'cpp',
17+
extension: 'cpp'
18+
},
19+
{
20+
name: 'C#',
21+
directory: 'csharp',
22+
extension: 'cs'
23+
},
24+
{
25+
name: 'Java',
26+
directory: 'java',
27+
extension: 'java'
28+
},
29+
{
30+
name: 'Python',
31+
directory: 'python',
32+
extension: 'py'
33+
},
34+
{
35+
name: 'JavaScript',
36+
directory: 'javascript',
37+
extension: 'js'
38+
},
39+
{
40+
name: 'TypeScript',
41+
directory: 'typescript',
42+
extension: 'ts'
43+
},
44+
{
45+
name: 'Go',
46+
directory: 'go',
47+
extension: 'go'
48+
},
49+
{
50+
name: 'Ruby',
51+
directory: 'ruby',
52+
extension: 'rb'
53+
},
54+
{
55+
name: 'Swift',
56+
directory: 'swift',
57+
extension: 'swift'
58+
},
59+
{
60+
name: 'Kotlin',
61+
directory: 'kotlin',
62+
extension: 'kt'
63+
},
64+
{
65+
name: 'Rust',
66+
directory: 'rust',
67+
extension: 'rs'
68+
},
69+
{
70+
name: 'Scala',
71+
directory: 'scala',
72+
extension: 'scala'
73+
},
74+
]
75+
76+
// Rename files to match leetcode url path, and normalize problem number to four digits.
77+
for (const lang of languages) {
78+
const langDir = lang.directory;
79+
const langExt = lang.extension;
80+
81+
// Get list of all files in the current lang directory
82+
const files = fs.readdirSync(langDir, { withFileTypes: true });
83+
console.log(`This many files in ${langDir}: ${files.length}`);
84+
85+
let counter = 0;
86+
for (const category in PROBLEMS_OBJ) {
87+
for (const problem of PROBLEMS_OBJ[category]) {
88+
const url = problem[1];
89+
90+
// Use leetcode url path to rename each problem for consistency
91+
let problemName = problem[1].replace('https://leetcode.com/problems/', '');
92+
problemName = problemName.replace('/', '').toLowerCase();
93+
94+
// Use problem number to find each problem
95+
const problemNumber = problem[2];
96+
const newProblemNumber = updateProblemNumber(problem[2]);
97+
98+
const foundFile = files.find(file => file.name.startsWith(`${problemNumber.toString()}-`));
99+
if (foundFile && foundFile.isFile()) {
100+
// rename file to match leetcode url path
101+
const oldFile = `${langDir}/${foundFile.name}`;
102+
const newFile = `${langDir}/${newProblemNumber}-${problemName}.${langExt}`;
103+
fs.renameSync(oldFile, newFile);
104+
counter++;
105+
106+
updateSiteData(url, `${newProblemNumber}-${problemName}`, langDir);
107+
}
108+
}
109+
}
110+
console.log(`Renamed ${counter} files in ${langDir}, which had ${files.length} total files.`);
111+
}
112+
113+
// Add leading zeros to make four digits long (24 -> 0024)
114+
function updateProblemNumber(problemNumberInt) {
115+
let problemNumber = problemNumberInt.toString();
116+
while (problemNumber.length < 4) {
117+
problemNumber = '0' + problemNumber;
118+
}
119+
return problemNumber;
120+
}
121+
122+
function updateSiteData(problemUrl, newCodeLink, langName) {
123+
for (const p of PROBLEMS_SITE_DATA) {
124+
if (problemUrl.includes(p.link)) {
125+
p.code = newCodeLink;
126+
p[langName] = true;
127+
return;
128+
}
129+
}
130+
console.log(`Could not find ${problemUrl} in PROBLEMS_SITE_DATA.`);
131+
}
132+
133+
134+
fs.writeFile('./.problemSiteData.json', JSON.stringify(PROBLEMS_SITE_DATA), function (err) {
135+
if (err) throw err;
136+
console.log('Saved!');
137+
});
138+
139+
140+
/** Update problem numbers in .problemList.json */
141+
142+
// for (const category in PROBLEMS_OBJ) {
143+
// for (const problem of PROBLEMS_OBJ[category]) {
144+
// problem[2] = updateProblemNumber(problem[2]);
145+
// }
146+
// }
147+
148+
// fs.writeFile('./.problemList.json', JSON.stringify(PROBLEMS_OBJ), function (err) {
149+
// if (err) throw err;
150+
// console.log('Saved!');
151+
// });

Diff for: ‎.github/workflows/verifySiteData.js

+97
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/** Script to verify code links in ./.problemSiteData.json */
2+
3+
const fs = require('fs');
4+
const https = require('/opt/homebrew/lib/node_modules/sync-request');
5+
6+
const PROBLEMS_SITE_DATA = JSON.parse(fs.readFileSync('./.problemSiteData.json', 'utf8'));
7+
8+
const languageMap = {
9+
c: {
10+
name: 'C',
11+
directory: 'c',
12+
extension: 'c'
13+
},
14+
cpp: {
15+
name: 'C++',
16+
directory: 'cpp',
17+
extension: 'cpp'
18+
},
19+
csharp: {
20+
name: 'C#',
21+
directory: 'csharp',
22+
extension: 'cs'
23+
},
24+
java: {
25+
name: 'Java',
26+
directory: 'java',
27+
extension: 'java'
28+
},
29+
python: {
30+
name: 'Python',
31+
directory: 'python',
32+
extension: 'py'
33+
},
34+
javascript: {
35+
name: 'JavaScript',
36+
directory: 'javascript',
37+
extension: 'js'
38+
},
39+
typescript: {
40+
name: 'TypeScript',
41+
directory: 'typescript',
42+
extension: 'ts'
43+
},
44+
go: {
45+
name: 'Go',
46+
directory: 'go',
47+
extension: 'go'
48+
},
49+
ruby: {
50+
name: 'Ruby',
51+
directory: 'ruby',
52+
extension: 'rb'
53+
},
54+
swift: {
55+
name: 'Swift',
56+
directory: 'swift',
57+
extension: 'swift'
58+
},
59+
kotlin: {
60+
name: 'Kotlin',
61+
directory: 'kotlin',
62+
extension: 'kt'
63+
},
64+
rust: {
65+
name: 'Rust',
66+
directory: 'rust',
67+
extension: 'rs'
68+
},
69+
scala: {
70+
name: 'Scala',
71+
directory: 'scala',
72+
extension: 'scala'
73+
},
74+
};
75+
76+
const GITHUB_BASE_URL = 'https://github.com/neetcode-gh/leetcode/blob/nc-refactor';
77+
78+
let anyErrorCode = false;
79+
for (const problem of PROBLEMS_SITE_DATA) {
80+
for (const language in languageMap) {
81+
if (problem[language] !== true) continue;
82+
83+
const { directory, extension } = languageMap[language];
84+
const codeUrl = `${GITHUB_BASE_URL}/${directory}/${problem.code}.${extension}`;
85+
86+
const res = https('GET', codeUrl).statusCode;
87+
if (res !== 200) {
88+
console.error(codeUrl)
89+
console.error(res)
90+
anyErrorCode = true;
91+
}
92+
}
93+
}
94+
95+
if (anyErrorCode) {
96+
process.exitCode(1)
97+
}

0 commit comments

Comments
 (0)
Please sign in to comment.