sportradar-api 0.10.13 → 0.10.14
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/.travis.yml +1 -1
- data/Gemfile.lock +1 -1
- data/README.md +1 -1
- data/lib/sportradar/api/baseball/REAME.md +3 -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 +49 -0
- data/lib/sportradar/api/baseball/events/lineup.rb +36 -0
- data/lib/sportradar/api/baseball/events/warming_up.rb +32 -0
- data/lib/sportradar/api/baseball/fielder.rb +26 -0
- data/lib/sportradar/api/baseball/game.rb +385 -0
- data/lib/sportradar/api/baseball/half_inning.rb +54 -0
- data/lib/sportradar/api/baseball/inning.rb +42 -0
- data/lib/sportradar/api/baseball/mlb/division.rb +32 -0
- data/lib/sportradar/api/baseball/mlb/hierarchy.rb +267 -0
- data/lib/sportradar/api/baseball/mlb/league.rb +27 -0
- data/lib/sportradar/api/baseball/mlb.rb +87 -0
- data/lib/sportradar/api/baseball/outcome.rb +87 -0
- data/lib/sportradar/api/baseball/pitch.rb +111 -0
- data/lib/sportradar/api/baseball/player.rb +119 -0
- data/lib/sportradar/api/baseball/record.rb +46 -0
- data/lib/sportradar/api/baseball/runner.rb +30 -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 +50 -0
- data/lib/sportradar/api/baseball.rb +45 -0
- data/lib/sportradar/api/broadcast.rb +13 -0
- data/lib/sportradar/api/data.rb +1 -1
- data/lib/sportradar/api/version.rb +1 -1
- data/lib/sportradar/api.rb +4 -1
- metadata +27 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d93b82036e8ee5eea224b2b56e3a57afb8ed492a
|
|
4
|
+
data.tar.gz: 0abfe21cc3bdb2ebc74f4d7f402e7d329ab3505b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 707e4c95d584e4b847b9a7a555b69f0ce6d95519c4274089cc46f28bb47b3fbf65989ea20bbcb3378a33392d559533711582357aefe739adc32503ee8fbed6ef
|
|
7
|
+
data.tar.gz: bd7ca5ac31b86cbb09f5180c441587c53d1514eb55c965f703eccfcb5606a10391b9344dddf558648e0dd2ba484b9bb420d9bca07a4375e359765a8972c8839b
|
data/.travis.yml
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
|
@@ -23,7 +23,7 @@ Our goal is to incrementally integrate with them. **Contributions are welcome**
|
|
|
23
23
|
| API | Version | Docs | Implemented? | Priority |
|
|
24
24
|
| --- | --- | --- | --- | --- |
|
|
25
25
|
| NFL | 1 | [📚](http://developer.sportradar.us/page/NFL_Official) | ✅ | 👍 |
|
|
26
|
-
| MLB |
|
|
26
|
+
| MLB | 6 | [📚](https://developer.sportradar.com/files/indexBaseball.html#major-league-baseball-api-v6) | ✅ | 👍 |
|
|
27
27
|
| NHL | 3 | [📚](http://developer.sportradar.us/docs/NHL_API) | - | - |
|
|
28
28
|
| NBA | 3 | [📚](http://developer.sportradar.us/docs/NBA_API) | ✅ | - |
|
|
29
29
|
| NCAAMB | 3 | [📚](http://developer.sportradar.us/docs/NCAA_Mens_Basketball) | ✅ | - |
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module Sportradar
|
|
2
|
+
module Api
|
|
3
|
+
module Baseball
|
|
4
|
+
class Error < Data
|
|
5
|
+
attr_accessor :response, :id, :type, :last_name, :first_name, :preferred_name, :jersey_number
|
|
6
|
+
|
|
7
|
+
def initialize(data, **opts)
|
|
8
|
+
@response = data
|
|
9
|
+
# @game = opts[:game]
|
|
10
|
+
|
|
11
|
+
update(data)
|
|
12
|
+
end
|
|
13
|
+
def update(data, **opts)
|
|
14
|
+
@id = data["id"]
|
|
15
|
+
@type = data["type"]
|
|
16
|
+
@last_name = data["last_name"]
|
|
17
|
+
@first_name = data["first_name"]
|
|
18
|
+
@preferred_name = data["preferred_name"]
|
|
19
|
+
@jersey_number = data["jersey_number"]
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
module Sportradar
|
|
2
|
+
module Api
|
|
3
|
+
module Baseball
|
|
4
|
+
class Event < Data
|
|
5
|
+
attr_accessor :response, :id, :at_bat, :lineup, :warming_up, :half_inning
|
|
6
|
+
# alias :type :event_type
|
|
7
|
+
|
|
8
|
+
def initialize(hash, **opts)
|
|
9
|
+
@response = hash
|
|
10
|
+
@half_inning = opts[:half_inning]
|
|
11
|
+
@at_bat = AtBat.new(hash['at_bat'], event: self) if hash['at_bat']
|
|
12
|
+
@lineup = Lineup.new(hash['lineup'], event: self) if hash['lineup']
|
|
13
|
+
@warming_up = WarmingUp.new(hash['warming_up'], event: self) if hash['warming_up']
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def description
|
|
17
|
+
(@at_bat || @lineup || @warming_up)&.description
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# def self.new(data, **opts)
|
|
21
|
+
# klass = subclass(data.keys.first)
|
|
22
|
+
# klass.new(data, **opts)
|
|
23
|
+
# rescue => e
|
|
24
|
+
# binding.pry
|
|
25
|
+
# end
|
|
26
|
+
|
|
27
|
+
# def ==(other)
|
|
28
|
+
# @at_bat == other.at_bat && @warming_up == other.warming_up && @lineup == other.lineup
|
|
29
|
+
# end
|
|
30
|
+
def self.subclass(event_type)
|
|
31
|
+
subclasses[event_type]
|
|
32
|
+
end
|
|
33
|
+
def self.subclasses
|
|
34
|
+
@subclasses ||= {
|
|
35
|
+
'at_bat' => AtBat,
|
|
36
|
+
'lineup' => Lineup,
|
|
37
|
+
'warming_up' => WarmingUp,
|
|
38
|
+
}.freeze
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
module Sportradar
|
|
2
|
+
module Api
|
|
3
|
+
module Baseball
|
|
4
|
+
class Event
|
|
5
|
+
class AtBat < Data
|
|
6
|
+
attr_accessor :response, :id, :event, :hitter_id, :outcome, :description
|
|
7
|
+
|
|
8
|
+
def initialize(data, **opts)
|
|
9
|
+
# @response = data
|
|
10
|
+
@api = opts[:api]
|
|
11
|
+
@event = opts[:event]
|
|
12
|
+
|
|
13
|
+
@id = data["id"]
|
|
14
|
+
@type = data['type']
|
|
15
|
+
|
|
16
|
+
@pitches_hash = {}
|
|
17
|
+
|
|
18
|
+
update(data)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# def ==(other)
|
|
22
|
+
# return false if other.nil?
|
|
23
|
+
# @id == other.id && pitches == other.pitches
|
|
24
|
+
# end
|
|
25
|
+
|
|
26
|
+
def update(data, **opts)
|
|
27
|
+
@description = data['description'] if data['description']
|
|
28
|
+
@hitter_id = data['hitter_id'] if data['hitter_id']
|
|
29
|
+
# this hasn't been checked yet
|
|
30
|
+
# pitch events
|
|
31
|
+
create_data(@pitches_hash, data.dig('events'), klass: Pitch, api: @api, at_bat: self)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def data_key
|
|
35
|
+
'at_bat'
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def over?
|
|
39
|
+
pitches.last.is_ab_over
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def pitches
|
|
43
|
+
@pitches_hash.values
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
module Sportradar
|
|
2
|
+
module Api
|
|
3
|
+
module Baseball
|
|
4
|
+
class Event
|
|
5
|
+
class Lineup < Data
|
|
6
|
+
attr_accessor :response, :id, :hitter_id, :outcome, :description
|
|
7
|
+
|
|
8
|
+
def initialize(data, **opts)
|
|
9
|
+
@response = data
|
|
10
|
+
# @api = opts[:api]
|
|
11
|
+
# @half_inning = opts[:half_inning]
|
|
12
|
+
@event = opts[:event]
|
|
13
|
+
|
|
14
|
+
@id = data["id"]
|
|
15
|
+
# @type = data['type']
|
|
16
|
+
|
|
17
|
+
update(data)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def update(data, **opts)
|
|
21
|
+
@description = data['description'] if data['description']
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def data_key
|
|
25
|
+
'lineup'
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
{"lineup"=>{"description"=>"Brandon Kintzler (P) replaces Matt Belisle (P).", "id"=>"ad7357db-117e-4454-8d44-418ef64aa275", "player_id"=>"e0d89956-1427-4b2f-9025-10330561e464", "order"=>0, "position"=>1, "team_id"=>"aa34e0ed-f342-4ec6-b774-c79b47b60e2d", "last_name"=>"Kintzler", "first_name"=>"Brandon", "preferred_name"=>"Brandon", "jersey_number"=>"27"}}
|
|
30
|
+
{"lineup"=>{"description"=>"Domingo Santana pinch-hitting for Rob Scahill.", "id"=>"4d232302-defe-4ed9-a1fc-4ef44e871138", "player_id"=>"d80a8b1f-aee7-400c-b21f-75e0ac4a32a2", "order"=>9, "position"=>11, "team_id"=>"dcfd5266-00ce-442c-bc09-264cd20cf455", "last_name"=>"Santana", "first_name"=>"Domingo", "preferred_name"=>"Domingo", "jersey_number"=>"16"}}
|
|
31
|
+
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module Sportradar
|
|
2
|
+
module Api
|
|
3
|
+
module Baseball
|
|
4
|
+
class Event
|
|
5
|
+
class WarmingUp < Data
|
|
6
|
+
attr_accessor :response, :id, :hitter_id, :outcome
|
|
7
|
+
|
|
8
|
+
def initialize(data, **opts)
|
|
9
|
+
@response = data
|
|
10
|
+
# @api = opts[:api]
|
|
11
|
+
# @half_inning = opts[:half_inning]
|
|
12
|
+
@event = opts[:event]
|
|
13
|
+
|
|
14
|
+
@id = data["id"]
|
|
15
|
+
@type = data['type']
|
|
16
|
+
|
|
17
|
+
update(data)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def update(data, **opts)
|
|
21
|
+
# parse pitches
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def data_key
|
|
25
|
+
'warming_up'
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module Sportradar
|
|
2
|
+
module Api
|
|
3
|
+
module Baseball
|
|
4
|
+
class Fielder < Data
|
|
5
|
+
attr_accessor :response, :id, :starting_base, :ending_base, :outcome_id, :out
|
|
6
|
+
|
|
7
|
+
def initialize(data, **opts)
|
|
8
|
+
@response = data
|
|
9
|
+
# @game = opts[:game]
|
|
10
|
+
|
|
11
|
+
update(data)
|
|
12
|
+
end
|
|
13
|
+
def update(data, **opts)
|
|
14
|
+
@id = data["id"]
|
|
15
|
+
@type = data["type"]
|
|
16
|
+
@sequence = data["sequence"]
|
|
17
|
+
@last_name = data["last_name"]
|
|
18
|
+
@first_name = data["first_name"]
|
|
19
|
+
@preferred_name = data["preferred_name"]
|
|
20
|
+
@jersey_number = data["jersey_number"]
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
module Sportradar
|
|
2
|
+
module Api
|
|
3
|
+
module Baseball
|
|
4
|
+
class Game < Data
|
|
5
|
+
attr_accessor :response, :id, :title, :home_id, :away_id, :score, :status, :coverage, :scheduled, :venue, :broadcast, :duration, :attendance, :team_stats, :player_stats, :changes
|
|
6
|
+
|
|
7
|
+
attr_reader :inning, :half, :outs, :bases, :pitchers
|
|
8
|
+
attr_reader :outcome, :count
|
|
9
|
+
|
|
10
|
+
def initialize(data, **opts)
|
|
11
|
+
@response = data
|
|
12
|
+
@api = opts[:api]
|
|
13
|
+
# @season = opts[:season]
|
|
14
|
+
@updates = {}
|
|
15
|
+
@changes = {}
|
|
16
|
+
|
|
17
|
+
@score = {}
|
|
18
|
+
@team_stats = {}
|
|
19
|
+
@player_stats = {}
|
|
20
|
+
@scoring_raw = Scoring.new(data, game: self)
|
|
21
|
+
@teams_hash = {}
|
|
22
|
+
@innings_hash = {}
|
|
23
|
+
@home_runs = nil
|
|
24
|
+
@away_runs = nil
|
|
25
|
+
@home_id = nil
|
|
26
|
+
@away_id = nil
|
|
27
|
+
@outcome = Outcome.new(data, game: self)
|
|
28
|
+
@count = {}
|
|
29
|
+
@pitchers = {}
|
|
30
|
+
|
|
31
|
+
@id = data['id']
|
|
32
|
+
|
|
33
|
+
update(data, **opts)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def timeouts
|
|
37
|
+
{}
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def tied?
|
|
41
|
+
@score[away_id].to_i == @score[home_id].to_i
|
|
42
|
+
end
|
|
43
|
+
def runs(team_id)
|
|
44
|
+
summary_stat(team_id, 'runs')
|
|
45
|
+
end
|
|
46
|
+
def hits(team_id)
|
|
47
|
+
@scoring_raw.hits(team_id)
|
|
48
|
+
end
|
|
49
|
+
def errors(team_id)
|
|
50
|
+
@scoring_raw.errors(team_id)
|
|
51
|
+
end
|
|
52
|
+
def team_summary(team_id)
|
|
53
|
+
team_id.is_a?(Symbol) ? @score[@team_ids[team_id]] : @score[team_id]
|
|
54
|
+
end
|
|
55
|
+
def summary_stat(team_id, stat)
|
|
56
|
+
team_summary(team_id)[stat]
|
|
57
|
+
end
|
|
58
|
+
def stats(team_id)
|
|
59
|
+
team_id.is_a?(Symbol) ? @team_stats[@team_ids[team_id]].to_i : @team_stats[team_id].to_i
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def scoring
|
|
63
|
+
@scoring_raw.scores
|
|
64
|
+
end
|
|
65
|
+
def update_score(score)
|
|
66
|
+
@score.merge!(score)
|
|
67
|
+
end
|
|
68
|
+
def update_stats(team, stats)
|
|
69
|
+
@team_stats.merge!(team.id => stats.merge!(team: team))
|
|
70
|
+
end
|
|
71
|
+
def update_player_stats(player, stats)
|
|
72
|
+
@player_stats.merge!(player.id => stats.merge!(player: player))
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def parse_score(data)
|
|
76
|
+
home_id = data.dig('home', 'id')
|
|
77
|
+
away_id = data.dig('away', 'id')
|
|
78
|
+
rhe = {
|
|
79
|
+
'runs' => { home_id => data.dig('home', 'runs'), away_id => data.dig('away', 'runs')},
|
|
80
|
+
'hits' => { home_id => data.dig('home', 'hits'), away_id => data.dig('away', 'hits')},
|
|
81
|
+
'errors' => { home_id => data.dig('home', 'errors'), away_id => data.dig('away', 'errors')},
|
|
82
|
+
}
|
|
83
|
+
@scoring_raw.update(rhe, source: :rhe)
|
|
84
|
+
update_score(home_id => data.dig('home', 'runs'))
|
|
85
|
+
update_score(away_id => data.dig('away', 'runs'))
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def parse_pitchers(data)
|
|
89
|
+
pitchers = {
|
|
90
|
+
'starting' => { home_id => data.dig('home', 'starting_pitcher'), away_id => data.dig('away', 'starting_pitcher')},
|
|
91
|
+
'probable' => { home_id => data.dig('home', 'probable_pitcher'), away_id => data.dig('away', 'probable_pitcher')},
|
|
92
|
+
'current' => { home_id => data.dig('home', 'current_pitcher'), away_id => data.dig('away', 'current_pitcher')},
|
|
93
|
+
}
|
|
94
|
+
@pitchers.merge!(pitchers) do |key, current_val, merge_val|
|
|
95
|
+
current_val.merge(merge_val) { |k, cur, mer| (mer || cur) }
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def update(data, source: nil, **opts)
|
|
100
|
+
# via pbp
|
|
101
|
+
@title = data['title'] if data['title']
|
|
102
|
+
@status = data['status'] if data['status']
|
|
103
|
+
@coverage = data['coverage'] if data['coverage']
|
|
104
|
+
@day_night = data['day_night'] if data['day_night']
|
|
105
|
+
@game_number = data['game_number'] if data['game_number']
|
|
106
|
+
@home_id = data['home_team'] || data.dig('home', 'id') if data['home_team'] || data.dig('home', 'id')
|
|
107
|
+
@away_id = data['away_team'] || data.dig('away', 'id') if data['away_team'] || data.dig('away', 'id')
|
|
108
|
+
# @home_runs = data['home_runs'].to_i if data['home_runs']
|
|
109
|
+
# @away_runs = data['away_runs'].to_i if data['away_runs']
|
|
110
|
+
|
|
111
|
+
@scheduled = Time.parse(data["scheduled"]) if data["scheduled"]
|
|
112
|
+
@venue = Venue.new(data['venue']) if data['venue']
|
|
113
|
+
@broadcast = Broadcast.new(data['broadcast']) if data['broadcast']
|
|
114
|
+
@home = Team.new(data['home'], api: api, game: self) if data['home']
|
|
115
|
+
@away = Team.new(data['away'], api: api, game: self) if data['away']
|
|
116
|
+
|
|
117
|
+
@duration = data['duration'] if data['duration']
|
|
118
|
+
@attendance = data['attendance'] if data['attendance']
|
|
119
|
+
|
|
120
|
+
@team_ids = { home: @home_id, away: @away_id}
|
|
121
|
+
|
|
122
|
+
parse_pitchers(data) if data['home'] && data['away']
|
|
123
|
+
|
|
124
|
+
if data['scoring']
|
|
125
|
+
parse_score(data['scoring'])
|
|
126
|
+
elsif data.dig('home', 'hits')
|
|
127
|
+
parse_score(data)
|
|
128
|
+
end
|
|
129
|
+
@scoring_raw.update(data, source: source)
|
|
130
|
+
if data['outcome']
|
|
131
|
+
@outcome.update(data, source: nil)
|
|
132
|
+
@count.merge!(@outcome.count || {})
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
create_data(@teams_hash, data['team'], klass: Team, api: api, game: self) if data['team']
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
# def update_from_team(id, data)
|
|
139
|
+
# end
|
|
140
|
+
|
|
141
|
+
def extract_count(data) # extract from pbp
|
|
142
|
+
recent_pitches = pitches.last(10)
|
|
143
|
+
last_pitch = recent_pitches.reverse_each.detect(&:count)
|
|
144
|
+
return unless last_pitch
|
|
145
|
+
@count.merge!(last_pitch.count)
|
|
146
|
+
hi = last_pitch.at_bat.event.half_inning
|
|
147
|
+
@count.merge!('inning' => hi.number.to_i, 'inning_half' => hi.half)
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def home
|
|
151
|
+
@teams_hash[@home_id] || @home
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def away
|
|
155
|
+
@teams_hash[@away_id] || @away
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def leading_team_id
|
|
159
|
+
return nil if score.values.uniq.size == 1
|
|
160
|
+
score.max_by(&:last).first
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def leading_team
|
|
164
|
+
@teams_hash[leading_team_id] || (@away_id == leading_team_id && away) || (@home_id == leading_team_id && home)
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def team(team_id)
|
|
168
|
+
@teams_hash[team_id]
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def assign_home(team)
|
|
172
|
+
@home_id = team.id
|
|
173
|
+
@teams_hash[team.id] = team
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
def assign_away(team)
|
|
177
|
+
@away_id = team.id
|
|
178
|
+
@teams_hash[team.id] = team
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def box
|
|
182
|
+
@box ||= get_box
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def pbp
|
|
186
|
+
if !future? && innings.empty?
|
|
187
|
+
get_pbp
|
|
188
|
+
end
|
|
189
|
+
@pbp ||= innings
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
def atbats
|
|
193
|
+
innings.flat_map(&:atbats)
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def events
|
|
197
|
+
innings.flat_map(&:events)
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def at_bats
|
|
201
|
+
events.map(&:at_bat).compact
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
def pitches
|
|
205
|
+
at_bats.flat_map(&:pitches)
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
def summary
|
|
209
|
+
@summary ||= get_summary
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
def innings
|
|
213
|
+
@innings_hash.values
|
|
214
|
+
end
|
|
215
|
+
def half_innings
|
|
216
|
+
innings.flat_map(&:half_innings)
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
# tracking updates
|
|
220
|
+
def remember(key, object)
|
|
221
|
+
@updates[key] = object&.dup
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
def not_updated?(key, object)
|
|
225
|
+
@updates[key] == object
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
def changed?(key)
|
|
229
|
+
@changes[key]
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
def check_newness(key, new_object)
|
|
233
|
+
@changes[key] = !not_updated?(key, new_object)
|
|
234
|
+
remember(key, new_object)
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
# status helpers
|
|
238
|
+
def postponed?
|
|
239
|
+
'postponed' == status
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
def unnecessary?
|
|
243
|
+
'unnecessary' == status
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
def cancelled?
|
|
247
|
+
['unnecessary', 'postponed'].include? status
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
def future?
|
|
251
|
+
['scheduled', 'delayed', 'created', 'time-tbd'].include? status
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
def started?
|
|
255
|
+
['inprogress', 'wdelay', 'delayed'].include? status
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
def finished?
|
|
259
|
+
['complete', 'closed'].include? status
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
def completed?
|
|
263
|
+
'complete' == status
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
def closed?
|
|
267
|
+
'closed' == status
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
# url path helpers
|
|
271
|
+
def path_base
|
|
272
|
+
"games/#{ id }"
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
def path_box
|
|
276
|
+
"#{ path_base }/boxscore"
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
def path_pbp
|
|
280
|
+
"#{ path_base }/pbp"
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
def path_summary
|
|
284
|
+
"#{ path_base }/summary"
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
# data retrieval
|
|
288
|
+
|
|
289
|
+
def get_box
|
|
290
|
+
data = api.get_data(path_box)
|
|
291
|
+
ingest_box(data)
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
def ingest_box(data)
|
|
295
|
+
data = data['game']
|
|
296
|
+
update(data, source: :box)
|
|
297
|
+
check_newness(:box, @clock)
|
|
298
|
+
data
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
def queue_pbp
|
|
302
|
+
url, headers, options, timeout = api.get_request_info(path_pbp)
|
|
303
|
+
{url: url, headers: headers, params: options, timeout: timeout, callback: method(:ingest_pbp)}
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
def get_pbp
|
|
307
|
+
data = api.get_data(path_pbp);
|
|
308
|
+
ingest_pbp(data)
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
def ingest_pbp(data)
|
|
312
|
+
data = data['game']
|
|
313
|
+
update(data, source: :pbp)
|
|
314
|
+
# @pbp = @innings_hash.values
|
|
315
|
+
innings = data['innings'].each { |inning| inning['id'] = "#{data['id']}-#{inning['number']}" }
|
|
316
|
+
create_data(@innings_hash, innings, klass: Inning, api: api, game: self) if data['innings']
|
|
317
|
+
extract_count(data)
|
|
318
|
+
check_newness(:pitches, pitches.last&.id)
|
|
319
|
+
check_newness(:events, events.last&.description)
|
|
320
|
+
check_newness(:score, @score)
|
|
321
|
+
data
|
|
322
|
+
# rescue => e
|
|
323
|
+
# binding.pry
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
def get_summary
|
|
327
|
+
data = api.get_data(path_summary)
|
|
328
|
+
ingest_summary(data)
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
def queue_summary
|
|
332
|
+
url, headers, options, timeout = api.get_request_info(path_summary)
|
|
333
|
+
{url: url, headers: headers, params: options, timeout: timeout, callback: method(:ingest_summary)}
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
def ingest_summary(data)
|
|
337
|
+
data = data['game']
|
|
338
|
+
update(data, source: :summary)
|
|
339
|
+
@inning = data.delete('inning').to_i
|
|
340
|
+
check_newness(:box, @clock)
|
|
341
|
+
check_newness(:score, @score)
|
|
342
|
+
data
|
|
343
|
+
end
|
|
344
|
+
|
|
345
|
+
def set_pbp(data)
|
|
346
|
+
create_data(@innings_hash, data, klass: inning_class, api: api, game: self)
|
|
347
|
+
@innings_hash
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
def api
|
|
351
|
+
@api || Sportradar::Api::Baseball::Mlb.new
|
|
352
|
+
end
|
|
353
|
+
end
|
|
354
|
+
end
|
|
355
|
+
end
|
|
356
|
+
end
|
|
357
|
+
|
|
358
|
+
__END__
|
|
359
|
+
|
|
360
|
+
# mlb = Sportradar::Api::Baseball::Mlb::Hierarchy.new
|
|
361
|
+
# res = mlb.get_schedule;
|
|
362
|
+
# g = mlb.games.first
|
|
363
|
+
# g = Sportradar::Api::Baseball::Game.new('id' => "8cd71519-429f-4461-88a2-8a0e134eb89b")
|
|
364
|
+
g = Sportradar::Api::Baseball::Game.new('id' => "9d0fe41c-4e6b-4433-b376-2d09ed39d184");
|
|
365
|
+
g = Sportradar::Api::Baseball::Game.new('id' => "0ab634d3-ce6c-4a79-be8d-b62b0ee506d5");
|
|
366
|
+
res = g.get_pbp;
|
|
367
|
+
res = g.get_summary;
|
|
368
|
+
res = g.get_box # probably not as useful as summary
|
|
369
|
+
|
|
370
|
+
|
|
371
|
+
mlb = Sportradar::Api::Baseball::Mlb::Hierarchy.new
|
|
372
|
+
res = mlb.get_daily_summary;
|
|
373
|
+
g = mlb.games[8];
|
|
374
|
+
g.count
|
|
375
|
+
g.get_pbp;
|
|
376
|
+
g.count
|
|
377
|
+
|
|
378
|
+
# mlb = Sportradar::Api::Baseball::Mlb::Hierarchy.new;
|
|
379
|
+
# res = mlb.get_daily_summary;
|
|
380
|
+
# g = mlb.games.sort_by(&:scheduled).first;
|
|
381
|
+
g = Sportradar::Api::Baseball::Game.new('id' => "8731b56d-9037-44d1-b890-fa496e94dc10");
|
|
382
|
+
res = g.get_pbp;
|
|
383
|
+
res = g.get_summary;
|
|
384
|
+
g.pitchers
|
|
385
|
+
|