Skip to content

Commit 855d420

Browse files
author
Shuo
authored
Merge pull request #592 from openset/develop
Add: parallel
2 parents 5cb5efd + 6949120 commit 855d420

File tree

9 files changed

+57
-33
lines changed

9 files changed

+57
-33
lines changed

internal/base/base.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,15 @@ import (
1010
"path"
1111
"path/filepath"
1212
"strings"
13+
"sync"
1314
)
1415

1516
const CmdName = "leetcode"
1617

17-
var Commands []*Command
18+
var (
19+
Commands []*Command
20+
Mutex sync.Mutex
21+
)
1822

1923
type Command struct {
2024
Run func(cmd *Command, args []string)

internal/description/description.go

+17-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package description
22

33
import (
4+
"sync"
5+
46
"github.com/openset/leetcode/internal/base"
57
"github.com/openset/leetcode/internal/leetcode"
68
)
@@ -16,13 +18,22 @@ func runDescription(cmd *base.Command, args []string) {
1618
if len(args) != 0 {
1719
cmd.Usage()
1820
}
21+
var wg sync.WaitGroup
22+
tokens := make(chan bool, 1<<7)
1923
problems := leetcode.ProblemsAll()
2024
for _, problem := range problems.StatStatusPairs {
21-
titleSlug := problem.Stat.QuestionTitleSlug
22-
question := leetcode.QuestionData(titleSlug, false).Data.Question
23-
if question.Content == "" && problem.PaidOnly == true && problem.Stat.QuestionArticleLive {
24-
question.Content = leetcode.GetDescription(problem.Stat.QuestionArticleSlug)
25-
}
26-
question.SaveContent()
25+
wg.Add(1)
26+
tokens <- true
27+
go func(problem leetcode.StatStatusPairsType) {
28+
titleSlug := problem.Stat.QuestionTitleSlug
29+
question := leetcode.QuestionData(titleSlug, false).Data.Question
30+
if question.Content == "" && problem.PaidOnly == true && problem.Stat.QuestionArticleLive {
31+
question.Content = leetcode.GetDescription(problem.Stat.QuestionArticleSlug)
32+
}
33+
question.SaveContent()
34+
<-tokens
35+
wg.Done()
36+
}(problem)
2737
}
38+
wg.Wait()
2839
}

internal/leetcode/base.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ var (
2323
translationSet = make(map[int]string)
2424
)
2525

26-
func graphQLRequest(filename string, days int, jsonStr string, v interface{}) {
26+
func graphQLRequest(graphQL, jsonStr, filename string, days int, v interface{}) {
2727
data := remember(filename, days, func() []byte {
2828
return client.PostJson(graphQL, jsonStr)
2929
})

internal/leetcode/config.go

-2
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,3 @@ const (
2727
questionArticleFile = "question_article_%s.html"
2828
topicTagFile = "topic_tag_%s.json"
2929
)
30-
31-
var graphQL = graphQLCnUrl

internal/leetcode/problems_all.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,13 @@ type problemsType struct {
2727
AcEasy int `json:"ac_easy"`
2828
AcMedium int `json:"ac_medium"`
2929
AcHard int `json:"ac_hard"`
30-
StatStatusPairs []statStatusPairsType `json:"stat_status_pairs"`
30+
StatStatusPairs []StatStatusPairsType `json:"stat_status_pairs"`
3131
FrequencyHigh int `json:"frequency_high"`
3232
FrequencyMid int `json:"frequency_mid"`
3333
CategorySlug string `json:"category_slug"`
3434
}
3535

36-
type statStatusPairsType struct {
36+
type StatStatusPairsType struct {
3737
Stat statType `json:"stat"`
3838
Status string `json:"status"`
3939
Difficulty difficultyType `json:"difficulty"`
@@ -62,7 +62,7 @@ type difficultyType struct {
6262

6363
type paidType bool
6464

65-
func (problem statStatusPairsType) WriteRow(buf *bytes.Buffer) {
65+
func (problem StatStatusPairsType) WriteRow(buf *bytes.Buffer) {
6666
format := "| <span id=\"%d\">%d</span> | [%s](https://leetcode.com/problems/%s%s)%s | [%s](https://github.com/openset/leetcode/tree/master/problems/%s) | %s |\n"
6767
id := problem.Stat.FrontendQuestionId
6868
stat := problem.Stat

internal/leetcode/question_data.go

+8-7
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import (
1212
"unicode"
1313
)
1414

15-
func QuestionData(titleSlug string, isForce bool) (qd questionDataType) {
15+
func QuestionData(titleSlug string, isForce bool, graphQL ...string) (qd questionDataType) {
1616
jsonStr := `{
1717
"operationName": "questionData",
1818
"variables": {
@@ -24,19 +24,20 @@ func QuestionData(titleSlug string, isForce bool) (qd questionDataType) {
2424
if isForce {
2525
days = 0
2626
}
27+
if len(graphQL) == 0 {
28+
graphQL = []string{graphQLCnUrl}
29+
}
2730
filename := fmt.Sprintf(questionDataFile, slugToSnake(titleSlug))
28-
graphQLRequest(filename, days, jsonStr, &qd)
31+
graphQLRequest(graphQL[0], jsonStr, filename, days, &qd)
2932
if qd.Data.Question.TitleSlug == "" {
3033
_ = os.Remove(getCachePath(filename))
31-
if graphQL == graphQLCnUrl {
32-
graphQL = graphQLUrl
33-
return QuestionData(titleSlug, isForce)
34+
if graphQL[0] == graphQLCnUrl {
35+
return QuestionData(titleSlug, isForce, graphQLUrl)
3436
}
3537
for _, err := range qd.Errors {
3638
log.Println(titleSlug, err.Message)
3739
}
3840
}
39-
graphQL = graphQLCnUrl
4041
return
4142
}
4243

@@ -68,7 +69,7 @@ type questionType struct {
6869
Dislikes int `json:"dislikes"`
6970
IsLiked int `json:"isLiked"`
7071
SimilarQuestions string `json:"similarQuestions"`
71-
TopicTags []tagType `json:"topicTags"`
72+
TopicTags []TagType `json:"topicTags"`
7273
CodeSnippets []codeSnippetsType `json:"codeSnippets"`
7374
Hints []string `json:"hints"`
7475
MysqlSchemas []string `json:"mysqlSchemas"`

internal/leetcode/question_translation.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ func GetQuestionTranslation() (qt questionTranslationType) {
1212
"variables": {},
1313
"query": "query getQuestionTranslation($lang: String) {\n translations: allAppliedQuestionTranslations(lang: $lang) {\n title\n question {\n questionId\n __typename\n }\n __typename\n }\n}\n"
1414
}`
15-
graphQLRequest(questionTranslationFile, 2, jsonStr, &qt)
15+
graphQLRequest(graphQLCnUrl, jsonStr, questionTranslationFile, 2, &qt)
1616
if qt.Data.Translations == nil {
1717
_ = os.Remove(getCachePath(questionTranslationFile))
1818
for _, err := range qt.Errors {

internal/leetcode/topic_tag.go

+14-11
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,12 @@ import (
1010
"sort"
1111
"strconv"
1212

13+
"github.com/openset/leetcode/internal/base"
1314
"github.com/openset/leetcode/internal/client"
1415
)
1516

1617
var (
17-
initTags []tagType
18+
initTags []TagType
1819
tagsFile = path.Join("tag", "tags.json")
1920
)
2021

@@ -25,25 +26,27 @@ func init() {
2526
reg := regexp.MustCompile(`href="/tag/(\S+?)/"`)
2627
for _, matches := range reg.FindAllStringSubmatch(string(html), -1) {
2728
if len(matches) >= 2 {
28-
initTags = append(initTags, tagType{Slug: matches[1]})
29+
initTags = append(initTags, TagType{Slug: matches[1]})
2930
}
3031
}
3132
}
3233

33-
func GetTags() (tags []tagType) {
34+
func GetTags() (tags []TagType) {
3435
cts := fileGetContents(tagsFile)
3536
jsonDecode(cts, &tags)
3637
tags = tagsUnique(tags)
3738
return
3839
}
3940

40-
func saveTags(tags []tagType) {
41+
func saveTags(tags []TagType) {
42+
base.Mutex.Lock()
4143
tags = append(GetTags(), tags...)
4244
filePutContents(tagsFile, jsonEncode(tagsUnique(tags)))
45+
base.Mutex.Unlock()
4346
}
4447

45-
func tagsUnique(tags []tagType) []tagType {
46-
rs, top := make([]tagType, 0, len(tags)), 1
48+
func tagsUnique(tags []TagType) []TagType {
49+
rs, top := make([]TagType, 0, len(tags)), 1
4750
tags = append(initTags, tags...)
4851
var flag = make(map[string]int)
4952
for _, tag := range tags {
@@ -74,7 +77,7 @@ func GetTopicTag(slug string) (tt topicTagType) {
7477
"query": "query getTopicTag($slug: String!) {\n topicTag(slug: $slug) {\n name\n translatedName\n questions {\n status\n questionId\n questionFrontendId\n title\n titleSlug\n translatedTitle\n stats\n difficulty\n isPaidOnly\n topicTags {\n name\n translatedName\n slug\n __typename\n }\n __typename\n }\n frequencies\n __typename\n }\n favoritesLists {\n publicFavorites {\n ...favoriteFields\n __typename\n }\n privateFavorites {\n ...favoriteFields\n __typename\n }\n __typename\n }\n}\n\nfragment favoriteFields on FavoriteNode {\n idHash\n id\n name\n isPublicFavorite\n viewCount\n creator\n isWatched\n questions {\n questionId\n title\n titleSlug\n __typename\n }\n __typename\n}\n"
7578
}`
7679
filename := fmt.Sprintf(topicTagFile, slugToSnake(slug))
77-
graphQLRequest(filename, 2, jsonStr, &tt)
80+
graphQLRequest(graphQLCnUrl, jsonStr, filename, 2, &tt)
7881
if tt.Data.TopicTag.Name == "" {
7982
_ = os.Remove(getCachePath(filename))
8083
for _, err := range tt.Errors {
@@ -84,7 +87,7 @@ func GetTopicTag(slug string) (tt topicTagType) {
8487
return
8588
}
8689

87-
type tagType struct {
90+
type TagType struct {
8891
Name string
8992
Slug string
9093
TranslatedName string
@@ -114,7 +117,7 @@ type ttQuestionType struct {
114117
TranslatedContent string `json:"translatedContent"`
115118
IsPaidOnly paidType `json:"isPaidOnly"`
116119
Difficulty string `json:"difficulty"`
117-
TopicTags []tagType `json:"topicTags"`
120+
TopicTags []TagType `json:"topicTags"`
118121
}
119122

120123
func (question ttQuestionType) TagsStr() string {
@@ -127,7 +130,7 @@ func (question ttQuestionType) TagsStr() string {
127130
return string(buf.Bytes())
128131
}
129132

130-
func (tag tagType) SaveContents() {
133+
func (tag TagType) SaveContents() {
131134
questions := GetTopicTag(tag.Slug).Data.TopicTag.Questions
132135
sort.Slice(questions, func(i, j int) bool {
133136
m, _ := strconv.Atoi(questions[i].QuestionFrontendId)
@@ -150,7 +153,7 @@ func (tag tagType) SaveContents() {
150153
filePutContents(filename, buf.Bytes())
151154
}
152155

153-
func (tag tagType) ShowName() string {
156+
func (tag TagType) ShowName() string {
154157
if tag.TranslatedName != "" {
155158
return tag.TranslatedName
156159
}

internal/tag/tag.go

+8-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"bytes"
55
"fmt"
66
"reflect"
7+
"sync"
78

89
"github.com/openset/leetcode/internal/base"
910
"github.com/openset/leetcode/internal/leetcode"
@@ -20,6 +21,7 @@ func runTag(cmd *base.Command, args []string) {
2021
if len(args) != 0 {
2122
cmd.Usage()
2223
}
24+
var wg sync.WaitGroup
2325
var buf bytes.Buffer
2426
buf.WriteString(base.AuthInfo("tag"))
2527
buf.WriteString("\n## 话题分类\n\n")
@@ -38,11 +40,16 @@ func runTag(cmd *base.Command, args []string) {
3840
if i&1 == 1 {
3941
buf.WriteString("\n")
4042
}
41-
tag.SaveContents()
43+
wg.Add(1)
44+
go func(tag leetcode.TagType) {
45+
tag.SaveContents()
46+
wg.Done()
47+
}(tag)
4248
}
4349
if reflect.DeepEqual(tags, leetcode.GetTags()) {
4450
break
4551
}
4652
}
4753
base.FilePutContents("tag/README.md", buf.Bytes())
54+
wg.Wait()
4855
}

0 commit comments

Comments
 (0)