sports_data_api 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +52 -3
  3. data/lib/sports_data_api.rb +1 -0
  4. data/lib/sports_data_api/ncaamb.rb +93 -0
  5. data/lib/sports_data_api/ncaamb/broadcast.rb +14 -0
  6. data/lib/sports_data_api/ncaamb/game.rb +51 -0
  7. data/lib/sports_data_api/ncaamb/games.rb +26 -0
  8. data/lib/sports_data_api/ncaamb/player.rb +22 -0
  9. data/lib/sports_data_api/ncaamb/season.rb +28 -0
  10. data/lib/sports_data_api/ncaamb/team.rb +40 -0
  11. data/lib/sports_data_api/ncaamb/teams.rb +83 -0
  12. data/lib/sports_data_api/ncaamb/tournament.rb +30 -0
  13. data/lib/sports_data_api/ncaamb/tournament_game.rb +23 -0
  14. data/lib/sports_data_api/ncaamb/tournament_list.rb +28 -0
  15. data/lib/sports_data_api/ncaamb/tournament_schedule.rb +51 -0
  16. data/lib/sports_data_api/ncaamb/venue.rb +20 -0
  17. data/lib/sports_data_api/version.rb +1 -1
  18. data/spec/cassettes/sports_data_api_ncaamb.yml +171013 -0
  19. data/spec/cassettes/sports_data_api_ncaamb_broadcast.yml +844 -0
  20. data/spec/cassettes/sports_data_api_ncaamb_game.yml +88015 -0
  21. data/spec/cassettes/sports_data_api_ncaamb_games.yml +844 -0
  22. data/spec/cassettes/sports_data_api_ncaamb_league_hierarchy.yml +9009 -0
  23. data/spec/cassettes/sports_data_api_ncaamb_player.yml +188 -0
  24. data/spec/cassettes/sports_data_api_ncaamb_season.yml +85489 -0
  25. data/spec/cassettes/sports_data_api_ncaamb_team.yml +5259 -0
  26. data/spec/cassettes/sports_data_api_ncaamb_tournament.yml +1773 -0
  27. data/spec/cassettes/sports_data_api_ncaamb_tournament_game.yml +2334 -0
  28. data/spec/cassettes/sports_data_api_ncaamb_tournament_list.yml +71 -0
  29. data/spec/cassettes/sports_data_api_ncaamb_tournament_schedule.yml +1705 -0
  30. data/spec/cassettes/sports_data_api_ncaamb_venue.yml +306 -0
  31. data/spec/lib/sports_data_api/mlb/player_spec.rb +1 -1
  32. data/spec/lib/sports_data_api/mlb/players_spec.rb +1 -1
  33. data/spec/lib/sports_data_api/mlb/team_spec.rb +1 -1
  34. data/spec/lib/sports_data_api/mlb/teams_spec.rb +1 -1
  35. data/spec/lib/sports_data_api/ncaamb/broadcast_spec.rb +18 -0
  36. data/spec/lib/sports_data_api/ncaamb/game_spec.rb +87 -0
  37. data/spec/lib/sports_data_api/ncaamb/games_spec.rb +19 -0
  38. data/spec/lib/sports_data_api/ncaamb/player_spec.rb +68 -0
  39. data/spec/lib/sports_data_api/ncaamb/season_spec.rb +41 -0
  40. data/spec/lib/sports_data_api/ncaamb/team_spec.rb +182 -0
  41. data/spec/lib/sports_data_api/ncaamb/teams_spec.rb +76 -0
  42. data/spec/lib/sports_data_api/ncaamb/tournament_game_spec.rb +38 -0
  43. data/spec/lib/sports_data_api/ncaamb/tournament_list_spec.rb +42 -0
  44. data/spec/lib/sports_data_api/ncaamb/tournament_schedule_spec.rb +43 -0
  45. data/spec/lib/sports_data_api/ncaamb/tournament_spec.rb +25 -0
  46. data/spec/lib/sports_data_api/ncaamb/venue_spec.rb +24 -0
  47. data/spec/lib/sports_data_api/ncaamb_spec.rb +41 -0
  48. data/spec/spec_helper.rb +1 -0
  49. data/sports_data_api.gemspec +1 -1
  50. metadata +72 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 62aab7aee23b0a730d1134d17519b149c0094327
