esi 0.4.5 → 0.4.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/esi.gemspec +19 -15
- data/lib/esi/access_token.rb +3 -1
- data/lib/esi/api_error.rb +134 -0
- data/lib/esi/calls/info.rb +0 -0
- data/lib/esi/calls.rb +26 -19
- data/lib/esi/client.rb +125 -31
- data/lib/esi/o_auth.rb +8 -15
- data/lib/esi/response.rb +32 -8
- data/lib/esi/version.rb +3 -1
- data/lib/esi.rb +46 -45
- data/lib/omniauth/esi.rb +2 -0
- data/lib/omniauth/strategies/esi.rb +12 -8
- metadata +61 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4ef7c659090137fe7ff8581cdb6c6a9e9c240faa
|
4
|
+
data.tar.gz: 1e47ffce54eda2555fa7f64e3e841e0507162040
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3354040d05b7f3d674c072081b30815bc63b1ced681d64933e24461b039839f424e29724e2e624320120b652a5e4e43dc7253a5eca4fd3371b0a745bc6db60c1
|
7
|
+
data.tar.gz: 318a635d10e008cd0fc1daf06f8cfe028c677f041af49db8261a8f6d08d535862ff1a25ac758835b2397d9d96f0cbc84dce9dbecfffbbe6c5c0f3f85e366d825
|
data/esi.gemspec
CHANGED
@@ -1,26 +1,30 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
2
3
|
lib = File.expand_path('../lib', __FILE__)
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
5
|
require 'esi/version'
|
5
6
|
|
6
7
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
8
|
+
spec.name = 'esi'
|
8
9
|
spec.version = Esi::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
10
|
+
spec.authors = ['Danny Hiemstra', 'Aaron Allen']
|
11
|
+
spec.email = ['dannyhiemstra@gmail.com', 'aaronmallen4@gmail.com']
|
11
12
|
|
12
|
-
spec.summary =
|
13
|
-
spec.description =
|
14
|
-
spec.homepage =
|
15
|
-
spec.license =
|
13
|
+
spec.summary = 'EVE ESI API wrapper'
|
14
|
+
spec.description = 'EVE ESI API wrapper'
|
15
|
+
spec.homepage = 'https://github.com/dhiemstra/esi'
|
16
|
+
spec.license = 'MIT'
|
16
17
|
|
17
18
|
spec.files = %w(LICENSE.txt README.md esi.gemspec) + Dir['lib/**/*.rb']
|
18
|
-
spec.require_paths = [
|
19
|
+
spec.require_paths = ['lib']
|
19
20
|
|
20
|
-
spec.add_dependency
|
21
|
-
spec.add_dependency
|
22
|
-
spec.add_dependency
|
23
|
-
spec.add_development_dependency
|
24
|
-
spec.add_development_dependency
|
25
|
-
spec.add_development_dependency
|
21
|
+
spec.add_dependency 'activesupport'
|
22
|
+
spec.add_dependency 'addressable', '~> 2.3'
|
23
|
+
spec.add_dependency 'oauth2', '~> 1.4'
|
24
|
+
spec.add_development_dependency 'bundler', '~> 1.14'
|
25
|
+
spec.add_development_dependency 'minitest', '~> 5.0'
|
26
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
27
|
+
spec.add_development_dependency 'rubocop', '~> 0.52'
|
28
|
+
spec.add_development_dependency 'shoulda', '~> 3.5'
|
29
|
+
spec.add_development_dependency 'yard', '~> 0.9'
|
26
30
|
end
|
data/lib/esi/access_token.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Esi
|
2
4
|
class AccessToken < OAuth2::AccessToken
|
3
5
|
EXPIRES_MARGIN = 30.seconds
|
@@ -13,7 +15,7 @@ module Esi
|
|
13
15
|
end
|
14
16
|
|
15
17
|
def verify
|
16
|
-
Esi::Response.new(get(
|
18
|
+
Esi::Response.new(get('/oauth/verify'))
|
17
19
|
end
|
18
20
|
|
19
21
|
def expired?
|
@@ -0,0 +1,134 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Esi
|
4
|
+
# ApiError base class
|
5
|
+
# @!attribute [r] response
|
6
|
+
# @return [Esi::Response] the ApiError Response
|
7
|
+
# @!attribute [r] key
|
8
|
+
# @return [String] the response.data[:key]
|
9
|
+
# @!attribute [r] message
|
10
|
+
# @return [String] the response error message
|
11
|
+
# @!attribute [r] type
|
12
|
+
# @return [String] the response.data[:exceptionType]
|
13
|
+
# @!attribute [r] original_exception
|
14
|
+
# @return [ExceptionClass|nil] the orginal raised exception
|
15
|
+
class ApiError < OAuth2::Error
|
16
|
+
attr_reader :response, :key, :message, :type, :original_exception
|
17
|
+
|
18
|
+
# Create a new instance of ApiError
|
19
|
+
# @param [Esi::Response] response the response that generated the exception
|
20
|
+
# @param [ExceptionClass|nil] the orginally raised exception
|
21
|
+
# @return [Esi::ApiError] an instance of ApiError
|
22
|
+
def initialize(response, original_exception = nil)
|
23
|
+
super(response.original_response)
|
24
|
+
|
25
|
+
@response = response
|
26
|
+
@original_exception = original_exception
|
27
|
+
@code = response.original_response.status
|
28
|
+
@key = response.data[:key]
|
29
|
+
@message = response.data[:message].presence || response.data[:error] || original_exception.try(:message)
|
30
|
+
@type = response.data[:exceptionType]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# ApiRequestError Class
|
35
|
+
# @!attribute [r] original_exception
|
36
|
+
# @return [ExceptionClass|nil] the orginal raised exception
|
37
|
+
class ApiRequestError < StandardError
|
38
|
+
attr_reader :original_exception
|
39
|
+
|
40
|
+
# Create a new instance of ApiRequestError
|
41
|
+
# @param [ExceptionClass|nil] the orginally raised exception
|
42
|
+
# @return [Esi::ApiRequestError] the instance of ApiRequestError
|
43
|
+
def initialize(original_exception)
|
44
|
+
@original_exception = original_exception
|
45
|
+
msg = "#{original_exception.class}: " \
|
46
|
+
"#{original_exception.try(:response).try(:status)}" \
|
47
|
+
' - ' \
|
48
|
+
"#{original_exception.try(:message)}"
|
49
|
+
super(msg)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# ApiUnknowntError Class
|
54
|
+
# @!attribute [r] response
|
55
|
+
# @return [Esi::Response] the ApiError Response
|
56
|
+
# @!attribute [r] key
|
57
|
+
# @return [String] the response.data[:key]
|
58
|
+
# @!attribute [r] message
|
59
|
+
# @return [String] the response error message
|
60
|
+
# @!attribute [r] type
|
61
|
+
# @return [String] the response.data[:exceptionType]
|
62
|
+
# @!attribute [r] original_exception
|
63
|
+
# @return [ExceptionClass|nil] the orginal raised exception
|
64
|
+
class ApiUnknownError < ApiError; end
|
65
|
+
|
66
|
+
# ApiBadRequestError Class
|
67
|
+
# @!attribute [r] response
|
68
|
+
# @return [Esi::Response] the ApiError Response
|
69
|
+
# @!attribute [r] key
|
70
|
+
# @return [String] the response.data[:key]
|
71
|
+
# @!attribute [r] message
|
72
|
+
# @return [String] the response error message
|
73
|
+
# @!attribute [r] type
|
74
|
+
# @return [String] the response.data[:exceptionType]
|
75
|
+
# @!attribute [r] original_exception
|
76
|
+
# @return [ExceptionClass|nil] the orginal raised exception
|
77
|
+
class ApiBadRequestError < ApiError; end
|
78
|
+
|
79
|
+
# ApiRefreshTokenExpiredError Class
|
80
|
+
# @!attribute [r] response
|
81
|
+
# @return [Esi::Response] the ApiError Response
|
82
|
+
# @!attribute [r] key
|
83
|
+
# @return [String] the response.data[:key]
|
84
|
+
# @!attribute [r] message
|
85
|
+
# @return [String] the response error message
|
86
|
+
# @!attribute [r] type
|
87
|
+
# @return [String] the response.data[:exceptionType]
|
88
|
+
# @!attribute [r] original_exception
|
89
|
+
# @return [ExceptionClass|nil] the orginal raised exception
|
90
|
+
class ApiRefreshTokenExpiredError < ApiError; end
|
91
|
+
|
92
|
+
# ApiInvalidAppClientKeysError Class
|
93
|
+
# @!attribute [r] response
|
94
|
+
# @return [Esi::Response] the ApiError Response
|
95
|
+
# @!attribute [r] key
|
96
|
+
# @return [String] the response.data[:key]
|
97
|
+
# @!attribute [r] message
|
98
|
+
# @return [String] the response error message
|
99
|
+
# @!attribute [r] type
|
100
|
+
# @return [String] the response.data[:exceptionType]
|
101
|
+
# @!attribute [r] original_exception
|
102
|
+
# @return [ExceptionClass|nil] the orginal raised exception
|
103
|
+
class ApiInvalidAppClientKeysError < ApiError; end
|
104
|
+
|
105
|
+
# ApiNotFoundError Class
|
106
|
+
# @!attribute [r] response
|
107
|
+
# @return [Esi::Response] the ApiError Response
|
108
|
+
# @!attribute [r] key
|
109
|
+
# @return [String] the response.data[:key]
|
110
|
+
# @!attribute [r] message
|
111
|
+
# @return [String] the response error message
|
112
|
+
# @!attribute [r] type
|
113
|
+
# @return [String] the response.data[:exceptionType]
|
114
|
+
# @!attribute [r] original_exception
|
115
|
+
# @return [ExceptionClass|nil] the orginal raised exception
|
116
|
+
class ApiNotFoundError < ApiError; end
|
117
|
+
|
118
|
+
# ApiForbiddenError Class
|
119
|
+
# @!attribute [r] response
|
120
|
+
# @return [Esi::Response] the ApiError Response
|
121
|
+
# @!attribute [r] key
|
122
|
+
# @return [String] the response.data[:key]
|
123
|
+
# @!attribute [r] message
|
124
|
+
# @return [String] the response error message
|
125
|
+
# @!attribute [r] type
|
126
|
+
# @return [String] the response.data[:exceptionType]
|
127
|
+
# @!attribute [r] original_exception
|
128
|
+
# @return [ExceptionClass|nil] the orginal raised exception
|
129
|
+
class ApiForbiddenError < ApiError; end
|
130
|
+
|
131
|
+
# Error Class
|
132
|
+
# @see [StandardError](https://ruby-doc.org/core-2.3.2/StandardError.html)
|
133
|
+
class Error < StandardError; end
|
134
|
+
end
|
File without changes
|
data/lib/esi/calls.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Esi
|
2
4
|
class Calls
|
3
5
|
class << self
|
@@ -29,13 +31,18 @@ module Esi
|
|
29
31
|
end
|
30
32
|
|
31
33
|
class Base
|
34
|
+
CACHE_NAMESPACE = 'esi'
|
35
|
+
|
32
36
|
class_attribute :scope
|
33
37
|
class_attribute :cache_duration
|
34
38
|
|
35
39
|
attr_accessor :path, :params
|
36
40
|
|
37
41
|
def cache_key
|
38
|
-
@cache_key ||=
|
42
|
+
@cache_key ||= begin
|
43
|
+
cache_args = [CACHE_NAMESPACE, path.gsub(%r{^\/}, ''), params.sort].flatten
|
44
|
+
ActiveSupport::Cache.expand_cache_key(cache_args)
|
45
|
+
end
|
39
46
|
end
|
40
47
|
|
41
48
|
def method
|
@@ -52,13 +59,13 @@ module Esi
|
|
52
59
|
end
|
53
60
|
|
54
61
|
def paginated?
|
55
|
-
|
62
|
+
!@paginated
|
56
63
|
end
|
57
64
|
end
|
58
65
|
|
59
66
|
class Regions < Base
|
60
67
|
def initialize
|
61
|
-
@path =
|
68
|
+
@path = '/universe/regions/'
|
62
69
|
end
|
63
70
|
end
|
64
71
|
|
@@ -70,7 +77,7 @@ module Esi
|
|
70
77
|
|
71
78
|
class Constellations < Base
|
72
79
|
def initialize
|
73
|
-
@path =
|
80
|
+
@path = '/universe/constellations/'
|
74
81
|
end
|
75
82
|
end
|
76
83
|
|
@@ -88,7 +95,7 @@ module Esi
|
|
88
95
|
|
89
96
|
class SolarSystems < Base
|
90
97
|
def initialize
|
91
|
-
@path =
|
98
|
+
@path = '/universe/systems/'
|
92
99
|
end
|
93
100
|
end
|
94
101
|
|
@@ -124,7 +131,7 @@ module Esi
|
|
124
131
|
|
125
132
|
class Structures < Base
|
126
133
|
def initialize
|
127
|
-
@path =
|
134
|
+
@path = '/universe/structures/'
|
128
135
|
end
|
129
136
|
end
|
130
137
|
|
@@ -136,7 +143,7 @@ module Esi
|
|
136
143
|
|
137
144
|
class Types < Base
|
138
145
|
def initialize
|
139
|
-
@path =
|
146
|
+
@path = '/universe/types'
|
140
147
|
@paginated = true
|
141
148
|
end
|
142
149
|
end
|
@@ -149,7 +156,7 @@ module Esi
|
|
149
156
|
|
150
157
|
class DogmaAttributes < Base
|
151
158
|
def initialize
|
152
|
-
@path =
|
159
|
+
@path = '/dogma/attributes/'
|
153
160
|
end
|
154
161
|
end
|
155
162
|
|
@@ -161,7 +168,7 @@ module Esi
|
|
161
168
|
|
162
169
|
class DogmaEffects < Base
|
163
170
|
def initialize
|
164
|
-
@path =
|
171
|
+
@path = '/dogma/effects/'
|
165
172
|
end
|
166
173
|
end
|
167
174
|
|
@@ -176,7 +183,7 @@ module Esi
|
|
176
183
|
self.cache_duration = 3600
|
177
184
|
|
178
185
|
def initialize
|
179
|
-
@path =
|
186
|
+
@path = '/industry/facilities'
|
180
187
|
end
|
181
188
|
end
|
182
189
|
|
@@ -185,7 +192,7 @@ module Esi
|
|
185
192
|
self.cache_duration = 3600
|
186
193
|
|
187
194
|
def initialize
|
188
|
-
@path =
|
195
|
+
@path = '/industry/systems'
|
189
196
|
end
|
190
197
|
end
|
191
198
|
|
@@ -194,7 +201,7 @@ module Esi
|
|
194
201
|
# https://esi.tech.ccp.is/latest/characters/907452336/search/?categories=structure&datasource=tranquility&search=Kamela&strict=false&token=Fp3ThF7wjvYBIDIIrtWE_Ryjt9BhYwUP75y2EL5Eq9mHPm8tYt9I9NwgZz8o26FFQBKoUToh2DYVc-Q5Ws400g2
|
195
202
|
|
196
203
|
def initialize(character_id: nil, categories:, search:, strict: false)
|
197
|
-
@path = (character_id ? "/characters/#{character_id}" : '') +
|
204
|
+
@path = (character_id ? "/characters/#{character_id}" : '') + '/search'
|
198
205
|
@params = { categories: categories, search: search, strict: strict }
|
199
206
|
end
|
200
207
|
end
|
@@ -210,7 +217,7 @@ module Esi
|
|
210
217
|
self.cache_duration = 3600
|
211
218
|
|
212
219
|
def initialize(character_ids)
|
213
|
-
@path =
|
220
|
+
@path = '/characters/names'
|
214
221
|
@params = { character_ids: character_ids.join(',') }
|
215
222
|
end
|
216
223
|
end
|
@@ -412,7 +419,7 @@ module Esi
|
|
412
419
|
self.cache_duration = 3600
|
413
420
|
|
414
421
|
def initialize
|
415
|
-
@path =
|
422
|
+
@path = '/alliances'
|
416
423
|
end
|
417
424
|
end
|
418
425
|
|
@@ -420,7 +427,7 @@ module Esi
|
|
420
427
|
self.cache_duration = 3600
|
421
428
|
|
422
429
|
def initialize(alliance_ids)
|
423
|
-
@path =
|
430
|
+
@path = '/alliances/names'
|
424
431
|
@params = { alliance_ids: alliance_ids.join(',') }
|
425
432
|
end
|
426
433
|
end
|
@@ -437,7 +444,7 @@ module Esi
|
|
437
444
|
self.cache_duration = 3600
|
438
445
|
|
439
446
|
def initialize(corporation_ids)
|
440
|
-
@path =
|
447
|
+
@path = '/corporations/names'
|
441
448
|
@params = { corporation_ids: corporation_ids.join(',') }
|
442
449
|
end
|
443
450
|
end
|
@@ -526,7 +533,7 @@ module Esi
|
|
526
533
|
|
527
534
|
class MarketGroups < Base
|
528
535
|
def initialize
|
529
|
-
@path =
|
536
|
+
@path = '/markets/groups'
|
530
537
|
@paginated = true
|
531
538
|
end
|
532
539
|
end
|
@@ -539,7 +546,7 @@ module Esi
|
|
539
546
|
|
540
547
|
class MarketPrices < Base
|
541
548
|
def initialize
|
542
|
-
@path =
|
549
|
+
@path = '/markets/prices'
|
543
550
|
end
|
544
551
|
end
|
545
552
|
|
@@ -605,7 +612,7 @@ module Esi
|
|
605
612
|
self.scope = 'esi-ui.open_window.v1'
|
606
613
|
|
607
614
|
def initialize(type_id)
|
608
|
-
@path =
|
615
|
+
@path = '/ui/openwindow/marketdetails'
|
609
616
|
@method = :post
|
610
617
|
@params = { type_id: type_id }
|
611
618
|
end
|
data/lib/esi/client.rb
CHANGED
@@ -1,17 +1,90 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Esi
|
4
|
+
# The Esi Client class
|
5
|
+
# @!attribute [rw] refresh_callback
|
6
|
+
# @return [#callback] the refresh_token callback method
|
7
|
+
# @!attribute [rw] access_token
|
8
|
+
# @return [String] the esi access_token
|
9
|
+
# @!attribute [rw] refresh_token
|
10
|
+
# @return [String] the esi refresh_token string
|
11
|
+
# @!attribute [rw] expires_at
|
12
|
+
# @return [Time] the timestamp of the esi token expire
|
13
|
+
# @!attribute [r] logger
|
14
|
+
# @return [Logger] the logger class for the gem
|
15
|
+
# @!attribute [r] oauth
|
16
|
+
# @return [Esi::Oauth] the oauth instance for the client
|
2
17
|
class Client
|
18
|
+
# @return [Fixnum] The max amount of request attempst Client will make
|
3
19
|
MAX_ATTEMPTS = 2
|
4
20
|
|
5
21
|
attr_accessor :refresh_callback, :access_token, :refresh_token, :expires_at
|
6
22
|
attr_reader :logger, :oauth
|
7
23
|
|
24
|
+
# Create a new instance of Client
|
25
|
+
# @param [String] token the esi access_token
|
26
|
+
# @param [String] refresh_token the esi refresh_token
|
27
|
+
# @param [Time] expires_at the time stamp the esi token expires_at
|
8
28
|
def initialize(token: nil, refresh_token: nil, expires_at: nil)
|
9
29
|
@logger = Esi.logger
|
10
30
|
@access_token = token
|
11
31
|
@refresh_token = refresh_token
|
12
32
|
@expires_at = expires_at
|
33
|
+
@oauth = init_oauth
|
34
|
+
end
|
35
|
+
|
36
|
+
# Set the current thread's Esi::Client
|
37
|
+
# @params [Esi::Client] the client to set
|
38
|
+
# @return [Esi::Client] the current thread's Esi::Client
|
39
|
+
def self.current=(client)
|
40
|
+
Thread.current[:esi_client] = client
|
41
|
+
end
|
42
|
+
|
43
|
+
# Get the current thread's Esi::Client
|
44
|
+
# @return [Esi::Client] the current thread's Esi::Client
|
45
|
+
def self.current
|
46
|
+
Thread.current[:esi_client] ||= new
|
47
|
+
end
|
48
|
+
|
49
|
+
# Switch to default Esi::Client (Esi::Client.new)
|
50
|
+
# @return [Esi::Client] the current thread's Esi::Client
|
51
|
+
def self.switch_to_default
|
52
|
+
self.current = new
|
53
|
+
end
|
54
|
+
|
55
|
+
# Switch current thread's client to instance of Esi::Client
|
56
|
+
# @return [self] the instance calling switch to
|
57
|
+
def switch_to
|
58
|
+
Esi::Client.current = self
|
59
|
+
end
|
60
|
+
|
61
|
+
# Yield block with instance of Esi::Client and revert to
|
62
|
+
# previous client or default client
|
63
|
+
#
|
64
|
+
# @example Call an Esi::Client method using an instance of client
|
65
|
+
# new_client = Esi::Client.new(token: 'foo', refresh_token: 'foo', expires_at: 30.minutes.from_now)
|
66
|
+
# new_client.with_client do |client|
|
67
|
+
# client.character(1234)
|
68
|
+
# end
|
69
|
+
# #=> Esi::Response<#>
|
70
|
+
#
|
71
|
+
# @yieldreturn [#block] the passed block.
|
72
|
+
def with_client
|
73
|
+
initial_client = Esi::Client.current
|
74
|
+
switch_to
|
75
|
+
yield(self) if block_given?
|
76
|
+
ensure
|
77
|
+
initial_client.switch_to if initial_client
|
78
|
+
Esi::Client.switch_to_default unless initial_client
|
13
79
|
end
|
14
80
|
|
81
|
+
# Intercept Esi::Client method_missing and attempt to call an Esi::Request
|
82
|
+
# with an Esi::Calls
|
83
|
+
# @param [Symbol|String] name the name of the method called
|
84
|
+
# @param [Array] *args the arguments to call the method with
|
85
|
+
# @param [#block] &block the block to pass to the underlying method
|
86
|
+
# @raise [NameError] If the Esi::Calls does not exist
|
87
|
+
# @return [Esi::Response] the response given for the call
|
15
88
|
def method_missing(name, *args, &block)
|
16
89
|
klass = nil
|
17
90
|
ActiveSupport::Notifications.instrument('esi.client.detect_call') do
|
@@ -25,6 +98,9 @@ module Esi
|
|
25
98
|
cached_response(klass, *args, &block)
|
26
99
|
end
|
27
100
|
|
101
|
+
# Test if the Esi::Client has a method
|
102
|
+
# @param [Symbol] name the name of the method to test
|
103
|
+
# @return [Boolean] wether or not the method exists
|
28
104
|
def method?(name)
|
29
105
|
begin
|
30
106
|
klass = Esi::Calls.const_get(method_to_class_name(name))
|
@@ -34,15 +110,24 @@ module Esi
|
|
34
110
|
!klass.nil?
|
35
111
|
end
|
36
112
|
|
113
|
+
# Test if the Esi::Client has a pluralized version of a method
|
114
|
+
# @param [Symbol] name the name of the method to test
|
115
|
+
# @return [Boolean] wether or not the pluralized method exists
|
37
116
|
def plural_method?(name)
|
38
117
|
plural = name.to_s.pluralize.to_sym
|
39
118
|
method? plural
|
40
119
|
end
|
41
120
|
|
121
|
+
# Log a message
|
122
|
+
# @param [String] message the message to log
|
123
|
+
# @return [void] the Logger.info method with message
|
42
124
|
def log(message)
|
43
125
|
logger.info message
|
44
126
|
end
|
45
127
|
|
128
|
+
# Log a message with debug
|
129
|
+
# @param [String] message the message to log
|
130
|
+
# @return [void] the Logger.debug method with message
|
46
131
|
def debug(message)
|
47
132
|
logger.debug message
|
48
133
|
end
|
@@ -64,46 +149,45 @@ module Esi
|
|
64
149
|
name.dup.to_s.split('_').map(&:capitalize).join
|
65
150
|
end
|
66
151
|
|
67
|
-
def
|
152
|
+
def init_oauth
|
68
153
|
@oauth ||= OAuth.new(
|
69
154
|
access_token: @access_token,
|
70
155
|
refresh_token: @refresh_token,
|
71
156
|
expires_at: @expires_at,
|
72
|
-
callback:
|
157
|
+
callback: lambda { |token, expires_at|
|
73
158
|
@access_token = token
|
74
159
|
@expires_at = expires_at
|
75
|
-
if refresh_callback.respond_to?(:call)
|
76
|
-
refresh_callback.call(token, expires_at)
|
77
|
-
end
|
160
|
+
refresh_callback.call(token, expires_at) if refresh_callback.respond_to?(:call)
|
78
161
|
}
|
79
162
|
)
|
80
163
|
end
|
81
164
|
|
82
165
|
def request_paginated(call, &block)
|
166
|
+
call.page = 1
|
83
167
|
response = nil
|
84
|
-
page = 1
|
85
|
-
|
86
168
|
ActiveSupport::Notifications.instrument('esi.client.request.paginated') do
|
87
|
-
|
88
|
-
call.page = page
|
89
|
-
page_response = request(call, &block)
|
90
|
-
|
91
|
-
if page_response.data.blank?
|
92
|
-
break
|
93
|
-
elsif response
|
94
|
-
response.merge(page_response)
|
95
|
-
else
|
96
|
-
response = page_response
|
97
|
-
end
|
98
|
-
|
99
|
-
page += 1
|
100
|
-
end
|
169
|
+
response = paginated_response(response, call, &block)
|
101
170
|
end
|
102
|
-
|
103
171
|
response
|
104
172
|
end
|
105
173
|
|
174
|
+
def paginated_response(response, call, &block)
|
175
|
+
loop do
|
176
|
+
page_response = request(call, &block)
|
177
|
+
break response if page_response.data.blank?
|
178
|
+
response = response ? response.merge(page_response) : page_response
|
179
|
+
call.page += 1
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
106
183
|
# FIXME: esi should not retry
|
184
|
+
# FIXME: make rubocop compliant
|
185
|
+
# rubocop:disable Lint/ShadowedException
|
186
|
+
# rubocop:disable Metrics/AbcSize
|
187
|
+
# rubocop:disable Metrics/BlockLength
|
188
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
189
|
+
# rubocop:disable Metrics/MethodLength
|
190
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
107
191
|
def request(call, &block)
|
108
192
|
response = nil
|
109
193
|
last_ex = nil
|
@@ -113,12 +197,12 @@ module Esi
|
|
113
197
|
debug "Starting request: #{url}"
|
114
198
|
|
115
199
|
ActiveSupport::Notifications.instrument('esi.client.request') do
|
116
|
-
1.upto(MAX_ATTEMPTS) do |
|
200
|
+
1.upto(MAX_ATTEMPTS) do |_try|
|
117
201
|
last_ex = nil
|
118
202
|
response = nil
|
119
203
|
|
120
204
|
begin
|
121
|
-
response = Timeout
|
205
|
+
response = Timeout.timeout(Esi.config.timeout) do
|
122
206
|
oauth.request(call.method, url, options)
|
123
207
|
end
|
124
208
|
rescue Faraday::SSLError, Faraday::ConnectionFailed, Timeout::Error, Net::ReadTimeout => e
|
@@ -136,7 +220,7 @@ module Esi
|
|
136
220
|
sleep 5
|
137
221
|
next
|
138
222
|
when 503 # Rate Limit
|
139
|
-
logger.error
|
223
|
+
logger.error 'RateLimit error, sleeping for 5 seconds'
|
140
224
|
sleep 5
|
141
225
|
next
|
142
226
|
when 404 # Not Found
|
@@ -166,34 +250,44 @@ module Esi
|
|
166
250
|
break if response
|
167
251
|
end
|
168
252
|
end
|
253
|
+
# rubocop:enable Lint/ShadowedException
|
254
|
+
# rubocop:enable Metrics/AbcSize
|
255
|
+
# rubocop:enable Metrics/BlockLength
|
256
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
257
|
+
# rubocop:enable Metrics/MethodLength
|
258
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
169
259
|
|
170
260
|
if last_ex
|
171
261
|
logger.error "Request failed with #{last_ex.class}"
|
172
262
|
debug_error(last_ex.class, url, response)
|
173
|
-
raise Esi::ApiRequestError
|
263
|
+
raise Esi::ApiRequestError, last_ex
|
174
264
|
end
|
175
265
|
|
176
|
-
debug
|
266
|
+
debug 'Request successful'
|
177
267
|
|
178
268
|
ActiveSupport::Notifications.instrument('esi.client.response.render') do
|
179
269
|
response = Response.new(response, call)
|
180
270
|
response.save
|
181
271
|
end
|
182
272
|
ActiveSupport::Notifications.instrument('esi.client.response.callback') do
|
183
|
-
response.data.each { |item|
|
273
|
+
response.data.each { |item| yield(item) } if block
|
184
274
|
end
|
185
275
|
response
|
186
276
|
end
|
187
277
|
|
188
278
|
def debug_error(klass, url, response)
|
189
279
|
[
|
190
|
-
'-'*60,
|
280
|
+
'-' * 60,
|
191
281
|
"#{klass}(#{response.error})",
|
192
282
|
"STATUS: #{response.status}",
|
193
|
-
"MESSAGE: #{
|
283
|
+
"MESSAGE: #{debug_message_for_response(response)}",
|
194
284
|
"URL: #{url}",
|
195
|
-
'-'*60
|
285
|
+
'-' * 60
|
196
286
|
].each { |msg| logger.error(msg) }
|
197
287
|
end
|
288
|
+
|
289
|
+
def debug_message_for_response(response)
|
290
|
+
response.respond_to?(:data) ? (response.data[:message].presence || response.data[:error]) : response.try(:body)
|
291
|
+
end
|
198
292
|
end
|
199
293
|
end
|
data/lib/esi/o_auth.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Esi
|
2
4
|
class OAuth
|
3
5
|
extend Forwardable
|
4
6
|
|
5
7
|
attr_reader :access_token, :refresh_token, :expires_at
|
6
|
-
def_delegators :token, :get, :post, :delete, :patch, :put
|
8
|
+
def_delegators :token, :request, :get, :post, :delete, :patch, :put
|
7
9
|
|
8
10
|
class << self
|
9
11
|
def authorize_url(redirect_uri:, scopes: nil)
|
@@ -20,15 +22,13 @@ module Esi
|
|
20
22
|
def client
|
21
23
|
@client ||= OAuth2::Client.new(
|
22
24
|
Esi.config.client_id, Esi.config.client_secret,
|
23
|
-
|
25
|
+
site: Esi.config.oauth_host
|
24
26
|
)
|
25
27
|
end
|
26
28
|
end
|
27
29
|
|
28
30
|
def initialize(access_token:, refresh_token:, expires_at:, callback: nil)
|
29
|
-
if callback && !callback.respond_to?(:call)
|
30
|
-
raise Esi::Error.new("Callback should be a callable Proc")
|
31
|
-
end
|
31
|
+
raise Esi::Error, 'Callback should be a callable Proc' if callback && !callback.respond_to?(:call)
|
32
32
|
|
33
33
|
@access_token = access_token
|
34
34
|
@refresh_token = refresh_token
|
@@ -36,28 +36,21 @@ module Esi
|
|
36
36
|
@callback = callback if callback
|
37
37
|
end
|
38
38
|
|
39
|
-
def request(*args)
|
40
|
-
token.request(*args)
|
41
|
-
end
|
42
|
-
|
43
39
|
private
|
44
40
|
|
45
41
|
def token
|
46
|
-
@token = Esi::AccessToken.new(OAuth.client, @access_token,
|
47
|
-
|
48
|
-
})
|
42
|
+
@token = Esi::AccessToken.new(OAuth.client, @access_token,
|
43
|
+
refresh_token: @refresh_token, expires_at: @expires_at)
|
49
44
|
refresh_access_token if @token.expired?
|
50
45
|
@token
|
51
46
|
end
|
52
47
|
|
53
48
|
def refresh_access_token
|
54
|
-
Esi.logger.debug "Refreshing access token"
|
55
|
-
|
56
49
|
ActiveSupport::Notifications.instrument('esi.oauth.refresh_token') do
|
57
50
|
@token = @token.refresh!
|
58
51
|
@access_token = @token.token
|
59
52
|
@expires_at = @token.expires_at.integer? ? Time.at(@token.expires_at) : @token.expires_at
|
60
|
-
@callback
|
53
|
+
@callback&.call(@access_token, @expires_at)
|
61
54
|
end
|
62
55
|
end
|
63
56
|
end
|
data/lib/esi/response.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Esi
|
2
4
|
class Response
|
3
5
|
extend Forwardable
|
@@ -6,10 +8,10 @@ module Esi
|
|
6
8
|
def_delegators :original_response, :status, :body, :headers
|
7
9
|
def_delegators :data, :each
|
8
10
|
|
9
|
-
def initialize(response, call=nil)
|
11
|
+
def initialize(response, call = nil)
|
10
12
|
@original_response = response
|
13
|
+
@data = normalize_response_body
|
11
14
|
@call = call
|
12
|
-
@data = MultiJson.load(body || {}, symbolize_keys: true, object_class: OpenStruct) # rescue OpenStruct.new
|
13
15
|
end
|
14
16
|
|
15
17
|
def merge(other_response)
|
@@ -29,18 +31,40 @@ module Esi
|
|
29
31
|
@cached_until ||= headers[:expires] ? Time.parse(headers[:expires]) : nil
|
30
32
|
end
|
31
33
|
|
34
|
+
def response_json
|
35
|
+
@response_json ||= begin
|
36
|
+
MultiJson.load(body, symbolize_keys: true)
|
37
|
+
rescue StandardError
|
38
|
+
{}
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
32
42
|
def save
|
33
|
-
return
|
34
|
-
|
43
|
+
return unless should_log_response?
|
44
|
+
File.write(log_directroy.join("#{Time.now.to_i}.json"), to_json)
|
45
|
+
end
|
35
46
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
47
|
+
def log_directory
|
48
|
+
call.class.to_s.split('::').last.underscore
|
49
|
+
dir = Pathname.new(Esi.config.response_log_path).join(call_name)
|
50
|
+
FileUtils.mkdir_p(dir)
|
51
|
+
dir
|
52
|
+
end
|
53
|
+
|
54
|
+
def should_log_response?
|
55
|
+
return false if call.nil?
|
56
|
+
return false if Esi.config.response_log_path.blank? || !Dir.exist?(Esi.config.response_log_path)
|
57
|
+
true
|
40
58
|
end
|
41
59
|
|
42
60
|
def method_missing(method, *args, &block)
|
43
61
|
data.send(method, *args, &block)
|
44
62
|
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def normalize_response_body
|
67
|
+
MultiJson.load(body || {}, symbolize_keys: true, object_class: OpenStruct)
|
68
|
+
end
|
45
69
|
end
|
46
70
|
end
|
data/lib/esi/version.rb
CHANGED
data/lib/esi.rb
CHANGED
@@ -1,12 +1,19 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'oauth2'
|
4
|
+
require 'forwardable'
|
5
|
+
require 'ostruct'
|
6
|
+
require 'addressable/uri'
|
7
|
+
require 'active_support/cache'
|
8
|
+
require 'active_support/notifications'
|
7
9
|
require 'active_support/core_ext/string'
|
8
|
-
require
|
10
|
+
require 'active_support/core_ext/class/attribute'
|
9
11
|
|
12
|
+
# The main Esi Module
|
13
|
+
# @!attribute [w] api_version
|
14
|
+
# @return [Symbol] the Esi Api version used by the gem
|
15
|
+
# @!attribute [w] logger
|
16
|
+
# @return [Logger] the logger class for the gem
|
10
17
|
module Esi
|
11
18
|
autoload :VERSION, 'esi/version'
|
12
19
|
autoload :AccessToken, 'esi/access_token'
|
@@ -15,6 +22,10 @@ module Esi
|
|
15
22
|
autoload :Client, 'esi/client'
|
16
23
|
autoload :Response, 'esi/response'
|
17
24
|
|
25
|
+
require_relative 'esi/api_error'
|
26
|
+
|
27
|
+
# Default ESI access scopes
|
28
|
+
# @return [Array<String>] the default scopes
|
18
29
|
SCOPES = %w(
|
19
30
|
esi-assets.read_assets.v1
|
20
31
|
esi-bookmarks.read_character_bookmarks.v1
|
@@ -61,7 +72,10 @@ module Esi
|
|
61
72
|
esi-universe.read_structures.v1
|
62
73
|
esi-wallet.read_character_wallet.v1
|
63
74
|
esi-wallet.read_corporation_wallets.v1
|
64
|
-
)
|
75
|
+
).freeze
|
76
|
+
|
77
|
+
# The default Esi gem configuration
|
78
|
+
# @return [Hash{Symbol => Symbol|String|Fixnum|Object|Array}] the default configuration
|
65
79
|
DEFAULT_CONFIG = {
|
66
80
|
datasource: :tranquility,
|
67
81
|
oauth_host: 'https://login.eveonline.com',
|
@@ -75,21 +89,27 @@ module Esi
|
|
75
89
|
client_secret: nil,
|
76
90
|
cache: ActiveSupport::Cache::MemoryStore.new,
|
77
91
|
scopes: SCOPES
|
78
|
-
}
|
92
|
+
}.freeze
|
79
93
|
|
80
94
|
class << self
|
81
95
|
attr_writer :api_version, :config, :logger, :cache
|
82
96
|
|
97
|
+
# The Esi Configuration
|
98
|
+
# @return [OpenStruct] the configuration object
|
83
99
|
def config
|
84
100
|
@config ||= OpenStruct.new(DEFAULT_CONFIG)
|
85
101
|
end
|
86
102
|
|
103
|
+
# The Esi logger class instance
|
104
|
+
# @return [MyLoggerInstance|Logger] an instance of the logger class
|
87
105
|
def logger
|
88
106
|
@logger ||= Esi.config.logger || Logger.new(Esi.config.log_target).tap do |l|
|
89
107
|
l.level = Logger.const_get(Esi.config.log_level.upcase)
|
90
108
|
end
|
91
109
|
end
|
92
110
|
|
111
|
+
# The Esi cache class instance
|
112
|
+
# @return [ActiveSupport::Cache::Store] an instance of cache
|
93
113
|
def cache
|
94
114
|
if Esi.config.cache.nil?
|
95
115
|
@cache ||= ActiveSupport::Cache::NullStore.new
|
@@ -98,54 +118,35 @@ module Esi
|
|
98
118
|
end
|
99
119
|
end
|
100
120
|
|
121
|
+
# The Esi Api version to interface with
|
122
|
+
# @return [Symbol] the esi api version
|
101
123
|
def api_version
|
102
124
|
@api_version || :latest
|
103
125
|
end
|
104
126
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
127
|
+
# Generate an Esi url for a given path
|
128
|
+
# @param [String] path the path to generate an esi url for
|
129
|
+
# @param [Hash{Symbol => String|Fixnum}] params the params for the url query
|
130
|
+
# @return [String] the generated url
|
131
|
+
def generate_url(path, params = {})
|
132
|
+
url = url_for_path(path)
|
110
133
|
uri = Addressable::URI.parse(url)
|
111
|
-
uri.query_values = {datasource: config.datasource}.merge(params.to_h)
|
134
|
+
uri.query_values = { datasource: config.datasource }.merge(params.to_h)
|
112
135
|
uri.to_s
|
113
136
|
end
|
114
137
|
|
138
|
+
# The current Esi client
|
139
|
+
# @return [Esi::Client] the current client
|
115
140
|
def client
|
116
|
-
@client ||= Client.
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
class ApiError < OAuth2::Error
|
121
|
-
attr_reader :response, :key, :message, :type, :original_exception
|
122
|
-
|
123
|
-
def initialize(response, original_exception=nil)
|
124
|
-
super(response.original_response)
|
125
|
-
|
126
|
-
@response = response
|
127
|
-
@original_exception = original_exception
|
128
|
-
@code = response.original_response.status
|
129
|
-
@key = response.data[:key]
|
130
|
-
@message = response.data[:message].presence || response.data[:error] || original_exception.try(:message)
|
131
|
-
@type = response.data[:exceptionType]
|
141
|
+
@client ||= Client.current
|
132
142
|
end
|
133
|
-
end
|
134
143
|
|
135
|
-
|
136
|
-
attr_reader :original_exception
|
144
|
+
private
|
137
145
|
|
138
|
-
def
|
139
|
-
|
140
|
-
|
146
|
+
def url_for_path(path)
|
147
|
+
path = path[1..-1] if path.start_with?('/')
|
148
|
+
path += '/' unless path.end_with?('/')
|
149
|
+
[config.api_host, config.api_version, path].join('/')
|
141
150
|
end
|
142
151
|
end
|
143
|
-
|
144
|
-
class ApiUnknownError < ApiError; end
|
145
|
-
class ApiBadRequestError < ApiError; end
|
146
|
-
class ApiRefreshTokenExpiredError < ApiError; end
|
147
|
-
class ApiInvalidAppClientKeysError < ApiError; end
|
148
|
-
class ApiNotFoundError < ApiError; end
|
149
|
-
class ApiForbiddenError < ApiError; end
|
150
|
-
class Error < StandardError; end
|
151
152
|
end
|
data/lib/omniauth/esi.rb
CHANGED
@@ -1,11 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'omniauth/strategies/oauth2'
|
2
4
|
|
3
5
|
module OmniAuth
|
4
6
|
module Strategies
|
5
7
|
class Esi < OmniAuth::Strategies::OAuth2
|
6
8
|
option :name, 'esi'
|
7
|
-
option :client_options,
|
8
|
-
option :authorize_options,
|
9
|
+
option :client_options, site: ::Esi.config.oauth_host, verify_url: '/oauth/verify'
|
10
|
+
option :authorize_options, %i(scope callback_url)
|
9
11
|
|
10
12
|
uid { extra_info[:character_id] }
|
11
13
|
|
@@ -19,11 +21,11 @@ module OmniAuth
|
|
19
21
|
end
|
20
22
|
|
21
23
|
credentials do
|
22
|
-
hash = {token: access_token.token}
|
23
|
-
hash
|
24
|
-
hash
|
25
|
-
hash
|
26
|
-
hash
|
24
|
+
hash = { token: access_token.token }
|
25
|
+
hash[:refresh_token] = access_token.refresh_token if access_token.refresh_token
|
26
|
+
hash[:expires_at] = access_token.expires_at if access_token.expires?
|
27
|
+
hash[:expires] = access_token.expires?
|
28
|
+
hash[:scopes] = extra_info[:scopes].split(' ') if extra_info[:scopes]
|
27
29
|
hash
|
28
30
|
end
|
29
31
|
|
@@ -32,7 +34,9 @@ module OmniAuth
|
|
32
34
|
end
|
33
35
|
|
34
36
|
def extra_info
|
35
|
-
@extra_info ||= deep_symbolize(
|
37
|
+
@extra_info ||= deep_symbolize(
|
38
|
+
access_token.get(options.client_options.verify_url).parsed.transform_keys!(&:underscore)
|
39
|
+
)
|
36
40
|
end
|
37
41
|
|
38
42
|
def authorize_params
|
metadata
CHANGED
@@ -1,29 +1,30 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: esi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Danny Hiemstra
|
8
|
+
- Aaron Allen
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date: 2018-02-
|
12
|
+
date: 2018-02-22 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
15
|
+
name: activesupport
|
15
16
|
requirement: !ruby/object:Gem::Requirement
|
16
17
|
requirements:
|
17
|
-
- - "
|
18
|
+
- - ">="
|
18
19
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
20
|
+
version: '0'
|
20
21
|
type: :runtime
|
21
22
|
prerelease: false
|
22
23
|
version_requirements: !ruby/object:Gem::Requirement
|
23
24
|
requirements:
|
24
|
-
- - "
|
25
|
+
- - ">="
|
25
26
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
27
|
+
version: '0'
|
27
28
|
- !ruby/object:Gem::Dependency
|
28
29
|
name: addressable
|
29
30
|
requirement: !ruby/object:Gem::Requirement
|
@@ -39,19 +40,19 @@ dependencies:
|
|
39
40
|
- !ruby/object:Gem::Version
|
40
41
|
version: '2.3'
|
41
42
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
43
|
+
name: oauth2
|
43
44
|
requirement: !ruby/object:Gem::Requirement
|
44
45
|
requirements:
|
45
|
-
- - "
|
46
|
+
- - "~>"
|
46
47
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
48
|
+
version: '1.4'
|
48
49
|
type: :runtime
|
49
50
|
prerelease: false
|
50
51
|
version_requirements: !ruby/object:Gem::Requirement
|
51
52
|
requirements:
|
52
|
-
- - "
|
53
|
+
- - "~>"
|
53
54
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
55
|
+
version: '1.4'
|
55
56
|
- !ruby/object:Gem::Dependency
|
56
57
|
name: bundler
|
57
58
|
requirement: !ruby/object:Gem::Requirement
|
@@ -66,6 +67,20 @@ dependencies:
|
|
66
67
|
- - "~>"
|
67
68
|
- !ruby/object:Gem::Version
|
68
69
|
version: '1.14'
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: minitest
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - "~>"
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '5.0'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - "~>"
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '5.0'
|
69
84
|
- !ruby/object:Gem::Dependency
|
70
85
|
name: rake
|
71
86
|
requirement: !ruby/object:Gem::Requirement
|
@@ -81,22 +96,51 @@ dependencies:
|
|
81
96
|
- !ruby/object:Gem::Version
|
82
97
|
version: '10.0'
|
83
98
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
99
|
+
name: rubocop
|
85
100
|
requirement: !ruby/object:Gem::Requirement
|
86
101
|
requirements:
|
87
102
|
- - "~>"
|
88
103
|
- !ruby/object:Gem::Version
|
89
|
-
version: '
|
104
|
+
version: '0.52'
|
90
105
|
type: :development
|
91
106
|
prerelease: false
|
92
107
|
version_requirements: !ruby/object:Gem::Requirement
|
93
108
|
requirements:
|
94
109
|
- - "~>"
|
95
110
|
- !ruby/object:Gem::Version
|
96
|
-
version: '
|
111
|
+
version: '0.52'
|
112
|
+
- !ruby/object:Gem::Dependency
|
113
|
+
name: shoulda
|
114
|
+
requirement: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - "~>"
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '3.5'
|
119
|
+
type: :development
|
120
|
+
prerelease: false
|
121
|
+
version_requirements: !ruby/object:Gem::Requirement
|
122
|
+
requirements:
|
123
|
+
- - "~>"
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '3.5'
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: yard
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
requirements:
|
130
|
+
- - "~>"
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: '0.9'
|
133
|
+
type: :development
|
134
|
+
prerelease: false
|
135
|
+
version_requirements: !ruby/object:Gem::Requirement
|
136
|
+
requirements:
|
137
|
+
- - "~>"
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
version: '0.9'
|
97
140
|
description: EVE ESI API wrapper
|
98
141
|
email:
|
99
142
|
- dannyhiemstra@gmail.com
|
143
|
+
- aaronmallen4@gmail.com
|
100
144
|
executables: []
|
101
145
|
extensions: []
|
102
146
|
extra_rdoc_files: []
|
@@ -106,7 +150,9 @@ files:
|
|
106
150
|
- esi.gemspec
|
107
151
|
- lib/esi.rb
|
108
152
|
- lib/esi/access_token.rb
|
153
|
+
- lib/esi/api_error.rb
|
109
154
|
- lib/esi/calls.rb
|
155
|
+
- lib/esi/calls/info.rb
|
110
156
|
- lib/esi/client.rb
|
111
157
|
- lib/esi/o_auth.rb
|
112
158
|
- lib/esi/response.rb
|