geocoder 1.4.9 → 1.6.7

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.
Files changed (107) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +60 -0
  3. data/LICENSE +1 -1
  4. data/README.md +350 -979
  5. data/bin/console +13 -0
  6. data/examples/autoexpire_cache_redis.rb +2 -0
  7. data/lib/easting_northing.rb +171 -0
  8. data/lib/generators/geocoder/config/templates/initializer.rb +1 -1
  9. data/lib/geocoder/cache.rb +4 -0
  10. data/lib/geocoder/calculations.rb +1 -1
  11. data/lib/geocoder/cli.rb +2 -2
  12. data/lib/geocoder/configuration.rb +3 -2
  13. data/lib/geocoder/configuration_hash.rb +4 -4
  14. data/lib/geocoder/exceptions.rb +1 -1
  15. data/lib/geocoder/ip_address.rb +16 -2
  16. data/lib/geocoder/lookup.rb +9 -5
  17. data/lib/geocoder/lookups/abstract_api.rb +46 -0
  18. data/lib/geocoder/lookups/amap.rb +7 -3
  19. data/lib/geocoder/lookups/baidu.rb +14 -10
  20. data/lib/geocoder/lookups/baidu_ip.rb +7 -36
  21. data/lib/geocoder/lookups/ban_data_gouv_fr.rb +18 -5
  22. data/lib/geocoder/lookups/base.rb +27 -4
  23. data/lib/geocoder/lookups/bing.rb +10 -13
  24. data/lib/geocoder/lookups/db_ip_com.rb +9 -6
  25. data/lib/geocoder/lookups/dstk.rb +4 -2
  26. data/lib/geocoder/lookups/esri.rb +44 -28
  27. data/lib/geocoder/lookups/freegeoip.rb +11 -7
  28. data/lib/geocoder/lookups/geocoder_ca.rb +4 -4
  29. data/lib/geocoder/lookups/geocodio.rb +5 -5
  30. data/lib/geocoder/lookups/geoportail_lu.rb +7 -7
  31. data/lib/geocoder/lookups/google.rb +15 -10
  32. data/lib/geocoder/lookups/google_places_details.rb +11 -17
  33. data/lib/geocoder/lookups/google_places_search.rb +30 -4
  34. data/lib/geocoder/lookups/google_premier.rb +14 -0
  35. data/lib/geocoder/lookups/here.rb +29 -23
  36. data/lib/geocoder/lookups/ip2location.rb +67 -0
  37. data/lib/geocoder/lookups/ipapi_com.rb +9 -13
  38. data/lib/geocoder/lookups/ipdata_co.rb +9 -4
  39. data/lib/geocoder/lookups/ipgeolocation.rb +51 -0
  40. data/lib/geocoder/lookups/ipinfo_io.rb +11 -29
  41. data/lib/geocoder/lookups/ipregistry.rb +68 -0
  42. data/lib/geocoder/lookups/ipstack.rb +11 -12
  43. data/lib/geocoder/lookups/latlon.rb +5 -6
  44. data/lib/geocoder/lookups/location_iq.rb +10 -4
  45. data/lib/geocoder/lookups/mapbox.rb +7 -6
  46. data/lib/geocoder/lookups/mapquest.rb +4 -5
  47. data/lib/geocoder/lookups/maxmind.rb +6 -6
  48. data/lib/geocoder/lookups/maxmind_geoip2.rb +8 -7
  49. data/lib/geocoder/lookups/maxmind_local.rb +7 -1
  50. data/lib/geocoder/lookups/nationaal_georegister_nl.rb +38 -0
  51. data/lib/geocoder/lookups/nominatim.rb +4 -4
  52. data/lib/geocoder/lookups/opencagedata.rb +6 -5
  53. data/lib/geocoder/lookups/osmnames.rb +57 -0
  54. data/lib/geocoder/lookups/pelias.rb +8 -9
  55. data/lib/geocoder/lookups/pickpoint.rb +9 -3
  56. data/lib/geocoder/lookups/pointpin.rb +10 -9
  57. data/lib/geocoder/lookups/postcode_anywhere_uk.rb +4 -5
  58. data/lib/geocoder/lookups/postcodes_io.rb +6 -3
  59. data/lib/geocoder/lookups/smarty_streets.rb +26 -11
  60. data/lib/geocoder/lookups/telize.rb +24 -4
  61. data/lib/geocoder/lookups/tencent.rb +59 -0
  62. data/lib/geocoder/lookups/test.rb +4 -0
  63. data/lib/geocoder/lookups/uk_ordnance_survey_names.rb +59 -0
  64. data/lib/geocoder/lookups/yandex.rb +7 -8
  65. data/lib/geocoder/query.rb +14 -0
  66. data/lib/geocoder/railtie.rb +1 -1
  67. data/lib/geocoder/results/abstract_api.rb +146 -0
  68. data/lib/geocoder/results/baidu.rb +10 -14
  69. data/lib/geocoder/results/ban_data_gouv_fr.rb +27 -2
  70. data/lib/geocoder/results/base.rb +13 -1
  71. data/lib/geocoder/results/bing.rb +1 -1
  72. data/lib/geocoder/results/db_ip_com.rb +1 -6
  73. data/lib/geocoder/results/freegeoip.rb +0 -5
  74. data/lib/geocoder/results/geocoder_ca.rb +3 -3
  75. data/lib/geocoder/results/geoip2.rb +0 -4
  76. data/lib/geocoder/results/geoportail_lu.rb +5 -3
  77. data/lib/geocoder/results/here.rb +4 -1
  78. data/lib/geocoder/results/ip2location.rb +22 -0
  79. data/lib/geocoder/results/ipdata_co.rb +0 -5
  80. data/lib/geocoder/results/ipgeolocation.rb +59 -0
  81. data/lib/geocoder/results/ipregistry.rb +304 -0
  82. data/lib/geocoder/results/maxmind.rb +0 -5
  83. data/lib/geocoder/results/maxmind_local.rb +0 -5
  84. data/lib/geocoder/results/nationaal_georegister_nl.rb +62 -0
  85. data/lib/geocoder/results/nominatim.rb +4 -0
  86. data/lib/geocoder/results/osmnames.rb +56 -0
  87. data/lib/geocoder/results/smarty_streets.rb +48 -18
  88. data/lib/geocoder/results/telize.rb +0 -5
  89. data/lib/geocoder/results/tencent.rb +72 -0
  90. data/lib/geocoder/results/test.rb +1 -1
  91. data/lib/geocoder/results/uk_ordnance_survey_names.rb +59 -0
  92. data/lib/geocoder/results/yandex.rb +217 -59
  93. data/lib/geocoder/sql.rb +4 -4
  94. data/lib/geocoder/stores/active_record.rb +1 -3
  95. data/lib/geocoder/util.rb +29 -0
  96. data/lib/geocoder/version.rb +1 -1
  97. data/lib/maxmind_database.rb +3 -3
  98. metadata +27 -23
  99. data/lib/geocoder/lookups/geocoder_us.rb +0 -43
  100. data/lib/geocoder/lookups/mapzen.rb +0 -15
  101. data/lib/geocoder/lookups/okf.rb +0 -44
  102. data/lib/geocoder/lookups/ovi.rb +0 -62
  103. data/lib/geocoder/results/geocoder_us.rb +0 -39
  104. data/lib/geocoder/results/mapzen.rb +0 -5
  105. data/lib/geocoder/results/okf.rb +0 -106
  106. data/lib/geocoder/results/ovi.rb +0 -71
  107. data/lib/hash_recursive_merge.rb +0 -74
