football-butler 1.1.0 → 2.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/lib/football/butler/api.rb +10 -16
  3. data/lib/football/butler/api_football/base_api_football.rb +17 -0
  4. data/lib/football/butler/api_football/coachs.rb +46 -0
  5. data/lib/football/butler/api_football/countries.rb +39 -0
  6. data/lib/football/butler/api_football/fixtures.rb +80 -0
  7. data/lib/football/butler/api_football/head_to_head.rb +56 -0
  8. data/lib/football/butler/api_football/injuries.rb +62 -0
  9. data/lib/football/butler/api_football/leagues.rb +101 -0
  10. data/lib/football/butler/api_football/lineups.rb +39 -0
  11. data/lib/football/butler/api_football/odds.rb +55 -0
  12. data/lib/football/butler/api_football/players.rb +47 -0
  13. data/lib/football/butler/api_football/predictions.rb +27 -0
  14. data/lib/football/butler/api_football/sidelineds.rb +37 -0
  15. data/lib/football/butler/api_football/standings.rb +35 -0
  16. data/lib/football/butler/api_football/statistics.rb +22 -0
  17. data/lib/football/butler/api_football/teams.rb +66 -0
  18. data/lib/football/butler/api_football/timezones.rb +21 -0
  19. data/lib/football/butler/api_football/top_scorers.rb +22 -0
  20. data/lib/football/butler/api_football/transfers.rb +36 -0
  21. data/lib/football/butler/api_football/trophies.rb +37 -0
  22. data/lib/football/butler/api_football/venues.rb +66 -0
  23. data/lib/football/butler/apifootball/base_apifootball.rb +17 -0
  24. data/lib/football/butler/apifootball/competitions.rb +30 -0
  25. data/lib/football/butler/apifootball/countries.rb +20 -0
  26. data/lib/football/butler/apifootball/events.rb +61 -0
  27. data/lib/football/butler/apifootball/head_to_head.rb +30 -0
  28. data/lib/football/butler/apifootball/lineups.rb +22 -0
  29. data/lib/football/butler/apifootball/odds.rb +25 -0
  30. data/lib/football/butler/apifootball/players.rb +27 -0
  31. data/lib/football/butler/apifootball/predictions.rb +28 -0
  32. data/lib/football/butler/apifootball/standings.rb +23 -0
  33. data/lib/football/butler/apifootball/statistics.rb +22 -0
  34. data/lib/football/butler/apifootball/teams.rb +29 -0
  35. data/lib/football/butler/apifootball/top_scorers.rb +22 -0
  36. data/lib/football/butler/areas.rb +23 -23
  37. data/lib/football/butler/base.rb +45 -18
  38. data/lib/football/butler/coachs.rb +26 -0
  39. data/lib/football/butler/competitions.rb +53 -44
  40. data/lib/football/butler/configuration.rb +275 -14
  41. data/lib/football/butler/countries.rb +11 -0
  42. data/lib/football/butler/events.rb +11 -0
  43. data/lib/football/butler/fixtures.rb +11 -0
  44. data/lib/football/butler/football_data/areas.rb +40 -0
  45. data/lib/football/butler/football_data/competitions.rb +72 -0
  46. data/lib/football/butler/football_data/head_to_head.rb +27 -0
  47. data/lib/football/butler/football_data/lineups.rb +32 -0
  48. data/lib/football/butler/football_data/matches.rb +110 -0
  49. data/lib/football/butler/football_data/odds.rb +27 -0
  50. data/lib/football/butler/football_data/players.rb +20 -0
  51. data/lib/football/butler/football_data/scorers.rb +23 -0
  52. data/lib/football/butler/football_data/standings.rb +47 -0
  53. data/lib/football/butler/football_data/teams.rb +39 -0
  54. data/lib/football/butler/head_to_head.rb +28 -0
  55. data/lib/football/butler/injuries.rb +31 -0
  56. data/lib/football/butler/leagues.rb +11 -0
  57. data/lib/football/butler/lineups.rb +18 -0
  58. data/lib/football/butler/matches.rb +48 -83
  59. data/lib/football/butler/odds.rb +18 -0
  60. data/lib/football/butler/players.rb +26 -0
  61. data/lib/football/butler/predictions.rb +17 -0
  62. data/lib/football/butler/scorers.rb +22 -0
  63. data/lib/football/butler/sidelineds.rb +20 -0
  64. data/lib/football/butler/standings.rb +16 -29
  65. data/lib/football/butler/statistics.rb +17 -0
  66. data/lib/football/butler/teams.rb +23 -23
  67. data/lib/football/butler/tier.rb +26 -11
  68. data/lib/football/butler/timezones.rb +16 -0
  69. data/lib/football/butler/top_scorers.rb +11 -0
  70. data/lib/football/butler/transfers.rb +21 -0
  71. data/lib/football/butler/trophies.rb +21 -0
  72. data/lib/football/butler/venues.rb +34 -0
  73. data/lib/football/butler/version.rb +8 -2
  74. data/lib/football/butler.rb +19 -0
  75. metadata +69 -6
