gameday_api 0.5.0 → 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/at_bat.rb +40 -0
- data/lib/batter.rb +101 -0
- data/lib/batting_appearance.rb +55 -0
- data/lib/box_score.rb +197 -0
- data/lib/cache_fetcher.rb +31 -0
- data/lib/coach.rb +16 -0
- data/lib/data_downloader.rb +231 -0
- data/lib/db_importer.rb +205 -0
- data/lib/event.rb +14 -0
- data/lib/event_log.rb +103 -0
- data/lib/game.rb +529 -0
- data/lib/game_status.rb +6 -0
- data/lib/gameday.rb +58 -0
- data/lib/gameday_fetcher.rb +245 -0
- data/lib/gameday_local_fetcher.rb +236 -0
- data/lib/gameday_parser.rb +305 -0
- data/lib/gameday_path_builder.rb +132 -0
- data/lib/gameday_remote_fetcher.rb +292 -0
- data/lib/gameday_url_builder.rb +125 -0
- data/lib/gameday_util.rb +136 -0
- data/lib/hip.rb +18 -0
- data/lib/hitchart.rb +26 -0
- data/lib/import_data.rb +8 -0
- data/lib/inning.rb +52 -0
- data/lib/line_score.rb +38 -0
- data/lib/media.rb +35 -0
- data/lib/media_highlight.rb +33 -0
- data/lib/media_mobile.rb +13 -0
- data/lib/pitch.rb +92 -0
- data/lib/pitcher.rb +131 -0
- data/lib/pitchfx_db_manager.rb +393 -0
- data/lib/pitching_appearance.rb +118 -0
- data/lib/player.rb +145 -0
- data/lib/players.rb +42 -0
- data/lib/roster.rb +61 -0
- data/lib/schedule.rb +53 -0
- data/lib/schedule_game.rb +24 -0
- data/lib/scoreboard.rb +23 -0
- data/lib/team.rb +336 -0
- metadata +42 -3
data/lib/at_bat.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'pitch'
|
2
|
+
|
3
|
+
|
4
|
+
# This class represents a single atbat during a single game
|
5
|
+
class AtBat
|
6
|
+
|
7
|
+
attr_accessor :gid, :inning, :away_team, :home_team
|
8
|
+
attr_accessor :num, :b, :s, :o, :batter_id, :stand, :b_height, :pitcher_id, :p_throws, :des, :event
|
9
|
+
attr_accessor :pitches
|
10
|
+
|
11
|
+
def init(element, gid, inning)
|
12
|
+
@inning = inning
|
13
|
+
@xml_doc = element
|
14
|
+
@gid = gid
|
15
|
+
@num = element.attributes["num"]
|
16
|
+
@b = element.attributes["b"]
|
17
|
+
@s = element.attributes["s"]
|
18
|
+
@o = element.attributes["o"]
|
19
|
+
@batter_id = element.attributes["batter"]
|
20
|
+
@stand = element.attributes["stand"]
|
21
|
+
@b_height = element.attributes["b_height"]
|
22
|
+
@pitcher_id = element.attributes["pitcher"]
|
23
|
+
@p_throws = element.attributes["p_throws"]
|
24
|
+
@des = element.attributes["des"]
|
25
|
+
@event = element.attributes["event"]
|
26
|
+
set_pitches(element)
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
def set_pitches(element)
|
31
|
+
@pitches = []
|
32
|
+
element.elements.each("pitch") do |element|
|
33
|
+
pitch = Pitch.new
|
34
|
+
pitch.init(element)
|
35
|
+
@pitches << pitch
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
end
|
data/lib/batter.rb
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'player'
|
2
|
+
|
3
|
+
# This class represents a single batter whom appeared in an MLB game
|
4
|
+
class Batter < Player
|
5
|
+
|
6
|
+
# attributes read from the batters/(pid).xml file
|
7
|
+
attr_accessor :team_abbrev, :pid, :pos, :first_name, :last_name, :jersey_number
|
8
|
+
attr_accessor :height, :weight, :bats, :throws, :dob
|
9
|
+
attr_accessor :season_stats, :career_stats, :month_stats, :empty_stats
|
10
|
+
attr_accessor :men_on_stats, :risp_stats, :loaded_stats, :vs_lhp_stats, :vs_rhp_stats
|
11
|
+
|
12
|
+
|
13
|
+
def load_from_id(gid, pid)
|
14
|
+
@gid = gid
|
15
|
+
@pid = pid
|
16
|
+
@xml_data = GamedayFetcher.fetch_batter(gid, pid)
|
17
|
+
@xml_doc = REXML::Document.new(@xml_data)
|
18
|
+
@team_abbrev = @xml_doc.root.attributes["team"]
|
19
|
+
@first_name = @xml_doc.root.attributes["first_name"]
|
20
|
+
@last_name = @xml_doc.root.attributes["last_name"]
|
21
|
+
@jersey_number = @xml_doc.root.attributes["jersey_number"]
|
22
|
+
@height = @xml_doc.root.attributes["height"]
|
23
|
+
@weight = @xml_doc.root.attributes["weight"]
|
24
|
+
@bats = @xml_doc.root.attributes["bats"]
|
25
|
+
@throws = @xml_doc.root.attributes["throws"]
|
26
|
+
@dob = @xml_doc.root.attributes['dob']
|
27
|
+
set_batting_stats
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
# Returns an array of all the appearances (Batting) made by this player
|
32
|
+
# for the season specified, in which the player had more than 1 hit.
|
33
|
+
def get_multihit_appearances(year)
|
34
|
+
appearances = get_all_appearances(year)
|
35
|
+
mh_appearances = []
|
36
|
+
# now go through all appearances to find those for this player
|
37
|
+
appearances.each do |appearance|
|
38
|
+
if appearance.h.to_i > 1 #add only multihit games
|
39
|
+
mh_appearances << appearance
|
40
|
+
end
|
41
|
+
end
|
42
|
+
mh_appearances
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
# Returns an array of batter ids for the game specified
|
47
|
+
# batters are found by looking in the gid/batters directory on gameday
|
48
|
+
def self.get_all_ids_for_game(gid)
|
49
|
+
batters_page = GamedayFetcher.fetch_batters_page(gid)
|
50
|
+
results = []
|
51
|
+
if batters_page
|
52
|
+
doc = Hpricot(batters_page)
|
53
|
+
a = doc.at('ul')
|
54
|
+
if a
|
55
|
+
(a/"a").each do |link|
|
56
|
+
# look at each link inside of a ul tag
|
57
|
+
if link.inner_html.include?(".xml") == true
|
58
|
+
# if the link contains the text '.xml' then it is a batter
|
59
|
+
str = link.inner_html
|
60
|
+
str.strip!
|
61
|
+
batter_id = str[0..str.length-5]
|
62
|
+
results << batter_id
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
results
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def set_batting_stats
|
74
|
+
@season_stats = BattingStats.new(@xml_doc.root.elements["season"])
|
75
|
+
@career_stats = BattingStats.new(@xml_doc.root.elements["career"])
|
76
|
+
@month_stats = BattingStats.new(@xml_doc.root.elements["month"])
|
77
|
+
@empty_stats = BattingStats.new(@xml_doc.root.elements["Empty"])
|
78
|
+
@men_on_stats = BattingStats.new(@xml_doc.root.elements["Men_On"])
|
79
|
+
@risp_stats = BattingStats.new(@xml_doc.root.elements["RISP"])
|
80
|
+
@loaded_stats = BattingStats.new(@xml_doc.root.elements["Loaded"])
|
81
|
+
@vs_lhp_stats = BattingStats.new(@xml_doc.root.elements["vs_LHP"])
|
82
|
+
@vs_rhp_stats = BattingStats.new(@xml_doc.root.elements["vs_RHP"])
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
|
88
|
+
class BattingStats
|
89
|
+
attr_accessor :des, :avg, :ab, :hr, :bb, :so
|
90
|
+
|
91
|
+
def initialize(element)
|
92
|
+
if element.attributes['des']
|
93
|
+
@des = element.attributes['des']
|
94
|
+
end
|
95
|
+
@avg = element.attributes['avg']
|
96
|
+
@ab = element.attributes['ab']
|
97
|
+
@hr = element.attributes['hr']
|
98
|
+
@bb = element.attributes['bb']
|
99
|
+
@so = element.attributes['so']
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'player'
|
2
|
+
|
3
|
+
|
4
|
+
# This class represents a batting record for a single player for a single game
|
5
|
+
# Note that this does NOT represent a single atbat of a player, but rather an appearance is a player's stats over an entire game.
|
6
|
+
class BattingAppearance
|
7
|
+
|
8
|
+
attr_accessor :pid, :batter_name, :pos, :bo, :ab, :po, :r, :bb, :a, :t, :sf, :h, :e, :d, :hbp, :so, :hr, :rbi, :lob, :sb, :avg, :fldg
|
9
|
+
attr_accessor :player, :atbats
|
10
|
+
|
11
|
+
# Used to initialize from box score data
|
12
|
+
def init(element)
|
13
|
+
self.pid = element.attributes['id']
|
14
|
+
self.batter_name = element.attributes['name']
|
15
|
+
self.pos = element.attributes['pos']
|
16
|
+
self.bo = element.attributes['bo']
|
17
|
+
self.ab = element.attributes['ab']
|
18
|
+
self.po = element.attributes['po']
|
19
|
+
self.r = element.attributes['r']
|
20
|
+
self.bb = element.attributes['bb']
|
21
|
+
self.a = element.attributes['a']
|
22
|
+
self.t = element.attributes['t']
|
23
|
+
self.sf = element.attributes['sf']
|
24
|
+
self.h = element.attributes['h']
|
25
|
+
self.e = element.attributes['e']
|
26
|
+
self.d = element.attributes['d']
|
27
|
+
self.hbp = element.attributes['hbp']
|
28
|
+
self.so = element.attributes['so']
|
29
|
+
self.hr = element.attributes['hr']
|
30
|
+
self.rbi = element.attributes['rbi']
|
31
|
+
self.lob = element.attributes['lob']
|
32
|
+
self.sb = element.attributes['sb']
|
33
|
+
self.avg = element.attributes['avg'] # season avg
|
34
|
+
self.fldg = element.attributes['fldg']
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
# Looks up the player record using the players.xml file for the player in this appearance
|
39
|
+
def get_player
|
40
|
+
if !self.player
|
41
|
+
# retrieve player object
|
42
|
+
player = Player.new
|
43
|
+
player.init()
|
44
|
+
self.player = player
|
45
|
+
end
|
46
|
+
self.player
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
# get the atbats associated with this appearance
|
51
|
+
def get_atbats
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
data/lib/box_score.rb
ADDED
@@ -0,0 +1,197 @@
|
|
1
|
+
require 'team'
|
2
|
+
require 'pitching_appearance'
|
3
|
+
require 'batting_appearance'
|
4
|
+
require 'gameday_fetcher'
|
5
|
+
require 'line_score'
|
6
|
+
require 'hpricot'
|
7
|
+
require 'rexml/document'
|
8
|
+
require 'gameday_util'
|
9
|
+
|
10
|
+
|
11
|
+
# Parses the MLB Gameday XML representation of a boxscore and returns data in easy to use
|
12
|
+
# arrays and hashes. Can be used along with a view template to easily create a displayable
|
13
|
+
# box score.
|
14
|
+
class BoxScore
|
15
|
+
|
16
|
+
attr_accessor :xml_data, :gid, :game, :linescore, :game_info, :home_batting_text, :away_batting_text
|
17
|
+
|
18
|
+
attr_accessor :game_id, :game_pk, :home_sport_code, :away_team_code, :home_team_code
|
19
|
+
attr_accessor :away_id, :home_id, :away_fname, :home_fname, :away_sname, :home_sname
|
20
|
+
attr_accessor :date, :away_wins, :away_loss, :home_wins, :home_loss, :status_ind
|
21
|
+
|
22
|
+
attr_accessor :home_runs, :away_runs
|
23
|
+
|
24
|
+
attr_accessor :temp, :wind_speed, :wind_dir
|
25
|
+
|
26
|
+
# complex attributes
|
27
|
+
attr_accessor :innings, :cities, :linescore_totals, :pitchers, :batters
|
28
|
+
|
29
|
+
|
30
|
+
# Loads the boxscore XML from the MLB gameday server and parses it using REXML
|
31
|
+
def load_from_id(gid)
|
32
|
+
@gid = gid
|
33
|
+
@xml_data = GamedayFetcher.fetch_boxscore(gid)
|
34
|
+
@xml_doc = REXML::Document.new(@xml_data)
|
35
|
+
if @xml_doc.root
|
36
|
+
@game = Game.new(@gid)
|
37
|
+
@game.boxscore = self
|
38
|
+
set_basic_info
|
39
|
+
@linescore = LineScore.new
|
40
|
+
@linescore.init(@xml_doc.root.elements["linescore"])
|
41
|
+
@home_runs = @linescore.home_team_runs
|
42
|
+
@away_runs = @linescore.away_team_runs
|
43
|
+
@game_info = @xml_doc.root.elements["game_info"].text
|
44
|
+
set_batting_text
|
45
|
+
set_cities
|
46
|
+
set_pitchers
|
47
|
+
set_batters
|
48
|
+
set_weather
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
# Saves an HTML version of the boxscore
|
54
|
+
def dump_to_file
|
55
|
+
GamedayUtil.save_file("boxscore.html", to_html('boxscore.html.erb'))
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
# Converts the boxscore into a formatted HTML representation.
|
60
|
+
# Relies on the boxscore.html.erb template for describing the layout
|
61
|
+
def to_html(template_filename)
|
62
|
+
gameday_info = GamedayUtil.parse_gameday_id('gid_' + gid)
|
63
|
+
template = ERB.new File.new(File.expand_path(File.dirname(__FILE__) + "/" + template_filename)).read, nil, "%"
|
64
|
+
return template.result(binding)
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
# Returns a 2 element array of leadoff hitters for this game.
|
69
|
+
# [0] = visitor's leadoff hitter
|
70
|
+
# [1] = home's leadoff hitter
|
71
|
+
def get_leadoff_hitters
|
72
|
+
find_hitters("batter")
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
# Returns a 2 element array of cleanup hitters for this game.
|
77
|
+
# [0] = visitor's cleanup hitter
|
78
|
+
# [1] = home's cleanup hitter
|
79
|
+
def get_cleanup_hitters
|
80
|
+
find_hitters("batter[@bo='400']")
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
def find_hitters(search_string)
|
85
|
+
results = []
|
86
|
+
away = @xml_doc.elements["boxscore/batting[@team_flag='away']/#{search_string}"]
|
87
|
+
away_batter = BattingAppearance.new
|
88
|
+
away_batter.init(away)
|
89
|
+
results << away_batter
|
90
|
+
home = @xml_doc.elements["boxscore/batting[@team_flag='home']/#{search_string}"]
|
91
|
+
home_batter = BattingAppearance.new
|
92
|
+
home_batter.init(home)
|
93
|
+
results << home_batter
|
94
|
+
results
|
95
|
+
end
|
96
|
+
|
97
|
+
|
98
|
+
private
|
99
|
+
|
100
|
+
# Retrieves basic game data from the XML root element and sets in object
|
101
|
+
def set_basic_info
|
102
|
+
@game_id = @xml_doc.root.attributes["game_id"]
|
103
|
+
@game_pk = @xml_doc.root.attributes["game_pk"]
|
104
|
+
@home_sport_code = @xml_doc.root.attributes["home_sport_code"]
|
105
|
+
@away_team_code = @xml_doc.root.attributes["away_team_code"]
|
106
|
+
@home_team_code = @xml_doc.root.attributes["home_team_code"]
|
107
|
+
@away_id = @xml_doc.root.attributes["away_id"]
|
108
|
+
@home_id = @xml_doc.root.attributes["home_id"]
|
109
|
+
@away_fname = @xml_doc.root.attributes["away_fname"]
|
110
|
+
@home_fname = @xml_doc.root.attributes["home_fname"]
|
111
|
+
@away_sname = @xml_doc.root.attributes["away_sname"]
|
112
|
+
@home_sname = @xml_doc.root.attributes["home_sname"]
|
113
|
+
@date = @xml_doc.root.attributes["date"]
|
114
|
+
@away_wins = @xml_doc.root.attributes["away_wins"]
|
115
|
+
@away_loss = @xml_doc.root.attributes["away_loss"]
|
116
|
+
@home_wins = @xml_doc.root.attributes["home_wins"]
|
117
|
+
@home_loss = @xml_doc.root.attributes["home_loss"]
|
118
|
+
@status_ind = @xml_doc.root.attributes["status_ind"]
|
119
|
+
end
|
120
|
+
|
121
|
+
|
122
|
+
def set_batting_text
|
123
|
+
if @xml_doc.root.elements["batting[@team_flag='home']/text_data"]
|
124
|
+
@home_batting_text = @xml_doc.root.elements["batting[@team_flag='home']/text_data"].text
|
125
|
+
end
|
126
|
+
if @xml_doc.root.elements["batting[@team_flag='away']/text_data"]
|
127
|
+
@away_batting_text = @xml_doc.root.elements["batting[@team_flag='away']/text_data"].text
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
|
132
|
+
# Sets an array of the city names for the teams playing the game
|
133
|
+
# [0] = away
|
134
|
+
# [1] = home
|
135
|
+
def set_cities
|
136
|
+
@cities = []
|
137
|
+
if @xml_doc.root
|
138
|
+
@cities.push @xml_doc.root.attributes["away_sname"]
|
139
|
+
@cities.push @xml_doc.root.attributes["home_sname"]
|
140
|
+
else
|
141
|
+
@cities.push 'unknown'
|
142
|
+
@cities.push 'unknown'
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
|
147
|
+
# Sets an array of hashes where each hash holds data for a pitcher whom appeared
|
148
|
+
# in the game. Specify either home or away team pitchers.
|
149
|
+
def set_pitchers
|
150
|
+
@pitchers, away_pitchers, home_pitchers = [], [], []
|
151
|
+
count = 1
|
152
|
+
@xml_doc.elements.each("boxscore/pitching[@team_flag='away']/pitcher") { |element|
|
153
|
+
pitcher = PitchingAppearance.new
|
154
|
+
pitcher.init(@gid, element, count)
|
155
|
+
count += 1
|
156
|
+
away_pitchers.push pitcher
|
157
|
+
}
|
158
|
+
count = 1
|
159
|
+
@xml_doc.elements.each("boxscore/pitching[@team_flag='home']/pitcher") { |element|
|
160
|
+
pitcher = PitchingAppearance.new
|
161
|
+
pitcher.init(@gid, element, count)
|
162
|
+
count += 1
|
163
|
+
home_pitchers.push pitcher
|
164
|
+
}
|
165
|
+
@pitchers << away_pitchers
|
166
|
+
@pitchers << home_pitchers
|
167
|
+
end
|
168
|
+
|
169
|
+
|
170
|
+
# Sets an array of hashes where each hash holds data for a batter whom appeared
|
171
|
+
# in the game. Specify either home or away team batters.
|
172
|
+
def set_batters
|
173
|
+
@batters, away_batters, home_batters = [], [], []
|
174
|
+
@xml_doc.elements.each("boxscore/batting[@team_flag='away']/batter") { |element|
|
175
|
+
batter = BattingAppearance.new
|
176
|
+
batter.init(element)
|
177
|
+
away_batters.push batter
|
178
|
+
}
|
179
|
+
@xml_doc.elements.each("boxscore/batting[@team_flag='home']/batter") { |element|
|
180
|
+
batter = BattingAppearance.new
|
181
|
+
batter.init(element)
|
182
|
+
home_batters.push batter
|
183
|
+
}
|
184
|
+
@batters << away_batters
|
185
|
+
@batters << home_batters
|
186
|
+
end
|
187
|
+
|
188
|
+
|
189
|
+
def set_weather
|
190
|
+
@game_info =~ /<br\/><b>Weather<\/b>: (\d+) degrees,.*<br\/><b>Wind<\/b>: (\d+) mph, ([\w\s]+).<br\/>/
|
191
|
+
@temp = $1
|
192
|
+
@wind_speed = $2
|
193
|
+
@wind_dir = $3
|
194
|
+
end
|
195
|
+
|
196
|
+
|
197
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'md5'
|
3
|
+
|
4
|
+
class CacheFetcher
|
5
|
+
|
6
|
+
def initialize(cache_dir=File.expand_path(File.dirname(__FILE__)) + '/tmp')
|
7
|
+
# this is the dir where we store our cache
|
8
|
+
@cache_dir = cache_dir
|
9
|
+
end
|
10
|
+
|
11
|
+
|
12
|
+
def fetch(url)
|
13
|
+
file = MD5.hexdigest(url)
|
14
|
+
file_path = File.join("", @cache_dir, file)
|
15
|
+
# we check if the file -- a MD5 hexdigest of the URL -- exists
|
16
|
+
# in the dir. If it does we just read data from the file and return
|
17
|
+
if !File.exists? file_path
|
18
|
+
#puts 'Not found in cache'
|
19
|
+
# if the file does not exist (or if the data is not fresh), we
|
20
|
+
# make an HTTP request and save it to a file
|
21
|
+
#puts 'Fetching file from internet...'
|
22
|
+
File.open(file_path, "w") do |data|
|
23
|
+
data << Net::HTTP.get_response(URI.parse(url)).body
|
24
|
+
end
|
25
|
+
else
|
26
|
+
#puts 'Using cache'
|
27
|
+
end
|
28
|
+
return File.new(file_path)
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
data/lib/coach.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# This class represents a single MLB coach
|
2
|
+
class Coach
|
3
|
+
|
4
|
+
attr_accessor :position, :first, :last, :id, :num
|
5
|
+
|
6
|
+
|
7
|
+
def init(element)
|
8
|
+
self.id = element.attributes['id']
|
9
|
+
self.first = element.attributes['first']
|
10
|
+
self.last = element.attributes['last']
|
11
|
+
self.num= element.attributes['num']
|
12
|
+
self.position = element.attributes['position']
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
@@ -0,0 +1,231 @@
|
|
1
|
+
require 'game'
|
2
|
+
require 'batter'
|
3
|
+
require 'pitcher'
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
|
7
|
+
|
8
|
+
# This class is used to download data files from the MLB Gameday site to
|
9
|
+
# local storage. The data that is downloaded will be stored into a path that
|
10
|
+
# replicates the MLB Gameday paths, for example here is a sample path for
|
11
|
+
# a specified date:
|
12
|
+
# /components/game/mlb/year_2008/month_04/day_07
|
13
|
+
#
|
14
|
+
class DataDownloader
|
15
|
+
|
16
|
+
FILE_BASE_PATH = 'components/game/mlb'
|
17
|
+
|
18
|
+
|
19
|
+
# Downloads all data files associated with the game specified by the game id passed in.
|
20
|
+
def download_all_for_game(gid)
|
21
|
+
download_xml_for_game(gid)
|
22
|
+
download_batters_for_game(gid)
|
23
|
+
download_inning_for_game(gid)
|
24
|
+
download_media_for_game(gid)
|
25
|
+
download_notification_for_game(gid)
|
26
|
+
download_onbase_for_game(gid)
|
27
|
+
download_pitchers_for_game(gid)
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
def download_batters_for_game(gid)
|
32
|
+
write_file(get_gid_path(gid) + "/batters.html", GamedayFetcher.fetch_batters_page(gid))
|
33
|
+
batter_path = get_gid_path(gid) + "/batters"
|
34
|
+
ids = Batter.get_all_ids_for_game(gid)
|
35
|
+
ids.each do |id|
|
36
|
+
if !File.exists? "#{batter_path}/#{id}.xml"
|
37
|
+
write_file("#{batter_path}/#{id}.xml", GamedayFetcher.fetch_batter(gid, id))
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
def download_pitchers_for_game(gid)
|
44
|
+
write_file(get_gid_path(gid) + "/pitchers.html", GamedayFetcher.fetch_pitchers_page(gid))
|
45
|
+
pitcher_path = get_gid_path(gid) + "/pitchers"
|
46
|
+
ids = Pitcher.get_all_ids_for_game(gid)
|
47
|
+
ids.each do |id|
|
48
|
+
if !File.exists? "#{pitcher_path}/#{id}.xml"
|
49
|
+
write_file("#{pitcher_path}/#{id}.xml", GamedayFetcher.fetch_pitcher(gid, id))
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
def download_inning_for_game(gid)
|
56
|
+
game = Game.new(gid)
|
57
|
+
inn_count = game.get_num_innings
|
58
|
+
inn_path = get_gid_path(gid) + "/inning"
|
59
|
+
(1..inn_count).each do |inn|
|
60
|
+
if !File.exists? "#{inn_path}/inning_#{inn}.xml"
|
61
|
+
write_file("#{inn_path}/inning_#{inn}.xml", GamedayFetcher.fetch_inningx(gid, inn))
|
62
|
+
end
|
63
|
+
end
|
64
|
+
if !File.exists? "#{inn_path}/inning_Scores.xml"
|
65
|
+
write_file("#{inn_path}/inning_Scores.xml", GamedayFetcher.fetch_inning_scores(gid))
|
66
|
+
end
|
67
|
+
if !File.exists? "#{inn_path}/inning_hit.xml"
|
68
|
+
write_file("#{inn_path}/inning_hit.xml", GamedayFetcher.fetch_inning_hit(gid))
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
def download_media_for_game(gid)
|
74
|
+
media_path = get_gid_path(gid) + "/media"
|
75
|
+
if !File.exists? "#{media_path}/highlights.xml"
|
76
|
+
write_file("#{media_path}/highlights.xml", GamedayFetcher.fetch_media_highlights(gid))
|
77
|
+
end
|
78
|
+
if !File.exists? "#{media_path}/mobile.xml"
|
79
|
+
write_file("#{media_path}/mobile.xml", GamedayFetcher.fetch_media_mobile(gid))
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
def download_notification_for_game(gid)
|
85
|
+
game = Game.new(gid)
|
86
|
+
inn_count = game.get_num_innings
|
87
|
+
notif_path = get_gid_path(gid) + "/notifications"
|
88
|
+
(1..inn_count).each do |inn|
|
89
|
+
if !File.exists? "#{notif_path}/notifications_#{inn}.xml"
|
90
|
+
write_file("#{notif_path}/notifications_#{inn}.xml", GamedayFetcher.fetch_notifications_inning(gid, inn))
|
91
|
+
end
|
92
|
+
end
|
93
|
+
if !File.exists? "#{notif_path}/notifications_full.xml"
|
94
|
+
write_file("#{notif_path}/notifications_full.xml", GamedayFetcher.fetch_notifications_full(gid))
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
|
99
|
+
def download_onbase_for_game(gid)
|
100
|
+
onbase_path = get_gid_path(gid) + "/onbase"
|
101
|
+
write_file("#{onbase_path}/linescore.xml", GamedayFetcher.fetch_onbase_linescore(gid))
|
102
|
+
write_file("#{onbase_path}/plays.xml", GamedayFetcher.fetch_onbase_plays(gid))
|
103
|
+
end
|
104
|
+
|
105
|
+
|
106
|
+
# Downloads the top-level xml directories for the game specified by the passed in game id.
|
107
|
+
# The files include:
|
108
|
+
# bench.xml
|
109
|
+
# benchO.xml
|
110
|
+
# boxscore.xml
|
111
|
+
# emailSource.xml
|
112
|
+
# eventLog.xml
|
113
|
+
# game.xml
|
114
|
+
# game_events.xml
|
115
|
+
# gamecenter.xml
|
116
|
+
# gameday_Syn.xml
|
117
|
+
# linescore.xml
|
118
|
+
# miniscoreboard.xml
|
119
|
+
# players.xml
|
120
|
+
# plays.xml
|
121
|
+
def download_xml_for_game(gid)
|
122
|
+
gid_path = get_gid_path(gid)
|
123
|
+
write_file("#{gid_path}/bench.xml", GamedayFetcher.fetch_bench(gid))
|
124
|
+
write_file("#{gid_path}/benchO.xml", GamedayFetcher.fetch_bencho(gid))
|
125
|
+
write_file("#{gid_path}/boxscore.xml", GamedayFetcher.fetch_boxscore(gid))
|
126
|
+
write_file("#{gid_path}/emailSource.xml", GamedayFetcher.fetch_emailsource(gid))
|
127
|
+
write_file("#{gid_path}/eventLog.xml", GamedayFetcher.fetch_eventlog(gid))
|
128
|
+
write_file("#{gid_path}/game.xml", GamedayFetcher.fetch_game_xml(gid))
|
129
|
+
write_file("#{gid_path}/game_events.xml", GamedayFetcher.fetch_game_events(gid))
|
130
|
+
write_file("#{gid_path}/gamecenter.xml", GamedayFetcher.fetch_gamecenter_xml(gid))
|
131
|
+
write_file("#{gid_path}/gameday_Syn.xml", GamedayFetcher.fetch_gamedaysyn(gid))
|
132
|
+
write_file("#{gid_path}/linescore.xml", GamedayFetcher.fetch_linescore(gid))
|
133
|
+
write_file("#{gid_path}/miniscoreboard.xml", GamedayFetcher.fetch_miniscoreboard(gid))
|
134
|
+
write_file("#{gid_path}/players.xml", GamedayFetcher.fetch_players(gid))
|
135
|
+
write_file("#{gid_path}/plays.xml", GamedayFetcher.fetch_plays(gid))
|
136
|
+
end
|
137
|
+
|
138
|
+
|
139
|
+
def download_xml_for_date(year, month, day)
|
140
|
+
day_path = get_day_path(year, month, day)
|
141
|
+
write_file("#{day_path}/epg.xml", GamedayFetcher.fetch_epg(year, month, day))
|
142
|
+
write_file("#{day_path}/master_scoreboard.xml", GamedayFetcher.fetch_scoreboard(year, month, day))
|
143
|
+
write_file("#{day_path}/media/highlights.xml", GamedayFetcher.fetch_day_highlights(year, month, day))
|
144
|
+
end
|
145
|
+
|
146
|
+
|
147
|
+
def download_all_for_date(year, month, day)
|
148
|
+
day_path = get_day_path(year, month, day)
|
149
|
+
write_file("#{day_path}/games.html", GamedayFetcher.fetch_games_page(year, month, day))
|
150
|
+
download_xml_for_date(year, month, day)
|
151
|
+
games = Game.find_by_date(year, month, day)
|
152
|
+
games.each do |game|
|
153
|
+
download_all_for_game(game.gid)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
|
158
|
+
def download_all_for_month(year, month)
|
159
|
+
start_date = Date.new(year.to_i, month.to_i) # first day of month
|
160
|
+
end_date = (start_date >> 1)-1 # last day of month
|
161
|
+
((start_date)..(end_date)).each do |dt|
|
162
|
+
puts 'Downloading ' + year.to_s + '/' + month.to_s + '/' + dt.day.to_s
|
163
|
+
download_all_for_date(year, month, dt.day.to_s)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
|
168
|
+
def download_all_for_range(year, start_month, start_day, end_month, end_day)
|
169
|
+
start_date = Date.new(year.to_i, start_month.to_i, start_day.to_i)
|
170
|
+
end_date = Date.new(year.to_i, end_month.to_i, end_day.to_i)
|
171
|
+
((start_date)..(end_date)).each do |dt|
|
172
|
+
puts 'Downloading ' + dt.year.to_s + '/' + dt.month.to_s + '/' + dt.day.to_s
|
173
|
+
download_all_for_date(dt.year.to_s, dt.month.to_s, dt.day.to_s)
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
|
178
|
+
def tmp_fetch_pages_for_month(year, month, end_day)
|
179
|
+
start_date = Date.new(year.to_i, month.to_i) # first day of month
|
180
|
+
if end_day
|
181
|
+
end_date = Date.new(year.to_i, month.to_i, end_day.to_i)
|
182
|
+
else
|
183
|
+
end_date = (start_date >> 1)-1 # last day of month
|
184
|
+
end
|
185
|
+
((start_date)..(end_date)).each do |dt|
|
186
|
+
day = dt.day.to_s
|
187
|
+
puts day
|
188
|
+
day_path = get_day_path(year, month, day)
|
189
|
+
write_file("#{day_path}/games.html", GamedayFetcher.fetch_games_page(year, month, day))
|
190
|
+
games = Game.find_by_date(year, month, day)
|
191
|
+
games.each do |game|
|
192
|
+
tmp_fetch_pages_for_game(game.gid)
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
def tmp_fetch_pages_for_game(gid)
|
198
|
+
write_file(get_gid_path(gid) + "/batters.html", GamedayFetcher.fetch_batters_page(gid))
|
199
|
+
write_file(get_gid_path(gid) + "/pitchers.html", GamedayFetcher.fetch_pitchers_page(gid))
|
200
|
+
end
|
201
|
+
|
202
|
+
|
203
|
+
private
|
204
|
+
|
205
|
+
|
206
|
+
def get_day_path(year, month, day)
|
207
|
+
year = GamedayUtil.convert_digit_to_string(year.to_i)
|
208
|
+
month = GamedayUtil.convert_digit_to_string(month.to_i)
|
209
|
+
day = GamedayUtil.convert_digit_to_string(day.to_i)
|
210
|
+
"#{FILE_BASE_PATH}/year_" + year + "/month_" + month + "/day_" + day
|
211
|
+
end
|
212
|
+
|
213
|
+
|
214
|
+
def get_gid_path(gid)
|
215
|
+
gameday_info = GamedayUtil.parse_gameday_id('gid_' + gid)
|
216
|
+
"#{FILE_BASE_PATH}/year_" + gameday_info['year'] + "/month_" + gameday_info['month'] + "/day_" + gameday_info['day'] + "/gid_"+gid
|
217
|
+
end
|
218
|
+
|
219
|
+
|
220
|
+
# Writes the gameday data to the file specified.
|
221
|
+
# Does not overwrite existing files.
|
222
|
+
def write_file(file_path, gd_data)
|
223
|
+
if gd_data && !File.exists?(file_path)
|
224
|
+
FileUtils.mkdir_p(File.dirname(file_path))
|
225
|
+
File.open(file_path, "w") do |data|
|
226
|
+
data << gd_data
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
end
|