@@ -8,12 +8,12 @@ module Geocoder::Lookup
8
8
  "Geocoder.ca"
9
9
  end
10
10
 
11
- def query_url(query)
12
- "#{protocol}://geocoder.ca/?" + url_query_string(query)
13
- end
14
-
15
11
  private # ---------------------------------------------------------------
16
12
 
13
+ def base_query_url(query)
14
+ "#{protocol}://geocoder.ca/?"
15
+ end
16
+
17
17
  def results(query)
18
18
  return [] unless doc = fetch_data(query)
19
19
  if doc['error'].nil?
@@ -8,11 +8,6 @@ module Geocoder::Lookup
8
8
  "Geocodio"
9
9
  end
10
10
 
11
- def query_url(query)
12
- path = query.reverse_geocode? ? "reverse" : "geocode"
13
- "#{protocol}://api.geocod.io/v1.3/#{path}?#{url_query_string(query)}"
14
- end
15
-
16
11
  def results(query)
17
12
  return [] unless doc = fetch_data(query)
18
13
  return doc["results"] if doc['error'].nil?
@@ -32,6 +27,11 @@ module Geocoder::Lookup
32
27
 
33
28
  private # ---------------------------------------------------------------
34
29
 
30
+ def base_query_url(query)
31
+ path = query.reverse_geocode? ? "reverse" : "geocode"
32
+ "#{protocol}://api.geocod.io/v1.6/#{path}?"
33
+ end
34
+
35
35
  def query_url_params(query)