@@ -1,35 +1,35 @@
1
1
  # frozen_string_literal: true
2
+ require 'football/butler/apifootball/countries'
3
+ require 'football/butler/football_data/areas'
4
+ require 'football/butler/api_football/countries'
2
5
 
3
6
  module Football
4
7
  module Butler
5
8
  class Areas < Base
6
- PATH = :areas
7
9
 
8
- ## AREA
9
- # v2/areas/{id}
10
- # returns area object directly as a hash
11
- def self.by_id(id:)
12
- path = "#{PATH}/#{id}"
13
- Api.get(path: path)
14
- end
10
+ class << self
11
+ ## AREA / COUNTRY
12
+ def by_id(id:)
13
+ api_switch_method(__method__, { id: id })
14
+ end
15
15
 
16
- ## AREAS
17
- # v2/areas
18
- def self.all(result: PATH)
19
- Api.get(path: PATH, result: result)
20
- end
16
+ ## AREAS / COUNTRIES
17
+ def all(result: api_switch_result)
18
+ api_switch_method(__method__, { result: result })
19
+ end
20
+
21
+ ## ADDITIONAL
22
+ def by_name(name:, result: api_switch_result, filters: {})
23
+ api_switch_method(__method__, { name: name, result: result, filters: filters })
24
+ end
21
25
 
22
- ## ADDITIONAL
23
- # v2/areas
24
- # v2/areas/{id}
25
- # returns area object directly as a hash
26
- def self.by_name(name:)
27
- areas = all
28
- return areas if areas.is_a?(Hash) && areas.with_indifferent_access.dig('message')
29
- area = areas&.detect { |area| area['name'] == name }
30
- return not_found_result(name) unless area
26
+ def by_code(code:, result: api_switch_result, filters: {})
27
+ api_switch_method(__method__, { code: code, result: result, filters: filters })
28
+ end
31
29
 
32
- by_id(id: area['id'])
30
+ def search_by_name(name:, result: api_switch_result, filters: {})
31
+ api_switch_method(__method__, { name: name, result: result, filters: filters })
32
+ end
33
33
  end
34
34
  end
35
35
  end
@@ -3,28 +3,13 @@
3
3
  module Football
4
4
  module Butler
5
5
  class Base
6
- MSG_INVALID_TOKEN = 'Your API token is invalid.' # 400
7
- MSG_NOT_EXIST = 'The resource you are looking for does not exist' # 404
8
- MSG_REACHED_LIMIT = 'You reached your request limit.' # 429
9
- MSG_INVALID_CONFIG = 'Invalid Configuration, check empty api_token / api_endpoint!'
6
+ MSG_INVALID_CONFIG = 'Invalid Configuration, check empty api_token or empty / invalid api_endpoint!'
10
7
 
11
8
  class << self
12
- # MESSAGES
13
- def invalid_token?(response)
14
- response.dig('message') ? response['message'] == MSG_INVALID_TOKEN : false
15
- end
16
-
17
- def resource_not_found?(response)
18
- response.dig('message') ? response['message'] == MSG_NOT_EXIST : false
19
- end
20
9
 
