├── .gitignore
├── Gemfile
├── lib
├── mlb_gameday
│ ├── version.rb
│ ├── batter.rb
│ ├── division.rb
│ ├── league.rb
│ ├── player.rb
│ ├── pitcher.rb
│ ├── team.rb
│ └── game.rb
└── mlb_gameday.rb
├── Rakefile
├── .rubocop.yml
├── test
├── year_2014
│ ├── pitchers
│ │ └── 477132.xml
│ ├── month_05
│ │ └── day_28
│ │ │ └── gid_2014_05_28_cinmlb_lanmlb_1
│ │ │ ├── pitchers
│ │ │ ├── 607162.xml
│ │ │ ├── 543493.xml
│ │ │ ├── 455092.xml
│ │ │ ├── 502009.xml
│ │ │ ├── 451532.xml
│ │ │ ├── 457707.xml
│ │ │ ├── 434442.xml
│ │ │ ├── 459967.xml
│ │ │ ├── 519437.xml
│ │ │ ├── 547973.xml
│ │ │ ├── 446185.xml
│ │ │ ├── 448159.xml
│ │ │ ├── 434181.xml
│ │ │ ├── 445156.xml
│ │ │ ├── 453198.xml
│ │ │ ├── 455009.xml
│ │ │ ├── 543331.xml
│ │ │ ├── 124604.xml
│ │ │ ├── 445276.xml
│ │ │ ├── 477132.xml
│ │ │ ├── 547943.xml
│ │ │ ├── 571561.xml
│ │ │ ├── 430904.xml
│ │ │ ├── 451216.xml
│ │ │ ├── 502190.xml
│ │ │ ├── 277417.xml
│ │ │ ├── 429717.xml
│ │ │ ├── 430580.xml
│ │ │ ├── 425844.xml
│ │ │ ├── 456501.xml
│ │ │ └── 456701.xml
│ │ │ ├── batters
│ │ │ ├── 445276.xml
│ │ │ ├── 453198.xml
│ │ │ ├── 455092.xml
│ │ │ ├── 519437.xml
│ │ │ ├── 607162.xml
│ │ │ ├── 429717.xml
│ │ │ ├── 430904.xml
│ │ │ ├── 457707.xml
│ │ │ ├── 459967.xml
│ │ │ ├── 543331.xml
│ │ │ ├── 547943.xml
│ │ │ ├── 124604.xml
│ │ │ ├── 425844.xml
│ │ │ ├── 445156.xml
│ │ │ ├── 446185.xml
│ │ │ ├── 451532.xml
│ │ │ ├── 502009.xml
│ │ │ ├── 543493.xml
│ │ │ ├── 571561.xml
│ │ │ ├── 277417.xml
│ │ │ ├── 430580.xml
│ │ │ ├── 543148.xml
│ │ │ ├── 544371.xml
│ │ │ ├── 628326.xml
│ │ │ ├── 434442.xml
│ │ │ ├── 435219.xml
│ │ │ ├── 451216.xml
│ │ │ ├── 454560.xml
│ │ │ ├── 456501.xml
│ │ │ ├── 502190.xml
│ │ │ ├── 408210.xml
│ │ │ ├── 421124.xml
│ │ │ ├── 448159.xml
│ │ │ ├── 455009.xml
│ │ │ ├── 547973.xml
│ │ │ ├── 475100.xml
│ │ │ ├── 502317.xml
│ │ │ ├── 346874.xml
│ │ │ ├── 408307.xml
│ │ │ ├── 434181.xml
│ │ │ ├── 458015.xml
│ │ │ ├── 457449.xml
│ │ │ ├── 477132.xml
│ │ │ ├── 465668.xml
│ │ │ ├── 456701.xml
│ │ │ ├── 435401.xml
│ │ │ ├── 460077.xml
│ │ │ ├── 457759.xml
│ │ │ ├── 519023.xml
│ │ │ ├── 571740.xml
│ │ │ ├── 430910.xml
│ │ │ ├── 434670.xml
│ │ │ ├── 446359.xml
│ │ │ ├── 543829.xml
│ │ │ ├── 461314.xml
│ │ │ ├── 407886.xml
│ │ │ ├── 457803.xml
│ │ │ ├── 444843.xml
│ │ │ ├── 453943.xml
│ │ │ ├── 408236.xml
│ │ │ ├── 624577.xml
│ │ │ └── 408252.xml
│ │ │ ├── linescore.xml
│ │ │ └── gamecenter.xml
│ └── month_07
│ │ └── day_15
│ │ └── gid_2014_07_15_nasmlb_aasmlb_1
│ │ └── pitchers
│ │ └── 477132.xml
├── download.rb
├── game_spec.rb
└── api_spec.rb
├── CHANGELOG.md
├── README.md
├── LICENSE.txt
├── mlb_gameday.gemspec
└── resources
└── data.yml
/.gitignore:
--------------------------------------------------------------------------------
1 | Gemfile.lock
2 | pkg
3 | test/year_2014
4 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | source 'https://rubygems.org'
4 |
5 | gemspec
6 |
--------------------------------------------------------------------------------
/lib/mlb_gameday/version.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module MLBGameday
4 | VERSION = '0.3.2'
5 | end
6 |
--------------------------------------------------------------------------------
/lib/mlb_gameday/batter.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module MLBGameday
4 | class Batter < Player
5 | end
6 | end
7 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'bundler/gem_tasks'
4 | require 'rake/testtask'
5 | require 'rspec/core/rake_task'
6 |
7 | Rake::TestTask.new do |t|
8 | t.pattern = 'test/*_spec.rb'
9 | end
10 |
11 | task default: :test
12 |
--------------------------------------------------------------------------------
/lib/mlb_gameday/division.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module MLBGameday
4 | class Division
5 | attr_reader :id, :league, :name, :teams
6 |
7 | def initialize(id:, league:, name:, teams:)
8 | @id = id
9 | @league = league
10 | @name = name
11 | @teams = teams
12 | end
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/lib/mlb_gameday/league.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module MLBGameday
4 | class League
5 | attr_reader :name, :divisions
6 |
7 | def initialize(name, divisions)
8 | @name = name
9 | @divisions = divisions
10 | end
11 |
12 | def division(name)
13 | raise 'Invalid division' unless %i[East Central West].include?(name)
14 |
15 | @divisions[name]
16 | end
17 | end
18 | end
19 |
--------------------------------------------------------------------------------
/.rubocop.yml:
--------------------------------------------------------------------------------
1 | AllCops:
2 | Include:
3 | - Rakefile
4 | - Gemfile
5 | TargetRubyVersion: 2.5
6 |
7 | Layout/MultilineMethodCallIndentation:
8 | EnforcedStyle: indented
9 |
10 | Metrics/AbcSize:
11 | Enabled: false
12 |
13 | Metrics/ClassLength:
14 | Max: 100
15 |
16 | Metrics/CyclomaticComplexity:
17 | Enabled: false
18 |
19 | Metrics/MethodLength:
20 | Max: 15
21 |
22 | Style/Documentation:
23 | Enabled: false
24 |
--------------------------------------------------------------------------------
/test/year_2014/pitchers/477132.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/lib/mlb_gameday/player.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module MLBGameday
4 | class Player
5 | attr_reader :id, :data
6 |
7 | def initialize(id:, xml:)
8 | @id = id
9 | @data = xml
10 | end
11 |
12 | def first_name
13 | @data.xpath('//Player//@first_name').text
14 | end
15 |
16 | def last_name
17 | @data.xpath('//Player//@last_name').text
18 | end
19 |
20 | def name
21 | "#{first_name} #{last_name}"
22 | end
23 | end
24 | end
25 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | ## 0.3.2
4 |
5 | * Don't load an extra XML file at the end of the game to find the W/L/S pitcher's stats.
6 |
7 | ## 0.3.1
8 |
9 | * Changed back to gdx - the redirect is gone.
10 |
11 | ## 0.3.0
12 |
13 | * Changed data source to gd-terr-origin.mlb.com since gdx.mlb.com redirects there.
14 | * Code cleanup.
15 |
16 | ## 0.2.3 / 0.2.4
17 |
18 | * Add All Star teams
19 |
20 | ## 0.2.1 / 0.2.2
21 |
22 | * Recognize "d-backs" as a name for the Diamondbacks
23 |
24 | ## 0.2.0
25 |
26 | * Added game attendance, weather, wind, elapsed time, and umpires
27 | * Understand a few more game statuses
28 | * Use Ruby 2.4 lonely operator (&.) **This drops compatibility for Ruby 2.3 and below.**
29 | * Fixed implicit names bug (thanks to @cacqw7) [#4](https://github.com/Fustrate/mlb_gameday/pull/4)
30 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # The Gameday API has been deprecated by MLB
2 |
3 | This gem is no longer under development. Use [the MLB Stats API gem](//github.com/Fustrate/mlb_stats_api) instead.
4 |
5 | # MLBGameday
6 |
7 | TODO: Write a gem description
8 |
9 | ## Installation
10 |
11 | Add this line to your application's Gemfile:
12 |
13 | gem 'mlb_gameday'
14 |
15 | And then execute:
16 |
17 | $ bundle
18 |
19 | Or install it yourself as:
20 |
21 | $ gem install mlb_gameday
22 |
23 | ## Usage
24 |
25 | `require 'mlb_gameday' #=> true`
26 | `gd2 = MLBGameday::API.new`
27 |
28 | ## Contributing
29 |
30 | 1. Fork it
31 | 2. Create your feature branch (`git checkout -b my-new-feature`)
32 | 3. Commit your changes (`git commit -am 'Add some feature'`)
33 | 4. Push to the branch (`git push origin my-new-feature`)
34 | 5. Create new Pull Request
35 |
--------------------------------------------------------------------------------
/lib/mlb_gameday/pitcher.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module MLBGameday
4 | class Pitcher < Player
5 | def era
6 | @data.xpath('//Player/season/@era').text.to_f
7 | end
8 |
9 | def wins
10 | @data.xpath('//Player/season/@w').text.to_i
11 | end
12 |
13 | def losses
14 | @data.xpath('//Player/season/@l').text.to_i
15 | end
16 |
17 | def innings
18 | @data.xpath('//Player/season/@ip').text.to_f
19 | end
20 |
21 | def saves
22 | @data.xpath('//Player/season/@sv').text.to_i
23 | end
24 |
25 | def whip
26 | @data.xpath('//Player/season/@whip').text.to_f
27 | end
28 |
29 | def strikeouts
30 | @data.xpath('//Player/season/@so').text.to_i
31 | end
32 |
33 | def walks
34 | @data.xpath('//Player/season/@bb').text.to_i
35 | end
36 | end
37 | end
38 |
--------------------------------------------------------------------------------
/test/download.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'open-uri'
4 | require 'fileutils'
5 |
6 | raise 'Please pass a URL to this program.' if ARGV[0].empty?
7 |
8 | def download_url(url)
9 | response = open(url)
10 |
11 | puts "Downloading #{url}"
12 |
13 | raise "Error downloading #{url}" unless response.status[0] == '200'
14 |
15 | handle_file url, response.read
16 | end
17 |
18 | def handle_file(url, body)
19 | filename = url.gsub 'http://gd2.mlb.com/components/game/mlb/', ''
20 |
21 | if body['Index of']
22 | body.scan(%r{
\s*(.*)}) do |match|
23 | # Only the "Parent Directory" link is different
24 | next if match[0] != match[1]
25 |
26 | download_url("#{url}/#{match[0]}")
27 | end
28 | else
29 | # Save the file
30 | save_file filename, body
31 | end
32 | end
33 |
34 | def save_file(filename, body)
35 | save_path = File.join Dir.pwd, filename
36 | FileUtils.mkdir_p File.dirname save_path
37 | File.open(save_path, 'w') { |file| file.write body }
38 | end
39 |
40 | download_url ARGV[0]
41 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2013 Steven Hoffman
2 |
3 | MIT License
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining
6 | a copy of this software and associated documentation files (the
7 | "Software"), to deal in the Software without restriction, including
8 | without limitation the rights to use, copy, modify, merge, publish,
9 | distribute, sublicense, and/or sell copies of the Software, and to
10 | permit persons to whom the Software is furnished to do so, subject to
11 | the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be
14 | included in all copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 |
--------------------------------------------------------------------------------
/mlb_gameday.gemspec:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | lib = File.expand_path('../lib', __FILE__)
4 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5 | require 'mlb_gameday/version'
6 |
7 | Gem::Specification.new do |spec|
8 | spec.name = 'mlb_gameday'
9 | spec.version = MLBGameday::VERSION
10 | spec.authors = ['Steven Hoffman']
11 | spec.email = ['git@fustrate.com']
12 | spec.description = 'Access data about games and players from the ' \
13 | 'official MLB Gameday API'
14 | spec.summary = 'Fetches gameday data from the MLB Gameday API'
15 | spec.homepage = 'http://github.com/fustrate/mlb_gameday'
16 | spec.license = 'MIT'
17 |
18 | spec.files = `git ls-files`.split($RS)
19 | spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
20 | spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
21 | spec.require_paths = %w[lib]
22 |
23 | spec.add_development_dependency 'bundler', '~> 1.9'
24 | spec.add_development_dependency 'minitest', '~> 5.5'
25 | spec.add_development_dependency 'rake', '~> 10.4'
26 |
27 | spec.add_dependency 'chronic', '~> 0.10'
28 | spec.add_dependency 'httparty', '~> 0.13'
29 | spec.add_dependency 'nokogiri', '~> 1.6'
30 | end
31 |
--------------------------------------------------------------------------------
/lib/mlb_gameday/team.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module MLBGameday
4 | class Team
5 | attr_reader :id, :name, :city, :league, :division, :code, :file_code
6 |
7 | def initialize(opts = {})
8 | @id = opts[:id]
9 | @name = opts[:name]
10 | @city = opts[:city]
11 | @league = opts[:league]
12 | @division = opts[:division]
13 | @alt_names = opts[:alt_names]
14 | @code = opts[:code]
15 | @file_code = opts[:file_code]
16 | end
17 |
18 | def full_name
19 | "#{city} #{name}"
20 | end
21 |
22 | def names
23 | @names ||= (implicit_names + alt_names).uniq
24 | end
25 |
26 | def called?(name)
27 | names.include?(name.downcase)
28 | end
29 |
30 | # So we don't get huge printouts
31 | def inspect
32 | %(#)
33 | end
34 |
35 | private
36 |
37 | def alt_names
38 | @alt_names ||= []
39 | end
40 |
41 | def implicit_names
42 | result = strict_names
43 | result << [code, singular_name, despaced_name].map(&:downcase)
44 | result << city.downcase unless ['New York', 'Chicago'].include?(city)
45 |
46 | result.flatten.uniq
47 | end
48 |
49 | def strict_names
50 | [name, full_name].map(&:downcase)
51 | end
52 |
53 | def singular_name
54 | name.chomp 's'
55 | end
56 |
57 | def despaced_name
58 | name.tr ' ', ''
59 | end
60 | end
61 | end
62 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/pitchers/607162.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/pitchers/543493.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/pitchers/455092.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/pitchers/502009.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/pitchers/451532.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/445276.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/453198.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/455092.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/519437.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/607162.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/429717.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/430904.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/457707.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/459967.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/543331.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/547943.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/124604.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/425844.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/445156.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/446185.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/451532.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/502009.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/543493.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/571561.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/pitchers/457707.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/277417.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/430580.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/543148.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/544371.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/628326.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/434442.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/435219.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/451216.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/454560.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/456501.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/502190.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/408210.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/421124.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/448159.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/455009.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/547973.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/pitchers/434442.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/pitchers/459967.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/pitchers/519437.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/pitchers/547973.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/475100.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/pitchers/446185.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/pitchers/448159.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/pitchers/434181.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/pitchers/445156.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/pitchers/453198.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/pitchers/455009.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/pitchers/543331.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/502317.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/pitchers/124604.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/pitchers/445276.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/346874.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/408307.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/pitchers/477132.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/pitchers/547943.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/pitchers/571561.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_07/day_15/gid_2014_07_15_nasmlb_aasmlb_1/pitchers/477132.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/434181.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/458015.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/pitchers/430904.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/pitchers/451216.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/pitchers/502190.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/pitchers/277417.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/pitchers/429717.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/pitchers/430580.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/457449.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/pitchers/425844.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/pitchers/456501.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/pitchers/456701.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/477132.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/465668.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/456701.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/435401.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/460077.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/457759.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/519023.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/571740.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/430910.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/434670.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/446359.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/543829.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/461314.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/407886.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/457803.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/444843.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/453943.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/408236.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/624577.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/batters/408252.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/game_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'minitest/autorun'
4 | require 'mlb_gameday.rb'
5 |
6 | # Mock the basic `open` function so we don't actually hit the MLB website
7 | class MockedApi < MLBGameday::API
8 | alias old_open open
9 |
10 | def open(url, &block)
11 | dir = File.dirname __FILE__
12 | base = url.gsub 'http://gdx.mlb.com/components/game/mlb/', ''
13 | path = File.join dir, base
14 |
15 | unless File.exist?(path)
16 | puts "Downloading from website: #{url}"
17 |
18 | return old_open(url, &block)
19 | end
20 |
21 | file = File.open path
22 |
23 | return file unless block_given?
24 |
25 | yield file
26 | end
27 | end
28 |
29 | class TestGame < MiniTest::Test
30 | def setup
31 | @api = MockedApi.new
32 | @game = @api.game('2014_05_28_cinmlb_lanmlb_1')
33 | # @free_game = @api.game('2013_04_01_slnmlb_arimlb_1')
34 | end
35 |
36 | def test_load_game_from_gid
37 | assert_equal 'Dodgers', @game.home_team.name
38 | end
39 |
40 | def test_load_game_for_team_on_date
41 | dodgers = @api.team('Dodgers')
42 |
43 | games = @api.find_games(team: dodgers, date: Date.parse('2014-05-28'))
44 |
45 | assert_equal 1, games.count
46 | end
47 |
48 | def test_game_has_two_teams
49 | assert_equal 2, @game.teams.count
50 | end
51 |
52 | def test_correct_venue
53 | assert_equal 'Dodger Stadium', @game.venue
54 | end
55 |
56 | def test_home_start_time
57 | assert_equal '7:10 PM PT', @game.home_start_time
58 | end
59 |
60 | def test_away_start_time
61 | assert_equal '10:10 PM ET', @game.away_start_time
62 | end
63 |
64 | def test_home_starting_pitcher
65 | assert_equal 'Clayton Kershaw', @game.home_pitcher.name
66 | end
67 |
68 | def test_home_tv
69 | assert_equal 'SportsNet LA, SNLA Spanish', @game.home_tv
70 | end
71 |
72 | def test_away_radio
73 | assert_equal 'WLW 700, Reds Radio Network', @game.away_radio
74 | end
75 |
76 | def test_free_game_1
77 | refute @game.free?
78 | end
79 |
80 | def test_free_game_2
81 | skip 'Free game not yet loaded.'
82 |
83 | assert @free_game.free?
84 | end
85 |
86 | def test_game_attendance
87 | assert_equal '41,129', @game.attendance
88 | end
89 |
90 | def test_game_elapsed_time
91 | assert_equal '3:08', @game.elapsed_time
92 | end
93 |
94 | def test_game_weather
95 | assert_equal '71 degrees, partly cloudy', @game.weather
96 | end
97 |
98 | def test_game_wind
99 | assert_equal '8 mph, Out to CF', @game.wind
100 | end
101 |
102 | def test_game_umpires
103 | assert_equal(
104 | {
105 | 'HP' => 'Phil Cuzzi',
106 | '1B' => 'Gerry Davis',
107 | '2B' => 'Quinn Wolcott',
108 | '3B' => 'Greg Gibson'
109 | },
110 | @game.umpires
111 | )
112 | end
113 | end
114 |
--------------------------------------------------------------------------------
/test/api_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'minitest/autorun'
4 | require 'mlb_gameday.rb'
5 |
6 | class TestApi < MiniTest::Test
7 | def setup
8 | @api = MLBGameday::API.new
9 | end
10 |
11 | def test_api_created
12 | refute_nil @api
13 | end
14 |
15 | def test_league_count
16 | assert_equal 2, @api.leagues.count
17 | end
18 |
19 | def test_division_count
20 | assert_equal 6, @api.divisions.count
21 | end
22 |
23 | def test_team_count
24 | assert_equal 32, @api.teams.count
25 | end
26 |
27 | def test_initial_search
28 | assert_equal 'Los Angeles', @api.team('LAD').city
29 | end
30 |
31 | def test_name_search
32 | assert_equal 'Los Angeles', @api.team('Dodgers').city
33 | end
34 |
35 | def test_name_search_for_nonexistent_returns_nil
36 | assert_nil @api.team('Senators')
37 | end
38 |
39 | def test_division_team_count
40 | assert_equal 5, @api.team('Dodgers').division.teams.count
41 | end
42 |
43 | def test_astros_in_al_west
44 | assert_equal 'American', @api.team('Astros').league.name
45 | assert_equal 'West', @api.team('Astros').division.name
46 | end
47 |
48 | def test_names_includes_code
49 | @api.teams.each do |team|
50 | assert_includes team.names, team.code.downcase
51 | end
52 | end
53 |
54 | def test_names_includes_name
55 | @api.teams.each do |team|
56 | assert_includes team.names, team.name.downcase
57 | end
58 | end
59 |
60 | def test_names_includes_alt_names
61 | @api.teams.each do |team|
62 | team.send(:alt_names).each do |alt_name|
63 | assert_includes team.names, alt_name.downcase
64 | end
65 | end
66 | end
67 |
68 | def test_names_include_singular_name_when_different_from_name
69 | @api.teams
70 | .reject { |team| team.name == team.send(:singular_name) }
71 | .each do |team|
72 | assert_includes team.names, team.send(:singular_name).downcase
73 | end
74 | end
75 |
76 | def test_names_includes_despaced_name_when_name_is_multi_word
77 | @api.teams
78 | .select { |team| team.name.split.size > 1 }
79 | .each do |team|
80 | assert_includes team.names, team.send(:despaced_name).downcase
81 | end
82 | end
83 |
84 | def test_names_includes_city_except_nyc_and_chicago
85 | @api.teams
86 | .reject { |team| ['New York', 'Chicago'].include?(team.city) }
87 | .each do |team|
88 | assert_includes team.names, team.city.downcase
89 | end
90 | end
91 |
92 | def test_names_does_not_include_city_for_nyc_and_chicago
93 | @api.teams
94 | .select { |team| ['New York', 'Chicago'].include?(team.city) }
95 | .each do |team|
96 | refute_includes team.names, team.city.downcase
97 | end
98 | end
99 |
100 | def test_no_teams_share_any_names
101 | @api.teams.each do |team|
102 | @api.teams.reject { |t| t == team }.each do |other_team|
103 | assert_equal (team.names - other_team.names), team.names
104 | end
105 | end
106 | end
107 |
108 | def test_all_star_teams
109 | assert_equal 2, @api.teams.select { |t| t.name['All Stars'] }.length
110 | end
111 | end
112 |
--------------------------------------------------------------------------------
/lib/mlb_gameday.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'httparty'
4 | require 'nokogiri'
5 | require 'open-uri'
6 | require 'psych'
7 | require 'chronic'
8 |
9 | %w[version league division team game player pitcher batter].each do |file|
10 | require "mlb_gameday/#{file}"
11 | end
12 |
13 | module MLBGameday
14 | API_URL = 'http://gdx.mlb.com/components/game/mlb'
15 |
16 | BATTER = '/year_%d/batters/%d'
17 | PITCHER = '/year_%d/pitchers/%d'
18 | GAME_FOLDER = '/year_%d/month_%02d/day_%02d/gid_%s'
19 | SCOREBOARD = '/year_%Y/month_%m/day_%d/miniscoreboard'
20 |
21 | class API
22 | attr_reader :leagues
23 |
24 | def initialize
25 | @data = Psych.load File.open File.join(
26 | File.dirname(File.expand_path(__FILE__)), '../resources/data.yml'
27 | )
28 |
29 | @leagues = @data[:leagues]
30 | end
31 |
32 | def league(name)
33 | return name if name.is_a? MLBGameday::League
34 |
35 | @leagues[name]
36 | end
37 |
38 | def team(name)
39 | return name if name.is_a? MLBGameday::Team
40 |
41 | teams.find { |team| team.called?(name) }
42 | end
43 |
44 | def teams
45 | @teams ||= divisions.map(&:teams).map(&:values).flatten +
46 | miscellaneous_teams
47 | end
48 |
49 | def miscellaneous_teams
50 | @data[:miscellaneous_teams].values
51 | end
52 |
53 | def division(league, name)
54 | @leagues[league][name]
55 | end
56 |
57 | def divisions
58 | @divisions ||= @leagues[:AL].divisions.values +
59 | @leagues[:NL].divisions.values
60 | end
61 |
62 | def pitcher(id, year: nil, gid: nil)
63 | return if id.empty?
64 |
65 | MLBGameday::Pitcher.new id: id, xml: pitcher_xml(id, year: year, gid: gid)
66 | end
67 |
68 | def batter(id, year: nil, gid: nil)
69 | return if id.empty?
70 |
71 | MLBGameday::Batter.new id: id, xml: batter_xml(id, year: year, gid: gid)
72 | end
73 |
74 | def game(gid)
75 | MLBGameday::Game.new(
76 | self,
77 | gid,
78 | gamecenter: gamecenter_xml(gid),
79 | linescore: linescore_xml(gid),
80 | rawboxscore: rawboxscore_xml(gid)
81 | )
82 | end
83 |
84 | def find_games(team: nil, date: nil)
85 | doc = scoreboard_xml(date || Date.today)
86 |
87 | if team
88 | code = team(team).code
89 |
90 | doc.xpath('//games/game').map do |game|
91 | next unless [game.xpath('@home_name_abbrev').text,
92 | game.xpath('@away_name_abbrev').text].include? code
93 |
94 | game game.xpath('@gameday_link').text
95 | end.compact!
96 | else
97 | doc.xpath('//games/game').map do |game|
98 | game game.xpath('@gameday_link').to_s
99 | end
100 | end
101 | end
102 |
103 | def scoreboard_xml(date)
104 | fetch_xml date.strftime SCOREBOARD
105 | end
106 |
107 | def linescore_xml(gid)
108 | fetch_xml "#{GAME_FOLDER}/linescore", gid: gid
109 | end
110 |
111 | def rawboxscore_xml(gid)
112 | fetch_xml "#{GAME_FOLDER}/rawboxscore", gid: gid
113 | end
114 |
115 | def gamecenter_xml(gid)
116 | fetch_xml "#{GAME_FOLDER}/gamecenter", gid: gid
117 | end
118 |
119 | def batter_xml(id, year: nil, gid: nil)
120 | # We only really want one piece of data from this file. This gives us
121 | # the GID of their most recent appearance.
122 | gid ||= fetch_xml(BATTER, id: id, year: (year || Date.today.year))
123 | .xpath('//batting/@game_id').text.gsub(/[^a-z0-9]/, '_')
124 |
125 | fetch_xml "#{GAME_FOLDER}/batters/%s", gid: gid, batter: id
126 | end
127 |
128 | def pitcher_xml(id, year: nil, gid: nil)
129 | # We only really want one piece of data from this file. This gives us
130 | # the GID of their most recent appearance.
131 | gid ||= fetch_xml(PITCHER, id: id, year: (year || Date.today.year))
132 | .xpath('//pitching/@game_id').text.gsub(/[^a-z0-9]/, '_')
133 |
134 | fetch_xml "#{GAME_FOLDER}/pitchers/%s", gid: gid, pitcher: id
135 | end
136 |
137 | protected
138 |
139 | def fetch_xml(path, interpolations = {})
140 | full_path = "#{API_URL}#{path}.xml"
141 |
142 | if interpolations[:gid]
143 | year, month, day, = interpolations[:gid].split '_'
144 |
145 | interpolations[:year] = year
146 | interpolations[:month] = month
147 | interpolations[:day] = day
148 | end
149 |
150 | full_path = format(full_path, interpolations) if interpolations.any?
151 |
152 | Nokogiri::XML open full_path
153 | rescue
154 | nil
155 | end
156 | end
157 | end
158 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/linescore.xml:
--------------------------------------------------------------------------------
1 |
2 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
103 |
112 |
122 |
123 |
130 |
131 |
132 |
133 |
--------------------------------------------------------------------------------
/test/year_2014/month_05/day_28/gid_2014_05_28_cinmlb_lanmlb_1/gamecenter.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Dodger Stadium
4 | Dodger Stadium
5 |
6 |
7 |
8 | SportsNet LA, SNLA Spanish
9 | 570 Fox Sports L.A. , KTNQ 1020
10 |
11 |
12 | FS-O
13 | WLW 700, Reds Radio Network
14 |
15 |
16 |
17 |
18 |
19 | 477132
20 | Clayton
21 | Kershaw
22 | Kershaw
23 | 22
24 | LHP
25 | 3
26 | 1
27 | 3.49
28 | 37
29 | 3
30 | 1
31 | 3.49
32 | 37
33 |
34 | Kershaw's RBI groundout
35 |
36 |
37 |
38 |
39 |
40 | 456701
41 | Homer
42 | Bailey
43 | Bailey, H
44 | 34
45 | RHP
46 | 4
47 | 3
48 | 5.34
49 | 50
50 | 4
51 | 3
52 | 5.34
53 | 50
54 |
55 | Bailey on career-high 12 K's
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 | http://mediadownloads.mlb.com/mlbam/2014/05/29/images/mlbf_33264035_th_7.jpg
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 | /assets/images/1/1/0/77312110/cuts/Homer_Bailey_spzhqcru_xq76bdsx.jpg
92 | /assets/images/1/1/0/77312110/cuts/Homer_Bailey_spzhqcru_xq76bdsx@2x.jpg
93 | /assets/images/1/1/0/77312110/cuts/Homer_Bailey_spzhqcru_v5y2ik4u.jpg
94 | /assets/images/1/1/0/77312110/cuts/Homer_Bailey_spzhqcru_v5y2ik4u@2x.jpg
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 | 00:02:10
105 |
106 | http://mediadownloads.mlb.com/mlbam/2014/05/29/mlbtv_cinlan_33264035_300K.mp4
107 | http://mediadownloads.mlb.com/mlbam/2014/05/29/mlbtv_cinlan_33264035_600K.mp4
108 | http://mediadownloads.mlb.com/mlbam/2014/05/29/mlbtv_cinlan_33264035_1200K.mp4
109 | http://mediadownloads.mlb.com/mlbam/2014/05/29/mlbtv_cinlan_33264035_1800K.mp4
110 | http://mediadownloads.mlb.com/mlbam/2014/05/29/33264035_m3u8/master_mobile.m3u8
111 | http://mediadownloads.mlb.com/mlbam/2014/05/29/33264035_m3u8/master_tablet.m3u8
112 | http://mediadownloads.mlb.com/mlbam/2014/05/29/33264035_m3u8/master_android_tablet.m3u8
113 | http://mediadownloads.mlb.com/mlbam/2014/05/29/images/mlbf_33264035_th_7.jpg
114 |
115 |
--------------------------------------------------------------------------------
/lib/mlb_gameday/game.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module MLBGameday
4 | # This class is just too long. It might be able to be split up, but it's not
5 | # likely to happen any time soon. For now, we'll disable the cop.
6 | # rubocop:disable Metrics/ClassLength
7 | class Game
8 | attr_reader :gid, :home_team, :away_team, :files
9 |
10 | def initialize(api, gid, files = {})
11 | @api = api
12 | @gid = gid
13 | @files = files
14 |
15 | @home_team = @api.team home_team_identifier
16 | @away_team = @api.team away_team_identifier
17 | end
18 |
19 | def teams
20 | [@home_team, @away_team]
21 | end
22 |
23 | def venue
24 | if @files[:linescore]
25 | return @files[:linescore].xpath('//game/@venue').text
26 | end
27 |
28 | files[:gamecenter].xpath('//game/venueShort').text
29 | end
30 |
31 | def home_start_time(ampm: true)
32 | if ampm
33 | [
34 | @files[:linescore].xpath('//game/@home_time').text,
35 | @files[:linescore].xpath('//game/@home_ampm').text,
36 | @files[:linescore].xpath('//game/@home_time_zone').text
37 | ].join ' '
38 | else
39 | [
40 | @files[:linescore].xpath('//game/@home_time').text,
41 | @files[:linescore].xpath('//game/@home_time_zone').text
42 | ].join ' '
43 | end
44 | end
45 |
46 | def away_start_time(ampm: true)
47 | if ampm
48 | [
49 | @files[:linescore].xpath('//game/@away_time').text,
50 | @files[:linescore].xpath('//game/@away_ampm').text,
51 | @files[:linescore].xpath('//game/@away_time_zone').text
52 | ].join ' '
53 | else
54 | [
55 | @files[:linescore].xpath('//game/@away_time').text,
56 | @files[:linescore].xpath('//game/@away_time_zone').text
57 | ].join ' '
58 | end
59 | end
60 |
61 | # Preview, Pre-Game, In Progress, Final
62 | def status
63 | return 'Preview' unless @files[:linescore]
64 |
65 | @status ||= @files[:linescore].xpath('//game/@status').text
66 | end
67 |
68 | # [3, Top/Middle/Bottom/End]
69 | def inning
70 | return [0, '?'] unless @files[:linescore]&.xpath('//game/@inning')
71 |
72 | [
73 | @files[:linescore].xpath('//game/@inning').text.to_i,
74 | @files[:linescore].xpath('//game/@inning_state').text
75 | ]
76 | end
77 |
78 | def runners
79 | first = nil
80 | second = nil
81 | third = nil
82 |
83 | [first, second, third]
84 | end
85 |
86 | def over?
87 | ['Final', 'Game Over', 'Completed Early'].include? status
88 | end
89 | alias fat_lady_has_sung? over?
90 |
91 | def in_progress?
92 | status == 'In Progress'
93 | end
94 |
95 | def started?
96 | over? || in_progress?
97 | end
98 |
99 | def postponed?
100 | status == 'Postponed'
101 | end
102 |
103 | def home_record
104 | return [0, 0] unless @files[:linescore]
105 |
106 | [
107 | @files[:linescore].xpath('//game/@home_win'),
108 | @files[:linescore].xpath('//game/@home_loss')
109 | ].map(&:text).map(&:to_i)
110 | end
111 |
112 | def away_record
113 | return [0, 0] unless @files[:linescore]
114 |
115 | [
116 | @files[:linescore].xpath('//game/@away_win'),
117 | @files[:linescore].xpath('//game/@away_loss')
118 | ].map(&:text).map(&:to_i)
119 | end
120 |
121 | def current_pitcher
122 | return nil unless in_progress?
123 |
124 | @api.pitcher @files[:linescore].xpath('//game/current_pitcher/@id').text,
125 | year: date.year
126 | end
127 |
128 | def opposing_pitcher
129 | return nil unless in_progress?
130 |
131 | @api.pitcher @files[:linescore].xpath('//game/opposing_pitcher/@id').text,
132 | year: date.year
133 | end
134 |
135 | def winning_pitcher
136 | return nil unless over?
137 |
138 | @api.pitcher @files[:linescore].xpath('//game/winning_pitcher/@id').text,
139 | year: date.year,
140 | gid: @gid
141 | end
142 |
143 | def losing_pitcher
144 | return nil unless over?
145 |
146 | @api.pitcher @files[:linescore].xpath('//game/losing_pitcher/@id').text,
147 | year: date.year,
148 | gid: @gid
149 | end
150 |
151 | def save_pitcher
152 | return nil unless over?
153 |
154 | @api.pitcher @files[:linescore].xpath('//game/save_pitcher/@id').text,
155 | year: date.year,
156 | gid: @gid
157 | end
158 |
159 | def away_starting_pitcher
160 | return '' unless @files[:linescore]
161 |
162 | @files[:linescore].xpath('//game/away_probable_pitcher/@id').text
163 | end
164 |
165 | def home_starting_pitcher
166 | return '' unless @files[:linescore]
167 |
168 | @files[:linescore].xpath('//game/home_probable_pitcher/@id').text
169 | end
170 |
171 | def score
172 | return [0, 0] unless in_progress? || over?
173 |
174 | [
175 | @files[:linescore].xpath('//game/@home_team_runs').text,
176 | @files[:linescore].xpath('//game/@away_team_runs').text
177 | ].map(&:to_i)
178 | end
179 |
180 | def home_pitcher
181 | # Spring training games can end in ties, in which case there's
182 | # really no pitching data. This should really return a null object.
183 | case status
184 | when 'In Progress'
185 | # The xpath changes based on which half of the inning it is
186 | if @files[:linescore].xpath('//game/@top_inning').text == 'Y'
187 | opposing_pitcher
188 | else
189 | current_pitcher
190 | end
191 | when 'Preview', 'Warmup', 'Pre-Game'
192 | @api.pitcher home_starting_pitcher
193 | when 'Final'
194 | home, away = score
195 |
196 | home > away ? winning_pitcher : losing_pitcher
197 | end
198 | end
199 |
200 | def away_pitcher
201 | # Spring training games can end in ties, in which case there's
202 | # really no pitching data. This should really return a null object.
203 | case status
204 | when 'In Progress'
205 | # The xpath changes based on which half of the inning it is
206 | if @files[:linescore].xpath('//game/@top_inning').text == 'Y'
207 | current_pitcher
208 | else
209 | opposing_pitcher
210 | end
211 | when 'Preview', 'Warmup', 'Pre-Game'
212 | @api.pitcher away_starting_pitcher
213 | when 'Final', 'Game Over'
214 | home, away = score
215 |
216 | home > away ? losing_pitcher : winning_pitcher
217 | end
218 | end
219 |
220 | def home_tv
221 | return nil unless files[:gamecenter]
222 |
223 | files[:gamecenter].xpath('//game/broadcast/home/tv').text
224 | end
225 |
226 | def away_tv
227 | return nil unless files[:gamecenter]
228 |
229 | files[:gamecenter].xpath('//game/broadcast/away/tv').text
230 | end
231 |
232 | def home_radio
233 | return nil unless files[:gamecenter]
234 |
235 | files[:gamecenter].xpath('//game/broadcast/home/radio').text
236 | end
237 |
238 | def away_radio
239 | return nil unless files[:gamecenter]
240 |
241 | files[:gamecenter].xpath('//game/broadcast/away/radio').text
242 | end
243 |
244 | def free?
245 | return false unless @files[:linescore]
246 |
247 | @files[:linescore].xpath('//game/game_media/media/@free').text == 'ALL'
248 | end
249 |
250 | def date
251 | return Date.today unless @files[:linescore] # SUPER KLUDGE
252 |
253 | @date ||= Chronic.parse(
254 | @files[:linescore].xpath('//game/@original_date').text
255 | )
256 | end
257 |
258 | def attendance
259 | @files[:rawboxscore]&.xpath('//boxscore/@attendance')&.text || '0'
260 | end
261 |
262 | def elapsed_time
263 | @files[:rawboxscore]&.xpath('//boxscore/@elapsed_time')&.text || ''
264 | end
265 |
266 | def weather
267 | @files[:rawboxscore]&.xpath('//boxscore/@weather')&.text || ''
268 | end
269 |
270 | def wind
271 | @files[:rawboxscore]&.xpath('//boxscore/@wind')&.text || ''
272 | end
273 |
274 | def umpires
275 | return [] unless @files[:rawboxscore]
276 |
277 | umps = {}
278 |
279 | @files[:rawboxscore].xpath('//boxscore/umpires/umpire').each do |umpire|
280 | umps[umpire.xpath('@position').text] = umpire.xpath('@name').text
281 | end
282 |
283 | umps
284 | end
285 |
286 | # So we don't get huge printouts
287 | def inspect
288 | %(#)
289 | end
290 |
291 | protected
292 |
293 | def home_team_identifier
294 | if files[:linescore]
295 | return files[:linescore].xpath('//game/@home_name_abbrev').text
296 | end
297 |
298 | files[:gamecenter].xpath('//game/@id').text[18, 6]
299 | end
300 |
301 | def away_team_identifier
302 | if files[:linescore]
303 | return files[:linescore].xpath('//game/@away_name_abbrev').text
304 | end
305 |
306 | files[:gamecenter].xpath('//game/@id').text[11, 6]
307 | end
308 | end
309 | # rubocop:enable Metrics/ClassLength
310 | end
311 |
--------------------------------------------------------------------------------
/resources/data.yml:
--------------------------------------------------------------------------------
1 | ---
2 | :leagues:
3 | :AL: &al !ruby/object:MLBGameday::League
4 | name: American
5 | divisions:
6 | :East: &aleast !ruby/object:MLBGameday::Division
7 | name: East
8 | league: *al
9 | id: 201
10 | teams:
11 | :BAL: !ruby/object:MLBGameday::Team
12 | name: Orioles
13 | city: Baltimore
14 | league: *al
15 | division: *aleast
16 | code: BAL
17 | file_code: bal
18 | id: 110
19 | alt_names: [balmlb]
20 | :BOS: !ruby/object:MLBGameday::Team
21 | name: Red Sox
22 | city: Boston
23 | league: *al
24 | division: *aleast
25 | code: BOS
26 | file_code: bos
27 | id: 111
28 | alt_names: [bosox, bosmlb]
29 | :NYY: !ruby/object:MLBGameday::Team
30 | name: Yankees
31 | city: New York
32 | league: *al
33 | division: *aleast
34 | code: NYY
35 | file_code: nyy
36 | id: 147
37 | alt_names:
38 | - new york yankee
39 | - nyamlb
40 | :TB: !ruby/object:MLBGameday::Team
41 | name: Rays
42 | city: Tampa Bay
43 | league: *al
44 | division: *aleast
45 | code: TB
46 | file_code: tb
47 | id: 139
48 | alt_names:
49 | - devil rays
50 | - devil ray
51 | - tampa
52 | - tbamlb
53 | :TOR: !ruby/object:MLBGameday::Team
54 | name: Blue Jays
55 | city: Toronto
56 | league: *al
57 | division: *aleast
58 | code: TOR
59 | file_code: tor
60 | id: 141
61 | alt_names:
62 | - bluejay
63 | - jays
64 | - jay
65 | - tormlb
66 | :Central: &alcentral !ruby/object:MLBGameday::Division
67 | name: Central
68 | league: *al
69 | id: 202
70 | teams:
71 | :CLE: !ruby/object:MLBGameday::Team
72 | name: Indians
73 | city: Cleveland
74 | league: *al
75 | division: *alcentral
76 | code: CLE
77 | file_code: cle
78 | id: 114
79 | :CWS: !ruby/object:MLBGameday::Team
80 | name: White Sox
81 | city: Chicago
82 | league: *al
83 | division: *alcentral
84 | code: CWS
85 | file_code: cws
86 | id: 145
87 | :DET: !ruby/object:MLBGameday::Team
88 | name: Tigers
89 | city: Detroit
90 | league: *al
91 | division: *alcentral
92 | code: DET
93 | file_code: det
94 | id: 116
95 | :KC: !ruby/object:MLBGameday::Team
96 | name: Royals
97 | city: Kansas City
98 | league: *al
99 | division: *alcentral
100 | code: KC
101 | file_code: kc
102 | id: 118
103 | alt_names:
104 | - kansas
105 | :MIN: !ruby/object:MLBGameday::Team
106 | name: Twins
107 | city: Minnesota
108 | league: *al
109 | division: *alcentral
110 | code: MIN
111 | file_code: min
112 | id: 142
113 | :West: &alwest !ruby/object:MLBGameday::Division
114 | name: West
115 | league: *al
116 | id: 200
117 | teams:
118 | :LAA: !ruby/object:MLBGameday::Team
119 | name: Angels
120 | city: Anaheim
121 | league: *al
122 | division: *alwest
123 | code: LAA
124 | file_code: ana
125 | id: 108
126 | alt_names:
127 | - ana
128 | - los angeles angel
129 | - los angeles angels
130 | - la angels
131 | - la angel
132 | - laaa
133 | - los angeles angels of anaheim
134 | :HOU: !ruby/object:MLBGameday::Team
135 | name: Astros
136 | city: Houston
137 | league: *al
138 | division: *alwest
139 | code: HOU
140 | file_code: hou
141 | id: 117
142 | :OAK: !ruby/object:MLBGameday::Team
143 | name: Athletics
144 | city: Oakland
145 | league: *al
146 | division: *alwest
147 | code: OAK
148 | file_code: oak
149 | id: 133
150 | alt_names:
151 | - as
152 | :SEA: !ruby/object:MLBGameday::Team
153 | name: Mariners
154 | city: Seattle
155 | league: *al
156 | division: *alwest
157 | code: SEA
158 | file_code: sea
159 | id: 136
160 | :TEX: !ruby/object:MLBGameday::Team
161 | name: Rangers
162 | city: Texas
163 | league: *al
164 | division: *alwest
165 | code: TEX
166 | file_code: tex
167 | id: 140
168 | :NL: &nl !ruby/object:MLBGameday::League
169 | name: National
170 | divisions:
171 | :East: &nleast !ruby/object:MLBGameday::Division
172 | name: East
173 | league: *nl
174 | id: 204
175 | teams:
176 | :ATL: !ruby/object:MLBGameday::Team
177 | name: Braves
178 | city: Atlanta
179 | league: *nl
180 | division: *nleast
181 | code: ATL
182 | file_code: atl
183 | id: 144
184 | :MIA: !ruby/object:MLBGameday::Team
185 | name: Marlins
186 | city: Miami
187 | league: *nl
188 | division: *nleast
189 | code: MIA
190 | file_code: mia
191 | id: 146
192 | alt_names:
193 | - florida
194 | :NYM: !ruby/object:MLBGameday::Team
195 | name: Mets
196 | city: New York
197 | league: *nl
198 | division: *nleast
199 | code: NYM
200 | file_code: nym
201 | id: 121
202 | alt_names:
203 | - new york met
204 | :PHI: !ruby/object:MLBGameday::Team
205 | name: Phillies
206 | city: Philadelphia
207 | league: *nl
208 | division: *nleast
209 | code: PHI
210 | file_code: phi
211 | id: 143
212 | alt_names:
213 | - philly
214 | :WSH: !ruby/object:MLBGameday::Team
215 | name: Nationals
216 | city: Washington
217 | league: *nl
218 | division: *nleast
219 | code: WSH
220 | file_code: was
221 | id: 120
222 | alt_names:
223 | - natinals
224 | :Central: &nlcentral !ruby/object:MLBGameday::Division
225 | name: Central
226 | league: *nl
227 | id: 205
228 | teams:
229 | :CHC: !ruby/object:MLBGameday::Team
230 | name: Cubs
231 | city: Chicago
232 | league: *nl
233 | division: *nlcentral
234 | code: CHC
235 | file_code: chc
236 | id: 112
237 | alt_names:
238 | - chicago cub
239 | :CIN: !ruby/object:MLBGameday::Team
240 | name: Reds
241 | city: Cincinnati
242 | league: *nl
243 | division: *nlcentral
244 | code: CIN
245 | file_code: cin
246 | id: 113
247 | :MIL: !ruby/object:MLBGameday::Team
248 | name: Brewers
249 | city: Milwaukee
250 | league: *nl
251 | division: *nlcentral
252 | code: MIL
253 | file_code: mil
254 | id: 158
255 | :PIT: !ruby/object:MLBGameday::Team
256 | name: Pirates
257 | city: Pittsburgh
258 | league: *nl
259 | division: *nlcentral
260 | code: PIT
261 | file_code: pit
262 | id: 134
263 | alt_names:
264 | - buccos
265 | - bucco
266 | :STL: !ruby/object:MLBGameday::Team
267 | name: Cardinals
268 | city: St. Louis
269 | league: *nl
270 | division: *nlcentral
271 | code: STL
272 | file_code: stl
273 | id: 138
274 | alt_names:
275 | - st louis
276 | :West: &nlwest !ruby/object:MLBGameday::Division
277 | name: West
278 | league: *nl
279 | id: 203
280 | teams:
281 | :ARI: !ruby/object:MLBGameday::Team
282 | name: Diamondbacks
283 | city: Arizona
284 | league: *nl
285 | division: *nlwest
286 | code: ARI
287 | file_code: ari
288 | id: 109
289 | alt_names:
290 | - dbacks
291 | - dback
292 | - az
293 | - "d-backs"
294 | :COL: !ruby/object:MLBGameday::Team
295 | name: Rockies
296 | city: Colorado
297 | league: *nl
298 | division: *nlwest
299 | code: COL
300 | file_code: col
301 | id: 115
302 | :LAD: !ruby/object:MLBGameday::Team
303 | name: Dodgers
304 | city: Los Angeles
305 | league: *nl
306 | division: *nlwest
307 | code: LAD
308 | file_code: la
309 | id: 119
310 | alt_names:
311 | - la
312 | - los angeles dodgers
313 | - los angeles dodger
314 | - la dodger
315 | - la dodgers
316 | :SD: !ruby/object:MLBGameday::Team
317 | name: Padres
318 | city: San Diego
319 | league: *nl
320 | division: *nlwest
321 | code: SD
322 | file_code: sd
323 | id: 135
324 | :SF: !ruby/object:MLBGameday::Team
325 | name: Giants
326 | city: San Francisco
327 | league: *nl
328 | division: *nlwest
329 | code: SF
330 | file_code: sf
331 | id: 137
332 | alt_names:
333 | - san fran
334 | - gigantes
335 | :miscellaneous_teams:
336 | :AAS: !ruby/object:MLBGameday::Team
337 | name: AL All Stars
338 | city: AL
339 | code: AL
340 | file_code: aas
341 | :NAS: !ruby/object:MLBGameday::Team
342 | name: NL All Stars
343 | city: NL
344 | code: NL
345 | file_code: nas
346 |
--------------------------------------------------------------------------------