From 64d1b135081a3cdeebd001f96d169ccd24fec041 Mon Sep 17 00:00:00 2001 From: Leigh MacDonald Date: Thu, 23 Feb 2023 03:01:46 -0700 Subject: [PATCH] Download lists in parallel. --- application.go | 16 ---------------- lists.go | 35 ++++++++++++++++++++++++----------- ui/chat.go | 8 ++------ ui/names.go | 2 +- ui/players.go | 15 ++++++++++----- 5 files changed, 37 insertions(+), 39 deletions(-) diff --git a/application.go b/application.go index 1b69062..11d1ad2 100644 --- a/application.go +++ b/application.go @@ -679,22 +679,6 @@ func (bd *BD) Shutdown() { if bd.settings.DiscordPresenceEnabled { client.Logout() } - // Ensure we save on exit - playerListFile, playerListFileErr := os.Create(bd.settings.LocalPlayerListPath()) - if playerListFileErr != nil { - log.Panicf("Failed to open player list for writing: %v\n", playerListFileErr) - } - if errWrite := bd.rules.ExportPlayers(rules.LocalRuleName, playerListFile); errWrite != nil { - log.Panicf("Failed to export player list: %v\n", playerListFileErr) - } - - rulesFile, rulesFileErr := os.Create(bd.settings.LocalRulesListPath()) - if rulesFileErr != nil { - log.Panicf("Failed to open player list for writing: %v\n", rulesFileErr) - } - if errWrite := bd.rules.ExportRules(rules.LocalRuleName, rulesFile); errWrite != nil { - log.Panicf("Failed to export rules list: %v\n", rulesFileErr) - } logClose(bd.store) } diff --git a/lists.go b/lists.go index 5c98366..6b4b56e 100644 --- a/lists.go +++ b/lists.go @@ -9,6 +9,7 @@ import ( "io" "log" "net/http" + "sync" ) func fetchURL(ctx context.Context, client http.Client, url string) ([]byte, error) { @@ -31,35 +32,47 @@ func fetchURL(ctx context.Context, client http.Client, url string) ([]byte, erro func downloadLists(ctx context.Context, lists []model.ListConfig) ([]rules.PlayerListSchema, []rules.RuleSchema) { var playerLists []rules.PlayerListSchema var rulesLists []rules.RuleSchema + mu := &sync.RWMutex{} client := http.Client{} - for _, u := range lists { - if !u.Enabled { - continue - } + downloadFn := func(u model.ListConfig) error { body, errFetch := fetchURL(ctx, client, u.URL) if errFetch != nil { - log.Printf("Failed to fetch player list: %v", u.URL) - continue + return errors.Wrapf(errFetch, "Failed to fetch player list: %s", u.URL) } switch u.ListType { case model.ListTypeTF2BDPlayerList: var result rules.PlayerListSchema if errParse := rules.ParsePlayerSchema(bytes.NewReader(body), &result); errParse != nil { - log.Printf("Failed to parse request: %v\n", errParse) - continue + return errors.Wrap(errParse, "Failed to parse request") } + mu.Lock() playerLists = append(playerLists, result) + mu.Unlock() log.Printf("Downloaded playerlist successfully: %s\n", result.FileInfo.Title) case model.ListTypeTF2BDRules: var result rules.RuleSchema if errParse := rules.ParseRulesList(bytes.NewReader(body), &result); errParse != nil { - log.Printf("Failed to parse request: %v\n", errParse) - continue + return errors.Wrap(errParse, "Failed to parse request") } + mu.Lock() rulesLists = append(rulesLists, result) + mu.Unlock() log.Printf("Downloaded rules successfully: %s\n", result.FileInfo.Title) } - + return nil + } + wg := &sync.WaitGroup{} + for _, listConfig := range lists { + if !listConfig.Enabled { + continue + } + wg.Add(1) + go func(lc model.ListConfig) { + defer wg.Done() + if errDL := downloadFn(lc); errDL != nil { + log.Printf("Failed to download list: %v", errDL) + } + }(listConfig) } return playerLists, rulesLists } diff --git a/ui/chat.go b/ui/chat.go index 578d424..01ac4fa 100644 --- a/ui/chat.go +++ b/ui/chat.go @@ -32,7 +32,7 @@ func (chatList *userMessageList) Reload(rr []model.UserMessage) error { if errReload := chatList.boundList.Reload(); errReload != nil { return errReload } - chatList.list.Refresh() + chatList.list.ScrollToBottom() return nil } @@ -60,16 +60,12 @@ func (ui *Ui) createGameChatMessageList() *userMessageList { userMessageListWidget := widget.NewListWithData( boundList, func() fyne.CanvasObject { - rootContainer := container.NewBorder( + return container.NewBorder( nil, nil, container.NewHBox(widget.NewLabel(""), newContextMenuRichText(nil)), nil, widget.NewRichTextWithText("")) - - rootContainer.Refresh() - - return rootContainer }, func(i binding.DataItem, o fyne.CanvasObject) { value := i.(binding.Untyped) diff --git a/ui/names.go b/ui/names.go index bb6958a..53b6f4d 100644 --- a/ui/names.go +++ b/ui/names.go @@ -32,7 +32,7 @@ func (nameList *userNameList) Reload(rr []model.UserNameHistory) error { if errReload := nameList.boundList.Reload(); errReload != nil { return errReload } - nameList.list.Refresh() + nameList.list.ScrollToBottom() return nil } diff --git a/ui/players.go b/ui/players.go index a3afff8..eaee86c 100644 --- a/ui/players.go +++ b/ui/players.go @@ -254,6 +254,11 @@ func (ui *Ui) generateUserMenu(steamId steamid.SID64, userId int64) *fyne.Menu { // │ K: 10 A: 66 │ // └─────────────────────────────────────────────────────────┘ func (ui *Ui) createPlayerList() *PlayerList { + const ( + symbolOk = "✓" + symbolBad = "✗" + ) + //iconSize := fyne.NewSize(64, 64) pl := &PlayerList{} boundList := binding.BindUntypedList(&[]interface{}{}) @@ -316,20 +321,20 @@ func (ui *Ui) createPlayerList() *PlayerList { profileLabel.Refresh() var vacState []string if ps.NumberOfVACBans > 0 { - vacState = append(vacState, fmt.Sprintf("VB: %d", ps.NumberOfGameBans)) + vacState = append(vacState, fmt.Sprintf("VB: %s", strings.Repeat(symbolBad, ps.NumberOfVACBans))) } if ps.NumberOfGameBans > 0 { - vacState = append(vacState, fmt.Sprintf("GB: %d", ps.NumberOfVACBans)) + vacState = append(vacState, fmt.Sprintf("GB: %s", strings.Repeat(symbolBad, ps.NumberOfGameBans))) } if ps.CommunityBanned { - vacState = append(vacState, "CB: ✓") + vacState = append(vacState, fmt.Sprintf("CB: %s", symbolBad)) } if ps.EconomyBan { - vacState = append(vacState, "EB: ✓") + vacState = append(vacState, fmt.Sprintf("EB: %s", symbolBad)) } vacStyle := stlBad if len(vacState) == 0 { - vacState = append(vacState, "✓") + vacState = append(vacState, symbolOk) vacStyle = stlOk }