sports_data_api 0.12.1 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +2 -3
  3. data/lib/sports_data_api/merged_stats.rb +15 -0
  4. data/lib/sports_data_api/mlb.rb +0 -1
  5. data/lib/sports_data_api/nhl/broadcast.rb +1 -9
  6. data/lib/sports_data_api/nhl/game.rb +44 -30
  7. data/lib/sports_data_api/nhl/games.rb +16 -13
  8. data/lib/sports_data_api/nhl/player.rb +4 -25
  9. data/lib/sports_data_api/nhl/season.rb +15 -10
  10. data/lib/sports_data_api/nhl/team.rb +38 -17
  11. data/lib/sports_data_api/nhl/teams.rb +14 -65
  12. data/lib/sports_data_api/nhl/venue.rb +1 -15
  13. data/lib/sports_data_api/nhl.rb +9 -9
  14. data/lib/sports_data_api/version.rb +1 -1
  15. data/lib/sports_data_api.rb +1 -0
  16. data/spec/cassettes/sports_data_api_nhl.yml +22186 -18938
  17. data/spec/cassettes/sports_data_api_nhl_broadcast.yml +209 -193
  18. data/spec/cassettes/sports_data_api_nhl_game.yml +29397 -23777
  19. data/spec/cassettes/sports_data_api_nhl_games.yml +210 -194
  20. data/spec/cassettes/sports_data_api_nhl_league_hierarchy.yml +567 -488
  21. data/spec/cassettes/sports_data_api_nhl_player.yml +3588 -328
  22. data/spec/cassettes/sports_data_api_nhl_season.yml +15674 -18921
  23. data/spec/cassettes/sports_data_api_nhl_team.yml +3901 -2100
  24. data/spec/cassettes/sports_data_api_nhl_venue.yml +170 -193
  25. data/spec/lib/sports_data_api/{mlb/merged_stats_spec.rb → merged_stats_spec.rb} +4 -4
  26. data/spec/lib/sports_data_api/mlb/statistics_spec.rb +5 -5
  27. data/spec/lib/sports_data_api/nhl/broadcast_spec.rb +7 -4
  28. data/spec/lib/sports_data_api/nhl/game_spec.rb +65 -38
  29. data/spec/lib/sports_data_api/nhl/player_spec.rb +92 -40
  30. data/spec/lib/sports_data_api/nhl/season_spec.rb +1 -1
  31. data/spec/lib/sports_data_api/nhl/team_spec.rb +94 -182
  32. data/spec/lib/sports_data_api/nhl/teams_spec.rb +14 -65
  33. data/spec/lib/sports_data_api/nhl/venue_spec.rb +12 -9
  34. data/spec/lib/sports_data_api/nhl_spec.rb +94 -12
  35. metadata +5 -5
  36. data/lib/sports_data_api/mlb/merged_stats.rb +0 -17
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d4888a1fe1b522f022b04ab5a1dad43912e01724b336669da51685f0e7cb4968
4
- data.tar.gz: 9b56da40713366909f3b1494b75911e3b850cdf487e75bf111734b903f8404e2
3
+ metadata.gz: cbf259487fe366744f521ad3b30bb5e4135c6bf514d45c3f6f1cfcd39e08edda
4
+ data.tar.gz: 4b787131f7ccd8ab11645292a92260e62a034c037ebf6dad576b2608ba58c03f
5
5
  SHA512:
6
- metadata.gz: 164a6298a5414f720977869729b04f613a6e89ea63dd271b67f33690138be6faa0629364dd4a117526e170317f28376cf92bc5d7747c6497cbeb73897e16edc9
7
- data.tar.gz: 4576fecccd6f384c20d7adc31fa45e2ef3593236c1c3263f01feb2227757d0e64e2e64f7481784b0738c6ba3b6776d6dcca0f02b229de491f8d12c371aa75299
6
+ metadata.gz: 21daae5927341cf9fa9421affff4fae33b0eaa19c9988e80732a7905dafecb3507d939d80ff5323e49ad46bf518b6a9eb92e59a64ba570b7119fb9fd05eac37e
7
+ data.tar.gz: a2e3e1c5586471ecffa85f56a3b01f17262bed8cbefcff029c68f0ccb80f70aa9a4d968fa193ccfe049a5a91746a96722b7b0e38bdb0d84da173be9f4a1f2597
data/.travis.yml CHANGED
@@ -3,9 +3,8 @@ before_install: gem install bundler && bundler -v
3
3
  rvm:
4
4
  - 2.2
5
5
  - 2.3
