opta_sd 1.0.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 +1 -0
- data/.rspec +3 -0
- data/Gemfile +22 -0
- data/Gemfile.lock +63 -0
- data/MIT-LICENSE +20 -0
- data/README.md +400 -0
- data/Rakefile +1 -0
- data/config/opta_sd.yml +2 -0
- data/config/parameters.yml +74 -0
- data/errors.yml +21 -0
- data/lib/opta_sd.rb +42 -0
- data/lib/opta_sd/core.rb +119 -0
- data/lib/opta_sd/error.rb +31 -0
- data/lib/opta_sd/soccer/commentary.rb +21 -0
- data/lib/opta_sd/soccer/match.rb +20 -0
- data/lib/opta_sd/soccer/match_event.rb +13 -0
- data/lib/opta_sd/soccer/match_facts.rb +14 -0
- data/lib/opta_sd/soccer/match_preview.rb +14 -0
- data/lib/opta_sd/soccer/match_statistics.rb +14 -0
- data/lib/opta_sd/soccer/pass_matrix.rb +14 -0
- data/lib/opta_sd/soccer/player_career.rb +15 -0
- data/lib/opta_sd/soccer/possession.rb +13 -0
- data/lib/opta_sd/soccer/rankings.rb +14 -0
- data/lib/opta_sd/soccer/seasonal_stats.rb +14 -0
- data/lib/opta_sd/soccer/soccer.rb +19 -0
- data/lib/opta_sd/soccer/squads.rb +14 -0
- data/lib/opta_sd/soccer/team_standings.rb +22 -0
- data/lib/opta_sd/soccer/tournament_calendar.rb +24 -0
- data/lib/opta_sd/soccer/tournament_schedule.rb +14 -0
- data/lib/opta_sd/version.rb +3 -0
- data/opta_sd.gemspec +27 -0
- data/spec/commentary_spec.rb +39 -0
- data/spec/match_event_spec.rb +26 -0
- data/spec/match_facts_spec.rb +14 -0
- data/spec/match_preview_spec.rb +15 -0
- data/spec/match_spec.rb +32 -0
- data/spec/match_statistics_spec.rb +43 -0
- data/spec/pass_matrix_spec.rb +27 -0
- data/spec/player_career_spec.rb +38 -0
- data/spec/possession_spec.rb +23 -0
- data/spec/rankings_spec.rb +14 -0
- data/spec/seasonal_stats_spec.rb +26 -0
- data/spec/spec_helper.rb +15 -0
- data/spec/squads.rb +40 -0
- data/spec/team_standings_spec.rb +61 -0
- data/spec/tournament_schedule_spec.rb +13 -0
- data/spec/tournament_spec.rb +48 -0
- metadata +169 -0
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
data/config/opta_sd.yml
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
core:
|
2
|
+
_rt: "_rt"
|
3
|
+
_format: "_fmt"
|
4
|
+
_locale: "_lcl"
|
5
|
+
_callback: "_clbk"
|
6
|
+
_sort: "_ordSrt"
|
7
|
+
_page_size: "_pgSz"
|
8
|
+
_page_number: "_pgNm"
|
9
|
+
|
10
|
+
match:
|
11
|
+
fixture: "fx"
|
12
|
+
tournament: "tmcl" # tournament_calendar
|
13
|
+
stage: "stg"
|
14
|
+
competition: "comp"
|
15
|
+
contestant: "ctst"
|
16
|
+
match_time: "mt.mDt"
|
17
|
+
match_date: "mt.mDt"
|
18
|
+
live: "live"
|
19
|
+
lineups: "lineups"
|
20
|
+
status: "status"
|
21
|
+
|
22
|
+
tournamentcalendar:
|
23
|
+
competition: "comp"
|
24
|
+
|
25
|
+
squads:
|
26
|
+
tournament: "tmcl"
|
27
|
+
contestant: "ctst"
|
28
|
+
detailed: "detailed"
|
29
|
+
people: "people"
|
30
|
+
|
31
|
+
possession:
|
32
|
+
fixture: "fx"
|
33
|
+
|
34
|
+
matchevent:
|
35
|
+
fixture: "fx"
|
36
|
+
|
37
|
+
matchstats:
|
38
|
+
fixture: "fx"
|
39
|
+
detailed: "detailed"
|
40
|
+
|
41
|
+
passmatrix:
|
42
|
+
fixture: "fx"
|
43
|
+
|
44
|
+
commentary:
|
45
|
+
fixture: "fx"
|
46
|
+
type: "type"
|
47
|
+
|
48
|
+
matchfacts:
|
49
|
+
fixture: "fx"
|
50
|
+
|
51
|
+
seasonstats:
|
52
|
+
tournament: "tmcl"
|
53
|
+
contestant: "ctst"
|
54
|
+
competition: "comp"
|
55
|
+
|
56
|
+
standings:
|
57
|
+
stage: "stg"
|
58
|
+
tournament: "tmcl"
|
59
|
+
live: "live"
|
60
|
+
type: "type"
|
61
|
+
|
62
|
+
playercareer:
|
63
|
+
person: "prsn"
|
64
|
+
active: "active"
|
65
|
+
contestant: "ctst"
|
66
|
+
|
67
|
+
matchpreview:
|
68
|
+
fixture: "fx"
|
69
|
+
|
70
|
+
rankings:
|
71
|
+
tournament: "tmcl"
|
72
|
+
|
73
|
+
tournamentschedule:
|
74
|
+
tournament: "tmcl"
|
data/errors.yml
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
10000: "An unexpected error has occurred"
|
2
|
+
10001: "Page not found error"
|
3
|
+
10010: "Outlet doesn't exist"
|
4
|
+
10100: "Feed Unavailable"
|
5
|
+
|
6
|
+
10200: "Missing request parameter"
|
7
|
+
10201: "Unknown request parameter"
|
8
|
+
10202: "Invalid request parameter value"
|
9
|
+
10203: "Ambiguous/Invalid request parameters"
|
10
|
+
10204: "Invalid request method"
|
11
|
+
10210: "Unsupported format: _fmt parameter"
|
12
|
+
10212: "Unsupported mode: _rt parameter"
|
13
|
+
10217: "Invalid pagination: _pgNm, _pgSz parameters"
|
14
|
+
10219: "_pgSz parameter above maximum"
|
15
|
+
|
16
|
+
10300: "Feed Access Denied"
|
17
|
+
10313: "User not Authorised"
|
18
|
+
10320: "Acceptable usage exceeded"
|
19
|
+
|
20
|
+
10400: "No data found"
|
21
|
+
10401: "Data request timeout"
|
data/lib/opta_sd.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
# Project Requirements
|
2
|
+
require 'yaml'
|
3
|
+
require 'json'
|
4
|
+
require 'nokogiri'
|
5
|
+
require 'net/http'
|
6
|
+
|
7
|
+
# Core Classes
|
8
|
+
require 'opta_sd/core'
|
9
|
+
require 'opta_sd/error'
|
10
|
+
require 'opta_sd/soccer/soccer'
|
11
|
+
require 'opta_sd/soccer/match'
|
12
|
+
require 'opta_sd/soccer/squads'
|
13
|
+
require 'opta_sd/soccer/rankings'
|
14
|
+
require 'opta_sd/soccer/commentary'
|
15
|
+
require 'opta_sd/soccer/possession'
|
16
|
+
require 'opta_sd/soccer/match_event'
|
17
|
+
require 'opta_sd/soccer/match_facts'
|
18
|
+
require 'opta_sd/soccer/pass_matrix'
|
19
|
+
require 'opta_sd/soccer/player_career'
|
20
|
+
require 'opta_sd/soccer/match_preview'
|
21
|
+
require 'opta_sd/soccer/seasonal_stats'
|
22
|
+
require 'opta_sd/soccer/team_standings'
|
23
|
+
require 'opta_sd/soccer/match_statistics'
|
24
|
+
require 'opta_sd/soccer/tournament_calendar'
|
25
|
+
require 'opta_sd/soccer/tournament_schedule'
|
26
|
+
|
27
|
+
|
28
|
+
# Wrapper Classes
|
29
|
+
# Soon
|
30
|
+
|
31
|
+
# Add present? to Object
|
32
|
+
class Object
|
33
|
+
def present?
|
34
|
+
!blank?
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class NilClass
|
39
|
+
def blank?
|
40
|
+
nil?
|
41
|
+
end
|
42
|
+
end
|
data/lib/opta_sd/core.rb
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
module OptaSD
|
2
|
+
class Core
|
3
|
+
|
4
|
+
PARAMETERS = YAML::load(File.open(File.expand_path('../../../config/parameters.yml', __FILE__)))
|
5
|
+
|
6
|
+
attr_reader :data
|
7
|
+
|
8
|
+
# The Initialize
|
9
|
+
def initialize
|
10
|
+
set_configuration
|
11
|
+
@params = Hash.new
|
12
|
+
end
|
13
|
+
|
14
|
+
# Build the Request and get the Data
|
15
|
+
def get
|
16
|
+
response = Net::HTTP.get(build_uri)
|
17
|
+
@data = parse_data(response)
|
18
|
+
self
|
19
|
+
end
|
20
|
+
|
21
|
+
# Parse The Response
|
22
|
+
def parse_data(response)
|
23
|
+
case @params[:_fmt]
|
24
|
+
when 'json' then parse_json(response)
|
25
|
+
when 'xml' then parse_xml(response)
|
26
|
+
else response end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Parse JSON Response
|
30
|
+
def parse_json(response)
|
31
|
+
data = JSON.parse(response)
|
32
|
+
fail OptaSD::Error.new(data), ErrorMessage.get_message(data['errorCode'].to_i) if data['errorCode']
|
33
|
+
data
|
34
|
+
end
|
35
|
+
|
36
|
+
# Parse XML Response
|
37
|
+
def parse_xml(response)
|
38
|
+
data = Nokogiri::XML(response) do |config| config.strict.noblanks end
|
39
|
+
fail OptaSD::Error.new(xml_error_to_hast(data)), ErrorMessage.get_message(data.children.first.content.to_i) if data.css('errorCode').first.present?
|
40
|
+
data
|
41
|
+
end
|
42
|
+
|
43
|
+
# Define Core API Parameters
|
44
|
+
PARAMETERS['core'].keys.each do |param_name|
|
45
|
+
define_method param_name do |value|
|
46
|
+
@params[PARAMETERS['core'][param_name].to_sym] = value
|
47
|
+
self
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
# Load OPTA SD API Configurations from `config_file`
|
54
|
+
def set_configuration
|
55
|
+
config = config_file
|
56
|
+
@domain = config['opta_domain']
|
57
|
+
@auth_token = config['opta_auth_token']
|
58
|
+
end
|
59
|
+
|
60
|
+
# Load Configurations file 'config/opta_sd_api.yml'
|
61
|
+
def config_file
|
62
|
+
YAML::load(File.open(File.expand_path('../../../config/opta_sd.yml', __FILE__)))
|
63
|
+
end
|
64
|
+
|
65
|
+
# Build the Base URL of the Request
|
66
|
+
def build_url
|
67
|
+
[
|
68
|
+
@domain,
|
69
|
+
@sport,
|
70
|
+
@feed_name,
|
71
|
+
@auth_token,
|
72
|
+
@resource
|
73
|
+
].compact.join('/')
|
74
|
+
end
|
75
|
+
|
76
|
+
# Convert Params from Hash To URI Query
|
77
|
+
def build_params
|
78
|
+
self._format('json') unless @params[:_fmt]
|
79
|
+
self._rt('b') unless @params[:_rt]
|
80
|
+
URI.encode_www_form(@params)
|
81
|
+
end
|
82
|
+
|
83
|
+
# Generate valid URI for the request
|
84
|
+
def build_uri
|
85
|
+
# puts [build_url, build_params].join('?')
|
86
|
+
URI.parse([build_url, build_params].join('?'))
|
87
|
+
end
|
88
|
+
|
89
|
+
def xml_error_to_hast(data)
|
90
|
+
{
|
91
|
+
"errorCode" => data.children.first.content.to_i,
|
92
|
+
"token" => data.children.first['token']
|
93
|
+
}
|
94
|
+
end
|
95
|
+
|
96
|
+
## ---------------------------------------- ##
|
97
|
+
|
98
|
+
# Define resource for Boolean Parameters
|
99
|
+
def self.boolean_params(model , *args)
|
100
|
+
args.each do |param_name|
|
101
|
+
define_method param_name do |value = true|
|
102
|
+
@params[PARAMETERS[model.to_s][param_name.to_s]] = value ? 'yes' : 'no'
|
103
|
+
self
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# Define Pesource Parameters
|
109
|
+
def self.resource_params(model, *args)
|
110
|
+
args.each do |param_name|
|
111
|
+
define_method param_name do |value|
|
112
|
+
@params[PARAMETERS[model.to_s][param_name.to_s] || param_name.to_s] = value
|
113
|
+
self
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module OptaSD
|
2
|
+
class Error < StandardError
|
3
|
+
attr_reader :env, :message
|
4
|
+
attr_reader :response, :error_code, :token
|
5
|
+
|
6
|
+
def initialize(response)
|
7
|
+
|
8
|
+
unless response.instance_of? Hash
|
9
|
+
fail ::ArgumentError, 'Response passed to OptaSD::Error must be a hash'
|
10
|
+
end
|
11
|
+
|
12
|
+
@error_code = response["errorCode"]
|
13
|
+
@message = ErrorMessage.get_message(@error_code.to_i)
|
14
|
+
@token = response["token"]
|
15
|
+
|
16
|
+
log_error
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def log_error
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class ErrorMessage
|
26
|
+
def self.get_message(error_code)
|
27
|
+
errors = YAML::load(File.open(File.expand_path('../../../errors.yml', __FILE__)))
|
28
|
+
errors[error_code.to_i]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module OptaSD
|
2
|
+
module Soccer
|
3
|
+
class Commentary < OptaSD::Soccer::SoccerCore
|
4
|
+
|
5
|
+
resource_params 'commentary', :fixture, :type
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
super
|
9
|
+
@feed_name = 'commentary'
|
10
|
+
end
|
11
|
+
|
12
|
+
%w(auto fallback manual).each do |type_value|
|
13
|
+
define_method type_value do
|
14
|
+
self.type(type_value)
|
15
|
+
self
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module OptaSD
|
2
|
+
module Soccer
|
3
|
+
class Match < OptaSD::Soccer::SoccerCore
|
4
|
+
|
5
|
+
boolean_params 'match', :live, :lineups
|
6
|
+
resource_params 'match', :fixture, :tournament, :stage, :competition, :contestant, :match_time, :match_date, :status
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
super
|
10
|
+
@feed_name = 'match'
|
11
|
+
end
|
12
|
+
|
13
|
+
def time_range(from, to)
|
14
|
+
match_time("[#{from.strftime('%Y-%m-%dT%H:%M:%SZ')} TO #{to.strftime('%Y-%m-%dT%H:%M:%SZ')}]")
|
15
|
+
return self
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module OptaSD
|
2
|
+
module Soccer
|
3
|
+
class PlayerCareer < OptaSD::Soccer::SoccerCore
|
4
|
+
|
5
|
+
boolean_params 'playercareer', :active
|
6
|
+
resource_params 'playercareer', :person, :contestant
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
super
|
10
|
+
@feed_name = 'playercareer'
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|