Skip to content

Commit 1c0cd24

Browse files
committed
Update README auto updates
1 parent 018d81a commit 1c0cd24

File tree

1 file changed

+34
-38
lines changed

1 file changed

+34
-38
lines changed

Scripts/update_project_readme.py

Lines changed: 34 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,59 @@
11
import os
22
import re
3-
import requests
43
from pathlib import Path
4+
import requests
55

66
SRC_DIR = "Solutions"
77
SITE_README_PATH = Path("Site_README.md")
88
GITHUB_README_PATH = Path("README.md")
9+
LINK_ICON = "🔗"
910

10-
LINK_ICON = "🔗" # Unicode link icon
11-
12-
def fetch_problem_data(slug: str):
13-
"""Fetch problem number, difficulty, and tags from LeetCode GraphQL API."""
11+
def fetch_question_details(slug: str):
12+
"""Fetch difficulty and tags from LeetCode GraphQL API."""
1413
url = "https://leetcode.com/graphql"
1514
query = {
1615
"query": """
1716
query getQuestionDetail($titleSlug: String!) {
1817
question(titleSlug: $titleSlug) {
19-
frontendQuestionId
2018
difficulty
21-
topicTags { name }
19+
topicTags {
20+
name
21+
slug
22+
}
2223
}
2324
}
2425
""",
2526
"variables": {"titleSlug": slug},
2627
}
27-
headers = {
28-
"Content-Type": "application/json",
29-
"User-Agent": "Mozilla/5.0",
30-
"Referer": f"https://leetcode.com/problems/{slug}/"
31-
}
3228
try:
33-
resp = requests.post(url, json=query, headers=headers, timeout=10)
29+
resp = requests.post(url, json=query, timeout=10)
3430
resp.raise_for_status()
35-
data = resp.json()["data"]["question"]
36-
number = data.get("frontendQuestionId", "")
37-
difficulty = data.get("difficulty", "")
38-
tags = [t["name"] for t in data.get("topicTags", [])]
39-
return number, difficulty, tags
31+
data = resp.json()
32+
question = data.get("data", {}).get("question")
33+
if not question:
34+
print(f"⚠️ No question data returned for slug: {slug}")
35+
return "", []
36+
difficulty = question.get("difficulty", "")
37+
tags = [tag.get("name") for tag in question.get("topicTags", []) if tag.get("name")]
38+
return difficulty, tags
4039
except Exception as e:
41-
print(f"Failed to fetch {slug}: {e}")
42-
return "", "", []
40+
print(f"Failed to fetch question details for {slug}: {e}")
41+
return "", []
4342

44-
# MkDocs HTML badge
43+
# MkDocs badge
4544
def difficulty_badge_site(difficulty: str) -> str:
4645
colors = {"Easy": "#46c6c2", "Medium": "#fac31d", "Hard": "#f8615c"}
46+
color = colors.get(difficulty, "#9E9E9E")
4747
if not difficulty:
4848
return ""
49-
color = colors.get(difficulty, "#9E9E9E")
5049
return f'<span style="background-color:#ffffff1a; color:{color}; padding:2px 6px; border-radius:6px;">{difficulty}</span>'
5150

52-
# GitHub Shields.io badge
51+
# GitHub badge
5352
def difficulty_badge_github(difficulty: str) -> str:
5453
colors = {"Easy": "4c1", "Medium": "f9c851", "Hard": "e05d44"}
54+
color = colors.get(difficulty, "9e9e9e")
5555
if not difficulty:
5656
return ""
57-
color = colors.get(difficulty, "9e9e9e")
5857
badge_url = f"https://img.shields.io/badge/Difficulty-{difficulty}-{color}.svg"
5958
return f"![{difficulty}]({badge_url})"
6059

@@ -63,40 +62,40 @@ def generate_table_rows(problems, badge_func):
6362
for slug, number, title, difficulty, tags in problems:
6463
diff_badge = badge_func(difficulty)
6564
tags_str = ", ".join(tags)
66-
solution_link = f"https://leetcode.romitsagu.com/solutions/leetcode{number}#/"
65+
solution_link = f"https://leetcode.romitsagu.com/solutions/leetcode{number}/"
6766
icon_md = f"[{LINK_ICON}]({solution_link})"
6867
rows.append(f"| {title} | {icon_md} | {diff_badge} | {tags_str} |")
6968
return "\n".join(rows)
7069

7170
def update_readme(readme_path, rows_str):
71+
"""Update the README table; creates one if not present."""
7272
if not readme_path.exists():
7373
raise FileNotFoundError(f"{readme_path} does not exist")
7474

7575
readme_text = readme_path.read_text()
76-
pattern = re.compile(
77-
r'(\| Problem \| Solution \| Difficulty \| Tags \|\n\|[-| ]+\|\n)(.*?)(\n|$)',
76+
# Match the full table
77+
table_pattern = re.compile(
78+
r'(\| Problem \| Solution \| Difficulty \| Tags \s*\|\n\|[-| ]+\|\n)(.*?)(?=\n\| |\Z)',
7879
re.DOTALL
7980
)
8081

81-
if pattern.search(readme_text):
82-
updated_text = pattern.sub(r"\1" + rows_str + r"\3", readme_text)
83-
print(f"Updated table rows in {readme_path.name}")
82+
if table_pattern.search(readme_text):
83+
updated_text = table_pattern.sub(r"\1" + rows_str, readme_text)
84+
print(f"Updated table rows in {readme_path.name}")
8485
else:
8586
new_table = (
8687
"| Problem | Solution | Difficulty | Tags |\n"
8788
"|---------|---------|------------|------|\n"
8889
+ rows_str
8990
)
9091
updated_text = readme_text.strip() + "\n\n" + new_table
91-
print(f"Added new table in {readme_path.name}")
92+
print(f"Added new table in {readme_path.name}")
9293

9394
readme_path.write_text(updated_text)
94-
print(f"{readme_path.name} updated successfully.")
9595

9696
def main():
9797
problems = []
9898

99-
# Step 1: Read all problem folders and fetch data
10099
for folder in sorted(os.listdir(SRC_DIR)):
101100
folder_path = Path(SRC_DIR) / folder
102101
if not folder_path.is_dir():
@@ -109,15 +108,12 @@ def main():
109108
folder_number = str(int(folder_number))
110109
title = f"{folder_number}. " + " ".join([w.capitalize() for w in slug.split("-")])
111110

112-
# Fetch API data once
113-
number, difficulty, tags = fetch_problem_data(slug)
114-
problems.append((slug, number, title, difficulty, tags))
111+
difficulty, tags = fetch_question_details(slug)
112+
problems.append((slug, folder_number, title, difficulty, tags))
115113

116-
# Step 2: Generate table rows
117114
site_rows = generate_table_rows(problems, difficulty_badge_site)
118115
github_rows = generate_table_rows(problems, difficulty_badge_github)
119116

120-
# Step 3: Update both READMEs
121117
update_readme(SITE_README_PATH, site_rows)
122118
update_readme(GITHUB_README_PATH, github_rows)
123119

0 commit comments

Comments
 (0)