6
- - 2.4.0
7
- - 2.5.0
8
- - ruby-head
6
+ - 2.4
7
+ - 2.5
9
8
  addons:
10
9
  code_climate:
11
10
  repo_token: a3efbc440cb5027fc10a3cfa845aab934cf8c48c27fa0b2ff34855933245aca1
@@ -0,0 +1,15 @@
1
+ module SportsDataApi
2
+ class MergedStats < JsonData
3
+ def initialize(json, override_var_name = nil)
4
+ super(json, override_var_name)
5
+ ivar = instance_variable_get("@#{instance_var_name}")
6
+ json.each do |key, val|
7
+ next unless val.is_a? Hash
8
+ json[key].each do |sub_key, data|
9
+ ivar["#{key}_#{sub_key}".to_sym] = data
10
+ end
11
+ ivar.delete key.to_sym
12
+ end
13
+ end
14
+ end
15
+ end
@@ -13,7 +13,6 @@ module SportsDataApi
13
13
  autoload :Division, File.join(DIR, 'division')
14
14
  autoload :Game, File.join(DIR, 'game')
15
15
  autoload :League, File.join(DIR, 'league')
16
- autoload :MergedStats, File.join(DIR, 'merged_stats')
17
16
  autoload :Player, File.join(DIR, 'player')
18
17
  autoload :Scoring, File.join(DIR, 'scoring')
19
18
  autoload :Statistics, File.join(DIR, 'statistics')
@@ -1,14 +1,6 @@
1
1
  module SportsDataApi
2
2
  module Nhl
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
3
+ class Broadcast < SportsDataApi::JsonData
12
4
  end
13
5
  end
14
6
  end
@@ -1,41 +1,51 @@
1
1
  module SportsDataApi
2
2
  module Nhl
3
3
  class Game
4
- attr_reader :id, :scheduled, :home, :home_team, :away,
5
- :away_team, :status, :venue, :broadcast, :year, :season,
6
- :date, :period, :clock, :home_team_id, :away_team_id
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
- @home_team_id = xml['home_team']
21
- @away_team_id = xml['away_team']
22
- @status = xml['status']
23
- @clock = xml['clock']
24
- @period = xml['period'] ? xml['period'].to_i : nil
25
-
26
- team_xml = xml.xpath('team')
27
- @home_team = Team.new(team_xml.first)
28
- @away_team = Team.new(team_xml.last)
29
- @venue = Venue.new(xml.xpath('venue'))
30
- @broadcast = Broadcast.new(xml.xpath('broadcast'))
31
- end
4
+ attr_reader :id, :status, :year, :season, :clock,
5
+ :home_team_id, :away_team_id
6
+
7
+ def initialize(json:, year: nil, season: nil)
8
+ @json = json
9
+ @year = year
10
+ @season = season
11
+ @id = json['id']
12
+ @home_team_id = json['home']['id']
13
+ @away_team_id = json['away']['id']
14
+ @status = json['status']
15
+ @clock = json['clock']
16
+ end
17
+
18
+ def period
19
+ return unless json['period']
20
+ json['period'].to_i
21
+ end
22
+
23
+ def scheduled
24
+ @scheduled = Time.parse(json['scheduled'])
25
+ end
26
+
27
+ def home_team
28
+ @home_team ||= Team.new(json['home'])
29
+ end
30
+
31
+ def away_team
32
+ @away_team ||= Team.new(json['away'])
33
+ end
34
+
35
+ def broadcast
36
+ return if json['broadcast'].nil? || json['broadcast'].empty?
37
+ @broadcast ||= Broadcast.new(json['broadcast'])
38
+ end
39
+
40
+ def venue
41
+ return if json['venue'].nil? || json['venue'].empty?
42
+ @venue ||= Venue.new(json['venue'])
32
43
  end
33
44
 
34
45
  ##
35
46
  # Wrapper for Nhl.game_summary
36
- # TODO
37
47
  def summary
38
- Nhl.game_summary(@id)
48
+ Nhl.game_summary(id)
39
49
  end
40
50
 
41
51
  ##
@@ -51,6 +61,10 @@ module SportsDataApi
51
61
  def boxscore
52
62
  raise NotImplementedError
53
63
  end
64
+
65
+ private
66
+
67
+ attr_reader :json
54
68
  end
55
69
  end
56
70
  end
@@ -2,25 +2,28 @@ module SportsDataApi
2
2
  module Nhl
3
3
  class Games
4
4
  include Enumerable
5
- attr_reader :games, :date
6
5
 
7
- def initialize(xml)
8
- @date = xml.first['date']
6
+ attr_reader :date
9
7
 
