class ContextIO::API::AbstractAPI

Constants

BASE_URL

@private

Attributes

base_url[RW]
key[R]

@!attribute [r] key

@return [String] The OAuth key for the user's Context.IO account.

@!attribute [r] secret

@return [String] The OAuth secret for the user's Context.IO account.

@!attribute [r] opts

@return [Hash] opts Optional options for OAuth connections.
opts[R]

@!attribute [r] key

@return [String] The OAuth key for the user's Context.IO account.

@!attribute [r] secret

@return [String] The OAuth secret for the user's Context.IO account.

@!attribute [r] opts

@return [Hash] opts Optional options for OAuth connections.
secret[R]

@!attribute [r] key

@return [String] The OAuth key for the user's Context.IO account.

@!attribute [r] secret

@return [String] The OAuth secret for the user's Context.IO account.

@!attribute [r] opts

@return [Hash] opts Optional options for OAuth connections.
version[RW]

Public Class Methods

base_url() click to toggle source

@return [String] The base URL the API is served from.

# File lib/contextio/api/abstract_api.rb, line 21
def self.base_url
        BASE_URL
end
new(key, secret, opts={}) click to toggle source

@param [String] key The user’s OAuth key for their Context.IO account. @param [String] secret The user’s OAuth secret for their Context.IO account. @param [Hash] opts Optional options for OAuth connections. ie. :timeout and :open_timeout are supported

# File lib/contextio/api/abstract_api.rb, line 46
def initialize(key, secret, opts={})
        @key = key
        @secret = secret
        @opts = opts || {}
        @base_url = self.class.base_url
        @version = self.class.version
end
user_agent_string() click to toggle source
# File lib/contextio/api/abstract_api.rb, line 25
def self.user_agent_string
        raise NotDefinedError, 'user_agent_string undefined in your API subclassed model.'
end
version() click to toggle source

@return [String] The version of the Context.IO API this version of the

gem is intended for use with.
# File lib/contextio/api/abstract_api.rb, line 15
def self.version
        raise NotDefinedError, 'VERSION is not defined in your API subclassed model.' if self::VERSION.nil?
        self::VERSION
end

Protected Class Methods

hash_to_url_params(params = {}) click to toggle source

Context.IO’s API expects query parameters that are arrays to be comma separated, rather than submitted more than once. This munges those arrays and then URL-encodes the whole thing into a query string.

@param [{String, Symbol => String, Symbol, Array<String, Symbol>}] params

A Hash of the query parameters.

@return [String] A URL-encoded version of the query parameters.

# File lib/contextio/api/abstract_api.rb, line 136
def self.hash_to_url_params(params = {})
        return '' if params.empty?

        params = params.inject({}) do |memo, (k, v)|
                memo[k] = Array(v).join(',')

                memo
        end

        "?#{URI.encode_www_form(params)}"
end

Public Instance Methods

path(resource_path, params = {}) click to toggle source

Generates the path for a resource_path and params hash for use with the API.

@param [String] resource_path The resource_path or full resource URL for

the resource being acted on.

@param [{String, Symbol => String, Symbol, Array<String, Symbol>}] params

A Hash of the query parameters for the action represented by this path.
# File lib/contextio/api/abstract_api.rb, line 60
def path(resource_path, params = {})
        "/#{version}/#{strip_resource_path(resource_path)}#{self.class.hash_to_url_params(params)}"
end
raw_request(method, resource_path, params={}) click to toggle source
# File lib/contextio/api/abstract_api.rb, line 81
def raw_request(method, resource_path, params={})
        response = oauth_request(method, resource_path, params)

        with_error_handling(response) do |response|
                response.body
        end
end
request(method, resource_path, params = {}) click to toggle source

Makes a request against the Context.IO API.

@param [String, Symbol] method The HTTP verb for the request (lower case). @param [String] resource_path The path to the resource in question. @param [{String, Symbol => String, Symbol, Array<String, Symbol>}] params

A Hash of the query parameters for the action represented by this
request.

@raise [API::Error] if the response code isn’t in the 200 or 300 range.

