mlb_gameday 0.0.11 → 0.1.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 +4 -4
- data/.rubocop.yml +19 -0
- data/Rakefile +6 -1
- data/lib/mlb_gameday.rb +139 -145
- data/lib/mlb_gameday/batter.rb +2 -2
- data/lib/mlb_gameday/division.rb +9 -18
- data/lib/mlb_gameday/game.rb +216 -225
- data/lib/mlb_gameday/league.rb +11 -17
- data/lib/mlb_gameday/pitcher.rb +33 -42
- data/lib/mlb_gameday/player.rb +17 -14
- data/lib/mlb_gameday/team.rb +17 -37
- data/lib/mlb_gameday/version.rb +1 -1
- data/mlb_gameday.gemspec +18 -16
- data/resources/data.yml +66 -0
- data/spec/basic_spec.rb +38 -38
- data/spec/game_spec.rb +44 -44
- data/spec/spec_helper.rb +0 -3
- metadata +39 -24
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2ce56fe941c7aa4f12153197768ee98e687f92b6
|
4
|
+
data.tar.gz: 44b99fa141ae3ef58ba69789265546d3bc7dc7d9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f19a6879750da08a088288a2a940b5cb30fe5b7cfaa8fe0128760c993a4d2478f1ab3ef35ff3e015afcf79915f278417a2cfaa650a4a83c69fb4c0834b00d9f9
|
7
|
+
data.tar.gz: d7e4c7d2068db64398847a2e61823bfc22c344a584b07646a113e4e13c5fdd2c836acc6e7a78c1302ad77b2d3f0dab9c7bee03b13d9f68956388ff88040496aa
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
AllCops:
|
2
|
+
Include:
|
3
|
+
- Rakefile
|
4
|
+
- Gemfile
|
5
|
+
|
6
|
+
Metrics/AbcSize:
|
7
|
+
Enabled: false
|
8
|
+
|
9
|
+
Metrics/ClassLength:
|
10
|
+
Max: 100
|
11
|
+
|
12
|
+
Metrics/CyclomaticComplexity:
|
13
|
+
Enabled: false
|
14
|
+
|
15
|
+
Metrics/MethodLength:
|
16
|
+
Max: 15
|
17
|
+
|
18
|
+
Style/Documentation:
|
19
|
+
Enabled: false
|
data/Rakefile
CHANGED
data/lib/mlb_gameday.rb
CHANGED
@@ -3,157 +3,151 @@ require 'nokogiri'
|
|
3
3
|
require 'open-uri'
|
4
4
|
require 'yaml'
|
5
5
|
|
6
|
-
%w
|
7
|
-
|
6
|
+
%w(version league division team game player pitcher batter).each do |file|
|
7
|
+
require "mlb_gameday/#{file}"
|
8
8
|
end
|
9
9
|
|
10
10
|
module MLBGameday
|
11
|
-
|
12
|
-
|
13
|
-
class API
|
14
|
-
def initialize
|
15
|
-
# File File File File File File File File File File File File File File File
|
16
|
-
@leagues = YAML.load File.open(File.join(File.dirname(File.expand_path(__FILE__)), '../resources/data.yml'))
|
17
|
-
end
|
18
|
-
|
19
|
-
def leagues
|
20
|
-
@leagues
|
21
|
-
end
|
22
|
-
|
23
|
-
def league(name)
|
24
|
-
return name if name.is_a? MLBGameday::League
|
25
|
-
|
26
|
-
@leagues[name]
|
27
|
-
end
|
28
|
-
|
29
|
-
def team(name)
|
30
|
-
return name if name.is_a? MLBGameday::Team
|
31
|
-
|
32
|
-
teams.each do |team|
|
33
|
-
return team if team.names.include? name.downcase
|
34
|
-
end
|
35
|
-
|
36
|
-
nil
|
37
|
-
end
|
38
|
-
|
39
|
-
def teams
|
40
|
-
@teams ||= divisions.map(&:teams).map(&:values).flatten
|
41
|
-
end
|
42
|
-
|
43
|
-
def division(league, name)
|
44
|
-
@leagues[league][name]
|
45
|
-
end
|
46
|
-
|
47
|
-
def divisions
|
48
|
-
@divisions ||= @leagues[:AL].divisions.values + @leagues[:NL].divisions.values
|
49
|
-
end
|
50
|
-
|
51
|
-
def pitcher(id)
|
52
|
-
return nil if id.empty?
|
11
|
+
API_URL = 'http://gd2.mlb.com/components/game/mlb'
|
53
12
|
|
54
|
-
|
55
|
-
|
13
|
+
BATTER = '/year_%{year}/batters/%{id}'
|
14
|
+
PITCHER = '/year_%{year}/pitchers/%{id}'
|
15
|
+
BOXSCORE = '/year_%{year}/month_%{month}/day_%{day}/gid_%{gid}/boxscore'
|
16
|
+
GAMECENTER = '/year_%{year}/month_%{month}/day_%{day}/gid_%{gid}/gamecenter'
|
17
|
+
LINESCORE = '/year_%{year}/month_%{month}/day_%{day}/gid_%{gid}/linescore'
|
18
|
+
SCOREBOARD = '/year_%Y/month_%m/day_%d/miniscoreboard'
|
56
19
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
self,
|
66
|
-
gid,
|
67
|
-
gamecenter: fetch_gamecenter_xml(gid),
|
68
|
-
linescore: fetch_linescore_xml(gid),
|
69
|
-
boxscore: fetch_boxscore_xml(gid)
|
70
|
-
)
|
71
|
-
end
|
72
|
-
|
73
|
-
def find_games(team: nil, date: nil)
|
74
|
-
date = Date.today if date.nil?
|
75
|
-
|
76
|
-
doc = fetch_scoreboard_xml(date)
|
77
|
-
|
78
|
-
if team.nil?
|
79
|
-
doc.xpath("//games/game").map do |game|
|
80
|
-
gid = game.xpath("@gameday_link").first.value
|
81
|
-
|
82
|
-
MLBGameday::Game.new(
|
83
|
-
self,
|
84
|
-
gid,
|
85
|
-
gamecenter: fetch_gamecenter_xml(gid),
|
86
|
-
linescore: fetch_linescore_xml(gid),
|
87
|
-
boxscore: fetch_boxscore_xml(gid)
|
88
|
-
)
|
89
|
-
end
|
90
|
-
else
|
91
|
-
team = team(team)
|
92
|
-
|
93
|
-
doc.xpath("//games/game").map do |game|
|
94
|
-
if [game.xpath("@home_name_abbrev").first.value, game.xpath("@away_name_abbrev").first.value].include? team.code
|
95
|
-
gid = game.xpath("@gameday_link").first.value
|
96
|
-
|
97
|
-
MLBGameday::Game.new(
|
98
|
-
self,
|
99
|
-
gid,
|
100
|
-
gamecenter: fetch_gamecenter_xml(gid),
|
101
|
-
linescore: fetch_linescore_xml(gid),
|
102
|
-
boxscore: fetch_boxscore_xml(gid),
|
103
|
-
)
|
104
|
-
end
|
105
|
-
end.compact!
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
def fetch_scoreboard_xml(date)
|
110
|
-
Nokogiri::XML(open(API_URL + date.strftime("/year_%Y/month_%m/day_%d/miniscoreboard.xml")))
|
111
|
-
end
|
20
|
+
class API
|
21
|
+
attr_reader :leagues
|
22
|
+
|
23
|
+
def initialize
|
24
|
+
@leagues = YAML.load File.open File.join(
|
25
|
+
File.dirname(File.expand_path __FILE__), '../resources/data.yml'
|
26
|
+
)
|
27
|
+
end
|
112
28
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
Nokogiri::XML(open(API_URL + "/year_#{ year }/month_#{ month }/day_#{ day }/gid_#{ gid }/linescore.xml"))
|
117
|
-
end
|
29
|
+
def league(name)
|
30
|
+
return name if name.is_a? MLBGameday::League
|
118
31
|
|
119
|
-
|
120
|
-
|
32
|
+
@leagues[name]
|
33
|
+
end
|
34
|
+
|
35
|
+
def team(name)
|
36
|
+
return name if name.is_a? MLBGameday::Team
|
121
37
|
|
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
|
-
|
38
|
+
teams.each do |team|
|
39
|
+
return team if team.names.include? name.downcase
|
40
|
+
end
|
41
|
+
|
42
|
+
nil
|
43
|
+
end
|
44
|
+
|
45
|
+
def teams
|
46
|
+
@teams ||= divisions.map(&:teams).map(&:values).flatten
|
47
|
+
end
|
48
|
+
|
49
|
+
def division(league, name)
|
50
|
+
@leagues[league][name]
|
51
|
+
end
|
52
|
+
|
53
|
+
def divisions
|
54
|
+
@divisions ||= @leagues[:AL].divisions.values +
|
55
|
+
@leagues[:NL].divisions.values
|
56
|
+
end
|
57
|
+
|
58
|
+
def pitcher(id)
|
59
|
+
return nil if id.empty?
|
60
|
+
|
61
|
+
MLBGameday::Pitcher.new id: id, xml: pitcher_xml(id)
|
62
|
+
end
|
63
|
+
|
64
|
+
def batter(id)
|
65
|
+
return nil if id.empty?
|
66
|
+
|
67
|
+
MLBGameday::Batter.new id: id, xml: batter_xml(id)
|
68
|
+
end
|
69
|
+
|
70
|
+
def game(gid)
|
71
|
+
MLBGameday::Game.new(
|
72
|
+
self,
|
73
|
+
gid,
|
74
|
+
gamecenter: gamecenter_xml(gid),
|
75
|
+
linescore: linescore_xml(gid),
|
76
|
+
boxscore: boxscore_xml(gid)
|
77
|
+
)
|
78
|
+
end
|
79
|
+
|
80
|
+
def find_games(team: nil, date: nil)
|
81
|
+
doc = scoreboard_xml(date || Date.today)
|
82
|
+
|
83
|
+
if team
|
84
|
+
code = team(team).code
|
85
|
+
|
86
|
+
doc.xpath('//games/game').map do |game|
|
87
|
+
next unless [game.xpath('@home_name_abbrev').text,
|
88
|
+
game.xpath('@away_name_abbrev').text].include? code
|
89
|
+
|
90
|
+
game game.xpath('@gameday_link').text
|
91
|
+
end.compact!
|
92
|
+
else
|
93
|
+
doc.xpath('//games/game').map do |game|
|
94
|
+
game game.xpath('@gameday_link').to_s
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def scoreboard_xml(date)
|
100
|
+
fetch_xml date.strftime SCOREBOARD
|
101
|
+
end
|
102
|
+
|
103
|
+
def linescore_xml(gid)
|
104
|
+
year, month, day, _ = gid.split '_'
|
105
|
+
|
106
|
+
fetch_xml LINESCORE, year: year, month: month, day: day, gid: gid
|
107
|
+
end
|
108
|
+
|
109
|
+
def boxscore_xml(gid)
|
110
|
+
year, month, day, _ = gid.split '_'
|
111
|
+
|
112
|
+
fetch_xml BOXSCORE, year: year, month: month, day: day, gid: gid
|
113
|
+
rescue
|
114
|
+
nil
|
115
|
+
end
|
116
|
+
|
117
|
+
def gamecenter_xml(gid)
|
118
|
+
year, month, day, _ = gid.split '_'
|
119
|
+
|
120
|
+
fetch_xml GAMECENTER, year: year, month: month, day: day, gid: gid
|
121
|
+
rescue
|
122
|
+
nil
|
123
|
+
end
|
124
|
+
|
125
|
+
def batter_xml(id, year: nil)
|
126
|
+
# We only really want one piece of data from this file...
|
127
|
+
year_data = fetch_xml BATTER, id: id, year: (year || Date.today.year)
|
128
|
+
|
129
|
+
gid = year_data.xpath('//batting/@game_id').text
|
130
|
+
year, month, day, _ = gid.split '/'
|
131
|
+
|
132
|
+
fetch_xml "/year_#{year}/month_#{month}/day_#{day}/" \
|
133
|
+
"gid_#{gid.gsub(/[^a-z0-9]/, '_')}/batters/#{id}"
|
134
|
+
end
|
135
|
+
|
136
|
+
def pitcher_xml(id, year: nil)
|
137
|
+
# We only really want one piece of data from this file...
|
138
|
+
year_data = fetch_xml PITCHER, id: id, year: (year || Date.today.year)
|
139
|
+
|
140
|
+
gid = year_data.xpath('//pitching/@game_id').text
|
141
|
+
year, month, day, _ = gid.split '/'
|
142
|
+
|
143
|
+
fetch_xml "/year_#{year}/month_#{month}/day_#{day}/" \
|
144
|
+
"gid_#{gid.gsub(/[^a-z0-9]/, '_')}/pitchers/#{id}"
|
145
|
+
end
|
146
|
+
|
147
|
+
protected
|
148
|
+
|
149
|
+
def fetch_xml(path, interpolations = {})
|
150
|
+
Nokogiri::XML open format(API_URL + path + '.xml', interpolations)
|
151
|
+
end
|
152
|
+
end
|
159
153
|
end
|
data/lib/mlb_gameday/batter.rb
CHANGED
data/lib/mlb_gameday/division.rb
CHANGED
@@ -1,21 +1,12 @@
|
|
1
1
|
module MLBGameday
|
2
|
-
|
3
|
-
|
4
|
-
@league = league
|
5
|
-
@name = name
|
6
|
-
@teams = teams
|
7
|
-
end
|
2
|
+
class Division
|
3
|
+
attr_reader :league, :name, :teams
|
8
4
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
def teams
|
18
|
-
@teams
|
19
|
-
end
|
20
|
-
end
|
5
|
+
def initialize(id:, league:, name:, teams:)
|
6
|
+
@id = id
|
7
|
+
@league = league
|
8
|
+
@name = name
|
9
|
+
@teams = teams
|
10
|
+
end
|
11
|
+
end
|
21
12
|
end
|
data/lib/mlb_gameday/game.rb
CHANGED
@@ -1,227 +1,218 @@
|
|
1
1
|
module MLBGameday
|
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
|
-
def boxscore
|
219
|
-
@boxscore
|
220
|
-
end
|
221
|
-
|
222
|
-
# So we don't get huge printouts
|
223
|
-
def inspect
|
224
|
-
%Q{#<MLBGameday::Game @gid="#{@gid}">}
|
225
|
-
end
|
226
|
-
end
|
2
|
+
# This class is just too long. It might be able to be split up, but it's not
|
3
|
+
# likely to happen any time soon. For now, we'll disable the cop.
|
4
|
+
# rubocop:disable Metrics/ClassLength
|
5
|
+
class Game
|
6
|
+
attr_reader :gid, :home_team, :away_team, :linescore, :gamecenter, :boxscore
|
7
|
+
|
8
|
+
def initialize(api, gid, linescore: nil, gamecenter: nil, boxscore: nil)
|
9
|
+
@api = api
|
10
|
+
@gid = gid
|
11
|
+
|
12
|
+
@linescore = linescore
|
13
|
+
@gamecenter = gamecenter
|
14
|
+
@boxscore = boxscore
|
15
|
+
|
16
|
+
@home_team = @api.team linescore.xpath('//game/@home_name_abbrev').text
|
17
|
+
@away_team = @api.team linescore.xpath('//game/@away_name_abbrev').text
|
18
|
+
end
|
19
|
+
|
20
|
+
def teams
|
21
|
+
[@home_team, @away_team]
|
22
|
+
end
|
23
|
+
|
24
|
+
def venue
|
25
|
+
@linescore.xpath('//game/@venue').text
|
26
|
+
end
|
27
|
+
|
28
|
+
def home_start_time(ampm: true)
|
29
|
+
if ampm
|
30
|
+
[
|
31
|
+
@linescore.xpath('//game/@home_time').text,
|
32
|
+
@linescore.xpath('//game/@home_ampm').text,
|
33
|
+
@linescore.xpath('//game/@home_time_zone').text
|
34
|
+
].join ' '
|
35
|
+
else
|
36
|
+
[
|
37
|
+
@linescore.xpath('//game/@home_time').text,
|
38
|
+
@linescore.xpath('//game/@home_time_zone').text
|
39
|
+
].join ' '
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def away_start_time(ampm: true)
|
44
|
+
if ampm
|
45
|
+
[
|
46
|
+
@linescore.xpath('//game/@away_time').text,
|
47
|
+
@linescore.xpath('//game/@away_ampm').text,
|
48
|
+
@linescore.xpath('//game/@away_time_zone').text
|
49
|
+
].join ' '
|
50
|
+
else
|
51
|
+
[
|
52
|
+
@linescore.xpath('//game/@away_time').text,
|
53
|
+
@linescore.xpath('//game/@away_time_zone').text
|
54
|
+
].join ' '
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Preview, Pre-Game, In Progress, Final
|
59
|
+
def status
|
60
|
+
@status ||= @linescore.xpath('//game/@status').text
|
61
|
+
end
|
62
|
+
|
63
|
+
# [3, Top/Middle/Bottom/End]
|
64
|
+
def inning
|
65
|
+
return [0, '?'] unless @linescore.xpath('//game/@inning')
|
66
|
+
|
67
|
+
[@linescore.xpath('//game/@inning').text.to_i,
|
68
|
+
@linescore.xpath('//game/@inning_state').text]
|
69
|
+
end
|
70
|
+
|
71
|
+
def runners
|
72
|
+
first, second, third = [nil, nil, nil]
|
73
|
+
|
74
|
+
[first, second, third]
|
75
|
+
end
|
76
|
+
|
77
|
+
def over?
|
78
|
+
['Final', 'Game Over', 'Completed Early'].include? status
|
79
|
+
end
|
80
|
+
alias_method :fat_lady_has_sung?, :over?
|
81
|
+
|
82
|
+
def in_progress?
|
83
|
+
status == 'In Progress'
|
84
|
+
end
|
85
|
+
|
86
|
+
def home_record
|
87
|
+
[@linescore.xpath('//game/@home_win'),
|
88
|
+
@linescore.xpath('//game/@home_loss')].map(&:text).map(&:to_i)
|
89
|
+
end
|
90
|
+
|
91
|
+
def away_record
|
92
|
+
[@linescore.xpath('//game/@away_win'),
|
93
|
+
@linescore.xpath('//game/@away_loss')].map(&:text).map(&:to_i)
|
94
|
+
end
|
95
|
+
|
96
|
+
def current_pitcher
|
97
|
+
return nil unless in_progress?
|
98
|
+
|
99
|
+
@api.pitcher @linescore.xpath('//game/current_pitcher/@id').text
|
100
|
+
end
|
101
|
+
|
102
|
+
def opposing_pitcher
|
103
|
+
return nil unless in_progress?
|
104
|
+
|
105
|
+
@api.pitcher @linescore.xpath('//game/opposing_pitcher/@id').text
|
106
|
+
end
|
107
|
+
|
108
|
+
def winning_pitcher
|
109
|
+
return nil unless over?
|
110
|
+
|
111
|
+
@api.pitcher @linescore.xpath('//game/winning_pitcher/@id').text
|
112
|
+
end
|
113
|
+
|
114
|
+
def losing_pitcher
|
115
|
+
return nil unless over?
|
116
|
+
|
117
|
+
@api.pitcher @linescore.xpath('//game/losing_pitcher/@id').text
|
118
|
+
end
|
119
|
+
|
120
|
+
def save_pitcher
|
121
|
+
return nil unless over?
|
122
|
+
|
123
|
+
@api.pitcher @linescore.xpath('//game/save_pitcher/@id').text
|
124
|
+
end
|
125
|
+
|
126
|
+
def away_starting_pitcher
|
127
|
+
@linescore.xpath('//game/away_probable_pitcher/@id').text
|
128
|
+
end
|
129
|
+
|
130
|
+
def home_starting_pitcher
|
131
|
+
@linescore.xpath('//game/home_probable_pitcher/@id').text
|
132
|
+
end
|
133
|
+
|
134
|
+
def score
|
135
|
+
return [0, 0] unless in_progress? || over?
|
136
|
+
|
137
|
+
[@linescore.xpath('//game/@home_team_runs').text,
|
138
|
+
@linescore.xpath('//game/@away_team_runs').text].map(&:to_i)
|
139
|
+
end
|
140
|
+
|
141
|
+
def home_pitcher
|
142
|
+
# Spring training games can end in ties, in which case there's
|
143
|
+
# really no pitching data. This should really return a null object.
|
144
|
+
case status
|
145
|
+
when 'In Progress'
|
146
|
+
# The xpath changes based on which half of the inning it is
|
147
|
+
if @linescore.xpath('//game/@top_inning').text == 'Y'
|
148
|
+
opposing_pitcher
|
149
|
+
else
|
150
|
+
current_pitcher
|
151
|
+
end
|
152
|
+
when 'Preview', 'Warmup', 'Pre-Game'
|
153
|
+
@api.pitcher home_starting_pitcher
|
154
|
+
when 'Final'
|
155
|
+
home, away = score
|
156
|
+
|
157
|
+
home > away ? winning_pitcher : losing_pitcher
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def away_pitcher
|
162
|
+
# Spring training games can end in ties, in which case there's
|
163
|
+
# really no pitching data. This should really return a null object.
|
164
|
+
case status
|
165
|
+
when 'In Progress'
|
166
|
+
# The xpath changes based on which half of the inning it is
|
167
|
+
if @linescore.xpath('//game/@top_inning').text == 'Y'
|
168
|
+
current_pitcher
|
169
|
+
else
|
170
|
+
opposing_pitcher
|
171
|
+
end
|
172
|
+
when 'Preview', 'Warmup', 'Pre-Game'
|
173
|
+
@api.pitcher away_starting_pitcher
|
174
|
+
when 'Final', 'Game Over'
|
175
|
+
home, away = score
|
176
|
+
|
177
|
+
home > away ? losing_pitcher : winning_pitcher
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
def home_tv
|
182
|
+
return nil unless @gamecenter
|
183
|
+
|
184
|
+
@gamecenter.xpath('//game/broadcast/home/tv').text
|
185
|
+
end
|
186
|
+
|
187
|
+
def away_tv
|
188
|
+
return nil unless @gamecenter
|
189
|
+
|
190
|
+
@gamecenter.xpath('//game/broadcast/away/tv').text
|
191
|
+
end
|
192
|
+
|
193
|
+
def home_radio
|
194
|
+
return nil unless @gamecenter
|
195
|
+
|
196
|
+
@gamecenter.xpath('//game/broadcast/home/radio').text
|
197
|
+
end
|
198
|
+
|
199
|
+
def away_radio
|
200
|
+
return nil unless @gamecenter
|
201
|
+
|
202
|
+
@gamecenter.xpath('//game/broadcast/away/radio').text
|
203
|
+
end
|
204
|
+
|
205
|
+
def free?
|
206
|
+
@linescore.xpath('//game/game_media/media/@free').text == 'ALL'
|
207
|
+
end
|
208
|
+
|
209
|
+
def date
|
210
|
+
@date ||= Chronic.parse @linescore.xpath('//game/@original_date').text
|
211
|
+
end
|
212
|
+
|
213
|
+
# So we don't get huge printouts
|
214
|
+
def inspect
|
215
|
+
%(#<MLBGameday::Game @gid="#{@gid}">)
|
216
|
+
end
|
217
|
+
end
|
227
218
|
end
|