really-broken-geocoder 1.5.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.
Files changed (136) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +557 -0
  3. data/LICENSE +20 -0
  4. data/README.md +3 -0
  5. data/bin/geocode +5 -0
  6. data/examples/autoexpire_cache_dalli.rb +62 -0
  7. data/examples/autoexpire_cache_redis.rb +28 -0
  8. data/examples/cache_bypass.rb +48 -0
  9. data/examples/reverse_geocode_job.rb +40 -0
  10. data/lib/generators/geocoder/config/config_generator.rb +14 -0
  11. data/lib/generators/geocoder/config/templates/initializer.rb +22 -0
  12. data/lib/generators/geocoder/maxmind/geolite_city_generator.rb +30 -0
  13. data/lib/generators/geocoder/maxmind/geolite_country_generator.rb +30 -0
  14. data/lib/generators/geocoder/maxmind/templates/migration/geolite_city.rb +30 -0
  15. data/lib/generators/geocoder/maxmind/templates/migration/geolite_country.rb +17 -0
  16. data/lib/generators/geocoder/migration_version.rb +15 -0
  17. data/lib/geocoder.rb +48 -0
  18. data/lib/geocoder/cache.rb +94 -0
  19. data/lib/geocoder/calculations.rb +420 -0
  20. data/lib/geocoder/cli.rb +121 -0
  21. data/lib/geocoder/configuration.rb +137 -0
  22. data/lib/geocoder/configuration_hash.rb +11 -0
  23. data/lib/geocoder/esri_token.rb +38 -0
  24. data/lib/geocoder/exceptions.rb +40 -0
  25. data/lib/geocoder/ip_address.rb +26 -0
  26. data/lib/geocoder/kernel_logger.rb +25 -0
  27. data/lib/geocoder/logger.rb +47 -0
  28. data/lib/geocoder/lookup.rb +118 -0
  29. data/lib/geocoder/lookups/amap.rb +63 -0
  30. data/lib/geocoder/lookups/baidu.rb +63 -0
  31. data/lib/geocoder/lookups/baidu_ip.rb +30 -0
  32. data/lib/geocoder/lookups/ban_data_gouv_fr.rb +130 -0
  33. data/lib/geocoder/lookups/base.rb +348 -0
  34. data/lib/geocoder/lookups/bing.rb +82 -0
  35. data/lib/geocoder/lookups/db_ip_com.rb +52 -0
  36. data/lib/geocoder/lookups/dstk.rb +22 -0
  37. data/lib/geocoder/lookups/esri.rb +95 -0
  38. data/lib/geocoder/lookups/freegeoip.rb +60 -0
  39. data/lib/geocoder/lookups/geocoder_ca.rb +53 -0
  40. data/lib/geocoder/lookups/geocoder_us.rb +51 -0
  41. data/lib/geocoder/lookups/geocodio.rb +42 -0
  42. data/lib/geocoder/lookups/geoip2.rb +45 -0
  43. data/lib/geocoder/lookups/geoportail_lu.rb +65 -0
  44. data/lib/geocoder/lookups/google.rb +95 -0
  45. data/lib/geocoder/lookups/google_places_details.rb +50 -0
  46. data/lib/geocoder/lookups/google_places_search.rb +33 -0
  47. data/lib/geocoder/lookups/google_premier.rb +57 -0
  48. data/lib/geocoder/lookups/here.rb +77 -0
  49. data/lib/geocoder/lookups/ip2location.rb +75 -0
  50. data/lib/geocoder/lookups/ipapi_com.rb +82 -0
  51. data/lib/geocoder/lookups/ipdata_co.rb +62 -0
  52. data/lib/geocoder/lookups/ipinfo_io.rb +44 -0
  53. data/lib/geocoder/lookups/ipstack.rb +63 -0
  54. data/lib/geocoder/lookups/latlon.rb +59 -0
  55. data/lib/geocoder/lookups/location_iq.rb +50 -0
  56. data/lib/geocoder/lookups/mapbox.rb +59 -0
  57. data/lib/geocoder/lookups/mapquest.rb +58 -0
  58. data/lib/geocoder/lookups/maxmind.rb +90 -0
  59. data/lib/geocoder/lookups/maxmind_geoip2.rb +70 -0
  60. data/lib/geocoder/lookups/maxmind_local.rb +65 -0
  61. data/lib/geocoder/lookups/nominatim.rb +64 -0
  62. data/lib/geocoder/lookups/opencagedata.rb +65 -0
  63. data/lib/geocoder/lookups/pelias.rb +63 -0
  64. data/lib/geocoder/lookups/pickpoint.rb +41 -0
  65. data/lib/geocoder/lookups/pointpin.rb +69 -0
  66. data/lib/geocoder/lookups/postcode_anywhere_uk.rb +50 -0
  67. data/lib/geocoder/lookups/postcodes_io.rb +31 -0
  68. data/lib/geocoder/lookups/smarty_streets.rb +63 -0
  69. data/lib/geocoder/lookups/telize.rb +75 -0
  70. data/lib/geocoder/lookups/tencent.rb +59 -0
  71. data/lib/geocoder/lookups/test.rb +44 -0
  72. data/lib/geocoder/lookups/yandex.rb +62 -0
  73. data/lib/geocoder/models/active_record.rb +51 -0
  74. data/lib/geocoder/models/base.rb +39 -0
  75. data/lib/geocoder/models/mongo_base.rb +62 -0
  76. data/lib/geocoder/models/mongo_mapper.rb +26 -0
  77. data/lib/geocoder/models/mongoid.rb +32 -0
  78. data/lib/geocoder/query.rb +125 -0
  79. data/lib/geocoder/railtie.rb +26 -0
  80. data/lib/geocoder/request.rb +114 -0
  81. data/lib/geocoder/results/amap.rb +87 -0
  82. data/lib/geocoder/results/baidu.rb +79 -0
  83. data/lib/geocoder/results/baidu_ip.rb +62 -0
  84. data/lib/geocoder/results/ban_data_gouv_fr.rb +257 -0
  85. data/lib/geocoder/results/base.rb +79 -0
  86. data/lib/geocoder/results/bing.rb +52 -0
  87. data/lib/geocoder/results/db_ip_com.rb +58 -0
  88. data/lib/geocoder/results/dstk.rb +6 -0
  89. data/lib/geocoder/results/esri.rb +75 -0
  90. data/lib/geocoder/results/freegeoip.rb +40 -0
  91. data/lib/geocoder/results/geocoder_ca.rb +60 -0
  92. data/lib/geocoder/results/geocoder_us.rb +39 -0
  93. data/lib/geocoder/results/geocodio.rb +78 -0
  94. data/lib/geocoder/results/geoip2.rb +76 -0
  95. data/lib/geocoder/results/geoportail_lu.rb +71 -0
  96. data/lib/geocoder/results/google.rb +150 -0
  97. data/lib/geocoder/results/google_places_details.rb +39 -0
  98. data/lib/geocoder/results/google_places_search.rb +52 -0
  99. data/lib/geocoder/results/google_premier.rb +6 -0
  100. data/lib/geocoder/results/here.rb +79 -0
  101. data/lib/geocoder/results/ip2location.rb +22 -0
  102. data/lib/geocoder/results/ipapi_com.rb +45 -0
  103. data/lib/geocoder/results/ipdata_co.rb +40 -0
  104. data/lib/geocoder/results/ipinfo_io.rb +48 -0
  105. data/lib/geocoder/results/ipstack.rb +60 -0
  106. data/lib/geocoder/results/latlon.rb +71 -0
  107. data/lib/geocoder/results/location_iq.rb +6 -0
  108. data/lib/geocoder/results/mapbox.rb +57 -0
  109. data/lib/geocoder/results/mapquest.rb +48 -0
  110. data/lib/geocoder/results/maxmind.rb +130 -0
  111. data/lib/geocoder/results/maxmind_geoip2.rb +9 -0
  112. data/lib/geocoder/results/maxmind_local.rb +44 -0
  113. data/lib/geocoder/results/nominatim.rb +109 -0
  114. data/lib/geocoder/results/opencagedata.rb +100 -0
  115. data/lib/geocoder/results/pelias.rb +58 -0
  116. data/lib/geocoder/results/pickpoint.rb +6 -0
  117. data/lib/geocoder/results/pointpin.rb +40 -0
  118. data/lib/geocoder/results/postcode_anywhere_uk.rb +42 -0
  119. data/lib/geocoder/results/postcodes_io.rb +40 -0
  120. data/lib/geocoder/results/smarty_streets.rb +142 -0
  121. data/lib/geocoder/results/telize.rb +40 -0
  122. data/lib/geocoder/results/tencent.rb +72 -0
  123. data/lib/geocoder/results/test.rb +33 -0
  124. data/lib/geocoder/results/yandex.rb +134 -0
  125. data/lib/geocoder/sql.rb +110 -0
  126. data/lib/geocoder/stores/active_record.rb +328 -0
  127. data/lib/geocoder/stores/base.rb +115 -0
  128. data/lib/geocoder/stores/mongo_base.rb +58 -0
  129. data/lib/geocoder/stores/mongo_mapper.rb +13 -0
  130. data/lib/geocoder/stores/mongoid.rb +13 -0
  131. data/lib/geocoder/version.rb +3 -0
  132. data/lib/hash_recursive_merge.rb +74 -0
  133. data/lib/maxmind_database.rb +109 -0
  134. data/lib/tasks/geocoder.rake +54 -0
  135. data/lib/tasks/maxmind.rake +73 -0
  136. metadata +186 -0
