sports_data_api 0.0.3 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (124) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +7 -0
  3. data/.ruby-gemset +1 -0
  4. data/.ruby-version +1 -0
  5. data/.travis.yml +2 -1
  6. data/Guardfile +1 -1
  7. data/README.md +20 -5
  8. data/lib/sports_data_api/exception.rb +5 -0
  9. data/lib/sports_data_api/mlb/boxscore.rb +36 -0
  10. data/lib/sports_data_api/mlb/broadcast.rb +14 -0
  11. data/lib/sports_data_api/mlb/game.rb +30 -0
  12. data/lib/sports_data_api/mlb/game_stat.rb +26 -0
  13. data/lib/sports_data_api/mlb/game_stats.rb +44 -0
  14. data/lib/sports_data_api/mlb/games.rb +29 -0
  15. data/lib/sports_data_api/mlb/player.rb +17 -0
  16. data/lib/sports_data_api/mlb/players.rb +42 -0
  17. data/lib/sports_data_api/mlb/season.rb +18 -0
  18. data/lib/sports_data_api/mlb/team.rb +35 -0
  19. data/lib/sports_data_api/mlb/teams.rb +42 -0
  20. data/lib/sports_data_api/mlb/venue.rb +15 -0
  21. data/lib/sports_data_api/mlb/venues.rb +37 -0
  22. data/lib/sports_data_api/mlb.rb +82 -0
  23. data/lib/sports_data_api/nba/broadcast.rb +14 -0
  24. data/lib/sports_data_api/nba/game.rb +54 -0
  25. data/lib/sports_data_api/nba/games.rb +26 -0
  26. data/lib/sports_data_api/nba/player.rb +22 -0
  27. data/lib/sports_data_api/nba/season.rb +28 -0
  28. data/lib/sports_data_api/nba/team.rb +40 -0
  29. data/lib/sports_data_api/nba/teams.rb +83 -0
  30. data/lib/sports_data_api/nba/venue.rb +20 -0
  31. data/lib/sports_data_api/nba.rb +71 -0
  32. data/lib/sports_data_api/nfl/broadcast.rb +15 -0
  33. data/lib/sports_data_api/nfl/game.rb +83 -0
  34. data/lib/sports_data_api/nfl/games.rb +29 -0
  35. data/lib/sports_data_api/nfl/injuries.rb +9 -0
  36. data/lib/sports_data_api/nfl/player.rb +15 -0
  37. data/lib/sports_data_api/nfl/player_season_stats.rb +26 -0
  38. data/lib/sports_data_api/nfl/season.rb +27 -0
  39. data/lib/sports_data_api/nfl/team.rb +46 -0
  40. data/lib/sports_data_api/nfl/team_roster.rb +17 -0
  41. data/lib/sports_data_api/nfl/team_season_stats.rb +19 -0
  42. data/lib/sports_data_api/nfl/teams.rb +84 -0
  43. data/lib/sports_data_api/nfl/venue.rb +22 -0
  44. data/lib/sports_data_api/nfl/weather.rb +17 -0
  45. data/lib/sports_data_api/nfl/week.rb +20 -0
  46. data/lib/sports_data_api/nfl.rb +98 -0
  47. data/lib/sports_data_api/stats.rb +13 -0
  48. data/lib/sports_data_api/version.rb +1 -1
  49. data/lib/sports_data_api.rb +37 -12
  50. data/spec/cassettes/sports_data_api_mlb_game.yml +20193 -0
  51. data/spec/cassettes/sports_data_api_mlb_game_boxscore.yml +225 -0
  52. data/spec/cassettes/sports_data_api_mlb_game_stats.yml +657 -0
  53. data/spec/cassettes/sports_data_api_mlb_games.yml +195 -0
  54. data/spec/cassettes/sports_data_api_mlb_player.yml +10891 -0
  55. data/spec/cassettes/sports_data_api_mlb_season.yml +20193 -0
  56. data/spec/cassettes/sports_data_api_mlb_team.yml +182 -0
  57. data/spec/cassettes/sports_data_api_mlb_team_roster.yml +10891 -0
  58. data/spec/cassettes/sports_data_api_mlb_teams.yml +403 -0
  59. data/spec/cassettes/sports_data_api_mlb_venues.yml +343 -0
  60. data/spec/cassettes/sports_data_api_nba.yml +74176 -0
  61. data/spec/cassettes/sports_data_api_nba_broadcast.yml +88 -0
  62. data/spec/cassettes/sports_data_api_nba_game.yml +21202 -0
  63. data/spec/cassettes/sports_data_api_nba_games.yml +128 -0
  64. data/spec/cassettes/sports_data_api_nba_league_hierarchy.yml +545 -0
  65. data/spec/cassettes/sports_data_api_nba_player.yml +244 -0
  66. data/spec/cassettes/sports_data_api_nba_season.yml +18228 -0
  67. data/spec/cassettes/sports_data_api_nba_team.yml +1398 -0
  68. data/spec/cassettes/sports_data_api_nba_team_roster.yml +244 -0
  69. data/spec/cassettes/sports_data_api_nba_venue.yml +88 -0
  70. data/spec/cassettes/sports_data_api_nfl.yml +19105 -0
  71. data/spec/cassettes/sports_data_api_nfl_broadcast.yml +112 -0
  72. data/spec/cassettes/sports_data_api_nfl_game.yml +16139 -0
  73. data/spec/cassettes/sports_data_api_nfl_games.yml +912 -0
  74. data/spec/cassettes/sports_data_api_nfl_player_season_stats.yml +997 -0
  75. data/spec/cassettes/sports_data_api_nfl_season.yml +14100 -0
  76. data/spec/cassettes/sports_data_api_nfl_team.yml +783 -0
  77. data/spec/cassettes/sports_data_api_nfl_team_hierarchy.yml +909 -0
  78. data/spec/cassettes/sports_data_api_nfl_team_roster.yml +618 -0
  79. data/spec/cassettes/sports_data_api_nfl_team_season_stats.yml +981 -0
  80. data/spec/cassettes/sports_data_api_nfl_venue.yml +112 -0
  81. data/spec/cassettes/sports_data_api_nfl_weather.yml +112 -0
  82. data/spec/cassettes/sports_data_api_nfl_week.yml +14100 -0
  83. data/spec/lib/sports_data_api/mlb/boxscore_spec.rb +63 -0
  84. data/spec/lib/sports_data_api/mlb/game_spec.rb +24 -0
  85. data/spec/lib/sports_data_api/mlb/game_stats_spec.rb +25 -0
  86. data/spec/lib/sports_data_api/mlb/games_spec.rb +24 -0
  87. data/spec/lib/sports_data_api/mlb/player_spec.rb +103 -0
  88. data/spec/lib/sports_data_api/mlb/players_spec.rb +17 -0
  89. data/spec/lib/sports_data_api/mlb/season_spec.rb +19 -0
  90. data/spec/lib/sports_data_api/mlb/team_spec.rb +24 -0
  91. data/spec/lib/sports_data_api/mlb/teams_spec.rb +30 -0
  92. data/spec/lib/sports_data_api/mlb/venues_spec.rb +17 -0
  93. data/spec/lib/sports_data_api/nba/broadcast_spec.rb +18 -0
  94. data/spec/lib/sports_data_api/nba/game_spec.rb +87 -0
  95. data/spec/lib/sports_data_api/nba/games_spec.rb +19 -0
  96. data/spec/lib/sports_data_api/nba/player_spec.rb +72 -0
  97. data/spec/lib/sports_data_api/nba/season_spec.rb +41 -0
  98. data/spec/lib/sports_data_api/nba/team_spec.rb +185 -0
  99. data/spec/lib/sports_data_api/nba/teams_spec.rb +76 -0
  100. data/spec/lib/sports_data_api/nba/venue_spec.rb +24 -0
  101. data/spec/lib/sports_data_api/nba_spec.rb +41 -0
  102. data/spec/lib/sports_data_api/nfl/broadcast_spec.rb +19 -0
  103. data/spec/lib/sports_data_api/nfl/game_spec.rb +126 -0
  104. data/spec/lib/sports_data_api/nfl/games_spec.rb +21 -0
  105. data/spec/lib/sports_data_api/nfl/player_season_stats.rb +28 -0
  106. data/spec/lib/sports_data_api/nfl/season_spec.rb +41 -0
  107. data/spec/lib/sports_data_api/nfl/team_roster_spec.rb +28 -0
  108. data/spec/lib/sports_data_api/nfl/team_season_stats.rb +19 -0
  109. data/spec/lib/sports_data_api/nfl/team_spec.rb +52 -0
  110. data/spec/lib/sports_data_api/nfl/teams_spec.rb +77 -0
  111. data/spec/lib/sports_data_api/nfl/venue_spec.rb +26 -0
  112. data/spec/lib/sports_data_api/nfl/weather_spec.rb +21 -0
  113. data/spec/lib/sports_data_api/nfl/week_spec.rb +21 -0
  114. data/spec/lib/sports_data_api/nfl_spec.rb +113 -0
  115. data/spec/lib/sports_data_api_spec.rb +8 -5
  116. data/spec/spec_helper.rb +30 -9
  117. data/sports_data_api.gemspec +19 -15
  118. metadata +267 -76
  119. data/.rvmrc +0 -38
  120. data/lib/nfl.rb +0 -149
  121. data/spec/lib/nfl_spec.rb +0 -125
  122. data/spec/xml/boxscore.xml +0 -93
  123. data/spec/xml/schedule.xml +0 -4067
  124. data/spec/xml/teams.xml +0 -119
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4d8be1761997f03cc4d7aa1b666c29982fbbb2e2
4
+ data.tar.gz: ae0d4e0bee91e4549235ad79c196fccead66a429
5
+ SHA512:
6
+ metadata.gz: 1bfc851b3033f99db197871765983dc185aeddba7636e284efb150c3eb3af6eeb83b5000b08a57e3d4bbde38abeec0b3195029646ceced18fd3d307226240d04
7
+ data.tar.gz: 255550917ad90c562706c64d36d9a01344ce37657db4afeb41e6e30ca045947bd620ef12e625872dcd70512ca0465b573b83f13a25fb9a7cddab31444d2433af
data/.gitignore CHANGED
@@ -16,6 +16,10 @@ test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
18
 
