geocoder 1.2.6 → 1.8.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 +266 -1
- data/LICENSE +1 -1
- data/README.md +530 -804
- data/bin/console +13 -0
- data/examples/app_defined_lookup_services.rb +22 -0
- data/examples/reverse_geocode_job.rb +40 -0
- data/lib/easting_northing.rb +171 -0
- data/lib/generators/geocoder/config/templates/initializer.rb +22 -16
- 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 +20 -33
- data/lib/geocoder/cache_stores/base.rb +40 -0
- data/lib/geocoder/cache_stores/generic.rb +35 -0
- data/lib/geocoder/cache_stores/redis.rb +34 -0
- data/lib/geocoder/calculations.rb +30 -38
- data/lib/geocoder/cli.rb +2 -2
- data/lib/geocoder/configuration.rb +36 -9
- data/lib/geocoder/configuration_hash.rb +4 -4
- data/lib/geocoder/esri_token.rb +38 -0
- data/lib/geocoder/exceptions.rb +19 -0
- data/lib/geocoder/ip_address.rb +26 -11
- data/lib/geocoder/kernel_logger.rb +25 -0
- data/lib/geocoder/logger.rb +47 -0
- data/lib/geocoder/lookup.rb +63 -13
- data/lib/geocoder/lookups/abstract_api.rb +46 -0
- data/lib/geocoder/lookups/amap.rb +63 -0
- data/lib/geocoder/lookups/amazon_location_service.rb +55 -0
- data/lib/geocoder/lookups/baidu.rb +17 -9
- data/lib/geocoder/lookups/baidu_ip.rb +7 -31
- data/lib/geocoder/lookups/ban_data_gouv_fr.rb +143 -0
- data/lib/geocoder/lookups/base.rb +75 -26
- data/lib/geocoder/lookups/bing.rb +38 -15
- data/lib/geocoder/lookups/db_ip_com.rb +52 -0
- data/lib/geocoder/lookups/dstk.rb +4 -2
- data/lib/geocoder/lookups/esri.rb +78 -12
- data/lib/geocoder/lookups/freegeoip.rb +22 -7
- data/lib/geocoder/lookups/geoapify.rb +78 -0
- data/lib/geocoder/lookups/geocoder_ca.rb +5 -6
- data/lib/geocoder/lookups/geocodio.rb +8 -8
- data/lib/geocoder/lookups/geoip2.rb +13 -4
- data/lib/geocoder/lookups/geoportail_lu.rb +65 -0
- data/lib/geocoder/lookups/google.rb +44 -11
- data/lib/geocoder/lookups/google_places_details.rb +31 -17
- data/lib/geocoder/lookups/google_places_search.rb +76 -0
- data/lib/geocoder/lookups/google_premier.rb +15 -1
- data/lib/geocoder/lookups/here.rb +38 -27
- data/lib/geocoder/lookups/ip2location.rb +71 -0
- data/lib/geocoder/lookups/ipapi_com.rb +82 -0
- data/lib/geocoder/lookups/ipbase.rb +49 -0
- data/lib/geocoder/lookups/ipdata_co.rb +62 -0
- data/lib/geocoder/lookups/ipgeolocation.rb +51 -0
- data/lib/geocoder/lookups/ipinfo_io.rb +44 -0
- data/lib/geocoder/lookups/ipqualityscore.rb +50 -0
- data/lib/geocoder/lookups/ipregistry.rb +68 -0
- data/lib/geocoder/lookups/ipstack.rb +63 -0
- data/lib/geocoder/lookups/latlon.rb +58 -0
- data/lib/geocoder/lookups/location_iq.rb +54 -0
- data/lib/geocoder/lookups/mapbox.rb +59 -0
- data/lib/geocoder/lookups/mapquest.rb +7 -9
- data/lib/geocoder/lookups/maxmind.rb +7 -7
- data/lib/geocoder/lookups/maxmind_geoip2.rb +70 -0
- data/lib/geocoder/lookups/maxmind_local.rb +16 -3
- data/lib/geocoder/lookups/melissa_street.rb +41 -0
- data/lib/geocoder/lookups/nationaal_georegister_nl.rb +38 -0
- data/lib/geocoder/lookups/nominatim.rb +18 -6
- data/lib/geocoder/lookups/opencagedata.rb +16 -9
- data/lib/geocoder/lookups/osmnames.rb +57 -0
- data/lib/geocoder/lookups/pc_miler.rb +85 -0
- data/lib/geocoder/lookups/pelias.rb +63 -0
- data/lib/geocoder/lookups/photon.rb +89 -0
- data/lib/geocoder/lookups/pickpoint.rb +41 -0
- data/lib/geocoder/lookups/pointpin.rb +14 -13
- data/lib/geocoder/lookups/postcode_anywhere_uk.rb +7 -8
- data/lib/geocoder/lookups/postcodes_io.rb +31 -0
- data/lib/geocoder/lookups/smarty_streets.rb +29 -6
- data/lib/geocoder/lookups/telize.rb +42 -7
- data/lib/geocoder/lookups/tencent.rb +59 -0
- data/lib/geocoder/lookups/test.rb +5 -0
- data/lib/geocoder/lookups/twogis.rb +58 -0
- data/lib/geocoder/lookups/uk_ordnance_survey_names.rb +59 -0
- data/lib/geocoder/lookups/yandex.rb +20 -13
- data/lib/geocoder/models/active_record.rb +4 -3
- data/lib/geocoder/models/mongo_base.rb +0 -2
- data/lib/geocoder/query.rb +15 -1
- data/lib/geocoder/railtie.rb +1 -1
- data/lib/geocoder/request.rb +103 -14
- data/lib/geocoder/results/abstract_api.rb +146 -0
- data/lib/geocoder/results/amap.rb +87 -0
- data/lib/geocoder/results/amazon_location_service.rb +57 -0
- data/lib/geocoder/results/baidu.rb +10 -14
- data/lib/geocoder/results/ban_data_gouv_fr.rb +282 -0
- data/lib/geocoder/results/base.rb +13 -1
- data/lib/geocoder/results/bing.rb +5 -1
- data/lib/geocoder/results/db_ip_com.rb +58 -0
- data/lib/geocoder/results/esri.rb +35 -8
- data/lib/geocoder/results/freegeoip.rb +2 -7
- data/lib/geocoder/results/geoapify.rb +179 -0
- data/lib/geocoder/results/geocoder_ca.rb +3 -3
- data/lib/geocoder/results/geocodio.rb +15 -3
- data/lib/geocoder/results/geoip2.rb +37 -25
- data/lib/geocoder/results/geoportail_lu.rb +71 -0
- data/lib/geocoder/results/google.rb +26 -0
- data/lib/geocoder/results/google_places_details.rb +4 -0
- data/lib/geocoder/results/google_places_search.rb +52 -0
- data/lib/geocoder/results/here.rb +30 -15
- data/lib/geocoder/results/ip2location.rb +22 -0
- data/lib/geocoder/results/ipapi_com.rb +45 -0
- data/lib/geocoder/results/ipbase.rb +40 -0
- data/lib/geocoder/results/ipdata_co.rb +40 -0
- data/lib/geocoder/results/ipgeolocation.rb +59 -0
- data/lib/geocoder/results/ipinfo_io.rb +48 -0
- data/lib/geocoder/results/ipqualityscore.rb +54 -0
- data/lib/geocoder/results/ipregistry.rb +304 -0
- data/lib/geocoder/results/ipstack.rb +60 -0
- data/lib/geocoder/results/latlon.rb +71 -0
- data/lib/geocoder/results/location_iq.rb +6 -0
- data/lib/geocoder/results/mapbox.rb +63 -0
- data/lib/geocoder/results/mapquest.rb +5 -8
- data/lib/geocoder/results/maxmind.rb +0 -5
- data/lib/geocoder/results/maxmind_geoip2.rb +9 -0
- data/lib/geocoder/results/maxmind_local.rb +0 -5
- data/lib/geocoder/results/melissa_street.rb +46 -0
- data/lib/geocoder/results/nationaal_georegister_nl.rb +62 -0
- data/lib/geocoder/results/nominatim.rb +41 -14
- data/lib/geocoder/results/opencagedata.rb +20 -2
- data/lib/geocoder/results/osmnames.rb +56 -0
- data/lib/geocoder/results/pc_miler.rb +98 -0
- data/lib/geocoder/results/pelias.rb +58 -0
- data/lib/geocoder/results/photon.rb +119 -0
- data/lib/geocoder/results/pickpoint.rb +6 -0
- data/lib/geocoder/results/pointpin.rb +0 -4
- 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/results/twogis.rb +76 -0
- data/lib/geocoder/results/uk_ordnance_survey_names.rb +59 -0
- data/lib/geocoder/results/yandex.rb +240 -32
- data/lib/geocoder/sql.rb +9 -6
- data/lib/geocoder/stores/active_record.rb +49 -10
- data/lib/geocoder/stores/base.rb +2 -14
- data/lib/geocoder/stores/mongo_base.rb +0 -31
- data/lib/geocoder/util.rb +29 -0
- data/lib/geocoder/version.rb +1 -1
- data/lib/geocoder.rb +2 -1
- data/lib/maxmind_database.rb +9 -9
- data/lib/tasks/geocoder.rake +29 -4
- data/lib/tasks/maxmind.rake +1 -1
- metadata +91 -169
- data/.gitignore +0 -6
- data/.travis.yml +0 -31
- data/Rakefile +0 -25
- data/examples/autoexpire_cache_dalli.rb +0 -62
- data/examples/autoexpire_cache_redis.rb +0 -28
- data/gemfiles/Gemfile.mongoid-2.4.x +0 -16
- data/lib/geocoder/lookups/geocoder_us.rb +0 -39
- data/lib/geocoder/lookups/okf.rb +0 -43
- data/lib/geocoder/lookups/ovi.rb +0 -62
- data/lib/geocoder/lookups/yahoo.rb +0 -88
- data/lib/geocoder/results/geocoder_us.rb +0 -39
- data/lib/geocoder/results/okf.rb +0 -106
- data/lib/geocoder/results/ovi.rb +0 -62
- data/lib/geocoder/results/yahoo.rb +0 -55
- data/lib/hash_recursive_merge.rb +0 -74
- data/lib/oauth_util.rb +0 -112
- data/test/fixtures/baidu_invalid_key +0 -1
- data/test/fixtures/baidu_ip_202_198_16_3 +0 -19
- data/test/fixtures/baidu_ip_invalid_key +0 -1
- data/test/fixtures/baidu_ip_no_results +0 -1
- data/test/fixtures/baidu_no_results +0 -1
- data/test/fixtures/baidu_reverse +0 -1
- data/test/fixtures/baidu_shanghai_pearl_tower +0 -12
- data/test/fixtures/bing_invalid_key +0 -1
- data/test/fixtures/bing_madison_square_garden +0 -40
- data/test/fixtures/bing_no_results +0 -16
- data/test/fixtures/bing_reverse +0 -42
- data/test/fixtures/cloudmade_invalid_key +0 -1
- data/test/fixtures/cloudmade_madison_square_garden +0 -1
- data/test/fixtures/cloudmade_no_results +0 -1
- data/test/fixtures/esri_madison_square_garden +0 -59
- data/test/fixtures/esri_no_results +0 -8
- data/test/fixtures/esri_reverse +0 -21
- data/test/fixtures/freegeoip_74_200_247_59 +0 -12
- data/test/fixtures/freegeoip_no_results +0 -1
- data/test/fixtures/geocoder_ca_madison_square_garden +0 -1
- data/test/fixtures/geocoder_ca_no_results +0 -1
- data/test/fixtures/geocoder_ca_reverse +0 -34
- data/test/fixtures/geocoder_us_madison_square_garden +0 -1
- data/test/fixtures/geocoder_us_no_results +0 -1
- data/test/fixtures/geocodio_1101_pennsylvania_ave +0 -1
- data/test/fixtures/geocodio_bad_api_key +0 -3
- data/test/fixtures/geocodio_invalid +0 -4
- data/test/fixtures/geocodio_no_results +0 -1
- data/test/fixtures/geocodio_over_query_limit +0 -4
- data/test/fixtures/google_garbage +0 -456
- data/test/fixtures/google_madison_square_garden +0 -57
- data/test/fixtures/google_no_city_data +0 -44
- data/test/fixtures/google_no_locality +0 -51
- data/test/fixtures/google_no_results +0 -4
- data/test/fixtures/google_over_limit +0 -4
- data/test/fixtures/google_places_details_invalid_request +0 -4
- data/test/fixtures/google_places_details_madison_square_garden +0 -120
- data/test/fixtures/google_places_details_no_results +0 -4
- data/test/fixtures/google_places_details_no_reviews +0 -60
- data/test/fixtures/google_places_details_no_types +0 -66
- data/test/fixtures/here_madison_square_garden +0 -72
- data/test/fixtures/here_no_results +0 -8
- data/test/fixtures/mapquest_error +0 -16
- data/test/fixtures/mapquest_invalid_api_key +0 -16
- data/test/fixtures/mapquest_invalid_request +0 -16
- data/test/fixtures/mapquest_madison_square_garden +0 -52
- data/test/fixtures/mapquest_no_results +0 -16
- data/test/fixtures/maxmind_24_24_24_21 +0 -1
- data/test/fixtures/maxmind_24_24_24_22 +0 -1
- data/test/fixtures/maxmind_24_24_24_23 +0 -1
- data/test/fixtures/maxmind_24_24_24_24 +0 -1
- data/test/fixtures/maxmind_74_200_247_59 +0 -1
- data/test/fixtures/maxmind_invalid_key +0 -1
- data/test/fixtures/maxmind_no_results +0 -1
- data/test/fixtures/nominatim_madison_square_garden +0 -150
- data/test/fixtures/nominatim_no_results +0 -1
- data/test/fixtures/nominatim_over_limit +0 -1
- data/test/fixtures/okf_kirstinmaki +0 -67
- data/test/fixtures/okf_no_results +0 -4
- data/test/fixtures/opencagedata_invalid_api_key +0 -25
- data/test/fixtures/opencagedata_invalid_request +0 -26
- data/test/fixtures/opencagedata_madison_square_garden +0 -73
- data/test/fixtures/opencagedata_no_results +0 -29
- data/test/fixtures/opencagedata_over_limit +0 -31
- data/test/fixtures/ovi_madison_square_garden +0 -72
- data/test/fixtures/ovi_no_results +0 -8
- data/test/fixtures/pointpin_10_10_10_10 +0 -1
- data/test/fixtures/pointpin_555_555_555_555 +0 -1
- data/test/fixtures/pointpin_80_111_555_555 +0 -1
- data/test/fixtures/pointpin_no_results +0 -1
- data/test/fixtures/postcode_anywhere_uk_geocode_v2_00_WR26NJ +0 -1
- data/test/fixtures/postcode_anywhere_uk_geocode_v2_00_generic_error +0 -1
- data/test/fixtures/postcode_anywhere_uk_geocode_v2_00_hampshire +0 -1
- data/test/fixtures/postcode_anywhere_uk_geocode_v2_00_key_limit_exceeded +0 -1
- data/test/fixtures/postcode_anywhere_uk_geocode_v2_00_no_results +0 -1
- data/test/fixtures/postcode_anywhere_uk_geocode_v2_00_romsey +0 -1
- data/test/fixtures/postcode_anywhere_uk_geocode_v2_00_unknown_key +0 -1
- data/test/fixtures/smarty_streets_11211 +0 -1
- data/test/fixtures/smarty_streets_madison_square_garden +0 -47
- data/test/fixtures/smarty_streets_no_results +0 -1
- data/test/fixtures/telize_10_10_10_10 +0 -1
- data/test/fixtures/telize_555_555_555_555 +0 -4
- data/test/fixtures/telize_74_200_247_59 +0 -1
- data/test/fixtures/telize_no_results +0 -1
- data/test/fixtures/yahoo_error +0 -1
- data/test/fixtures/yahoo_invalid_key +0 -2
- data/test/fixtures/yahoo_madison_square_garden +0 -52
- data/test/fixtures/yahoo_no_results +0 -10
- data/test/fixtures/yahoo_over_limit +0 -2
- data/test/fixtures/yandex_canada_rue_dupuis_14 +0 -446
- data/test/fixtures/yandex_invalid_key +0 -1
- data/test/fixtures/yandex_kremlin +0 -48
- data/test/fixtures/yandex_new_york +0 -1
- data/test/fixtures/yandex_no_city_and_town +0 -112
- data/test/fixtures/yandex_no_results +0 -16
- data/test/integration/http_client_test.rb +0 -31
- data/test/mongoid_test_helper.rb +0 -43
- data/test/test_helper.rb +0 -416
- data/test/unit/active_record_test.rb +0 -16
- data/test/unit/cache_test.rb +0 -37
- data/test/unit/calculations_test.rb +0 -220
- data/test/unit/configuration_test.rb +0 -55
- data/test/unit/error_handling_test.rb +0 -56
- data/test/unit/geocoder_test.rb +0 -78
- data/test/unit/https_test.rb +0 -17
- data/test/unit/ip_address_test.rb +0 -27
- data/test/unit/lookup_test.rb +0 -153
- data/test/unit/lookups/bing_test.rb +0 -68
- data/test/unit/lookups/dstk_test.rb +0 -26
- data/test/unit/lookups/esri_test.rb +0 -48
- data/test/unit/lookups/freegeoip_test.rb +0 -27
- data/test/unit/lookups/geocoder_ca_test.rb +0 -17
- data/test/unit/lookups/geocodio_test.rb +0 -55
- data/test/unit/lookups/geoip2_test.rb +0 -27
- data/test/unit/lookups/google_places_details_test.rb +0 -122
- data/test/unit/lookups/google_premier_test.rb +0 -22
- data/test/unit/lookups/google_test.rb +0 -84
- data/test/unit/lookups/mapquest_test.rb +0 -60
- data/test/unit/lookups/maxmind_local_test.rb +0 -28
- data/test/unit/lookups/maxmind_test.rb +0 -63
- data/test/unit/lookups/nominatim_test.rb +0 -31
- data/test/unit/lookups/okf_test.rb +0 -38
- data/test/unit/lookups/opencagedata_test.rb +0 -64
- data/test/unit/lookups/pointpin_test.rb +0 -30
- data/test/unit/lookups/postcode_anywhere_uk_test.rb +0 -70
- data/test/unit/lookups/smarty_streets_test.rb +0 -71
- data/test/unit/lookups/telize_test.rb +0 -36
- data/test/unit/lookups/yahoo_test.rb +0 -35
- data/test/unit/method_aliases_test.rb +0 -26
- data/test/unit/model_test.rb +0 -38
- data/test/unit/mongoid_test.rb +0 -47
- data/test/unit/near_test.rb +0 -87
- data/test/unit/oauth_util_test.rb +0 -31
- data/test/unit/proxy_test.rb +0 -37
- data/test/unit/query_test.rb +0 -52
- data/test/unit/rake_task_test.rb +0 -21
- data/test/unit/request_test.rb +0 -35
- data/test/unit/result_test.rb +0 -72
- data/test/unit/test_mode_test.rb +0 -70
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
require "geocoder/lookups/google"
|
|
2
|
+
require "geocoder/results/google_places_search"
|
|
3
|
+
|
|
4
|
+
module Geocoder
|
|
5
|
+
module Lookup
|
|
6
|
+
class GooglePlacesSearch < Google
|
|
7
|
+
def name
|
|
8
|
+
"Google Places Search"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def required_api_key_parts
|
|
12
|
+
["key"]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def supported_protocols
|
|
16
|
+
[:https]
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
def result_root_attr
|
|
22
|
+
'candidates'
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def base_query_url(query)
|
|
26
|
+
"#{protocol}://maps.googleapis.com/maps/api/place/findplacefromtext/json?"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def query_url_google_params(query)
|
|
30
|
+
{
|
|
31
|
+
input: query.text,
|
|
32
|
+
inputtype: 'textquery',
|
|
33
|
+
fields: fields(query),
|
|
34
|
+
locationbias: locationbias(query),
|
|
35
|
+
language: query.language || configuration.language
|
|
36
|
+
}
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def fields(query)
|
|
40
|
+
if query.options.has_key?(:fields)
|
|
41
|
+
return format_fields(query.options[:fields])
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
if configuration.has_key?(:fields)
|
|
45
|
+
return format_fields(configuration[:fields])
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
default_fields
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def default_fields
|
|
52
|
+
legacy = %w[id reference]
|
|
53
|
+
basic = %w[business_status formatted_address geometry icon name
|
|
54
|
+
photos place_id plus_code types]
|
|
55
|
+
contact = %w[opening_hours]
|
|
56
|
+
atmosphere = %W[price_level rating user_ratings_total]
|
|
57
|
+
format_fields(legacy, basic, contact, atmosphere)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def format_fields(*fields)
|
|
61
|
+
flattened = fields.flatten.compact
|
|
62
|
+
return if flattened.empty?
|
|
63
|
+
|
|
64
|
+
flattened.join(',')
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def locationbias(query)
|
|
68
|
+
if query.options.has_key?(:locationbias)
|
|
69
|
+
query.options[:locationbias]
|
|
70
|
+
else
|
|
71
|
+
configuration[:locationbias]
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
@@ -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,20 @@ module Geocoder::Lookup
|
|
|
21
21
|
|
|
22
22
|
private # ---------------------------------------------------------------
|
|
23
23
|
|
|
24
|
+
def result_root_attr
|
|
25
|
+
'results'
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def cache_key(query)
|
|
29
|
+
"#{protocol}://maps.googleapis.com/maps/api/geocode/json?" + hash_to_query(cache_key_params(query))
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def cache_key_params(query)
|
|
33
|
+
query_url_google_params(query).merge(super).reject do |k,v|
|
|
34
|
+
[:key, :client, :channel].include?(k)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
24
38
|
def query_url_params(query)
|
|
25
39
|
query_url_google_params(query).merge(super).merge(
|
|
26
40
|
:key => nil, # don't use param inherited from Google lookup
|
|
@@ -9,54 +9,65 @@ 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
|
+
service = query.reverse_geocode? ? "revgeocode" : "geocode"
|
|
23
|
+
|
|
24
|
+
"#{protocol}://#{service}.search.hereapi.com/v1/#{service}?"
|
|
25
|
+
end
|
|
26
|
+
|
|
21
27
|
def results(query)
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
return [] if r.nil? || !r.is_a?(Array) || r.empty?
|
|
26
|
-
return r.first['Result']
|
|
28
|
+
unless configuration.api_key.is_a?(String)
|
|
29
|
+
api_key_not_string!
|
|
30
|
+
return []
|
|
27
31
|
end
|
|
28
|
-
[]
|
|
32
|
+
return [] unless doc = fetch_data(query)
|
|
33
|
+
return [] if doc["items"].nil?
|
|
34
|
+
|
|
35
|
+
doc["items"]
|
|
29
36
|
end
|
|
30
37
|
|
|
31
|
-
def
|
|
38
|
+
def query_url_here_options(query, reverse_geocode)
|
|
32
39
|
options = {
|
|
33
|
-
:
|
|
34
|
-
:
|
|
35
|
-
:app_code=>api_code
|
|
40
|
+
apiKey: configuration.api_key,
|
|
41
|
+
lang: (query.language || configuration.language)
|
|
36
42
|
}
|
|
43
|
+
return options if reverse_geocode
|
|
37
44
|
|
|
45
|
+
unless (country = query.options[:country]).nil?
|
|
46
|
+
options[:in] = "countryCode:#{country}"
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
options
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def query_url_params(query)
|
|
38
53
|
if query.reverse_geocode?
|
|
39
|
-
super.merge(
|
|
40
|
-
:
|
|
41
|
-
:mode=>:retrieveAddresses
|
|
54
|
+
super.merge(query_url_here_options(query, true)).merge(
|
|
55
|
+
at: query.sanitized_text
|
|
42
56
|
)
|
|
43
57
|
else
|
|
44
|
-
super.merge(
|
|
45
|
-
:
|
|
58
|
+
super.merge(query_url_here_options(query, false)).merge(
|
|
59
|
+
q: query.sanitized_text
|
|
46
60
|
)
|
|
47
61
|
end
|
|
48
62
|
end
|
|
49
63
|
|
|
50
|
-
def
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
64
|
+
def api_key_not_string!
|
|
65
|
+
msg = <<~MSG
|
|
66
|
+
API key for HERE Geocoding and Search API should be a string.
|
|
67
|
+
For more info on how to obtain it, please see https://developer.here.com/documentation/identity-access-management/dev_guide/topics/plat-using-apikeys.html
|
|
68
|
+
MSG
|
|
55
69
|
|
|
56
|
-
|
|
57
|
-
if a=configuration.api_key
|
|
58
|
-
return a.last if a.is_a?(Array)
|
|
59
|
-
end
|
|
70
|
+
raise_error(Geocoder::ConfigurationError, msg) || Geocoder.log(:warn, msg)
|
|
60
71
|
end
|
|
61
72
|
end
|
|
62
73
|
end
|
|
@@ -0,0 +1,71 @@
|
|
|
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 required_api_key_parts
|
|
12
|
+
['key']
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def supported_protocols
|
|
16
|
+
[:http, :https]
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private # ----------------------------------------------------------------
|
|
20
|
+
|
|
21
|
+
def base_query_url(query)
|
|
22
|
+
"#{protocol}://api.ip2location.com/v2/?"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def query_url_params(query)
|
|
26
|
+
super.merge(
|
|
27
|
+
key: configuration.api_key,
|
|
28
|
+
ip: query.sanitized_text,
|
|
29
|
+
package: configuration[:package],
|
|
30
|
+
)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def results(query)
|
|
34
|
+
# don't look up a loopback or private address, just return the stored result
|
|
35
|
+
return [reserved_result(query.text)] if query.internal_ip_address?
|
|
36
|
+
return [] unless doc = fetch_data(query)
|
|
37
|
+
if doc["response"] == "INVALID ACCOUNT"
|
|
38
|
+
raise_error(Geocoder::InvalidApiKey) || Geocoder.log(:warn, "INVALID ACCOUNT")
|
|
39
|
+
return []
|
|
40
|
+
else
|
|
41
|
+
return [doc]
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def reserved_result(query)
|
|
46
|
+
{
|
|
47
|
+
"country_code" => "INVALID IP ADDRESS",
|
|
48
|
+
"country_name" => "INVALID IP ADDRESS",
|
|
49
|
+
"region_name" => "INVALID IP ADDRESS",
|
|
50
|
+
"city_name" => "INVALID IP ADDRESS",
|
|
51
|
+
"latitude" => "INVALID IP ADDRESS",
|
|
52
|
+
"longitude" => "INVALID IP ADDRESS",
|
|
53
|
+
"zip_code" => "INVALID IP ADDRESS",
|
|
54
|
+
"time_zone" => "INVALID IP ADDRESS",
|
|
55
|
+
"isp" => "INVALID IP ADDRESS",
|
|
56
|
+
"domain" => "INVALID IP ADDRESS",
|
|
57
|
+
"net_speed" => "INVALID IP ADDRESS",
|
|
58
|
+
"idd_code" => "INVALID IP ADDRESS",
|
|
59
|
+
"area_code" => "INVALID IP ADDRESS",
|
|
60
|
+
"weather_station_code" => "INVALID IP ADDRESS",
|
|
61
|
+
"weather_station_name" => "INVALID IP ADDRESS",
|
|
62
|
+
"mcc" => "INVALID IP ADDRESS",
|
|
63
|
+
"mnc" => "INVALID IP ADDRESS",
|
|
64
|
+
"mobile_brand" => "INVALID IP ADDRESS",
|
|
65
|
+
"elevation" => "INVALID IP ADDRESS",
|
|
66
|
+
"usage_type" => "INVALID IP ADDRESS"
|
|
67
|
+
}
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
end
|
|
71
|
+
end
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
require 'geocoder/lookups/base'
|
|
2
|
+
require 'geocoder/results/ipapi_com'
|
|
3
|
+
|
|
4
|
+
module Geocoder::Lookup
|
|
5
|
+
class IpapiCom < Base
|
|
6
|
+
|
|
7
|
+
def name
|
|
8
|
+
"ip-api.com"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def supported_protocols
|
|
12
|
+
if configuration.api_key
|
|
13
|
+
[:http, :https]
|
|
14
|
+
else
|
|
15
|
+
[:http]
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private # ----------------------------------------------------------------
|
|
20
|
+
|
|
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
|
|
27
|
+
|
|
28
|
+
def parse_raw_data(raw_data)
|
|
29
|
+
if raw_data.chomp == "invalid key"
|
|
30
|
+
invalid_key_result
|
|
31
|
+
else
|
|
32
|
+
super(raw_data)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def results(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
|
+
|
|
40
|
+
return [] unless doc = fetch_data(query)
|
|
41
|
+
|
|
42
|
+
if doc["message"] == "invalid key"
|
|
43
|
+
raise_error(Geocoder::InvalidApiKey) || Geocoder.log(:warn, "Invalid API key.")
|
|
44
|
+
return []
|
|
45
|
+
else
|
|
46
|
+
return [doc]
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def reserved_result(query)
|
|
51
|
+
{
|
|
52
|
+
"message" => "reserved range",
|
|
53
|
+
"query" => query,
|
|
54
|
+
"status" => "fail",
|
|
55
|
+
"ip" => query,
|
|
56
|
+
"city" => "",
|
|
57
|
+
"region_code" => "",
|
|
58
|
+
"region_name" => "",
|
|
59
|
+
"metrocode" => "",
|
|
60
|
+
"zipcode" => "",
|
|
61
|
+
"latitude" => "0",
|
|
62
|
+
"longitude" => "0",
|
|
63
|
+
"country_name" => "Reserved",
|
|
64
|
+
"country_code" => "RD"
|
|
65
|
+
}
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def invalid_key_result
|
|
69
|
+
{
|
|
70
|
+
"message" => "invalid key"
|
|
71
|
+
}
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def query_url_params(query)
|
|
75
|
+
params = {}
|
|
76
|
+
params.merge!(fields: configuration[:fields]) if configuration.has_key?(:fields)
|
|
77
|
+
params.merge!(key: configuration.api_key) if configuration.api_key
|
|
78
|
+
params.merge(super)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
end
|
|
82
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
require 'geocoder/lookups/base'
|
|
2
|
+
require 'geocoder/results/ipbase'
|
|
3
|
+
|
|
4
|
+
module Geocoder::Lookup
|
|
5
|
+
class Ipbase < Base
|
|
6
|
+
|
|
7
|
+
def name
|
|
8
|
+
"ipbase.com"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def supported_protocols
|
|
12
|
+
[:https]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
private # ---------------------------------------------------------------
|
|
16
|
+
|
|
17
|
+
def base_query_url(query)
|
|
18
|
+
"https://api.ipbase.com/v2/info?"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def query_url_params(query)
|
|
22
|
+
{
|
|
23
|
+
:ip => query.sanitized_text,
|
|
24
|
+
:apikey => configuration.api_key
|
|
25
|
+
}
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def results(query)
|
|
29
|
+
# don't look up a loopback or private address, just return the stored result
|
|
30
|
+
return [reserved_result(query.text)] if query.internal_ip_address?
|
|
31
|
+
doc = fetch_data(query) || {}
|
|
32
|
+
doc.fetch("data", {})["location"] ? [doc] : []
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def reserved_result(ip)
|
|
36
|
+
{
|
|
37
|
+
"data" => {
|
|
38
|
+
"ip" => ip,
|
|
39
|
+
"location" => {
|
|
40
|
+
"city" => { "name" => "" },
|
|
41
|
+
"country" => { "alpha2" => "RD", "name" => "Reserved" },
|
|
42
|
+
"region" => { "alpha2" => "", "name" => "" },
|
|
43
|
+
"zip" => ""
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -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
|
+
configuration[:host] || "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
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
require 'geocoder/lookups/base'
|
|
2
|
+
require 'geocoder/results/ipinfo_io'
|
|
3
|
+
|
|
4
|
+
module Geocoder::Lookup
|
|
5
|
+
class IpinfoIo < Base
|
|
6
|
+
|
|
7
|
+
def name
|
|
8
|
+
"Ipinfo.io"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
private # ---------------------------------------------------------------
|
|
12
|
+
|
|
13
|
+
def base_query_url(query)
|
|
14
|
+
url = "#{protocol}://ipinfo.io/#{query.sanitized_text}/geo"
|
|
15
|
+
url << "?" if configuration.api_key
|
|
16
|
+
url
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def results(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?
|
|
22
|
+
|
|
23
|
+
if !(doc = fetch_data(query)).is_a?(Hash) or doc['error']
|
|
24
|
+
[]
|
|
25
|
+
else
|
|
26
|
+
[doc]
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def reserved_result(ip)
|
|
31
|
+
{
|
|
32
|
+
"ip" => ip,
|
|
33
|
+
"bogon" => true
|
|
34
|
+
}
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def query_url_params(query)
|
|
38
|
+
{
|
|
39
|
+
token: configuration.api_key
|
|
40
|
+
}.merge(super)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'geocoder/lookups/base'
|
|
4
|
+
require 'geocoder/results/ipqualityscore'
|
|
5
|
+
|
|
6
|
+
module Geocoder::Lookup
|
|
7
|
+
class Ipqualityscore < Base
|
|
8
|
+
|
|
9
|
+
def name
|
|
10
|
+
"IPQualityScore"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def required_api_key_parts
|
|
14
|
+
['api_key']
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
private # ---------------------------------------------------------------
|
|
18
|
+
|
|
19
|
+
def base_query_url(query)
|
|
20
|
+
"#{protocol}://ipqualityscore.com/api/json/ip/#{configuration.api_key}/#{query.sanitized_text}?"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def valid_response?(response)
|
|
24
|
+
if (json = parse_json(response.body))
|
|
25
|
+
success = json['success']
|
|
26
|
+
end
|
|
27
|
+
super && success == true
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def results(query, reverse = false)
|
|
31
|
+
return [] unless doc = fetch_data(query)
|
|
32
|
+
|
|
33
|
+
return [doc] if doc['success']
|
|
34
|
+
|
|
35
|
+
case doc['message']
|
|
36
|
+
when /invalid (.*) key/i
|
|
37
|
+
raise_error Geocoder::InvalidApiKey ||
|
|
38
|
+
Geocoder.log(:warn, "#{name} API error: invalid api key.")
|
|
39
|
+
when /insufficient credits/, /exceeded your request quota/
|
|
40
|
+
raise_error Geocoder::OverQueryLimitError ||
|
|
41
|
+
Geocoder.log(:warn, "#{name} API error: query limit exceeded.")
|
|
42
|
+
when /invalid (.*) address/i
|
|
43
|
+
raise_error Geocoder::InvalidRequest ||
|
|
44
|
+
Geocoder.log(:warn, "#{name} API error: invalid request.")
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
[doc]
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -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
|