Created
March 21, 2022 09:48
-
-
Save viartemev/caa8f7a41f0c8049d62477cddca013ec to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"encoding/json" | |
"fmt" | |
"io" | |
"io/ioutil" | |
"log" | |
"net/http" | |
"strings" | |
"sync" | |
"time" | |
) | |
type GameInfo struct { | |
Title string | |
Video string | |
} | |
func main() { | |
start := time.Now() | |
var wg sync.WaitGroup | |
gamesVideos := make(map[int]*GameInfo) | |
upcomingGames := fetchUpcomingGames() | |
finishedGames := filterFinishedGames(upcomingGames) | |
for _, game := range finishedGames { | |
title := fmt.Sprintf("%v vs %v", game.Teams.Home.Team.Name, game.Teams.Away.Team.Name) | |
gamesVideos[game.GamePk] = &GameInfo{title, "video link"} | |
} | |
for _, date := range upcomingGames.Dates { | |
for _, game := range date.Games { | |
wg.Add(1) | |
game := game | |
go func() { | |
gameInfo := fetchGameInfo(game.GamePk) | |
video := extractGameVideo(gameInfo) | |
gamesVideos[game.GamePk] = &GameInfo{Title: gamesVideos[game.GamePk].Title, Video: video} | |
defer wg.Done() | |
}() | |
} | |
} | |
wg.Wait() | |
for _, info := range gamesVideos { | |
fmt.Printf("Game %v %v\n", info.Title, info.Video) | |
} | |
log.Printf("Operations took %s", time.Since(start)) | |
} | |
func filterFinishedGames(schedule Schedule) []Games { | |
var finishedGames []Games | |
for _, date := range schedule.Dates { | |
for _, game := range date.Games { | |
if game.Status.AbstractGameState == "Final" { | |
finishedGames = append(finishedGames, game) | |
} | |
} | |
} | |
return finishedGames | |
} | |
func extractGameVideo(game Game) string { | |
var video string | |
for _, media := range game.Media.Epg { | |
if media.Title == "Recap" { | |
for _, item := range media.Items { | |
for _, playback := range item.Playbacks { | |
if strings.Contains(playback.Name, "FLASH_1800K") { | |
video = playback.Url | |
} | |
} | |
} | |
} | |
} | |
return video | |
} | |
func fetchGameInfo(gamePk int) Game { | |
client := http.Client{ | |
Timeout: time.Second * 2, | |
} | |
url := "https://statsapi.web.nhl.com/api/v1/game/" + fmt.Sprintf("%v", gamePk) + "/content" | |
req, err := http.NewRequest(http.MethodGet, url, nil) | |
if err != nil { | |
log.Fatal(err) | |
} | |
res, getErr := client.Do(req) | |
if getErr != nil { | |
log.Fatal(getErr) | |
} | |
if res.Body != nil { | |
defer func(Body io.ReadCloser) { | |
err := Body.Close() | |
if err != nil { | |
log.Fatal(err) | |
} | |
}(res.Body) | |
} | |
body, readErr := ioutil.ReadAll(res.Body) | |
if readErr != nil { | |
log.Fatal(readErr) | |
} | |
game := &Game{} | |
jsonErr := json.Unmarshal(body, &game) | |
if jsonErr != nil { | |
log.Fatal(jsonErr) | |
} | |
return *game | |
} | |
type Game struct { | |
Link string `json:"link"` | |
Media struct { | |
Epg []struct { | |
Title string `json:"title"` | |
Items []struct { | |
Playbacks []struct { | |
Name string `json:"name"` | |
Url string `json:"url"` | |
} | |
} | |
} | |
} | |
} | |
func fetchUpcomingGames() Schedule { | |
client := http.Client{ | |
Timeout: time.Second * 2, | |
} | |
url := "https://statsapi.web.nhl.com/api/v1/schedule" | |
req, err := http.NewRequest(http.MethodGet, url, nil) | |
if err != nil { | |
log.Fatal(err) | |
} | |
res, getErr := client.Do(req) | |
if getErr != nil { | |
log.Fatal(getErr) | |
} | |
if res.Body != nil { | |
defer func(Body io.ReadCloser) { | |
err := Body.Close() | |
if err != nil { | |
log.Fatal(err) | |
} | |
}(res.Body) | |
} | |
body, readErr := ioutil.ReadAll(res.Body) | |
if readErr != nil { | |
log.Fatal(readErr) | |
} | |
schedule := &Schedule{} | |
jsonErr := json.Unmarshal(body, &schedule) | |
if jsonErr != nil { | |
log.Fatal(jsonErr) | |
} | |
return *schedule | |
} | |
type Schedule struct { | |
Dates []struct { | |
Date string `json:"date"` | |
Games []Games | |
} | |
} | |
type Games struct { | |
GamePk int `json:"gamePk"` | |
Teams Teams | |
Status struct { | |
AbstractGameState string `json:"abstractGameState"` | |
} | |
} | |
type Teams struct { | |
Away struct { | |
Team Team | |
} `json:"away"` | |
Home struct { | |
Team Team | |
} `json:"home"` | |
} | |
type Team struct { | |
Name string `json:"name"` | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment