Class: Esi::Client
- Inherits:
-
Object
- Object
- Esi::Client
- Defined in:
- lib/esi/client.rb
Overview
The Esi Client class
Constant Summary collapse
- MAX_ATTEMPTS =
Returns The max amount of request attempst Client will make.
2
Instance Attribute Summary collapse
-
#access_token ⇒ String
The esi access_token.
-
#expires_at ⇒ Time
The timestamp of the esi token expire.
-
#logger ⇒ Logger
readonly
The logger class for the gem.
-
#oauth ⇒ Esi::Oauth
readonly
The oauth instance for the client.
-
#refresh_callback ⇒ #callback
The refresh_token callback method.
-
#refresh_token ⇒ String
The esi refresh_token string.
Class Method Summary collapse
-
.current ⇒ Esi::Client
Get the current thread’s ‘Esi::Client`.
-
.current=(client) ⇒ Esi::Client
Set the current thread’s ‘Esi::Client`.
-
.switch_to_default ⇒ Esi::Client
Switch to default Esi::Client (Esi::Client.new).
Instance Method Summary collapse
-
#debug(message) ⇒ void
Log a message with debug.
-
#initialize(token: nil, refresh_token: nil, expires_at: nil) ⇒ Client
constructor
Create a new instance of Client.
-
#log(message) ⇒ void
Log a message.
-
#method?(name) ⇒ Boolean
Test if the Esi::Client has a method.
-
#method_missing(name, *args, &block) ⇒ Esi::Response
Intercept Esi::Client method_missing and attempt to call an Esi::Request with an Esi::Calls.
-
#plural_method?(name) ⇒ Boolean
Test if the Esi::Client has a pluralized version of a method.
-
#switch_to ⇒ self
Switch current thread’s client to instance of Esi::Client.
-
#with_client ⇒ Object
Yield block with instance of Esi::Client and revert to previous client or default client.
Constructor Details
#initialize(token: nil, refresh_token: nil, expires_at: nil) ⇒ Client
Create a new instance of Client
28 29 30 31 32 33 34 |
# File 'lib/esi/client.rb', line 28 def initialize(token: nil, refresh_token: nil, expires_at: nil) @logger = Esi.logger @access_token = token @refresh_token = refresh_token @expires_at = expires_at @oauth = init_oauth end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args, &block) ⇒ Esi::Response
91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/esi/client.rb', line 91 def method_missing(name, *args, &block) klass = nil ActiveSupport::Notifications.instrument('esi.client.detect_call') do class_name = method_to_class_name name begin klass = Esi::Calls.const_get(class_name) rescue NameError super(name, *args, &block) end end cached_response(klass, *args, &block) end |
Instance Attribute Details
#access_token ⇒ String
Returns the esi access_token.
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 |
# File 'lib/esi/client.rb', line 17 class Client # @return [Fixnum] The max amount of request attempst Client will make MAX_ATTEMPTS = 2 attr_accessor :refresh_callback, :access_token, :refresh_token, :expires_at attr_reader :logger, :oauth # Create a new instance of Client # @param token [String] token the esi access_token # @param refresh_token [String] refresh_token the esi refresh_token # @param expires_at [Time] expires_at the time stamp the esi token expires_at def initialize(token: nil, refresh_token: nil, expires_at: nil) @logger = Esi.logger @access_token = token @refresh_token = refresh_token @expires_at = expires_at @oauth = init_oauth end # Set the current thread's `Esi::Client` # # @param client [Esi::Client] the client to set # # @return [Esi::Client] the current thread's `Esi::Client` def self.current=(client) Thread.current[:esi_client] = client end # Get the current thread's `Esi::Client` # @return [Esi::Client] the current thread's `Esi::Client` def self.current Thread.current[:esi_client] ||= new end # Switch to default Esi::Client (Esi::Client.new) # @return [Esi::Client] the current thread's `Esi::Client` def self.switch_to_default self.current = new end # Switch current thread's client to instance of Esi::Client # @return [self] the instance calling switch to def switch_to Esi::Client.current = self end # Yield block with instance of Esi::Client and revert to # previous client or default client # # @example Call an Esi::Client method using an instance of client # new_client = Esi::Client.new(token: 'foo', refresh_token: 'foo', exceptionxpires_at: 30.minutes.from_now) # new_client.with_client do |client| # client.character(1234) # end # #=> Esi::Response<#> # # @yieldreturn [#block] the passed block. def with_client initial_client = Esi::Client.current switch_to yield(self) if block_given? ensure initial_client.switch_to if initial_client Esi::Client.switch_to_default unless initial_client end # Intercept Esi::Client method_missing and attempt to call an Esi::Request # with an Esi::Calls # # @param name [Symbol|String] name the name of the method called # @param args [Array] *args the arguments to call the method with # @param block [#block] &block the block to pass to the underlying method # @raise [NameError] If the Esi::Calls does not exist # @return [Esi::Response] the response given for the call def method_missing(name, *args, &block) klass = nil ActiveSupport::Notifications.instrument('esi.client.detect_call') do class_name = method_to_class_name name begin klass = Esi::Calls.const_get(class_name) rescue NameError super(name, *args, &block) end end cached_response(klass, *args, &block) end # Test if the Esi::Client has a method # @param [Symbol] name the name of the method to test # @return [Boolean] wether or not the method exists def method?(name) begin klass = Esi::Calls.const_get(method_to_class_name(name)) rescue NameError return false end !klass.nil? end # Test if the Esi::Client has a pluralized version of a method # @param [Symbol] name the name of the method to test # @return [Boolean] wether or not the pluralized method exists def plural_method?(name) plural = name.to_s.pluralize.to_sym method? plural end # Log a message # @param [String] message the message to log # @return [void] the Logger.info method with message def log() logger.info end # Log a message with debug # @param [String] message the message to log # @return [void] the Logger.debug method with message def debug() logger.debug end private def make_call(call, &block) call.paginated? ? request_paginated(call, &block) : request(call, &block) end def cached_response(klass, *args, &block) call = klass.new(*args) Esi.cache.fetch(call.cache_key, exceptionxpires_in: klass.cache_duration) do make_call(call, &block) end end def method_to_class_name(name) name.dup.to_s.split('_').map(&:capitalize).join end def init_oauth OAuth.new( access_token: @access_token, refresh_token: @refresh_token, expires_at: @expires_at, callback: lambda { |token, exceptionxpires_at| @access_token = token @expires_at = expires_at refresh_callback.call(token, exceptionxpires_at) if refresh_callback.respond_to?(:call) } ) end def request_paginated(call, &block) call.page = 1 paginated_response(response, call, &block) end def paginated_response(response, call, &block) loop do page_response = request(call, &block) break response if page_response.data.blank? response = response ? response.merge(page_response) : page_response call.page += 1 end end # @todo make rubocop compliant # rubocop:disable Metrics/AbcSize def request(call, &block) response = Timeout.timeout(Esi.config.timeout) do oauth.request(call.method, call.url, timeout: Esi.config.timeout) end response = Response.new(response, call) response.data.each { |item| yield(item) } if block response.save rescue OAuth2::Error => e exception = error_class_for(e.response.status).new(Response.new(e.response, call), e) raise exception.is_a?(Esi::ApiBadRequestError) ? process_bad_request_error(exception) : exception rescue Faraday::SSLError, Faraday::ConnectionFailed, Timeout::Error => e raise Esi::TimeoutError.new(Response.new(e.response, call), exception) end # rubocop:enable Metrics/AbcSize def error_class_for(status) case status when 400 then Esi::ApiBadRequestError when 401 then Esi::UnauthorizedError when 403 then Esi::ApiForbiddenError when 404 then Esi::ApiNotFoundError when 502 then Esi::TemporaryServerError when 503 then Esi::RateLimitError else Esi::ApiUnknownError end end def process_bad_request_error(exception) case exception. when 'invalid_token' then Esi::ApiRefreshTokenExpiredError.new(response, exception) when 'invalid_client' then Esi::ApiInvalidAppClientKeysError.new(response, exception) else exception end end end |
#expires_at ⇒ Time
Returns the timestamp of the esi token expire.
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 |
# File 'lib/esi/client.rb', line 17 class Client # @return [Fixnum] The max amount of request attempst Client will make MAX_ATTEMPTS = 2 attr_accessor :refresh_callback, :access_token, :refresh_token, :expires_at attr_reader :logger, :oauth # Create a new instance of Client # @param token [String] token the esi access_token # @param refresh_token [String] refresh_token the esi refresh_token # @param expires_at [Time] expires_at the time stamp the esi token expires_at def initialize(token: nil, refresh_token: nil, expires_at: nil) @logger = Esi.logger @access_token = token @refresh_token = refresh_token @expires_at = expires_at @oauth = init_oauth end # Set the current thread's `Esi::Client` # # @param client [Esi::Client] the client to set # # @return [Esi::Client] the current thread's `Esi::Client` def self.current=(client) Thread.current[:esi_client] = client end # Get the current thread's `Esi::Client` # @return [Esi::Client] the current thread's `Esi::Client` def self.current Thread.current[:esi_client] ||= new end # Switch to default Esi::Client (Esi::Client.new) # @return [Esi::Client] the current thread's `Esi::Client` def self.switch_to_default self.current = new end # Switch current thread's client to instance of Esi::Client # @return [self] the instance calling switch to def switch_to Esi::Client.current = self end # Yield block with instance of Esi::Client and revert to # previous client or default client # # @example Call an Esi::Client method using an instance of client # new_client = Esi::Client.new(token: 'foo', refresh_token: 'foo', exceptionxpires_at: 30.minutes.from_now) # new_client.with_client do |client| # client.character(1234) # end # #=> Esi::Response<#> # # @yieldreturn [#block] the passed block. def with_client initial_client = Esi::Client.current switch_to yield(self) if block_given? ensure initial_client.switch_to if initial_client Esi::Client.switch_to_default unless initial_client end # Intercept Esi::Client method_missing and attempt to call an Esi::Request # with an Esi::Calls # # @param name [Symbol|String] name the name of the method called # @param args [Array] *args the arguments to call the method with # @param block [#block] &block the block to pass to the underlying method # @raise [NameError] If the Esi::Calls does not exist # @return [Esi::Response] the response given for the call def method_missing(name, *args, &block) klass = nil ActiveSupport::Notifications.instrument('esi.client.detect_call') do class_name = method_to_class_name name begin klass = Esi::Calls.const_get(class_name) rescue NameError super(name, *args, &block) end end cached_response(klass, *args, &block) end # Test if the Esi::Client has a method # @param [Symbol] name the name of the method to test # @return [Boolean] wether or not the method exists def method?(name) begin klass = Esi::Calls.const_get(method_to_class_name(name)) rescue NameError return false end !klass.nil? end # Test if the Esi::Client has a pluralized version of a method # @param [Symbol] name the name of the method to test # @return [Boolean] wether or not the pluralized method exists def plural_method?(name) plural = name.to_s.pluralize.to_sym method? plural end # Log a message # @param [String] message the message to log # @return [void] the Logger.info method with message def log() logger.info end # Log a message with debug # @param [String] message the message to log # @return [void] the Logger.debug method with message def debug() logger.debug end private def make_call(call, &block) call.paginated? ? request_paginated(call, &block) : request(call, &block) end def cached_response(klass, *args, &block) call = klass.new(*args) Esi.cache.fetch(call.cache_key, exceptionxpires_in: klass.cache_duration) do make_call(call, &block) end end def method_to_class_name(name) name.dup.to_s.split('_').map(&:capitalize).join end def init_oauth OAuth.new( access_token: @access_token, refresh_token: @refresh_token, expires_at: @expires_at, callback: lambda { |token, exceptionxpires_at| @access_token = token @expires_at = expires_at refresh_callback.call(token, exceptionxpires_at) if refresh_callback.respond_to?(:call) } ) end def request_paginated(call, &block) call.page = 1 paginated_response(response, call, &block) end def paginated_response(response, call, &block) loop do page_response = request(call, &block) break response if page_response.data.blank? response = response ? response.merge(page_response) : page_response call.page += 1 end end # @todo make rubocop compliant # rubocop:disable Metrics/AbcSize def request(call, &block) response = Timeout.timeout(Esi.config.timeout) do oauth.request(call.method, call.url, timeout: Esi.config.timeout) end response = Response.new(response, call) response.data.each { |item| yield(item) } if block response.save rescue OAuth2::Error => e exception = error_class_for(e.response.status).new(Response.new(e.response, call), e) raise exception.is_a?(Esi::ApiBadRequestError) ? process_bad_request_error(exception) : exception rescue Faraday::SSLError, Faraday::ConnectionFailed, Timeout::Error => e raise Esi::TimeoutError.new(Response.new(e.response, call), exception) end # rubocop:enable Metrics/AbcSize def error_class_for(status) case status when 400 then Esi::ApiBadRequestError when 401 then Esi::UnauthorizedError when 403 then Esi::ApiForbiddenError when 404 then Esi::ApiNotFoundError when 502 then Esi::TemporaryServerError when 503 then Esi::RateLimitError else Esi::ApiUnknownError end end def process_bad_request_error(exception) case exception. when 'invalid_token' then Esi::ApiRefreshTokenExpiredError.new(response, exception) when 'invalid_client' then Esi::ApiInvalidAppClientKeysError.new(response, exception) else exception end end end |
#logger ⇒ Logger (readonly)
Returns the logger class for the gem.
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 |
# File 'lib/esi/client.rb', line 17 class Client # @return [Fixnum] The max amount of request attempst Client will make MAX_ATTEMPTS = 2 attr_accessor :refresh_callback, :access_token, :refresh_token, :expires_at attr_reader :logger, :oauth # Create a new instance of Client # @param token [String] token the esi access_token # @param refresh_token [String] refresh_token the esi refresh_token # @param expires_at [Time] expires_at the time stamp the esi token expires_at def initialize(token: nil, refresh_token: nil, expires_at: nil) @logger = Esi.logger @access_token = token @refresh_token = refresh_token @expires_at = expires_at @oauth = init_oauth end # Set the current thread's `Esi::Client` # # @param client [Esi::Client] the client to set # # @return [Esi::Client] the current thread's `Esi::Client` def self.current=(client) Thread.current[:esi_client] = client end # Get the current thread's `Esi::Client` # @return [Esi::Client] the current thread's `Esi::Client` def self.current Thread.current[:esi_client] ||= new end # Switch to default Esi::Client (Esi::Client.new) # @return [Esi::Client] the current thread's `Esi::Client` def self.switch_to_default self.current = new end # Switch current thread's client to instance of Esi::Client # @return [self] the instance calling switch to def switch_to Esi::Client.current = self end # Yield block with instance of Esi::Client and revert to # previous client or default client # # @example Call an Esi::Client method using an instance of client # new_client = Esi::Client.new(token: 'foo', refresh_token: 'foo', exceptionxpires_at: 30.minutes.from_now) # new_client.with_client do |client| # client.character(1234) # end # #=> Esi::Response<#> # # @yieldreturn [#block] the passed block. def with_client initial_client = Esi::Client.current switch_to yield(self) if block_given? ensure initial_client.switch_to if initial_client Esi::Client.switch_to_default unless initial_client end # Intercept Esi::Client method_missing and attempt to call an Esi::Request # with an Esi::Calls # # @param name [Symbol|String] name the name of the method called # @param args [Array] *args the arguments to call the method with # @param block [#block] &block the block to pass to the underlying method # @raise [NameError] If the Esi::Calls does not exist # @return [Esi::Response] the response given for the call def method_missing(name, *args, &block) klass = nil ActiveSupport::Notifications.instrument('esi.client.detect_call') do class_name = method_to_class_name name begin klass = Esi::Calls.const_get(class_name) rescue NameError super(name, *args, &block) end end cached_response(klass, *args, &block) end # Test if the Esi::Client has a method # @param [Symbol] name the name of the method to test # @return [Boolean] wether or not the method exists def method?(name) begin klass = Esi::Calls.const_get(method_to_class_name(name)) rescue NameError return false end !klass.nil? end # Test if the Esi::Client has a pluralized version of a method # @param [Symbol] name the name of the method to test # @return [Boolean] wether or not the pluralized method exists def plural_method?(name) plural = name.to_s.pluralize.to_sym method? plural end # Log a message # @param [String] message the message to log # @return [void] the Logger.info method with message def log() logger.info end # Log a message with debug # @param [String] message the message to log # @return [void] the Logger.debug method with message def debug() logger.debug end private def make_call(call, &block) call.paginated? ? request_paginated(call, &block) : request(call, &block) end def cached_response(klass, *args, &block) call = klass.new(*args) Esi.cache.fetch(call.cache_key, exceptionxpires_in: klass.cache_duration) do make_call(call, &block) end end def method_to_class_name(name) name.dup.to_s.split('_').map(&:capitalize).join end def init_oauth OAuth.new( access_token: @access_token, refresh_token: @refresh_token, expires_at: @expires_at, callback: lambda { |token, exceptionxpires_at| @access_token = token @expires_at = expires_at refresh_callback.call(token, exceptionxpires_at) if refresh_callback.respond_to?(:call) } ) end def request_paginated(call, &block) call.page = 1 paginated_response(response, call, &block) end def paginated_response(response, call, &block) loop do page_response = request(call, &block) break response if page_response.data.blank? response = response ? response.merge(page_response) : page_response call.page += 1 end end # @todo make rubocop compliant # rubocop:disable Metrics/AbcSize def request(call, &block) response = Timeout.timeout(Esi.config.timeout) do oauth.request(call.method, call.url, timeout: Esi.config.timeout) end response = Response.new(response, call) response.data.each { |item| yield(item) } if block response.save rescue OAuth2::Error => e exception = error_class_for(e.response.status).new(Response.new(e.response, call), e) raise exception.is_a?(Esi::ApiBadRequestError) ? process_bad_request_error(exception) : exception rescue Faraday::SSLError, Faraday::ConnectionFailed, Timeout::Error => e raise Esi::TimeoutError.new(Response.new(e.response, call), exception) end # rubocop:enable Metrics/AbcSize def error_class_for(status) case status when 400 then Esi::ApiBadRequestError when 401 then Esi::UnauthorizedError when 403 then Esi::ApiForbiddenError when 404 then Esi::ApiNotFoundError when 502 then Esi::TemporaryServerError when 503 then Esi::RateLimitError else Esi::ApiUnknownError end end def process_bad_request_error(exception) case exception. when 'invalid_token' then Esi::ApiRefreshTokenExpiredError.new(response, exception) when 'invalid_client' then Esi::ApiInvalidAppClientKeysError.new(response, exception) else exception end end end |
#oauth ⇒ Esi::Oauth (readonly)
Returns the oauth instance for the client.
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 |
# File 'lib/esi/client.rb', line 17 class Client # @return [Fixnum] The max amount of request attempst Client will make MAX_ATTEMPTS = 2 attr_accessor :refresh_callback, :access_token, :refresh_token, :expires_at attr_reader :logger, :oauth # Create a new instance of Client # @param token [String] token the esi access_token # @param refresh_token [String] refresh_token the esi refresh_token # @param expires_at [Time] expires_at the time stamp the esi token expires_at def initialize(token: nil, refresh_token: nil, expires_at: nil) @logger = Esi.logger @access_token = token @refresh_token = refresh_token @expires_at = expires_at @oauth = init_oauth end # Set the current thread's `Esi::Client` # # @param client [Esi::Client] the client to set # # @return [Esi::Client] the current thread's `Esi::Client` def self.current=(client) Thread.current[:esi_client] = client end # Get the current thread's `Esi::Client` # @return [Esi::Client] the current thread's `Esi::Client` def self.current Thread.current[:esi_client] ||= new end # Switch to default Esi::Client (Esi::Client.new) # @return [Esi::Client] the current thread's `Esi::Client` def self.switch_to_default self.current = new end # Switch current thread's client to instance of Esi::Client # @return [self] the instance calling switch to def switch_to Esi::Client.current = self end # Yield block with instance of Esi::Client and revert to # previous client or default client # # @example Call an Esi::Client method using an instance of client # new_client = Esi::Client.new(token: 'foo', refresh_token: 'foo', exceptionxpires_at: 30.minutes.from_now) # new_client.with_client do |client| # client.character(1234) # end # #=> Esi::Response<#> # # @yieldreturn [#block] the passed block. def with_client initial_client = Esi::Client.current switch_to yield(self) if block_given? ensure initial_client.switch_to if initial_client Esi::Client.switch_to_default unless initial_client end # Intercept Esi::Client method_missing and attempt to call an Esi::Request # with an Esi::Calls # # @param name [Symbol|String] name the name of the method called # @param args [Array] *args the arguments to call the method with # @param block [#block] &block the block to pass to the underlying method # @raise [NameError] If the Esi::Calls does not exist # @return [Esi::Response] the response given for the call def method_missing(name, *args, &block) klass = nil ActiveSupport::Notifications.instrument('esi.client.detect_call') do class_name = method_to_class_name name begin klass = Esi::Calls.const_get(class_name) rescue NameError super(name, *args, &block) end end cached_response(klass, *args, &block) end # Test if the Esi::Client has a method # @param [Symbol] name the name of the method to test # @return [Boolean] wether or not the method exists def method?(name) begin klass = Esi::Calls.const_get(method_to_class_name(name)) rescue NameError return false end !klass.nil? end # Test if the Esi::Client has a pluralized version of a method # @param [Symbol] name the name of the method to test # @return [Boolean] wether or not the pluralized method exists def plural_method?(name) plural = name.to_s.pluralize.to_sym method? plural end # Log a message # @param [String] message the message to log # @return [void] the Logger.info method with message def log() logger.info end # Log a message with debug # @param [String] message the message to log # @return [void] the Logger.debug method with message def debug() logger.debug end private def make_call(call, &block) call.paginated? ? request_paginated(call, &block) : request(call, &block) end def cached_response(klass, *args, &block) call = klass.new(*args) Esi.cache.fetch(call.cache_key, exceptionxpires_in: klass.cache_duration) do make_call(call, &block) end end def method_to_class_name(name) name.dup.to_s.split('_').map(&:capitalize).join end def init_oauth OAuth.new( access_token: @access_token, refresh_token: @refresh_token, expires_at: @expires_at, callback: lambda { |token, exceptionxpires_at| @access_token = token @expires_at = expires_at refresh_callback.call(token, exceptionxpires_at) if refresh_callback.respond_to?(:call) } ) end def request_paginated(call, &block) call.page = 1 paginated_response(response, call, &block) end def paginated_response(response, call, &block) loop do page_response = request(call, &block) break response if page_response.data.blank? response = response ? response.merge(page_response) : page_response call.page += 1 end end # @todo make rubocop compliant # rubocop:disable Metrics/AbcSize def request(call, &block) response = Timeout.timeout(Esi.config.timeout) do oauth.request(call.method, call.url, timeout: Esi.config.timeout) end response = Response.new(response, call) response.data.each { |item| yield(item) } if block response.save rescue OAuth2::Error => e exception = error_class_for(e.response.status).new(Response.new(e.response, call), e) raise exception.is_a?(Esi::ApiBadRequestError) ? process_bad_request_error(exception) : exception rescue Faraday::SSLError, Faraday::ConnectionFailed, Timeout::Error => e raise Esi::TimeoutError.new(Response.new(e.response, call), exception) end # rubocop:enable Metrics/AbcSize def error_class_for(status) case status when 400 then Esi::ApiBadRequestError when 401 then Esi::UnauthorizedError when 403 then Esi::ApiForbiddenError when 404 then Esi::ApiNotFoundError when 502 then Esi::TemporaryServerError when 503 then Esi::RateLimitError else Esi::ApiUnknownError end end def process_bad_request_error(exception) case exception. when 'invalid_token' then Esi::ApiRefreshTokenExpiredError.new(response, exception) when 'invalid_client' then Esi::ApiInvalidAppClientKeysError.new(response, exception) else exception end end end |
#refresh_callback ⇒ #callback
Returns the refresh_token callback method.
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 |
# File 'lib/esi/client.rb', line 17 class Client # @return [Fixnum] The max amount of request attempst Client will make MAX_ATTEMPTS = 2 attr_accessor :refresh_callback, :access_token, :refresh_token, :expires_at attr_reader :logger, :oauth # Create a new instance of Client # @param token [String] token the esi access_token # @param refresh_token [String] refresh_token the esi refresh_token # @param expires_at [Time] expires_at the time stamp the esi token expires_at def initialize(token: nil, refresh_token: nil, expires_at: nil) @logger = Esi.logger @access_token = token @refresh_token = refresh_token @expires_at = expires_at @oauth = init_oauth end # Set the current thread's `Esi::Client` # # @param client [Esi::Client] the client to set # # @return [Esi::Client] the current thread's `Esi::Client` def self.current=(client) Thread.current[:esi_client] = client end # Get the current thread's `Esi::Client` # @return [Esi::Client] the current thread's `Esi::Client` def self.current Thread.current[:esi_client] ||= new end # Switch to default Esi::Client (Esi::Client.new) # @return [Esi::Client] the current thread's `Esi::Client` def self.switch_to_default self.current = new end # Switch current thread's client to instance of Esi::Client # @return [self] the instance calling switch to def switch_to Esi::Client.current = self end # Yield block with instance of Esi::Client and revert to # previous client or default client # # @example Call an Esi::Client method using an instance of client # new_client = Esi::Client.new(token: 'foo', refresh_token: 'foo', exceptionxpires_at: 30.minutes.from_now) # new_client.with_client do |client| # client.character(1234) # end # #=> Esi::Response<#> # # @yieldreturn [#block] the passed block. def with_client initial_client = Esi::Client.current switch_to yield(self) if block_given? ensure initial_client.switch_to if initial_client Esi::Client.switch_to_default unless initial_client end # Intercept Esi::Client method_missing and attempt to call an Esi::Request # with an Esi::Calls # # @param name [Symbol|String] name the name of the method called # @param args [Array] *args the arguments to call the method with # @param block [#block] &block the block to pass to the underlying method # @raise [NameError] If the Esi::Calls does not exist # @return [Esi::Response] the response given for the call def method_missing(name, *args, &block) klass = nil ActiveSupport::Notifications.instrument('esi.client.detect_call') do class_name = method_to_class_name name begin klass = Esi::Calls.const_get(class_name) rescue NameError super(name, *args, &block) end end cached_response(klass, *args, &block) end # Test if the Esi::Client has a method # @param [Symbol] name the name of the method to test # @return [Boolean] wether or not the method exists def method?(name) begin klass = Esi::Calls.const_get(method_to_class_name(name)) rescue NameError return false end !klass.nil? end # Test if the Esi::Client has a pluralized version of a method # @param [Symbol] name the name of the method to test # @return [Boolean] wether or not the pluralized method exists def plural_method?(name) plural = name.to_s.pluralize.to_sym method? plural end # Log a message # @param [String] message the message to log # @return [void] the Logger.info method with message def log() logger.info end # Log a message with debug # @param [String] message the message to log # @return [void] the Logger.debug method with message def debug() logger.debug end private def make_call(call, &block) call.paginated? ? request_paginated(call, &block) : request(call, &block) end def cached_response(klass, *args, &block) call = klass.new(*args) Esi.cache.fetch(call.cache_key, exceptionxpires_in: klass.cache_duration) do make_call(call, &block) end end def method_to_class_name(name) name.dup.to_s.split('_').map(&:capitalize).join end def init_oauth OAuth.new( access_token: @access_token, refresh_token: @refresh_token, expires_at: @expires_at, callback: lambda { |token, exceptionxpires_at| @access_token = token @expires_at = expires_at refresh_callback.call(token, exceptionxpires_at) if refresh_callback.respond_to?(:call) } ) end def request_paginated(call, &block) call.page = 1 paginated_response(response, call, &block) end def paginated_response(response, call, &block) loop do page_response = request(call, &block) break response if page_response.data.blank? response = response ? response.merge(page_response) : page_response call.page += 1 end end # @todo make rubocop compliant # rubocop:disable Metrics/AbcSize def request(call, &block) response = Timeout.timeout(Esi.config.timeout) do oauth.request(call.method, call.url, timeout: Esi.config.timeout) end response = Response.new(response, call) response.data.each { |item| yield(item) } if block response.save rescue OAuth2::Error => e exception = error_class_for(e.response.status).new(Response.new(e.response, call), e) raise exception.is_a?(Esi::ApiBadRequestError) ? process_bad_request_error(exception) : exception rescue Faraday::SSLError, Faraday::ConnectionFailed, Timeout::Error => e raise Esi::TimeoutError.new(Response.new(e.response, call), exception) end # rubocop:enable Metrics/AbcSize def error_class_for(status) case status when 400 then Esi::ApiBadRequestError when 401 then Esi::UnauthorizedError when 403 then Esi::ApiForbiddenError when 404 then Esi::ApiNotFoundError when 502 then Esi::TemporaryServerError when 503 then Esi::RateLimitError else Esi::ApiUnknownError end end def process_bad_request_error(exception) case exception. when 'invalid_token' then Esi::ApiRefreshTokenExpiredError.new(response, exception) when 'invalid_client' then Esi::ApiInvalidAppClientKeysError.new(response, exception) else exception end end end |
#refresh_token ⇒ String
Returns the esi refresh_token string.
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 |
# File 'lib/esi/client.rb', line 17 class Client # @return [Fixnum] The max amount of request attempst Client will make MAX_ATTEMPTS = 2 attr_accessor :refresh_callback, :access_token, :refresh_token, :expires_at attr_reader :logger, :oauth # Create a new instance of Client # @param token [String] token the esi access_token # @param refresh_token [String] refresh_token the esi refresh_token # @param expires_at [Time] expires_at the time stamp the esi token expires_at def initialize(token: nil, refresh_token: nil, expires_at: nil) @logger = Esi.logger @access_token = token @refresh_token = refresh_token @expires_at = expires_at @oauth = init_oauth end # Set the current thread's `Esi::Client` # # @param client [Esi::Client] the client to set # # @return [Esi::Client] the current thread's `Esi::Client` def self.current=(client) Thread.current[:esi_client] = client end # Get the current thread's `Esi::Client` # @return [Esi::Client] the current thread's `Esi::Client` def self.current Thread.current[:esi_client] ||= new end # Switch to default Esi::Client (Esi::Client.new) # @return [Esi::Client] the current thread's `Esi::Client` def self.switch_to_default self.current = new end # Switch current thread's client to instance of Esi::Client # @return [self] the instance calling switch to def switch_to Esi::Client.current = self end # Yield block with instance of Esi::Client and revert to # previous client or default client # # @example Call an Esi::Client method using an instance of client # new_client = Esi::Client.new(token: 'foo', refresh_token: 'foo', exceptionxpires_at: 30.minutes.from_now) # new_client.with_client do |client| # client.character(1234) # end # #=> Esi::Response<#> # # @yieldreturn [#block] the passed block. def with_client initial_client = Esi::Client.current switch_to yield(self) if block_given? ensure initial_client.switch_to if initial_client Esi::Client.switch_to_default unless initial_client end # Intercept Esi::Client method_missing and attempt to call an Esi::Request # with an Esi::Calls # # @param name [Symbol|String] name the name of the method called # @param args [Array] *args the arguments to call the method with # @param block [#block] &block the block to pass to the underlying method # @raise [NameError] If the Esi::Calls does not exist # @return [Esi::Response] the response given for the call def method_missing(name, *args, &block) klass = nil ActiveSupport::Notifications.instrument('esi.client.detect_call') do class_name = method_to_class_name name begin klass = Esi::Calls.const_get(class_name) rescue NameError super(name, *args, &block) end end cached_response(klass, *args, &block) end # Test if the Esi::Client has a method # @param [Symbol] name the name of the method to test # @return [Boolean] wether or not the method exists def method?(name) begin klass = Esi::Calls.const_get(method_to_class_name(name)) rescue NameError return false end !klass.nil? end # Test if the Esi::Client has a pluralized version of a method # @param [Symbol] name the name of the method to test # @return [Boolean] wether or not the pluralized method exists def plural_method?(name) plural = name.to_s.pluralize.to_sym method? plural end # Log a message # @param [String] message the message to log # @return [void] the Logger.info method with message def log() logger.info end # Log a message with debug # @param [String] message the message to log # @return [void] the Logger.debug method with message def debug() logger.debug end private def make_call(call, &block) call.paginated? ? request_paginated(call, &block) : request(call, &block) end def cached_response(klass, *args, &block) call = klass.new(*args) Esi.cache.fetch(call.cache_key, exceptionxpires_in: klass.cache_duration) do make_call(call, &block) end end def method_to_class_name(name) name.dup.to_s.split('_').map(&:capitalize).join end def init_oauth OAuth.new( access_token: @access_token, refresh_token: @refresh_token, expires_at: @expires_at, callback: lambda { |token, exceptionxpires_at| @access_token = token @expires_at = expires_at refresh_callback.call(token, exceptionxpires_at) if refresh_callback.respond_to?(:call) } ) end def request_paginated(call, &block) call.page = 1 paginated_response(response, call, &block) end def paginated_response(response, call, &block) loop do page_response = request(call, &block) break response if page_response.data.blank? response = response ? response.merge(page_response) : page_response call.page += 1 end end # @todo make rubocop compliant # rubocop:disable Metrics/AbcSize def request(call, &block) response = Timeout.timeout(Esi.config.timeout) do oauth.request(call.method, call.url, timeout: Esi.config.timeout) end response = Response.new(response, call) response.data.each { |item| yield(item) } if block response.save rescue OAuth2::Error => e exception = error_class_for(e.response.status).new(Response.new(e.response, call), e) raise exception.is_a?(Esi::ApiBadRequestError) ? process_bad_request_error(exception) : exception rescue Faraday::SSLError, Faraday::ConnectionFailed, Timeout::Error => e raise Esi::TimeoutError.new(Response.new(e.response, call), exception) end # rubocop:enable Metrics/AbcSize def error_class_for(status) case status when 400 then Esi::ApiBadRequestError when 401 then Esi::UnauthorizedError when 403 then Esi::ApiForbiddenError when 404 then Esi::ApiNotFoundError when 502 then Esi::TemporaryServerError when 503 then Esi::RateLimitError else Esi::ApiUnknownError end end def process_bad_request_error(exception) case exception. when 'invalid_token' then Esi::ApiRefreshTokenExpiredError.new(response, exception) when 'invalid_client' then Esi::ApiInvalidAppClientKeysError.new(response, exception) else exception end end end |
Class Method Details
.current ⇒ Esi::Client
Get the current thread’s ‘Esi::Client`
47 48 49 |
# File 'lib/esi/client.rb', line 47 def self.current Thread.current[:esi_client] ||= new end |
.current=(client) ⇒ Esi::Client
Set the current thread’s ‘Esi::Client`
41 42 43 |
# File 'lib/esi/client.rb', line 41 def self.current=(client) Thread.current[:esi_client] = client end |
.switch_to_default ⇒ Esi::Client
Switch to default Esi::Client (Esi::Client.new)
53 54 55 |
# File 'lib/esi/client.rb', line 53 def self.switch_to_default self.current = new end |
Instance Method Details
#debug(message) ⇒ void
This method returns an undefined value.
Log a message with debug
134 135 136 |
# File 'lib/esi/client.rb', line 134 def debug() logger.debug end |
#log(message) ⇒ void
This method returns an undefined value.
Log a message
127 128 129 |
# File 'lib/esi/client.rb', line 127 def log() logger.info end |
#method?(name) ⇒ Boolean
Test if the Esi::Client has a method
107 108 109 110 111 112 113 114 |
# File 'lib/esi/client.rb', line 107 def method?(name) begin klass = Esi::Calls.const_get(method_to_class_name(name)) rescue NameError return false end !klass.nil? end |
#plural_method?(name) ⇒ Boolean
Test if the Esi::Client has a pluralized version of a method
119 120 121 122 |
# File 'lib/esi/client.rb', line 119 def plural_method?(name) plural = name.to_s.pluralize.to_sym method? plural end |
#switch_to ⇒ self
Switch current thread’s client to instance of Esi::Client
59 60 61 |
# File 'lib/esi/client.rb', line 59 def switch_to Esi::Client.current = self end |
#with_client ⇒ Object
Yield block with instance of Esi::Client and revert to
previous client or default client
74 75 76 77 78 79 80 81 |
# File 'lib/esi/client.rb', line 74 def with_client initial_client = Esi::Client.current switch_to yield(self) if block_given? ensure initial_client.switch_to if initial_client Esi::Client.switch_to_default unless initial_client end |