mirror of
https://github.com/nprasad2077/NBA_Go.git
synced 2026-09-22 14:05:13 +00:00
76 lines
2.4 KiB
Go
76 lines
2.4 KiB
Go
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
|
|
} |