-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathleetcode_graphql.py
More file actions
242 lines (203 loc) · 6.44 KB
/
Copy pathleetcode_graphql.py
File metadata and controls
242 lines (203 loc) · 6.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
import requests
import time
import json
import sys
url = "https://leetcode.com/graphql/"
problem = "add-two-numbers"
def getTopicID(problem, target_lang="python3"):
variables = {
"query": "", # optional search string
"languageTags": [target_lang], # filter by language
"topicTags": [problem], # filter by topic
"questionSlug": problem, # slug of the problem
"skip": 0, # pagination offset
"first": 1, # number of results
"orderBy": "hot" # sort option (e.g. "hot", "newest")
}
# GraphQL query string
query = """
query communitySolutions(
$questionSlug: String!,
$skip: Int!,
$first: Int!,
$query: String,
$orderBy: TopicSortingOption,
$languageTags: [String!],
$topicTags: [String!]
) {
questionSolutions(
filters: {
questionSlug: $questionSlug,
skip: $skip,
first: $first,
query: $query,
orderBy: $orderBy,
languageTags: $languageTags,
topicTags: $topicTags
}
) {
hasDirectResults
totalNum
solutions {
id
title
commentCount
viewCount
solutionTags {
name
slug
}
post {
id
status
voteCount
creationDate
author {
username
profile {
userAvatar
reputation
}
}
}
}
}
}
"""
# Build payload
payload = {
"query": query,
"variables": variables
}
headers = {"Content-Type": "application/json"}
response = extractResponse(headers, payload, "community.json", "all_community.json")
return response["data"]["questionSolutions"]["solutions"][0]["id"]
def getContent(saveContent = True, path1="content.json", path2="all_content.json"):
# 1. Load JSON file
with open("solution.json", "r", encoding="utf-8") as f:
data = json.load(f)
# 2. Extract the content field
content = data["data"]["topic"]["post"]["content"]
# 3. Decode escape sequences so \n -> actual newlines
# First encode to bytes, then decode with "unicode_escape"
#cleaned_content = content.encode("utf-8").decode("unicode_escape")
try:
# Wrap in quotes and use json.loads to handle all escape sequences properly
cleaned_content = json.loads(f'"{content}"')
except json.JSONDecodeError:
# Fallback to manual replacement if json.loads fails
cleaned_content = content.replace('\\n', '\n').replace('\\t', '\t').replace('\\"', '"').replace('\\\\', '\\')
full_content = {
problem: {
"content": cleaned_content
}
}
if saveContent:
with open("content.txt", "w", encoding="utf-8") as f:
f.write(cleaned_content)
# Load existing content or create empty dict if file doesn't exist
try:
with open(path2, "r", encoding="utf-8") as f:
all_content = json.load(f)
except (FileNotFoundError, json.JSONDecodeError):
all_content = {}
# Update the dictionary with new content (this will merge, not overwrite)
all_content.update(full_content)
with open(path2, "w", encoding="utf-8") as f:
json.dump(all_content, f, indent=4, ensure_ascii=False)
# 4. Print nicely
#print(cleaned_content)
def getSolution(topicId):
# define your variable here
#topicId = 3678229
# build the query and variables as Python objects
payload = {
"query": """
query communitySolution($topicId: Int!) {
topic(id: $topicId) {
id
viewCount
topLevelCommentCount
subscribed
title
pinned
solutionTags {
name
slug
}
hideFromTrending
commentCount
isFavorite
post {
id
voteCount
voteStatus
content
updationDate
creationDate
status
isHidden
author {
isDiscussAdmin
isDiscussStaff
username
nameColor
activeBadge {
displayName
icon
}
profile {
userAvatar
reputation
}
isActive
}
authorIsModerator
isOwnPost
}
}
}
""",
"variables": {"topicId": topicId}
}
headers = {
"Content-Type": "application/json"
}
return extractResponse(headers, payload, "solution.json", "all_solutions.json")
def extractResponse(headers, payload, path1, path2):
# use json= to auto-convert dict to JSON
time.sleep(0.5)
response = requests.post(url, headers=headers, json=payload)
data = response.json()
with open(path1, "w", encoding="utf-8") as f:
json.dump(data, f, indent=4)
solutions = []
with open(path2, "r", encoding="utf-8") as f:
solutions = json.load(f)
solutions.append(data)
with open(path2, "w", encoding="utf-8") as f:
json.dump(solutions, f, indent=4)
#print(json.dumps(data, indent=4))
return data
def main(arg=None, problem_slug=None, target_lang="python"):
# Use provided problem_slug or default to global 'problem'
global problem
problem = problem_slug
if arg is None:
topicID = getTopicID(problem)
getSolution(topicID)
getContent()
elif arg == "1":
getContent()
elif arg == "2":
topicID = getTopicID(problem)
getSolution(topicID)
else:
print("Usage: python leetcode-graphql.py [1|2]")
return 1
if __name__ == "__main__":
arg = sys.argv[1] if len(sys.argv) > 1 else None
main(arg)
#topicID = getTopicID("two-sum")
#solution = getSolution(topicID)
#getContent()