sports_data_api 0.0.3 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 [](https://travis-ci.org/RLovelett/sports_data_api)
|
1
|
+
# SportsDataApi [](https://travis-ci.org/RLovelett/sports_data_api) [](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
|