# File lib/contextio/api/abstract_api.rb, line 73
def request(method, resource_path, params = {})
        response = oauth_request(method, resource_path, params, { 'Accept' => 'application/json' })

        with_error_handling(response) do |response|
                parse_json(response.body)
        end
end
user_agent_string() click to toggle source
# File lib/contextio/api/abstract_api.rb, line 29
def user_agent_string
        self.class.user_agent_string
end

Protected Instance Methods

connection() click to toggle source

@!attribute [r] connection @return [Faraday::Connection] A handle on the Faraday connection object.

# File lib/contextio/api/abstract_api.rb, line 150
def connection
        @connection ||= Faraday::Connection.new(base_url) do |faraday|
                faraday.headers['User-Agent'] = user_agent_string

                faraday.request :oauth, consumer_key: key, consumer_secret: secret
                faraday.request :url_encoded

                faraday.adapter Faraday.default_adapter
        end
end
determine_best_error_message(parsed_body) click to toggle source

Given a parsed JSON body from an error response, figures out if it can pull useful information therefrom.

@param [Hash] parsed_body A Hash parsed from a JSON document that may

describe an error condition.

@return [String, Nil] If it can, it will return a human-readable

error-describing String. Otherwise, nil.
# File lib/contextio/api/abstract_api.rb, line 199
def determine_best_error_message(parsed_body)
        return unless parsed_body.respond_to?(:[])

        if parsed_body['type'] == 'error'
                return parsed_body['value']
        elsif parsed_body.has_key?('success') && !parsed_body['success']
                return [parsed_body['feedback_code'], parsed_body['connectionLog']].compact.join("\n")
        end
end
oauth_request(method, resource_path, params, headers=nil) click to toggle source

Makes a request signed for OAuth, encoding parameters correctly, etc.

@param [String, Symbol] method The HTTP verb for the request (lower case). @param [String] resource_path The path to the resource in question. @param [{String, Symbol => String, Symbol, Array<String, Symbol>}] params

A Hash of the query parameters for the action represented by this
request.

@param [{String, Symbol => String, Symbol, Array<String, Symbol>}] headers

A Hash of headers to be merged with the default headers for making
requests.

@return [Faraday::Response] The response object from the request.

# File lib/contextio/api/abstract_api.rb, line 103
def oauth_request(method, resource_path, params, headers=nil)
        normalized_params = params.inject({}) do |normalized_params, (key, value)|
                value = (value ? 1 : 0) if value == !!value
                normalized_params[key.to_sym] = value
                normalized_params
        end

        connection.send(method, path(resource_path), normalized_params, headers) do |request|
                if request.method == :put
                        request.params = normalized_params
                        request.body   = {}
                end
        end
end
parse_json(document) click to toggle source

Parses JSON if there’s valid JSON passed in.

@param [String] document A string you suspect may be a JSON document.

@return [Hash, Array, Nil] Either a parsed version of the JSON document or

nil, if the document wasn't valid JSON.
# File lib/contextio/api/abstract_api.rb, line 184
def parse_json(document)
        return JSON.parse(document.to_s)
rescue JSON::ParserError => e
        return nil
end
strip_resource_path(resource_path) click to toggle source

So that we can accept full URLs, this strips the domain and version number out and returns just the resource path.

@param [#to_s] resource_path The full URL or path for a resource.

@return [String] The resource path.

# File lib/contextio/api/abstract_api.rb, line 124
def strip_resource_path(resource_path)
        resource_path.to_s.gsub("#{base_url}/#{version}/", '')
end
with_error_handling(response, &block) click to toggle source

Errors can come in a few shapes and we want to detect them and extract the useful information. If no errors are found, it calls the provided block and passes the response through.

@param [Faraday::Response] response A response object from making a request to the

API with Faraday.

@raise [API::Error] if the response code isn’t in the 200 or 300 range.

# File lib/contextio/api/abstract_api.rb, line 169
def with_error_handling(response, &block)
        return block.call(response) if response.success?

        parsed_body = parse_json(response.body)
        message = determine_best_error_message(parsed_body) || "HTTP #{response.status} Error"

        raise ContextIO::API::Error, message
end