shot chart create

This commit is contained in:
Ravi Prasad
2025-05-12 21:06:03 -05:00
parent a1809d3808
commit f0447c2141
10 changed files with 612 additions and 2 deletions
+76
View File
@@ -0,0 +1,76 @@
package services
import (
"encoding/json"
"fmt"
"log"
"time"
"github.com/nprasad2077/NBA_Go/models"
"github.com/nprasad2077/NBA_Go/utils"
"github.com/nprasad2077/NBA_Go/utils/metrics"
"gorm.io/gorm"
"gorm.io/gorm/clause"
)
// FetchAndStoreShotChartForPlayer fetches a single player's shot chart, parses
// each shot's date into a season, and upserts into DB.
func FetchAndStoreShotChartForPlayer(db *gorm.DB, playerId string) error {
metrics.DBOperationsTotal.WithLabelValues("fetch", "player_shot_chart").Inc()
url := fmt.Sprintf("http://rest.nbaapi.com/api/ShotChartData/playerid/%s", playerId)
body, err := utils.GetJSON(url)
if err != nil {
return err
}
var shots []models.PlayerShotChart
if err := json.Unmarshal(body, &shots); err != nil {
return err
}
for _, shot := range shots {
// parse date "Feb 11, 2023" → time.Time
if t, err := time.Parse("Jan 2, 2006", shot.Date); err == nil {
shot.Season = t.Year()
}
err := db.Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "player_id"}, {Name: "external_id"}},
DoUpdates: clause.AssignmentColumns([]string{
"player_name", "top", "left", "date", "qtr",
"time_remaining", "result", "shot_type", "distance_ft",
"lead", "team_score", "opponent_team_score", "opponent",
"team", "season",
}),
}).Create(&shot).Error
metrics.DBOperationsTotal.WithLabelValues("store", "player_shot_chart").Inc()
if err != nil {
log.Printf("Failed to upsert shot chart for %s id=%d: %v",
shot.PlayerID, shot.ExternalID, err)
}
}
return nil
}
// FetchAndStoreAllPlayerShotCharts loads every distinct playerId from your stats
// tables and invokes the per-player fetch.
func FetchAndStoreAllPlayerShotCharts(db *gorm.DB) error {
var playerIds []string
// gather from total stats (could also include advanced stats)
db.Model(&models.PlayerTotalStat{}).
Distinct("player_id").
Pluck("player_id", &playerIds)
for _, pid := range playerIds {
if err := FetchAndStoreShotChartForPlayer(db, pid); err != nil {
log.Printf("Error importing shot chart for %s: %v", pid, err)
}
// throttle
time.Sleep(1100 * time.Millisecond)
}
return nil
}