Repos / gorts / 050f917fd7
commit 050f917fd77b203484257f8e17ad6b1ca36c5fe3
Author: Nhân <hi@imnhan.com>
Date:   Thu Jun 22 21:23:42 2023 +0700

    fetch players from smashgg

diff --git a/main.go b/main.go
index e4f9420..28b0206 100644
--- a/main.go
+++ b/main.go
@@ -14,7 +14,6 @@
 	"os/exec"
 	"strconv"
 	"strings"
-	"time"
 
 	"go.imnhan.com/gorts/netstring"
 	"go.imnhan.com/gorts/players"
@@ -175,10 +174,17 @@ func startGUI(tclPath string) {
 		case "fetchplayers":
 			startggInputs.Token = req[1]
 			startggInputs.Slug = req[2]
-			time.Sleep(3 * time.Second)
+			ps, err := startgg.FetchPlayers(startggInputs)
 			fmt.Fprintln(stdin, "fetchplayers__resp")
-			respond("All done.")
+			if err != nil {
+				respond("err", fmt.Sprintf("Error: %s", err))
+				break
+			}
+			allplayers = ps
+			// TODO: show write errors to user instead of ignoring
 			startggInputs.Write(StartggFile)
+			players.Write(PlayersFile, allplayers)
+			respond("ok", fmt.Sprintf("Successfully fetched %d players.", len(allplayers)))
 		}
 	}
 
diff --git a/players/players.go b/players/players.go
index 18b7895..25cde1c 100644
--- a/players/players.go
+++ b/players/players.go
@@ -2,6 +2,7 @@
 
 import (
 	"encoding/csv"
+	"fmt"
 	"log"
 	"os"
 	"regexp"
@@ -57,3 +58,17 @@ func normalize(in string) (out string) {
 func (p *Player) MatchesName(query string) bool {
 	return strings.Contains(normalize(p.Name), normalize(query))
 }
+
+func Write(filepath string, ps []Player) error {
+	f, err := os.Create(filepath)
+	if err != nil {
+		return fmt.Errorf("write players to file: %w", err)
+	}
+	defer f.Close()
+
+	writer := csv.NewWriter(f)
+	for _, p := range ps {
+		writer.Write([]string{p.Name, p.Country, p.Team})
+	}
+	return nil
+}
diff --git a/startgg/startgg.go b/startgg/startgg.go
index c62cc74..1ea76d1 100644
--- a/startgg/startgg.go
+++ b/startgg/startgg.go
@@ -5,6 +5,7 @@
 	"bytes"
 	_ "embed"
 	"encoding/json"
+	"errors"
 	"fmt"
 	"io/ioutil"
 	"net/http"
@@ -49,6 +50,7 @@ func (c *Inputs) Write(filepath string) {
 	}
 }
 
+// TODO: follow pagination
 func FetchPlayers(i Inputs) ([]players.Player, error) {
 	query := `
 {
@@ -99,10 +101,67 @@ func FetchPlayers(i Inputs) ([]players.Player, error) {
 	defer resp.Body.Close()
 
 	respdata, err := ioutil.ReadAll(resp.Body)
-	fmt.Println(">>>>", string(respdata))
+	//fmt.Println(">>>>", string(respdata[:50]))
 
-	//var res map[string]interface{}
-	//json.NewDecoder(resp.Body).Decode(&res)
-	//fmt.Println(res["json"])
-	return nil, nil
+	if resp.StatusCode != http.StatusOK {
+		respJson := struct {
+			Message string `json:"message"`
+		}{}
+		err = json.Unmarshal(respdata, &respJson)
+		if err != nil {
+			return nil, fmt.Errorf(
+				"Unexpected %d response: %s", resp.StatusCode, respdata,
+			)
+		}
+		return nil, errors.New(respJson.Message)
+	}
+
+	respJson := struct {
+		Data struct {
+			Tournament struct {
+				Participants struct {
+					Nodes []struct {
+						// TODO: read team names from entrants too
+						GamerTag string `json:"gamerTag"`
+						Prefix   string `json:"prefix"`
+						User     struct {
+							Location struct {
+								Country string `json:"country"`
+							} `json:"location"`
+						} `json:"user"`
+					} `json:"nodes"`
+				} `json:"participants"`
+			} `json:"tournament"`
+		} `json:"data"`
+	}{}
+
+	err = json.Unmarshal(respdata, &respJson)
+	if err != nil {
+		return nil, fmt.Errorf(
+			"Unexpected %d response: %s", resp.StatusCode, respdata,
+		)
+	}
+
+	participants := respJson.Data.Tournament.Participants.Nodes
+	results := make([]players.Player, len(participants))
+	for i, part := range participants {
+		p := players.Player{}
+
+		if part.Prefix == "" {
+			p.Name = part.GamerTag
+		} else {
+			p.Name = fmt.Sprintf("%s %s", part.Prefix, part.GamerTag)
+		}
+
+		code, ok := countryNameToCode[part.User.Location.Country]
+		if ok {
+			p.Country = code
+		} else if code != "" {
+			fmt.Printf("*** Unknown country: %s\n", part.User.Location.Country)
+		}
+
+		results[i] = p
+	}
+
+	return results, nil
 }
diff --git a/tcl/main.tcl b/tcl/main.tcl
index 006f7d1..cab8226 100644
--- a/tcl/main.tcl
+++ b/tcl/main.tcl
@@ -296,7 +296,16 @@ proc fetchplayers {} {
 }
 
 proc fetchplayers__resp {} {
-    set ::startgg(msg) [lindex [ipc_read] 0]
+    set resp [ipc_read]
+    set status [lindex $resp 0]
+    set msg [lindex $resp 1]
+
+    set ::startgg(msg) $msg
+
+    if {$status == "ok"} {
+        loadplayernames
+    }
+
     .n.s.fetch configure -state normal
     .n.s.token configure -state normal
     .n.s.tournamentslug configure -state normal