sportradar-api 0.9.12 → 0.11.21
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 +4 -4
- data/.env.sample +6 -0
- data/.travis.yml +1 -0
- data/Gemfile.lock +32 -30
- data/README.md +12 -9
- data/lib/sportradar/api/baseball/README.md +28 -0
- data/lib/sportradar/api/baseball/error.rb +25 -0
- data/lib/sportradar/api/baseball/event.rb +44 -0
- data/lib/sportradar/api/baseball/events/at_bat.rb +96 -0
- data/lib/sportradar/api/baseball/events/lineup.rb +41 -0
- data/lib/sportradar/api/baseball/events/warming_up.rb +35 -0
- data/lib/sportradar/api/baseball/fielder.rb +26 -0
- data/lib/sportradar/api/baseball/game.rb +472 -0
- data/lib/sportradar/api/baseball/half_inning.rb +69 -0
- data/lib/sportradar/api/baseball/inning.rb +42 -0
- data/lib/sportradar/api/baseball/lineup.rb +116 -0
- data/lib/sportradar/api/baseball/mlb/division.rb +32 -0
- data/lib/sportradar/api/baseball/mlb/hierarchy.rb +273 -0
- data/lib/sportradar/api/baseball/mlb/league.rb +27 -0
- data/lib/sportradar/api/baseball/mlb.rb +84 -0
- data/lib/sportradar/api/baseball/outcome.rb +87 -0
- data/lib/sportradar/api/baseball/pitch.rb +245 -0
- data/lib/sportradar/api/baseball/player.rb +119 -0
- data/lib/sportradar/api/baseball/record.rb +42 -0
- data/lib/sportradar/api/baseball/runner.rb +78 -0
- data/lib/sportradar/api/baseball/scoring.rb +86 -0
- data/lib/sportradar/api/baseball/team.rb +147 -0
- data/lib/sportradar/api/baseball/venue.rb +51 -0
- data/lib/sportradar/api/baseball.rb +46 -0
- data/lib/sportradar/api/basketball/broadcast.rb +15 -0
- data/lib/sportradar/api/basketball/game.rb +339 -0
- data/lib/sportradar/api/basketball/injury.rb +41 -0
- data/lib/sportradar/api/basketball/nba/conference.rb +27 -0
- data/lib/sportradar/api/basketball/nba/division.rb +30 -0
- data/lib/sportradar/api/basketball/nba/game.rb +62 -0
- data/lib/sportradar/api/basketball/nba/hierarchy.rb +47 -0
- data/lib/sportradar/api/basketball/nba/player.rb +160 -0
- data/lib/sportradar/api/basketball/nba/quarter.rb +51 -0
- data/lib/sportradar/api/basketball/nba/schedule.rb +43 -0
- data/lib/sportradar/api/basketball/nba/scoring.rb +15 -0
- data/lib/sportradar/api/basketball/nba/season.rb +54 -0
- data/lib/sportradar/api/basketball/nba/series.rb +82 -0
- data/lib/sportradar/api/basketball/nba/team.rb +74 -0
- data/lib/sportradar/api/basketball/nba.rb +129 -0
- data/lib/sportradar/api/basketball/ncaamb/bracket.rb +44 -0
- data/lib/sportradar/api/basketball/ncaamb/conference.rb +41 -0
- data/lib/sportradar/api/basketball/ncaamb/division.rb +42 -0
- data/lib/sportradar/api/basketball/ncaamb/game.rb +75 -0
- data/lib/sportradar/api/basketball/ncaamb/half.rb +49 -0
- data/lib/sportradar/api/basketball/ncaamb/hierarchy.rb +65 -0
- data/lib/sportradar/api/basketball/ncaamb/player.rb +162 -0
- data/lib/sportradar/api/basketball/ncaamb/round.rb +55 -0
- data/lib/sportradar/api/basketball/ncaamb/schedule.rb +41 -0
- data/lib/sportradar/api/basketball/ncaamb/season.rb +55 -0
- data/lib/sportradar/api/basketball/ncaamb/team.rb +61 -0
- data/lib/sportradar/api/basketball/ncaamb/tournament.rb +154 -0
- data/lib/sportradar/api/basketball/ncaamb.rb +149 -0
- data/lib/sportradar/api/basketball/play.rb +75 -0
- data/lib/sportradar/api/basketball/plays/assist.rb +14 -0
- data/lib/sportradar/api/basketball/plays/base.rb +126 -0
- data/lib/sportradar/api/basketball/plays/block.rb +14 -0
- data/lib/sportradar/api/basketball/plays/clear_path_foul.rb +11 -0
- data/lib/sportradar/api/basketball/plays/deadball.rb +11 -0
- data/lib/sportradar/api/basketball/plays/defensive_three_seconds.rb +11 -0
- data/lib/sportradar/api/basketball/plays/delay.rb +11 -0
- data/lib/sportradar/api/basketball/plays/ejection.rb +14 -0
- data/lib/sportradar/api/basketball/plays/end_period.rb +28 -0
- data/lib/sportradar/api/basketball/plays/flagrant_one.rb +11 -0
- data/lib/sportradar/api/basketball/plays/flagrant_two.rb +11 -0
- data/lib/sportradar/api/basketball/plays/foul.rb +17 -0
- data/lib/sportradar/api/basketball/plays/free_throw_made.rb +23 -0
- data/lib/sportradar/api/basketball/plays/free_throw_miss.rb +25 -0
- data/lib/sportradar/api/basketball/plays/jumpball.rb +12 -0
- data/lib/sportradar/api/basketball/plays/kickball.rb +11 -0
- data/lib/sportradar/api/basketball/plays/lineup_change.rb +11 -0
- data/lib/sportradar/api/basketball/plays/offensive_foul.rb +11 -0
- data/lib/sportradar/api/basketball/plays/official_timeout.rb +11 -0
- data/lib/sportradar/api/basketball/plays/open_inbound.rb +9 -0
- data/lib/sportradar/api/basketball/plays/open_tip.rb +11 -0
- data/lib/sportradar/api/basketball/plays/personal_foul.rb +9 -0
- data/lib/sportradar/api/basketball/plays/rebound.rb +28 -0
- data/lib/sportradar/api/basketball/plays/review.rb +11 -0
- data/lib/sportradar/api/basketball/plays/shooting_foul.rb +9 -0
- data/lib/sportradar/api/basketball/plays/shot_made.rb +22 -0
- data/lib/sportradar/api/basketball/plays/shot_miss.rb +22 -0
- data/lib/sportradar/api/basketball/plays/steal.rb +11 -0
- data/lib/sportradar/api/basketball/plays/team_timeout.rb +14 -0
- data/lib/sportradar/api/basketball/plays/technical_foul.rb +14 -0
- data/lib/sportradar/api/basketball/plays/three_point_made.rb +14 -0
- data/lib/sportradar/api/basketball/plays/three_point_miss.rb +11 -0
- data/lib/sportradar/api/basketball/plays/timeout.rb +24 -0
- data/lib/sportradar/api/basketball/plays/turnover.rb +19 -0
- data/lib/sportradar/api/basketball/plays/tv_timeout.rb +11 -0
- data/lib/sportradar/api/basketball/plays/two_point_made.rb +14 -0
- data/lib/sportradar/api/basketball/plays/two_point_miss.rb +11 -0
- data/lib/sportradar/api/basketball/plays.rb +39 -0
- data/lib/sportradar/api/basketball/record.rb +28 -0
- data/lib/sportradar/api/basketball/scoring.rb +103 -0
- data/lib/sportradar/api/basketball/season.rb +20 -0
- data/lib/sportradar/api/basketball/team.rb +136 -0
- data/lib/sportradar/api/basketball/venue.rb +54 -0
- data/lib/sportradar/api/basketball.rb +35 -0
- data/lib/sportradar/api/{nfl/broadcast.rb → broadcast.rb} +1 -1
- data/lib/sportradar/api/content/article.rb +1 -1
- data/lib/sportradar/api/content/article_list.rb +1 -1
- data/lib/sportradar/api/content.rb +17 -5
- data/lib/sportradar/api/data.rb +53 -0
- data/lib/sportradar/api/football/README.md +62 -0
- data/lib/sportradar/api/football/drive.rb +114 -0
- data/lib/sportradar/api/football/event.rb +36 -0
- data/lib/sportradar/api/football/game.rb +404 -0
- data/lib/sportradar/api/football/game_stats.rb +135 -0
- data/lib/sportradar/api/football/ncaafb/api.rb +81 -0
- data/lib/sportradar/api/football/ncaafb/conference.rb +53 -0
- data/lib/sportradar/api/football/ncaafb/division.rb +42 -0
- data/lib/sportradar/api/football/ncaafb/drive.rb +36 -0
- data/lib/sportradar/api/football/ncaafb/game.rb +130 -0
- data/lib/sportradar/api/football/ncaafb/play.rb +97 -0
- data/lib/sportradar/api/football/ncaafb/player.rb +31 -0
- data/lib/sportradar/api/football/ncaafb/quarter.rb +15 -0
- data/lib/sportradar/api/football/ncaafb/subdivision.rb +43 -0
- data/lib/sportradar/api/football/ncaafb/team.rb +49 -0
- data/lib/sportradar/api/football/ncaafb/week.rb +24 -0
- data/lib/sportradar/api/football/ncaafb.rb +273 -0
- data/lib/sportradar/api/football/nfl/api.rb +76 -0
- data/lib/sportradar/api/football/nfl/conference.rb +35 -0
- data/lib/sportradar/api/football/nfl/depth_chart.rb +53 -0
- data/lib/sportradar/api/football/nfl/division.rb +37 -0
- data/lib/sportradar/api/football/nfl/drive.rb +19 -0
- data/lib/sportradar/api/football/nfl/event.rb +19 -0
- data/lib/sportradar/api/football/nfl/game.rb +77 -0
- data/lib/sportradar/api/football/nfl/league_depth_chart.rb +41 -0
- data/lib/sportradar/api/football/nfl/play.rb +27 -0
- data/lib/sportradar/api/football/nfl/player.rb +31 -0
- data/lib/sportradar/api/football/nfl/quarter.rb +15 -0
- data/lib/sportradar/api/football/nfl/team.rb +42 -0
- data/lib/sportradar/api/football/nfl/team_depth_chart.rb +44 -0
- data/lib/sportradar/api/football/nfl/week.rb +24 -0
- data/lib/sportradar/api/football/nfl.rb +322 -0
- data/lib/sportradar/api/football/play.rb +116 -0
- data/lib/sportradar/api/football/play_statistics.rb +313 -0
- data/lib/sportradar/api/football/player.rb +121 -0
- data/lib/sportradar/api/football/quarter.rb +46 -0
- data/lib/sportradar/api/football/record.rb +48 -0
- data/lib/sportradar/api/football/scoring.rb +92 -0
- data/lib/sportradar/api/football/situation.rb +32 -0
- data/lib/sportradar/api/football/stat_pack/defense.rb +20 -20
- data/lib/sportradar/api/football/stat_pack/extra_points.rb +5 -4
- data/lib/sportradar/api/football/stat_pack/field_goals.rb +6 -5
- data/lib/sportradar/api/football/stat_pack/fumbles.rb +11 -9
- data/lib/sportradar/api/football/stat_pack/kick_returns.rb +8 -7
- data/lib/sportradar/api/football/stat_pack/kickoffs.rb +9 -7
- data/lib/sportradar/api/football/stat_pack/misc_returns.rb +1 -1
- data/lib/sportradar/api/football/stat_pack/passing.rb +13 -11
- data/lib/sportradar/api/football/stat_pack/penalties.rb +2 -2
- data/lib/sportradar/api/football/stat_pack/punt_returns.rb +7 -6
- data/lib/sportradar/api/football/stat_pack/punts.rb +12 -10
- data/lib/sportradar/api/football/stat_pack/receiving.rb +10 -9
- data/lib/sportradar/api/football/stat_pack/rushing.rb +11 -9
- data/lib/sportradar/api/football/stat_pack.rb +7 -3
- data/lib/sportradar/api/football/team.rb +160 -0
- data/lib/sportradar/api/football/venue.rb +25 -0
- data/lib/sportradar/api/football/week.rb +57 -0
- data/lib/sportradar/api/football.rb +47 -0
- data/lib/sportradar/api/images/asset.rb +2 -1
- data/lib/sportradar/api/images/ref.rb +15 -0
- data/lib/sportradar/api/images.rb +51 -9
- data/lib/sportradar/api/mma/event.rb +111 -0
- data/lib/sportradar/api/mma/fight.rb +107 -0
- data/lib/sportradar/api/mma/fighter.rb +95 -0
- data/lib/sportradar/api/mma/judge.rb +70 -0
- data/lib/sportradar/api/mma/league.rb +63 -0
- data/lib/sportradar/api/mma/referee.rb +70 -0
- data/lib/sportradar/api/mma/result.rb +68 -0
- data/lib/sportradar/api/mma/roster.rb +72 -0
- data/lib/sportradar/api/mma/schedule.rb +53 -0
- data/lib/sportradar/api/mma/score.rb +83 -0
- data/lib/sportradar/api/mma/venue.rb +72 -0
- data/lib/sportradar/api/mma.rb +195 -0
- data/lib/sportradar/api/poll.rb +40 -0
- data/lib/sportradar/api/request.rb +40 -8
- data/lib/sportradar/api/soccer/schedule.rb +1 -0
- data/lib/sportradar/api/version.rb +1 -1
- data/lib/sportradar/api.rb +20 -34
- metadata +157 -34
- data/lib/sportradar/api/nfl/.play_statistics.rb.swo +0 -0
- data/lib/sportradar/api/nfl/changelog.rb +0 -17
- data/lib/sportradar/api/nfl/coach.rb +0 -17
- data/lib/sportradar/api/nfl/conference.rb +0 -16
- data/lib/sportradar/api/nfl/depth_chart.rb +0 -47
- data/lib/sportradar/api/nfl/division.rb +0 -16
- data/lib/sportradar/api/nfl/draft.rb +0 -16
- data/lib/sportradar/api/nfl/drive.rb +0 -73
- data/lib/sportradar/api/nfl/event.rb +0 -19
- data/lib/sportradar/api/nfl/franchise.rb +0 -14
- data/lib/sportradar/api/nfl/game.rb +0 -94
- data/lib/sportradar/api/nfl/game_statistic.rb +0 -133
- data/lib/sportradar/api/nfl/hierarchy.rb +0 -19
- data/lib/sportradar/api/nfl/injury.rb +0 -16
- data/lib/sportradar/api/nfl/league_depth_chart.rb +0 -26
- data/lib/sportradar/api/nfl/play.rb +0 -39
- data/lib/sportradar/api/nfl/play_statistics.rb +0 -247
- data/lib/sportradar/api/nfl/player.rb +0 -49
- data/lib/sportradar/api/nfl/position.rb +0 -14
- data/lib/sportradar/api/nfl/quarter.rb +0 -29
- data/lib/sportradar/api/nfl/scoring.rb +0 -25
- data/lib/sportradar/api/nfl/season.rb +0 -23
- data/lib/sportradar/api/nfl/situation.rb +0 -18
- data/lib/sportradar/api/nfl/statistic.rb +0 -28
- data/lib/sportradar/api/nfl/summary.rb +0 -17
- data/lib/sportradar/api/nfl/team.rb +0 -56
- data/lib/sportradar/api/nfl/team_depth_chart.rb +0 -44
- data/lib/sportradar/api/nfl/venue.rb +0 -22
- data/lib/sportradar/api/nfl/week.rb +0 -16
- data/lib/sportradar/api/nfl.rb +0 -205
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
module Sportradar
|
|
2
|
+
module Api
|
|
3
|
+
module Baseball
|
|
4
|
+
class Team < Data
|
|
5
|
+
attr_accessor :response, :id, :market, :name, :alias, :full_name, :venue, :records, :player_stats, :team_stats
|
|
6
|
+
|
|
7
|
+
def initialize(data, **opts)
|
|
8
|
+
@response = data # comment this out when done developing
|
|
9
|
+
@api = opts[:api]
|
|
10
|
+
@id = data['id']
|
|
11
|
+
|
|
12
|
+
@games_hash = {}
|
|
13
|
+
@players_hash = {}
|
|
14
|
+
@player_stats = {}
|
|
15
|
+
@records = {}
|
|
16
|
+
@stats = nil
|
|
17
|
+
@runs = nil
|
|
18
|
+
|
|
19
|
+
update(data, **opts)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def update(data, **opts)
|
|
23
|
+
handle_names(data)
|
|
24
|
+
@venue = Venue.new(data['venue']) if data['venue']
|
|
25
|
+
|
|
26
|
+
@alias = data['abbr'] if data['abbr']
|
|
27
|
+
@runs = data['runs'].to_i if data['runs']
|
|
28
|
+
# # @home = data['home'] == 'true' if data['home']
|
|
29
|
+
# # @away = data['away'] == 'true' if data['away']
|
|
30
|
+
# # @scoring = data.dig('scoring', 'quarter') if data.dig('scoring', 'quarter')
|
|
31
|
+
|
|
32
|
+
parse_records(data) if data['win']
|
|
33
|
+
parse_players(data.dig('players'), opts[:game]) if data.dig('players')
|
|
34
|
+
|
|
35
|
+
if opts[:game]
|
|
36
|
+
# opts[:game].update_from_team(id, "runs"=>6)
|
|
37
|
+
# opts[:game].update_from_team(id, "hits"=>11)
|
|
38
|
+
# opts[:game].update_from_team(id, "errors"=>1)
|
|
39
|
+
# opts[:game].update_from_team(id, "win"=>11)
|
|
40
|
+
# opts[:game].update_from_team(id, "loss"=>16)
|
|
41
|
+
# opts[:game].update_from_team(id, "probable_pitcher"=>{"jersey_number"=>"45", "id"=>"c1f19b5a-9dee-4053-9cad-ee4196f921e1", "win"=>2, "loss"=>3, "era"=>5.0})
|
|
42
|
+
# opts[:game].update_from_team(id, "starting_pitcher"=>{"last_name"=>"Cotton", "first_name"=>"Jharel", "preferred_name"=>"Jharel", "jersey_number"=>"45"})
|
|
43
|
+
# opts[:game].update_from_team(id, "current_pitcher"=>{"last_name"=>"Dull", "first_name"=>"Ryan", "preferred_name"=>"Ryan", "jersey_number"=>"66"})
|
|
44
|
+
# add_game(opts[:game])
|
|
45
|
+
# opts[:game].update_score(id => @runs) if @runs
|
|
46
|
+
opts[:game].update_stats(self, data['statistics']) if data['statistics']
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
def handle_names(data)
|
|
50
|
+
# need to do some more work here
|
|
51
|
+
@name = data['name'] if data['name']
|
|
52
|
+
if data['name'] && data['market']
|
|
53
|
+
@market = data['market']
|
|
54
|
+
@full_name = [@market, data['name']].join(' ')
|
|
55
|
+
elsif data['name'] && !data.key?('market')
|
|
56
|
+
@full_name = data['name']
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def record(type = 'overall')
|
|
61
|
+
@records[type]
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def games
|
|
65
|
+
@games_hash.values
|
|
66
|
+
end
|
|
67
|
+
def add_game(game)
|
|
68
|
+
@games_hash[game.id] = game.id if game
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def players
|
|
72
|
+
get_roster if @players_hash.empty?
|
|
73
|
+
@players_hash.values
|
|
74
|
+
end
|
|
75
|
+
alias :roster :players
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
# parsing response data
|
|
79
|
+
|
|
80
|
+
def parse_players(data, game)
|
|
81
|
+
create_data(@players_hash, data, klass: Player, api: api, team: self, game: game)
|
|
82
|
+
end
|
|
83
|
+
def update_player_stats(player, stats, game = nil)
|
|
84
|
+
game ? game.update_player_stats(player, stats) : @player_stats.merge!(player.id => stats.merge!(player: player))
|
|
85
|
+
end
|
|
86
|
+
def parse_records(data)
|
|
87
|
+
@records['overall'] = Record.new(data, type: 'overall')
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def parse_season_stats(data)
|
|
91
|
+
@team_stats = data.dig('statistics')
|
|
92
|
+
update(data)
|
|
93
|
+
player_data = data.dig('players')
|
|
94
|
+
create_data(@players_hash, player_data, klass: Player, api: api, team: self)
|
|
95
|
+
data
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
# data retrieval
|
|
100
|
+
|
|
101
|
+
def get_roster
|
|
102
|
+
data = api.get_data(path_roster)
|
|
103
|
+
ingest_roster(data)
|
|
104
|
+
end
|
|
105
|
+
def ingest_roster(data)
|
|
106
|
+
update(data)
|
|
107
|
+
data
|
|
108
|
+
end
|
|
109
|
+
def queue_roster
|
|
110
|
+
url, headers, options, timeout = api.get_request_info(path_roster)
|
|
111
|
+
{url: url, headers: headers, params: options, timeout: timeout, callback: method(:ingest_roster)}
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def get_season_stats(year = Date.today.year)
|
|
115
|
+
data = api.get_data(path_season_stats(year))
|
|
116
|
+
ingest_season_stats(data)
|
|
117
|
+
end
|
|
118
|
+
def ingest_season_stats(data)
|
|
119
|
+
parse_season_stats(data)
|
|
120
|
+
end
|
|
121
|
+
def queue_season_stats
|
|
122
|
+
url, headers, options, timeout = api.get_request_info(path_season_stats)
|
|
123
|
+
{url: url, headers: headers, params: options, timeout: timeout, callback: method(:ingest_season_stats)}
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# url path helpers
|
|
127
|
+
def path_base
|
|
128
|
+
"teams/#{ id }"
|
|
129
|
+
end
|
|
130
|
+
def path_base_stats(season_year = api.default_year, default_season = api.default_season)
|
|
131
|
+
"seasontd/#{season_year}/#{default_season}/teams/#{id}"
|
|
132
|
+
end
|
|
133
|
+
def path_roster
|
|
134
|
+
"#{ path_base }/profile"
|
|
135
|
+
end
|
|
136
|
+
def path_season_stats(year)
|
|
137
|
+
"#{ path_base_stats(year) }/statistics"
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def api
|
|
141
|
+
@api || Sportradar::Api::Baseball::Mlb.new
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
module Sportradar
|
|
2
|
+
module Api
|
|
3
|
+
module Baseball
|
|
4
|
+
class Venue < Data
|
|
5
|
+
attr_accessor :response, :id, :name, :address, :city, :state, :country, :zip, :capacity, :timezone
|
|
6
|
+
@all_hash = {}
|
|
7
|
+
def self.new(data, **opts)
|
|
8
|
+
existing = @all_hash[data['id']]
|
|
9
|
+
if existing
|
|
10
|
+
existing.update(data, **opts)
|
|
11
|
+
existing
|
|
12
|
+
else
|
|
13
|
+
@all_hash[data['id']] = super
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
def self.all
|
|
17
|
+
@all_hash.values
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def initialize(data, **opts)
|
|
21
|
+
@response = data
|
|
22
|
+
@id = data["id"]
|
|
23
|
+
|
|
24
|
+
update(data, **opts)
|
|
25
|
+
end
|
|
26
|
+
def update(data, **opts)
|
|
27
|
+
@name = data['name']
|
|
28
|
+
@address = data['address']
|
|
29
|
+
@city = data['city']
|
|
30
|
+
@state = data['state']
|
|
31
|
+
@zip = data['zip']
|
|
32
|
+
@country = data['country']
|
|
33
|
+
@capacity = data['capacity']
|
|
34
|
+
@timezone = data['timezone']
|
|
35
|
+
|
|
36
|
+
@surface = data['surface']
|
|
37
|
+
|
|
38
|
+
# dimensions
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def location
|
|
42
|
+
"#{name}, #{city}"
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
KEYS_SCHEDULE = ["id", "name", "capacity", "address", "city", "state", "zip", "country"]
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
__END__
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# require_relative 'baseball/season'
|
|
2
|
+
require_relative 'baseball/game'
|
|
3
|
+
require_relative 'baseball/outcome'
|
|
4
|
+
require_relative 'baseball/team'
|
|
5
|
+
require_relative 'baseball/record'
|
|
6
|
+
require_relative 'baseball/venue'
|
|
7
|
+
require_relative 'baseball/inning'
|
|
8
|
+
require_relative 'baseball/half_inning'
|
|
9
|
+
require_relative 'baseball/error'
|
|
10
|
+
require_relative 'baseball/fielder'
|
|
11
|
+
require_relative 'baseball/runner'
|
|
12
|
+
require_relative 'baseball/event'
|
|
13
|
+
require_relative 'baseball/events/at_bat'
|
|
14
|
+
require_relative 'baseball/events/lineup'
|
|
15
|
+
require_relative 'baseball/events/warming_up'
|
|
16
|
+
require_relative 'baseball/pitch'
|
|
17
|
+
require_relative 'baseball/player'
|
|
18
|
+
require_relative 'baseball/lineup'
|
|
19
|
+
# require_relative 'baseball/broadcast'
|
|
20
|
+
# require_relative 'baseball/injury'
|
|
21
|
+
require_relative 'baseball/scoring'
|
|
22
|
+
|
|
23
|
+
require_relative 'baseball/mlb'
|
|
24
|
+
require_relative 'baseball/mlb/hierarchy'
|
|
25
|
+
require_relative 'baseball/mlb/league'
|
|
26
|
+
require_relative 'baseball/mlb/division'
|
|
27
|
+
# require_relative 'baseball/mlb/season'
|
|
28
|
+
# require_relative 'baseball/mlb/schedule'
|
|
29
|
+
# require_relative 'baseball/mlb/game'
|
|
30
|
+
# require_relative 'baseball/mlb/team'
|
|
31
|
+
# require_relative 'baseball/mlb/player'
|
|
32
|
+
# require_relative 'baseball/mlb/quarter'
|
|
33
|
+
|
|
34
|
+
# require_relative 'baseball/ncaamb'
|
|
35
|
+
# require_relative 'baseball/ncaamb/season'
|
|
36
|
+
# require_relative 'baseball/ncaamb/schedule'
|
|
37
|
+
# require_relative 'baseball/ncaamb/tournament'
|
|
38
|
+
# require_relative 'baseball/ncaamb/round'
|
|
39
|
+
# require_relative 'baseball/ncaamb/bracket'
|
|
40
|
+
# require_relative 'baseball/ncaamb/game'
|
|
41
|
+
# require_relative 'baseball/ncaamb/half'
|
|
42
|
+
# require_relative 'baseball/ncaamb/hierarchy'
|
|
43
|
+
# require_relative 'baseball/ncaamb/division'
|
|
44
|
+
# require_relative 'baseball/ncaamb/conference'
|
|
45
|
+
# require_relative 'baseball/ncaamb/team'
|
|
46
|
+
# require_relative 'baseball/ncaamb/player'
|
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
module Sportradar
|
|
2
|
+
module Api
|
|
3
|
+
module Basketball
|
|
4
|
+
class Game < Data
|
|
5
|
+
attr_accessor :response, :id, :title, :home_id, :away_id, :score, :status, :coverage, :scheduled, :venue, :broadcast, :clock, :duration, :attendance, :team_stats, :player_stats, :changes, :media_timeouts
|
|
6
|
+
|
|
7
|
+
attr_accessor :period
|
|
8
|
+
@all_hash = {}
|
|
9
|
+
# def self.new(data, **opts)
|
|
10
|
+
# existing = @all_hash[data['id']]
|
|
11
|
+
# if existing
|
|
12
|
+
# existing.update(data, **opts)
|
|
13
|
+
# existing
|
|
14
|
+
# else
|
|
15
|
+
# @all_hash[data['id']] = super
|
|
16
|
+
# end
|
|
17
|
+
# end
|
|
18
|
+
# def self.all
|
|
19
|
+
# @all_hash.values
|
|
20
|
+
# end
|
|
21
|
+
|
|
22
|
+
def initialize(data, **opts)
|
|
23
|
+
@response = data
|
|
24
|
+
@api = opts[:api]
|
|
25
|
+
# @season = opts[:season]
|
|
26
|
+
@updates = {}
|
|
27
|
+
@changes = {}
|
|
28
|
+
|
|
29
|
+
@score = {}
|
|
30
|
+
@team_stats = {}
|
|
31
|
+
@player_stats = {}
|
|
32
|
+
@scoring_raw = Scoring.new(data, game: self)
|
|
33
|
+
@teams_hash = {}
|
|
34
|
+
@periods_hash = {}
|
|
35
|
+
@home_points = nil
|
|
36
|
+
@away_points = nil
|
|
37
|
+
@home_id = nil
|
|
38
|
+
@away_id = nil
|
|
39
|
+
|
|
40
|
+
@id = data['id']
|
|
41
|
+
|
|
42
|
+
update(data, **opts)
|
|
43
|
+
end
|
|
44
|
+
def timeouts
|
|
45
|
+
{}
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def tied?
|
|
49
|
+
@score[away_id].to_i == @score[home_id].to_i
|
|
50
|
+
end
|
|
51
|
+
def points(team_id)
|
|
52
|
+
team_id.is_a?(Symbol) ? @score[@team_ids[team_id]].to_i : @score[team_id].to_i
|
|
53
|
+
end
|
|
54
|
+
def stats(team_id)
|
|
55
|
+
team_id.is_a?(Symbol) ? @team_stats[@team_ids[team_id]].to_i : @team_stats[team_id].to_i
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def scoring
|
|
59
|
+
@scoring_raw.scores
|
|
60
|
+
end
|
|
61
|
+
def update_score(score)
|
|
62
|
+
@score.merge!(score)
|
|
63
|
+
end
|
|
64
|
+
def update_stats(team, stats)
|
|
65
|
+
@team_stats.merge!(team.id => stats.merge!(team: team))
|
|
66
|
+
end
|
|
67
|
+
def update_player_stats(player, stats)
|
|
68
|
+
@player_stats.merge!(player.id => stats.merge!(player: player))
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def parse_score(data)
|
|
72
|
+
update_score(data.dig('home', 'id') => data.dig('home', 'points').to_i)
|
|
73
|
+
update_score(data.dig('away', 'id') => data.dig('away', 'points').to_i)
|
|
74
|
+
end
|
|
75
|
+
def clock_seconds
|
|
76
|
+
return unless @clock
|
|
77
|
+
m,s = @clock.split(':')
|
|
78
|
+
m.to_i * 60 + s.to_i
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def update(data, source: nil, **opts)
|
|
82
|
+
# via pbp
|
|
83
|
+
@status = data['status'] if data['status']
|
|
84
|
+
@coverage = data['coverage'] if data['coverage']
|
|
85
|
+
@home_id = data['home_team'] || data.dig('home', 'id') if data['home_team'] || data.dig('home', 'id')
|
|
86
|
+
@away_id = data['away_team'] || data.dig('away', 'id') if data['away_team'] || data.dig('away', 'id')
|
|
87
|
+
@home_points = data['home_points'].to_i if data['home_points']
|
|
88
|
+
@away_points = data['away_points'].to_i if data['away_points']
|
|
89
|
+
|
|
90
|
+
@scheduled = Time.parse(data["scheduled"]) if data["scheduled"]
|
|
91
|
+
@venue = Venue.new(data['venue']) if data['venue']
|
|
92
|
+
@broadcast = Broadcast.new(data['broadcast']) if !data['broadcast'].to_h.empty?
|
|
93
|
+
@home = team_class.new(data['home'], api: api, game: self) if data['home']
|
|
94
|
+
@away = team_class.new(data['away'], api: api, game: self) if data['away']
|
|
95
|
+
@title = data['title'] || @title || (home && away && "#{home.full_name} vs #{away.full_name}")
|
|
96
|
+
|
|
97
|
+
@duration = data['duration'] if data['duration']
|
|
98
|
+
@clock = data['clock'] if data['clock']
|
|
99
|
+
@attendance = data['attendance'] if data['attendance']
|
|
100
|
+
@lead_changes = data['lead_changes'] if data['lead_changes']
|
|
101
|
+
@times_tied = data['times_tied'] if data['times_tied']
|
|
102
|
+
|
|
103
|
+
@team_ids = { home: @home_id, away: @away_id}
|
|
104
|
+
|
|
105
|
+
update_score(@home_id => @home_points.to_i) if @home_points
|
|
106
|
+
update_score(@away_id => @away_points.to_i) if @away_points
|
|
107
|
+
parse_score(data['scoring']) if data['scoring']
|
|
108
|
+
@scoring_raw.update(data, source: source)
|
|
109
|
+
|
|
110
|
+
create_data(@teams_hash, data['team'], klass: team_class, api: api, game: self) if data['team']
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def home
|
|
114
|
+
@teams_hash[@home_id] || @home
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def away
|
|
118
|
+
@teams_hash[@away_id] || @away
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def leading_team_id
|
|
122
|
+
return nil if score.values.uniq.size == 1
|
|
123
|
+
score.max_by(&:last).first
|
|
124
|
+
end
|
|
125
|
+
def leading_team
|
|
126
|
+
@teams_hash[leading_team_id] || (@away_id == leading_team_id && away) || (@home_id == leading_team_id && home)
|
|
127
|
+
end
|
|
128
|
+
def team(team_id)
|
|
129
|
+
@teams_hash[team_id]
|
|
130
|
+
end
|
|
131
|
+
def assign_home(team)
|
|
132
|
+
@home_id = team.id
|
|
133
|
+
@teams_hash[team.id] = team
|
|
134
|
+
end
|
|
135
|
+
def assign_away(team)
|
|
136
|
+
@away_id = team.id
|
|
137
|
+
@teams_hash[team.id] = team
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def box
|
|
141
|
+
@box ||= get_box
|
|
142
|
+
end
|
|
143
|
+
def pbp
|
|
144
|
+
if !future? && periods.empty?
|
|
145
|
+
get_pbp
|
|
146
|
+
end
|
|
147
|
+
@pbp ||= periods
|
|
148
|
+
end
|
|
149
|
+
def plays
|
|
150
|
+
periods.flat_map(&:plays)
|
|
151
|
+
end
|
|
152
|
+
def plays_by_type(play_type, *types)
|
|
153
|
+
if types.empty?
|
|
154
|
+
plays.grep(Play.subclass(play_type.delete('_')))
|
|
155
|
+
else
|
|
156
|
+
play_classes = [play_type, *types].map { |type| Play.subclass(type.delete('_')) }
|
|
157
|
+
plays.select { |play| play_classes.any? { |klass| play.kind_of?(klass) } }
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
def summary
|
|
161
|
+
@summary ||= get_summary
|
|
162
|
+
end
|
|
163
|
+
alias :events :plays
|
|
164
|
+
|
|
165
|
+
def periods
|
|
166
|
+
@periods_hash.values
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
# tracking updates
|
|
171
|
+
def remember(key, object)
|
|
172
|
+
@updates[key] = object&.dup
|
|
173
|
+
end
|
|
174
|
+
def not_updated?(key, object)
|
|
175
|
+
@updates[key] == object
|
|
176
|
+
end
|
|
177
|
+
def changed?(key)
|
|
178
|
+
@changes[key]
|
|
179
|
+
end
|
|
180
|
+
def check_newness(key, new_object)
|
|
181
|
+
@changes[key] = !not_updated?(key, new_object)
|
|
182
|
+
remember(key, new_object)
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
# url paths
|
|
186
|
+
def path_base
|
|
187
|
+
"games/#{ id }"
|
|
188
|
+
end
|
|
189
|
+
def path_box
|
|
190
|
+
"#{ path_base }/boxscore"
|
|
191
|
+
end
|
|
192
|
+
def path_pbp
|
|
193
|
+
"#{ path_base }/pbp"
|
|
194
|
+
end
|
|
195
|
+
def path_summary
|
|
196
|
+
"#{ path_base }/summary"
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
# status helpers
|
|
200
|
+
def realtime_state
|
|
201
|
+
if future?
|
|
202
|
+
'Scheduled'
|
|
203
|
+
elsif finished?
|
|
204
|
+
'Final'
|
|
205
|
+
elsif postponed?
|
|
206
|
+
'Postponed'
|
|
207
|
+
# elsif halftime?
|
|
208
|
+
# 'Halftime'
|
|
209
|
+
else
|
|
210
|
+
clock_display
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
def clock_display
|
|
215
|
+
if clock && period
|
|
216
|
+
"#{clock} #{period_display}"
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
def period_display
|
|
220
|
+
if period > 5
|
|
221
|
+
"#{period - 4}OT"
|
|
222
|
+
elsif period == 5
|
|
223
|
+
'OT'
|
|
224
|
+
else
|
|
225
|
+
"#{period}Q"
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
def postponed?
|
|
230
|
+
'postponed' == status
|
|
231
|
+
end
|
|
232
|
+
def unnecessary?
|
|
233
|
+
'unnecessary' == status
|
|
234
|
+
end
|
|
235
|
+
def cancelled?
|
|
236
|
+
['unnecessary', 'postponed'].include? status
|
|
237
|
+
end
|
|
238
|
+
def future?
|
|
239
|
+
['scheduled', 'delayed', 'created', 'time-tbd', 'if-necessary'].include? status
|
|
240
|
+
end
|
|
241
|
+
def started?
|
|
242
|
+
['inprogress', 'halftime', 'delayed'].include? status
|
|
243
|
+
end
|
|
244
|
+
def finished?
|
|
245
|
+
['complete', 'closed'].include? status
|
|
246
|
+
end
|
|
247
|
+
def completed?
|
|
248
|
+
'complete' == status
|
|
249
|
+
end
|
|
250
|
+
def closed?
|
|
251
|
+
'closed' == status
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
# data retrieval
|
|
255
|
+
|
|
256
|
+
def get_box
|
|
257
|
+
data = api.get_data(path_box)
|
|
258
|
+
ingest_box(data)
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
def ingest_box(data)
|
|
262
|
+
update(data, source: :box)
|
|
263
|
+
@period = data.delete(period_name).to_i
|
|
264
|
+
check_newness(:box, @clock)
|
|
265
|
+
data
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
def queue_pbp
|
|
269
|
+
url, headers, options, timeout = api.get_request_info(path_pbp)
|
|
270
|
+
{url: url, headers: headers, params: options, timeout: timeout, callback: method(:ingest_pbp)}
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
def get_pbp
|
|
274
|
+
data = api.get_data(path_pbp)
|
|
275
|
+
ingest_pbp(data)
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
def ingest_pbp(data)
|
|
279
|
+
period_name = 'periods'
|
|
280
|
+
update(data, source: :pbp)
|
|
281
|
+
period_data = if data[period_name] && !data[period_name].empty?
|
|
282
|
+
@period = data[period_name].last['sequence'].to_i
|
|
283
|
+
pers = data[period_name]
|
|
284
|
+
pers.is_a?(Array) && (pers.size == 1) ? pers[0] : pers
|
|
285
|
+
else
|
|
286
|
+
@period = nil
|
|
287
|
+
[]
|
|
288
|
+
end
|
|
289
|
+
if data['overtime']
|
|
290
|
+
extra_periods = data['overtime'].is_a?(Hash) ? [data['overtime']] : data['overtime']
|
|
291
|
+
period_data.concat(extra_periods)
|
|
292
|
+
end
|
|
293
|
+
set_pbp(period_data)
|
|
294
|
+
@pbp = @periods_hash.values
|
|
295
|
+
check_newness(:pbp, plays.last&.updated)
|
|
296
|
+
check_newness(:score, @score)
|
|
297
|
+
data
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
def get_summary
|
|
301
|
+
data = api.get_data(path_summary)
|
|
302
|
+
ingest_summary(data)
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
def queue_summary
|
|
306
|
+
url, headers, options, timeout = api.get_request_info(path_summary)
|
|
307
|
+
{url: url, headers: headers, params: options, timeout: timeout, callback: method(:ingest_summary)}
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
def ingest_summary(data)
|
|
311
|
+
update(data, source: :summary)
|
|
312
|
+
@period = data.delete(period_name).to_i
|
|
313
|
+
check_newness(:box, @clock)
|
|
314
|
+
check_newness(:score, @score)
|
|
315
|
+
data
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
def set_pbp(data)
|
|
319
|
+
create_data(@periods_hash, data, klass: period_class, api: api, game: self)
|
|
320
|
+
@plays = nil # to clear empty array empty
|
|
321
|
+
@periods_hash
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
# @abstract Subclass is expected to implement #period_class
|
|
325
|
+
# @!method period_class
|
|
326
|
+
# The class used for game periods
|
|
327
|
+
|
|
328
|
+
# @abstract Subclass is expected to implement #period_name
|
|
329
|
+
# @!method period_name
|
|
330
|
+
# The string name used for game periods
|
|
331
|
+
|
|
332
|
+
# @abstract Subclass is expected to implement #api
|
|
333
|
+
# @!method api
|
|
334
|
+
# The base for the requests needed for a subclass
|
|
335
|
+
|
|
336
|
+
end
|
|
337
|
+
end
|
|
338
|
+
end
|
|
339
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
module Sportradar
|
|
2
|
+
module Api
|
|
3
|
+
module Basketball
|
|
4
|
+
class Injury < Data
|
|
5
|
+
attr_accessor :response, :id, :comment, :descripton, :status, :start_date, :update_date
|
|
6
|
+
|
|
7
|
+
def initialize(data, **opts)
|
|
8
|
+
@response = data
|
|
9
|
+
update(data, **opts)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def update(data, **opts)
|
|
13
|
+
@id = data.last&.dig('id')
|
|
14
|
+
@comment = data.last&.dig('comment')
|
|
15
|
+
@descripton = data.last&.dig('desc')
|
|
16
|
+
@status = data.last&.dig('status')
|
|
17
|
+
@start_date = data.last&.dig('start_date')
|
|
18
|
+
@update_date = data.last&.dig('update_date')
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def out?
|
|
22
|
+
@status == 'Out'
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private def sample_data
|
|
26
|
+
{
|
|
27
|
+
"injury" => {
|
|
28
|
+
"id" => "069a9d3f-036e-4dab-9b49-d2e75082230e",
|
|
29
|
+
"comment" => "Paul will have surgery to repair torn ligaments in his left thumb and is expected to be out for six-to-eight weeks to recover, according to a report from ESPN.com.",
|
|
30
|
+
"desc" => "Thumb",
|
|
31
|
+
"status" => "Out",
|
|
32
|
+
"start_date" => "2017-01-17",
|
|
33
|
+
"update_date"=> "2017-01-17"
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module Sportradar
|
|
2
|
+
module Api
|
|
3
|
+
module Basketball
|
|
4
|
+
class Nba
|
|
5
|
+
class Conference < Data
|
|
6
|
+
attr_accessor :response, :id, :name, :alias
|
|
7
|
+
|
|
8
|
+
def initialize(data, **opts)
|
|
9
|
+
@response = data
|
|
10
|
+
@api = opts[:api]
|
|
11
|
+
|
|
12
|
+
@id = data["id"]
|
|
13
|
+
@name = data["name"]
|
|
14
|
+
@alias = data["alias"]
|
|
15
|
+
@divisions_hash = create_data({}, data["divisions"], klass: Division, conference: self, api: @api) # if response["division"]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def divisions
|
|
19
|
+
@divisions_hash.values
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module Sportradar
|
|
2
|
+
module Api
|
|
3
|
+
module Basketball
|
|
4
|
+
class Nba
|
|
5
|
+
class Division < Data
|
|
6
|
+
attr_accessor :response, :id, :name, :alias
|
|
7
|
+
|
|
8
|
+
def initialize(data, **opts)
|
|
9
|
+
@response = data
|
|
10
|
+
@api = opts[:api]
|
|
11
|
+
|
|
12
|
+
@id = data["id"]
|
|
13
|
+
@name = data["name"]
|
|
14
|
+
@alias = data["alias"]
|
|
15
|
+
@assigned_teams = nil
|
|
16
|
+
@teams_hash = create_data({}, data["teams"], klass: Team, division: self, api: @api) # if response["team"]
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def teams
|
|
20
|
+
@assigned_teams || @teams_hash.values
|
|
21
|
+
end
|
|
22
|
+
def teams=(array)
|
|
23
|
+
@assigned_teams = array
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|