gameday_api 0.5.0 → 0.5.1

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.
data/lib/game.rb ADDED
@@ -0,0 +1,529 @@
1
+ require 'gameday_util'
2
+ require 'team'
3
+ require 'players'
4
+ require 'game_status'
5
+ require 'event_log'
6
+ require 'inning'
7
+ require 'hitchart'
8
+ require 'media'
9
+
10
+
11
+ # This class represents a single MLB game
12
+ class Game
13
+
14
+ attr_accessor :gid, :home_team_name, :home_team_abbrev, :visit_team_name, :visit_team_abbrev,
15
+ :year, :month, :day, :game_number, :visiting_team, :home_team
16
+ attr_accessor :boxscore, :rosters, :eventlog, :media, :date
17
+
18
+ attr_accessor :innings #array of Inning objects, from innings files
19
+
20
+ attr_accessor :players # data from the players.xml file
21
+
22
+ # additional attributes from master_scoreboard.xml
23
+ attr_accessor :scoreboard_game_id, :ampm, :venue, :game_pk, :time, :time_zone, :game_type
24
+ attr_accessor :away_name_abbrev, :home_name_abbrev, :away_code, :away_file_code, :away_team_id
25
+ attr_accessor :away_team_city, :away_team_name, :away_division
26
+ attr_accessor :home_code, :home_file_code, :home_team_id, :home_team_city, :home_team_name, :home_division
27
+ attr_accessor :day, :gameday_sw, :away_games_back, :home_games_back, :away_games_back_wildcard, :home_games_back_wildcard
28
+ attr_accessor :venue_w_chan_loc, :gameday, :away_win, :away_loss, :home_win, :home_loss, :league
29
+
30
+ attr_accessor :status # An instance of GameStatus object
31
+ attr_accessor :homeruns # an array of players with homeruns in the game
32
+ attr_accessor :winning_pitcher, :losing_pitcher, :save_pitcher # Instances of Player object
33
+ attr_accessor :away_innings, :home_innings # An arry of one element for each inning, the element is the home or away score
34
+ attr_accessor :home_hits, :away_hits, :home_errors, :away_errors, :home_runs, :away_runs
35
+
36
+ def initialize(gid)
37
+ @innings = []
38
+ team = Team.new('')
39
+ if gid
40
+ @gid = gid
41
+ @xml_data = GamedayFetcher.fetch_game_xml(gid)
42
+ if @xml_data && @xml_data.size > 0
43
+ @xml_doc = REXML::Document.new(@xml_data)
44
+ @game_type = @xml_doc.root.attributes["type"]
45
+ @time = @xml_doc.root.attributes["local_game_time"]
46
+ info = GamedayUtil.parse_gameday_id('gid_'+gid)
47
+ @home_team_abbrev = info["home_team_abbrev"]
48
+ @visit_team_abbrev = info["visiting_team_abbrev"]
49
+ @visiting_team = Team.new(@visit_team_abbrev )
50
+ @home_team = Team.new(@home_team_abbrev )
51
+ @year = info["year"]
52
+ @month = info["month"]
53
+ @day = info["day"]
54
+ @game_number = info["game_number"]
55
+ if Team.teams[@home_team_abbrev]
56
+ @home_team_name = Team.teams[@home_team_abbrev][0]
57
+ else
58
+ @home_team_name = @home_team_abbrev
59
+ end
60
+ if Team.teams[@visit_team_abbrev]
61
+ @visit_team_name = Team.teams[@visit_team_abbrev][0]
62
+ else
63
+ @visit_team_name = @visit_team_abbrev
64
+ end
65
+ else
66
+ raise ArgumentError, "Could not find game.xml"
67
+ end
68
+ end
69
+ end
70
+
71
+
72
+ # Setup a Game object from data read from the master_scoreboard.xml file
73
+ def load_from_scoreboard(element)
74
+ @away_innings = []
75
+ @home_innings = []
76
+ @scoreboard_game_id = element.attributes['id']
77
+ @ampm = element.attributes['ampm']
78
+ @venue = element.attributes['venue']
79
+ @game_pk = element.attributes['game_pk']
80
+ @time = element.attributes['time']
81
+ @time_zone = element.attributes['time_zone']
82
+ @game_type = element.attributes['game_type']
83
+ @away_name_abbrev = element.attributes['away_name_abbrev']
84
+ @home_name_abbrev = element.attributes['home_name_abbrev']
85
+ @away_code = element.attributes['away_code']
86
+ @away_file_code = element.attributes['away_file_code']
87
+ @away_team_id = element.attributes['away_team_id']
88
+ @away_team_city = element.attributes['away_team_city']
89
+ @away_team_name = element.attributes['away_team_name']
90
+ @away_division = element.attributes['away_division']
91
+ @home_code = element.attributes['home_code']
92
+ @home_file_code = element.attributes['home_file_code']
93
+ @home_team_id = element.attributes['home_team_id']
94
+ @home_team_city = element.attributes['home_team_city']
95
+ @home_team_name = element.attributes['home_team_name']
96
+ @home_division = element.attributes['home_division']
97
+ @day = element.attributes['day']
98
+ @gameday_sw = element.attributes['gameday_sw']
99
+ @away_games_back = element.attributes['away_games_back']
100
+ @home_games_back = element.attributes['home_games_back']
101
+ @away_games_back_wildcard = element.attributes['away_games_back_wildcard']
102
+ @home_games_back_wildcard = element.attributes['home_games_back_wildcard']
103
+ @venue_w_chan_loc = element.attributes['venue_w_chan_loc']
104
+ @gameday = element.attributes['gameday']
105
+ @away_win = element.attributes['away_win']
106
+ @away_loss = element.attributes['away_loss']
107
+ @home_win = element.attributes['home_win']
108
+ @home_loss = element.attributes['home_loss']
109
+ @league = element.attributes['league']
110
+
111
+ set_status(element)
112
+ set_innings(element)
113
+ set_totals(element)
114
+ set_pitchers(element)
115
+ set_homeruns(element)
116
+ end
117
+
118
+
119
+ # Sets the game status from data in the master_scoreboard.xml file
120
+ def set_status(element)
121
+ element.elements.each("status") { |status|
122
+ @status = GameStatus.new
123
+ @status.status = status.attributes['status']
124
+ @status.ind = status.attributes['ind']
125
+ @status.reason = status.attributes['reason']
126
+ @status.inning = status.attributes['inning']
127
+ @status.top_inning = status.attributes['top_inning']
128
+ @status.b = status.attributes['b']
129
+ @status.s = status.attributes['s']
130
+ @status.o = status.attributes['o']
131
+ }
132
+ end
133
+
134
+
135
+ # Sets the away and home innings array containing scores by inning from data in the master_scoreboard.xml file
136
+ def set_innings(element)
137
+ element.elements.each("linescore/inning") { |element|
138
+ @away_innings << element.attributes['away']
139
+ @home_innings << element.attributes['home']
140
+ }
141
+ end
142
+
143
+
144
+ # Sets the Runs/Hits/Errors totals from data in the master_scoreboard.xml file
145
+ def set_totals(element)
146
+ element.elements.each("linescore/r") { |runs|
147
+ @away_runs = runs.attributes['away']
148
+ @home_runs = runs.attributes['home']
149
+ }
150
+ element.elements.each("linescore/h") { |hits|
151
+ @away_hits = hits.attributes['away']
152
+ @home_hits = hits.attributes['home']
153
+ }
154
+ element.elements.each("linescore/e") { |errs|
155
+ @away_errors = errs.attributes['away']
156
+ @home_errors = errs.attributes['home']
157
+ }
158
+ end
159
+
160
+
161
+ # Sets a list of players who had homeruns in this game from data in the master_scoreboard.xml file
162
+ def set_homeruns(element)
163
+ @homeruns = []
164
+ element.elements.each("home_runs/player") do |hr|
165
+ player = Player.new
166
+ player.last = hr.attributes['last']
167
+ player.first = hr.attributes['first']
168
+ player.hr = hr.attributes['hr']
169
+ player.std_hr = hr.attributes['std_hr']
170
+ player.team_code = hr.attributes['team_code']
171
+ @homeruns << player
172
+ end
173
+ end
174
+
175
+
176
+ # Sets the pitchers of record (win, lose, save) from data in the master_scoreboard.xml file
177
+ def set_pitchers(element)
178
+ element.elements.each("winning_pitcher") do |wp|
179
+ @winning_pitcher = Player.new
180
+ @winning_pitcher.init_pitcher_from_scoreboard(wp)
181
+ end
182
+ element.elements.each("losing_pitcher") do |lp|
183
+ @losing_pitcher = Player.new
184
+ @losing_pitcher.init_pitcher_from_scoreboard(lp)
185
+ end
186
+ element.elements.each("save_pitcher") do |sp|
187
+ @save_pitcher = Player.new
188
+ @save_pitcher.first = sp.attributes['first']
189
+ @save_pitcher.last = sp.attributes['last']
190
+ @save_pitcher.saves = sp.attributes['saves']
191
+ end
192
+ end
193
+
194
+
195
+ def self.find_by_month(year, month)
196
+ games = []
197
+ start_date = Date.new(year.to_i, month.to_i) # first day of month
198
+ end_date = (start_date >> 1)-1 # last day of month
199
+ ((start_date)..(end_date)).each do |dt|
200
+ games += find_by_date(year, month, dt.day.to_s)
201
+ end
202
+ games
203
+ end
204
+
205
+
206
+ # Returns an array of Game objects for each game for the specified day
207
+ def self.find_by_date(year, month, day)
208
+ begin
209
+ games = []
210
+ games_page = GamedayFetcher.fetch_games_page(year, month, day)
211
+ if games_page
212
+ @hp = Hpricot(games_page)
213
+ a = @hp.at('ul')
214
+ (a/"a").each do |link|
215
+ # look at each link inside of a ul tag
216
+ if link.inner_html.include?('gid')
217
+ # if the link contains the text 'gid' then it is a listing of a game
218
+ str = link.inner_html
219
+ gid = str[5..str.length-2]
220
+ begin
221
+ game = Game.new(gid)
222
+ games.push game
223
+ rescue
224
+ puts "Could not create game object for #{year}, #{month}, #{day} - #{gid}"
225
+ end
226
+ end
227
+ end
228
+ else
229
+ puts "Could not read games page for #{year}, #{month}, #{day}."
230
+ end
231
+ return games
232
+ rescue
233
+ puts "No games data found for #{year}, #{month}, #{day}."
234
+ end
235
+ end
236
+
237
+
238
+ # Returns a 2 element array containing the home and visiting rosters for this game
239
+ # [0] array of all visitor players
240
+ # [1] array of all home players
241
+ def get_rosters
242
+ if !@rosters
243
+ players = Players.new
244
+ players.load_from_id(@gid)
245
+ @rosters = players.rosters
246
+ end
247
+ @rosters
248
+ end
249
+
250
+
251
+ def get_eventlog
252
+ if !@eventlog
253
+ @eventlog = EventLog.new
254
+ @eventlog.load_from_id(@gid)
255
+ end
256
+ @eventlog
257
+ end
258
+
259
+
260
+ # Returns a BoxScore object representing the boxscore for this game
261
+ def get_boxscore
262
+ if !@boxscore
263
+ box = BoxScore.new
264
+ box.load_from_id(self.gid)
265
+ @boxscore = box
266
+ end
267
+ @boxscore
268
+ end
269
+
270
+
271
+ # Saves an HTML version of the boxscore for the game
272
+ def dump_boxscore
273
+ if self.gid
274
+ bs = get_boxscore
275
+ GamedayUtil.save_file("boxscore.html", bs.to_html('boxscore.html.erb'))
276
+ else
277
+ puts "No data for input specified"
278
+ end
279
+ end
280
+
281
+
282
+ # Returns a string containing the linescore in the following printed format:
283
+ # Away 1 3 1
284
+ # Home 5 8 0
285
+ def print_linescore
286
+ bs = get_boxscore
287
+ output = ''
288
+ if bs.linescore
289
+ output += self.visit_team_name + ' ' + bs.linescore.away_team_runs + ' ' + bs.linescore.away_team_hits + ' ' + bs.linescore.away_team_errors + "\n"
290
+ output += self.home_team_name + ' ' + bs.linescore.home_team_runs + ' ' + bs.linescore.home_team_hits + ' ' + bs.linescore.home_team_errors
291
+ else
292
+ output += 'No linescore available for ' + @visit_team_name + ' vs. ' + @home_team_name
293
+ end
294
+ output
295
+ end
296
+
297
+
298
+ # Returns an array of the starting pitchers for the game
299
+ # [0] = visiting team pitcher
300
+ # [1] = home team pitcher
301
+ def get_starting_pitchers
302
+ results = []
303
+ results << get_pitchers('away')[0]
304
+ results << get_pitchers('home')[0]
305
+ end
306
+
307
+
308
+ # Returns an array of the closing pitchers for the game
309
+ # [0] = visiting team pitcher
310
+ # [1] = home team pitcher
311
+ def get_closing_pitchers
312
+ results = []
313
+ away_pitchers = get_pitchers('away')
314
+ home_pitchers = get_pitchers('home')
315
+ results << away_pitchers[(away_pitchers.size) - 1]
316
+ results << home_pitchers[(home_pitchers.size) -1]
317
+ end
318
+
319
+
320
+ # Returns an array of all pitchers for either the home team or the away team.
321
+ # The values in the returned array are PitchingAppearance instances
322
+ def get_pitchers(home_or_away)
323
+ if self.gid
324
+ bs = get_boxscore
325
+ if home_or_away == 'away'
326
+ bs.pitchers[0]
327
+ else
328
+ bs.pitchers[1]
329
+ end
330
+ else
331
+ puts "No data for input specified"
332
+ end
333
+ end
334
+
335
+
336
+ # Returns an array of pitches from this game for the pitcher identified by pid
337
+ def get_pitches(pid)
338
+ results = []
339
+ atbats = get_atbats
340
+ atbats.each do |ab|
341
+ if ab.pitcher_id == pid
342
+ results << ab.pitches
343
+ end
344
+ end
345
+ results.flatten
346
+ end
347
+
348
+
349
+ # Returns an array of either home or away batters for this game
350
+ # home_or_away must be a string with value 'home' or 'away'
351
+ # The values in the returned array are BattingAppearance instances
352
+ def get_batters(home_or_away)
353
+ if self.gid
354
+ bs = get_boxscore
355
+ if home_or_away == 'away'
356
+ bs.batters[0]
357
+ else
358
+ bs.batters[1]
359
+ end
360
+ else
361
+ puts "No data for input specified"
362
+ end
363
+ end
364
+
365
+
366
+ # Returns the starting lineups for this game in an array with 2 elements
367
+ # results[0] = visitors
368
+ # results[1] = home
369
+ def get_lineups
370
+ results = []
371
+ results << get_batters('away')
372
+ results << get_batters('home')
373
+ end
374
+
375
+
376
+ # Returns the pitchers for this game in an array with 2 elements
377
+ # results[0] = visitors
378
+ # results[1] = home
379
+ def get_pitching
380
+ results = []
381
+ results << get_pitchers('away')
382
+ results << get_pitchers('home')
383
+ end
384
+
385
+
386
+ # Returns the team abreviation of the winning team
387
+ def get_winner
388
+ ls = get_boxscore.linescore
389
+ if ls.home_team_runs > ls.away_team_runs
390
+ return home_team_abbrev
391
+ else
392
+ return visit_team_abbrev
393
+ end
394
+ end
395
+
396
+
397
+ # Returns a 2 element array holding the game score
398
+ # [0] visiting team runs
399
+ # [1] home team runs
400
+ def get_score
401
+ results = []
402
+ ls = get_boxscore.linescore
403
+ results << ls.away_team_runs
404
+ results << ls.home_team_runs
405
+ results
406
+ end
407
+
408
+
409
+ # Returns a string holding the game attendance value
410
+ def get_attendance
411
+ game_info = get_boxscore.game_info
412
+ # parse game_info to get attendance
413
+ game_info[game_info.length-12..game_info.length-7]
414
+ end
415
+
416
+
417
+ def get_media
418
+ if !@media
419
+ @media = Media.new
420
+ @media.load_from_id(@gid)
421
+ end
422
+ @media
423
+ end
424
+
425
+
426
+ # Returns an array of Inning objects that represent each inning of the game
427
+ def get_innings
428
+ if @innings.length == 0
429
+ inn_count = get_num_innings
430
+ (1..get_num_innings).each do |inn|
431
+ inning = Inning.new
432
+ inning.load_from_id(@gid, inn)
433
+ @innings << inning
434
+ end
435
+ end
436
+ @innings
437
+ end
438
+
439
+
440
+ # Returns an array of AtBat objects that represent each atbat of the game
441
+ def get_atbats
442
+ atbats = []
443
+ innings = get_innings
444
+ innings.each do |inning|
445
+ inning.top_atbats.each do |atbat|
446
+ atbats << atbat
447
+ end
448
+ inning.bottom_atbats.each do |atbat|
449
+ atbats << atbat
450
+ end
451
+ end
452
+ atbats
453
+ end
454
+
455
+
456
+ def get_hitchart
457
+ if !@hitchart
458
+ @hitchart = Hitchart.new
459
+ @hitchart.load_from_gid(@gid)
460
+ end
461
+ @hitchart
462
+ end
463
+
464
+
465
+ # Returns the number of innings for this game
466
+ def get_num_innings
467
+ bs = get_boxscore
468
+ if bs.linescore
469
+ return get_boxscore.linescore.innings.length
470
+ else
471
+ return 0
472
+ end
473
+ end
474
+
475
+
476
+ # Returns a hash of umpires for this game
477
+ #
478
+ # { 'hp' => 'john doe',
479
+ # '1b' => 'paul jones',
480
+ # '2b' => 'mike james',
481
+ # '3b' => 'pete myers' }
482
+ #
483
+ def get_umpires
484
+ if !@players
485
+ @players = Players.new
486
+ @players.load_from_id(@gid)
487
+ end
488
+ @players.umpires
489
+ end
490
+
491
+
492
+ def get_date
493
+ bs = get_boxscore
494
+ bs.date
495
+ end
496
+
497
+
498
+ def get_temp
499
+ bs = get_boxscore
500
+ bs.temp
501
+ end
502
+
503
+
504
+ def get_wind_speed
505
+ bs = get_boxscore
506
+ bs.wind_speed
507
+ end
508
+
509
+
510
+ def get_wind_dir
511
+ bs = get_boxscore
512
+ bs.wind_dir
513
+ end
514
+
515
+
516
+ def get_home_runs
517
+ bs = get_boxscore
518
+ bs.home_runs
519
+ end
520
+
521
+
522
+ def get_away_runs
523
+ bs = get_boxscore
524
+ bs.away_runs
525
+ end
526
+
527
+
528
+ end
529
+
@@ -0,0 +1,6 @@
1
+
2
+ class GameStatus
3
+
4
+ attr_accessor :status, :ind, :reason, :inning, :top_inning, :b, :s, :o
5
+
6
+ end
data/lib/gameday.rb ADDED
@@ -0,0 +1,58 @@
1
+ require 'rubygems'
2
+ require 'net/http'
3
+ require 'hpricot'
4
+ require 'erb'
5
+ require 'game'
6
+ require 'team'
7
+ require 'box_score'
8
+
9
+
10
+ class Gameday
11
+
12
+ # Change this to point to the server you are reading Gameday data from
13
+ GD2_MLB_BASE = "http://gd2.mlb.com/components/game"
14
+
15
+
16
+ def initialize
17
+ super
18
+ end
19
+
20
+
21
+ # Returns an array of game id's for the given date
22
+ def get_all_gids_for_date(year, month, day)
23
+ begin
24
+ gids = []
25
+ url = GamedayUtil.build_day_url(year, month, date)
26
+ connection = GamedayUtil.get_connection(url)
27
+ if connection
28
+ @hp = Hpricot(connection)
29
+ a = @hp.at('ul')
30
+ (a/"a").each do |link|
31
+ if link.inner_html.include?('gid')
32
+ str = link.inner_html
33
+ gids.push str[5..str.length-2]
34
+ end
35
+ end
36
+ end
37
+ connection.close
38
+ return gids
39
+ rescue
40
+ puts "No games data found for #{year}, #{month}, #{day}."
41
+ end
42
+ end
43
+
44
+
45
+ # Converts numbers to two character strings by prepending a '0' if number
46
+ # is less than 10.
47
+ def convert_to_two_digit_str(number)
48
+ if number < 10
49
+ return '0'+number.to_s
50
+ else
51
+ return number.to_s
52
+ end
53
+ end
54
+
55
+ end
56
+
57
+
58
+