10
+ # MESSAGES
21
11
  def reached_limit?(response)
22
- response.dig('message') ? response['message'].start_with?(MSG_REACHED_LIMIT) : false
23
- end
24
-
25
- # CODES
26
- def bad_request?(response)
27
- response.dig('errorCode') ? response['errorCode'] == 400 : false
12
+ Configuration.reached_limit?(response)
28
13
  end
29
14
 
30
15
  # RESULT MESSAGES
@@ -36,9 +21,51 @@ module Football
36
21
  error_message(MSG_INVALID_CONFIG)
37
22
  end
38
23
 
24
+ def unsupported_api_call(klass, method)
25
+ message = "Method '#{method}' is not supported for the endpoint '#{klass}' by this API: "
26
+ message += "#{Configuration.api_name}"
27
+ error_message(message)
28
+ end
29
+
30
+ def unsupported_api_endpoint(klass)
31
+ error_message("The Endpoint '#{klass}' is not supported by this API: #{Configuration.api_name}")
32
+ end
33
+
39
34
  def error_message(error)
40
35
  { message: error }.with_indifferent_access
41
36
  end
37
+
38
+ # MULTI-API
39
+ def api_switch_method(method, named_params)
40
+ klass = api_switch
41
+
42
+ if klass
43
+ klass.respond_to?(method) ?
44
+ klass.send(method, **named_params) :
45
+ unsupported_api_call(this_class, method)
46
+ else
47
+ unsupported_api_endpoint(this_class)
48
+ end
49
+ end
50
+
51
+ def api_switch_result
52
+ Configuration.api_result(api_switch)
53
+ end
54
+
55
+ def api_switch
56
+ "Football::Butler::#{api_class}::#{this_class}".constantize
57
+ rescue
58
+ return nil
59
+ end
60
+
61
+ def api_class
62
+ Configuration.api_class
63
+ end
64
+
65
+ def this_class
66
+ klass = self.to_s.split('::').last
67
+ Configuration.class_converter(klass)
68
+ end
42
69
  end
43
70
  end
44
71
  end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+ require 'football/butler/api_football/coachs'
3
+
4
+ module Football
5
+ module Butler
6
+ class Coachs < Base
7
+
8
+ class << self
9
+ ## COACHS
10
+ #
11
+ def by_id(id:, result: api_switch_result, filters: {})
12
+ api_switch_method(__method__, { id: id, result: result, filters: filters })
13
+ end
14
+
15
+ def search_by_name(name:, result: api_switch_result, filters: {})
16
+ api_switch_method(__method__, { name: name, result: result, filters: filters })
17
+ end
18
+
19
+ def by_team(team:, result: api_switch_result, filters: {})
20
+ api_switch_method(__method__, { team: team, result: result, filters: filters })
21
+ end
22
+
23
+ end
24
+ end
25
+ end
26
+ end
@@ -1,62 +1,71 @@
1
1
  # frozen_string_literal: true
2
+ require 'football/butler/apifootball/competitions'
3
+ require 'football/butler/football_data/competitions'
4
+ require 'football/butler/api_football/leagues'
2
5
 
3
6
  module Football
4
7
  module Butler
5
8
  class Competitions < Base
6
- PATH = :competitions
7
-
8
- ## COMPETITION
9
- # v2/competitions/{id}
10
- # returns competition object directly as a hash
11
- def self.by_id(id:)
12
- path = "#{PATH}/#{id}"
13
- Api.get(path: path)
14
- end
15
9
 
16
- ## COMPETITIONS
17
- #
18
- # areas={AREAS}
19
- # plan={PLAN}
20
- #
21
- # v2/competitions
22
- def self.all(result: PATH, filters: Configuration.tier_plan_filter)
23
- Api.get(path: PATH, result: result, filters: filters)
24
- end
10
+ class << self
11
+ ## COMPETITION
12
+ def by_id(id:)
13
+ api_switch_method(__method__, { id: id })
14
+ end
25
15
 
26
- # v2/competitions?plan={plan}
27
- def self.by_plan(plan:, result: PATH, filters: {})
28
- filters.merge!({ plan: plan })
29
- Api.get(path: PATH, result: result, filters: filters)
30
- end
16
+ def by_country(id:, result: api_switch_result)
17
+ api_switch_method(__method__, { id: id, result: result })
18
+ end
31
19
 
32
- # v2/competitions?areas={id1, id2, ...}
33
- def self.by_areas(ids:, result: PATH, filters: {})
34
- filters.merge!({ areas: ids.join(',') })
35
- Api.get(path: PATH, result: result, filters: filters)
36
- end
20
+ def by_country_name(name:, result: api_switch_result)
21
+ api_switch_method(__method__, { name: name, result: result })
22
+ end
37
23
 
38
- ## ADDITIONAL
39
- # v2/competitions/{id}
40
- def self.current_match_day(id:)
41
- response = by_id(id:id)
24
+ ## COMPETITIONS
25
+ def all(result: api_switch_result, filters: {})
26
+ api_switch_method(__method__, { result: result, filters: filters })
27
+ end
42
28
 
43
- if response.is_a?(Hash) && response.dig('message')
44
- response
45
- else
46
- response['currentSeason']['currentMatchday']
29
+ def all_tier_plan_filter(result: api_switch_result, filters: {})
30
+ filters.merge!(Configuration.tier_plan_filter)
31
+ api_switch_method(__method__, { result: result, filters: filters })
47
32
  end
48
- end
49
33
 
50
- # v2/competitions/{id}
51
- def self.seasons(id:)
52
- response = by_id(id:id)
34
+ def by_plan(plan:, result: api_switch_result, filters: {})
35
+ api_switch_method(__method__, { plan: plan, result: result, filters: filters })
36
+ end
37
+
38
+ def by_areas(ids:, result: api_switch_result, filters: {})
39
+ api_switch_method(__method__, { ids: ids, result: result, filters: filters })
40
+ end
53
41
 
54
- if response.is_a?(Hash) && response.dig('message')
55
- response
56
- else
57
- response['seasons']
42
+ ## ADDITIONAL
43
+ def current_match_day(id:)
44
+ api_switch_method(__method__, { id: id })
45
+ end
46
+
47
+ def seasons(id:)
48
+ api_switch_method(__method__, { id: id })
49
+ end
50
+
51
+ def all_seasons(result: api_switch_result)
52
+ api_switch_method(__method__, { result: result })
53
+ end
54
+
55
+ def search_by_name(name:, result: api_switch_result, filters: {})
56
+ api_switch_method(__method__, { name: name, result: result, filters: filters })
57
+ end
58
+
59
+ def all_leagues(result: api_switch_result, filters: {})
60
+ api_switch_method(__method__, { result: result, filters: filters })
61
+ end
62
+
63
+ # /leagues?type=cup
64
+ def all_cups(result: api_switch_result, filters: {})
65
+ api_switch_method(__method__, { result: result, filters: filters })
58
66
  end
59
67
  end
68
+
60
69
  end
61
70
  end
62
71
  end
@@ -3,60 +3,104 @@
3
3
  module Football
4
4
  module Butler
5
5
  module Configuration
6
+ # MULTI-API
7
+ API_URL_FOOTBALL_DATA = 'https://api.football-data.org'
8
+ API_URL_APIFOOTBALL = 'https://apiv2.apifootball.com/?'
9
+ API_URL_API_FOOTBALL = 'https://v3.football.api-sports.io'
10
+
11
+ API_VERSION_FOOTBALL_DATA = 2
12
+ API_VERSION_APIFOOTBALL = 2
13
+ API_VERSION_API_FOOTBALL = 3
14
+
6
15
  # API
7
- DEFAULT_API_URL = "https://api.football-data.org"
16
+ AVAILABLE_APIS = [:football_data_org, :apifootball_com, :api_football_com]
17
+ DEFAULT_API_NAME = :football_data_org
18
+ DEFAULT_API_URL = API_URL_FOOTBALL_DATA
8
19
 
9
20
  DEFAULT_API_TOKEN = nil
