sportradar-api 0.13.5 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/Gemfile.lock +8 -7
- data/lib/sportradar/api/baseball/mlb/api.rb +1 -1
- data/lib/sportradar/api/basketball/ncaamb/game.rb +4 -0
- data/lib/sportradar/api/basketball/ncaamb/tournament.rb +2 -2
- data/lib/sportradar/api/basketball/ncaamb.rb +2 -2
- data/lib/sportradar/api/basketball/play.rb +2 -1
- data/lib/sportradar/api/basketball/plays/base.rb +8 -1
- data/lib/sportradar/api/basketball/team.rb +1 -1
- data/lib/sportradar/api/images.rb +13 -11
- data/lib/sportradar/api/soccer/api.rb +1 -1
- data/lib/sportradar/api/soccer/event.rb +1 -1
- data/lib/sportradar/api/soccer/match.rb +37 -8
- data/lib/sportradar/api/soccer/player.rb +65 -5
- data/lib/sportradar/api/soccer/team.rb +23 -11
- data/lib/sportradar/api/soccer/tournament.rb +7 -3
- data/lib/sportradar/api/version.rb +1 -1
- data/lib/sportradar/api.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 33784418fb807e49dedec710bc4d07e22165615929f5b379e5b75da16f7a474c
|
|
4
|
+
data.tar.gz: '09071e245846662f1f9f60297fdfac12690746040d8e93705be21bba543f583c'
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b6aa4fc6699921922fc84be63de15569e658baac30506093fe7e250844f51908657e859e70404b55cfe0c8362d945ec19cc5b2c1df3a74711ded681efefea994
|
|
7
|
+
data.tar.gz: d882cba949755f62c7e3885ca8683866e19f59c3fc9c6fd4bf34e95cdd205f1323130f4b6c0d203c96e43ac3e74bf3b44bd2b439ba6753a431712ef151e9a1dd
|
data/Gemfile.lock
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
sportradar-api (0.
|
|
4
|
+
sportradar-api (0.14.0)
|
|
5
5
|
activesupport
|
|
6
6
|
httparty (>= 0.14.0)
|
|
7
7
|
|
|
8
8
|
GEM
|
|
9
9
|
remote: https://rubygems.org/
|
|
10
10
|
specs:
|
|
11
|
-
activesupport (5.1
|
|
11
|
+
activesupport (5.2.1)
|
|
12
12
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
13
|
-
i18n (
|
|
13
|
+
i18n (>= 0.7, < 2)
|
|
14
14
|
minitest (~> 5.1)
|
|
15
15
|
tzinfo (~> 1.1)
|
|
16
16
|
addressable (2.5.1)
|
|
@@ -45,9 +45,10 @@ GEM
|
|
|
45
45
|
guard-compat (~> 1.2)
|
|
46
46
|
minitest (>= 3.0)
|
|
47
47
|
hashdiff (0.3.4)
|
|
48
|
-
httparty (0.
|
|
48
|
+
httparty (0.16.2)
|
|
49
49
|
multi_xml (>= 0.5.2)
|
|
50
|
-
i18n (
|
|
50
|
+
i18n (1.1.0)
|
|
51
|
+
concurrent-ruby (~> 1.0)
|
|
51
52
|
json (2.1.0)
|
|
52
53
|
listen (3.1.5)
|
|
53
54
|
rb-fsevent (~> 0.9, >= 0.9.4)
|
|
@@ -86,7 +87,7 @@ GEM
|
|
|
86
87
|
thor (0.19.4)
|
|
87
88
|
thread_safe (0.3.6)
|
|
88
89
|
tins (1.14.0)
|
|
89
|
-
tzinfo (1.2.
|
|
90
|
+
tzinfo (1.2.5)
|
|
90
91
|
thread_safe (~> 0.1)
|
|
91
92
|
vcr (3.0.3)
|
|
92
93
|
webmock (3.0.1)
|
|
@@ -114,4 +115,4 @@ DEPENDENCIES
|
|
|
114
115
|
webmock
|
|
115
116
|
|
|
116
117
|
BUNDLED WITH
|
|
117
|
-
1.
|
|
118
|
+
1.16.3
|
|
@@ -26,7 +26,7 @@ module Sportradar
|
|
|
26
26
|
'reg'
|
|
27
27
|
end
|
|
28
28
|
def default_access_level
|
|
29
|
-
if (ENV['
|
|
29
|
+
if (ENV['SPORTRADAR_ENV_MLB'] || ENV['SPORTRADAR_ENV'] || ENV['RACK_ENV'] || ENV['RAILS_ENV']) == 'production'
|
|
30
30
|
'p'
|
|
31
31
|
else
|
|
32
32
|
't'
|
|
@@ -91,7 +91,7 @@ module Sportradar
|
|
|
91
91
|
|
|
92
92
|
# summary
|
|
93
93
|
def get_summary
|
|
94
|
-
data = api.get_data(path_summary)
|
|
94
|
+
data = api.get_data(path_summary).to_h
|
|
95
95
|
ingest_summary(data)
|
|
96
96
|
end
|
|
97
97
|
def queue_summary
|
|
@@ -105,7 +105,7 @@ module Sportradar
|
|
|
105
105
|
|
|
106
106
|
# schedule
|
|
107
107
|
def get_schedule
|
|
108
|
-
data = api.get_data(path_schedule)
|
|
108
|
+
data = api.get_data(path_schedule).to_h
|
|
109
109
|
ingest_schedule(data)
|
|
110
110
|
end
|
|
111
111
|
def queue_schedule
|
|
@@ -16,7 +16,7 @@ module Sportradar
|
|
|
16
16
|
# end
|
|
17
17
|
# end
|
|
18
18
|
def self.new(data, **opts)
|
|
19
|
-
klass = subclass(data['event_type'])
|
|
19
|
+
klass = subclass(data['event_type']) || Base
|
|
20
20
|
klass.new(data, **opts)
|
|
21
21
|
# rescue => e
|
|
22
22
|
# binding.pry
|
|
@@ -53,6 +53,7 @@ module Sportradar
|
|
|
53
53
|
"tvtimeout" => TvTimeout,
|
|
54
54
|
"clearpathfoul" => ClearPathFoul,
|
|
55
55
|
"technicalfoul" => TechnicalFoul,
|
|
56
|
+
"minortechnicalfoul" => TechnicalFoul,
|
|
56
57
|
"review" => Review,
|
|
57
58
|
"defensivethreeseconds" => DefensiveThreeSeconds,
|
|
58
59
|
"flagrantone" => FlagrantOne,
|
|
@@ -3,7 +3,7 @@ module Sportradar
|
|
|
3
3
|
module Basketball
|
|
4
4
|
class Play
|
|
5
5
|
class Base < Data
|
|
6
|
-
attr_accessor :response, :id, :clock, :event_type, :description, :statistics, :score, :team_id, :player_id, :quarter, :half, :updated, :location, :possession, :on_court, :game_seconds, :identifier
|
|
6
|
+
attr_accessor :response, :id, :clock, :event_type, :description, :statistics, :score, :team_id, :player_id, :quarter, :half, :updated, :location, :possession, :on_court, :on_court_ids, :game_seconds, :identifier
|
|
7
7
|
alias :type :event_type
|
|
8
8
|
|
|
9
9
|
def initialize(data, **opts)
|
|
@@ -87,11 +87,18 @@ module Sportradar
|
|
|
87
87
|
@location = data['location'] # {"coord_x"=>"0", "coord_y"=>"0"},
|
|
88
88
|
@possession = data['possession'] # {"name"=>"Knicks", "market"=>"New York", "id"=>"583ec70e-fb46-11e1-82cb-f4ce4684ea4c"},
|
|
89
89
|
# @on_court = data['on_court'] # hash
|
|
90
|
+
handle_on_court(data['on_court']) if data['on_court']
|
|
90
91
|
|
|
91
92
|
handle_time(data, **opts)
|
|
92
93
|
parse_statistics(data) if data['statistics']
|
|
93
94
|
end
|
|
94
95
|
|
|
96
|
+
def handle_on_court(data)
|
|
97
|
+
teams = [data['home'], data['away']]
|
|
98
|
+
@on_court = teams.flat_map { |hash| hash['players'].map { |pl| OpenStruct.new(pl) } }
|
|
99
|
+
@on_court_ids = @on_court.map(&:id)
|
|
100
|
+
end
|
|
101
|
+
|
|
95
102
|
def handle_time(data, **opts)
|
|
96
103
|
@game_seconds = if opts[:quarter]
|
|
97
104
|
@quarter = opts[:quarter].sequence.to_i rescue opts[:quarter].to_i
|
|
@@ -115,7 +115,7 @@ module Sportradar
|
|
|
115
115
|
{url: url, headers: headers, params: options, timeout: timeout, callback: method(:ingest_roster)}
|
|
116
116
|
end
|
|
117
117
|
|
|
118
|
-
def get_season_stats(year =
|
|
118
|
+
def get_season_stats(year = api.default_year)
|
|
119
119
|
data = api.get_data(path_season_stats(year)).to_h
|
|
120
120
|
ingest_season_stats(data)
|
|
121
121
|
end
|
|
@@ -23,7 +23,8 @@ module Sportradar
|
|
|
23
23
|
else
|
|
24
24
|
response = get request_url("#{league}/#{image_type}/players/manifest")
|
|
25
25
|
end
|
|
26
|
-
elsif nfl_premium || usat_premium || sport == 'ncaafb'
|
|
26
|
+
elsif nfl_premium || usat_premium || sport == 'ncaafb' || sport == 'nba'
|
|
27
|
+
year = Date.today.month < 8 ? Date.today.year - 1 : Date.today
|
|
27
28
|
response = get request_url("#{image_type}/players/#{year}/manifest")
|
|
28
29
|
else
|
|
29
30
|
response = get request_url("players/#{image_type}/manifests/all_assets")
|
|
@@ -39,7 +40,6 @@ module Sportradar
|
|
|
39
40
|
# Coach Manifests
|
|
40
41
|
|
|
41
42
|
def coach_manifests
|
|
42
|
-
raise Sportradar::Api::Error::InvalidLeague unless league.nil?
|
|
43
43
|
response = get request_url("coaches/#{image_type}/manifests/all_assets")
|
|
44
44
|
if response.success? && response["assetlist"]
|
|
45
45
|
Sportradar::Api::Images::AssetList.new response["assetlist"]
|
|
@@ -50,7 +50,6 @@ module Sportradar
|
|
|
50
50
|
alias_method :all_coaches, :coach_manifests
|
|
51
51
|
|
|
52
52
|
def venue_manifests
|
|
53
|
-
raise Sportradar::Api::Error::InvalidLeague unless league.nil?
|
|
54
53
|
if version == 3
|
|
55
54
|
response = get request_url("venues/manifest")
|
|
56
55
|
else
|
|
@@ -97,7 +96,7 @@ module Sportradar
|
|
|
97
96
|
private
|
|
98
97
|
|
|
99
98
|
def request_url(path)
|
|
100
|
-
"/#{sport}-images-#{access_level}#{version}/#{provider}/#{path}"
|
|
99
|
+
"/#{sport}-images-#{access_level}#{version}/#{provider}/#{( league + '/') if league}#{path}"
|
|
101
100
|
end
|
|
102
101
|
|
|
103
102
|
def api_key
|
|
@@ -138,6 +137,8 @@ module Sportradar
|
|
|
138
137
|
'ap_premium'
|
|
139
138
|
elsif usat_premium
|
|
140
139
|
'usat_premium'
|
|
140
|
+
elsif sport == 'nba'
|
|
141
|
+
'getty_premium'
|
|
141
142
|
else
|
|
142
143
|
'usat'
|
|
143
144
|
# REUTERS IS JUST FOR SOCCER sport == 'mlb' ? 'usat' : 'reuters'
|
|
@@ -145,11 +146,12 @@ module Sportradar
|
|
|
145
146
|
end
|
|
146
147
|
|
|
147
148
|
def version
|
|
148
|
-
if uses_v3_api? || nfl_premium || usat_premium
|
|
149
|
-
|
|
150
|
-
elsif uses_v2_api?
|
|
151
|
-
|
|
152
|
-
end
|
|
149
|
+
# if uses_v3_api? || nfl_premium || usat_premium || sport == 'nba'
|
|
150
|
+
# 3
|
|
151
|
+
# elsif uses_v2_api?
|
|
152
|
+
# Sportradar::Api.version('images')
|
|
153
|
+
# end
|
|
154
|
+
3
|
|
153
155
|
end
|
|
154
156
|
|
|
155
157
|
def image_type
|
|
@@ -169,7 +171,7 @@ module Sportradar
|
|
|
169
171
|
end
|
|
170
172
|
|
|
171
173
|
def allowed_sports
|
|
172
|
-
v2_api_sports + v3_api_sports
|
|
174
|
+
v2_api_sports + v3_api_sports + soccer_leagues
|
|
173
175
|
end
|
|
174
176
|
|
|
175
177
|
def v2_api_sports
|
|
@@ -177,7 +179,7 @@ module Sportradar
|
|
|
177
179
|
end
|
|
178
180
|
|
|
179
181
|
def v3_api_sports
|
|
180
|
-
['mlb', 'soccer', 'cricket', 'f1', 'rugby', 'tennis', 'ncaafb',
|
|
182
|
+
['mlb', 'soccer', 'cricket', 'f1', 'rugby', 'tennis', 'ncaafb', 'nba' ]
|
|
181
183
|
end
|
|
182
184
|
|
|
183
185
|
def soccer_leagues
|
|
@@ -19,7 +19,7 @@ module Sportradar
|
|
|
19
19
|
'reg'
|
|
20
20
|
end
|
|
21
21
|
def default_access_level
|
|
22
|
-
if (ENV['SPORTRADAR_ENV'] || ENV['RACK_ENV'] || ENV['RAILS_ENV']) == 'production'
|
|
22
|
+
if (ENV['SPORTRADAR_SOCCER_ENV'] || ENV['SPORTRADAR_ENV'] || ENV['RACK_ENV'] || ENV['RAILS_ENV']) == 'production'
|
|
23
23
|
'x'
|
|
24
24
|
else
|
|
25
25
|
'xt'
|
|
@@ -2,7 +2,7 @@ module Sportradar
|
|
|
2
2
|
module Api
|
|
3
3
|
module Soccer
|
|
4
4
|
class Event < Data
|
|
5
|
-
attr_reader :id, :type, :time, :period, :period_type, :period_name, :match_time, :team, :x, :y, :outcome, :home_score, :away_score, :goal_scorer, :stoppage_time, :player_out, :player_in, :player
|
|
5
|
+
attr_reader :id, :type, :time, :period, :period_type, :period_name, :match_time, :team, :x, :y, :outcome, :home_score, :away_score, :goal_scorer, :stoppage_time, :player_out, :player_in, :player, :commentaries
|
|
6
6
|
|
|
7
7
|
def initialize(data, **opts)
|
|
8
8
|
@response = data
|
|
@@ -8,6 +8,7 @@ module Sportradar
|
|
|
8
8
|
attr_reader :home, :away, :tournament_id
|
|
9
9
|
attr_reader :period, :score, :broadcast, :coverage # these are for consistency with other sports
|
|
10
10
|
attr_reader :match_time, :stoppage_time
|
|
11
|
+
attr_reader :team_stats, :player_stats
|
|
11
12
|
|
|
12
13
|
def initialize(data = {}, league_group: nil, **opts)
|
|
13
14
|
@response = data
|
|
@@ -22,9 +23,12 @@ module Sportradar
|
|
|
22
23
|
@lineups_hash = {}
|
|
23
24
|
get_tournament_id(data, **opts)
|
|
24
25
|
@scoring_raw = Scoring.new(data, game: self)
|
|
25
|
-
@home = Team.new(
|
|
26
|
-
@away = Team.new(
|
|
26
|
+
@home = Team.new(data['home'].to_h, api: api, match: self)
|
|
27
|
+
@away = Team.new(data['away'].to_h, api: api, match: self)
|
|
27
28
|
@teams_hash = { away: @away, home: @home }
|
|
29
|
+
@team_ids = { away: @away.id, home: @home.id }
|
|
30
|
+
@team_stats = {}
|
|
31
|
+
@player_stats = {}
|
|
28
32
|
|
|
29
33
|
update(data, **opts)
|
|
30
34
|
end
|
|
@@ -66,7 +70,7 @@ module Sportradar
|
|
|
66
70
|
@away_score = data['away_score'] if data['away_score']
|
|
67
71
|
@period = data['period'] if data['period']
|
|
68
72
|
@match_time = data.dig('clock', 'match_time') if data.dig('clock', 'match_time')
|
|
69
|
-
@stoppage_time = data.dig('clock', 'stoppage_time')
|
|
73
|
+
@stoppage_time = data.dig('clock', 'stoppage_time')
|
|
70
74
|
@ball_locations = data['ball_locations'] if data['ball_locations']
|
|
71
75
|
@winner_id = data['winner_id'] if data['winner_id']
|
|
72
76
|
|
|
@@ -142,18 +146,19 @@ module Sportradar
|
|
|
142
146
|
['live'].include?(@status) || ['halftime', '1st_half', '2nd_half'].include?(@match_status)
|
|
143
147
|
end
|
|
144
148
|
def finished?
|
|
145
|
-
['complete', 'closed'].include?(@status) || ['ended'].include?(@match_status)
|
|
149
|
+
['ended', 'complete', 'closed'].include?(@status) || ['ended'].include?(@match_status)
|
|
146
150
|
end
|
|
147
151
|
def completed?
|
|
148
|
-
'complete'
|
|
152
|
+
['ended', 'complete'].include? status
|
|
149
153
|
end
|
|
150
154
|
def closed?
|
|
151
155
|
'closed' == status
|
|
152
156
|
end
|
|
153
157
|
|
|
154
158
|
def clock_display
|
|
155
|
-
|
|
156
|
-
|
|
159
|
+
return unless @match_time
|
|
160
|
+
if @stoppage_time && (@match_time == '45:00' || @match_time == '90:00') # stoppage time
|
|
161
|
+
@match_time.split(':').first + ?' + '+' + @stoppage_time.split(':').first
|
|
157
162
|
else
|
|
158
163
|
@match_time.split(':').first + ?'
|
|
159
164
|
end
|
|
@@ -164,7 +169,7 @@ module Sportradar
|
|
|
164
169
|
return nil unless @match_time
|
|
165
170
|
mm, ss = @match_time.split(':').map(&:to_i)
|
|
166
171
|
time = mm * 60 + ss
|
|
167
|
-
if @match_time == '45:00' || @match_time == '90:00' # stoppage time
|
|
172
|
+
if @stoppage_time && (@match_time == '45:00' || @match_time == '90:00') # stoppage time
|
|
168
173
|
mm, ss = @stoppage_time.split(':').map(&:to_i)
|
|
169
174
|
stop_time = mm * 60 + ss
|
|
170
175
|
time += stop_time
|
|
@@ -181,9 +186,20 @@ module Sportradar
|
|
|
181
186
|
@away.update(away_hash, match: self)
|
|
182
187
|
@teams_hash[@home.id] = @home
|
|
183
188
|
@teams_hash[@away.id] = @away
|
|
189
|
+
@team_ids = { away: @away.id, home: @home.id }
|
|
184
190
|
end
|
|
185
191
|
end
|
|
186
192
|
|
|
193
|
+
def update_stats(team, stats)
|
|
194
|
+
@team_stats.merge!(team.id => stats.merge(team: team))
|
|
195
|
+
end
|
|
196
|
+
def update_player_stats(player, stats)
|
|
197
|
+
@player_stats.merge!(player.id => stats.merge!(player: player))
|
|
198
|
+
end
|
|
199
|
+
def stats(team_id)
|
|
200
|
+
team_id.is_a?(Symbol) ? @team_stats[@team_ids[team_id]] : @team_stats[team_id]
|
|
201
|
+
end
|
|
202
|
+
|
|
187
203
|
def get_tournament_id(data, **opts)
|
|
188
204
|
@tournament_id ||= if opts[:tournament]
|
|
189
205
|
opts[:tournament].id
|
|
@@ -210,6 +226,19 @@ module Sportradar
|
|
|
210
226
|
end
|
|
211
227
|
end
|
|
212
228
|
|
|
229
|
+
def timeline_by_minute(minute_start, minute_end = nil)
|
|
230
|
+
if minute_end
|
|
231
|
+
@timeline_hash.each_value.select { |ev| (minute_start..minute_end).cover?(ev.match_time.to_i) }
|
|
232
|
+
else
|
|
233
|
+
@timeline_hash.each_value.select { |ev| minute_start === ev.match_time }
|
|
234
|
+
end
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
def plays_by_minute(type, minute_start, minute_end = nil)
|
|
238
|
+
timeline_by_minute(minute_start, minute_end).select { |ev| ev.type == type }
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
|
|
213
242
|
def lineups(which = nil)
|
|
214
243
|
if which
|
|
215
244
|
@lineups_hash[which.to_s]
|
|
@@ -3,13 +3,15 @@ module Sportradar
|
|
|
3
3
|
module Soccer
|
|
4
4
|
class Player < Data
|
|
5
5
|
|
|
6
|
-
attr_reader :id, :league_group, :name, :type, :nationality, :country_code, :height, :weight, :jersey_number, :preferred_foot, :stats, :date_of_birth, :matches_played
|
|
6
|
+
attr_reader :id, :league_group, :name, :type, :nationality, :country_code, :height, :weight, :jersey_number, :preferred_foot, :stats, :game_stats, :date_of_birth, :matches_played
|
|
7
7
|
alias :position :type
|
|
8
8
|
|
|
9
9
|
def initialize(data = {}, league_group: nil, **opts)
|
|
10
10
|
@response = data
|
|
11
11
|
@id = data['id'] if data['id']
|
|
12
12
|
@api = opts[:api]
|
|
13
|
+
@team = opts[:team]
|
|
14
|
+
|
|
13
15
|
@league_group = league_group || data['league_group'] || @api&.league_group
|
|
14
16
|
|
|
15
17
|
update(data, **opts)
|
|
@@ -34,22 +36,80 @@ module Sportradar
|
|
|
34
36
|
@jersey_number = data['jersey_number'] if data['jersey_number']
|
|
35
37
|
@preferred_foot = data['preferred_foot'] if data['preferred_foot']
|
|
36
38
|
@matches_played = data['matches_played'] if data['matches_played']
|
|
37
|
-
|
|
38
39
|
@stats = data['statistics'] if data['statistics']
|
|
39
|
-
|
|
40
40
|
@date_of_birth = Date.parse(data['date_of_birth']) if data['date_of_birth']
|
|
41
|
+
set_game_stats(data)
|
|
42
|
+
|
|
43
|
+
@team.update_player_stats(self, data['statistics']) if data['statistics'] && @team
|
|
44
|
+
if opts[:match]
|
|
45
|
+
@team.update_player_stats(self, data, opts[:match])
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def set_game_stats(data)
|
|
51
|
+
@game_stats ||= {}
|
|
52
|
+
|
|
53
|
+
@game_stats[:substituted_in] = data['substituted_in'] if data['substituted_in'].present?
|
|
54
|
+
@game_stats[:substituted_out] = data['substituted_out'] if data['substituted_out'].present?
|
|
55
|
+
@game_stats[:goals_scored] = data['goals_scored'] if data['goals_scored'].present?
|
|
56
|
+
@game_stats[:assists] = data['assists'] if data['assists'].present?
|
|
57
|
+
@game_stats[:own_goals] = data['own_goals'] if data['own_goals'].present?
|
|
58
|
+
@game_stats[:yellow_cards] = data['yellow_cards'] if data['yellow_cards'].present?
|
|
59
|
+
@game_stats[:yellow_red_cards] = data['yellow_red_cards'] if data['yellow_red_cards'].present?
|
|
60
|
+
@game_stats[:red_cards] = data['red_cards'] if data['red_cards'].present?
|
|
61
|
+
@game_stats[:goal_line_clearances] = data['goal_line_clearances'] if data['goal_line_clearances'].present?
|
|
62
|
+
@game_stats[:interceptions] = data['interceptions'] if data['interceptions'].present?
|
|
63
|
+
@game_stats[:chances_created] = data['chances_created'] if data['chances_created'].present?
|
|
64
|
+
@game_stats[:crosses_successful] = data['crosses_successful'] if data['crosses_successful'].present?
|
|
65
|
+
@game_stats[:crosses_total] = data['crosses_total'] if data['crosses_total'].present?
|
|
66
|
+
@game_stats[:passes_short_successful] = data['passes_short_successful'] if data['passes_short_successful'].present?
|
|
67
|
+
@game_stats[:passes_medium_successful] = data['passes_medium_successful'] if data['passes_medium_successful'].present?
|
|
68
|
+
@game_stats[:passes_long_successful] = data['passes_long_successful'] if data['passes_long_successful'].present?
|
|
69
|
+
@game_stats[:passes_short_total] = data['passes_short_total'] if data['passes_short_total'].present?
|
|
70
|
+
@game_stats[:passes_medium_total] = data['passes_medium_total'] if data['passes_medium_total'].present?
|
|
71
|
+
@game_stats[:passes_long_total] = data['passes_long_total'] if data['passes_long_total'].present?
|
|
72
|
+
@game_stats[:duels_header_successful] = data['duels_header_successful'] if data['duels_header_successful'].present?
|
|
73
|
+
@game_stats[:duels_sprint_successful] = data['duels_sprint_successful'] if data['duels_sprint_successful'].present?
|
|
74
|
+
@game_stats[:duels_tackle_successful] = data['duels_tackle_successful'] if data['duels_tackle_successful'].present?
|
|
75
|
+
@game_stats[:duels_header_total] = data['duels_header_total'] if data['duels_header_total'].present?
|
|
76
|
+
@game_stats[:duels_sprint_total] = data['duels_sprint_total'] if data['duels_sprint_total'].present?
|
|
77
|
+
@game_stats[:duels_tackle_total] = data['duels_tackle_total'] if data['duels_tackle_total'].present?
|
|
78
|
+
@game_stats[:goals_conceded] = data['goals_conceded'] if data['goals_conceded'].present?
|
|
79
|
+
@game_stats[:shots_faced_saved] = data['shots_faced_saved'] if data['shots_faced_saved'].present?
|
|
80
|
+
@game_stats[:shots_faced_total] = data['shots_faced_total'] if data['shots_faced_total'].present?
|
|
81
|
+
@game_stats[:penalties_faced] = data['penalties_faced'] if data['penalties_faced'].present?
|
|
82
|
+
@game_stats[:penalties_saved] = data['penalties_saved'] if data['penalties_saved'].present?
|
|
83
|
+
@game_stats[:fouls_committed] = data['fouls_committed'] if data['fouls_committed'].present?
|
|
84
|
+
@game_stats[:was_fouled] = data['was_fouled'] if data['was_fouled'].present?
|
|
85
|
+
@game_stats[:offsides] = data['offsides'] if data['offsides'].present?
|
|
86
|
+
@game_stats[:shots_on_goal] = data['shots_on_goal'] if data['shots_on_goal'].present?
|
|
87
|
+
@game_stats[:shots_off_goal] = data['shots_off_goal'] if data['shots_off_goal'].present?
|
|
88
|
+
@game_stats[:shots_blocked] = data['shots_blocked'] if data['shots_blocked'].present?
|
|
89
|
+
@game_stats[:minutes_played] = data['minutes_played'] if data['minutes_played'].present?
|
|
90
|
+
@game_stats[:performance_score] = data['performance_score'] if data['performance_score'].present?
|
|
91
|
+
@game_stats[:goals_by_head] = data['goals_by_head'] if data['goals_by_head'].present?
|
|
92
|
+
@game_stats[:goals_by_penalty] = data['goals_by_penalty'] if data['goals_by_penalty'].present?
|
|
41
93
|
end
|
|
42
94
|
|
|
43
95
|
def display_name
|
|
44
96
|
@name || [@first_name, @last_name].join(' ')
|
|
45
97
|
end
|
|
46
98
|
|
|
99
|
+
def birth_date
|
|
100
|
+
@date_of_birth
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def jersey
|
|
104
|
+
@jersey_number
|
|
105
|
+
end
|
|
106
|
+
|
|
47
107
|
def first_name
|
|
48
|
-
@
|
|
108
|
+
@name.split()[1]
|
|
49
109
|
end
|
|
50
110
|
|
|
51
111
|
def last_name
|
|
52
|
-
@
|
|
112
|
+
@name.split()[0].delete(',')
|
|
53
113
|
end
|
|
54
114
|
|
|
55
115
|
def api
|
|
@@ -2,13 +2,14 @@ module Sportradar
|
|
|
2
2
|
module Api
|
|
3
3
|
module Soccer
|
|
4
4
|
class Team < Data
|
|
5
|
-
|
|
5
|
+
attr_reader :response
|
|
6
|
+
attr_accessor :tournament_id, :venue, :player_stats
|
|
6
7
|
attr_reader :id, :league_group, :name, :country, :country_code, :abbreviation, :qualifier
|
|
7
8
|
alias :alias :abbreviation
|
|
8
9
|
alias :market :name
|
|
9
10
|
alias :display_name :name
|
|
10
11
|
alias :full_name :name
|
|
11
|
-
attr_reader :
|
|
12
|
+
attr_reader :team_stats, :jerseys, :manager, :statistics
|
|
12
13
|
|
|
13
14
|
def initialize(data = {}, league_group: nil, **opts)
|
|
14
15
|
@response = data
|
|
@@ -17,6 +18,7 @@ module Sportradar
|
|
|
17
18
|
@league_group = league_group || data['league_group'] || @api&.league_group
|
|
18
19
|
|
|
19
20
|
@players_hash = {}
|
|
21
|
+
@player_stats = {}
|
|
20
22
|
@matches_hash = {}
|
|
21
23
|
|
|
22
24
|
update(data, **opts)
|
|
@@ -31,7 +33,6 @@ module Sportradar
|
|
|
31
33
|
update(data["team"])
|
|
32
34
|
end
|
|
33
35
|
|
|
34
|
-
|
|
35
36
|
@name = data['name'] if data['name']
|
|
36
37
|
@country = data['country'] if data['country']
|
|
37
38
|
@country_code = data['country_code'] if data['country_code']
|
|
@@ -39,11 +40,15 @@ module Sportradar
|
|
|
39
40
|
@qualifier = data['qualifier'] if data['qualifier']
|
|
40
41
|
@venue = Venue.new(data['venue']) if data['venue']
|
|
41
42
|
|
|
42
|
-
create_data(@players_hash, data['players'], klass: Player, api: api, team: self) if data['players']
|
|
43
|
-
create_data(@players_hash, data['player_statistics'], klass: Player, api: api, team: self) if data['player_statistics']
|
|
43
|
+
create_data(@players_hash, data['players'], klass: Player, api: api, team: self, **opts) if data['players']
|
|
44
|
+
create_data(@players_hash, data['player_statistics'], klass: Player, api: api, team: self, **opts) if data['player_statistics']
|
|
45
|
+
|
|
46
|
+
@team_stats = data['team_statistics'] if data['team_statistics']
|
|
44
47
|
|
|
45
|
-
#
|
|
46
|
-
|
|
48
|
+
# parse_players(data.dig('players'), opts[:match]) if data.dig('players')
|
|
49
|
+
if opts[:match]
|
|
50
|
+
opts[:match].update_stats(self, data['statistics']) if data['statistics']
|
|
51
|
+
end
|
|
47
52
|
|
|
48
53
|
create_data(@matches_hash, Soccer.parse_results(data['results']), klass: Match, api: api, team: self) if data['results']
|
|
49
54
|
create_data(@matches_hash, data['schedule'], klass: Match, api: api, team: self) if data['schedule']
|
|
@@ -57,10 +62,10 @@ module Sportradar
|
|
|
57
62
|
def get_tournament_id(data, **opts)
|
|
58
63
|
@tournament_id ||= if opts[:tournament]
|
|
59
64
|
opts[:tournament].id
|
|
60
|
-
elsif opts[:season]
|
|
61
|
-
opts[:season]
|
|
62
|
-
elsif opts[:match]
|
|
63
|
-
opts[:match]
|
|
65
|
+
elsif opts[:season]&.tournament_id
|
|
66
|
+
opts[:season]&.tournament_id
|
|
67
|
+
elsif opts[:match]&.tournament_id
|
|
68
|
+
opts[:match]&.tournament_id
|
|
64
69
|
elsif data['tournament_id']
|
|
65
70
|
data['tournament_id']
|
|
66
71
|
elsif data['tournament']
|
|
@@ -70,6 +75,10 @@ module Sportradar
|
|
|
70
75
|
end
|
|
71
76
|
end
|
|
72
77
|
|
|
78
|
+
def update_player_stats(player, stats, game = nil)
|
|
79
|
+
game ? game.update_player_stats(player, stats) : @player_stats.merge(player.id => stats.to_h.merge(player: player))
|
|
80
|
+
end
|
|
81
|
+
|
|
73
82
|
def players
|
|
74
83
|
@players_hash.values
|
|
75
84
|
end
|
|
@@ -141,6 +150,9 @@ module Sportradar
|
|
|
141
150
|
data = api.get_data(path_statistics(tourn_id)).to_h
|
|
142
151
|
ingest_statistics(data)
|
|
143
152
|
end
|
|
153
|
+
def get_season_stats(*args)
|
|
154
|
+
get_statistics
|
|
155
|
+
end
|
|
144
156
|
def ingest_statistics(data)
|
|
145
157
|
update(data)
|
|
146
158
|
data
|
|
@@ -2,7 +2,7 @@ module Sportradar
|
|
|
2
2
|
module Api
|
|
3
3
|
module Soccer
|
|
4
4
|
class Tournament < Data
|
|
5
|
-
attr_reader :id, :league_group, :name, :category
|
|
5
|
+
attr_reader :id, :league_group, :name, :category, :coverage_info, :live_coverage, :season_coverage_info
|
|
6
6
|
alias :display_name :name
|
|
7
7
|
alias :alias :name
|
|
8
8
|
|
|
@@ -26,8 +26,10 @@ module Sportradar
|
|
|
26
26
|
update(data['tournament'])
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
-
@name
|
|
30
|
-
@category
|
|
29
|
+
@name = data["name"] || @name
|
|
30
|
+
@category = data['category'] || @category
|
|
31
|
+
@coverage_info = data['coverage_info'] || @coverage_info
|
|
32
|
+
@live_coverage = data.dig('coverage_info', 'live_coverage') || @live_coverage
|
|
31
33
|
|
|
32
34
|
parse_info(data)
|
|
33
35
|
parse_season(data)
|
|
@@ -86,6 +88,7 @@ module Sportradar
|
|
|
86
88
|
|
|
87
89
|
def parse_season(data)
|
|
88
90
|
if data['season_coverage_info']
|
|
91
|
+
@season_coverage_info = data['season_coverage_info'] if data['season_coverage_info']
|
|
89
92
|
data['season_coverage_info']['id'] ||= data['season_coverage_info'].delete('season_id')
|
|
90
93
|
create_data(@seasons_hash, data['season_coverage_info'], klass: Season, api: api, tournament: self)
|
|
91
94
|
end
|
|
@@ -235,6 +238,7 @@ module Sportradar
|
|
|
235
238
|
'eu.uefa_champions_league' => "sr:tournament:7",
|
|
236
239
|
'eu.la_liga' => "sr:tournament:8",
|
|
237
240
|
'eu.eng_premier_league' => "sr:tournament:17",
|
|
241
|
+
'eu.premier_league' => "sr:tournament:17",
|
|
238
242
|
'eu.serie_a' => "sr:tournament:23",
|
|
239
243
|
'eu.ligue_1' => "sr:tournament:34",
|
|
240
244
|
'eu.bundesliga' => "sr:tournament:35",
|
data/lib/sportradar/api.rb
CHANGED
|
@@ -60,7 +60,7 @@ module Sportradar
|
|
|
60
60
|
{api: :nascar, version: 3},
|
|
61
61
|
{api: :odds, version: 1},
|
|
62
62
|
{api: :content, version: 3},
|
|
63
|
-
{api: :images, version:
|
|
63
|
+
{api: :images, version: 3},
|
|
64
64
|
{api: :live_images, version: 1},
|
|
65
65
|
{api: :olympics, version: 2},
|
|
66
66
|
{api: :soccer, version: 3},
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sportradar-api
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.14.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ben Eggett
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2018-08-23 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -471,7 +471,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
471
471
|
version: '0'
|
|
472
472
|
requirements: []
|
|
473
473
|
rubyforge_project:
|
|
474
|
-
rubygems_version: 2.6
|
|
474
|
+
rubygems_version: 2.7.6
|
|
475
475
|
signing_key:
|
|
476
476
|
specification_version: 4
|
|
477
477
|
summary: Sportradar API client
|