36
36
  {
37
37
  :api_key => configuration.api_key,
@@ -9,14 +9,14 @@ module Geocoder
9
9
  "Geoportail.lu"
10
10
  end
11
11
 
12
- def query_url(query)
13
- url_base_path(query) + url_query_string(query)
14
- end
15
-
16
- private
12
+ private # ---------------------------------------------------------------
17
13
 
18
- def url_base_path(query)
19
- query.reverse_geocode? ? reverse_geocode_url_base_path : search_url_base_path
14
+ def base_query_url(query)
15
+ if query.reverse_geocode?
16
+ reverse_geocode_url_base_path
17
+ else
18
+ search_url_base_path
19
+ end
20
20
  end
21
21
 
22
22
  def search_url_base_path
@@ -21,12 +21,12 @@ module Geocoder::Lookup
21
21
  end
22
22
  end
23
23
 
24
- def query_url(query)
25
- "#{protocol}://maps.googleapis.com/maps/api/geocode/json?" + url_query_string(query)
26
- end
27
-
28
24
  private # ---------------------------------------------------------------
29
25
 
26
+ def base_query_url(query)
27
+ "#{protocol}://maps.googleapis.com/maps/api/geocode/json?"
28
+ end
29
+
30
30
  def configure_ssl!(client)
31
31
  client.instance_eval {
32
32
  @ssl_context = OpenSSL::SSL::SSLContext.new
@@ -44,19 +44,24 @@ module Geocoder::Lookup
44
44
  super(response) and ['OK', 'ZERO_RESULTS'].include?(status)
45
45
  end
46
46
 
47
+ def result_root_attr
48
+ 'results'
49
+ end
50
+
47
51
  def results(query)
48
52
  return [] unless doc = fetch_data(query)
49
- case doc['status']; when "OK" # OK status implies >0 results
50
- return doc['results']
53
+ case doc['status']
54
+ when "OK" # OK status implies >0 results
55
+ return doc[result_root_attr]
51
56
  when "OVER_QUERY_LIMIT"
52
57
  raise_error(Geocoder::OverQueryLimitError) ||
53
58
  Geocoder.log(:warn, "#{name} API error: over query limit.")
54
59
  when "REQUEST_DENIED"
55
- raise_error(Geocoder::RequestDenied) ||
56
- Geocoder.log(:warn, "#{name} API error: request denied.")
60
+ raise_error(Geocoder::RequestDenied, doc['error_message']) ||
61
+ Geocoder.log(:warn, "#{name} API error: request denied (#{doc['error_message']}).")
57
62
  when "INVALID_REQUEST"
58
- raise_error(Geocoder::InvalidRequest) ||
59
- Geocoder.log(:warn, "#{name} API error: invalid request.")
63
+ raise_error(Geocoder::InvalidRequest, doc['error_message']) ||
64
+ Geocoder.log(:warn, "#{name} API error: invalid request (#{doc['error_message']}).")
60
65
  end
61
66
  return []
62
67
  end
@@ -16,27 +16,21 @@ 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)}"
19
+ private
20
+
21
+ def base_query_url(query)
22
+ "#{protocol}://maps.googleapis.com/maps/api/place/details/json?"
21
23
  end