@@ -0,0 +1,45 @@
1
+ require 'geocoder/lookups/base'
2
+ require 'geocoder/results/geoip2'
3
+
4
+ module Geocoder
5
+ module Lookup
6
+ class Geoip2 < Base
7
+ attr_reader :gem_name
8
+
9
+ def initialize
10
+ unless configuration[:file].nil?
11
+ begin
12
+ @gem_name = configuration[:lib] || 'maxminddb'
13
+ require @gem_name
14
+ rescue LoadError
15
+ raise "Could not load Maxmind DB dependency. To use the GeoIP2 lookup you must add the #{@gem_name} gem to your Gemfile or have it installed in your system."
16
+ end
17
+
18
+ @mmdb = db_class.new(configuration[:file].to_s)
19
+ end
20
+ super
21
+ end
22
+
23
+ def name
24
+ 'GeoIP2'
25
+ end
26
+
27
+ def required_api_key_parts
28
+ []
29
+ end
30
+
31
+ private
32
+
33
+ def db_class
34
+ gem_name == 'hive_geoip2' ? Hive::GeoIP2 : MaxMindDB
35
+ end
36
+
37
+ def results(query)
38
+ return [] unless configuration[:file]
39
+
40
+ result = @mmdb.lookup(query.to_s)
41
+ result.nil? ? [] : [result]
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,65 @@
1
+ require 'geocoder/lookups/base'
2
+ require "geocoder/results/geoportail_lu"
3
+
4
+ module Geocoder
5
+ module Lookup
6
+ class GeoportailLu < Base
7
+
8
+ def name
9
+ "Geoportail.lu"
10
+ end
11
+
12
+ private # ---------------------------------------------------------------
13
+
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
+ end
21
+
22
+ def search_url_base_path
23
+ "#{protocol}://api.geoportail.lu/geocoder/search?"
24
+ end
25
+
26
+ def reverse_geocode_url_base_path
27
+ "#{protocol}://api.geoportail.lu/geocoder/reverseGeocode?"
28
+ end
29
+
30
+ def query_url_geoportail_lu_params(query)
31
+ query.reverse_geocode? ? reverse_geocode_params(query) : search_params(query)
32
+ end
33
+
34
+ def search_params(query)
35
+ {
36
+ queryString: query.sanitized_text
37
+ }
38
+ end
39
+
40
+ def reverse_geocode_params(query)
41
+ lat_lon = query.coordinates
42
+ {
43
+ lat: lat_lon.first,
44
+ lon: lat_lon.last
45
+ }
46
+ end
47
+
48
+ def query_url_params(query)
49
+ query_url_geoportail_lu_params(query).merge(super)
50
+ end
51
+
52
+ def results(query)
53
+ return [] unless doc = fetch_data(query)
54
+ if doc['success'] == true
55
+ result = doc['results']
56
+ else
57
+ result = []
58
+ raise_error(Geocoder::Error) ||
59
+ warn("Geportail.lu Geocoding API error")
60
+ end
61
+ result
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,95 @@
1
+ require 'geocoder/lookups/base'
2
+ require "geocoder/results/google"
3
+
4
+ module Geocoder::Lookup
5
+ class Google < Base
6
+
7
+ def name
8
+ "Google"
9
+ end
10
+
11
+ def map_link_url(coordinates)
12
+ "http://maps.google.com/maps?q=#{coordinates.join(',')}"
13
+ end
14
+
15
+ def supported_protocols
16
+ # Google requires HTTPS if an API key is used.
17
+ if configuration.api_key
18
+ [:https]
19
+ else
20
+ [:http, :https]
21
+ end
22
+ end
23
+
24
+ private # ---------------------------------------------------------------
25
+
26
+ def base_query_url(query)
27
+ "#{protocol}://maps.googleapis.com/maps/api/geocode/json?"
28
+ end
29
+
30
+ def configure_ssl!(client)
31
+ client.instance_eval {
32
+ @ssl_context = OpenSSL::SSL::SSLContext.new
33
+ options = OpenSSL::SSL::OP_NO_SSLv2 | OpenSSL::SSL::OP_NO_SSLv3
34
+ if OpenSSL::SSL.const_defined?('OP_NO_COMPRESSION')
35
+ options |= OpenSSL::SSL::OP_NO_COMPRESSION
36
+ end
37
+ @ssl_context.set_params({options: options})
38
+ }
39
+ end
40
+
41
+ def valid_response?(response)
42
+ json = parse_json(response.body)
43
+ status = json["status"] if json
44
+ super(response) and ['OK', 'ZERO_RESULTS'].include?(status)
45
+ end
46
+
47
+ def results(query)
48
+ return [] unless doc = fetch_data(query)
49
+ case doc['status']; when "OK" # OK status implies >0 results
50
+ return doc['results']
51
+ when "OVER_QUERY_LIMIT"
52
+ raise_error(Geocoder::OverQueryLimitError) ||
53
+ Geocoder.log(:warn, "#{name} API error: over query limit.")
54
+ when "REQUEST_DENIED"
55
+ raise_error(Geocoder::RequestDenied, doc['error_message']) ||
56
+ Geocoder.log(:warn, "#{name} API error: request denied (#{doc['error_message']}).")
57
+ when "INVALID_REQUEST"
58
+ raise_error(Geocoder::InvalidRequest, doc['error_message']) ||
59
+ Geocoder.log(:warn, "#{name} API error: invalid request (#{doc['error_message']}).")
60
+ end
61
+ return []
62
+ end
63
+
64
+ def query_url_google_params(query)
65
+ params = {
66
+ :sensor => "false",
67
+ :language => (query.language || configuration.language)
68
+ }
69
+ if query.options[:google_place_id]
70
+ params[:place_id] = query.sanitized_text
71
+ else
72
+ params[(query.reverse_geocode? ? :latlng : :address)] = query.sanitized_text
73
+ end
74
+ unless (bounds = query.options[:bounds]).nil?
75
+ params[:bounds] = bounds.map{ |point| "%f,%f" % point }.join('|')
76
+ end
77
+ unless (region = query.options[:region]).nil?
78
+ params[:region] = region
79
+ end
80
+ unless (components = query.options[:components]).nil?
81
+ params[:components] = components.is_a?(Array) ? components.join("|") : components
82
+ end
83
+ unless (result_type = query.options[:result_type]).nil?
84
+ params[:result_type] = result_type.is_a?(Array) ? result_type.join("|") : result_type
85
+ end
86
+ params
87
+ end
88
+
89
+ def query_url_params(query)
90
+ query_url_google_params(query).merge(
91
+ :key => configuration.api_key
92
+ ).merge(super)
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,50 @@
1
+ require "geocoder/lookups/google"
2
+ require "geocoder/results/google_places_details"
3
+
4
+ module Geocoder
5
+ module Lookup
6
+ class GooglePlacesDetails < Google
7
+ def name
8
+ "Google Places Details"
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 base_query_url(query)
22
+ "#{protocol}://maps.googleapis.com/maps/api/place/details/json?"
23
+ end
24
+
25
+ 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
+ []
40
+ end
41
+
42
+ def query_url_google_params(query)
43
+ {
44
+ placeid: query.text,
45
+ language: query.language || configuration.language
46
+ }
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,33 @@
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 base_query_url(query)
22
+ "#{protocol}://maps.googleapis.com/maps/api/place/textsearch/json?"
23
+ end
24
+
25
+ def query_url_google_params(query)
26
+ {
27
+ query: query.text,
28
+ language: query.language || configuration.language
29
+ }
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,57 @@
1
+ require 'openssl'
2
+ require 'base64'
3
+ require 'geocoder/lookups/google'
4
+ require 'geocoder/results/google_premier'
5
+
6
+ module Geocoder::Lookup
7
+ class GooglePremier < Google
8
+
9
+ def name
10
+ "Google Premier"
11
+ end
12
+
13
+ def required_api_key_parts
14
+ ["private key"]
15
+ end
16
+
17
+ def query_url(query)
18
+ path = "/maps/api/geocode/json?" + url_query_string(query)
19
+ "#{protocol}://maps.googleapis.com#{path}&signature=#{sign(path)}"
20
+ end
21
+
22
+ private # ---------------------------------------------------------------
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
+
34
+ def query_url_params(query)
35
+ query_url_google_params(query).merge(super).merge(
36
+ :key => nil, # don't use param inherited from Google lookup
37
+ :client => configuration.api_key[1],
38
+ :channel => configuration.api_key[2]
39
+ )
40
+ end
41
+
42
+ def sign(string)
43
+ raw_private_key = url_safe_base64_decode(configuration.api_key[0])
44
+ digest = OpenSSL::Digest.new('sha1')
45
+ raw_signature = OpenSSL::HMAC.digest(digest, raw_private_key, string)
46
+ url_safe_base64_encode(raw_signature)
47
+ end
48
+
49
+ def url_safe_base64_decode(base64_string)
50
+ Base64.decode64(base64_string.tr('-_', '+/'))
51
+ end
52
+
53
+ def url_safe_base64_encode(raw)
54
+ Base64.encode64(raw).tr('+/', '-_').strip
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,77 @@
1
+ require 'geocoder/lookups/base'
2
+ require 'geocoder/results/here'
3
+
4
+ module Geocoder::Lookup
5
+ class Here < Base
6
+
7
+ def name
8
+ "Here"
9
+ end
10
+
11
+ def required_api_key_parts
12
+ ["app_id", "app_code"]
13
+ end
14
+
15
+ private # ---------------------------------------------------------------
16
+
17
+ def base_query_url(query)
18
+ "#{protocol}://#{if query.reverse_geocode? then 'reverse.' end}geocoder.api.here.com/6.2/#{if query.reverse_geocode? then 'reverse' end}geocode.json?"
19
+ end
20
+
21
+ def results(query)
22
+ return [] unless doc = fetch_data(query)
23
+ return [] unless doc['Response'] && doc['Response']['View']
24
+ if r=doc['Response']['View']
25
+ return [] if r.nil? || !r.is_a?(Array) || r.empty?
26
+ return r.first['Result']
27
+ end
28
+ []
29
+ end
30
+
31
+ def query_url_here_options(query, reverse_geocode)
32
+ options = {
33
+ gen: 9,
34
+ app_id: api_key,
35
+ app_code: api_code,
36
+ language: (query.language || configuration.language)
37
+ }
38
+ if reverse_geocode
39
+ options[:mode] = :retrieveAddresses
40
+ return options
41
+ end
42
+
43
+ unless (country = query.options[:country]).nil?
44
+ options[:country] = country
45
+ end
46
+
47
+ unless (mapview = query.options[:bounds]).nil?
48
+ options[:mapview] = mapview.map{ |point| "%f,%f" % point }.join(';')
49
+ end
50
+ options
51
+ end
52
+
53
+ def query_url_params(query)
54
+ if query.reverse_geocode?
55
+ super.merge(query_url_here_options(query, true)).merge(
56
+ prox: query.sanitized_text
57
+ )
58
+ else
59
+ super.merge(query_url_here_options(query, false)).merge(
60
+ searchtext: query.sanitized_text
61
+ )
62
+ end
63
+ end
64
+
65
+ def api_key
66
+ if (a = configuration.api_key)
67
+ return a.first if a.is_a?(Array)
68
+ end
69
+ end
70
+
71
+ def api_code
72
+ if (a = configuration.api_key)
73
+ return a.last if a.is_a?(Array)
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,75 @@
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
+ {
23
+ key: configuration.api_key ? configuration.api_key : "demo",
24
+ format: "json",
25
+ ip: query.sanitized_text
26
+ }.merge(super)
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
+ def query_url_params(query)
67
+ params = super
68
+ if configuration.has_key?(:package)
69
+ params.merge!(package: configuration[:package])
70
+ end
71
+ params
72
+ end
73
+
74
+ end
75
+ end