@@ -2,25 +2,26 @@ package leetcode
2
2
3
3
import (
4
4
"encoding/json"
5
+ "errors"
5
6
"fmt"
7
+ "github.com/zcong1993/leetcode-tool/internal/config"
6
8
"io/ioutil"
7
9
"net/http"
10
+ "os"
8
11
"strings"
9
12
10
- "github.com/zcong1993/leetcode-tool/internal/config"
11
-
12
13
"github.com/tidwall/gjson"
13
14
)
14
15
15
16
type Meta struct {
16
- Index string
17
- Title string
18
- Difficulty string
19
- Tags []string
20
- Link string
21
- Content string
22
- Code string
23
- CodeSnippets string
17
+ Index string
18
+ Title string
19
+ Difficulty string
20
+ Tags []string
21
+ Link string
22
+ Content string
23
+ // Code string
24
+ // CodeSnippets string
24
25
}
25
26
26
27
type Tag struct {
@@ -31,86 +32,68 @@ type Tag struct {
31
32
32
33
var (
33
34
difficultyMap = map [string ]string {
34
- "Easy " : "简单" ,
35
- "Medium " : "中等" ,
36
- "Hard " : "困难" ,
35
+ "easy " : "简单" ,
36
+ "medium " : "中等" ,
37
+ "hard " : "困难" ,
37
38
}
38
39
)
39
40
40
41
type Leetcode struct {
41
- Config * config.Config
42
+ Config * config.Config
43
+ Problems []byte
42
44
}
43
45
44
46
func NewLeetcode (config * config.Config ) * Leetcode {
45
47
return & Leetcode {Config : config }
46
48
}
47
49
48
50
func (l * Leetcode ) getAllProblem () ([]byte , error ) {
49
- req , err := http . NewRequest ( http . MethodGet , "https:// leetcode-cn.com/api /problems/all/" , nil )
50
- if err != nil {
51
- return nil , err
51
+ file , err := ioutil . ReadFile ( "/Users/ppsteven/Projects/ leetcode-tool/data /problems.json" )
52
+ if err == os . ErrNotExist {
53
+ return nil , errors . New ( "234324" )
52
54
}
53
- req .Header .Set ("Cookie" , l .Config .Cookie )
54
- resp , err := http .DefaultClient .Do (req )
55
- if err != nil {
56
- return nil , err
57
- }
58
- defer resp .Body .Close ()
59
- return ioutil .ReadAll (resp .Body )
60
- }
61
-
62
- func (l * Leetcode ) findProblemSlugByNumber (problems []byte , number string ) string {
63
- return gjson .GetBytes (problems , fmt .Sprintf ("stat_status_pairs.#(stat.frontend_question_id=\" %s\" ).stat.question__title_slug" , number )).String ()
55
+ return file , nil
64
56
}
65
57
66
- func (l * Leetcode ) getDetail (slug string ) (* Meta , error ) {
67
- if slug == "" {
58
+ func (l * Leetcode ) getDetail (number string ) (* Meta , error ) {
59
+ if number == "" {
68
60
return nil , nil
69
61
}
70
- req , err := http .NewRequest ("POST" , "https://leetcode-cn.com/graphql/" , strings .NewReader (fmt .Sprintf (`{"operationName":"questionData","variables":{"titleSlug": "%s"},"query":"query questionData($titleSlug: String!) {\n question(titleSlug: $titleSlug) {\n questionId\n questionFrontendId\n boundTopicId\n title\n titleSlug\n content\n translatedTitle\n translatedContent\n isPaidOnly\n difficulty\n likes\n dislikes\n isLiked\n similarQuestions\n contributors {\n username\n profileUrl\n avatarUrl\n __typename\n }\n langToValidPlayground\n topicTags {\n name\n slug\n translatedName\n __typename\n }\n companyTagStats\n codeSnippets {\n lang\n langSlug\n code\n __typename\n }\n stats\n hints\n solution {\n id\n canSeeDetail\n __typename\n }\n status\n sampleTestCase\n metaData\n judgerAvailable\n judgeType\n mysqlSchemas\n enableRunCode\n envInfo\n book {\n id\n bookName\n pressName\n source\n shortDescription\n fullDescription\n bookImgUrl\n pressImgUrl\n productUrl\n __typename\n }\n isSubscribed\n isDailyQuestion\n dailyRecordStatus\n editorType\n ugcQuestionId\n style\n __typename\n }\n}\n"}` , slug )))
71
- req .Header .Add ("Accept" , "application/json, text/plain, */*" )
72
- req .Header .Add ("Content-Type" , "application/json;charset=utf-8" )
73
- req .Header .Add ("User-Agent" , "axios/0.19.2" )
74
- req .Header .Add ("Host" , "leetcode-cn.com" )
75
- if err != nil {
76
- return nil , err
77
- }
78
- resp , err := http .DefaultClient .Do (req )
79
- if err != nil {
80
- return nil , err
81
- }
82
- defer resp .Body .Close ()
83
- content , err := ioutil .ReadAll (resp .Body )
84
- if err != nil {
85
- return nil , err
86
- }
87
- tagsResult := gjson .GetBytes (content , "data.question.topicTags.#.slug" ).Array ()
62
+
63
+ problem := gjson .GetBytes (l .Problems , fmt .Sprintf ("%s" , number ))
64
+
65
+ tagsResult := problem .Get ("topicTags.#.slug" ).Array ()
88
66
tags := make ([]string , len (tagsResult ))
89
67
for i , t := range tagsResult {
90
68
tags [i ] = t .String ()
91
69
}
92
70
93
- codeSnippets := gjson .GetBytes (content , "data.question.codeSnippets" ).String ()
71
+ title := "title"
72
+ difficulty := problem .Get ("difficulty" ).String ()
73
+ content := "content.en"
74
+ if l .Config .Env == "cn" {
75
+ title = "titleCn"
76
+ content = "content.cn"
77
+ difficulty = difficultyMap [strings .ToLower (difficulty )]
78
+ }
79
+ title = problem .Get (title ).String ()
80
+ content = problem .Get (content ).String ()
94
81
95
82
return & Meta {
96
- Index : gjson .GetBytes (content , "data.question.questionId" ).String (),
97
- Title : gjson .GetBytes (content , "data.question.translatedTitle" ).String (),
98
- Difficulty : difficultyMap [gjson .GetBytes (content , "data.question.difficulty" ).String ()],
99
- Tags : tags ,
100
- Link : fmt .Sprintf ("https://leetcode-cn.com/problems/%s/" , gjson .GetBytes (content , "data.question.titleSlug" ).String ()),
101
- Content : gjson .GetBytes (content , "data.question.translatedContent" ).String (),
102
- Code : gjson .GetBytes (content , "data.question.codeSnippets.#(lang=Go).code" ).String (),
103
- CodeSnippets : codeSnippets ,
83
+ Index : number ,
84
+ Title : title ,
85
+ Difficulty : difficulty ,
86
+ Tags : tags ,
87
+ Link : fmt .Sprintf ("https://leetcode.cn/problems/%s/description/" , problem .Get ("titleSlug" ).String ()),
88
+ Content : content ,
104
89
}, nil
105
90
}
106
91
107
92
func (l * Leetcode ) GetMetaByNumber (number string ) (* Meta , error ) {
108
- problems , err := l .getAllProblem ()
109
- if err != nil {
110
- return nil , err
93
+ if l .Problems == nil {
94
+ l .Problems , _ = l .getAllProblem ()
111
95
}
112
- slug := l .findProblemSlugByNumber (problems , number )
113
- return l .getDetail (slug )
96
+ return l .getDetail (number )
114
97
}
115
98
116
99
func (l * Leetcode ) GetTags () ([]Tag , error ) {
0 commit comments