-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsportmonks.go
405 lines (335 loc) · 12.8 KB
/
sportmonks.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
package sportmonks
import (
"encoding/json"
"errors"
"fmt"
"log"
"net/http"
"strconv"
"strings"
"github.com/antonholmquist/jason"
)
var apiToken = ""
var apiURL = "https://soccer.sportmonks.com/api/v2.0/"
var dataNotFound = "key 'data' not found"
var tooManyAttemptsError = "invalid character 'T' looking for beginning of value"
var tooManyAttemptsMessage = "Too Many Attempts."
//Logger is a dedicated sportmonks logger
var Logger = log.Logger{}
type paginatedRequest struct {
pageNumber int64
data []*jason.Object
}
//NoIncludes specifies the default of no includes
var NoIncludes = ""
//FirstOrAllPages specifies the default when a specific page is not requested
//this default should be used when requesting the first page or all pages
var FirstOrAllPages = 0
//AllPages specifies to fetch all pages available for that request
var AllPages = true
//SinglePage specifies to only fetch a single page for the request
var SinglePage = false
//SetAPIToken sets the API token for sportmonks
func SetAPIToken(s string) {
apiToken = s
}
//Get API request
func Get(endpoint string, include string, page int, allPages bool) ([]byte, error) {
if endpoint == "" {
return []byte{}, errors.New("no endpoint provided")
} else if apiToken == "" {
return []byte{}, errors.New("apiToken has not been set")
}
requestURL := apiURL + endpoint
r, err := http.NewRequest("GET", requestURL, nil)
if err != nil {
return []byte{}, err
}
q := r.URL.Query()
q.Add("api_token", apiToken)
if include != "" {
q.Add("include", include)
}
if page != FirstOrAllPages {
q.Add("page", strconv.Itoa(page))
allPages = false
}
r.URL.RawQuery = q.Encode()
resp, err := http.Get(r.URL.String())
if err != nil {
return []byte{}, err
}
body, err := jason.NewObjectFromReader(resp.Body)
if err != nil {
if strings.Contains(fmt.Sprint(err), tooManyAttemptsError) {
err = errors.New(tooManyAttemptsMessage)
}
return []byte{}, err
}
var isObject bool
var dataObject *jason.Object
var dataObjectArray []*jason.Object
dataObjectArray, err = body.GetObjectArray("data")
if err != nil {
dataObject, err = body.GetObject("data")
if err != nil {
if strings.Contains(fmt.Sprint(err), dataNotFound) {
//No errors. Empty response
return []byte{}, nil
}
return []byte{}, err
}
isObject = true
}
if allPages {
pages, err := body.GetInt64("meta", "pagination", "total_pages")
// No error means endpoint is paginated
if err == nil {
if pages > 1 {
c := make(chan paginatedRequest)
requests := make([][]*jason.Object, pages)
for i := int64(2); i <= pages; i++ {
go getRequest(r.URL.String(), i, c)
}
for i := int64(2); i <= pages; i++ {
g := <-c
requests[g.pageNumber-1] = g.data
}
for i := int64(1); i < pages; i++ {
dataObjectArray = append(dataObjectArray, requests[i]...)
}
}
}
}
var m []byte
if isObject {
m, err = json.Marshal(dataObject)
if err != nil {
return []byte{}, err
}
} else {
m, err = json.Marshal(dataObjectArray)
if err != nil {
return []byte{}, err
}
}
return m, nil
}
//Goroutine which fetches a specified page
func getRequest(requestURL string, pageNumber int64, c chan paginatedRequest) {
req, err := http.NewRequest("GET", requestURL, nil)
if err != nil {
Logger.Println(err)
c <- paginatedRequest{pageNumber, []*jason.Object{}}
return
}
q := req.URL.Query()
q.Add("page", strconv.FormatInt(pageNumber, 10))
req.URL.RawQuery = q.Encode()
resp, err := http.Get(req.URL.String())
if err != nil {
Logger.Println(err)
c <- paginatedRequest{pageNumber, []*jason.Object{}}
return
}
body, err := jason.NewObjectFromReader(resp.Body)
if err != nil {
if strings.Contains(fmt.Sprint(err), tooManyAttemptsError) {
err = errors.New(tooManyAttemptsMessage)
}
Logger.Println(err)
c <- paginatedRequest{pageNumber, []*jason.Object{}}
return
}
var isObject bool
var dataObject *jason.Object
var dataObjectArray []*jason.Object
dataObjectArray, err = body.GetObjectArray("data")
if err != nil {
dataObject, err = body.GetObject("data")
if err != nil {
if strings.Contains(fmt.Sprint(err), dataNotFound) {
//No errors. Empty response
c <- paginatedRequest{pageNumber, []*jason.Object{}}
return
}
Logger.Println(err)
c <- paginatedRequest{pageNumber, []*jason.Object{}}
return
}
isObject = true
}
if isObject {
c <- paginatedRequest{pageNumber, []*jason.Object{dataObject}}
} else {
c <- paginatedRequest{pageNumber, dataObjectArray}
}
}
//Continents request for all continents
func Continents(include string) ([]byte, error) {
return Get("continents", include, FirstOrAllPages, SinglePage)
}
//Continent request for continent identified by supplied ID
func Continent(ID int, include string) ([]byte, error) {
return Get(fmt.Sprintf("continents/%v", ID), include, FirstOrAllPages, SinglePage)
}
//Countries request for all countries
func Countries(include string, page int, allPages bool) ([]byte, error) {
return Get("countries", include, page, allPages)
}
//Country request for specific country identified by ID
func Country(ID int, include string) ([]byte, error) {
return Get(fmt.Sprintf("countries/%v", ID), include, FirstOrAllPages, SinglePage)
}
//Leagues request for all leagues
func Leagues(include string, page int, allPages bool) ([]byte, error) {
return Get("leagues", include, page, allPages)
}
//League request for specific league identified by ID
func League(ID int, include string) ([]byte, error) {
return Get(fmt.Sprintf("leagues/%v", ID), include, FirstOrAllPages, SinglePage)
}
//Seasons request for all seasons
func Seasons(include string, page int, allPages bool) ([]byte, error) {
return Get("seasons", include, page, allPages)
}
//Season request for specific season identified by ID
func Season(ID int, include string) ([]byte, error) {
return Get(fmt.Sprintf("seasons/%v", ID), include, FirstOrAllPages, SinglePage)
}
//Fixture request for specific fixture identified by ID
func Fixture(ID int, include string) ([]byte, error) {
return Get(fmt.Sprintf("fixtures/%v", ID), include, FirstOrAllPages, SinglePage)
}
//FixturesFromToDateTeam fetches all fixtures between the specified dates for the team identified by teamID
func FixturesFromToDateTeam(fromDate, toDate string, teamID int, include string, page int, allPages bool) ([]byte, error) {
return Get(fmt.Sprintf("fixtures/between/%v/%v/%v", fromDate, toDate, teamID), include, page, allPages)
}
//FixturesDate fetches fixtures played at a specific date
func FixturesDate(date string, include string, page int, allPages bool) ([]byte, error) {
return Get(fmt.Sprintf("fixtures/date/%v", date), include, page, allPages)
}
//FixturesFromToDate fetches fixtures played between the specified dates
func FixturesFromToDate(fromDate, toDate string, include string, page int, allPages bool) ([]byte, error) {
return Get(fmt.Sprintf("fixtures/between/%v/%v", fromDate, toDate), include, page, allPages)
}
//FixturesMultipleList fetches all fixtures with IDs contained in the supplied comma-separated int string
func FixturesMultipleList(IDs, include string) ([]byte, error) {
return Get(fmt.Sprintf("fixtures/multi/%v", IDs), include, FirstOrAllPages, SinglePage)
}
//FixturesMultipleIntList fetches all fixtures with IDs contained in the supplied int slice
func FixturesMultipleIntList(IDs []int, include string) ([]byte, error) {
return Get(fmt.Sprintf("fixtures/multi/%v", IntSliceToSepString(IDs, ",")), include, FirstOrAllPages, SinglePage)
}
//StagesSeason fetches all stages for season specified by ID
func StagesSeason(ID int, include string) ([]byte, error) {
return Get(fmt.Sprintf("stages/season/%v", ID), include, FirstOrAllPages, SinglePage)
}
//Stage fetches stage identified by ID
func Stage(ID int, include string) ([]byte, error) {
return Get(fmt.Sprintf("stages/%v", ID), include, FirstOrAllPages, SinglePage)
}
//LivescoresNow fetches live fixtures
func LivescoresNow(include string) ([]byte, error) {
return Get("livescores/now", include, FirstOrAllPages, SinglePage)
}
//Livescores fetches fixtures which are played today
func Livescores(include string, page int, allPages bool) ([]byte, error) {
return Get("livescores", include, page, allPages)
}
//CommentariesFixture fetches textual representations of events within a fixture
func CommentariesFixture(ID int) ([]byte, error) {
return Get(fmt.Sprintf("commentaries/fixture/%v", ID), "", FirstOrAllPages, SinglePage)
}
//VideoHighlights fetches links to videos posted on social media (Community feature)
func VideoHighlights(include string, page int, allPages bool) ([]byte, error) {
return Get("highlights", include, page, allPages)
}
//Head2Head fetches all fixtures involving two teams
func Head2Head(team1ID, team2ID int, include string) ([]byte, error) {
return Get(fmt.Sprintf("head2head/%v/%v", team1ID, team2ID), include, FirstOrAllPages, SinglePage)
}
//TvStationsFixture fetches all Tv stations which broadcast the specified fixture
func TvStationsFixture(ID int) ([]byte, error) {
return Get(fmt.Sprintf("tvstations/fixture/%v", ID), "", FirstOrAllPages, SinglePage)
}
//StandingsSeason fetches standings for the specified season
func StandingsSeason(ID int, include string) ([]byte, error) {
return Get(fmt.Sprintf("standings/season/%v", ID), include, FirstOrAllPages, SinglePage)
}
//LiveStandingsSeason fetches live standings for the specified season
func LiveStandingsSeason(ID int, include string) ([]byte, error) {
return Get(fmt.Sprintf("standings/season/live/%v", ID), include, FirstOrAllPages, SinglePage)
}
//Team fetches a team identified by specified ID
func Team(ID int, include string) ([]byte, error) {
return Get(fmt.Sprintf("teams/%v", ID), include, FirstOrAllPages, SinglePage)
}
//SeasonTeams fetches all teams from a specified season
func SeasonTeams(ID int, include string) ([]byte, error) {
return Get(fmt.Sprintf("teams/season/%v", ID), include, FirstOrAllPages, SinglePage)
}
//SeasonTopScorer fetches the top goal scorers for a specified season
func SeasonTopScorer(ID int, include string) ([]byte, error) {
return Get(fmt.Sprintf("topscorers/season/%v", ID), include, FirstOrAllPages, SinglePage)
}
//Venue fetches a venue specified by ID
func Venue(ID int) ([]byte, error) {
return Get(fmt.Sprintf("venues/%v", ID), "", FirstOrAllPages, SinglePage)
}
//SeasonVenues fetches venues for specified season
func SeasonVenues(ID int) ([]byte, error) {
return Get(fmt.Sprintf("venues/season/%v", ID), "", FirstOrAllPages, SinglePage)
}
//SeasonRounds fetches all rounds for specified season
func SeasonRounds(ID int, include string) ([]byte, error) {
return Get(fmt.Sprintf("rounds/season/%v", ID), include, FirstOrAllPages, SinglePage)
}
//Round fetches round specified by ID
func Round(ID int, include string) ([]byte, error) {
return Get(fmt.Sprintf("rounds/%v", ID), include, FirstOrAllPages, SinglePage)
}
//OddsFixtureBookmaker fetches betting information for specified fixture for specified bookmaker
func OddsFixtureBookmaker(fixtureID, bookmakerID int) ([]byte, error) {
return Get(fmt.Sprintf("odds/fixture/%v/bookmaker/%v", fixtureID, bookmakerID), "", FirstOrAllPages, SinglePage)
}
//OddsFixture fetches betting odds for specified fixture
func OddsFixture(ID int) ([]byte, error) {
return Get(fmt.Sprintf("odds/fixture/%v", ID), "", FirstOrAllPages, SinglePage)
}
//OddsFixtureMarket fetches betting odds for specified fixture for specified market
func OddsFixtureMarket(fixtureID, marketID int) ([]byte, error) {
return Get(fmt.Sprintf("odds/fixture/%v/market/%v", fixtureID, marketID), "", FirstOrAllPages, SinglePage)
}
//OddsInPlayFixture fetches in play odds for specified fixture
func OddsInPlayFixture(ID int) ([]byte, error) {
return Get(fmt.Sprintf("odds/inplay/fixture/%v", ID), "", FirstOrAllPages, SinglePage)
}
//Bookmakers fetches all bookmakers
func Bookmakers() ([]byte, error) {
return Get("bookmakers", "", FirstOrAllPages, SinglePage)
}
//Bookmaker fetches bookmaker specified by ID
func Bookmaker(ID int) ([]byte, error) {
return Get(fmt.Sprintf("bookmakers/%v", ID), "", FirstOrAllPages, SinglePage)
}
//Markets fetches all markets
func Markets() ([]byte, error) {
return Get("markets", "", FirstOrAllPages, SinglePage)
}
//Market fetches a market specified by ID
func Market(ID int) ([]byte, error) {
return Get(fmt.Sprintf("markets/%v", ID), "", FirstOrAllPages, SinglePage)
}
//Player fetches a player specified by ID
func Player(ID int, include string) ([]byte, error) {
return Get(fmt.Sprintf("players/%v", ID), include, FirstOrAllPages, SinglePage)
}
//SeasonTeamSquad fetches a squad for a specified team for a specified season
func SeasonTeamSquad(seasonID, teamID int, include string) ([]byte, error) {
return Get(fmt.Sprintf("squad/season/%v/team/%v", seasonID, teamID), include, FirstOrAllPages, SinglePage)
}
//Coach fetches a squad specified by ID
func Coach(ID int) ([]byte, error) {
return Get(fmt.Sprintf("coaches/%v", ID), "", FirstOrAllPages, SinglePage)
}