10
- @games = xml.xpath("games/game").map do |game_xml|
11
- Game.new(date: @date, xml: game_xml)
12
- end
8
+ def initialize(json)
9
+ @json = json
10
+ @date = json['date']
13
11
  end
14
12
 
15
- def each &block
16
- @games.each do |game|
17
- if block_given?
18
- block.call game
19
- else
20
- yield game
21
- end
13
+ def games
14
+ @games ||= json['games'].map do |game_json|
15
+ Game.new(json: game_json)
22
16
  end
23
17
  end
18
+
19
+ def each
20
+ return games.each unless block_given?
21
+ games.each { |game| yield game }
22
+ end
23
+
24
+ private
25
+
26
+ attr_reader :json
24
27
  end
25
28
  end
26
29
  end
@@ -1,30 +1,9 @@
1
1
  module SportsDataApi
2
2
  module Nhl
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
-
19
- if @stats
20
- goaltending_xml = xml.xpath('goaltending').first
21
- if goaltending_xml.is_a? Nokogiri::XML::Element
22
- goaltending_ivar = @stats.instance_variable_set("@#{goaltending_xml.name}", {})
23
- @stats.class.class_eval { attr_reader :"#{goaltending_xml.name}" }
24
- goaltending_xml.attributes.each { |attr_name, attr_value| goaltending_ivar[attr_name.to_sym] = attr_value.value }
25
- end
26
- end
27
- end
3
+ class Player < SportsDataApi::JsonData
4
+ def stats
5
+ return if player[:statistics].nil? || player[:statistics].empty?
6
+ @stats ||= SportsDataApi::MergedStats.new(player[:statistics])
28
7
  end
29
8
  end
30
9
  end
@@ -1,17 +1,18 @@
1
1
  module SportsDataApi
2
2
  module Nhl
3
3
  class Season
4
- attr_reader :id, :year, :type, :games
4
+ attr_reader :id, :year, :type
5
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
6
+ def initialize(json)
7
+ @json = json
8
+ @id = json['season']['id']
9
+ @year = json['season']['year']
10
+ @type = json['season']['type'].to_sym
11
+ end
11
12
 
12
- @games = xml.first.xpath("games/game").map do |game_xml|
13
- Game.new(year: @year, season: @type, xml: game_xml)
14
- end
13
+ def games
14
+ @games ||= json['games'].map do |game_json|
15
+ Game.new(year: year, season: type, json: game_json)
15
16
  end
16
17
  end
17
18
 
@@ -21,8 +22,12 @@ module SportsDataApi
21
22
  #
22
23
  # The only valid types are: :pre, :reg, :pst
23
24
  def self.valid?(season)
24
- [:PRE, :REG, :PST].include?(season)
25
+ %i[PRE REG PST].include?(season)
25
26
  end
27
+
28
+ private
29
+
30
+ attr_reader :json
26
31
  end
27
32
  end
28
33
  end
@@ -1,29 +1,46 @@
1
1
  module SportsDataApi
2
2
  module Nhl
3
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
4
+ attr_reader :id, :name, :market, :alias
5
+
6
+ def initialize(json, conference = nil, division = nil)
7
+ @json = json
8
+ @id = json['id']
9
+ @name = json['name']
10
+ @market = json['market']
11
+ @alias = json['alias']
12
+ @conference = conference
13
+ @division = division
14
+ end
15
+
16
+ def conference
17
+ @conference ||= json.fetch('conference', {})['alias']
18
+ end
19
+
20
+ def division
21
+ @division ||= json.fetch('division', {})['alias']
22
+ end
23
+
24
+ def points
25
+ return unless json['points']
26
+ json['points'].to_i
27
+ end
28
+
29
+ def players
30
+ return [] if json['players'].nil?
31
+ @players ||= json['players'].map do |player_json|
32
+ Player.new(player_json)
20
33
  end
21
34
  end
22
35
 
36
+ def venue
37
+ return if json['venue'].nil?
38
+ @venue ||= Venue.new(json['venue'])
39
+ end
40
+
23
41
  ##
24
42
  # Compare the Team with another team
25
43
  def ==(other)
26
- # Must have an id to compare
27
44
  return false if id.nil?
28
45
 
29
46
  if other.is_a? SportsDataApi::Nhl::Team
@@ -34,6 +51,10 @@ module SportsDataApi
34
51
  super(other)
35
52
  end
36
53
  end
54
+
55
+ private
56
+
57
+ attr_reader :json
37
58
  end
38
59
  end
39
60
  end
@@ -3,81 +3,30 @@ module SportsDataApi
3
3
  class Teams
4
4
  include Enumerable
