diff --git a/.gitignore b/.gitignore index f63a89a..74d6ec3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ # binary +teamsnap-team-gen # credentials google_sheets_credentials.json diff --git a/go.mod b/go.mod index 6ebb4aa..14f55d0 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/brijs/teamsnap-team-gen go 1.16 require ( + github.com/sirupsen/logrus v1.8.1 golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d golang.org/x/oauth2 v0.0.0-20210810183815-faf39c7919d5 google.golang.org/api v0.54.0 diff --git a/go.sum b/go.sum index 04fb66d..0bb75dc 100644 --- a/go.sum +++ b/go.sum @@ -54,6 +54,8 @@ github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnht github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -148,13 +150,18 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -284,6 +291,7 @@ golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -517,6 +525,7 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/main.go b/main.go index baaea87..b1b11bf 100644 --- a/main.go +++ b/main.go @@ -3,13 +3,13 @@ package main import ( "flag" "fmt" - "log" "os" "time" sheets "github.com/brijs/teamsnap-team-gen/sheets" teamgen "github.com/brijs/teamsnap-team-gen/teamgen" ts "github.com/brijs/teamsnap-team-gen/teamsnap" + log "github.com/sirupsen/logrus" ) var Usage = func() { @@ -17,6 +17,20 @@ var Usage = func() { flag.PrintDefaults() } +func init() { + // Log as JSON instead of the default ASCII formatter. + // log.SetFormatter(&log.JSONFormatter{}) + + // Output to stdout instead of the default stderr + // Can be any io.Writer, see below for File example + log.SetOutput(os.Stdout) + + // Only log the warning severity or above. + log.SetLevel(log.InfoLevel) + + // log.SetReportCaller(true) +} + func main() { // flags var ( @@ -31,7 +45,7 @@ func main() { flag.Func("date", "Specify reference date (eg 2021/08/14). The script will find the first upcoming match after that date", func(flagValue string) error { layout := "2006/01/02" if date, err = time.Parse(layout, flagValue); err != nil { - fmt.Println(err) + log.Error(err) return err } return err @@ -44,12 +58,12 @@ func main() { flag.Parse() teamId := teamNameLookup[groupName] - fmt.Println("Running for Teamsnap Team = (", teamId, groupName, "), for date=", date) + log.Info("Running for Teamsnap Team = (", teamId, groupName, "), for date=", date) if opsNewSheet { - log.Println("Creating a new sheet & exiting") + log.Info("Creating a new sheet & exiting") url := sheets.CreateNewSheet() - log.Println("New Spreadsheet URL: ", url) + log.Info("New Spreadsheet URL: ", url) return } @@ -57,37 +71,37 @@ func main() { // 1. Get all players in team players, _ := tsClient.GetAllPlayersInTeam(teamId) - // printDebugInfo(players) + printDebugInfo(players) // 2. Get Upcoming match nextMatch, _ := tsClient.GetUpcomingEvent(teamId, date) - fmt.Printf("Event => %+v\n", nextMatch) + log.Infof("Event => %+v", nextMatch) // 3. Get Player availability tsClient.GetAvailability(nextMatch.Id, players) - // printDebugInfo(players) + printDebugInfo(players) // 4. Get Volunteer assignments tsClient.GetAssignments(nextMatch.Id, teamId, players) - // printDebugInfo(players) + printDebugInfo(players) sheetsService := sheets.NewService() // 5. Get Stick team pref sheetsService.GetPreferredTeam(groupName, players) teamAName, teamBName := sheetsService.GetTeamInfo(groupName) - // printDebugInfo(players) + printDebugInfo(players) // 6. Split into teams teamA, teamB := teamgen.AssignTeamsToAvailablePlayers(players, getRotation(nextMatch, teamRotationOffset), teamAName, teamBName) - // printDebugInfo(teamA) - // printDebugInfo(teamB) + printDebugInfo(teamA) + printDebugInfo(teamB) // 7. Get Volunteers volunteers := teamgen.GetVolunteers(players) - // printDebugInfo(volunteers) + printDebugInfo(volunteers) // 8. Format / publish to spreadsheet sheetsService.PublishMatch(nextMatch, teamA, teamB, volunteers, groupName, teamAName, teamBName) - fmt.Println("Successfully completed generated teams for ", groupName) + log.Info("Successfully completed generated teams for ", groupName) } diff --git a/sheets/sheets.go b/sheets/sheets.go index 14fce37..6571e75 100644 --- a/sheets/sheets.go +++ b/sheets/sheets.go @@ -1,12 +1,12 @@ package sheets import ( - "fmt" "io/ioutil" - "log" + "time" ts "github.com/brijs/teamsnap-team-gen/teamsnap" + log "github.com/sirupsen/logrus" "golang.org/x/net/context" "golang.org/x/oauth2/google" "google.golang.org/api/sheets/v4" @@ -49,7 +49,7 @@ func NewService() *Service { } func (s *Service) PublishMatch(nextMatch ts.Event, teamA []*ts.Player, teamB []*ts.Player, volunteers []*ts.Player, groupName string, teamAName string, teamBName string) { - fmt.Println("PublishMatch") + log.Info("PublishMatch") ctx := context.Background() rangeData := groupName + "_Match!A1:Z1000" @@ -109,7 +109,7 @@ func (s *Service) PublishMatch(nextMatch ts.Event, teamA []*ts.Player, teamB []* } func (s *Service) GetPreferredTeam(teamName string, players []*ts.Player) { - fmt.Println("GetPreferredTeamMappings") + log.Info("GetPreferredTeamMappings") ctx := context.Background() readRange := getPreferredTeamRangeName(teamName) @@ -126,20 +126,20 @@ func (s *Service) GetPreferredTeam(teamName string, players []*ts.Player) { } if len(resp.Values) == 0 { - fmt.Println("No data found.") + log.Warn("No data found.") } else { // fmt.Println("Name, Name, Team") for _, row := range resp.Values { // Print columns A through C, which correspond to indices 0 and 4. if len(row) > 2 { - // fmt.Printf("%s, %s, %s\n", row[0], row[1], row[2]) + log.Trace("%s, %s, %s\n", row[0], row[1], row[2]) key := row[0].(string) + " " + row[1].(string) if temp[key] != nil { temp[key].PreferredTeam = row[2].(string) } } if len(row) == 2 { // no mappings - // fmt.Printf("%s, %s\n", row[0], row[1]) + log.Trace("%s, %s\n", row[0], row[1]) } } @@ -149,7 +149,7 @@ func (s *Service) GetPreferredTeam(teamName string, players []*ts.Player) { } func (s *Service) GetTeamInfo(teamName string) (teamAName string, teamBName string) { - fmt.Println("GetTeamInfo") + log.Info("GetTeamInfo") ctx := context.Background() readRange := getTeamInfoRangeName(teamName) @@ -160,7 +160,7 @@ func (s *Service) GetTeamInfo(teamName string) (teamAName string, teamBName stri // build a map for all players for quick lookup if len(resp.Values) == 0 { - fmt.Println("No data found.") + log.Warn("No data found.") } if len(resp.Values) < 3 || len(resp.Values[1]) < 2 || len(resp.Values[2]) < 2 { log.Fatalln("TeamInfo Range not found or missing rows.") diff --git a/sheets/sheets_util.go b/sheets/sheets_util.go index 1f26a8b..7197e94 100644 --- a/sheets/sheets_util.go +++ b/sheets/sheets_util.go @@ -3,10 +3,10 @@ package sheets import ( "encoding/json" "fmt" - "log" "net/http" "os" + log "github.com/sirupsen/logrus" "golang.org/x/net/context" "golang.org/x/oauth2" ) @@ -65,7 +65,7 @@ func deleteTokenFile() { // Saves a token to a file path. func saveToken(path string, token *oauth2.Token) { - fmt.Printf("Saving credential file to: %s\n", path) + log.Info("Saving credential file to: %s\n", path) f, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600) if err != nil { log.Fatalf("Unable to cache oauth token: %v", err) diff --git a/teamgen/teamgen.go b/teamgen/teamgen.go index 4dde25b..c982600 100644 --- a/teamgen/teamgen.go +++ b/teamgen/teamgen.go @@ -1,12 +1,12 @@ package teamgen import ( - "fmt" "math" "sort" "strings" ts "github.com/brijs/teamsnap-team-gen/teamsnap" + log "github.com/sirupsen/logrus" ) type adj struct { @@ -64,7 +64,7 @@ func filterByTeamNameAndSort(players []*ts.Player, teamName string, rotation int return } func AssignTeamsToAvailablePlayers(players []*ts.Player, rotation int, teamAName string, teamBName string) (teamA []*ts.Player, teamB []*ts.Player) { - fmt.Println("AssignTeamsToAvailablePlayers") + log.Info("AssignTeamsToAvailablePlayers") total, a, b := 0, 0, 0 // get current team counts @@ -115,7 +115,7 @@ func AssignTeamsToAvailablePlayers(players []*ts.Player, rotation int, teamAName } func GetVolunteers(players []*ts.Player) (ret []*ts.Player) { - fmt.Println("GetVolunteers") + log.Info("GetVolunteers") // filter Available players for _, p := range players { diff --git a/teamsnap/tsApi.go b/teamsnap/tsApi.go index 71a2beb..f8992d8 100644 --- a/teamsnap/tsApi.go +++ b/teamsnap/tsApi.go @@ -2,10 +2,11 @@ package ts import ( "fmt" - "log" "net/http" "strconv" "time" + + log "github.com/sirupsen/logrus" ) // type Id uint64 @@ -32,7 +33,7 @@ type Event struct { } func (c *Client) GetAllPlayersInTeam(teamId int) (players []*Player, err error) { - fmt.Println("GetAllPlayersInTeam") + log.Info("GetAllPlayersInTeam") // test event req, err := http.NewRequest("GET", c.baseURL+fmt.Sprintf("members/search?team_id=%d", teamId), nil) @@ -54,7 +55,7 @@ func (c *Client) GetAllPlayersInTeam(teamId int) (players []*Player, err error) } func (c *Client) GetUpcomingEvent(teamId int, date time.Time) (e Event, err error) { - fmt.Println("GetUpcomingEvent") + log.Info("GetUpcomingEvent") req, err := http.NewRequest("GET", c.baseURL+fmt.Sprintf("/events/search?started_after=%s&page_size=1&team_id=%d", date.Format("2006-01-02T15:04"), teamId), nil) if err != nil { @@ -75,7 +76,7 @@ func (c *Client) GetUpcomingEvent(teamId int, date time.Time) (e Event, err erro } func (c *Client) GetAvailability(eventId uint64, players []*Player) (err error) { - fmt.Println("GetAvailability") + log.Info("GetAvailability") // Create a new request using http req, err := http.NewRequest("GET", c.baseURL+"availabilities/search?event_id="+strconv.FormatUint(uint64(eventId), 10), nil) @@ -99,7 +100,7 @@ func (c *Client) GetAvailability(eventId uint64, players []*Player) (err error) // https://api.teamsnap.com/v3/assignments/search?event_id=246172835&team_id=6892639 func (c *Client) GetAssignments(eventId uint64, teamId int, players []*Player) (err error) { - fmt.Println("GetAssignments") + log.Info("GetAssignments") // Create a new request using http req, err := http.NewRequest("GET", fmt.Sprintf(c.baseURL+"assignments/search?event_id=%d&team_id=%d", eventId, teamId), nil) diff --git a/teamsnap/tsUtils.go b/teamsnap/tsUtils.go index c9fd38e..b881402 100644 --- a/teamsnap/tsUtils.go +++ b/teamsnap/tsUtils.go @@ -1,16 +1,16 @@ package ts import ( - "fmt" "time" cj "github.com/brijs/teamsnap-team-gen/collectionjson" + log "github.com/sirupsen/logrus" ) func mapToEvent(d []cj.DataType) Event { e := Event{} for _, v := range d { - // fmt.Println(v.Name, "=>", v.Value) + log.Trace(v.Name, "=>", v.Value) switch n := v.Name; n { case "id": e.Id = uint64(v.Value.(float64)) @@ -34,7 +34,7 @@ func mapToEvent(d []cj.DataType) Event { t, err := time.Parse("2006-01-02T15:04:05Z07:00", v.Value.(string)) if err != nil { - fmt.Println(err) + log.Error(err) } e.StartDate = t case "opponent_name": @@ -51,7 +51,7 @@ func mapToPlayers(i []cj.ItemType) []*Player { p, isPlayer := Player{}, true for _, v := range d.Data { - // fmt.Println(v.Name, "=>", v.Value) + log.Trace(v.Name, "=>", v.Value) switch n := v.Name; n { case "id": p.Id = uint64(v.Value.(float64)) @@ -63,7 +63,7 @@ func mapToPlayers(i []cj.ItemType) []*Player { case "is_non_player": isPlayer = !v.Value.(bool) case "status_code": - // fmt.Printf(v.Name, "%T %v=>\n", v.Value, v.Value) + log.Trace(v.Name, "%T %v=>\n", v.Value, v.Value) p.IsAvailable = v.Value != nil && v.Value.(float64) != 0 } } @@ -86,13 +86,13 @@ func mapAvailabilityToPlayers(i []cj.ItemType, players []*Player) { for _, d := range i { p := Player{} for _, v := range d.Data { - // fmt.Println(v.Name, "=>", v.Value) + log.Trace(v.Name, "=>", v.Value) switch n := v.Name; n { case "member_id": p.Id = uint64(v.Value.(float64)) // p.Id = v.Value.(string) case "status_code": - // fmt.Printf(v.Name, "%T %v=>\n", v.Value, v.Value) + log.Trace(v.Name, "%T %v=>\n", v.Value, v.Value) p.IsAvailable = v.Value != nil && v.Value.(float64) != 0 } } @@ -100,7 +100,7 @@ func mapAvailabilityToPlayers(i []cj.ItemType, players []*Player) { if temp[p.Id] != nil { temp[p.Id].IsAvailable = p.IsAvailable } else { - //fmt.Printf("WARN: couldn't update availability info for %+v\n", p) + log.Trace("WARN: couldn't update availability info for %+v\n", p) } } @@ -117,7 +117,7 @@ func mapAssignmentsToPlayers(i []cj.ItemType, players []*Player) { for _, d := range i { p := Player{} for _, v := range d.Data { - // fmt.Println(v.Name, "=>", v.Value) + log.Trace(v.Name, "=>", v.Value) switch n := v.Name; n { case "member_id": p.Id = uint64(v.Value.(float64)) @@ -136,7 +136,7 @@ func mapAssignmentsToPlayers(i []cj.ItemType, players []*Player) { tempP.VolunteerDesc = p.VolunteerDesc tempP.VolunteerPosition = p.VolunteerPosition } else { - fmt.Printf("WARN: couldn't update assignment info for %+v\n", p) + log.Warn("WARN: couldn't update assignment info for %+v\n", p) } } diff --git a/utils.go b/utils.go index 24a7571..94ac6e2 100644 --- a/utils.go +++ b/utils.go @@ -3,12 +3,12 @@ package main import ( "flag" "fmt" - "log" "math" "os" "time" ts "github.com/brijs/teamsnap-team-gen/teamsnap" + log "github.com/sirupsen/logrus" ) var ( @@ -59,12 +59,12 @@ func getRotation(e ts.Event, teamRotationOffset int) int { t, _ := time.Parse(timeFormat, dStr) f, _ := time.Parse(timeFormat, refDateStr) - // fmt.Println(dStr, refDateStr, t, f) + log.Trace(dStr, refDateStr, t, f) // count number of weeks since Aug 8 duration := t.Sub(f) rotation := int(math.Ceil(float64(duration.Hours() / (24 * 7)))) - fmt.Println("Team Rotation offset = ", rotation) + log.Debug("Team Rotation offset = ", rotation) if rotation < 0 { return 0 } @@ -72,8 +72,8 @@ func getRotation(e ts.Event, teamRotationOffset int) int { } func printDebugInfo(players []*ts.Player) { - fmt.Printf("Players len=%d\n", len(players)) + log.Debug("Players len=%d\n", len(players)) for _, p := range players { - fmt.Printf("%+v\n", *p) + log.Debug("%+v\n", *p) } }