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
@@ -0,0 +1,22 @@
|
|
1
|
+
module SportsDataApi
|
2
|
+
module Nba
|
3
|
+
class Player
|
4
|
+
attr_reader :stats
|
5
|
+
|
6
|
+
def initialize(xml)
|
7
|
+
if xml.is_a? Nokogiri::XML::Element
|
8
|
+
player_ivar = self.instance_variable_set("@#{xml.name}", {})
|
9
|
+
self.class.class_eval { attr_reader :"#{xml.name}" }
|
10
|
+
xml.attributes.each do | attr_name, attr_value|
|
11
|
+
player_ivar[attr_name.to_sym] = attr_value.value
|
12
|
+
end
|
13
|
+
|
14
|
+
stats_xml = xml.xpath('statistics')
|
15
|
+
if stats_xml.is_a? Nokogiri::XML::NodeSet and stats_xml.count > 0
|
16
|
+
@stats = SportsDataApi::Stats.new(stats_xml.first)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module SportsDataApi
|
2
|
+
module Nba
|
3
|
+
class Season
|
4
|
+
attr_reader :id, :year, :type, :games
|
5
|
+
|
6
|
+
def initialize(xml)
|
7
|
+
if xml.is_a? Nokogiri::XML::NodeSet
|
8
|
+
@id = xml.first["id"]
|
9
|
+
@year = xml.first["year"].to_i
|
10
|
+
@type = xml.first["type"].to_sym
|
11
|
+
|
12
|
+
@games = xml.first.xpath("games/game").map do |game_xml|
|
13
|
+
Game.new(year: @year, season: @type, xml: game_xml)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
##
|
19
|
+
# Check if the requested season is a valid
|
20
|
+
# NBA season type.
|
21
|
+
#
|
22
|
+
# The only valid types are: :pre, :reg, :pst
|
23
|
+
def self.valid?(season)
|
24
|
+
[:PRE, :REG, :PST].include?(season)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module SportsDataApi
|
2
|
+
module Nba
|
3
|
+
class Team
|
4
|
+
attr_reader :id, :name, :market, :alias, :conference, :division,
|
5
|
+
:stats, :players, :points
|
6
|
+
|
7
|
+
def initialize(xml, conference = nil, division = nil)
|
8
|
+
xml = xml.first if xml.is_a? Nokogiri::XML::NodeSet
|
9
|
+
if xml.is_a? Nokogiri::XML::Element
|
10
|
+
@id = xml['id']
|
11
|
+
@name = xml['name']
|
12
|
+
@market = xml['market']
|
13
|
+
@alias = xml['alias']
|
14
|
+
@points = xml['points'] ? xml['points'].to_i : nil
|
15
|
+
@conference = conference
|
16
|
+
@division = division
|
17
|
+
@players = xml.xpath("players/player").map do |player_xml|
|
18
|
+
Player.new(player_xml)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
##
|
24
|
+
# Compare the Team with another team
|
25
|
+
def ==(other)
|
26
|
+
# Must have an id to compare
|
27
|
+
return false if self.id.nil?
|
28
|
+
|
29
|
+
if other.is_a? SportsDataApi::Nba::Team
|
30
|
+
return false if other.id.nil?
|
31
|
+
self.id === other.id
|
32
|
+
elsif other.is_a? Symbol
|
33
|
+
self.id.to_sym === other
|
34
|
+
else
|
35
|
+
super(other)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module SportsDataApi
|
2
|
+
module Nba
|
3
|
+
class Teams
|
4
|
+
include Enumerable
|
5
|
+
|
6
|
+
attr_reader :conferences, :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('conference').each do |conference|
|
15
|
+
# Conference ID, e.g., EASTERN or WESTERN
|
16
|
+
cname = conference['alias']
|
17
|
+
|
18
|
+
conference.xpath('division').each do |division|
|
19
|
+
# Division ID, e.g., ATLANTIC, PACIFIC
|
20
|
+
dname = division['alias']
|
21
|
+
|
22
|
+
# Create a new team
|
23
|
+
@teams << division.xpath('team').map { |team| Team.new(team, cname, dname) }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
@teams.flatten!
|
29
|
+
|
30
|
+
uniq_conferences = @teams.map { |team| team.conference.upcase }.uniq
|
31
|
+
@allowed_conferences = uniq_conferences.map { |str| str.to_sym }.concat(uniq_conferences.map { |str| str.downcase.to_sym })
|
32
|
+
@conferences = uniq_conferences.map { |conf| conf.to_sym }
|
33
|
+
|
34
|
+
uniq_divisions = @teams.map { |team| team.division.upcase }.uniq
|
35
|
+
@divisions = @teams.map { |team| team.division.to_sym }.uniq
|
36
|
+
@allowed_divisions = uniq_divisions.map { |str| str.to_sym }.concat(uniq_divisions.map { |str| str.downcase.to_sym })
|
37
|
+
end
|
38
|
+
|
39
|
+
def [](search_index)
|
40
|
+
found_index = @teams.index(search_index)
|
41
|
+
unless found_index.nil?
|
42
|
+
@teams[found_index]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
##
|
47
|
+
#
|
48
|
+
def respond_to?(method)
|
49
|
+
@allowed_conferences.include?(method) || @allowed_divisions.include?(method)
|
50
|
+
end
|
51
|
+
|
52
|
+
##
|
53
|
+
#
|
54
|
+
def method_missing(method)
|
55
|
+
if @allowed_conferences.include?(method)
|
56
|
+
return @teams.select do |team|
|
57
|
+
up = team.conference.upcase.to_sym
|
58
|
+
dw = team.conference.downcase.to_sym
|
59
|
+
up === method || dw === method
|
60
|
+
end
|
61
|
+
elsif @allowed_divisions.include?(method)
|
62
|
+
return @teams.select do |team|
|
63
|
+
up = team.division.upcase.to_sym
|
64
|
+
dw = team.division.downcase.to_sym
|
65
|
+
up === method || dw === method
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
##
|
71
|
+
# Make the class Enumerable
|
72
|
+
def each(&block)
|
73
|
+
@teams.each do |team|
|
74
|
+
if block_given?
|
75
|
+
block.call team
|
76
|
+
else
|
77
|
+
yield team
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module SportsDataApi
|
2
|
+
module Nba
|
3
|
+
class Venue
|
4
|
+
attr_reader :id, :name, :address, :city, :state, :zip, :country, :capacity
|
5
|
+
def initialize(xml)
|
6
|
+
xml = xml.first if xml.is_a? Nokogiri::XML::NodeSet
|
7
|
+
if xml.is_a? Nokogiri::XML::Element
|
8
|
+
@id = xml['id']
|
9
|
+
@name = xml['name']
|
10
|
+
@address = xml['address']
|
11
|
+
@city = xml['city']
|
12
|
+
@state = xml['state']
|
13
|
+
@zip = xml['zip']
|
14
|
+
@country = xml['country']
|
15
|
+
@capacity = xml['capacity']
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module SportsDataApi
|
2
|
+
module Nba
|
3
|
+
|
4
|
+
class Exception < ::Exception
|
5
|
+
end
|
6
|
+
|
7
|
+
DIR = File.join(File.dirname(__FILE__), 'nba')
|
8
|
+
BASE_URL = 'http://api.sportsdatallc.org/nba-%{access_level}%{version}'
|
9
|
+
DEFAULT_VERSION = 3
|
10
|
+
SPORT = :nba
|
11
|
+
|
12
|
+
autoload :Team, File.join(DIR, 'team')
|
13
|
+
autoload :Teams, File.join(DIR, 'teams')
|
14
|
+
autoload :Player, File.join(DIR, 'player')
|
15
|
+
autoload :Game, File.join(DIR, 'game')
|
16
|
+
autoload :Games, File.join(DIR, 'games')
|
17
|
+
autoload :Season, File.join(DIR, 'season')
|
18
|
+
autoload :Venue, File.join(DIR, 'venue')
|
19
|
+
autoload :Broadcast, File.join(DIR, 'broadcast')
|
20
|
+
|
21
|
+
##
|
22
|
+
# Fetches NBA season schedule for a given year and season
|
23
|
+
def self.schedule(year, season, version = DEFAULT_VERSION)
|
24
|
+
season = season.to_s.upcase.to_sym
|
25
|
+
raise SportsDataApi::Nba::Exception.new("#{season} is not a valid season") unless Season.valid?(season)
|
26
|
+
|
27
|
+
response = self.response_xml(version, "/games/#{year}/#{season}/schedule.xml")
|
28
|
+
|
29
|
+
return Season.new(response.xpath("/league/season-schedule"))
|
30
|
+
end
|
31
|
+
|
32
|
+
##
|
33
|
+
# Fetches NBA team roster
|
34
|
+
def self.team_roster(team, version = DEFAULT_VERSION)
|
35
|
+
response = self.response_xml(version, "/teams/#{team}/profile.xml")
|
36
|
+
|
37
|
+
return Team.new(response.xpath("team"))
|
38
|
+
end
|
39
|
+
|
40
|
+
##
|
41
|
+
# Fetches NBA game summary for a given game
|
42
|
+
def self.game_summary(game, version = DEFAULT_VERSION)
|
43
|
+
response = self.response_xml(version, "/games/#{game}/summary.xml")
|
44
|
+
|
45
|
+
return Game.new(xml: response.xpath("/game"))
|
46
|
+
end
|
47
|
+
|
48
|
+
##
|
49
|
+
# Fetches all NBA teams
|
50
|
+
def self.teams(version = DEFAULT_VERSION)
|
51
|
+
response = self.response_xml(version, "/league/hierarchy.xml")
|
52
|
+
|
53
|
+
return Teams.new(response.xpath('/league'))
|
54
|
+
end
|
55
|
+
|
56
|
+
##
|
57
|
+
# Fetches NBA daily schedule for a given date
|
58
|
+
def self.daily(year, month, day, version = DEFAULT_VERSION)
|
59
|
+
response = self.response_xml(version, "/games/#{year}/#{month}/#{day}/schedule.xml")
|
60
|
+
|
61
|
+
return Games.new(response.xpath('league/daily-schedule'))
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
def self.response_xml(version, url)
|
66
|
+
base_url = BASE_URL % { access_level: SportsDataApi.access_level(SPORT), version: version }
|
67
|
+
response = SportsDataApi.generic_request("#{base_url}#{url}", SPORT)
|
68
|
+
Nokogiri::XML(response.to_s).remove_namespaces!
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module SportsDataApi
|
2
|
+
module Nfl
|
3
|
+
class Broadcast
|
4
|
+
attr_reader :network, :satellite, :internet
|
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
|
+
@internet = xml['internet']
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module SportsDataApi
|
2
|
+
module Nfl
|
3
|
+
class Game
|
4
|
+
attr_reader :id, :scheduled, :home, :home_team, :away,
|
5
|
+
:away_team, :status, :quarter, :clock, :venue, :broadcast, :weather,
|
6
|
+
:year, :season, :week
|
7
|
+
|
8
|
+
def initialize(year, season, week, xml)
|
9
|
+
@year = year.to_i
|
10
|
+
@season = season.to_sym
|
11
|
+
@week = week.to_i
|
12
|
+
|
13
|
+
xml = xml.first if xml.is_a? Nokogiri::XML::NodeSet
|
14
|
+
if xml.is_a? Nokogiri::XML::Element
|
15
|
+
@id = xml['id']
|
16
|
+
@scheduled = Time.parse xml['scheduled']
|
17
|
+
@home = xml['home']
|
18
|
+
@away = xml['away']
|
19
|
+
@status = xml['status']
|
20
|
+
@quarter = xml['quarter'].to_i
|
21
|
+
@clock = xml['clock']
|
22
|
+
|
23
|
+
team_xml = xml.xpath('team')
|
24
|
+
@home_team = Team.new(team_xml.first)
|
25
|
+
@away_team = Team.new(team_xml.last)
|
26
|
+
@venue = Venue.new(xml.xpath('venue'))
|
27
|
+
@broadcast = Broadcast.new(xml.xpath('broadcast'))
|
28
|
+
@weather = Weather.new(xml.xpath('weather'))
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
##
|
33
|
+
# Wrapper for Nfl.statistics
|
34
|
+
# TODO
|
35
|
+
def statistics
|
36
|
+
raise NotImplementedError
|
37
|
+
end
|
38
|
+
|
39
|
+
##
|
40
|
+
# Wrapper for Nfl.summary
|
41
|
+
# TODO
|
42
|
+
def summary
|
43
|
+
raise NotImplementedError
|
44
|
+
end
|
45
|
+
|
46
|
+
##
|
47
|
+
# Wrapper for Nfl.pbp (Nfl.play_by_play)
|
48
|
+
# TODO
|
49
|
+
def pbp
|
50
|
+
raise NotImplementedError
|
51
|
+
end
|
52
|
+
|
53
|
+
##
|
54
|
+
# Wrapper for Nfl.boxscore these helper methods are used
|
55
|
+
# to provide similar functionality as the links attribute
|
56
|
+
# found in the weekly schedule example.
|
57
|
+
def boxscore
|
58
|
+
Nfl.boxscore(year, season, week, home, away, 1)
|
59
|
+
end
|
60
|
+
|
61
|
+
##
|
62
|
+
# Wrapper for Nfl.roster
|
63
|
+
# TODO
|
64
|
+
def roster
|
65
|
+
raise NotImplementedError
|
66
|
+
end
|
67
|
+
|
68
|
+
##
|
69
|
+
# Wrapper for Nfl.injuries
|
70
|
+
# TODO
|
71
|
+
def injuries
|
72
|
+
raise NotImplementedError
|
73
|
+
end
|
74
|
+
|
75
|
+
##
|
76
|
+
# Wrapper for Nfl.depthchart
|
77
|
+
# TODO
|
78
|
+
def depthchart
|
79
|
+
raise NotImplementedError
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module SportsDataApi
|
2
|
+
module Nfl
|
3
|
+
class Games
|
4
|
+
include Enumerable
|
5
|
+
attr_reader :games, :year, :season, :week
|
6
|
+
|
7
|
+
def initialize(xml)
|
8
|
+
@year = xml.first['season'].to_i
|
9
|
+
@season = xml.first['type'].to_sym
|
10
|
+
@week = xml.first['week'].to_i
|
11
|
+
|
12
|
+
@games = xml.xpath("game").map do |game_xml|
|
13
|
+
Game.new(@year, @season, @week, game_xml)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def each &block
|
18
|
+
@games.each do |game|
|
19
|
+
if block_given?
|
20
|
+
block.call game
|
21
|
+
else
|
22
|
+
yield game
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module SportsDataApi
|
2
|
+
module Nfl
|
3
|
+
class Player
|
4
|
+
def initialize(xml)
|
5
|
+
if xml.is_a? Nokogiri::XML::Element
|
6
|
+
player_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
|
+
player_ivar[attr_name.to_sym] = attr_value.value
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module SportsDataApi
|
2
|
+
module Nfl
|
3
|
+
class PlayerSeasonStats
|
4
|
+
attr_reader :stats, :id, :players
|
5
|
+
def initialize(xml)
|
6
|
+
xml = xml.first if xml.is_a? Nokogiri::XML::NodeSet
|
7
|
+
@players = []
|
8
|
+
xml.xpath("player").each do | p |
|
9
|
+
player = {}
|
10
|
+
stats = []
|
11
|
+
|
12
|
+
p.children.each do | stat |
|
13
|
+
if stat.name == "text"
|
14
|
+
next
|
15
|
+
end
|
16
|
+
stats << SportsDataApi::Stats.new(stat)
|
17
|
+
end
|
18
|
+
|
19
|
+
player[:id] = p['id']
|
20
|
+
player[:stats] = stats
|
21
|
+
@players << player
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module SportsDataApi
|
2
|
+
module Nfl
|
3
|
+
class Season
|
4
|
+
attr_reader :year, :type, :weeks
|
5
|
+
|
6
|
+
def initialize(xml)
|
7
|
+
@weeks = []
|
8
|
+
if xml.is_a? Nokogiri::XML::NodeSet
|
9
|
+
@year = xml.first["season"].to_i
|
10
|
+
@type = xml.first["type"].to_sym
|
11
|
+
@weeks = xml.first.xpath("week").map do |week_xml|
|
12
|
+
Week.new(@year, @type, week_xml)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
##
|
18
|
+
# Check if the requested season is a valid
|
19
|
+
# NFL season type.
|
20
|
+
#
|
21
|
+
# The only valid types are: :PRE, :REG, :PST
|
22
|
+
def self.valid?(season)
|
23
|
+
[:PRE, :REG, :PST].include?(season)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module SportsDataApi
|
2
|
+
module Nfl
|
3
|
+
class Team
|
4
|
+
attr_reader :id, :name, :conference, :division, :market, :remaining_challenges, :remaining_timeouts, :score, :quarters
|
5
|
+
|
6
|
+
def initialize(xml, conference = nil, division = nil)
|
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
|
+
@conference = conference
|
12
|
+
@division = division
|
13
|
+
@market = xml['market']
|
14
|
+
@remaining_challenges = xml['remaining_challenges'].to_i
|
15
|
+
@remaining_timeouts = xml['remaining_timeouts'].to_i
|
16
|
+
@quarters = xml.xpath('scoring/quarter').map do |quarter|
|
17
|
+
quarter['points'].to_i
|
18
|
+
end
|
19
|
+
@quarters = @quarters.fill(0, @quarters.size, 4 - @quarters.size)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# Sum the score of each quarter
|
24
|
+
def score
|
25
|
+
@quarters.inject(:+)
|
26
|
+
end
|
27
|
+
|
28
|
+
##
|
29
|
+
# Compare the Team with another team
|
30
|
+
def ==(other)
|
31
|
+
# Must have an id to compare
|
32
|
+
return false if self.id.nil?
|
33
|
+
|
34
|
+
if other.is_a? SportsDataApi::Nfl::Team
|
35
|
+
return false if other.id.nil?
|
36
|
+
self.id === other.id
|
37
|
+
elsif other.is_a? Symbol
|
38
|
+
self.id.to_sym === other
|
39
|
+
else
|
40
|
+
super(other)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module SportsDataApi
|
2
|
+
module Nfl
|
3
|
+
class TeamRoster
|
4
|
+
attr_reader :players
|
5
|
+
|
6
|
+
def initialize(xml)
|
7
|
+
@players = []
|
8
|
+
xml.children.each do | player |
|
9
|
+
if player.name == "text"
|
10
|
+
next
|
11
|
+
end
|
12
|
+
@players << Player.new(player)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module SportsDataApi
|
2
|
+
module Nfl
|
3
|
+
class TeamSeasonStats
|
4
|
+
attr_reader :id, :stats
|
5
|
+
def initialize(xml)
|
6
|
+
xml = xml.first if xml.is_a? Nokogiri::XML::NodeSet
|
7
|
+
@id = xml['id']
|
8
|
+
@stats = []
|
9
|
+
xml.xpath("players").remove
|
10
|
+
xml.children.each do | stat |
|
11
|
+
if stat.name == "text"
|
12
|
+
next
|
13
|
+
end
|
14
|
+
@stats << SportsDataApi::Stats.new(stat)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
module SportsDataApi
|
2
|
+
module Nfl
|
3
|
+
class Teams
|
4
|
+
include Enumerable
|
5
|
+
|
6
|
+
attr_reader :conferences, :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('conference').each do |conference|
|
15
|
+
# Conference ID, e.g., AFC or NFC
|
16
|
+
cid = conference['id']
|
17
|
+
|
18
|
+
conference.xpath('division').each do |division|
|
19
|
+
# Division ID, e.g., AFC_EAST, NFC_NORTH
|
20
|
+
did = division['id']
|
21
|
+
|
22
|
+
# Create a new team
|
23
|
+
@teams << division.xpath('team').map { |team| Team.new(team, cid, did) }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
@teams.flatten!
|
29
|
+
|
30
|
+
uniq_conferences = @teams.map { |team| team.conference.upcase }.uniq
|
31
|
+
@allowed_conferences = uniq_conferences.map { |str| str.to_sym }.concat(uniq_conferences.map { |str| str.downcase.to_sym })
|
32
|
+
@conferences = uniq_conferences.map { |conf| conf.to_sym }
|
33
|
+
|
34
|
+
uniq_divisions = @teams.map { |team| team.division.upcase }.uniq
|
35
|
+
@divisions = @teams.map { |team| team.division.to_sym }.uniq
|
36
|
+
@allowed_divisions = uniq_divisions.map { |str| str.to_sym }.concat(uniq_divisions.map { |str| str.downcase.to_sym })
|
37
|
+
end
|
38
|
+
|
39
|
+
def [](search_index)
|
40
|
+
found_index = @teams.index(search_index)
|
41
|
+
unless found_index.nil?
|
42
|
+
@teams[found_index]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
##
|
47
|
+
#
|
48
|
+
def respond_to?(method)
|
49
|
+
@allowed_conferences.include?(method) || @allowed_divisions.include?(method)
|
50
|
+
end
|
51
|
+
|
52
|
+
##
|
53
|
+
#
|
54
|
+
def method_missing(method)
|
55
|
+
if @allowed_conferences.include?(method)
|
56
|
+
return @teams.select do |team|
|
57
|
+
up = team.conference.upcase.to_sym
|
58
|
+
dw = team.conference.downcase.to_sym
|
59
|
+
up === method || dw === method
|
60
|
+
end
|
61
|
+
elsif @allowed_divisions.include?(method)
|
62
|
+
return @teams.select do |team|
|
63
|
+
up = team.division.upcase.to_sym
|
64
|
+
dw = team.division.downcase.to_sym
|
65
|
+
up === method || dw === method
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
##
|
71
|
+
# Make the class Enumerable
|
72
|
+
def each(&block)
|
73
|
+
@teams.each do |team|
|
74
|
+
if block_given?
|
75
|
+
block.call team
|
76
|
+
else
|
77
|
+
yield team
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module SportsDataApi
|
2
|
+
module Nfl
|
3
|
+
class Venue
|
4
|
+
attr_reader :id, :name, :address, :city, :state, :zip, :country, :capacity, :type, :surface
|
5
|
+
def initialize(xml)
|
6
|
+
xml = xml.first if xml.is_a? Nokogiri::XML::NodeSet
|
7
|
+
if xml.is_a? Nokogiri::XML::Element
|
8
|
+
@id = xml['id']
|
9
|
+
@name = xml['name']
|
10
|
+
@address = xml['address']
|
11
|
+
@city = xml['city']
|
12
|
+
@state = xml['state']
|
13
|
+
@zip = xml['zip']
|
14
|
+
@country = xml['country']
|
15
|
+
@capacity = xml['capacity']
|
16
|
+
@type = xml['type']
|
17
|
+
@surface = xml['surface']
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module SportsDataApi
|
2
|
+
module Nfl
|
3
|
+
class Weather
|
4
|
+
attr_reader :temperature, :condition, :humidity, :wind_speed, :wind_direction
|
5
|
+
def initialize(xml)
|
6
|
+
xml = xml.first if xml.is_a? Nokogiri::XML::NodeSet
|
7
|
+
if xml.is_a? Nokogiri::XML::Element
|
8
|
+
@temperature = xml['temperature'].to_i
|
9
|
+
@condition = xml['condition']
|
10
|
+
@humidity = xml['humidity'].to_i
|
11
|
+
@wind_speed = xml.xpath('wind').first['speed'].to_i
|
12
|
+
@wind_direction = xml.xpath('wind').first['direction']
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|