5
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']
6
+ def initialize(json)
7
+ @json = json
8
+ end
21
9
 
22
- # Create a new team
23
- @teams << division.xpath('team').map { |team| Team.new(team, cname, dname) }
10
+ def teams
11
+ @teams ||= json['conferences'].flat_map do |conference|
12
+ conference['divisions'].flat_map do |division|
13
+ division['teams'].map do |team_json|
14
+ Team.new(team_json, conference['alias'], division['alias'])
24
15
  end
25
16
  end
26
17
  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
18
  end
45
19
 
46
20
  ##
47
- #
48
- def respond_to?(method)
49
- @allowed_conferences.include?(method) || @allowed_divisions.include?(method)
21
+ # Make the class Enumerable
22
+ def each
23
+ return teams.each unless block_given?
24
+ teams.each { |team| yield team }
50
25
  end
51
26
 
52
- ##
53
- #
54
- def method_missing(method)
55
- if @allowed_conferences.include?(method)
56
- @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
- @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
27
+ private
69
28
 
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
29
+ attr_reader :json
81
30
  end
82
31
  end
83
32
  end
@@ -1,20 +1,6 @@
1
1
  module SportsDataApi
2
2
  module Nhl
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
3
+ class Venue < SportsDataApi::JsonData
18
4
  end
19
5
  end
20
6
  end
@@ -5,8 +5,8 @@ module SportsDataApi
5
5
  class Exception < ::Exception
6
6
  end
7
7
 
8
- API_VERSION = 4
9
- BASE_URL = 'https://api.sportsdatallc.org/nhl-%{access_level}%{version}'
8
+ API_VERSION = 5
9
+ BASE_URL = 'https://api.sportradar.us/nhl/%{access_level}/v%{version}/en'
10
10
  DIR = File.join(File.dirname(__FILE__), 'nhl')
11
11
  SPORT = :nhl
12
12
 
@@ -26,31 +26,31 @@ module SportsDataApi
26
26
  season = season.to_s.upcase.to_sym
27
27
  raise Exception.new("#{season} is not a valid season") unless Season.valid?(season)
28
28
 
29
- Season.new(response_xml_xpath("/games/#{year}/#{season}/schedule.xml", '/league/season-schedule'))
29
+ Season.new(response_json("/games/#{year}/#{season}/schedule.json"))
30
30
  end
31
31
 
32
32
  ##
33
33
  # Fetches NHL team roster
34
- def team_roster(team)
35
- Team.new(response_xml_xpath("/teams/#{team}/profile.xml", 'team'))
34
+ def team_roster(team_id)
35
+ Team.new(response_json("/teams/#{team_id}/profile.json"))
36
36
  end
37
37
 
38
38
  ##
39
39
  # Fetches NHL game summary for a given game
40
- def game_summary(game)
41
- Game.new(xml: response_xml_xpath("/games/#{game}/summary.xml", '/game'))
40
+ def game_summary(game_id)
41
+ Game.new(json: response_json("/games/#{game_id}/summary.json"))
42
42
  end
43
43
 
44
44
  ##
45
45
  # Fetches all NHL teams
46
46
  def teams
47
- Teams.new(response_xml_xpath("/league/hierarchy.xml", '/league'))
47
+ Teams.new(response_json('/league/hierarchy.json'))
48
48
  end
49
49
 
50
50
  ##
51
51
  # Fetches NHL daily schedule for a given date
52
52
  def daily(year, month, day)
53
- Games.new(response_xml_xpath("/games/#{year}/#{month}/#{day}/schedule.xml", 'league/daily-schedule'))
53
+ Games.new(response_json("/games/#{year}/#{month}/#{day}/schedule.json"))
54
54
  end
55
55
  end
56
56
  end
@@ -1,3 +1,3 @@
1
1
  module SportsDataApi
2
- VERSION = '0.12.1'
2
+ VERSION = '0.13.0'
3
3
  end
@@ -57,6 +57,7 @@ module SportsDataApi
57
57
  autoload :Exception, File.join(LIBRARY_PATH, 'exception')
58
58
  autoload :Golf, File.join(LIBRARY_PATH, 'golf')
59
59
  autoload :JsonData, File.join(LIBRARY_PATH, 'json_data')
60
+ autoload :MergedStats, File.join(LIBRARY_PATH, 'merged_stats')
60
61
  autoload :Mlb, File.join(LIBRARY_PATH, 'mlb')
61
62
  autoload :Nba, File.join(LIBRARY_PATH, 'nba')
62
63
  autoload :Ncaafb, File.join(LIBRARY_PATH, 'ncaafb')