sports_data_api 0.12.1 → 0.13.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.
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')