module Mapbox

Constants

LATITUDE_KEY
LONGITUDE_KEY

Attributes

access_token[RW]
api_base[RW]
request_open_timeout[RW]
request_opts[RW]
request_timeout[RW]

Public Class Methods

api_error(error, rcode, rbody, error_obj) click to toggle source
# File lib/mapbox.rb, line 134
def self.api_error(error, rcode, rbody, error_obj)
  StandardError.new(error[:message], rcode, rbody, error_obj)
end
authentication_error(error, rcode, rbody, error_obj) click to toggle source
# File lib/mapbox.rb, line 130
def self.authentication_error(error, rcode, rbody, error_obj)
  AuthenticationError.new(error[:message], rcode, rbody, error_obj)
end
execute_request(opts) click to toggle source
# File lib/mapbox.rb, line 84
def self.execute_request(opts)
  RestClient::Request.execute(opts)
end
general_api_error(rcode, rbody) click to toggle source
# File lib/mapbox.rb, line 100
def self.general_api_error(rcode, rbody)
  StandardError.new("Invalid response object from API: #{rbody.inspect} " +
               "(HTTP response code was #{rcode})")
end
handle_api_error(rcode, rbody) click to toggle source
# File lib/mapbox.rb, line 105
def self.handle_api_error(rcode, rbody)
  begin
    error_obj = JSON.parse(rbody)
    error = error_obj[:error] or raise StandardError.new # escape from parsing

  rescue JSON::ParserError, StandardError
    raise general_api_error(rcode, rbody)
  end

  case rcode
  when 400, 404
    raise invalid_request_error error, rcode, rbody, error_obj
  when 401
    raise authentication_error error, rcode, rbody, error_obj
  else
    raise api_error error, rcode, rbody, error_obj
  end

end
handle_restclient_error(e, api_base_url=nil) click to toggle source
# File lib/mapbox.rb, line 138
def self.handle_restclient_error(e, api_base_url=nil)
  api_base_url = @api_base unless api_base_url
  connection_message = "Please check your internet connection and try again. " \
      "If this problem persists, you should check Mapbox's service status at " \
      "https://status.mapbox.com/, or let us know at help@mapbox.com."

  case e
  when RestClient::RequestTimeout
    message = "Could not connect to Mapbox (#{api_base_url}). #{connection_message}"

  when RestClient::ServerBrokeConnection
    message = "The connection to the server (#{api_base_url}) broke before the " \
      "request completed. #{connection_message}"

  when RestClient::SSLCertificateNotVerified
    message = "Could not verify Mapbox's SSL certificate. " \
      "Please make sure that your network is not intercepting certificates. " \
      "(Try going to https://api.mapbox.com/ in your browser.) " \
      "If this problem persists, let us know at help@mapbox.com."

  when SocketError
    message = "Unexpected error communicating when trying to connect to Mapbox. " \
      "You may be seeing this message because your DNS is not working. " \
      "To check, try running 'host mapbox.com' from the command line."

  else
    message = "Unexpected error communicating with Mapbox. " \
      "If this problem persists, let us know at help@mapbox.com."

  end

  raise StandardError.new(message + "\n\n(Network error: #{e.message})")
end
invalid_request_error(error, rcode, rbody, error_obj) click to toggle source
# File lib/mapbox.rb, line 125
def self.invalid_request_error(error, rcode, rbody, error_obj)
  StandardError.new(error[:message], error[:param], rcode,
    rbody, error_obj)
end
parse(response) click to toggle source
# File lib/mapbox.rb, line 88
def self.parse(response)
  begin
    # Would use :symbolize_names => true, but apparently there is
    # some library out there that makes symbolize_names not work.
    response = JSON.parse(response.body)
  rescue JSON::ParserError
    raise general_api_error(response.code, response.body)
  end

  response
end
request(method, url, api_key, params={}, headers={}, api_base_url=nil) click to toggle source
# File lib/mapbox.rb, line 17
def self.request(method, url, api_key, params={}, headers={}, api_base_url=nil)
  api_base_url = api_base_url || @api_base
  params = params || {}

  unless access_token ||= @access_token
    raise AuthenticationError.new('No API key provided. ' \
      'Set your API key using "Mapbox.access_token = <access_token>". ' \
      'You can generate API keys from the Mapbox web interface. ' \
      'See https://mapbox.com/developers for details, or email help@mapbox.com ' \
      'if you have any questions.')
  end

  url = api_base_url + url

  params['access_token'] = access_token

  case method.to_s.downcase.to_sym
  when :get, :head, :delete
    # Make params into GET parameters
    url += "#{URI.parse(url).query ? '&' : '?'}#{URI.encode_www_form(params)}" if params && params.any?
    payload = nil
  end

  @request_opts = {:verify_ssl => OpenSSL::SSL::VERIFY_PEER,
                    :ssl_ca_file => @ssl_bundle_path}

  @request_opts.update(
    :method => method,
    :open_timeout => @request_open_timeout || 30,
    :payload => payload,
    :url => url,
    :timeout => @request_timeout || 80)

  begin
    response = execute_request(@request_opts)
  rescue SocketError => e
    handle_restclient_error(e, api_base_url)
  rescue NoMethodError => e
    # Work around RestClient bug
    if e.message =~ /\WRequestFailed\W/
      e = StandardError.new('Unexpected HTTP response code')
      handle_restclient_error(e, api_base_url)
    else
      raise
    end
  rescue RestClient::ExceptionWithResponse => e
    if e.response
      handle_api_error(e, e.response)
    else
      handle_restclient_error(e, api_base_url)
    end
  rescue RestClient::Exception, Errno::ECONNREFUSED => e
    handle_restclient_error(e, api_base_url)
  end

  [parse(response), api_key]
end
uri_encode(params) click to toggle source
# File lib/mapbox.rb, line 75
def self.uri_encode(params)
  params.
    map { |k,v| "#{k}=#{url_encode(v)}" }.join('&')
end
url_encode(key) click to toggle source
# File lib/mapbox.rb, line 80
def self.url_encode(key)
  URI.encode_www_form_component(key.to_s)
end