lib/geocoder/lookups/base.rb in geocoder-1.1.5 vs lib/geocoder/lookups/base.rb in geocoder-1.1.6
- old
+ new
@@ -15,10 +15,25 @@
module Lookup
class Base
##
+ # Human-readable name of the geocoding API.
+ #
+ def name
+ fail
+ end
+
+ ##
+ # Symbol which is used in configuration to refer to this Lookup.
+ #
+ def handle
+ str = self.class.to_s
+ str[str.rindex(':')+1..-1].gsub(/([a-z\d]+)([A-Z])/,'\1_\2').downcase.to_sym
+ end
+
+ ##
# Query the geocoding API and return a Geocoder::Result object.
# Returns +nil+ on timeout or error.
#
# Takes a search string (eg: "Mississippi Coast Coliseumf, Biloxi, MS",
# "205.128.54.202") for geocoding, or coordinates (latitude, longitude)
@@ -41,20 +56,41 @@
#
def map_link_url(coordinates)
nil
end
+ ##
+ # Array containing string descriptions of keys required by the API.
+ # Empty array if keys are optional or not required.
+ #
+ def required_api_key_parts
+ []
+ end
+ ##
+ # URL to use for querying the geocoding engine.
+ #
+ def query_url(query)
+ fail
+ end
+
private # -------------------------------------------------------------
##
+ # An object with configuration data for this particular lookup.
+ #
+ def configuration
+ Geocoder.config_for_lookup(handle)
+ end
+
+ ##
# Object used to make HTTP requests.
#
def http_client
- protocol = "http#{'s' if Geocoder::Configuration.use_https}"
+ protocol = "http#{'s' if configuration.use_https}"
proxy_name = "#{protocol}_proxy"
- if proxy = Geocoder::Configuration.send(proxy_name)
+ if proxy = configuration.send(proxy_name)
proxy_url = protocol + '://' + proxy
begin
uri = URI.parse(proxy_url)
rescue URI::InvalidURIError
raise ConfigurationError,
@@ -82,17 +118,10 @@
query_url_params(query).reject{ |key,value| value.nil? }
)
end
##
- # URL to use for querying the geocoding engine.
- #
- def query_url(query)
- fail
- end
-
- ##
# Key to use for caching a geocoding result. Usually this will be the
# request URL, but in cases where OAuth is used and the nonce,
# timestamp, etc varies from one request to another, we need to use
# something else (like the URL before OAuth encoding).
#
@@ -110,11 +139,11 @@
##
# Raise exception if configuration specifies it should be raised.
# Return false if exception not raised.
#
def raise_error(error, message = nil)
- exceptions = Geocoder::Configuration.always_raise
+ exceptions = configuration.always_raise
if exceptions == :all or exceptions.include?( error.is_a?(Class) ? error : error.class )
raise error, message
else
false
end
@@ -127,11 +156,11 @@
parse_raw_data fetch_raw_data(query)
rescue SocketError => err
raise_error(err) or warn "Geocoding API connection cannot be established."
rescue TimeoutError => err
raise_error(err) or warn "Geocoding API not responding fast enough " +
- "(see Geocoder::Configuration.timeout to set limit)."
+ "(use Geocoder.configure(:timeout => ...) to set limit)."
end
##
# Parses a raw search result (returns hash or array).
#
@@ -148,11 +177,11 @@
##
# Protocol to use for communication with geocoding services.
# Set in configuration but not available for every service.
#
def protocol
- "http" + (Geocoder::Configuration.use_https ? "s" : "")
+ "http" + (configuration.use_https ? "s" : "")
end
##
# Fetch a raw geocoding result (JSON string).
# The result might or might not be cached.
@@ -160,10 +189,11 @@
def fetch_raw_data(query)
key = cache_key(query)
if cache and body = cache[key]
@cache_hit = true
else
+ check_api_key_configuration!(query)
response = make_api_request(query)
body = response.body
if cache and (200..399).include?(response.code.to_i)
cache[key] = body
end
@@ -175,22 +205,35 @@
##
# Make an HTTP(S) request to a geocoding API and
# return the response object.
#
def make_api_request(query)
- timeout(Geocoder::Configuration.timeout) do
+ timeout(configuration.timeout) do
uri = URI.parse(query_url(query))
client = http_client.new(uri.host, uri.port)
- client.use_ssl = true if Geocoder::Configuration.use_https
- client.get(uri.request_uri, Geocoder::Configuration.http_headers)
+ client.use_ssl = true if configuration.use_https
+ client.get(uri.request_uri, configuration.http_headers)
end
end
+ def check_api_key_configuration!(query)
+ key_parts = query.lookup.required_api_key_parts
+ if key_parts.size > Array(configuration.api_key).size
+ parts_string = key_parts.size == 1 ? key_parts.first : key_parts
+ raise Geocoder::ConfigurationError,
+ "The #{query.lookup.name} API requires a key to be configured: " +
+ parts_string.inspect
+ end
+ end
+
##
# The working Cache object.
#
def cache
- Geocoder.cache
+ if @cache.nil? and store = configuration.cache
+ @cache = Cache.new(store, configuration.cache_prefix)
+ end
+ @cache
end
##
# Simulate ActiveSupport's Object#to_query.
# Removes any keys with nil value.