From 2699983dab1783e8882ed4ff864ad78d224f3024 Mon Sep 17 00:00:00 2001 From: aocgame Date: Thu, 19 Dec 2019 09:44:51 +0800 Subject: [PATCH] =?UTF-8?q?=E7=94=A8cookie=E7=99=BB=E5=BD=95=E5=BA=94?= =?UTF-8?q?=E5=AF=B9leetcode=E4=B8=BB=E7=AB=99=E7=99=BB=E5=BD=95=E6=9C=BA?= =?UTF-8?q?=E5=88=B6=E7=9A=84=E8=B0=83=E6=95=B4=E3=80=81=E9=80=9A=E8=BF=87?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E8=8E=B7=E5=8F=96=E9=A2=98=E7=9B=AE=E4=B8=8E?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=A8=A1=E7=89=88=E6=9D=A5=E5=A1=AB=E5=85=85?= =?UTF-8?q?=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Helper/README.md | 4 +- Helper/buildProblemDir.go | 27 ++++++++----- Helper/config.go | 1 + Helper/leetcode-getGraphql.go | 75 +++++++++++++++++++++++++++++++++++ Helper/problemGoFile.go | 2 +- Helper/problemReadme.go | 10 +++-- Helper/signin.go | 30 ++++++++------ 7 files changed, 120 insertions(+), 29 deletions(-) create mode 100644 Helper/leetcode-getGraphql.go diff --git a/Helper/README.md b/Helper/README.md index 3c73ded9e..24a2908f5 100644 --- a/Helper/README.md +++ b/Helper/README.md @@ -6,8 +6,10 @@ 1. 在`LeetCode-in-Go`目录下,添加文本文件`config.toml`。 1. 把以下内容复制到`config.toml`中。 1. 把`config.toml`中的`test`分别修改为你的 leetcode `用户名`和`密码`。 +1. 去 leetcode 登录后,把网站 cookie 复制 (有洁癖者只要复制 LEETCODE_SESSION 就够了) 并替换 `config.toml`中的`Cookie`。 ```toml -Login="test" +Username="test" Password="test" +Cookie="LEETCODE_SESSION=XXXXXXXXX;" ``` \ No newline at end of file diff --git a/Helper/buildProblemDir.go b/Helper/buildProblemDir.go index c9172d7fd..514ced343 100644 --- a/Helper/buildProblemDir.go +++ b/Helper/buildProblemDir.go @@ -4,7 +4,6 @@ import ( "fmt" "log" "os" - "os/exec" "runtime/debug" "strings" "syscall" @@ -52,6 +51,7 @@ func build(p problem) { } }() + // windows用户注释这两行 mask := syscall.Umask(0) defer syscall.Umask(mask) @@ -63,24 +63,29 @@ func build(p problem) { log.Printf("开始创建 %d %s 的文件夹...\n", p.ID, p.Title) + content, fc := getGraphql(p) + if fc == "" { + log.Panicf("查无Go语言写法") + } + // 利用 chrome 打开题目页面 - go func() { - cmd := exec.Command("google-chrome", p.link()) - _, err = cmd.Output() - if err != nil { - panic(err.Error()) - } - }() + // go func() { + // cmd := exec.Command("google-chrome", p.link()) + // _, err = cmd.Output() + // if err != nil { + // panic(err.Error()) + // } + // }() - fc := getFunction(p.link()) + // fc := getFunction(p.link()) - fcName, para, ans, fc := parseFunction(fc) + fcName, para, ans, _ := parseFunction(fc) creatGo(p, fc, ans) creatGoTest(p, fcName, para, ans) - creatREADME(p) + creatREADME(p, content) log.Printf("%d.%s 的文件夹,创建完毕。\n", p.ID, p.Title) } diff --git a/Helper/config.go b/Helper/config.go index b01103c76..b2c78f007 100644 --- a/Helper/config.go +++ b/Helper/config.go @@ -14,6 +14,7 @@ const ( type config struct { Username string Password string + Cookie string // 以下是电子邮件设置 SMTP string diff --git a/Helper/leetcode-getGraphql.go b/Helper/leetcode-getGraphql.go new file mode 100644 index 000000000..1de75871a --- /dev/null +++ b/Helper/leetcode-getGraphql.go @@ -0,0 +1,75 @@ +package main + +import ( + "bytes" + "encoding/json" + "io/ioutil" + "log" + "net/http" +) + +type JsL4CodeSnippets []struct { + Lang string + Code string +} + +type JsL3Detail struct { + Content string + CodeSnippets JsL4CodeSnippets +} + +type JsL2Question struct { + Question JsL3Detail +} + +type JsL1Data struct { + Data JsL2Question +} + +func getGraphql(p problem) (string, string) { + // req := newReq() + + params := make(map[string]interface{}) + params["operationName"] = "questionData" + params["query"] = "query questionData($titleSlug: String!) { question(titleSlug: $titleSlug) { content codeSnippets { lang code } } }" + titleSlug := make(map[string]string) + titleSlug["titleSlug"] = p.TitleSlug + params["variables"] = titleSlug + + // Make this JSON + postJson, _ := json.Marshal(params) + + // http.POST expects an io.Reader, which a byte buffer does + postContent := bytes.NewBuffer(postJson) + + resp, err := http.Post("https://leetcode.com/graphql", "application/json", postContent) + if err != nil { + log.Fatal("getGraphql: POST Error: " + err.Error()) + } + + defer resp.Body.Close() + + if resp.StatusCode != 200 { + log.Fatal("抓题失败 code: " + resp.Status) + } + + respBytes, err := ioutil.ReadAll(resp.Body) + if err != nil { + log.Fatal("getGraphql: Read Error: " + err.Error()) + } + + //byte数组直接转成string,优化内存 + // str := (*string)(unsafe.Pointer(&respBytes)) + // fmt.Printf("%#v\n", *str) + + res := &JsL1Data{} + json.Unmarshal(respBytes, &res) + + code := "" + for _, qc := range res.Data.Question.CodeSnippets { + if qc.Lang == "Go" { + code = qc.Code + } + } + return res.Data.Question.Content, code +} diff --git a/Helper/problemGoFile.go b/Helper/problemGoFile.go index 6a039f86b..bae9b9832 100644 --- a/Helper/problemGoFile.go +++ b/Helper/problemGoFile.go @@ -9,7 +9,7 @@ import ( ) func parseFunction(fc string) (fcName, para, ansType, nfc string) { - log.Println("准备分解函数:", fc) + log.Println("正在分解函数") defer func() { // 必须要先声明defer,否则不能捕获到panic异常 if err := recover(); err != nil { diff --git a/Helper/problemReadme.go b/Helper/problemReadme.go index 532a80847..b8ae5f559 100644 --- a/Helper/problemReadme.go +++ b/Helper/problemReadme.go @@ -4,9 +4,11 @@ import ( "fmt" "sort" "strings" + + "github.com/TruthHun/html2md" ) -func creatREADME(p problem) { +func creatREADME(p problem, s string) { fileFormat := `# [%d. %s](%s) %s @@ -14,10 +16,12 @@ func creatREADME(p problem) { questionDescription := strings.TrimSpace(getDescription(p.link())) - content := fmt.Sprintf(fileFormat, p.ID, p.Title, p.link(), questionDescription) + content := fmt.Sprintf(fileFormat, p.ID, p.Title, p.link(), questionDescription) + s + "\n\n## 解题思路\n\n## 可能的變化" content = replaceCharacters(content) + content = html2md.Convert(content) + filename := fmt.Sprintf("%s/README.md", p.Dir()) write(filename, content) @@ -36,7 +40,7 @@ func replaceCharacters(s string) string { "<": "<", ">": ">", "≥": ">=", - " ": "`", + " ": " ", "&": "&", "'": "'", " \n": "\n", diff --git a/Helper/signin.go b/Helper/signin.go index b630d8b3a..6ed97f200 100644 --- a/Helper/signin.go +++ b/Helper/signin.go @@ -23,7 +23,7 @@ func newReq() *request.Request { // 登录 leetcode // 返回的 req 带有 cookie func signin() *request.Request { - log.Println("正在登录中...") + // log.Println("正在登录中...") cfg := getConfig() // 对 req 赋值 @@ -31,25 +31,29 @@ func signin() *request.Request { // 配置request req.Headers = map[string]string{ + "Content-Type": "application/json", "Accept-Encoding": "", - "Referer": "https://leetcode.com/", + "cookie": cfg.Cookie, + "Referer": "https://leetcode.com/accounts/login/", + "origin": "https://leetcode.com", } // login - csrfToken := getCSRFToken(req) + // csrfToken := getCSRFToken(req) - log.Printf("csrfToken: %s", csrfToken) + // log.Printf("csrfToken: %s", csrfToken) - req.Data = map[string]string{ - "csrfmiddlewaretoken": csrfToken, - "login": cfg.Username, - "password": cfg.Password, - } - if err := login(req); err != nil { - log.Fatal(err) - } + // req.Data = map[string]string{ + // "csrfmiddlewaretoken": csrfToken, + // "login": cfg.Username, + // "password": cfg.Password, + // "next": "problems", + // } + // if err := login(req); err != nil { + // log.Fatal(err) + // } - log.Println("成功登录") + // log.Println("成功登录") return req }