19
+ # RVM
20
+ .rvmrc
21
+ .ruby-gemset
22
+
19
23
  # YARD artifacts
20
24
  .yardoc
21
25
  _yardoc
@@ -23,3 +27,6 @@ doc/
23
27
 
24
28
  # OSX artifacts
25
29
  .DS_Store
30
+
31
+ # RubyMine
32
+ .idea/
data/.ruby-gemset ADDED
@@ -0,0 +1 @@
1
+ sports_data_api
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ ruby-2.1.2
data/.travis.yml CHANGED
@@ -1,4 +1,5 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 1.9.2
4
3
  - 1.9.3
4
+ - 2.0.0
5
+ - 2.1.0
data/Guardfile CHANGED
@@ -1,7 +1,7 @@
1
1
  # A sample Guardfile
2
2
  # More info at https://github.com/guard/guard#readme
3
3
 
4
- guard 'rspec' do
4
+ guard 'rspec', all_after_pass: true, keep_failed: false do
5
5
  watch(%r{^spec/.+_spec\.rb$})
6
6
  watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
7
7
  watch('spec/spec_helper.rb') { "spec" }
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # SportsDataApi [![Build Status](https://travis-ci.org/RLovelett/sports_data_api.png?branch=master)](https://travis-ci.org/RLovelett/sports_data_api)
1
+ # SportsDataApi [![Build Status](https://travis-ci.org/RLovelett/sports_data_api.png?branch=master)](https://travis-ci.org/RLovelett/sports_data_api) [![Coverage Status](https://coveralls.io/repos/RLovelett/sports_data_api/badge.png?branch=master)](https://coveralls.io/r/RLovelett/sports_data_api?branch=master)
2
2
 
