geocoder 1.5.0 → 1.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/CHANGELOG.md +29 -2
- data/LICENSE +1 -1
- data/README.md +15 -17
- data/bin/console +7 -0
- data/examples/autoexpire_cache_redis.rb +2 -0
- data/lib/easting_northing.rb +171 -0
- data/lib/geocoder/calculations.rb +1 -1
- data/lib/geocoder/ip_address.rb +13 -0
- data/lib/geocoder/lookup.rb +8 -4
- data/lib/geocoder/lookups/baidu_ip.rb +1 -1
- data/lib/geocoder/lookups/ban_data_gouv_fr.rb +13 -0
- data/lib/geocoder/lookups/base.rb +7 -2
- data/lib/geocoder/lookups/bing.rb +2 -1
- data/lib/geocoder/lookups/esri.rb +38 -13
- data/lib/geocoder/lookups/freegeoip.rb +7 -7
- data/lib/geocoder/lookups/here.rb +28 -22
- data/lib/geocoder/lookups/ip2location.rb +7 -14
- data/lib/geocoder/lookups/ipapi_com.rb +2 -1
- data/lib/geocoder/lookups/ipdata_co.rb +5 -4
- data/lib/geocoder/lookups/ipgeolocation.rb +51 -0
- data/lib/geocoder/lookups/ipinfo_io.rb +2 -11
- data/lib/geocoder/lookups/ipregistry.rb +68 -0
- data/lib/geocoder/lookups/ipstack.rb +2 -2
- data/lib/geocoder/lookups/maxmind.rb +2 -2
- data/lib/geocoder/lookups/maxmind_geoip2.rb +4 -7
- data/lib/geocoder/lookups/nationaal_georegister_nl.rb +38 -0
- data/lib/geocoder/lookups/osmnames.rb +57 -0
- data/lib/geocoder/lookups/pelias.rb +2 -3
- data/lib/geocoder/lookups/pickpoint.rb +1 -1
- data/lib/geocoder/lookups/pointpin.rb +3 -3
- data/lib/geocoder/lookups/smarty_streets.rb +13 -3
- data/lib/geocoder/lookups/telize.rb +2 -2
- data/lib/geocoder/lookups/tencent.rb +59 -0
- data/lib/geocoder/lookups/uk_ordnance_survey_names.rb +59 -0
- data/lib/geocoder/lookups/yandex.rb +2 -2
- data/lib/geocoder/query.rb +14 -0
- data/lib/geocoder/railtie.rb +1 -1
- data/lib/geocoder/results/baidu.rb +0 -4
- data/lib/geocoder/results/ban_data_gouv_fr.rb +1 -1
- data/lib/geocoder/results/here.rb +4 -1
- data/lib/geocoder/results/ipgeolocation.rb +59 -0
- data/lib/geocoder/results/ipregistry.rb +308 -0
- data/lib/geocoder/results/nationaal_georegister_nl.rb +62 -0
- data/lib/geocoder/results/osmnames.rb +56 -0
- data/lib/geocoder/results/smarty_streets.rb +48 -18
- data/lib/geocoder/results/tencent.rb +72 -0
- data/lib/geocoder/results/uk_ordnance_survey_names.rb +59 -0
- data/lib/geocoder/results/yandex.rb +217 -59
- data/lib/geocoder/sql.rb +4 -4
- data/lib/geocoder/stores/active_record.rb +1 -1
- data/lib/geocoder/version.rb +1 -1
- data/lib/hash_recursive_merge.rb +1 -2
- data/lib/maxmind_database.rb +3 -3
- metadata +18 -13
- data/lib/geocoder/lookups/geocoder_us.rb +0 -51
- data/lib/geocoder/lookups/mapzen.rb +0 -15
- data/lib/geocoder/results/geocoder_us.rb +0 -39
- data/lib/geocoder/results/mapzen.rb +0 -5
@@ -40,31 +40,56 @@ module Geocoder::Lookup
|
|
40
40
|
else
|
41
41
|
params[:text] = query.sanitized_text
|
42
42
|
end
|
43
|
-
|
44
|
-
params[:
|
43
|
+
|
44
|
+
params[:token] = token(query)
|
45
|
+
|
46
|
+
if for_storage_value = for_storage(query)
|
47
|
+
params[:forStorage] = for_storage_value
|
48
|
+
end
|
45
49
|
params[:sourceCountry] = configuration[:source_country] if configuration[:source_country]
|
46
50
|
params.merge(super)
|
47
51
|
end
|
48
52
|
|
49
|
-
def
|
50
|
-
|
51
|
-
|
53
|
+
def for_storage(query)
|
54
|
+
if query.options.has_key?(:for_storage)
|
55
|
+
query.options[:for_storage]
|
56
|
+
else
|
57
|
+
configuration[:for_storage]
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def token(query)
|
62
|
+
token_instance = if query.options[:token]
|
63
|
+
query.options[:token]
|
64
|
+
else
|
65
|
+
configuration[:token]
|
66
|
+
end
|
67
|
+
|
68
|
+
if !valid_token_configured?(token_instance) && configuration.api_key
|
69
|
+
token_instance = create_and_save_token!(query)
|
70
|
+
end
|
71
|
+
|
72
|
+
token_instance.to_s unless token_instance.nil?
|
52
73
|
end
|
53
74
|
|
54
|
-
def valid_token_configured?
|
55
|
-
!
|
75
|
+
def valid_token_configured?(token_instance)
|
76
|
+
!token_instance.nil? && token_instance.active?
|
56
77
|
end
|
57
78
|
|
58
|
-
def create_and_save_token!
|
59
|
-
|
79
|
+
def create_and_save_token!(query)
|
80
|
+
token_instance = create_token
|
81
|
+
|
82
|
+
if query.options[:token]
|
83
|
+
query.options[:token] = token_instance
|
84
|
+
else
|
85
|
+
Geocoder.merge_into_lookup_config(:esri, token: token_instance)
|
86
|
+
end
|
87
|
+
|
88
|
+
token_instance
|
60
89
|
end
|
61
90
|
|
62
91
|
def create_token
|
63
92
|
Geocoder::EsriToken.generate_token(*configuration.api_key)
|
64
93
|
end
|
65
|
-
|
66
|
-
def save_token!(token_instance)
|
67
|
-
Geocoder.merge_into_lookup_config(:esri, token: token_instance)
|
68
|
-
end
|
69
94
|
end
|
70
95
|
end
|
@@ -7,10 +7,10 @@ module Geocoder::Lookup
|
|
7
7
|
def name
|
8
8
|
"FreeGeoIP"
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
def supported_protocols
|
12
12
|
if configuration[:host]
|
13
|
-
[:
|
13
|
+
[:https]
|
14
14
|
else
|
15
15
|
# use https for default host
|
16
16
|
[:https]
|
@@ -32,8 +32,8 @@ module Geocoder::Lookup
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def results(query)
|
35
|
-
# don't look up a loopback address, just return the stored result
|
36
|
-
return [reserved_result(query.text)] if query.
|
35
|
+
# don't look up a loopback or private address, just return the stored result
|
36
|
+
return [reserved_result(query.text)] if query.internal_ip_address?
|
37
37
|
# note: Freegeoip.net returns plain text "Not Found" on bad request
|
38
38
|
(doc = fetch_data(query)) ? [doc] : []
|
39
39
|
end
|
@@ -44,8 +44,8 @@ module Geocoder::Lookup
|
|
44
44
|
"city" => "",
|
45
45
|
"region_code" => "",
|
46
46
|
"region_name" => "",
|
47
|
-
"
|
48
|
-
"
|
47
|
+
"metro_code" => "",
|
48
|
+
"zip_code" => "",
|
49
49
|
"latitude" => "0",
|
50
50
|
"longitude" => "0",
|
51
51
|
"country_name" => "Reserved",
|
@@ -54,7 +54,7 @@ module Geocoder::Lookup
|
|
54
54
|
end
|
55
55
|
|
56
56
|
def host
|
57
|
-
configuration[:host] || "freegeoip.
|
57
|
+
configuration[:host] || "freegeoip.app"
|
58
58
|
end
|
59
59
|
end
|
60
60
|
end
|
@@ -9,13 +9,17 @@ module Geocoder::Lookup
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def required_api_key_parts
|
12
|
-
[
|
12
|
+
['api_key']
|
13
|
+
end
|
14
|
+
|
15
|
+
def supported_protocols
|
16
|
+
[:https]
|
13
17
|
end
|
14
18
|
|
15
19
|
private # ---------------------------------------------------------------
|
16
20
|
|
17
21
|
def base_query_url(query)
|
18
|
-
"#{protocol}://#{if query.reverse_geocode? then 'reverse.' end}geocoder.
|
22
|
+
"#{protocol}://#{if query.reverse_geocode? then 'reverse.' end}geocoder.ls.hereapi.com/6.2/#{if query.reverse_geocode? then 'reverse' end}geocode.json?"
|
19
23
|
end
|
20
24
|
|
21
25
|
def results(query)
|
@@ -28,34 +32,36 @@ module Geocoder::Lookup
|
|
28
32
|
[]
|
29
33
|
end
|
30
34
|
|
31
|
-
def
|
35
|
+
def query_url_here_options(query, reverse_geocode)
|
32
36
|
options = {
|
33
|
-
:
|
34
|
-
:
|
35
|
-
:
|
37
|
+
gen: 9,
|
38
|
+
apikey: configuration.api_key,
|
39
|
+
language: (query.language || configuration.language)
|
36
40
|
}
|
41
|
+
if reverse_geocode
|
42
|
+
options[:mode] = :retrieveAddresses
|
43
|
+
return options
|
44
|
+
end
|
37
45
|
|
38
|
-
|
39
|
-
|
40
|
-
:prox=>query.sanitized_text,
|
41
|
-
:mode=>:retrieveAddresses
|
42
|
-
)
|
43
|
-
else
|
44
|
-
super.merge(options).merge(
|
45
|
-
:searchtext=>query.sanitized_text
|
46
|
-
)
|
46
|
+
unless (country = query.options[:country]).nil?
|
47
|
+
options[:country] = country
|
47
48
|
end
|
48
|
-
end
|
49
49
|
|
50
|
-
|
51
|
-
|
52
|
-
return a.first if a.is_a?(Array)
|
50
|
+
unless (mapview = query.options[:bounds]).nil?
|
51
|
+
options[:mapview] = mapview.map{ |point| "%f,%f" % point }.join(';')
|
53
52
|
end
|
53
|
+
options
|
54
54
|
end
|
55
55
|
|
56
|
-
def
|
57
|
-
if
|
58
|
-
|
56
|
+
def query_url_params(query)
|
57
|
+
if query.reverse_geocode?
|
58
|
+
super.merge(query_url_here_options(query, true)).merge(
|
59
|
+
prox: query.sanitized_text
|
60
|
+
)
|
61
|
+
else
|
62
|
+
super.merge(query_url_here_options(query, false)).merge(
|
63
|
+
searchtext: query.sanitized_text
|
64
|
+
)
|
59
65
|
end
|
60
66
|
end
|
61
67
|
end
|
@@ -19,15 +19,16 @@ module Geocoder::Lookup
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def query_url_params(query)
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
22
|
+
params = super
|
23
|
+
if configuration.has_key?(:package)
|
24
|
+
params.merge!(package: configuration[:package])
|
25
|
+
end
|
26
|
+
params
|
27
27
|
end
|
28
28
|
|
29
29
|
def results(query)
|
30
|
-
return
|
30
|
+
# don't look up a loopback or private address, just return the stored result
|
31
|
+
return [reserved_result(query.text)] if query.internal_ip_address?
|
31
32
|
return [] unless doc = fetch_data(query)
|
32
33
|
if doc["response"] == "INVALID ACCOUNT"
|
33
34
|
raise_error(Geocoder::InvalidApiKey) || Geocoder.log(:warn, "INVALID ACCOUNT")
|
@@ -62,13 +63,5 @@ module Geocoder::Lookup
|
|
62
63
|
}
|
63
64
|
end
|
64
65
|
|
65
|
-
def query_url_params(query)
|
66
|
-
params = super
|
67
|
-
if configuration.has_key?(:package)
|
68
|
-
params.merge!(package: configuration[:package])
|
69
|
-
end
|
70
|
-
params
|
71
|
-
end
|
72
|
-
|
73
66
|
end
|
74
67
|
end
|
@@ -34,7 +34,8 @@ module Geocoder::Lookup
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def results(query)
|
37
|
-
return
|
37
|
+
# don't look up a loopback or private address, just return the stored result
|
38
|
+
return [reserved_result(query.text)] if query.internal_ip_address?
|
38
39
|
|
39
40
|
return [] unless doc = fetch_data(query)
|
40
41
|
|
@@ -13,7 +13,9 @@ module Geocoder::Lookup
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def query_url(query)
|
16
|
-
|
16
|
+
# Ipdata.co requires that the API key be sent as a query parameter.
|
17
|
+
# It no longer supports API keys sent as headers.
|
18
|
+
"#{protocol}://#{host}/#{query.sanitized_text}?api-key=#{configuration.api_key}"
|
17
19
|
end
|
18
20
|
|
19
21
|
private # ---------------------------------------------------------------
|
@@ -23,9 +25,8 @@ module Geocoder::Lookup
|
|
23
25
|
end
|
24
26
|
|
25
27
|
def results(query)
|
26
|
-
|
27
|
-
|
28
|
-
return [reserved_result(query.text)] if query.loopback_ip_address?
|
28
|
+
# don't look up a loopback or private address, just return the stored result
|
29
|
+
return [reserved_result(query.text)] if query.internal_ip_address?
|
29
30
|
# note: Ipdata.co returns plain text on bad request
|
30
31
|
(doc = fetch_data(query)) ? [doc] : []
|
31
32
|
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'geocoder/lookups/base'
|
2
|
+
require 'geocoder/results/ipgeolocation'
|
3
|
+
|
4
|
+
|
5
|
+
module Geocoder::Lookup
|
6
|
+
class Ipgeolocation < Base
|
7
|
+
|
8
|
+
ERROR_CODES = {
|
9
|
+
400 => Geocoder::RequestDenied, # subscription is paused
|
10
|
+
401 => Geocoder::InvalidApiKey, # missing/invalid API key
|
11
|
+
403 => Geocoder::InvalidRequest, # invalid IP address
|
12
|
+
404 => Geocoder::InvalidRequest, # not found
|
13
|
+
423 => Geocoder::InvalidRequest # bogon/reserved IP address
|
14
|
+
}
|
15
|
+
ERROR_CODES.default = Geocoder::Error
|
16
|
+
|
17
|
+
def name
|
18
|
+
"Ipgeolocation"
|
19
|
+
end
|
20
|
+
|
21
|
+
def supported_protocols
|
22
|
+
[:https]
|
23
|
+
end
|
24
|
+
|
25
|
+
private # ----------------------------------------------------------------
|
26
|
+
|
27
|
+
def base_query_url(query)
|
28
|
+
"#{protocol}://api.ipgeolocation.io/ipgeo?"
|
29
|
+
end
|
30
|
+
def query_url_params(query)
|
31
|
+
{
|
32
|
+
ip: query.sanitized_text,
|
33
|
+
apiKey: configuration.api_key
|
34
|
+
}.merge(super)
|
35
|
+
end
|
36
|
+
|
37
|
+
def results(query)
|
38
|
+
# don't look up a loopback or private address, just return the stored result
|
39
|
+
return [reserved_result(query.text)] if query.internal_ip_address?
|
40
|
+
[fetch_data(query)]
|
41
|
+
end
|
42
|
+
|
43
|
+
def reserved_result(ip)
|
44
|
+
{
|
45
|
+
"ip" => ip,
|
46
|
+
"country_name" => "Reserved",
|
47
|
+
"country_code2" => "RD"
|
48
|
+
}
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -8,15 +8,6 @@ module Geocoder::Lookup
|
|
8
8
|
"Ipinfo.io"
|
9
9
|
end
|
10
10
|
|
11
|
-
# HTTPS available only for paid plans
|
12
|
-
def supported_protocols
|
13
|
-
if configuration.api_key
|
14
|
-
[:http, :https]
|
15
|
-
else
|
16
|
-
[:http]
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
11
|
private # ---------------------------------------------------------------
|
21
12
|
|
22
13
|
def base_query_url(query)
|
@@ -26,8 +17,8 @@ module Geocoder::Lookup
|
|
26
17
|
end
|
27
18
|
|
28
19
|
def results(query)
|
29
|
-
# don't look up a loopback address, just return the stored result
|
30
|
-
return [reserved_result(query.text)] if query.
|
20
|
+
# don't look up a loopback or private address, just return the stored result
|
21
|
+
return [reserved_result(query.text)] if query.internal_ip_address?
|
31
22
|
|
32
23
|
if !(doc = fetch_data(query)).is_a?(Hash) or doc['error']
|
33
24
|
[]
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'geocoder/lookups/base'
|
2
|
+
require 'geocoder/results/ipregistry'
|
3
|
+
|
4
|
+
module Geocoder::Lookup
|
5
|
+
class Ipregistry < Base
|
6
|
+
|
7
|
+
ERROR_CODES = {
|
8
|
+
400 => Geocoder::InvalidRequest,
|
9
|
+
401 => Geocoder::InvalidRequest,
|
10
|
+
402 => Geocoder::OverQueryLimitError,
|
11
|
+
403 => Geocoder::InvalidApiKey,
|
12
|
+
451 => Geocoder::RequestDenied,
|
13
|
+
500 => Geocoder::Error
|
14
|
+
}
|
15
|
+
ERROR_CODES.default = Geocoder::Error
|
16
|
+
|
17
|
+
def name
|
18
|
+
"Ipregistry"
|
19
|
+
end
|
20
|
+
|
21
|
+
def supported_protocols
|
22
|
+
[:https, :http]
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def base_query_url(query)
|
28
|
+
"#{protocol}://#{host}/#{query.sanitized_text}?"
|
29
|
+
end
|
30
|
+
|
31
|
+
def cache_key(query)
|
32
|
+
query_url(query)
|
33
|
+
end
|
34
|
+
|
35
|
+
def host
|
36
|
+
configuration[:host] || "api.ipregistry.co"
|
37
|
+
end
|
38
|
+
|
39
|
+
def query_url_params(query)
|
40
|
+
{
|
41
|
+
key: configuration.api_key
|
42
|
+
}.merge(super)
|
43
|
+
end
|
44
|
+
|
45
|
+
def results(query)
|
46
|
+
# don't look up a loopback or private address, just return the stored result
|
47
|
+
return [reserved_result(query.text)] if query.internal_ip_address?
|
48
|
+
|
49
|
+
return [] unless (doc = fetch_data(query))
|
50
|
+
|
51
|
+
if (error = doc['error'])
|
52
|
+
code = error['code']
|
53
|
+
msg = error['message']
|
54
|
+
raise_error(ERROR_CODES[code], msg ) || Geocoder.log(:warn, "Ipregistry API error: #{msg}")
|
55
|
+
return []
|
56
|
+
end
|
57
|
+
[doc]
|
58
|
+
end
|
59
|
+
|
60
|
+
def reserved_result(ip)
|
61
|
+
{
|
62
|
+
"ip" => ip,
|
63
|
+
"country_name" => "Reserved",
|
64
|
+
"country_code" => "RD"
|
65
|
+
}
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -34,8 +34,8 @@ module Geocoder::Lookup
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def results(query)
|
37
|
-
# don't look up a loopback address, just return the stored result
|
38
|
-
return [reserved_result(query.text)] if query.
|
37
|
+
# don't look up a loopback or private address, just return the stored result
|
38
|
+
return [reserved_result(query.text)] if query.internal_ip_address?
|
39
39
|
|
40
40
|
return [] unless doc = fetch_data(query)
|
41
41
|
|
@@ -57,8 +57,8 @@ module Geocoder::Lookup
|
|
57
57
|
end
|
58
58
|
|
59
59
|
def results(query)
|
60
|
-
# don't look up a loopback address, just return the stored result
|
61
|
-
return [reserved_result] if query.
|
60
|
+
# don't look up a loopback or private address, just return the stored result
|
61
|
+
return [reserved_result] if query.internal_ip_address?
|
62
62
|
doc = fetch_data(query)
|
63
63
|
if doc and doc.is_a?(Array)
|
64
64
|
if !data_contains_error?(doc)
|
@@ -32,11 +32,7 @@ module Geocoder::Lookup
|
|
32
32
|
return s
|
33
33
|
else
|
34
34
|
raise(
|
35
|
-
Geocoder::ConfigurationError,
|
36
|
-
"When using MaxMind GeoIP2 you MUST specify a service name and basic_auth: " +
|
37
|
-
"Geocoder.configure(:maxmind_geoip2 => {:service => ...}, " +
|
38
|
-
":basic_auth => {:user ..., :password => ...}), " +
|
39
|
-
"where service is one of: #{services.inspect}"
|
35
|
+
Geocoder::ConfigurationError, "When using MaxMind GeoIP2 you must specify a service and credentials: Geocoder.configure(maxmind_geoip2: {service: ..., basic_auth: {user: ..., password: ...}}), where service is one of: #{services.inspect}"
|
40
36
|
)
|
41
37
|
end
|
42
38
|
end
|
@@ -57,8 +53,9 @@ module Geocoder::Lookup
|
|
57
53
|
end
|
58
54
|
|
59
55
|
def results(query)
|
60
|
-
# don't look up a loopback address
|
61
|
-
return [] if query.
|
56
|
+
# don't look up a loopback or private address, just return the stored result
|
57
|
+
return [] if query.internal_ip_address?
|
58
|
+
|
62
59
|
doc = fetch_data(query)
|
63
60
|
if doc
|
64
61
|
if !data_contains_error?(doc)
|