10
- DEFAULT_API_VERSION = 2
21
+ DEFAULT_API_VERSION = API_VERSION_FOOTBALL_DATA
11
22
  DEFAULT_API_ENDPOINT = "#{DEFAULT_API_URL}/v#{DEFAULT_API_VERSION}"
12
23
 
13
24
  # ADDITIONAL
14
25
  DEFAULT_TIER_PLAN = nil
15
26
  DEFAULT_WAIT_ON_LIMIT = false
16
27
 
28
+ # MESSAGES
29
+ MSG_REACHED_LIMIT = {
30
+ football_data_org: 'You reached your request limit.', # code: 429
31
+ api_football_com: 'Too many requests. Your rate limit is 10 requests per minute.' # code: 200
32
+ }
33
+
17
34
  class << self
18
- attr_accessor :api_version, :api_token, :api_endpoint, :tier_plan, :wait_on_limit, :init_done
35
+ attr_accessor :api_version, :api_token, :api_endpoint, :tier_plan, :wait_on_limit, :init_done,
36
+ :api_name, :header_token_name, :header_additional
19
37
 
20
38
  def configure
21
39
  raise "You need to configure football-butler first, see readme." unless block_given?
22
40
 
23
41
  yield self
24
42
 
43
+ # api_name: AVAILABLE_APIS
44
+ @api_name = set_api_name(self.api_name)
45
+
25
46
  @api_token ||= DEFAULT_API_TOKEN
26
47
  @api_version ||= DEFAULT_API_VERSION
27
- @api_endpoint ||= DEFAULT_API_ENDPOINT
48
+ @api_endpoint ||= set_api_endpoint(@api_name, @api_version)
28
49
  @tier_plan ||= DEFAULT_TIER_PLAN
29
- @wait_on_limit ||= DEFAULT_WAIT_ON_LIMIT
50
+ @wait_on_limit ||= set_wait_on_limit(self.wait_on_limit, @api_name)
51
+
52
+ @header_token_name ||= set_header_token_name(@api_name)
53
+ @header_additional ||= {}
30
54
 
31
55
  @init_done = true
32
56
 
33
- true
57
+ api_name_valid?(self.api_name)
34
58
  end
35
59
 
36
60
  def reconfigure(
37
- api_token: nil, api_version: nil, api_endpoint: nil, tier_plan: nil, wait_on_limit: nil
61
+ api_token: nil, api_version: nil, api_endpoint: nil, tier_plan: nil, wait_on_limit: nil,
62
+ api_name: nil, header_token_name: nil, header_additional: nil
38
63
  )
39
64
 
40
65
  reset unless @init_done
41
66
 
42
- @api_token = api_token unless api_token.nil?
43
- unless api_version.nil?
67
+ @api_name = set_api_name(api_name) unless api_name.nil?
68
+ @api_token = api_token if api_token
69
+
70
+ if api_version
44
71
  @api_version = api_version
45
- @api_endpoint = "#{DEFAULT_API_URL}/v#{api_version}" if api_endpoint.nil?
72
+ @api_endpoint = set_api_endpoint(@api_name, @api_version) if api_endpoint.nil?
46
73
  end
47
- @api_endpoint = api_endpoint unless api_endpoint.nil?
48
- @tier_plan = tier_plan unless tier_plan.nil?
49
- @wait_on_limit = wait_on_limit unless wait_on_limit.nil?
50
74
 
51
- true
75
+ if api_endpoint.nil?
76
+ @api_endpoint = set_api_endpoint(@api_name, @api_version) if api_name
77
+ else
78
+ @api_endpoint = api_endpoint
79
+ end
80
+
81
+ @tier_plan = tier_plan if tier_plan
82
+ @wait_on_limit = set_wait_on_limit(wait_on_limit, @api_name) unless wait_on_limit.nil?
83
+
84
+ @header_token_name = header_token_name ? header_token_name : set_header_token_name(@api_name)
85
+ @header_additional = header_additional if header_additional
86
+
87
+ api_name_valid?(api_name ? api_name : @api_name)
88
+ end
89
+
90
+ def api_name_valid?(api_name)
91
+ AVAILABLE_APIS.include?(api_name)
52
92
  end
