@@ -2,25 +2,26 @@ package leetcode
22
33import (
44 "encoding/json"
5+ "errors"
56 "fmt"
7+ "github.com/zcong1993/leetcode-tool/internal/config"
68 "io/ioutil"
79 "net/http"
10+ "os"
811 "strings"
912
10- "github.com/zcong1993/leetcode-tool/internal/config"
11-
1213 "github.com/tidwall/gjson"
1314)
1415
1516type 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
2425}
2526
2627type Tag struct {
@@ -31,86 +32,68 @@ type Tag struct {
3132
3233var (
3334 difficultyMap = map [string ]string {
34- "Easy " : "简单" ,
35- "Medium " : "中等" ,
36- "Hard " : "困难" ,
35+ "easy " : "简单" ,
36+ "medium " : "中等" ,
37+ "hard " : "困难" ,
3738 }
3839)
3940
4041type Leetcode struct {
41- Config * config.Config
42+ Config * config.Config
43+ Problems []byte
4244}
4345
4446func NewLeetcode (config * config.Config ) * Leetcode {
4547 return & Leetcode {Config : config }
4648}
4749
4850func (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" )
5254 }
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
6456}
6557
66- func (l * Leetcode ) getDetail (slug string ) (* Meta , error ) {
67- if slug == "" {
58+ func (l * Leetcode ) getDetail (number string ) (* Meta , error ) {
59+ if number == "" {
6860 return nil , nil
6961 }
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 ()
8866 tags := make ([]string , len (tagsResult ))
8967 for i , t := range tagsResult {
9068 tags [i ] = t .String ()
9169 }
9270
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 ()
9481
9582 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 ,
10489 }, nil
10590}
10691
10792func (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 ()
11195 }
112- slug := l .findProblemSlugByNumber (problems , number )
113- return l .getDetail (slug )
96+ return l .getDetail (number )
11497}
11598
11699func (l * Leetcode ) GetTags () ([]Tag , error ) {
0 commit comments