4
- data.tar.gz: f95759783b3b4d34a87f79db7e6e5be0d0ed414c
3
+ metadata.gz: daa6b600a49f7cc130a5a54f361dbd390340c145
4
+ data.tar.gz: 52f55a92b4e598cbbce507f82e24c49b7e2de667
5
5
  SHA512:
6
- metadata.gz: 9152043f7a7d85ef9245dd0466f83d7f970d23c60a3a0ecb2007edda75623f01b3b7ec4781d2e16fd38aa010dbd90f1b7d6ba898d3148d8bd393ad8d018512b5
7
- data.tar.gz: a2f99223b3092b2639a04ad843fd12e60f55af1388a3d937e550922e49bc6ae24f7457c9396c5d72ab35359815bc6452b4d73da1e57e59f742623a84793c3939
6
+ metadata.gz: 21fc4f3db62ace35e8261ac078e73afedcaef5849b0e81726fdf8a3bdc42b7dcdc6b54cb8b18ac6aada7434b21f53b5d129845e2b018b2f5203d2c1817a4f8e4
7
+ data.tar.gz: a76ab1ccea8466ca38bb448896f0c380355512ca38b309bd51ba1bf41e3665577f50636c7ca8daeefffbcd038d4acae93479574b2e974c4a6afec72c14e9d325
data/README.md CHANGED
@@ -24,9 +24,9 @@ log](https://github.com/rlovelett/sports_data_api/issues).
24
24
  * [NBA](http://developer.sportsdatallc.com/docs/NBA_API)
25
25
  * [MLB](http://developer.sportsdatallc.com/docs/MLB_API)
26
26
  * [NHL](http://developer.sportsdatallc.com/docs/NHL_API)
27
+ * [NCAAMB](http://developer.sportsdatallc.com/docs/NCAAMB_API)
27
28
  * TODO
28
- 2. [NCAA Basketball](http://developer.sportsdatallc.com/docs/NCAA_Mens_Basketball)
29
- 3. [NCAA Football](http://developer.sportsdatallc.com/docs/NCAA_Football_API)
29
+ 2. [NCAA Football](http://developer.sportsdatallc.com/docs/NCAA_Football_API)
30
30
 
31
31
  ## Installation
32
32
 
@@ -48,6 +48,55 @@ 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
49
  Requests for better documentation are welcome.
50
50
 
51
+ ### Example if you want to get weekly stats for a player.
52
+
53
+ ```ruby
54
+ SportsDataApi.set_access_level(:nfl, '<YOUR ACCESS LEVEL HERE>')
55
+ SportsDataApi.set_key(:nfl, '<YOUR API KEY HERE>')
56
+ game_stats = SportsDataApi::Nfl.game_statistics(2014, :REG, 9, 'HOU', 'PHI')
57
+ foster_stats = game_stats.home_team.players.select { |player| player['name'] === 'Arian Foster' }.first
58
+
59
+ # foster_stats should now be a `Hash` containing something that looks like this:
60
+ # {"id"=>"d89d2aef-c383-4ddf-bed8-3761aed35b10",
61
+ # "name"=>"Arian Foster",
62
+ # "jersey"=>23,
63
+ # "position"=>"RB",
64
+ # "touchdowns"=>{"pass"=>1, "rush"=>0, "int"=>0, "fum_ret"=>0, "punt_ret"=>0, "kick_ret"=>0, "fg_ret"=>0, "other"=>0},
65
+ # "rushing"=>
66
+ # {"att"=>15,
67
+ # "yds"=>56,
68
+ # "avg"=>3.733,
69
+ # "lg"=>18,
70
+ # "td"=>0,
71
+ # "fd"=>3,
72
+ # "fd_pct"=>20.0,
73
+ # "sfty"=>0,
74
+ # "rz_att"=>0,
75
+ # "fum"=>0,
76
+ # "yds_10_pls"=>2,
77
+ # "yds_20_pls"=>0,
78
+ # "yds_30_pls"=>0,
79
+ # "yds_40_pls"=>0,
80
+ # "yds_50_pls"=>0},
81
+ # "receiving"=>
82
+ # {"tar"=>3,
83
+ # "rec"=>2,
84
+ # "yds"=>63,
85
+ # "yac"=>63,
86
+ # "fd"=>1,
87
+ # "avg"=>31.5,
88
+ # "td"=>1,
89
+ # "lg"=>56,
90
+ # "rz_tar"=>0,
91
+ # "fum"=>0,
92
+ # "yds_10_pls"=>0,
93
+ # "yds_20_pls"=>0,
94
+ # "yds_30_pls"=>0,
95
+ # "yds_40_pls"=>0,
96
+ # "yds_50_pls"=>1},
97
+ # "first_downs"=>{"num"=>4, "pass"=>1, "rush"=>3, "pen"=>0}}
98
+ ```
99
+
51
100
  ## Testing
52
101
 
53
102
  The tests for the API have been mocked using [VCR](https://github.com/vcr/vcr) and [WebMock](https://github.com/bblimke/webmock).
@@ -61,7 +110,7 @@ However, if you want to refresh the actual server API responses you will need to
61
110
  This can be achieved simply by performing the following two steps:
62
111
 
63
112
  1. Delete all the cassettes (`rm spec/cassettes/*.yml`)
64
- 2. Run specs passing the API key as environment variable (`SPORTS_DATA_<NFL|NBA|MLB|NHL>_API_KEY=realapikey bundle exec rake spec`)
113
+ 2. Run specs passing the API key as environment variable (`SPORTS_DATA_<NFL|NBA|MLB|NHL|NCAAMB>_API_KEY=realapikey bundle exec rake spec`)
65
114
 
66
115
  ## Contributing
67
116
 
@@ -51,5 +51,6 @@ module SportsDataApi
51
51
  autoload :Nba, File.join(LIBRARY_PATH, 'nba')
52
52
  autoload :Mlb, File.join(LIBRARY_PATH, 'mlb')
53
53
  autoload :Nhl, File.join(LIBRARY_PATH, 'nhl')
54
+ autoload :Ncaamb, File.join(LIBRARY_PATH, 'ncaamb')
54
55
  autoload :Exception, File.join(LIBRARY_PATH, 'exception')
55
56
  end
@@ -0,0 +1,93 @@
1
+ module SportsDataApi
2
+ module Ncaamb
3
+
4
+ class Exception < ::Exception
5
+ end
6
+
7
+ DIR = File.join(File.dirname(__FILE__), 'ncaamb')
8
+ BASE_URL = 'http://api.sportsdatallc.org/ncaamb-%{access_level}%{version}'
9
+ DEFAULT_VERSION = 3
10
+ SPORT = :ncaamb
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
+ autoload :TournamentList, File.join(DIR, 'tournament_list')
21
+ autoload :Tournament, File.join(DIR, 'tournament')
22
+ autoload :TournamentSchedule, File.join(DIR, 'tournament_schedule')
23
+ autoload :TournamentGame, File.join(DIR, 'tournament_game')
24
+
25
+ ##
26
+ # Fetches NCAAAMB season schedule for a given year and season
27
+ def self.schedule(year, season, version = DEFAULT_VERSION)
28
+ season = season.to_s.upcase.to_sym
29
+ raise SportsDataApi::Ncaamb::Exception.new("#{season} is not a valid season") unless Season.valid?(season)
30
+
31
+ response = self.response_xml(version, "/games/#{year}/#{season}/schedule.xml")
32
+
33
+ return Season.new(response.xpath("/league/season-schedule"))
34
+ end
35
+
36
+ # ##
37
+ # # Fetches NCAAMB team roster
38
+ def self.team_roster(team, version = DEFAULT_VERSION)
39
+ response = self.response_xml(version, "/teams/#{team}/profile.xml")
40
+
41
+ return Team.new(response.xpath("team"))
42
+ end
43
+
44
+ # ##
45
+ # # Fetches NCAAMB game summary for a given game
46
+ def self.game_summary(game, version = DEFAULT_VERSION)
47
+ response = self.response_xml(version, "/games/#{game}/summary.xml")
48
+
49
+ return Game.new(xml: response.xpath("/game"))
50
+ end
51
+
52
+ # ##
53
+ # # Fetches all NCAAMB teams
54
+ def self.teams(version = DEFAULT_VERSION)
55
+ response = self.response_xml(version, "/league/hierarchy.xml")
56
+
57
+ return Teams.new(response.xpath('/league'))
58
+ end
59
+
60
+ # ##
61
+ # # Fetches NCAAMB daily schedule for a given date
62
+ def self.daily(year, month, day, version = DEFAULT_VERSION)
63
+ response = self.response_xml(version, "/games/#{year}/#{month}/#{day}/schedule.xml")
64
+
65
+ return Games.new(response.xpath('league/daily-schedule'))
66
+ end
67
+
68
+ # Fetches NCAAAMB tournaments for a given year and season
69
+ def self.tournament_list(year, season, version = DEFAULT_VERSION)
70
+ season = season.to_s.upcase.to_sym
71
+ raise SportsDataApi::Ncaamb::Exception.new("#{season} is not a valid season") unless TournamentList.valid?(season)
72
+
73
+ response = self.response_xml(version, "/tournaments/#{year}/#{season}/schedule.xml")
74
+
75
+ return TournamentList.new(response.xpath("/league/season-schedule"))
76
+ end
77
+
78
+ def self.tournament_schedule(year, season, tournament_id, version = DEFAULT_VERSION)
79
+ response = self.response_xml(version, "/tournaments/#{tournament_id}/schedule.xml")
80
+ raise SportsDataApi::Ncaamb::Exception.new("#{season} is not a valid season") unless TournamentSchedule.valid?(season)
81
+
82
+ return TournamentSchedule.new(year, season, response.xpath("/league/tournament-schedule"))
83
+ end
84
+
85
+ private
86
+
87
+ def self.response_xml(version, url)
88
+ base_url = BASE_URL % { access_level: SportsDataApi.access_level(SPORT), version: version }
89
+ response = SportsDataApi.generic_request("#{base_url}#{url}", SPORT)
90
+ Nokogiri::XML(response.to_s).remove_namespaces!
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,14 @@
1
+ module SportsDataApi
2
+ module Ncaamb
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,51 @@
1
+ module SportsDataApi
2
+ module Ncaamb
3
+ class Game
4
+ attr_reader :id, :scheduled, :home, :home_team, :away,
5
+ :away_team, :status, :venue, :broadcast, :year, :season,
6
+ :date, :half, :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
+ @half = xml['half'] ? xml['half'].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
+ def summary
33
+ Ncaamb.game_summary(@id)
34
+ end
35
+
36
+ ##
37
+ # Wrapper for NCAAMB.pbp (NCAAMB.play_by_play)
38
+ # TODO
39
+ def pbp
40
+ raise NotImplementedError
41
+ end
42
+
43
+ ##
44
+ # Wrapper for NCAAMB.boxscore
45
+ # TODO
46
+ def boxscore
47
+ raise NotImplementedError
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,26 @@
1
+ module SportsDataApi
2
+ module Ncaamb
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
@@ -0,0 +1,22 @@
1
+ module SportsDataApi
2
+ module Ncaamb
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 Ncaamb
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
+ # NCAAMB season type.
21
+ #
22
+ # The only valid types are: :reg, :pst, :ct
23
+ def self.valid?(season)
24
+ [:REG, :PST, :CT].include?(season)
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,40 @@
1
+ module SportsDataApi
2
+ module Ncaamb
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::Ncaamb::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 Ncaamb
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('division').each do |division|
15
+ # Division ID, e.g., D1 or D2
16
+ dname = division['alias']
17
+
18
+ division.xpath('conference').each do |conference|
19
+ # conference ID, e.g., ATLANTIC, PACIFIC
20
+ cname = conference['alias']
21
+
22
+ # Create a new team
23
+ @teams << conference.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