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.
- checksums.yaml +7 -0
- data/.gitignore +7 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +2 -1
- data/Guardfile +1 -1
- data/README.md +20 -5
- data/lib/sports_data_api/exception.rb +5 -0
- data/lib/sports_data_api/mlb/boxscore.rb +36 -0
- data/lib/sports_data_api/mlb/broadcast.rb +14 -0
- data/lib/sports_data_api/mlb/game.rb +30 -0
- data/lib/sports_data_api/mlb/game_stat.rb +26 -0
- data/lib/sports_data_api/mlb/game_stats.rb +44 -0
- data/lib/sports_data_api/mlb/games.rb +29 -0
- data/lib/sports_data_api/mlb/player.rb +17 -0
- data/lib/sports_data_api/mlb/players.rb +42 -0
- data/lib/sports_data_api/mlb/season.rb +18 -0
- data/lib/sports_data_api/mlb/team.rb +35 -0
- data/lib/sports_data_api/mlb/teams.rb +42 -0
- data/lib/sports_data_api/mlb/venue.rb +15 -0
- data/lib/sports_data_api/mlb/venues.rb +37 -0
- data/lib/sports_data_api/mlb.rb +82 -0
- data/lib/sports_data_api/nba/broadcast.rb +14 -0
- data/lib/sports_data_api/nba/game.rb +54 -0
- data/lib/sports_data_api/nba/games.rb +26 -0
- data/lib/sports_data_api/nba/player.rb +22 -0
- data/lib/sports_data_api/nba/season.rb +28 -0
- data/lib/sports_data_api/nba/team.rb +40 -0
- data/lib/sports_data_api/nba/teams.rb +83 -0
- data/lib/sports_data_api/nba/venue.rb +20 -0
- data/lib/sports_data_api/nba.rb +71 -0
- data/lib/sports_data_api/nfl/broadcast.rb +15 -0
- data/lib/sports_data_api/nfl/game.rb +83 -0
- data/lib/sports_data_api/nfl/games.rb +29 -0
- data/lib/sports_data_api/nfl/injuries.rb +9 -0
- data/lib/sports_data_api/nfl/player.rb +15 -0
- data/lib/sports_data_api/nfl/player_season_stats.rb +26 -0
- data/lib/sports_data_api/nfl/season.rb +27 -0
- data/lib/sports_data_api/nfl/team.rb +46 -0
- data/lib/sports_data_api/nfl/team_roster.rb +17 -0
- data/lib/sports_data_api/nfl/team_season_stats.rb +19 -0
- data/lib/sports_data_api/nfl/teams.rb +84 -0
- data/lib/sports_data_api/nfl/venue.rb +22 -0
- data/lib/sports_data_api/nfl/weather.rb +17 -0
- data/lib/sports_data_api/nfl/week.rb +20 -0
- data/lib/sports_data_api/nfl.rb +98 -0
- data/lib/sports_data_api/stats.rb +13 -0
- data/lib/sports_data_api/version.rb +1 -1
- data/lib/sports_data_api.rb +37 -12
- data/spec/cassettes/sports_data_api_mlb_game.yml +20193 -0
- data/spec/cassettes/sports_data_api_mlb_game_boxscore.yml +225 -0
- data/spec/cassettes/sports_data_api_mlb_game_stats.yml +657 -0
- data/spec/cassettes/sports_data_api_mlb_games.yml +195 -0
- data/spec/cassettes/sports_data_api_mlb_player.yml +10891 -0
- data/spec/cassettes/sports_data_api_mlb_season.yml +20193 -0
- data/spec/cassettes/sports_data_api_mlb_team.yml +182 -0
- data/spec/cassettes/sports_data_api_mlb_team_roster.yml +10891 -0
- data/spec/cassettes/sports_data_api_mlb_teams.yml +403 -0
- data/spec/cassettes/sports_data_api_mlb_venues.yml +343 -0
- data/spec/cassettes/sports_data_api_nba.yml +74176 -0
- data/spec/cassettes/sports_data_api_nba_broadcast.yml +88 -0
- data/spec/cassettes/sports_data_api_nba_game.yml +21202 -0
- data/spec/cassettes/sports_data_api_nba_games.yml +128 -0
- data/spec/cassettes/sports_data_api_nba_league_hierarchy.yml +545 -0
- data/spec/cassettes/sports_data_api_nba_player.yml +244 -0
- data/spec/cassettes/sports_data_api_nba_season.yml +18228 -0
- data/spec/cassettes/sports_data_api_nba_team.yml +1398 -0
- data/spec/cassettes/sports_data_api_nba_team_roster.yml +244 -0
- data/spec/cassettes/sports_data_api_nba_venue.yml +88 -0
- data/spec/cassettes/sports_data_api_nfl.yml +19105 -0
- data/spec/cassettes/sports_data_api_nfl_broadcast.yml +112 -0
- data/spec/cassettes/sports_data_api_nfl_game.yml +16139 -0
- data/spec/cassettes/sports_data_api_nfl_games.yml +912 -0
- data/spec/cassettes/sports_data_api_nfl_player_season_stats.yml +997 -0
- data/spec/cassettes/sports_data_api_nfl_season.yml +14100 -0
- data/spec/cassettes/sports_data_api_nfl_team.yml +783 -0
- data/spec/cassettes/sports_data_api_nfl_team_hierarchy.yml +909 -0
- data/spec/cassettes/sports_data_api_nfl_team_roster.yml +618 -0
- data/spec/cassettes/sports_data_api_nfl_team_season_stats.yml +981 -0
- data/spec/cassettes/sports_data_api_nfl_venue.yml +112 -0
- data/spec/cassettes/sports_data_api_nfl_weather.yml +112 -0
- data/spec/cassettes/sports_data_api_nfl_week.yml +14100 -0
- data/spec/lib/sports_data_api/mlb/boxscore_spec.rb +63 -0
- data/spec/lib/sports_data_api/mlb/game_spec.rb +24 -0
- data/spec/lib/sports_data_api/mlb/game_stats_spec.rb +25 -0
- data/spec/lib/sports_data_api/mlb/games_spec.rb +24 -0
- data/spec/lib/sports_data_api/mlb/player_spec.rb +103 -0
- data/spec/lib/sports_data_api/mlb/players_spec.rb +17 -0
- data/spec/lib/sports_data_api/mlb/season_spec.rb +19 -0
- data/spec/lib/sports_data_api/mlb/team_spec.rb +24 -0
- data/spec/lib/sports_data_api/mlb/teams_spec.rb +30 -0
- data/spec/lib/sports_data_api/mlb/venues_spec.rb +17 -0
- data/spec/lib/sports_data_api/nba/broadcast_spec.rb +18 -0
- data/spec/lib/sports_data_api/nba/game_spec.rb +87 -0
- data/spec/lib/sports_data_api/nba/games_spec.rb +19 -0
- data/spec/lib/sports_data_api/nba/player_spec.rb +72 -0
- data/spec/lib/sports_data_api/nba/season_spec.rb +41 -0
- data/spec/lib/sports_data_api/nba/team_spec.rb +185 -0
- data/spec/lib/sports_data_api/nba/teams_spec.rb +76 -0
- data/spec/lib/sports_data_api/nba/venue_spec.rb +24 -0
- data/spec/lib/sports_data_api/nba_spec.rb +41 -0
- data/spec/lib/sports_data_api/nfl/broadcast_spec.rb +19 -0
- data/spec/lib/sports_data_api/nfl/game_spec.rb +126 -0
- data/spec/lib/sports_data_api/nfl/games_spec.rb +21 -0
- data/spec/lib/sports_data_api/nfl/player_season_stats.rb +28 -0
- data/spec/lib/sports_data_api/nfl/season_spec.rb +41 -0
- data/spec/lib/sports_data_api/nfl/team_roster_spec.rb +28 -0
- data/spec/lib/sports_data_api/nfl/team_season_stats.rb +19 -0
- data/spec/lib/sports_data_api/nfl/team_spec.rb +52 -0
- data/spec/lib/sports_data_api/nfl/teams_spec.rb +77 -0
- data/spec/lib/sports_data_api/nfl/venue_spec.rb +26 -0
- data/spec/lib/sports_data_api/nfl/weather_spec.rb +21 -0
- data/spec/lib/sports_data_api/nfl/week_spec.rb +21 -0
- data/spec/lib/sports_data_api/nfl_spec.rb +113 -0
- data/spec/lib/sports_data_api_spec.rb +8 -5
- data/spec/spec_helper.rb +30 -9
- data/sports_data_api.gemspec +19 -15
- metadata +267 -76
- data/.rvmrc +0 -38
- data/lib/nfl.rb +0 -149
- data/spec/lib/nfl_spec.rb +0 -125
- data/spec/xml/boxscore.xml +0 -93
- data/spec/xml/schedule.xml +0 -4067
- 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
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
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. [
|
28
|
-
4. [NCAA
|
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
|
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,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
|