Skip to content

Commit 100d46a

Browse files
committed
feat(downloader): implement complete solution download pipeline.
1 parent 0d339f6 commit 100d46a

2 files changed

Lines changed: 73 additions & 40 deletions

File tree

leetcode/downloader.py

Lines changed: 70 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import json
12
from pathlib import Path
23

34
from config.settings import Config
@@ -8,38 +9,34 @@ class SubmissionDownloader:
89
Handles downloading and storing LeetCode submissions locally.
910
"""
1011

12+
LANGUAGE_FILES = {
13+
"python3": "solution.py",
14+
"python": "solution.py",
15+
"java": "Solution.java",
16+
"cpp": "solution.cpp",
17+
"c": "solution.c",
18+
"javascript": "solution.js",
19+
"typescript": "solution.ts",
20+
"go": "solution.go",
21+
"rust": "solution.rs",
22+
"kotlin": "Solution.kt",
23+
"swift": "solution.swift",
24+
"csharp": "Solution.cs",
25+
}
26+
1127
def __init__(self):
1228
self.solutions_dir = Config.STORAGE_DIR / "solutions"
29+
self.solutions_dir.mkdir(parents=True, exist_ok=True)
1330

14-
# Create storage/solutions if it doesn't exist
15-
self.solutions_dir.mkdir(
16-
parents=True,
17-
exist_ok=True,
31+
@classmethod
32+
def get_solution_filename(cls, language: str) -> str:
33+
return cls.LANGUAGE_FILES.get(
34+
language.lower(),
35+
"solution.txt",
1836
)
1937

20-
@staticmethod
21-
def get_solution_filename(language: str) -> str:
22-
mapping = {
23-
"python3": "solution.py",
24-
"java": "Solution.java",
25-
"cpp": "solution.cpp",
26-
"c": "solution.c",
27-
"javascript": "solution.js",
28-
}
29-
30-
return mapping.get(language, "solution.txt")
31-
3238
@staticmethod
3339
def _format_folder_name(question_id: str, slug: str) -> str:
34-
"""
35-
Convert:
36-
295
37-
find-median-from-data-stream
38-
39-
Into:
40-
0295_Find_Median_from_Data_Stream
41-
"""
42-
4340
problem_number = str(question_id).zfill(4)
4441

4542
title = "_".join(
@@ -50,10 +47,6 @@ def _format_folder_name(question_id: str, slug: str) -> str:
5047
return f"{problem_number}_{title}"
5148

5249
def create_problem_directory(self, detail) -> Path:
53-
"""
54-
Create the directory for a problem if it doesn't already exist.
55-
"""
56-
5750
folder_name = self._format_folder_name(
5851
detail.question_id,
5952
detail.title_slug,
@@ -67,22 +60,62 @@ def create_problem_directory(self, detail) -> Path:
6760
)
6861

6962
return problem_dir
70-
7163

7264
def save_solution(self, detail) -> Path:
73-
"""
74-
Save the source code into the appropriate solution file.
75-
"""
76-
77-
filename = self.get_solution_filename(detail.language)
78-
7965
problem_dir = self.create_problem_directory(detail)
8066

67+
filename = self.get_solution_filename(
68+
detail.language
69+
)
70+
8171
solution_file = problem_dir / filename
8272

8373
solution_file.write_text(
8474
detail.code,
8575
encoding="utf-8",
8676
)
8777

88-
return solution_file
78+
return solution_file
79+
80+
def save_metadata(self, detail) -> Path:
81+
problem_dir = self.create_problem_directory(detail)
82+
83+
metadata = {
84+
"submission_id": detail.submission_id,
85+
"question_id": detail.question_id,
86+
"title_slug": detail.title_slug,
87+
"language": detail.language,
88+
"language_verbose": detail.language_verbose,
89+
"runtime": detail.runtime_display,
90+
"memory": detail.memory_display,
91+
"status_code": detail.status_code,
92+
"timestamp": detail.timestamp,
93+
}
94+
95+
metadata_file = problem_dir / "metadata.json"
96+
97+
metadata_file.write_text(
98+
json.dumps(metadata, indent=4),
99+
encoding="utf-8",
100+
)
101+
102+
return metadata_file
103+
104+
def download(self, detail) -> Path:
105+
"""
106+
Complete download pipeline.
107+
108+
Creates directory,
109+
saves solution,
110+
saves metadata.
111+
112+
Returns problem directory.
113+
"""
114+
115+
problem_dir = self.create_problem_directory(detail)
116+
117+
self.save_solution(detail)
118+
119+
self.save_metadata(detail)
120+
121+
return problem_dir

main.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,10 +140,10 @@ def main():
140140

141141
downloader = SubmissionDownloader()
142142

143-
solution_path = downloader.save_solution(detail)
144-
143+
folder = downloader.download(detail)
144+
145145
console.print(
146-
f"\n[bold green]Solution saved:[/bold green]\n{solution_path}"
146+
f"\n[bold green]Solution saved:[/bold green]\n{folder}"
147147
)
148148

149149
if __name__ == "__main__":

0 commit comments

Comments
 (0)