Skip to content

Commit 6aba022

Browse files
committed
feat(api): fetch and parse LeetCode submission details.
1 parent 80a7cc0 commit 6aba022

5 files changed

Lines changed: 140 additions & 6 deletions

File tree

leetcode/api.py

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,29 @@
11
from config.settings import Config
2-
from leetcode.parser import parse_submissions
2+
3+
from leetcode.parser import (
4+
parse_submissions,
5+
parse_submission_detail,
6+
)
7+
38
from leetcode.queries import (
49
PROFILE_QUERY,
510
RECENT_SUBMISSIONS_QUERY,
11+
SUBMISSION_DETAILS_QUERY,
612
)
713

814

915
class LeetCodeAPI:
10-
1116
def __init__(self, client):
1217
self.client = client
1318

1419
def get_profile(self):
20+
"""Fetch the user's profile and solved statistics."""
21+
1522
response = self.client.post(
1623
PROFILE_QUERY,
1724
{
1825
"username": Config.LEETCODE_USERNAME
19-
}
26+
},
2027
)
2128

2229
if "errors" in response:
@@ -25,6 +32,7 @@ def get_profile(self):
2532
return response["data"]["matchedUser"]
2633

2734
def get_recent_submissions(self, limit=15):
35+
"""Fetch the user's recent accepted submissions."""
2836

2937
response = self.client.post(
3038
RECENT_SUBMISSIONS_QUERY,
@@ -39,4 +47,22 @@ def get_recent_submissions(self, limit=15):
3947

4048
return parse_submissions(
4149
response["data"]["recentAcSubmissionList"]
50+
)
51+
52+
def get_submission_detail(self, submission_id):
53+
"""Fetch detailed information about a submission."""
54+
55+
response = self.client.post(
56+
SUBMISSION_DETAILS_QUERY,
57+
{
58+
"submissionId": int(submission_id)
59+
},
60+
)
61+
62+
if "errors" in response:
63+
raise Exception(response["errors"])
64+
65+
return parse_submission_detail(
66+
submission_id,
67+
response["data"]["submissionDetails"],
4268
)

leetcode/models.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,33 @@ class Submission:
99
slug: str
1010
timestamp: int
1111

12+
@property
13+
def date(self):
14+
return datetime.fromtimestamp(self.timestamp)
15+
16+
17+
@dataclass(slots=True)
18+
class SubmissionDetail:
19+
submission_id: str
20+
21+
question_id: str
22+
title_slug: str
23+
24+
language: str
25+
language_verbose: str
26+
27+
runtime: int
28+
runtime_display: str
29+
30+
memory: int
31+
memory_display: str
32+
33+
status_code: int
34+
35+
code: str
36+
37+
timestamp: int
38+
1239
@property
1340
def date(self):
1441
return datetime.fromtimestamp(self.timestamp)

leetcode/parser.py

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
from leetcode.models import Submission
1+
from leetcode.models import Submission, SubmissionDetail
22

33

44
def parse_submissions(data):
5+
"""Parse recent submissions."""
6+
57
submissions = []
68

79
for item in data:
@@ -10,8 +12,34 @@ def parse_submissions(data):
1012
id=item["id"],
1113
title=item["title"],
1214
slug=item["titleSlug"],
13-
timestamp=int(item["timestamp"])
15+
timestamp=int(item["timestamp"]),
1416
)
1517
)
1618

17-
return submissions
19+
return submissions
20+
21+
22+
def parse_submission_detail(submission_id, data):
23+
"""Parse GraphQL response into a SubmissionDetail object."""
24+
25+
return SubmissionDetail(
26+
submission_id=str(submission_id),
27+
28+
question_id=data["question"]["questionId"],
29+
title_slug=data["question"]["titleSlug"],
30+
31+
language=data["lang"]["name"],
32+
language_verbose=data["lang"]["verboseName"],
33+
34+
runtime=data["runtime"],
35+
runtime_display=data["runtimeDisplay"],
36+
37+
memory=data["memory"],
38+
memory_display=data["memoryDisplay"],
39+
40+
status_code=data["statusCode"],
41+
42+
code=data["code"],
43+
44+
timestamp=int(data["timestamp"]),
45+
)

leetcode/queries.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
}
1515
"""
1616

17+
1718
RECENT_SUBMISSIONS_QUERY = """
1819
query recentAcSubmissions($username: String!, $limit: Int!) {
1920
recentAcSubmissionList(
@@ -26,4 +27,33 @@
2627
timestamp
2728
}
2829
}
30+
"""
31+
32+
33+
SUBMISSION_DETAILS_QUERY = """
34+
query submissionDetails($submissionId: Int!) {
35+
submissionDetails(submissionId: $submissionId) {
36+
37+
runtime
38+
runtimeDisplay
39+
40+
memory
41+
memoryDisplay
42+
43+
code
44+
timestamp
45+
46+
statusCode
47+
48+
lang {
49+
name
50+
verboseName
51+
}
52+
53+
question {
54+
questionId
55+
titleSlug
56+
}
57+
}
58+
}
2959
"""

main.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,29 @@ def main():
109109
if new_submissions:
110110
detector.update(new_submissions[0])
111111

112+
detail = api.get_submission_detail(
113+
submissions[0].id
114+
)
112115

116+
console.print("\n[bold cyan]Latest Submission Details[/bold cyan]\n")
117+
118+
console.print(f"Question ID : {detail.question_id}")
119+
console.print(f"Slug : {detail.title_slug}")
120+
console.print(f"Language : {detail.language}")
121+
console.print(f"Runtime : {detail.runtime_display}")
122+
console.print(f"Memory : {detail.memory_display}")
123+
124+
125+
STATUS_MAP = {
126+
10: "Accepted",
127+
11: "Wrong Answer",
128+
12: "Memory Limit Exceeded",
129+
13: "Output Limit Exceeded",
130+
14: "Time Limit Exceeded",
131+
15: "Runtime Error",
132+
16: "Internal Error",
133+
20: "Compile Error",
134+
}
135+
console.print(f"Status : {STATUS_MAP.get(detail.status_code, 'Unknown')}")
113136
if __name__ == "__main__":
114137
main()

0 commit comments

Comments
 (0)