geocoder 1.4.3 → 1.6.1
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 +64 -0
- data/LICENSE +1 -1
- data/README.md +365 -883
- data/examples/autoexpire_cache_redis.rb +5 -3
- data/lib/generators/geocoder/config/templates/initializer.rb +3 -2
- data/lib/generators/geocoder/maxmind/geolite_city_generator.rb +2 -0
- data/lib/generators/geocoder/maxmind/geolite_country_generator.rb +2 -0
- data/lib/generators/geocoder/maxmind/templates/migration/geolite_city.rb +1 -1
- data/lib/generators/geocoder/maxmind/templates/migration/geolite_country.rb +1 -1
- data/lib/generators/geocoder/migration_version.rb +15 -0
- data/lib/geocoder/cache.rb +6 -2
- data/lib/geocoder/calculations.rb +1 -1
- data/lib/geocoder/cli.rb +2 -2
- data/lib/geocoder/configuration.rb +2 -2
- data/lib/geocoder/exceptions.rb +1 -1
- data/lib/geocoder/ip_address.rb +14 -1
- data/lib/geocoder/lookup.rb +13 -6
- data/lib/geocoder/lookups/amap.rb +63 -0
- data/lib/geocoder/lookups/baidu.rb +14 -10
- data/lib/geocoder/lookups/baidu_ip.rb +7 -36
- data/lib/geocoder/lookups/ban_data_gouv_fr.rb +17 -4
- data/lib/geocoder/lookups/base.rb +28 -5
- data/lib/geocoder/lookups/bing.rb +15 -13
- data/lib/geocoder/lookups/db_ip_com.rb +52 -0
- data/lib/geocoder/lookups/dstk.rb +4 -2
- data/lib/geocoder/lookups/esri.rb +39 -29
- data/lib/geocoder/lookups/freegeoip.rb +16 -7
- data/lib/geocoder/lookups/geocoder_ca.rb +4 -4
- data/lib/geocoder/lookups/geocodio.rb +5 -5
- data/lib/geocoder/lookups/geoportail_lu.rb +7 -7
- data/lib/geocoder/lookups/google.rb +13 -9
- data/lib/geocoder/lookups/google_places_details.rb +4 -4
- data/lib/geocoder/lookups/google_places_search.rb +4 -4
- data/lib/geocoder/lookups/google_premier.rb +11 -1
- data/lib/geocoder/lookups/here.rb +29 -23
- data/lib/geocoder/lookups/ip2location.rb +67 -0
- data/lib/geocoder/lookups/ipapi_com.rb +9 -13
- data/lib/geocoder/lookups/ipdata_co.rb +62 -0
- data/lib/geocoder/lookups/ipgeolocation.rb +51 -0
- data/lib/geocoder/lookups/ipinfo_io.rb +11 -29
- data/lib/geocoder/lookups/ipregistry.rb +68 -0
- data/lib/geocoder/lookups/ipstack.rb +63 -0
- data/lib/geocoder/lookups/latlon.rb +4 -4
- data/lib/geocoder/lookups/location_iq.rb +26 -8
- data/lib/geocoder/lookups/mapbox.rb +12 -6
- data/lib/geocoder/lookups/mapquest.rb +4 -5
- data/lib/geocoder/lookups/maxmind.rb +6 -6
- data/lib/geocoder/lookups/maxmind_geoip2.rb +8 -7
- data/lib/geocoder/lookups/nominatim.rb +17 -5
- data/lib/geocoder/lookups/opencagedata.rb +7 -6
- data/lib/geocoder/lookups/osmnames.rb +57 -0
- data/lib/geocoder/lookups/pelias.rb +8 -9
- data/lib/geocoder/lookups/pickpoint.rb +41 -0
- data/lib/geocoder/lookups/pointpin.rb +10 -9
- data/lib/geocoder/lookups/postcode_anywhere_uk.rb +4 -5
- data/lib/geocoder/lookups/postcodes_io.rb +31 -0
- data/lib/geocoder/lookups/smarty_streets.rb +20 -10
- data/lib/geocoder/lookups/telize.rb +26 -6
- data/lib/geocoder/lookups/tencent.rb +59 -0
- data/lib/geocoder/lookups/yandex.rb +12 -8
- data/lib/geocoder/models/active_record.rb +4 -3
- data/lib/geocoder/query.rb +14 -0
- data/lib/geocoder/railtie.rb +1 -1
- data/lib/geocoder/request.rb +32 -0
- data/lib/geocoder/results/amap.rb +87 -0
- data/lib/geocoder/results/baidu.rb +10 -14
- data/lib/geocoder/results/ban_data_gouv_fr.rb +1 -1
- data/lib/geocoder/results/base.rb +13 -1
- data/lib/geocoder/results/bing.rb +1 -1
- data/lib/geocoder/results/db_ip_com.rb +58 -0
- data/lib/geocoder/results/freegeoip.rb +0 -5
- data/lib/geocoder/results/geocoder_ca.rb +3 -3
- data/lib/geocoder/results/geoip2.rb +24 -10
- data/lib/geocoder/results/geoportail_lu.rb +5 -3
- data/lib/geocoder/results/google.rb +16 -5
- data/lib/geocoder/results/here.rb +12 -1
- data/lib/geocoder/results/ip2location.rb +22 -0
- data/lib/geocoder/results/ipdata_co.rb +40 -0
- data/lib/geocoder/results/ipgeolocation.rb +59 -0
- data/lib/geocoder/results/ipregistry.rb +308 -0
- data/lib/geocoder/results/ipstack.rb +60 -0
- data/lib/geocoder/results/maxmind.rb +0 -5
- data/lib/geocoder/results/maxmind_local.rb +0 -5
- data/lib/geocoder/results/nominatim.rb +12 -0
- data/lib/geocoder/results/opencagedata.rb +12 -2
- data/lib/geocoder/results/osmnames.rb +56 -0
- data/lib/geocoder/results/pickpoint.rb +6 -0
- data/lib/geocoder/results/postcodes_io.rb +40 -0
- data/lib/geocoder/results/smarty_streets.rb +55 -19
- data/lib/geocoder/results/telize.rb +0 -5
- data/lib/geocoder/results/tencent.rb +72 -0
- data/lib/geocoder/results/test.rb +1 -1
- data/lib/geocoder/sql.rb +4 -4
- data/lib/geocoder/stores/active_record.rb +16 -5
- data/lib/geocoder/stores/base.rb +1 -2
- data/lib/geocoder/version.rb +1 -1
- data/lib/hash_recursive_merge.rb +1 -2
- data/lib/maxmind_database.rb +3 -3
- data/lib/tasks/geocoder.rake +11 -3
- metadata +30 -14
- data/lib/geocoder/lookups/geocoder_us.rb +0 -43
- data/lib/geocoder/lookups/mapzen.rb +0 -15
- data/lib/geocoder/lookups/okf.rb +0 -44
- data/lib/geocoder/lookups/ovi.rb +0 -62
- data/lib/geocoder/results/geocoder_us.rb +0 -39
- data/lib/geocoder/results/mapzen.rb +0 -5
- data/lib/geocoder/results/okf.rb +0 -106
- data/lib/geocoder/results/ovi.rb +0 -71
|
@@ -16,12 +16,12 @@ module Geocoder
|
|
|
16
16
|
[:https]
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
-
def query_url(query)
|
|
20
|
-
"#{protocol}://maps.googleapis.com/maps/api/place/details/json?#{url_query_string(query)}"
|
|
21
|
-
end
|
|
22
|
-
|
|
23
19
|
private
|
|
24
20
|
|
|
21
|
+
def base_query_url(query)
|
|
22
|
+
"#{protocol}://maps.googleapis.com/maps/api/place/details/json?"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
25
|
def results(query)
|
|
26
26
|
return [] unless doc = fetch_data(query)
|
|
27
27
|
|
|
@@ -16,12 +16,12 @@ module Geocoder
|
|
|
16
16
|
[:https]
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
-
def query_url(query)
|
|
20
|
-
"#{protocol}://maps.googleapis.com/maps/api/place/textsearch/json?#{url_query_string(query)}"
|
|
21
|
-
end
|
|
22
|
-
|
|
23
19
|
private
|
|
24
20
|
|
|
21
|
+
def base_query_url(query)
|
|
22
|
+
"#{protocol}://maps.googleapis.com/maps/api/place/textsearch/json?"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
25
|
def query_url_google_params(query)
|
|
26
26
|
{
|
|
27
27
|
query: query.text,
|
|
@@ -11,7 +11,7 @@ module Geocoder::Lookup
|
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
def required_api_key_parts
|
|
14
|
-
["private key"
|
|
14
|
+
["private key"]
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
def query_url(query)
|
|
@@ -21,6 +21,16 @@ module Geocoder::Lookup
|
|
|
21
21
|
|
|
22
22
|
private # ---------------------------------------------------------------
|
|
23
23
|
|
|
24
|
+
def cache_key(query)
|
|
25
|
+
"#{protocol}://maps.googleapis.com/maps/api/geocode/json?" + hash_to_query(cache_key_params(query))
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def cache_key_params(query)
|
|
29
|
+
query_url_google_params(query).merge(super).reject do |k,v|
|
|
30
|
+
[:key, :client, :channel].include?(k)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
24
34
|
def query_url_params(query)
|
|
25
35
|
query_url_google_params(query).merge(super).merge(
|
|
26
36
|
:key => nil, # don't use param inherited from Google lookup
|
|
@@ -9,15 +9,19 @@ module Geocoder::Lookup
|
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
def required_api_key_parts
|
|
12
|
-
[
|
|
12
|
+
['api_key']
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
-
def
|
|
16
|
-
|
|
15
|
+
def supported_protocols
|
|
16
|
+
[:https]
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
private # ---------------------------------------------------------------
|
|
20
20
|
|
|
21
|
+
def base_query_url(query)
|
|
22
|
+
"#{protocol}://#{if query.reverse_geocode? then 'reverse.' end}geocoder.ls.hereapi.com/6.2/#{if query.reverse_geocode? then 'reverse' end}geocode.json?"
|
|
23
|
+
end
|
|
24
|
+
|
|
21
25
|
def results(query)
|
|
22
26
|
return [] unless doc = fetch_data(query)
|
|
23
27
|
return [] unless doc['Response'] && doc['Response']['View']
|
|
@@ -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
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
require 'geocoder/lookups/base'
|
|
2
|
+
require 'geocoder/results/ip2location'
|
|
3
|
+
|
|
4
|
+
module Geocoder::Lookup
|
|
5
|
+
class Ip2location < Base
|
|
6
|
+
|
|
7
|
+
def name
|
|
8
|
+
"IP2LocationApi"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def supported_protocols
|
|
12
|
+
[:http, :https]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
private # ----------------------------------------------------------------
|
|
16
|
+
|
|
17
|
+
def base_query_url(query)
|
|
18
|
+
"#{protocol}://api.ip2location.com/?"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def query_url_params(query)
|
|
22
|
+
params = super
|
|
23
|
+
if configuration.has_key?(:package)
|
|
24
|
+
params.merge!(package: configuration[:package])
|
|
25
|
+
end
|
|
26
|
+
params
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def results(query)
|
|
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?
|
|
32
|
+
return [] unless doc = fetch_data(query)
|
|
33
|
+
if doc["response"] == "INVALID ACCOUNT"
|
|
34
|
+
raise_error(Geocoder::InvalidApiKey) || Geocoder.log(:warn, "INVALID ACCOUNT")
|
|
35
|
+
return []
|
|
36
|
+
else
|
|
37
|
+
return [doc]
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def reserved_result(query)
|
|
42
|
+
{
|
|
43
|
+
"country_code" => "INVALID IP ADDRESS",
|
|
44
|
+
"country_name" => "INVALID IP ADDRESS",
|
|
45
|
+
"region_name" => "INVALID IP ADDRESS",
|
|
46
|
+
"city_name" => "INVALID IP ADDRESS",
|
|
47
|
+
"latitude" => "INVALID IP ADDRESS",
|
|
48
|
+
"longitude" => "INVALID IP ADDRESS",
|
|
49
|
+
"zip_code" => "INVALID IP ADDRESS",
|
|
50
|
+
"time_zone" => "INVALID IP ADDRESS",
|
|
51
|
+
"isp" => "INVALID IP ADDRESS",
|
|
52
|
+
"domain" => "INVALID IP ADDRESS",
|
|
53
|
+
"net_speed" => "INVALID IP ADDRESS",
|
|
54
|
+
"idd_code" => "INVALID IP ADDRESS",
|
|
55
|
+
"area_code" => "INVALID IP ADDRESS",
|
|
56
|
+
"weather_station_code" => "INVALID IP ADDRESS",
|
|
57
|
+
"weather_station_name" => "INVALID IP ADDRESS",
|
|
58
|
+
"mcc" => "INVALID IP ADDRESS",
|
|
59
|
+
"mnc" => "INVALID IP ADDRESS",
|
|
60
|
+
"mobile_brand" => "INVALID IP ADDRESS",
|
|
61
|
+
"elevation" => "INVALID IP ADDRESS",
|
|
62
|
+
"usage_type" => "INVALID IP ADDRESS"
|
|
63
|
+
}
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
end
|
|
67
|
+
end
|
|
@@ -8,17 +8,6 @@ module Geocoder::Lookup
|
|
|
8
8
|
"ip-api.com"
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
-
def query_url(query)
|
|
12
|
-
domain = configuration.api_key ? "pro.ip-api.com" : "ip-api.com"
|
|
13
|
-
url_ = "#{protocol}://#{domain}/json/#{query.sanitized_text}"
|
|
14
|
-
|
|
15
|
-
if (params = url_query_string(query)) && !params.empty?
|
|
16
|
-
url_ + "?" + params
|
|
17
|
-
else
|
|
18
|
-
url_
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
|
|
22
11
|
def supported_protocols
|
|
23
12
|
if configuration.api_key
|
|
24
13
|
[:http, :https]
|
|
@@ -27,8 +16,14 @@ module Geocoder::Lookup
|
|
|
27
16
|
end
|
|
28
17
|
end
|
|
29
18
|
|
|
19
|
+
private # ----------------------------------------------------------------
|
|
30
20
|
|
|
31
|
-
|
|
21
|
+
def base_query_url(query)
|
|
22
|
+
domain = configuration.api_key ? "pro.ip-api.com" : "ip-api.com"
|
|
23
|
+
url = "#{protocol}://#{domain}/json/#{query.sanitized_text}"
|
|
24
|
+
url << "?" if not url_query_string(query).empty?
|
|
25
|
+
url
|
|
26
|
+
end
|
|
32
27
|
|
|
33
28
|
def parse_raw_data(raw_data)
|
|
34
29
|
if raw_data.chomp == "invalid key"
|
|
@@ -39,7 +34,8 @@ module Geocoder::Lookup
|
|
|
39
34
|
end
|
|
40
35
|
|
|
41
36
|
def results(query)
|
|
42
|
-
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?
|
|
43
39
|
|
|
44
40
|
return [] unless doc = fetch_data(query)
|
|
45
41
|
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
require 'geocoder/lookups/base'
|
|
2
|
+
require 'geocoder/results/ipdata_co'
|
|
3
|
+
|
|
4
|
+
module Geocoder::Lookup
|
|
5
|
+
class IpdataCo < Base
|
|
6
|
+
|
|
7
|
+
def name
|
|
8
|
+
"ipdata.co"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def supported_protocols
|
|
12
|
+
[:https]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def query_url(query)
|
|
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}"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private # ---------------------------------------------------------------
|
|
22
|
+
|
|
23
|
+
def cache_key(query)
|
|
24
|
+
query_url(query)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def results(query)
|
|
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?
|
|
30
|
+
# note: Ipdata.co returns plain text on bad request
|
|
31
|
+
(doc = fetch_data(query)) ? [doc] : []
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def reserved_result(ip)
|
|
35
|
+
{
|
|
36
|
+
"ip" => ip,
|
|
37
|
+
"city" => "",
|
|
38
|
+
"region_code" => "",
|
|
39
|
+
"region_name" => "",
|
|
40
|
+
"metrocode" => "",
|
|
41
|
+
"zipcode" => "",
|
|
42
|
+
"latitude" => "0",
|
|
43
|
+
"longitude" => "0",
|
|
44
|
+
"country_name" => "Reserved",
|
|
45
|
+
"country_code" => "RD"
|
|
46
|
+
}
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def host
|
|
50
|
+
"api.ipdata.co"
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def check_response_for_errors!(response)
|
|
54
|
+
if response.code.to_i == 403
|
|
55
|
+
raise_error(Geocoder::RequestDenied) ||
|
|
56
|
+
Geocoder.log(:warn, "Geocoding API error: 403 API key does not exist")
|
|
57
|
+
else
|
|
58
|
+
super(response)
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
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,47 +8,29 @@ module Geocoder::Lookup
|
|
|
8
8
|
"Ipinfo.io"
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
if configuration.api_key
|
|
13
|
-
"#{protocol}://ipinfo.io/#{query.sanitized_text}/geo?" + url_query_string(query)
|
|
14
|
-
else
|
|
15
|
-
"#{protocol}://ipinfo.io/#{query.sanitized_text}/geo"
|
|
16
|
-
end
|
|
17
|
-
end
|
|
11
|
+
private # ---------------------------------------------------------------
|
|
18
12
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
if configuration.api_key
|
|
22
|
-
|
|
23
|
-
else
|
|
24
|
-
[:http]
|
|
25
|
-
end
|
|
13
|
+
def base_query_url(query)
|
|
14
|
+
url = "#{protocol}://ipinfo.io/#{query.sanitized_text}/geo"
|
|
15
|
+
url << "?" if configuration.api_key
|
|
16
|
+
url
|
|
26
17
|
end
|
|
27
18
|
|
|
28
|
-
private # ---------------------------------------------------------------
|
|
29
|
-
|
|
30
19
|
def results(query)
|
|
31
|
-
# don't look up a loopback address, just return the stored result
|
|
32
|
-
return [reserved_result(query.text)] if query.
|
|
33
|
-
|
|
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?
|
|
22
|
+
|
|
23
|
+
if !(doc = fetch_data(query)).is_a?(Hash) or doc['error']
|
|
34
24
|
[]
|
|
35
25
|
else
|
|
36
26
|
[doc]
|
|
37
27
|
end
|
|
38
28
|
end
|
|
39
29
|
|
|
40
|
-
def empty_result?(doc)
|
|
41
|
-
!doc.is_a?(Hash) or doc.keys == ["ip"]
|
|
42
|
-
end
|
|
43
|
-
|
|
44
30
|
def reserved_result(ip)
|
|
45
31
|
{
|
|
46
|
-
"ip"
|
|
47
|
-
"
|
|
48
|
-
"region" => "",
|
|
49
|
-
"country" => "",
|
|
50
|
-
"loc" => "0,0",
|
|
51
|
-
"postal" => ""
|
|
32
|
+
"ip" => ip,
|
|
33
|
+
"bogon" => true
|
|
52
34
|
}
|
|
53
35
|
end
|
|
54
36
|
|
|
@@ -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
|