blob: 170fe50a7c29566d2ac3ce1b4c646023075cbd0a [file] [log] [blame]
Het Satasiyac6df3322022-02-05 14:12:30 -08001package scraping
2
3// A library to grab match data from The Blue Alliance.
4import (
5 "encoding/json"
6 "errors"
Philipp Schraderd3fac192022-03-02 20:35:46 -08007 "fmt"
Het Satasiyac6df3322022-02-05 14:12:30 -08008 "io/ioutil"
Het Satasiyac6df3322022-02-05 14:12:30 -08009 "net/http"
10 "os"
Philipp Schraderd3fac192022-03-02 20:35:46 -080011 "strconv"
Het Satasiyac6df3322022-02-05 14:12:30 -080012)
13
14// Stores the TBA API key to access the API.
Philipp Schraderd3fac192022-03-02 20:35:46 -080015type scrapingConfig struct {
16 ApiKey string `json:"api_key"`
17 BaseUrl string `json:"base_url"`
Het Satasiyac6df3322022-02-05 14:12:30 -080018}
19
20// Takes in year and FIRST event code and returns all matches in that event according to TBA.
21// Also takes in a file path to the JSON config file that contains your TBA API key.
22// It defaults to <workspace root>/config.json
23// the config is expected to have the following contents:
24//{
25// api_key:"myTBAapiKey"
26//}
Philipp Schraderd3fac192022-03-02 20:35:46 -080027func AllMatches(year int32, eventCode, configPath string) ([]Match, error) {
28 if configPath == "" {
29 configPath = os.Getenv("BUILD_WORKSPACE_DIRECTORY") + "/scouting_config.json"
Het Satasiyac6df3322022-02-05 14:12:30 -080030 }
Philipp Schraderd3fac192022-03-02 20:35:46 -080031
Het Satasiyac6df3322022-02-05 14:12:30 -080032 // Takes the filepath and grabs the api key from the json.
Philipp Schraderd3fac192022-03-02 20:35:46 -080033 content, err := ioutil.ReadFile(configPath)
Het Satasiyac6df3322022-02-05 14:12:30 -080034 if err != nil {
Philipp Schraderd3fac192022-03-02 20:35:46 -080035 return nil, errors.New(fmt.Sprint("Failed to open config at ", configPath, ": ", err))
Het Satasiyac6df3322022-02-05 14:12:30 -080036 }
37 // Parses the JSON parameters into a struct.
Philipp Schraderd3fac192022-03-02 20:35:46 -080038 var config scrapingConfig
39 if err := json.Unmarshal([]byte(content), &config); err != nil {
40 return nil, errors.New(fmt.Sprint("Failed to parse config file as JSON: ", err))
41 }
42
43 // Perform some basic validation on the data.
44 if config.ApiKey == "" {
45 return nil, errors.New("Missing 'api_key' in config JSON.")
46 }
47 if config.BaseUrl == "" {
48 config.BaseUrl = "https://www.thebluealliance.com"
Het Satasiyac6df3322022-02-05 14:12:30 -080049 }
50
51 // Create the TBA event key for the year and event code.
Philipp Schraderd3fac192022-03-02 20:35:46 -080052 eventKey := strconv.Itoa(int(year)) + eventCode
Het Satasiyac6df3322022-02-05 14:12:30 -080053
54 // Create a get request for the match info.
Philipp Schraderd3fac192022-03-02 20:35:46 -080055 req, err := http.NewRequest("GET", config.BaseUrl+"/api/v3/event/"+eventKey+"/matches", nil)
Het Satasiyac6df3322022-02-05 14:12:30 -080056 if err != nil {
Philipp Schraderd3fac192022-03-02 20:35:46 -080057 return nil, errors.New(fmt.Sprint("Failed to build http request: ", err))
Het Satasiyac6df3322022-02-05 14:12:30 -080058 }
59
60 // Add the auth key header to the request.
Philipp Schraderd3fac192022-03-02 20:35:46 -080061 req.Header.Add("X-TBA-Auth-Key", config.ApiKey)
Het Satasiyac6df3322022-02-05 14:12:30 -080062
Philipp Schraderd3fac192022-03-02 20:35:46 -080063 // Make the API request.
64 client := &http.Client{}
Het Satasiyac6df3322022-02-05 14:12:30 -080065 resp, err := client.Do(req)
Het Satasiyac6df3322022-02-05 14:12:30 -080066 if err != nil {
Philipp Schraderd3fac192022-03-02 20:35:46 -080067 return nil, errors.New(fmt.Sprint("Failed to make TBA API request: ", err))
Het Satasiyac6df3322022-02-05 14:12:30 -080068 }
69
Het Satasiyac6df3322022-02-05 14:12:30 -080070 defer resp.Body.Close()
Philipp Schraderd3fac192022-03-02 20:35:46 -080071 if resp.StatusCode != 200 {
72 return nil, errors.New(fmt.Sprint("Got unexpected status code from TBA API request: ", resp.Status))
73 }
Het Satasiyac6df3322022-02-05 14:12:30 -080074
75 // Get all bytes from response body.
76 bodyBytes, err := ioutil.ReadAll(resp.Body)
77 if err != nil {
Philipp Schraderd3fac192022-03-02 20:35:46 -080078 return nil, errors.New(fmt.Sprint("Failed to read TBA API response: ", err))
Het Satasiyac6df3322022-02-05 14:12:30 -080079 }
80
81 var matches []Match
82 // Unmarshal json into go usable format.
Philipp Schraderd3fac192022-03-02 20:35:46 -080083 if err := json.Unmarshal([]byte(bodyBytes), &matches); err != nil {
84 return nil, errors.New(fmt.Sprint("Failed to parse JSON received from TBA: ", err))
Het Satasiyac6df3322022-02-05 14:12:30 -080085 }
86
87 return matches, nil
88}