3
3
  SportsDataApi is an attempt to make a Ruby interface to the
4
4
  [SportsData](http://www.sportsdatallc.com/) API. The goal is to
@@ -21,12 +21,12 @@ log](https://github.com/rlovelett/sports_data_api/issues).
21
21
  ## API Support
22
22
 
23
23
  * [NFL](http://developer.sportsdatallc.com/docs/NFL_API)
24
+ * [NBA](http://developer.sportsdatallc.com/docs/NBA_API)
24
25
  * TODO
25
26
  1. [MLB](http://developer.sportsdatallc.com/docs/MLB_API)
26
27
  2. [NHL](http://developer.sportsdatallc.com/docs/NHL_API)
27
- 3. [NBA](http://developer.sportsdatallc.com/docs/NBA_API)
28
- 4. [NCAA Basketball](http://developer.sportsdatallc.com/docs/NCAA_Mens_Backetball)
29
- 5. [NCAA Football](http://developer.sportsdatallc.com/docs/NCAA_Football_API)
28
+ 3. [NCAA Basketball](http://developer.sportsdatallc.com/docs/NCAA_Mens_Basketball)
29
+ 4. [NCAA Football](http://developer.sportsdatallc.com/docs/NCAA_Football_API)
30
30
 
31
31
  ## Installation
32
32
 
@@ -46,7 +46,22 @@ Or install it yourself as:
46
46
 
47
47
  The specs for this Gem should give you some idea of how to make use of
48
48
  the API. For now they will be the usage information. As always Pull
49
- Requests for better documentation are always welcome.
49
+ Requests for better documentation are welcome.
50
+
51
+ ## Testing
52
+
53
+ The tests for the API have been mocked using [VCR](https://github.com/vcr/vcr) and [WebMock](https://github.com/bblimke/webmock).
54
+
55
+ Actual calls to the Sports Data LLC have been mocked out to prevent storage of valid API credentials and making
56
+ superflous API calls while testing. As such, in order to generically run the tests (without actually hitting)
57
+ the server the only thing that needs to be done is to run the specs (e.g., `bundle exec rake spec` or
58
+ `bundle exec guard start`).
59
+
60
+ However, if you want to refresh the actual server API responses you will need to re-record all of the VCR cassettes.
61
+ This can be achieved simply by performing the following two steps:
62
+
63
+ 1. Delete all the cassettes (`rm spec/cassettes/*.yml`)
64
+ 2. Run specs passing the API key as environment variable (`SPORTS_DATA_<NBA|NFL>_API_KEY=realapikey bundle exec rake spec`)
50
65
 
51
66
  ## Contributing
52
67
 
@@ -0,0 +1,5 @@
1
+ module SportsDataApi
2
+ class Exception < ::Exception
3
+ # To change this template use File | Settings | File Templates.
4
+ end
5
+ end
@@ -0,0 +1,36 @@
1
+ module SportsDataApi
2
+ module Mlb
3
+ class Boxscore
4
+ VALID_GAME_STATUSES = ['closed', 'inprogress']
5
+
6
+ def initialize(xml)
7
+ self.class.class_eval { attr_reader :"game_state" }
8
+
9
+ xml = xml.first if xml.is_a? Nokogiri::XML::NodeSet
10
+ return unless VALID_GAME_STATUSES.include? xml['status'].to_s.downcase
11
+
12
+ boxscore_ivar = self.instance_variable_set("@game_state", {})
13
+ visitor = xml.xpath("visitor").first
14
+ boxscore_ivar[:visitor_score] = visitor.attributes["runs"].value
15
+
16
+ home = xml.xpath("home").first
17
+ boxscore_ivar[:home_score] = home.attributes["runs"].value
18
+ boxscore_ivar[:status] = xml['status'].to_s.downcase
19
+ if xml['status'] == 'closed'
20
+ inning = xml.xpath('final').first
21
+ if inning
22
+ inning.attributes.each do | attr_name, attr_value|
23
+ boxscore_ivar[attr_name.to_sym] = attr_value.value
24
+ end
25
+ end
26
+ elsif xml['status'] == 'inprogress'
27
+ inning = xml.xpath('outcome').first
28
+ if inning
29
+ boxscore_ivar[:inning] = inning.attributes['current_inning'].value
30
+ boxscore_ivar[:inning_half] = inning.attributes['current_inning_half'].value
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,14 @@
1
+ module SportsDataApi
2
+ module Mlb
3
+ class Broadcast
4
+ attr_reader :network, :satellite
5
+ def initialize(xml)
6
+ xml = xml.first if xml.is_a? Nokogiri::XML::NodeSet
7
+ if xml.is_a? Nokogiri::XML::Element
8
+ @network = xml['network']
9
+ @satellite = xml['satellite']
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,30 @@
1
+ module SportsDataApi
2
+ module Mlb
3
+ class Game
4
+ attr_reader :id, :scheduled, :home, :home_team, :away,
5
+ :away_team, :status, :venue, :broadcast, :year, :season,
6
+ :date, :quarter, :clock, :rescheduled_reason, :rescheduled_from
7
+
8
+ def initialize(args={})
9
+ xml = args.fetch(:xml)
10
+ @year = args[:year] ? args[:year].to_i : nil
11
+
12
+ xml = xml.first if xml.is_a? Nokogiri::XML::NodeSet
13
+ if xml.is_a? Nokogiri::XML::Element
14
+ @id = xml['id']
15
+ @scheduled = Time.parse(xml.xpath('scheduled_start').children.first.to_s)
16
+ @home = xml['home']
17
+ @away = xml['visitor']
18
+ @status = xml['status']
19
+ @venue = xml['venue']
20
+ @broadcast = Broadcast.new(xml.xpath('broadcast'))
21
+ rescheduled_from = xml.xpath('rescheduled_from')
22
+ if rescheduled_from.count > 0
23
+ @rescheduled_reason = rescheduled_from.first['reason']
24
+ @rescheduled_from = Time.parse(rescheduled_from.first.children.first.to_s)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,26 @@
1
+ module SportsDataApi
2
+ module Mlb
3
+ class GameStat
4
+ attr_reader :player_id
5
+ def initialize(xml)
6
+ if xml.is_a? Nokogiri::XML::Element
7
+ stat_ivar = self.instance_variable_set("@#{xml.name}", {})
8
+ self.class.class_eval { attr_reader :"#{xml.name}" }
9
+
10
+ xml.attributes.each do | attr_name, attr_value|
11
+ stat_ivar[attr_name.to_sym] = attr_value.value
12
+ end
13
+
14
+ xml.xpath('.//*').each do |other_stat|
15
+ if other_stat.is_a? Nokogiri::XML::Element
16
+ stat_ivar[other_stat.name.to_sym] = {}
17
+ other_stat.attributes.each do | attr_name, attr_value|
18
+ stat_ivar[other_stat.name.to_sym][attr_name.to_sym] = attr_value.value
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,44 @@
1
+ module SportsDataApi
2
+ module Mlb
3
+ class GameStats
4
+ include Enumerable
5
+
6
+ def initialize(xml)
7
+ @stats = {}
8
+ @stats[:hitting] = []
9
+ @stats[:pitching] = []
10
+ xml = xml.first if xml.is_a? Nokogiri::XML::NodeSet
11
+ @stats[:status] = xml['status']
12
+ xml.children.each do |child|
13
+ next unless child.is_a? Nokogiri::XML::Element
14
+ child.xpath("hitting").xpath("players").xpath("player").each do |player|
15
+ @stats[:hitting] << GameStat.new(player)
16
+ end
17
+
18
+ child.xpath("pitching").xpath("players").xpath("player").each do |player|
19
+ @stats[:pitching] << GameStat.new(player)
20
+ end
21
+ end
22
+ @stats
23
+ end
24
+
25
+ def [](search_index)
26
+ if @stats.has_key?(search_index)
27
+ @stats[search_index]
28
+ end
29
+ end
30
+
31
+ ##
32
+ # Make the class Enumerable
33
+ def each(&block)
34
+ @stats.each do |stat|
35
+ if block_given?
36
+ block.call stat
37
+ else
38
+ yield stat
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,29 @@
1
+ module SportsDataApi
2
+ module Mlb
3
+ class Games
4
+ include Enumerable
5
+ attr_reader :games, :year
6
+
7
+ def initialize(xml)
8
+ xml = xml.first if xml.is_a? Nokogiri::XML::NodeSet
9
+ @year = xml['season_year']
10
+ @games = []
11
+ if xml.is_a? Nokogiri::XML::Element
12
+ xml.xpath('event').each do |event|
13
+ @games << Game.new(year: @year, xml: event)
14
+ end
15
+ end
16
+ end
17
+
18
+ def each &block
19
+ @games.each do |game|
20
+ if block_given?
21
+ block.call game
22
+ else
23
+ yield game
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,17 @@
1
+ module SportsDataApi
2
+ module Mlb
3
+ class Player
4
+ attr_reader :team_id
5
+ def initialize(xml, team_id)
6
+ if xml.is_a? Nokogiri::XML::Element
7
+ player_ivar = self.instance_variable_set("@#{xml.name}", {})
8
+ self.class.class_eval { attr_reader :"#{xml.name}" }
9
+ player_ivar[:team_id] = team_id
10
+ xml.attributes.each do | attr_name, attr_value|
11
+ player_ivar[attr_name.to_sym] = attr_value.value
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,42 @@
1
+ module SportsDataApi
2
+ module Mlb
3
+ class Players
4
+ include Enumerable
5
+
6
+ ##
7
+ # Initialize by passing the raw XML returned from the API
8
+ def initialize(xml)
9
+ @players = []
10
+ xml = xml.first if xml.is_a? Nokogiri::XML::NodeSet
11
+ if xml.is_a? Nokogiri::XML::Element
12
+ xml.xpath('team').each do |team|
13
+ team.xpath('players').xpath('player').each do |player|
14
+ p = Player.new(player, team['id'])
15
+ @players << p
16
+ end
17
+ end
18
+ end
19
+ @players
20
+ end
21
+
22
+ def [](search_index)
23
+ found_index = @teams.index(search_index)
24
+ unless found_index.nil?
25
+ @teams[found_index]
26
+ end
27
+ end
28
+
29
+ ##
30
+ # Make the class Enumerable
31
+ def each(&block)
32
+ @players.each do |player|
33
+ if block_given?
34
+ block.call player
35
+ else
36
+ yield player
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,18 @@
1
+ module SportsDataApi
2
+ module Mlb
3
+ class Season
4
+ attr_reader :year, :games
5
+
6
+ def initialize(xml)
7
+ xml = xml.first if xml.is_a? Nokogiri::XML::NodeSet
8
+ @year = xml['season_year']
9
+ @games = []
10
+ if xml.is_a? Nokogiri::XML::Element
11
+ xml.xpath('event').each do |event|
12
+ @games << Game.new(year: @year, xml: event)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,35 @@
1
+ module SportsDataApi
2
+ module Mlb
3
+ class Team
4
+ attr_reader :id, :name, :market, :alias, :league, :division
5
+
6
+ def initialize(xml)
7
+ xml = xml.first if xml.is_a? Nokogiri::XML::NodeSet
8
+ if xml.is_a? Nokogiri::XML::Element
9
+ @id = xml['id']
10
+ @name = xml['name']
11
+ @market = xml['market']
12
+ @alias = xml['abbr']
13
+ @league = xml['league']
14
+ @division = xml['division']
15
+ end
16
+ end
17
+
18
+ ##
19
+ # Compare the Team with another team
20
+ def ==(other)
21
+ # Must have an id to compare
22
+ return false if self.id.nil?
23
+
24
+ if other.is_a? SportsDataApi::Mlb::Team
25
+ return false if other.id.nil?
26
+ self.id === other.id
27
+ elsif other.is_a? Symbol
28
+ self.id.to_sym === other
29
+ else
30
+ super(other)
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,42 @@
1
+ module SportsDataApi
2
+ module Mlb
3
+ class Teams
4
+ include Enumerable
5
+
6
+ attr_reader :leagues, :divisions
7
+
8
+ ##
9
+ # Initialize by passing the raw XML returned from the API
10
+ def initialize(xml)
11
+ @teams = []
12
+ xml = xml.first if xml.is_a? Nokogiri::XML::NodeSet
13
+ if xml.is_a? Nokogiri::XML::Element
14
+ xml.xpath('//team').each do |team|
15
+ @teams << Team.new(team) if !team['league'].empty?
16
+ end
17
+ end
18
+
19
+ @teams
20
+ end
21
+
22
+ def [](search_index)
23
+ found_index = @teams.index(search_index)
24
+ unless found_index.nil?
25
+ @teams[found_index]
26
+ end
27
+ end
28
+
29
+ ##
30
+ # Make the class Enumerable
31
+ def each(&block)
32
+ @teams.each do |team|
33
+ if block_given?
34
+ block.call team
35
+ else
36
+ yield team
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,15 @@
1
+ module SportsDataApi
2
+ module Mlb
3
+ class Venue
4
+ def initialize(xml)
5
+ if xml.is_a? Nokogiri::XML::Element
6
+ venue_ivar = self.instance_variable_set("@#{xml.name}", {})
7
+ self.class.class_eval { attr_reader :"#{xml.name}" }
8
+ xml.attributes.each do | attr_name, attr_value|
9
+ venue_ivar[attr_name.to_sym] = attr_value.value
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,37 @@
1
+ module SportsDataApi
2
+ module Mlb
3
+ class Venues
4
+ include Enumerable
5
+
6
+ def initialize(xml)
7
+ @venues = []
8
+ xml = xml.first if xml.is_a? Nokogiri::XML::NodeSet
9
+ xml.children.each do |venue|
10
+ next unless venue.is_a? Nokogiri::XML::Element
11
+ @venues << Venue.new(venue)
12
+ end
13
+ @venues
14
+ end
15
+
16
+ def [](search_index)
17
+ found_index = @venues.index(search_index)
18
+ unless found_index.nil?
19
+ @venues[found_index]
20
+ end
21
+ end
22
+
23
+ ##
24
+ # Make the class Enumerable
25
+ def each(&block)
26
+ @venues.each do |venue|
27
+ if block_given?
28
+ block.call venue
29
+ else
30
+ yield venue
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+
@@ -0,0 +1,82 @@
1
+ module SportsDataApi
2
+ module Mlb
3
+
4
+ class Exception < ::Exception
5
+ end
6
+
7
+ DIR = File.join(File.dirname(__FILE__), 'mlb')
8
+ BASE_URL = 'http://api.sportsdatallc.org/mlb-%{access_level}%{version}'
9
+ DEFAULT_VERSION = 4
10
+ SPORT = :mlb
11
+
12
+ autoload :Team, File.join(DIR, 'team')
13
+ autoload :Teams, File.join(DIR, 'teams')
14
+ autoload :Player, File.join(DIR, 'player')
15
+ autoload :Players, File.join(DIR, 'players')
16
+ autoload :Game, File.join(DIR, 'game')
17
+ autoload :Games, File.join(DIR, 'games')
18
+ autoload :Season, File.join(DIR, 'season')
19
+ autoload :Broadcast, File.join(DIR, 'broadcast')
20
+ autoload :GameStat, File.join(DIR,'game_stat')
21
+ autoload :GameStats, File.join(DIR, 'game_stats')
22
+ autoload :Boxscore, File.join(DIR, 'boxscore')
23
+ autoload :Venue, File.join(DIR, 'venue')
24
+ autoload :Venues, File.join(DIR, 'venues')
25
+
26
+ ##
27
+ # Fetches all NBA teams
28
+ def self.teams(year=Date.today.year, version = DEFAULT_VERSION)
29
+ response = self.response_xml(version, "/teams/#{year}.xml")
30
+ return Teams.new(response.xpath('/teams'))
31
+ end
32
+
33
+ ##
34
+ # Fetches MLB season schedule for a given year and season
35
+ def self.schedule(year=Date.today.year, version = DEFAULT_VERSION)
36
+ response = self.response_xml(version, "/schedule/#{year}.xml")
37
+ return Season.new(response.xpath("calendars"))
38
+ end
39
+
40
+ ##
41
+ # Fetches MLB daily schedule for a given date
42
+ def self.daily(year, month, day, version = DEFAULT_VERSION)
43
+ response = self.response_xml(version, "/daily/schedule/#{year}/#{month}/#{day}.xml")
44
+ return Games.new(response.xpath("calendars"))
45
+ end
46
+
47
+ ##
48
+ # Fetches MLB venues
49
+ def self.venues(version = DEFAULT_VERSION)
50
+ response = self.response_xml(version, "/venues/venues.xml")
51
+ return Venues.new(response.xpath("venues"))
52
+ end
53
+
54
+ ##
55
+ # Fetch MLB game stats
56
+ def self.game_statistics(event_id, version = DEFAULT_VERSION )
57
+ response = self.response_xml(version, "/statistics/#{event_id}.xml")
58
+ return GameStats.new(response.xpath("/statistics"))
59
+ end
60
+
61
+ ##
62
+ # Fetch MLB Game Boxscore
63
+ def self.game_boxscore(event_id, version = DEFAULT_VERSION )
64
+ response = self.response_xml(version, "/boxscore/#{event_id}.xml")
65
+ return Boxscore.new(response.xpath("/boxscore"))
66
+ end
67
+
68
+ ##
69
+ # Fetches MLB team roster
70
+ def self.team_roster(year=Date.today.year, version = DEFAULT_VERSION)
71
+ response = self.response_xml(version, "/rosters-full/#{year}.xml")
72
+ return Players.new(response.xpath("rosters"))
73
+ end
74
+
75
+ private
76
+ def self.response_xml(version, url)
77
+ base_url = BASE_URL % { access_level: SportsDataApi.access_level(SPORT), version: version }
78
+ response = SportsDataApi.generic_request("#{base_url}#{url}", SPORT)
79
+ Nokogiri::XML(response.to_s).remove_namespaces!
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,14 @@
1
+ module SportsDataApi
2
+ module Nba
3
+ class Broadcast
4
+ attr_reader :network, :satellite
5
+ def initialize(xml)
6
+ xml = xml.first if xml.is_a? Nokogiri::XML::NodeSet
7
+ if xml.is_a? Nokogiri::XML::Element
8
+ @network = xml['network']
9
+ @satellite = xml['satellite']
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,54 @@
1
+ module SportsDataApi
2
+ module Nba
3
+ class Game
4
+ attr_reader :id, :scheduled, :home, :home_team, :away,
5
+ :away_team, :status, :venue, :broadcast, :year, :season,
6
+ :date, :quarter, :clock
7
+
8
+ def initialize(args={})
9
+ xml = args.fetch(:xml)
10
+ @year = args[:year] ? args[:year].to_i : nil
11
+ @season = args[:season] ? args[:season].to_sym : nil
12
+ @date = args[:date]
13
+
14
+ xml = xml.first if xml.is_a? Nokogiri::XML::NodeSet
15
+ if xml.is_a? Nokogiri::XML::Element
16
+ @id = xml['id']
17
+ @scheduled = Time.parse xml['scheduled']
18
+ @home = xml['home_team']
19
+ @away = xml['away_team']
20
+ @status = xml['status']
21
+ @clock = xml['clock']
22
+ @quarter = xml['quarter'] ? xml['quarter'].to_i : nil
23
+
24
+ team_xml = xml.xpath('team')
25
+ @home_team = Team.new(team_xml.first)
26
+ @away_team = Team.new(team_xml.last)
27
+ @venue = Venue.new(xml.xpath('venue'))
28
+ @broadcast = Broadcast.new(xml.xpath('broadcast'))
29
+ end
30
+ end
31
+
32
+ ##
33
+ # Wrapper for Nba.game_summary
34
+ # TODO
35
+ def summary
36
+ Nba.game_summary(@id)
37
+ end
38
+
39
+ ##
40
+ # Wrapper for Nba.pbp (Nba.play_by_play)
41
+ # TODO
42
+ def pbp
43
+ raise NotImplementedError
44
+ end
45
+
46
+ ##
47
+ # Wrapper for Nba.boxscore
48
+ # TODO
49
+ def boxscore
50
+ raise NotImplementedError
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,26 @@
1
+ module SportsDataApi
2
+ module Nba
3
+ class Games
4
+ include Enumerable
5
+ attr_reader :games, :date
6
+
7
+ def initialize(xml)
8
+ @date = xml.first['date']
9
+
10
+ @games = xml.xpath("games/game").map do |game_xml|
11
+ Game.new(date: @date, xml: game_xml)
12
+ end
13
+ end
14
+
15
+ def each &block
16
+ @games.each do |game|
17
+ if block_given?
18
+ block.call game
19
+ else
20
+ yield game
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end