geocoder 1.5.0 → 1.6.2
Sign up to get free protection for your applications and to get access to all the features.
- 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)
|