-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathgen_readme.py
More file actions
210 lines (172 loc) · 6.24 KB
/
gen_readme.py
File metadata and controls
210 lines (172 loc) · 6.24 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
# -*- coding: UTF-8 -*-
import os
import requests
import json
import re
import sys
# usage: python leetcode.py <username> <dir> <num>
# > Please input topic link:
Remove = ["</?p>", "</?ul>", "</?ol>", "</li>", "</sup>"]
Replace = [[" ", " "], [""", '"'], ["<", "<"], [">", ">"],
["≤", "≤"], ["≥", "≥"], ["<sup>", "^"], ["'", "'"],
["×", "x"], ["“", "“"], ["”", "”"],
[" *<strong> *", " **"], [" *</strong> *", "** "],
[" *<code> *", " `"], [" *</code> *", "` "], ["<pre>", "```\n"],
["</pre>", "\n```\n"], ["<em> *</em>", ""], [" *<em> *", " *"],
[" *</em> *", "* "], ["</?div.*?>", ""], [" *</?li>", "- "]]
markdown_format = """# {titlename}
## 1. 题目描述
{Content}
## 2. 解题
"""
graphql_query = '''query getQuestionDetail($titleSlug: String!) {
question(titleSlug: $titleSlug) {
questionId
questionFrontendId
title
titleSlug
content
translatedTitle
translatedContent
difficulty
topicTags {
name
slug
translatedName
__typename
}
codeSnippets {
lang
langSlug
code
__typename
}
__typename
}
}'''
gotest_template = """import (
"testing"
)
func Test_{0}(t *testing.T){{
panic("not implemented") // TODO: Implement
}}
"""
def convert(src):
# pre内部预处理
def remove_label_in_pre(matched):
tmp = matched.group()
tmp = re.sub("<[^>p]*>", "", tmp) # 不匹配>与p
return tmp
src = re.sub("<pre>[\s\S]*?</pre>", remove_label_in_pre,
src) # 注意此处非贪心匹配,因为可能有多个示例
# 可以直接删除的标签
for curPattern in Remove:
src = re.sub(curPattern, "", src)
# 需要替换内容的标签
for curPattern, curRepl in Replace:
src = re.sub(curPattern, curRepl, src)
return src
def get_all(slug: str) -> dict:
"""
根据题目的 id 获取题目的名字,内容,代码块,标签,返回 json 格式的 dict 对象
"""
user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.122 Safari/537.36"
session = requests.Session()
url = "https://leetcode.cn/graphql"
params = {
'operationName':
"getQuestionDetail",
'variables': {
'titleSlug': slug
},
'query': graphql_query
}
json_data = json.dumps(params).encode('utf8')
headers = {
'User-Agent': user_agent,
'Connection': 'keep-alive',
'Content-Type': 'application/json',
'Referer': 'https://leetcode-cn.com/problems/' + slug
}
resp = session.post(url, data=json_data, headers=headers, timeout=10)
resp.encoding = 'utf8'
content = resp.json()
question = content['data']['question']
return question
def get_problem_content(slug: str) -> str:
question = get_all(slug)
res = convert(question['translatedContent'])
# 在正文后面填上标签
res += "\n \n**标签**\n"
tags = question['topicTags']
for tag in tags:
if tag['translatedName'] != None:
tagName = tag['translatedName']
else:
tagName = tag['name']
res += "`" + tagName + "` "
return res + "\n"
def get_solution_by_lang(slug: str, lang: str) -> str:
"""
获取给定题目的对应语言的函数
支持的参数如下
C++ Java Python Python3 C C# JavaScript Ruby Swift Go Scala Kotlin
Rust PHP TypeScript Racket
"""
question = get_all(slug)
# 获取对应语言的函数
codeSnippets = question['codeSnippets']
for x in codeSnippets:
if x['lang'] == lang:
return x['code']
def gen_markdown(path, content, title):
"""
生成 markdown 文件
"""
file = open(path, 'a', encoding="utf-8")
markdown_content = markdown_format.format(
titlename=title, Content=content)
file.write(markdown_content)
print("Generate readme.md in: ", path)
file.close()
def gen_files(url: str, username: str, dir: str, num: str):
"""
根据 url 生成对应的文件
"""
if url.startswith("https://leetcode.cn/problems/"):
slug = url.replace("https://leetcode.cn/problems/", "",
1).strip('/')
else:
print("Generate readme.md failed. Got Wrong URL!!!\nIt should be like https://leetcode-cn.com/problems/evaluate-division/")
return
url = "https://leetcode.cn/problems/" + slug
# 获取一些变量
question = get_all(slug=slug)
title = question['questionFrontendId'] + '.' + question['translatedTitle']
content = get_problem_content(slug)
raw_func = get_solution_by_lang(slug, 'Go')
func = re.compile(r'({\n.*?\n})').sub(
"{\n\tpanic(\"not implemented\") // TODO: Implement\n}", raw_func, 1)
content = re.sub(r'\n\n\n\n*', "\n", content) # 替换掉多个换行符
func_name = re.compile(r'(func\s\w+)').findall(raw_func)[0].split(" ")[-1]
test_func = gotest_template.format(func_name)
# 获取当前目录
base_dir = os.getcwd()
# 生成 markdown 文件
go_package = dir+num
filepath = os.path.join(base_dir, username,
dir, go_package, "readme.md")
gen_markdown(filepath, content, title)
# 向go文件中写入解题函数
with open(os.path.join(base_dir, username, dir, go_package, go_package+".go"), mode='a') as go_file:
go_file.write("\n")
go_file.write(func)
# 向go_test文件中写入测试函数
with open(os.path.join(base_dir, username, dir, go_package, go_package+"_test"+".go"), mode='a') as test_file:
test_file.write("\n")
test_file.write(test_func)
return
if __name__ == '__main__':
url = input("请输入题目链接: ")
gen_files(url=url, username=sys.argv[1], dir=sys.argv[2], num=sys.argv[3])
# gen_files(url=url, username="yangchnet", dir="goden", num="0103")