require 'excon' require 'json' require 'strutta-api/api_object.rb' require 'strutta-api/entries.rb' require 'strutta-api/errors.rb' require 'strutta-api/flow.rb' require 'strutta-api/games.rb' require 'strutta-api/participants.rb' require 'strutta-api/points.rb' require 'strutta-api/moderation.rb' require 'strutta-api/judging.rb' require 'strutta-api/rounds.rb' require 'strutta-api/version.rb' module Strutta # Strutta API engine # Handles API requests and errors class API include Strutta::Version attr_accessor :host, :path, :token, :debug, :session # Initializes the Strutta API wrapper # # @param token [String] your Strutta API token # @param host [String] Strutta API host URL - used to switched between prod/staging # @param path [String] Strutta API host path - used to switched between versions # @return [Strutta::API] instantiated Strutta API object def initialize(token, host = 'http://strutta-api.herokuapp.com/', path = Version::VERSION_PATH) fail Error, 'You must provide a Strutta API key' unless token @host = host @path = path @token = token @session = Excon.new @host @debug = debug end # Makes an API call # # @param method [String] the required HTTP method # @param url [String] URL for the call # @param params [Hash] Parameters for the call # @return [Hash] Parsed body of the response def call(method, url, params = {}) params = JSON.generate(params) r = @session.send(method, path: "#{@path}#{url}", headers: api_headers, body: params) # Delete calls have no JSON return return true if r.status == 204 # Raise exceptions on error response codes cast_error(r.status, r.body) if r.status >= 400 JSON.parse(r.body) end # Instantiates a Strutta::Games object # # @param id [Integer, nil] the ID of the Strutta game # @return [Strutta::Games] The instantiated Strutta::Games object def games(id = nil) Games.new id, self end private # Utility: build the Headers hash # @return [Hash] Headers for an API call def api_headers { 'Content-Type' => 'application/json', 'Authorization' => "Token token=#{@token}" } end # Throws exceptions based on HTTP responses # # @param status [Integer] the HTTP response status # @param body [JSON] the HTTP response body # @return [Error] An appropriate exception def cast_error(status, body) error_info = JSON.parse(body) msg = error_info['error'] && error_info['message'] ? "#{error_info['error']} - #{error_info['message']}" : "We received an unexpected error: #{body}" fail error_map(status), msg rescue JSON::ParserError raise Errors::Error, "We received an unexpected error: #{body}" end # Map errors to HTTP statuses # # @param status [Integer] the HTTP response status # @return [Error] The associated exception def error_map(status) case status when 401 Errors::Unauthorized when 400 Errors::BadRequestError when 404 Errors::ObjectNotFoundError when 422 Errors::UnprocessableEntityError else Errors::Error end end end end