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.
- checksums.yaml +4 -4
- data/.travis.yml +2 -3
- data/lib/sports_data_api/merged_stats.rb +15 -0
- data/lib/sports_data_api/mlb.rb +0 -1
- data/lib/sports_data_api/nhl/broadcast.rb +1 -9
- data/lib/sports_data_api/nhl/game.rb +44 -30
- data/lib/sports_data_api/nhl/games.rb +16 -13
- data/lib/sports_data_api/nhl/player.rb +4 -25
- data/lib/sports_data_api/nhl/season.rb +15 -10
- data/lib/sports_data_api/nhl/team.rb +38 -17
- data/lib/sports_data_api/nhl/teams.rb +14 -65
- data/lib/sports_data_api/nhl/venue.rb +1 -15
- data/lib/sports_data_api/nhl.rb +9 -9
- data/lib/sports_data_api/version.rb +1 -1
- data/lib/sports_data_api.rb +1 -0
- data/spec/cassettes/sports_data_api_nhl.yml +22186 -18938
- data/spec/cassettes/sports_data_api_nhl_broadcast.yml +209 -193
- data/spec/cassettes/sports_data_api_nhl_game.yml +29397 -23777
- data/spec/cassettes/sports_data_api_nhl_games.yml +210 -194
- data/spec/cassettes/sports_data_api_nhl_league_hierarchy.yml +567 -488
- data/spec/cassettes/sports_data_api_nhl_player.yml +3588 -328
- data/spec/cassettes/sports_data_api_nhl_season.yml +15674 -18921
- data/spec/cassettes/sports_data_api_nhl_team.yml +3901 -2100
- data/spec/cassettes/sports_data_api_nhl_venue.yml +170 -193
- data/spec/lib/sports_data_api/{mlb/merged_stats_spec.rb → merged_stats_spec.rb} +4 -4
- data/spec/lib/sports_data_api/mlb/statistics_spec.rb +5 -5
- data/spec/lib/sports_data_api/nhl/broadcast_spec.rb +7 -4
- data/spec/lib/sports_data_api/nhl/game_spec.rb +65 -38
- data/spec/lib/sports_data_api/nhl/player_spec.rb +92 -40
- data/spec/lib/sports_data_api/nhl/season_spec.rb +1 -1
- data/spec/lib/sports_data_api/nhl/team_spec.rb +94 -182
- data/spec/lib/sports_data_api/nhl/teams_spec.rb +14 -65
- data/spec/lib/sports_data_api/nhl/venue_spec.rb +12 -9
- data/spec/lib/sports_data_api/nhl_spec.rb +94 -12
- metadata +5 -5
- 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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cbf259487fe366744f521ad3b30bb5e4135c6bf514d45c3f6f1cfcd39e08edda
|
4
|
+
data.tar.gz: 4b787131f7ccd8ab11645292a92260e62a034c037ebf6dad576b2608ba58c03f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 21daae5927341cf9fa9421affff4fae33b0eaa19c9988e80732a7905dafecb3507d939d80ff5323e49ad46bf518b6a9eb92e59a64ba570b7119fb9fd05eac37e
|
7
|
+
data.tar.gz: a2e3e1c5586471ecffa85f56a3b01f17262bed8cbefcff029c68f0ccb80f70aa9a4d968fa193ccfe049a5a91746a96722b7b0e38bdb0d84da173be9f4a1f2597
|
data/.travis.yml
CHANGED
@@ -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
|
data/lib/sports_data_api/mlb.rb
CHANGED
@@ -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, :
|
5
|
-
:
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
@
|
11
|
-
@
|
12
|
-
@
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
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(
|
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
|
-
|
8
|
-
@date = xml.first['date']
|
6
|
+
attr_reader :date
|
9
7
|
|
10
|
-
|
11
|
-
|
12
|
-
|
8
|
+
def initialize(json)
|
9
|
+
@json = json
|
10
|
+
@date = json['date']
|
13
11
|
end
|
14
12
|
|
15
|
-
def
|
16
|
-
@games.
|
17
|
-
|
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
|
-
|
5
|
-
|
6
|
-
|
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
|
4
|
+
attr_reader :id, :year, :type
|
5
5
|
|
6
|
-
def initialize(
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
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
|
-
|
13
|
-
|
14
|
-
|
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
|
-
[
|
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
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
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
|
-
|
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
|
-
|
23
|
-
|
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
|
49
|
-
|
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
|
data/lib/sports_data_api/nhl.rb
CHANGED
@@ -5,8 +5,8 @@ module SportsDataApi
|
|
5
5
|
class Exception < ::Exception
|
6
6
|
end
|
7
7
|
|
8
|
-
API_VERSION =
|
9
|
-
BASE_URL = 'https://api.
|
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(
|
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(
|
35
|
-
Team.new(
|
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(
|
41
|
-
Game.new(
|
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(
|
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(
|
53
|
+
Games.new(response_json("/games/#{year}/#{month}/#{day}/schedule.json"))
|
54
54
|
end
|
55
55
|
end
|
56
56
|
end
|
data/lib/sports_data_api.rb
CHANGED
@@ -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')
|