geocoder 1.1.5 → 1.1.6
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of geocoder might be problematic. Click here for more details.
- data/.travis.yml +4 -0
- data/{CHANGELOG.rdoc → CHANGELOG.md} +90 -37
- data/README.md +96 -45
- data/examples/autoexpire_cache.rb +1 -3
- data/lib/generators/geocoder/config/templates/initializer.rb +18 -22
- data/lib/geocoder.rb +2 -4
- data/lib/geocoder/cache.rb +2 -1
- data/lib/geocoder/calculations.rb +12 -12
- data/lib/geocoder/cli.rb +10 -11
- data/lib/geocoder/configuration.rb +67 -43
- data/lib/geocoder/configuration_hash.rb +11 -0
- data/lib/geocoder/exceptions.rb +3 -0
- data/lib/geocoder/lookup.rb +1 -1
- data/lib/geocoder/lookups/base.rb +59 -16
- data/lib/geocoder/lookups/bing.rb +21 -11
- data/lib/geocoder/lookups/freegeoip.rb +8 -4
- data/lib/geocoder/lookups/geocoder_ca.rb +11 -7
- data/lib/geocoder/lookups/google.rb +18 -9
- data/lib/geocoder/lookups/google_premier.rb +16 -8
- data/lib/geocoder/lookups/mapquest.rb +12 -5
- data/lib/geocoder/lookups/maxmind.rb +72 -0
- data/lib/geocoder/lookups/nominatim.rb +13 -8
- data/lib/geocoder/lookups/test.rb +4 -0
- data/lib/geocoder/lookups/yahoo.rb +38 -11
- data/lib/geocoder/lookups/yandex.rb +17 -9
- data/lib/geocoder/query.rb +17 -8
- data/lib/geocoder/request.rb +7 -1
- data/lib/geocoder/results/google.rb +6 -0
- data/lib/geocoder/results/maxmind.rb +136 -0
- data/lib/geocoder/results/nominatim.rb +0 -10
- data/lib/geocoder/sql.rb +6 -4
- data/lib/geocoder/stores/active_record.rb +5 -5
- data/lib/geocoder/stores/base.rb +3 -2
- data/lib/geocoder/version.rb +1 -1
- data/lib/hash_recursive_merge.rb +74 -0
- data/lib/oauth_util.rb +8 -2
- data/test/cache_test.rb +2 -2
- data/test/calculations_test.rb +4 -4
- data/test/configuration_test.rb +26 -51
- data/test/error_handling_test.rb +4 -4
- data/test/fixtures/bing_invalid_key +1 -0
- data/test/fixtures/{bing_madison_square_garden.json → bing_madison_square_garden} +0 -0
- data/test/fixtures/{bing_no_results.json → bing_no_results} +0 -0
- data/test/fixtures/{bing_reverse.json → bing_reverse} +0 -0
- data/test/fixtures/{freegeoip_74_200_247_59.json → freegeoip_74_200_247_59} +0 -0
- data/test/fixtures/{freegeoip_no_results.json → freegeoip_no_results} +0 -0
- data/test/fixtures/{geocoder_ca_madison_square_garden.json → geocoder_ca_madison_square_garden} +0 -0
- data/test/fixtures/{geocoder_ca_no_results.json → geocoder_ca_no_results} +0 -0
- data/test/fixtures/{geocoder_ca_reverse.json → geocoder_ca_reverse} +0 -0
- data/test/fixtures/{google_garbage.json → google_garbage} +0 -0
- data/test/fixtures/{google_madison_square_garden.json → google_madison_square_garden} +0 -0
- data/test/fixtures/{google_no_city_data.json → google_no_city_data} +0 -0
- data/test/fixtures/{google_no_locality.json → google_no_locality} +0 -0
- data/test/fixtures/{google_no_results.json → google_no_results} +0 -0
- data/test/fixtures/{mapquest_madison_square_garden.json → mapquest_madison_square_garden} +0 -0
- data/test/fixtures/{mapquest_no_results.json → mapquest_no_results} +0 -0
- data/test/fixtures/maxmind_24_24_24_21 +1 -0
- data/test/fixtures/maxmind_24_24_24_22 +1 -0
- data/test/fixtures/maxmind_24_24_24_23 +1 -0
- data/test/fixtures/maxmind_24_24_24_24 +1 -0
- data/test/fixtures/maxmind_74_200_247_59 +1 -0
- data/test/fixtures/maxmind_invalid_key +1 -0
- data/test/fixtures/maxmind_no_results +1 -0
- data/test/fixtures/{nominatim_madison_square_garden.json → nominatim_madison_square_garden} +0 -0
- data/test/fixtures/{nominatim_no_results.json → nominatim_no_results} +0 -0
- data/test/fixtures/{yahoo_error.json → yahoo_error} +0 -0
- data/test/fixtures/yahoo_invalid_key +2 -0
- data/test/fixtures/{yahoo_madison_square_garden.json → yahoo_madison_square_garden} +0 -0
- data/test/fixtures/{yahoo_no_results.json → yahoo_no_results} +0 -0
- data/test/fixtures/yahoo_over_limit +2 -0
- data/test/fixtures/{yandex_invalid_key.json → yandex_invalid_key} +0 -0
- data/test/fixtures/{yandex_kremlin.json → yandex_kremlin} +0 -0
- data/test/fixtures/{yandex_no_results.json → yandex_no_results} +0 -0
- data/test/https_test.rb +3 -3
- data/test/integration/smoke_test.rb +2 -2
- data/test/lookup_test.rb +82 -5
- data/test/oauth_util_test.rb +30 -0
- data/test/proxy_test.rb +2 -2
- data/test/query_test.rb +3 -0
- data/test/result_test.rb +2 -2
- data/test/services_test.rb +121 -44
- data/test/test_helper.rb +44 -109
- data/test/test_mode_test.rb +3 -3
- metadata +42 -33
@@ -1,25 +1,21 @@
|
|
1
|
-
Geocoder.configure
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
Geocoder.configure(
|
2
|
+
# geocoding options
|
3
|
+
# :timeout => 3, # geocoding service timeout (secs)
|
4
|
+
# :lookup => :google, # name of geocoding service (symbol)
|
5
|
+
# :language => :en, # ISO-639 language code
|
6
|
+
# :use_https => false, # use HTTPS for lookup requests? (if supported)
|
7
|
+
# :http_proxy => nil, # HTTP proxy server (user:pass@host:port)
|
8
|
+
# :https_proxy => nil, # HTTPS proxy server (user:pass@host:port)
|
9
|
+
# :api_key => nil, # API key for geocoding service
|
10
|
+
# :cache => nil, # cache object (must respond to #[], #[]=, and #keys)
|
11
|
+
# :cache_prefix => "geocoder:", # prefix (string) to use for all cache keys
|
5
12
|
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
# config.http_proxy = nil # HTTP proxy server (user:pass@host:port)
|
11
|
-
# config.https_proxy = nil # HTTPS proxy server (user:pass@host:port)
|
12
|
-
# config.api_key = nil # API key for geocoding service
|
13
|
-
# config.cache = nil # cache object (must respond to #[], #[]=, and #keys)
|
14
|
-
# config.cache_prefix = "geocoder:" # prefix (string) to use for all cache keys
|
13
|
+
# exceptions that should not be rescued by default
|
14
|
+
# (if you want to implement custom error handling);
|
15
|
+
# supports SocketError and TimeoutError
|
16
|
+
# :always_raise => [],
|
15
17
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
# config.always_raise = []
|
20
|
-
|
21
|
-
## Calculation options
|
22
|
-
# config.units = :mi # :km for kilometers or :mi for miles
|
23
|
-
# config.distances = :linear # :spherical or :linear
|
18
|
+
# calculation options
|
19
|
+
# :units => :mi, # :km for kilometers or :mi for miles
|
20
|
+
# :distances => :linear # :spherical or :linear
|
24
21
|
end
|
25
|
-
|
data/lib/geocoder.rb
CHANGED
@@ -43,10 +43,8 @@ module Geocoder
|
|
43
43
|
# The working Cache object, or +nil+ if none configured.
|
44
44
|
#
|
45
45
|
def cache
|
46
|
-
|
47
|
-
|
48
|
-
end
|
49
|
-
@cache
|
46
|
+
warn "WARNING: Calling Geocoder.cache is DEPRECATED. The #cache method now belongs to the Geocoder::Lookup object."
|
47
|
+
Geocoder::Lookup.get(Geocoder.config.lookup).send(:configuration).cache
|
50
48
|
end
|
51
49
|
end
|
52
50
|
|
data/lib/geocoder/cache.rb
CHANGED
@@ -40,7 +40,7 @@ module Geocoder
|
|
40
40
|
# Distance spanned by one degree of latitude in the given units.
|
41
41
|
#
|
42
42
|
def latitude_degree_distance(units = nil)
|
43
|
-
units ||= Geocoder
|
43
|
+
units ||= Geocoder.config.units
|
44
44
|
2 * Math::PI * earth_radius(units) / 360
|
45
45
|
end
|
46
46
|
|
@@ -49,7 +49,7 @@ module Geocoder
|
|
49
49
|
# This ranges from around 69 miles at the equator to zero at the poles.
|
50
50
|
#
|
51
51
|
def longitude_degree_distance(latitude, units = nil)
|
52
|
-
units ||= Geocoder
|
52
|
+
units ||= Geocoder.config.units
|
53
53
|
latitude_degree_distance(units) * Math.cos(to_radians(latitude))
|
54
54
|
end
|
55
55
|
|
@@ -67,12 +67,12 @@ module Geocoder
|
|
67
67
|
# The options hash supports:
|
68
68
|
#
|
69
69
|
# * <tt>:units</tt> - <tt>:mi</tt> or <tt>:km</tt>
|
70
|
-
#
|
70
|
+
# Use Geocoder.configure(:units => ...) to configure default units.
|
71
71
|
#
|
72
72
|
def distance_between(point1, point2, options = {})
|
73
73
|
|
74
74
|
# set default options
|
75
|
-
options[:units] ||= Geocoder
|
75
|
+
options[:units] ||= Geocoder.config.units
|
76
76
|
|
77
77
|
# convert to coordinate arrays
|
78
78
|
point1 = extract_coordinates(point1)
|
@@ -103,14 +103,14 @@ module Geocoder
|
|
103
103
|
# the spherical method is "correct" in that it returns the shortest path
|
104
104
|
# (one along a great circle) but the linear method is less confusing
|
105
105
|
# (returns due east or west when given two points with the same latitude).
|
106
|
-
#
|
106
|
+
# Use Geocoder.configure(:distances => ...) to configure calculation method.
|
107
107
|
#
|
108
108
|
# Based on: http://www.movable-type.co.uk/scripts/latlong.html
|
109
109
|
#
|
110
110
|
def bearing_between(point1, point2, options = {})
|
111
111
|
|
112
112
|
# set default options
|
113
|
-
options[:method] ||= Geocoder
|
113
|
+
options[:method] ||= Geocoder.config.distances
|
114
114
|
options[:method] = :linear unless options[:method] == :spherical
|
115
115
|
|
116
116
|
# convert to coordinate arrays
|
@@ -197,12 +197,12 @@ module Geocoder
|
|
197
197
|
# ways of specifying the point. Also accepts an options hash:
|
198
198
|
#
|
199
199
|
# * <tt>:units</tt> - <tt>:mi</tt> or <tt>:km</tt>.
|
200
|
-
#
|
200
|
+
# Use Geocoder.configure(:units => ...) to configure default units.
|
201
201
|
#
|
202
202
|
def bounding_box(point, radius, options = {})
|
203
203
|
lat,lon = extract_coordinates(point)
|
204
204
|
radius = radius.to_f
|
205
|
-
units = options[:units] || Geocoder
|
205
|
+
units = options[:units] || Geocoder.config.units
|
206
206
|
[
|
207
207
|
lat - (radius / latitude_degree_distance(units)),
|
208
208
|
lon - (radius / longitude_degree_distance(lat, units)),
|
@@ -240,12 +240,12 @@ module Geocoder
|
|
240
240
|
end
|
241
241
|
|
242
242
|
def distance_to_radians(distance, units = nil)
|
243
|
-
units ||= Geocoder
|
243
|
+
units ||= Geocoder.config.units
|
244
244
|
distance.to_f / earth_radius(units)
|
245
245
|
end
|
246
246
|
|
247
247
|
def radians_to_distance(radians, units = nil)
|
248
|
-
units ||= Geocoder
|
248
|
+
units ||= Geocoder.config.units
|
249
249
|
radians * earth_radius(units)
|
250
250
|
end
|
251
251
|
|
@@ -265,10 +265,10 @@ module Geocoder
|
|
265
265
|
|
266
266
|
##
|
267
267
|
# Radius of the Earth in the given units (:mi or :km).
|
268
|
-
#
|
268
|
+
# Use Geocoder.configure(:units => ...) to configure default units.
|
269
269
|
#
|
270
270
|
def earth_radius(units = nil)
|
271
|
-
units ||= Geocoder
|
271
|
+
units ||= Geocoder.config.units
|
272
272
|
units == :km ? EARTH_RADIUS : to_miles(EARTH_RADIUS)
|
273
273
|
end
|
274
274
|
|
data/lib/geocoder/cli.rb
CHANGED
@@ -13,34 +13,33 @@ module Geocoder
|
|
13
13
|
opts.separator "\nOptions: "
|
14
14
|
|
15
15
|
opts.on("-k <key>", "--key <key>",
|
16
|
-
"Key for geocoding API (optional
|
17
|
-
|
18
|
-
|
19
|
-
Geocoder::Configuration.api_key = premier_key
|
16
|
+
"Key for geocoding API (usually optional). Enclose multi-part keys in quotes and separate parts by spaces") do |key|
|
17
|
+
if (key_parts = key.split(/\s+/)).size > 1
|
18
|
+
Geocoder.configure(:api_key => key_parts)
|
20
19
|
else
|
21
|
-
Geocoder
|
20
|
+
Geocoder.configure(:api_key => key)
|
22
21
|
end
|
23
22
|
end
|
24
23
|
|
25
24
|
opts.on("-l <language>", "--language <language>",
|
26
25
|
"Language of output (see API docs for valid choices)") do |language|
|
27
|
-
Geocoder
|
26
|
+
Geocoder.configure(:language => language)
|
28
27
|
end
|
29
28
|
|
30
29
|
opts.on("-p <proxy>", "--proxy <proxy>",
|
31
30
|
"HTTP proxy server to use (user:pass@host:port)") do |proxy|
|
32
|
-
Geocoder
|
31
|
+
Geocoder.configure(:http_proxy => proxy)
|
33
32
|
end
|
34
33
|
|
35
34
|
opts.on("-s <service>", Geocoder::Lookup.all_services_except_test, "--service <service>",
|
36
35
|
"Geocoding service: #{Geocoder::Lookup.all_services_except_test * ', '}") do |service|
|
37
|
-
Geocoder
|
38
|
-
Geocoder
|
36
|
+
Geocoder.configure(:lookup => service.to_sym)
|
37
|
+
Geocoder.configure(:ip_lookup => service.to_sym)
|
39
38
|
end
|
40
39
|
|
41
40
|
opts.on("-t <seconds>", "--timeout <seconds>",
|
42
41
|
"Maximum number of seconds to wait for API response") do |timeout|
|
43
|
-
Geocoder
|
42
|
+
Geocoder.configure(:timeout => timeout.to_i)
|
44
43
|
end
|
45
44
|
|
46
45
|
opts.on("-j", "--json", "Print API's raw JSON response") do
|
@@ -80,7 +79,7 @@ module Geocoder
|
|
80
79
|
|
81
80
|
if show_url
|
82
81
|
q = Geocoder::Query.new(query)
|
83
|
-
out << q.
|
82
|
+
out << q.url + "\n"
|
84
83
|
exit 0
|
85
84
|
end
|
86
85
|
|
@@ -1,39 +1,49 @@
|
|
1
1
|
require 'singleton'
|
2
|
+
require 'geocoder/configuration_hash'
|
2
3
|
|
3
4
|
module Geocoder
|
4
5
|
|
5
6
|
##
|
6
|
-
#
|
7
|
+
# Configuration options should be set by passing a hash:
|
7
8
|
#
|
8
|
-
|
9
|
+
# Geocoder.configure(
|
10
|
+
# :timeout => 5,
|
11
|
+
# :lookup => :yandex,
|
12
|
+
# :api_key => "2a9fsa983jaslfj982fjasd",
|
13
|
+
# :units => :km
|
14
|
+
# )
|
15
|
+
#
|
16
|
+
def self.configure(options = nil, &block)
|
9
17
|
if block_given?
|
18
|
+
warn "WARNING: Passing a block to Geocoder.configure is DEPRECATED. Please pass a hash instead (eg: Geocoder.configure(:units => ..., :api_key => ...))."
|
10
19
|
block.call(Configuration.instance)
|
20
|
+
elsif !options.nil?
|
21
|
+
Configuration.instance.configure(options)
|
11
22
|
else
|
23
|
+
warn "WARNING: Use of Geocoder.configure to read or write single config options is DEPRECATED. To write to the config please pass a hash (eg: Geocoder.configure(:units => ...)). To read config options please use the Geocoder.config object (eg: Geocoder.config.units)."
|
12
24
|
Configuration.instance
|
13
25
|
end
|
14
26
|
end
|
15
27
|
|
16
28
|
##
|
17
|
-
#
|
18
|
-
# (geocoding service provider, caching, units of measurement, etc).
|
19
|
-
# Configuration can be done in two ways:
|
20
|
-
#
|
21
|
-
# 1) Using Geocoder.configure and passing a block
|
22
|
-
# (useful for configuring multiple things at once):
|
23
|
-
#
|
24
|
-
# Geocoder.configure do |config|
|
25
|
-
# config.timeout = 5
|
26
|
-
# config.lookup = :yandex
|
27
|
-
# config.api_key = "2a9fsa983jaslfj982fjasd"
|
28
|
-
# config.units = :km
|
29
|
-
# end
|
29
|
+
# Read-only access to the singleton's config data.
|
30
30
|
#
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
31
|
+
def self.config
|
32
|
+
Configuration.instance.data
|
33
|
+
end
|
34
|
+
|
35
|
+
##
|
36
|
+
# Read-only access to lookup-specific config data.
|
36
37
|
#
|
38
|
+
def self.config_for_lookup(lookup_name)
|
39
|
+
data = config.clone
|
40
|
+
data.reject!{ |key,value| !Configuration::OPTIONS.include?(key) }
|
41
|
+
if config.has_key?(lookup_name)
|
42
|
+
data.merge!(config[lookup_name])
|
43
|
+
end
|
44
|
+
data
|
45
|
+
end
|
46
|
+
|
37
47
|
class Configuration
|
38
48
|
include Singleton
|
39
49
|
|
@@ -54,53 +64,67 @@ module Geocoder
|
|
54
64
|
:distances
|
55
65
|
]
|
56
66
|
|
57
|
-
attr_accessor
|
67
|
+
attr_accessor :data
|
68
|
+
|
69
|
+
def self.set_defaults
|
70
|
+
instance.set_defaults
|
71
|
+
end
|
72
|
+
|
73
|
+
OPTIONS.each do |o|
|
74
|
+
define_method o do
|
75
|
+
@data[o]
|
76
|
+
end
|
77
|
+
define_method "#{o}=" do |value|
|
78
|
+
@data[o] = value
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def configure(options)
|
83
|
+
@data.rmerge!(options)
|
84
|
+
end
|
58
85
|
|
59
86
|
def initialize # :nodoc
|
87
|
+
@data = Geocoder::ConfigurationHash.new
|
60
88
|
set_defaults
|
61
89
|
end
|
62
90
|
|
63
91
|
def set_defaults
|
64
|
-
|
65
|
-
|
66
|
-
@
|
67
|
-
@
|
68
|
-
@
|
69
|
-
@
|
70
|
-
@
|
71
|
-
@
|
72
|
-
@
|
73
|
-
@
|
74
|
-
@
|
92
|
+
|
93
|
+
# geocoding options
|
94
|
+
@data[:timeout] = 3 # geocoding service timeout (secs)
|
95
|
+
@data[:lookup] = :google # name of street address geocoding service (symbol)
|
96
|
+
@data[:ip_lookup] = :freegeoip # name of IP address geocoding service (symbol)
|
97
|
+
@data[:language] = :en # ISO-639 language code
|
98
|
+
@data[:http_headers] = {} # HTTP headers for lookup
|
99
|
+
@data[:use_https] = false # use HTTPS for lookup requests? (if supported)
|
100
|
+
@data[:http_proxy] = nil # HTTP proxy server (user:pass@host:port)
|
101
|
+
@data[:https_proxy] = nil # HTTPS proxy server (user:pass@host:port)
|
102
|
+
@data[:api_key] = nil # API key for geocoding service
|
103
|
+
@data[:cache] = nil # cache object (must respond to #[], #[]=, and #keys)
|
104
|
+
@data[:cache_prefix] = "geocoder:" # prefix (string) to use for all cache keys
|
75
105
|
|
76
106
|
# exceptions that should not be rescued by default
|
77
107
|
# (if you want to implement custom error handling);
|
78
108
|
# supports SocketError and TimeoutError
|
79
|
-
@always_raise = []
|
109
|
+
@data[:always_raise] = []
|
80
110
|
|
81
111
|
# calculation options
|
82
|
-
@units = :mi
|
83
|
-
@distances = :linear
|
112
|
+
@data[:units] = :mi # :mi or :km
|
113
|
+
@data[:distances] = :linear # :linear or :spherical
|
84
114
|
end
|
85
115
|
|
86
116
|
instance_eval(OPTIONS.map do |option|
|
87
117
|
o = option.to_s
|
88
118
|
<<-EOS
|
89
119
|
def #{o}
|
90
|
-
instance
|
120
|
+
instance.data[:#{o}]
|
91
121
|
end
|
92
122
|
|
93
123
|
def #{o}=(value)
|
94
|
-
instance
|
124
|
+
instance.data[:#{o}] = value
|
95
125
|
end
|
96
126
|
EOS
|
97
127
|
end.join("\n\n"))
|
98
128
|
|
99
|
-
class << self
|
100
|
-
def set_defaults
|
101
|
-
instance.set_defaults
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
129
|
end
|
106
130
|
end
|
data/lib/geocoder/exceptions.rb
CHANGED
data/lib/geocoder/lookup.rb
CHANGED
@@ -16,6 +16,21 @@ module Geocoder
|
|
16
16
|
|
17
17
|
class Base
|
18
18
|
|
19
|
+
##
|
20
|
+
# Human-readable name of the geocoding API.
|
21
|
+
#
|
22
|
+
def name
|
23
|
+
fail
|
24
|
+
end
|
25
|
+
|
26
|
+
##
|
27
|
+
# Symbol which is used in configuration to refer to this Lookup.
|
28
|
+
#
|
29
|
+
def handle
|
30
|
+
str = self.class.to_s
|
31
|
+
str[str.rindex(':')+1..-1].gsub(/([a-z\d]+)([A-Z])/,'\1_\2').downcase.to_sym
|
32
|
+
end
|
33
|
+
|
19
34
|
##
|
20
35
|
# Query the geocoding API and return a Geocoder::Result object.
|
21
36
|
# Returns +nil+ on timeout or error.
|
@@ -43,16 +58,37 @@ module Geocoder
|
|
43
58
|
nil
|
44
59
|
end
|
45
60
|
|
61
|
+
##
|
62
|
+
# Array containing string descriptions of keys required by the API.
|
63
|
+
# Empty array if keys are optional or not required.
|
64
|
+
#
|
65
|
+
def required_api_key_parts
|
66
|
+
[]
|
67
|
+
end
|
68
|
+
|
69
|
+
##
|
70
|
+
# URL to use for querying the geocoding engine.
|
71
|
+
#
|
72
|
+
def query_url(query)
|
73
|
+
fail
|
74
|
+
end
|
46
75
|
|
47
76
|
private # -------------------------------------------------------------
|
48
77
|
|
78
|
+
##
|
79
|
+
# An object with configuration data for this particular lookup.
|
80
|
+
#
|
81
|
+
def configuration
|
82
|
+
Geocoder.config_for_lookup(handle)
|
83
|
+
end
|
84
|
+
|
49
85
|
##
|
50
86
|
# Object used to make HTTP requests.
|
51
87
|
#
|
52
88
|
def http_client
|
53
|
-
protocol = "http#{'s' if
|
89
|
+
protocol = "http#{'s' if configuration.use_https}"
|
54
90
|
proxy_name = "#{protocol}_proxy"
|
55
|
-
if proxy =
|
91
|
+
if proxy = configuration.send(proxy_name)
|
56
92
|
proxy_url = protocol + '://' + proxy
|
57
93
|
begin
|
58
94
|
uri = URI.parse(proxy_url)
|
@@ -83,13 +119,6 @@ module Geocoder
|
|
83
119
|
)
|
84
120
|
end
|
85
121
|
|
86
|
-
##
|
87
|
-
# URL to use for querying the geocoding engine.
|
88
|
-
#
|
89
|
-
def query_url(query)
|
90
|
-
fail
|
91
|
-
end
|
92
|
-
|
93
122
|
##
|
94
123
|
# Key to use for caching a geocoding result. Usually this will be the
|
95
124
|
# request URL, but in cases where OAuth is used and the nonce,
|
@@ -112,7 +141,7 @@ module Geocoder
|
|
112
141
|
# Return false if exception not raised.
|
113
142
|
#
|
114
143
|
def raise_error(error, message = nil)
|
115
|
-
exceptions =
|
144
|
+
exceptions = configuration.always_raise
|
116
145
|
if exceptions == :all or exceptions.include?( error.is_a?(Class) ? error : error.class )
|
117
146
|
raise error, message
|
118
147
|
else
|
@@ -129,7 +158,7 @@ module Geocoder
|
|
129
158
|
raise_error(err) or warn "Geocoding API connection cannot be established."
|
130
159
|
rescue TimeoutError => err
|
131
160
|
raise_error(err) or warn "Geocoding API not responding fast enough " +
|
132
|
-
"(
|
161
|
+
"(use Geocoder.configure(:timeout => ...) to set limit)."
|
133
162
|
end
|
134
163
|
|
135
164
|
##
|
@@ -150,7 +179,7 @@ module Geocoder
|
|
150
179
|
# Set in configuration but not available for every service.
|
151
180
|
#
|
152
181
|
def protocol
|
153
|
-
"http" + (
|
182
|
+
"http" + (configuration.use_https ? "s" : "")
|
154
183
|
end
|
155
184
|
|
156
185
|
##
|
@@ -162,6 +191,7 @@ module Geocoder
|
|
162
191
|
if cache and body = cache[key]
|
163
192
|
@cache_hit = true
|
164
193
|
else
|
194
|
+
check_api_key_configuration!(query)
|
165
195
|
response = make_api_request(query)
|
166
196
|
body = response.body
|
167
197
|
if cache and (200..399).include?(response.code.to_i)
|
@@ -177,11 +207,21 @@ module Geocoder
|
|
177
207
|
# return the response object.
|
178
208
|
#
|
179
209
|
def make_api_request(query)
|
180
|
-
timeout(
|
210
|
+
timeout(configuration.timeout) do
|
181
211
|
uri = URI.parse(query_url(query))
|
182
212
|
client = http_client.new(uri.host, uri.port)
|
183
|
-
client.use_ssl = true if
|
184
|
-
client.get(uri.request_uri,
|
213
|
+
client.use_ssl = true if configuration.use_https
|
214
|
+
client.get(uri.request_uri, configuration.http_headers)
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
def check_api_key_configuration!(query)
|
219
|
+
key_parts = query.lookup.required_api_key_parts
|
220
|
+
if key_parts.size > Array(configuration.api_key).size
|
221
|
+
parts_string = key_parts.size == 1 ? key_parts.first : key_parts
|
222
|
+
raise Geocoder::ConfigurationError,
|
223
|
+
"The #{query.lookup.name} API requires a key to be configured: " +
|
224
|
+
parts_string.inspect
|
185
225
|
end
|
186
226
|
end
|
187
227
|
|
@@ -189,7 +229,10 @@ module Geocoder
|
|
189
229
|
# The working Cache object.
|
190
230
|
#
|
191
231
|
def cache
|
192
|
-
|
232
|
+
if @cache.nil? and store = configuration.cache
|
233
|
+
@cache = Cache.new(store, configuration.cache_prefix)
|
234
|
+
end
|
235
|
+
@cache
|
193
236
|
end
|
194
237
|
|
195
238
|
##
|