Skip to content

Commit 7aedb97

Browse files
committed
feat: read problems on file
1 parent 7da1456 commit 7aedb97

File tree

8 files changed

+236
-74
lines changed

8 files changed

+236
-74
lines changed

cmd/main.go

-2
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,6 @@ func showMeta(lc *leetcode.Leetcode, number string) {
4747
log.Fatal("mate not found")
4848
}
4949
meta.Content = ""
50-
meta.Code = ""
51-
meta.CodeSnippets = ""
5250
fmt.Printf("%+v\n", meta)
5351
}
5452

cmd/new/main.go

+1-3
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@ import (
1010
"strings"
1111
"text/template"
1212

13-
"github.com/tidwall/gjson"
14-
1513
"github.com/zcong1993/leetcode-tool/pkg/leetcode"
1614
)
1715

@@ -115,7 +113,7 @@ func Run(lc *leetcode.Leetcode, n string, lang string) {
115113
n,
116114
}
117115
metaf.Meta.Content = strings.ReplaceAll(metaf.Meta.Content, "↵", "")
118-
metaf.Meta.Code = gjson.Get(metaf.CodeSnippets, fmt.Sprintf("#(lang=%s).code", config.LeetcodeLang)).String()
116+
//metaf.Meta.Code = gjson.Get(metaf.CodeSnippets, fmt.Sprintf("#(lang=%s).code", config.LeetcodeLang)).String()
119117

120118
problemFp := filepath.Join(fp, "problem.md")
121119
if !fileExists(problemFp) {

data/problems.json

+1
Large diffs are not rendered by default.

go.mod

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ require (
66
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect
77
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d // indirect
88
github.com/bmatcuk/doublestar/v2 v2.0.3
9+
github.com/dghubble/sling v1.4.2 // indirect
910
github.com/tidwall/gjson v1.6.3
1011
gopkg.in/alecthomas/kingpin.v2 v2.2.6
1112
)

go.sum

+6
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ github.com/bmatcuk/doublestar/v2 v2.0.3 h1:D6SI8MzWzXXBXZFS87cFL6s/n307lEU+thM2S
66
github.com/bmatcuk/doublestar/v2 v2.0.3/go.mod h1:QMmcs3H2AUQICWhfzLXz+IYln8lRQmTZRptLie8RgRw=
77
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
88
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
9+
github.com/dghubble/sling v1.4.2 h1:vs1HIGBbSl2SEALyU+irpYFLZMfc49Fp+jYryFebQjM=
10+
github.com/dghubble/sling v1.4.2/go.mod h1:o0arCOz0HwfqYQJLrRtqunaWOn4X6jxE/6ORKRpVTD4=
11+
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
12+
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
13+
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
914
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
1015
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
1116
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@@ -17,6 +22,7 @@ github.com/tidwall/match v1.0.1 h1:PnKP62LPNxHKTwvHHZZzdOAOCtsJTjo6dZLCwpKm5xc=
1722
github.com/tidwall/match v1.0.1/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E=
1823
github.com/tidwall/pretty v1.0.2 h1:Z7S3cePv9Jwm1KwS0513MRaoUe3S01WPbLNV40pwWZU=
1924
github.com/tidwall/pretty v1.0.2/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
25+
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
2026
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
2127
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
2228
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=

internal/config/config.go

+2-7
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,15 @@ import (
55
"io/ioutil"
66
)
77

8-
const defaultCookie = "alicfw=1089899001%7C2081167297%7C1328233593%7C1328234352; alicfw_gfver=v1.200309.1"
9-
108
type Config struct {
11-
Lang string `json:"lang"`
12-
Cookie string `json:"cookie"`
9+
Lang string `json:"lang"`
10+
Env string `json:"env"` // eg. en, cn
1311
}
1412

1513
const configPath = ".leetcode.json"
1614

1715
func NewConfig() *Config {
1816
c := loadConfig()
19-
if c.Cookie == "" {
20-
c.Cookie = defaultCookie
21-
}
2217
return &c
2318
}
2419

pkg/leetcode/leetcode.go

+45-62
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,26 @@ package leetcode
22

33
import (
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

1516
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
2425
}
2526

2627
type Tag struct {
@@ -31,86 +32,68 @@ type Tag struct {
3132

3233
var (
3334
difficultyMap = map[string]string{
34-
"Easy": "简单",
35-
"Medium": "中等",
36-
"Hard": "困难",
35+
"easy": "简单",
36+
"medium": "中等",
37+
"hard": "困难",
3738
}
3839
)
3940

4041
type Leetcode struct {
41-
Config *config.Config
42+
Config *config.Config
43+
Problems []byte
4244
}
4345

4446
func NewLeetcode(config *config.Config) *Leetcode {
4547
return &Leetcode{Config: config}
4648
}
4749

4850
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")
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

10792
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()
11195
}
112-
slug := l.findProblemSlugByNumber(problems, number)
113-
return l.getDetail(slug)
96+
return l.getDetail(number)
11497
}
11598

11699
func (l *Leetcode) GetTags() ([]Tag, error) {

0 commit comments

Comments
 (0)