53
93
 
54
94
  def reset
95
+ @api_name = DEFAULT_API_NAME
55
96
  @api_version = DEFAULT_API_VERSION
56
97
  @api_endpoint = DEFAULT_API_ENDPOINT
57
98
  @tier_plan = DEFAULT_TIER_PLAN
58
99
  @wait_on_limit = DEFAULT_WAIT_ON_LIMIT
59
100
 
101
+ @header_token_name = set_header_token_name(@api_name)
102
+ @header_additional = {}
103
+
60
104
  @init_done = true
61
105
 
62
106
  true
@@ -66,6 +110,223 @@ module Football
66
110
  def tier_plan_filter
67
111
  tier_plan.nil? ? {} : { plan: tier_plan }
68
112
  end
113
+
114
+ # [:football_data_org, :apifootball_com]
115
+ # - https://www.football-data.org/documentation/api
116
+ # - https://apifootball.com/documentation
117
+ def api_class
118
+ case api_name
119
+ when :apifootball_com
120
+ 'Apifootball'
121
+ when :football_data_org
122
+ 'FootballData'
123
+ when :api_football_com
124
+ 'ApiFootball'
125
+ end
126
+ end
127
+
128
+ def set_api_name(api_name)
129
+ api_name_valid?(api_name) ? api_name : DEFAULT_API_NAME
130
+ end
131
+
132
+ def set_api_endpoint(api_name, api_version = DEFAULT_API_VERSION)
133
+ return if api_name.nil?
134
+
135
+ case api_name
136
+ when :apifootball_com
137
+ API_URL_APIFOOTBALL
138
+ when :football_data_org
139
+ "#{API_URL_FOOTBALL_DATA}/v#{api_version}"
140
+ when :api_football_com
141
+ API_URL_API_FOOTBALL
142
+ end
143
+ end
144
+
145
+ def set_wait_on_limit(wait_on_limit, api_name)
146
+ case api_name
147
+ when :apifootball_com
148
+ false
149
+ when :football_data_org
150
+ wait_on_limit
151
+ when :api_football_com
152
+ wait_on_limit
153
+ end
154
+ end
155
+
156
+ def set_header_token_name(api_name)
157
+ case api_name
158
+ when :apifootball_com
159
+ # not used in header
160
+ nil
161
+ when :football_data_org
162
+ "X-Auth-Token"
163
+ when :api_football_com
164
+ "x-apisports-key"
165
+ end
166
+ end
167
+
168
+ def http_party_headers
169
+ result = case api_name
170
+ when :apifootball_com
171
+ {}
172
+ when :football_data_org, :api_football_com
173
+ { Configuration.header_token_name => Configuration.api_token }
174
+ end
175
+
176
+ result.merge!(Configuration.header_additional)
177
+ result
178
+ end
179
+
180
+ def http_party_url(path)
181
+ case api_name
182
+ when :apifootball_com
183
+ "#{Configuration.api_endpoint}#{path}&APIkey=#{Configuration.api_token}"
184
+ when :football_data_org
185
+ "#{Configuration.api_endpoint}/#{path}"
186
+ when :api_football_com
187
+ "#{Configuration.api_endpoint}/#{path}"
188
+ end
189
+ end
190
+
191
+ def http_party_response(response, result)
192
+ case api_name
193
+ when :apifootball_com
194
+ response_apifootball_com(response, result)
195
+ when :football_data_org
196
+ response_football_data_org(response, result)
197
+ when :api_football_com
198
+ response_api_football_com(response, result)
199
+ end
200
+ end
201
+
202
+ def response_apifootball_com(response, result)
203
+ case result
204
+ when :default
205
+ response
206
+ when :array_first
207
+ response.parsed_response.is_a?(Array) ? response.parsed_response.first : nil
208
+ else
209
+ response.parsed_response
210
+ end
211
+ end
212
+
213
+ def response_football_data_org(response, result)
214
+ case result
215
+ when :default
216
+ response
217
+ when :parsed_response
218
+ response.parsed_response
219
+ else
220
+ response&.keys&.include?(result.to_s) ? response[result.to_s] : nil
221
+ end
222
+ end
223
+
224
+ def response_api_football_com(response, result)
225
+ case result
226
+ when :default
227
+ response
228
+ when :parsed_response
229
+ response.parsed_response
230
+ when :array_first
231
+ response&.keys&.include?('response') && response['response'].is_a?(Array) ?
232
+ response['response'].first : nil
233
+ else
234
+ response&.keys&.include?('response') ? response['response'] : nil
235
+ end
236
+ end
237
+
238
+ def api_result(klass)
239
+ case api_name
240
+ when :apifootball_com
241
+ :parsed_response
242
+ when :football_data_org
243
+ klass::PATH
244
+ when :api_football_com
245
+ :response
246
+ end
247
+ rescue
248
+ return nil
249
+ end
250
+
251
+ def tier_from_response(response)
252
+ case api_name
253
+ when :apifootball_com
254
+ # n/a
255
+ when :football_data_org, :api_football_com
256
+ Tier.set_from_response_headers(response)
257
+ end
258
+ end
259
+
260
+ def class_converter(klass)
261
+ case api_name
262
+ when :apifootball_com
263
+ case klass
264
+ when 'Areas'
265
+ return 'Countries'
266
+ when 'Matches'
267
+ return 'Events'
268
+ when 'Fixtures'
269
+ return 'Events'
270
+ when 'Scorers'
271
+ return 'TopScorers'
272
+ when 'Leagues'
273
+ return 'Competitions'
274
+ end
275
+ when :football_data_org
276
+ case klass
277
+ when 'Countries'
278
+ return 'Areas'
279
+ when 'Events'
280
+ return 'Matches'
281
+ when 'Fixtures'
282
+ return 'Matches'
283
+ when 'TopScorers'
284
+ return 'Scorers'
285
+ when 'Leagues'
286
+ return 'Competitions'
287
+ end
288
+ when :api_football_com
289
+ case klass
290
+ when 'Areas'
291
+ return 'Countries'
292
+ when 'Competitions'
293
+ return 'Leagues'
294
+ when 'Events'
295
+ return 'Fixtures'
296
+ when 'Matches'
297
+ return 'Fixtures'
298
+ when 'Scorers'
299
+ return 'TopScorers'
300
+ end
301
+ end
302
+
303
+ klass
304
+ end
305
+
306
+ def reached_limit?(response)
307
+ case api_name
308
+ when :apifootball_com
309
+ false
310
+ when :football_data_org
311
+ return false if !response.is_a?(Hash) &&
312
+ (response.respond_to?(:parsed_response) &&
313
+ !response.parsed_response.is_a?(Hash))
314
+ return response.dig('message') ? response['message'].start_with?(MSG_REACHED_LIMIT[api_name]) : false
315
+ when :api_football_com
316
+ if response.is_a?(HTTParty::Response) && response&.headers.present?
317
+ if response.headers['x-ratelimit-remaining'] == '0' ||
318
+ response.headers['x-ratelimit-requests-remaining'] == '0'
319
+ return true
320
+ end
321
+ elsif response.is_a?(HTTParty::Response) && response.parsed_response.dig('errors', 'rateLimit').present?
322
+ return true
323
+ end
324
+ end
325
+
326
+ false
327
+ rescue
328
+ return false
329
+ end
69
330
  end
70
331
  end
71
332
  end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+ require 'football/butler/apifootball/countries'
3
+ require 'football/butler/football_data/areas'
4
+ require 'football/butler/api_football/countries'
5
+
6
+ module Football
7
+ module Butler
8
+ class Countries < Areas
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+ require 'football/butler/apifootball/events'
3
+ require 'football/butler/football_data/matches'
4
+ require 'football/butler/api_football/fixtures'
5
+
6
+ module Football
7
+ module Butler
8
+ class Events < Matches
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+ require 'football/butler/apifootball/events'
3
+ require 'football/butler/football_data/matches'
4
+ require 'football/butler/api_football/fixtures'
5
+
6
+ module Football
7
+ module Butler
8
+ class Fixtures < Matches
9
+ end
10
+ end
11
+ end