22
24
 
23
- private
25
+ def result_root_attr
26
+ 'result'
27
+ end
24
28
 
25
29
  def results(query)
26
- return [] unless doc = fetch_data(query)
27
-
28
- case doc["status"]
29
- when "OK"
30
- return [doc["result"]]
31
- when "OVER_QUERY_LIMIT"
32
- raise_error(Geocoder::OverQueryLimitError) || Geocoder.log(:warn, "Google Places Details API error: over query limit.")
33
- when "REQUEST_DENIED"
34
- raise_error(Geocoder::RequestDenied) || Geocoder.log(:warn, "Google Places Details API error: request denied.")
35
- when "INVALID_REQUEST"
36
- raise_error(Geocoder::InvalidRequest) || Geocoder.log(:warn, "Google Places Details API error: invalid request.")
37
- end
38
-
39
- []
30
+ result = super(query)
31
+ return [result] unless result.is_a? Array
32
+
33
+ result
40
34
  end
41
35
 
42
36
  def query_url_google_params(query)
@@ -16,18 +16,44 @@ 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)}"
19
+ private
20
+
21
+ def result_root_attr
22
+ 'candidates'
21
23
  end
22
24
 
23
- private
25
+ def base_query_url(query)
26
+ "#{protocol}://maps.googleapis.com/maps/api/place/findplacefromtext/json?"
27
+ end
24
28
 
25
29
  def query_url_google_params(query)
26
30
  {
27
- query: query.text,
31
+ input: query.text,
32
+ inputtype: 'textquery',
33
+ fields: fields(query),
28
34
  language: query.language || configuration.language
29
35
  }
30
36
  end
37
+
38
+ def fields(query)
39
+ query_fields = query.options[:fields]
40
+ return format_fields(query_fields) if query_fields
41
+
42
+ default_fields
43
+ end
44
+
45
+ def default_fields
46
+ legacy = %w[id reference]
47
+ basic = %w[business_status formatted_address geometry icon name
48
+ photos place_id plus_code types]
49
+ contact = %w[opening_hours]
50
+ atmosphere = %W[price_level rating user_ratings_total]
51
+ format_fields(legacy, basic, contact, atmosphere)
52
+ end
53
+
54
+ def format_fields(*fields)
55
+ fields.flatten.join(',')
56
+ end
31
57
  end
32
58
  end
33
59
  end
@@ -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,15 +9,19 @@ module Geocoder::Lookup
9
9
  end
10
10
 
11
11
  def required_api_key_parts
12
- ["app_id", "app_code"]
12
+ ['api_key']
13
13
  end
14
14
 
15
- def query_url(query)
16
- "#{protocol}://#{if query.reverse_geocode? then 'reverse.' end}geocoder.api.here.com/6.2/#{if query.reverse_geocode? then 'reverse' end}geocode.json?" + url_query_string(query)
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 query_url_params(query)
35
+ def query_url_here_options(query, reverse_geocode)
32
36
  options = {
33
- :gen=>4,
34
- :app_id=>api_key,
35
- :app_code=>api_code
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
- if query.reverse_geocode?
39
- super.merge(options).merge(
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
- def api_key
51
- if a=configuration.api_key
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 api_code
57
- if a=configuration.api_key
58
- return a.last if a.is_a?(Array)
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
- private
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 [reserved_result(query.text)] if query.loopback_ip_address?
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
 
@@ -13,15 +13,20 @@ module Geocoder::Lookup
13
13
  end
14
14
 
15
15
  def query_url(query)
16
- "#{protocol}://#{host}/#{query.sanitized_text}"
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 # ---------------------------------------------------------------
20
22
 
23
+ def cache_key(query)
24
+ query_url(query)
25
+ end
26
+
21
27
  def results(query)
22
- Geocoder.configure(:ipdata_co => {:http_headers => { "api-key" => configuration.api_key }}) if configuration.api_key
23
- # don't look up a loopback address, just return the stored result
24
- 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?
25
30
  # note: Ipdata.co returns plain text on bad request
26
31
  (doc = fetch_data(query)) ? [doc] : []
27
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