From dcd2891edd76db3922cb025724b18b9301a52ed7 Mon Sep 17 00:00:00 2001 From: Dylan Tientcheu Date: Thu, 15 Dec 2022 02:03:58 +0100 Subject: [PATCH] feat: add standings command --- cmd/game.go | 15 +++-- go.mod | 2 + go.sum | 4 ++ nag/leaguestandingsv3.go | 6 ++ nba/standings.go | 122 +++++++++++++++++++++++++++++++++++++++ ui/constants/consts.go | 30 +++++++++- ui/ui.go | 12 +++- 7 files changed, 182 insertions(+), 9 deletions(-) create mode 100644 nba/standings.go diff --git a/cmd/game.go b/cmd/game.go index de944b9..c9a9b3c 100644 --- a/cmd/game.go +++ b/cmd/game.go @@ -1,13 +1,11 @@ /* Copyright © 2022 NAME HERE - */ package cmd import ( "time" - "github.com/dylantientcheu/nbacli/nba" "github.com/dylantientcheu/nbacli/ui" "github.com/spf13/cobra" @@ -25,7 +23,6 @@ var gameCmd = &cobra.Command{ Use: "games", Short: "Get the NBA schedule for a specific date", Run: func(cmd *cobra.Command, args []string) { - scbrd := nba.ScoreboardRepository{} // no date then get today's games dateArg := time.Now() @@ -41,13 +38,23 @@ var gameCmd = &cobra.Command{ } // start the tui - ui.StartTea(scbrd, dateArg) + ui.StartTea(dateArg) + + }, +} +var StandingCmd = &cobra.Command{ + Use: "standings", + Short: "Get the NBA standings for the current season", + Run: func(cmd *cobra.Command, args []string) { + // start the tui + ui.StartStanding() }, } func init() { rootCmd.AddCommand(gameCmd) + rootCmd.AddCommand(StandingCmd) rootCmd.PersistentFlags().StringVarP(&date, "date", "d", "", "Date to get the schedule for (YYYYMMDD)") rootCmd.PersistentFlags().BoolVarP(&hasYesterday, "yesterday", "y", false, "Get yesterday's games") rootCmd.PersistentFlags().BoolVarP(&hasTomorrow, "tomorrow", "t", false, "Get tomorrow's games") diff --git a/go.mod b/go.mod index 33d115e..127a953 100644 --- a/go.mod +++ b/go.mod @@ -12,9 +12,11 @@ require ( github.com/aymanbagabas/go-osc52 v1.0.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/sahilm/fuzzy v0.1.0 // indirect + github.com/samber/lo v1.36.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/stretchr/testify v1.8.1 // indirect github.com/tkuchiki/go-timezone v0.2.2 // indirect + golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 // indirect ) require ( diff --git a/go.sum b/go.sum index 99cdf2c..0531608 100644 --- a/go.sum +++ b/go.sum @@ -62,6 +62,8 @@ github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUc github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sahilm/fuzzy v0.1.0 h1:FzWGaw2Opqyu+794ZQ9SYifWv2EIXpwP4q8dY1kDAwI= github.com/sahilm/fuzzy v0.1.0/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y= +github.com/samber/lo v1.36.0 h1:4LaOxH1mHnbDGhTVE0i1z8v/lWaQW8AIfOD3HU4mSaw= +github.com/samber/lo v1.36.0/go.mod h1:HLeWcJRRyLKp3+/XBJvOrerCQn9mhdKMHyd7IRlgeQ8= github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA= github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= @@ -77,6 +79,8 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o github.com/tkuchiki/go-timezone v0.2.0/go.mod h1:b1Ean9v2UXtxSq4TZF0i/TU9NuoWa9hOzOKoGCV2zqY= github.com/tkuchiki/go-timezone v0.2.2 h1:MdHR65KwgVTwWFQrota4SKzc4L5EfuH5SdZZGtk/P2Q= github.com/tkuchiki/go-timezone v0.2.2/go.mod h1:oFweWxYl35C/s7HMVZXiA19Jr9Y0qJHMaG/J2TES4LY= +golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 h1:3MTrJm4PyNL9NBqvYDSj3DHl46qQakyfqfWo4jgfaEM= +golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/nag/leaguestandingsv3.go b/nag/leaguestandingsv3.go index c5df7c2..56c7ba9 100644 --- a/nag/leaguestandingsv3.go +++ b/nag/leaguestandingsv3.go @@ -11,6 +11,7 @@ import ( // LeagueStandingsV3 wraps request to and response from leaguestandingsv3 endpoint. type LeagueStandingsV3 struct { *Client + LeagueID string Season string SeasonType params.SeasonType @@ -22,6 +23,8 @@ func NewLeagueStandingsV3() *LeagueStandingsV3 { return &LeagueStandingsV3{ Client: NewDefaultClient(), + LeagueID: params.LeagueID.Default(), + Season: params.CurrentSeason, SeasonType: params.DefaultSeasonType, } @@ -37,8 +40,10 @@ func (c *LeagueStandingsV3) Get() error { req.Header = DefaultStatsHeader q := req.URL.Query() + q.Add("LeagueID", c.LeagueID) q.Add("Season", c.Season) q.Add("SeasonType", string(c.SeasonType)) + req.URL.RawQuery = q.Encode() b, err := c.Do(req) @@ -50,6 +55,7 @@ func (c *LeagueStandingsV3) Get() error { if err := json.Unmarshal(b, &res); err != nil { return err } + c.Response = &res return nil } diff --git a/nba/standings.go b/nba/standings.go new file mode 100644 index 0000000..5bba3d7 --- /dev/null +++ b/nba/standings.go @@ -0,0 +1,122 @@ +package nba + +import ( + "github.com/mitchellh/mapstructure" + + "github.com/dylantientcheu/nbacli/nag" +) + +type Standing struct { + LeagueID string + SeasonID string + TeamID int64 + TeamCity string + TeamName string + TeamSlug string + Conference nag.Conference + ConferenceRecord string + PlayoffRank int64 + ClinchIndicator string + Division string + DivisionRecord string + DivisionRank int64 + WINS int64 + Losses int64 + WinPCT float64 + LeagueRank int64 + Record string + Home string + Road string + L10 string + Last10Home string + Last10Road string + Ot string + ThreePTSOrLess string + TenPTSOrMore string + LongHomeStreak int64 + StrLongHomeStreak string + LongRoadStreak int64 + StrLongRoadStreak string + LongWinStreak int64 + LongLossStreak int64 + CurrentHomeStreak int64 + StrCurrentHomeStreak string + CurrentRoadStreak int64 + StrCurrentRoadStreak string + CurrentStreak int64 + StrCurrentStreak string + ConferenceGamesBack float64 + DivisionGamesBack float64 + ClinchedConferenceTitle int64 + ClinchedDivisionTitle int64 + ClinchedPlayoffBirth int64 + ClinchedPlayIn int64 + EliminatedConference int64 + EliminatedDivision int64 + AheadAtHalf string + BehindAtHalf string + TiedAtHalf string + AheadAtThird string + BehindAtThird string + TiedAtThird string + Score100PTS string + OppScore100PTS string + OppOver500 string + LeadInFGPCT string + LeadInReb string + FewerTurnovers string + PointsPG float64 + OppPointsPG float64 + DiffPointsPG float64 + TotalPoints int64 + OppTotalPoints int64 + DiffTotalPoints int64 +} + +type StandingsRepository struct { +} + +func (g *StandingsRepository) GetSeasonStandings() ([]Standing, []Standing) { + sbv2 := nag.NewLeagueStandingsV3() + err := sbv2.Get() + if err != nil { + panic(err) + } + if sbv2.Response == nil { + panic("no response") + } + + n := nag.Map(*sbv2.Response) + var result nag.LeagueStandingsResponse + mapstructure.Decode(n, &result) + + easternConference := make([]Standing, 0, len(result.Standings)/2) + westernConference := make([]Standing, 0, len(result.Standings)/2) + + for _, v := range result.Standings { + var standing Standing + standing.TeamID = v.TeamID + standing.PlayoffRank = v.PlayoffRank + standing.TeamName = v.TeamName + standing.WINS = v.WINS + standing.Losses = v.Losses + standing.WinPCT = v.WinPCT + standing.Home = v.Home + standing.Road = v.Road + standing.Conference = v.Conference + standing.ConferenceRecord = v.ConferenceRecord + standing.PointsPG = v.PointsPG + standing.OppPointsPG = v.OppPointsPG + standing.DiffPointsPG = v.DiffPointsPG + standing.StrCurrentStreak = v.StrCurrentStreak + standing.L10 = v.L10 + + if v.Conference == nag.East { + easternConference = append(easternConference, standing) + } else { + westernConference = append(westernConference, standing) + } + } + + return easternConference, westernConference +} diff --git a/ui/constants/consts.go b/ui/constants/consts.go index ac587d8..ea6d60e 100644 --- a/ui/constants/consts.go +++ b/ui/constants/consts.go @@ -2,6 +2,7 @@ package constants import ( "github.com/dylantientcheu/nbacli/nba" + "github.com/evertras/bubble-table/table" "github.com/charmbracelet/bubbles/key" tea "github.com/charmbracelet/bubbletea" @@ -10,15 +11,40 @@ import ( /* CONSTANTS */ +var BaseStyle = lipgloss.NewStyle(). + BorderStyle(lipgloss.RoundedBorder()). + BorderForeground(lipgloss.Color("#874BFD")) + var ( // P the current tea program P *tea.Program - // Er the entry repository for the tui + Gm *nba.BoxScoreRepository - // Pr the project repository for the tui Sb *nba.ScoreboardRepository + St *nba.StandingsRepository + // WindowSize store the size of the terminal window WindowSize tea.WindowSizeMsg + + CustomTableBorder = table.Border{ + Top: "─", + Left: "│", + Right: "│", + Bottom: "─", + + TopRight: "╮", + TopLeft: "╭", + BottomRight: "╯", + BottomLeft: "╰", + + TopJunction: "┬", + LeftJunction: "├", + RightJunction: "┤", + BottomJunction: "┴", + InnerJunction: "┼", + + InnerDivider: "│", + } ) /* STYLING */ diff --git a/ui/ui.go b/ui/ui.go index 248be4c..a228e82 100644 --- a/ui/ui.go +++ b/ui/ui.go @@ -13,7 +13,8 @@ import ( ) // StartTea the entry point for the UI. Initializes the model. -func StartTea(sb nba.ScoreboardRepository, date time.Time) { +func StartTea(date time.Time) { + scbrd := nba.ScoreboardRepository{} if f, err := tea.LogToFile("debug.log", "help"); err != nil { fmt.Println("Couldn't open a file for logging:", err) os.Exit(1) @@ -25,15 +26,20 @@ func StartTea(sb nba.ScoreboardRepository, date time.Time) { } }() } - constants.Sb = &sb + constants.Sb = &scbrd m := InitScoreboard(date) UpdateTeaView(m) } +func StartStanding() { + m := InitStandingsView() + UpdateTeaView(m) +} + func UpdateTeaView(m tea.Model) { constants.P = tea.NewProgram(m, tea.WithAltScreen()) - if err := constants.P.Start(); err != nil { + if _, err := constants.P.Run(); err != nil { fmt.Println("Error running program:", err) os.Exit(1) }