geocoder 1.4.8 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of geocoder might be problematic. Click here for more details.

Files changed (92) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +31 -0
  3. data/LICENSE +1 -1
  4. data/README.md +355 -950
  5. data/examples/autoexpire_cache_redis.rb +2 -0
  6. data/lib/generators/geocoder/config/templates/initializer.rb +1 -1
  7. data/lib/geocoder/calculations.rb +1 -1
  8. data/lib/geocoder/cli.rb +2 -2
  9. data/lib/geocoder/configuration.rb +1 -1
  10. data/lib/geocoder/exceptions.rb +1 -1
  11. data/lib/geocoder/ip_address.rb +14 -1
  12. data/lib/geocoder/lookup.rb +7 -5
  13. data/lib/geocoder/lookups/amap.rb +7 -3
  14. data/lib/geocoder/lookups/baidu.rb +14 -10
  15. data/lib/geocoder/lookups/baidu_ip.rb +7 -36
  16. data/lib/geocoder/lookups/ban_data_gouv_fr.rb +17 -4
  17. data/lib/geocoder/lookups/base.rb +27 -4
  18. data/lib/geocoder/lookups/bing.rb +10 -13
  19. data/lib/geocoder/lookups/db_ip_com.rb +9 -6
  20. data/lib/geocoder/lookups/dstk.rb +4 -2
  21. data/lib/geocoder/lookups/esri.rb +39 -29
  22. data/lib/geocoder/lookups/freegeoip.rb +11 -7
  23. data/lib/geocoder/lookups/geocoder_ca.rb +4 -4
  24. data/lib/geocoder/lookups/geocodio.rb +5 -5
  25. data/lib/geocoder/lookups/geoportail_lu.rb +7 -7
  26. data/lib/geocoder/lookups/google.rb +8 -8
  27. data/lib/geocoder/lookups/google_places_details.rb +4 -4
  28. data/lib/geocoder/lookups/google_places_search.rb +4 -4
  29. data/lib/geocoder/lookups/google_premier.rb +10 -0
  30. data/lib/geocoder/lookups/here.rb +29 -23
  31. data/lib/geocoder/lookups/ip2location.rb +67 -0
  32. data/lib/geocoder/lookups/ipapi_com.rb +9 -13
  33. data/lib/geocoder/lookups/ipdata_co.rb +9 -4
  34. data/lib/geocoder/lookups/ipgeolocation.rb +63 -0
  35. data/lib/geocoder/lookups/ipinfo_io.rb +11 -29
  36. data/lib/geocoder/lookups/ipregistry.rb +68 -0
  37. data/lib/geocoder/lookups/ipstack.rb +11 -12
  38. data/lib/geocoder/lookups/latlon.rb +4 -4
  39. data/lib/geocoder/lookups/location_iq.rb +10 -4
  40. data/lib/geocoder/lookups/mapbox.rb +7 -6
  41. data/lib/geocoder/lookups/mapquest.rb +4 -5
  42. data/lib/geocoder/lookups/maxmind.rb +6 -6
  43. data/lib/geocoder/lookups/maxmind_geoip2.rb +8 -7
  44. data/lib/geocoder/lookups/nominatim.rb +4 -4
  45. data/lib/geocoder/lookups/opencagedata.rb +6 -5
  46. data/lib/geocoder/lookups/osmnames.rb +57 -0
  47. data/lib/geocoder/lookups/pelias.rb +8 -9
  48. data/lib/geocoder/lookups/pickpoint.rb +9 -3
  49. data/lib/geocoder/lookups/pointpin.rb +10 -9
  50. data/lib/geocoder/lookups/postcode_anywhere_uk.rb +4 -5
  51. data/lib/geocoder/lookups/postcodes_io.rb +31 -0
  52. data/lib/geocoder/lookups/smarty_streets.rb +20 -10
  53. data/lib/geocoder/lookups/telize.rb +23 -3
  54. data/lib/geocoder/lookups/tencent.rb +59 -0
  55. data/lib/geocoder/lookups/yandex.rb +6 -6
  56. data/lib/geocoder/query.rb +14 -0
  57. data/lib/geocoder/railtie.rb +1 -1
  58. data/lib/geocoder/results/baidu.rb +10 -14
  59. data/lib/geocoder/results/ban_data_gouv_fr.rb +1 -1
  60. data/lib/geocoder/results/base.rb +13 -1
  61. data/lib/geocoder/results/bing.rb +1 -1
  62. data/lib/geocoder/results/db_ip_com.rb +0 -5
  63. data/lib/geocoder/results/freegeoip.rb +0 -5
  64. data/lib/geocoder/results/geocoder_ca.rb +3 -3
  65. data/lib/geocoder/results/geoip2.rb +4 -4
  66. data/lib/geocoder/results/geoportail_lu.rb +5 -3
  67. data/lib/geocoder/results/here.rb +4 -1
  68. data/lib/geocoder/results/ip2location.rb +22 -0
  69. data/lib/geocoder/results/ipdata_co.rb +0 -5
  70. data/lib/geocoder/results/ipgeolocation.rb +59 -0
  71. data/lib/geocoder/results/ipregistry.rb +308 -0
  72. data/lib/geocoder/results/maxmind.rb +0 -5
  73. data/lib/geocoder/results/maxmind_local.rb +0 -5
  74. data/lib/geocoder/results/osmnames.rb +56 -0
  75. data/lib/geocoder/results/postcodes_io.rb +40 -0
  76. data/lib/geocoder/results/smarty_streets.rb +48 -18
  77. data/lib/geocoder/results/telize.rb +0 -5
  78. data/lib/geocoder/results/tencent.rb +72 -0
  79. data/lib/geocoder/results/test.rb +1 -1
  80. data/lib/geocoder/stores/active_record.rb +1 -3
  81. data/lib/geocoder/version.rb +1 -1
  82. data/lib/hash_recursive_merge.rb +1 -2
  83. data/lib/maxmind_database.rb +3 -3
  84. metadata +17 -18
  85. data/lib/geocoder/lookups/geocoder_us.rb +0 -43
  86. data/lib/geocoder/lookups/mapzen.rb +0 -15
  87. data/lib/geocoder/lookups/okf.rb +0 -44
  88. data/lib/geocoder/lookups/ovi.rb +0 -62
  89. data/lib/geocoder/results/geocoder_us.rb +0 -39
  90. data/lib/geocoder/results/mapzen.rb +0 -5
  91. data/lib/geocoder/results/okf.rb +0 -106
  92. data/lib/geocoder/results/ovi.rb +0 -71
@@ -66,6 +66,13 @@ module Geocoder
66
66
  IpAddress.new(text).valid? rescue false
67
67
  end
68
68
 
69
+ ##
70
+ # Is the Query text a loopback or private IP address?
71
+ #
72
+ def internal_ip_address?
73
+ ip_address? && IpAddress.new(text).internal?
74
+ end
75
+
69
76
  ##
70
77
  # Is the Query text a loopback IP address?
71
78
  #
@@ -73,6 +80,13 @@ module Geocoder
73
80
  ip_address? && IpAddress.new(text).loopback?
74
81
  end
75
82
 
83
+ ##
84
+ # Is the Query text a private IP address?
85
+ #
86
+ def private_ip_address?
87
+ ip_address? && IpAddress.new(text).private?
88
+ end
89
+
76
90
  ##
77
91
  # Does the given string look like latitude/longitude coordinates?
78
92
  #
@@ -4,7 +4,7 @@ module Geocoder
4
4
  if defined? Rails::Railtie
5
5
  require 'rails'
6
6
  class Railtie < Rails::Railtie
7
- initializer 'geocoder.insert_into_active_record' do
7
+ initializer 'geocoder.insert_into_active_record', before: :load_config_initializers do
8
8
  ActiveSupport.on_load :active_record do
9
9
  Geocoder::Railtie.insert
10
10
  end
@@ -7,38 +7,34 @@ module Geocoder::Result
7
7
  ['lat', 'lng'].map{ |i| @data['location'][i] }
8
8
  end
9
9
 
10
- def address
11
- @data['formatted_address']
12
- end
13
-
14
- def state
15
- province
16
- end
17
-
18
10
  def province
19
- @data['addressComponent']['province']
11
+ @data['addressComponent'] and @data['addressComponent']['province'] or ""
20
12
  end
21
13
 
14
+ alias_method :state, :province
15
+
22
16
  def city
23
- @data['addressComponent']['city']
17
+ @data['addressComponent'] and @data['addressComponent']['city'] or ""
24
18
  end
25
19
 
26
20
  def district
27
- @data['addressComponent']['district']
21
+ @data['addressComponent'] and @data['addressComponent']['district'] or ""
28
22
  end
29
23
 
30
24
  def street
31
- @data['addressComponent']['street']
25
+ @data['addressComponent'] and @data['addressComponent']['street'] or ""
32
26
  end
33
27
 
34
28
  def street_number
35
- @data['addressComponent']['street_number']
29
+ @data['addressComponent'] and @data['addressComponent']['street_number']
36
30
  end
37
31
 
38
32
  def formatted_address
39
- @data['formatted_address']
33
+ @data['formatted_address'] or ""
40
34
  end
41
35
 
36
+ alias_method :address, :formatted_address
37
+
42
38
  def address_components
43
39
  @data['addressComponent']
44
40
  end
@@ -7,7 +7,7 @@ module Geocoder::Result
7
7
  #### BASE METHODS ####
8
8
 
9
9
  def self.response_attributes
10
- %w[limit attribution version licence type features]
10
+ %w[limit attribution version licence type features center]
11
11
  end
12
12
 
13
13
  response_attributes.each do |a|
@@ -20,8 +20,20 @@ module Geocoder
20
20
  ##
21
21
  # A string in the given format.
22
22
  #
23
+ # This default implementation dumbly follows the United States address
24
+ # format and will return incorrect results for most countries. Some APIs
25
+ # return properly formatted addresses and those should be funneled
26
+ # through this method.
27
+ #
23
28
  def address(format = :full)
24
- fail
29
+ if state_code.to_s != ""
30
+ s = ", #{state_code}"
31
+ elsif state.to_s != ""
32
+ s = ", #{state}"
33
+ else
34
+ s = ""
35
+ end
36
+ "#{city}#{s} #{postal_code}, #{country}".sub(/^[ ,]*/, '')
25
37
  end
26
38
 
27
39
  ##
@@ -24,7 +24,7 @@ module Geocoder::Result
24
24
  alias_method :country_code, :country
25
25
 
26
26
  def postal_code
27
- @data['address']['postalCode']
27
+ @data['address']['postalCode'].to_s
28
28
  end
29
29
 
30
30
  def coordinates
@@ -7,11 +7,6 @@ module Geocoder::Result
7
7
  ['latitude', 'longitude'].map{ |coordinate_name| @data[coordinate_name] }
8
8
  end
9
9
 
10
- def address(format = :full)
11
- s = state_code.to_s == "" ? "" : ", #{state_code}"
12
- "#{city}#{s} #{zip_code}, #{country_name}".sub(/^[ ,]*/, "")
13
- end
14
-
15
10
  def city
16
11
  @data['city']
17
12
  end
@@ -3,11 +3,6 @@ require 'geocoder/results/base'
3
3
  module Geocoder::Result
4
4
  class Freegeoip < Base
5
5
 
6
- def address(format = :full)
7
- s = state_code.to_s == "" ? "" : ", #{state_code}"
8
- "#{city}#{s} #{postal_code}, #{country}".sub(/^[ ,]*/, "")
9
- end
10
-
11
6
  def city
12
7
  @data['city']
13
8
  end
@@ -16,17 +16,17 @@ module Geocoder::Result
16
16
  end
17
17
 
18
18
  def city
19
- @data['city']
19
+ @data['city'] or (@data['standard'] and @data['standard']['city']) or ""
20
20
  end
21
21
 
22
22
  def state
23
- @data['prov']
23
+ @data['prov'] or (@data['standard'] and @data['standard']['prov']) or ""
24
24
  end
25
25
 
26
26
  alias_method :state_code, :state
27
27
 
28
28
  def postal_code
29
- @data['postal']
29
+ @data['postal'] or (@data['standard'] and @data['standard']['postal']) or ""
30
30
  end
31
31
 
32
32
  def country
@@ -3,10 +3,6 @@ require 'geocoder/results/base'
3
3
  module Geocoder
4
4
  module Result
5
5
  class Geoip2 < Base
6
- def address(format = :full)
7
- s = state.to_s == '' ? '' : ", #{state_code}"
8
- "#{city}#{s} #{postal_code}, #{country}".sub(/^[ ,]*/, '')
9
- end
10
6
 
11
7
  def coordinates
12
8
  %w[latitude longitude].map do |l|
@@ -62,6 +58,10 @@ module Geocoder
62
58
  @language ||= default_language
63
59
  end
64
60
 
61
+ def data
62
+ @data.to_hash
63
+ end
64
+
65
65
  private
66
66
 
67
67
  def default_language
@@ -59,11 +59,13 @@ module Geocoder::Result
59
59
  private
60
60
 
61
61
  def geolocalized?
62
- try_to_extract('coordinates', geomlonlat).present?
62
+ !!try_to_extract('coordinates', geomlonlat)
63
63
  end
64
64
 
65
- def try_to_extract(key, nullable_hash)
66
- nullable_hash.try(:[], key)
65
+ def try_to_extract(key, hash)
66
+ if hash.is_a?(Hash) and hash.include?(key)
67
+ hash[key]
68
+ end
67
69
  end
68
70
  end
69
71
  end
@@ -27,7 +27,10 @@ module Geocoder::Result
27
27
  end
28
28
 
29
29
  def state
30
- address_data['County']
30
+ fail unless d = address_data['AdditionalData']
31
+ if v = d.find{|ad| ad['key']=='StateName'}
32
+ return v['value']
33
+ end
31
34
  end
32
35
 
33
36
  def province
@@ -0,0 +1,22 @@
1
+ require 'geocoder/results/base'
2
+
3
+ module Geocoder::Result
4
+ class Ip2location < Base
5
+
6
+ def address(format = :full)
7
+ "#{city_name} #{zip_code}, #{country_name}".sub(/^[ ,]*/, '')
8
+ end
9
+
10
+ def self.response_attributes
11
+ %w[country_code country_name region_name city_name latitude longitude
12
+ zip_code time_zone isp domain net_speed idd_code area_code usage_type
13
+ weather_station_code weather_station_name mcc mnc mobile_brand elevation]
14
+ end
15
+
16
+ response_attributes.each do |attr|
17
+ define_method attr do
18
+ @data[attr] || ""
19
+ end
20
+ end
21
+ end
22
+ end
@@ -3,11 +3,6 @@ require 'geocoder/results/base'
3
3
  module Geocoder::Result
4
4
  class IpdataCo < Base
5
5
 
6
- def address(format = :full)
7
- s = state_code.to_s == "" ? "" : ", #{state_code}"
8
- "#{city}#{s} #{postal_code}, #{country}".sub(/^[ ,]*/, "")
9
- end
10
-
11
6
  def city
12
7
  @data['city']
13
8
  end
@@ -0,0 +1,59 @@
1
+ require 'geocoder/results/base'
2
+
3
+ module Geocoder::Result
4
+ class Ipgeolocation < Base
5
+
6
+ def coordinates
7
+ [@data['latitude'].to_f, @data['longitude'].to_f]
8
+ end
9
+
10
+ def address(format = :full)
11
+ "#{city}, #{state} #{postal_code}, #{country_name}".sub(/^[ ,]*/, "")
12
+ end
13
+
14
+ def state
15
+ @data['state_prov']
16
+ end
17
+
18
+ def state_code
19
+ @data['state_prov']
20
+ end
21
+
22
+ def country
23
+ @data['country_name']
24
+ end
25
+
26
+ def country_code
27
+ @data['country_code2']
28
+ end
29
+
30
+ def postal_code
31
+ @data['zipcode']
32
+ end
33
+
34
+ def self.response_attributes
35
+ [
36
+ ['ip', ''],
37
+ ['hostname', ''],
38
+ ['continent_code', ''],
39
+ ['continent_name', ''],
40
+ ['country_code2', ''],
41
+ ['country_code3', ''],
42
+ ['country_name', ''],
43
+ ['country_capital',''],
44
+ ['district',''],
45
+ ['state_prov',''],
46
+ ['city', ''],
47
+ ['zipcode', ''],
48
+ ['time_zone', {}],
49
+ ['currency', {}]
50
+ ]
51
+ end
52
+
53
+ response_attributes.each do |attr, default|
54
+ define_method attr do
55
+ @data[attr] || default
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,308 @@
1
+ require 'geocoder/results/base'
2
+
3
+ module Geocoder::Result
4
+ class Ipregistry < Base
5
+
6
+ def initialize(data)
7
+ super
8
+
9
+ @data = flatten_hash(data)
10
+ end
11
+
12
+ def flatten_hash(hash)
13
+ hash.each_with_object({}) do |(k, v), h|
14
+ if v.is_a? Hash
15
+ flatten_hash(v).map do |h_k, h_v|
16
+ h["#{k}_#{h_k}".to_s] = h_v
17
+ end
18
+ else
19
+ h[k] = v
20
+ end
21
+ end
22
+ end
23
+
24
+ private :flatten_hash
25
+
26
+ def city
27
+ @data['location_city']
28
+ end
29
+
30
+ def country
31
+ @data['location_country_name']
32
+ end
33
+
34
+ def country_code
35
+ @data['location_country_code']
36
+ end
37
+
38
+ def latitude
39
+ @data['location_latitude']
40
+ end
41
+
42
+ def longitude
43
+ @data['location_longitude']
44
+ end
45
+
46
+ def postal_code
47
+ @data['location_postal']
48
+ end
49
+
50
+ def state
51
+ @data['location_region_name']
52
+ end
53
+
54
+ def state_code
55
+ @data['location_region_code']
56
+ end
57
+
58
+ # methods for fields specific to Ipregistry
59
+
60
+ def ip
61
+ @data["ip"]
62
+ end
63
+
64
+ def type
65
+ @data["type"]
66
+ end
67
+
68
+ def hostname
69
+ @data["hostname"]
70
+ end
71
+
72
+ def carrier_name
73
+ @data["carrier_name"]
74
+ end
75
+
76
+ def carrier_mcc
77
+ @data["carrier_mcc"]
78
+ end
79
+
80
+ def carrier_mnc
81
+ @data["carrier_mnc"]
82
+ end
83
+
84
+ def connection_asn
85
+ @data["connection_asn"]
86
+ end
87
+
88
+ def connection_domain
89
+ @data["connection_domain"]
90
+ end
91
+
92
+ def connection_organization
93
+ @data["connection_organization"]
94
+ end
95
+
96
+ def connection_type
97
+ @data["connection_type"]
98
+ end
99
+
100
+ def currency_code
101
+ @data["currency_code"]
102
+ end
103
+
104
+ def currency_name
105
+ @data["currency_name"]
106
+ end
107
+
108
+ def currency_plural
109
+ @data["currency_plural"]
110
+ end
111
+
112
+ def currency_symbol
113
+ @data["currency_symbol"]
114
+ end
115
+
116
+ def currency_symbol_native
117
+ @data["currency_symbol_native"]
118
+ end
119
+
120
+ def currency_format_negative_prefix
121
+ @data["currency_format_negative_prefix"]
122
+ end
123
+
124
+ def currency_format_negative_suffix
125
+ @data["currency_format_negative_suffix"]
126
+ end
127
+
128
+ def currency_format_positive_prefix
129
+ @data["currency_format_positive_prefix"]
130
+ end
131
+
132
+ def currency_format_positive_suffix
133
+ @data["currency_format_positive_suffix"]
134
+ end
135
+
136
+ def location_continent_code
137
+ @data["location_continent_code"]
138
+ end
139
+
140
+ def location_continent_name
141
+ @data["location_continent_name"]
142
+ end
143
+
144
+ def location_country_area
145
+ @data["location_country_area"]
146
+ end
147
+
148
+ def location_country_borders
149
+ @data["location_country_borders"]
150
+ end
151
+
152
+ def location_country_calling_code
153
+ @data["location_country_calling_code"]
154
+ end
155
+
156
+ def location_country_capital
157
+ @data["location_country_capital"]
158
+ end
159
+
160
+ def location_country_code
161
+ @data["location_country_code"]
162
+ end
163
+
164
+ def location_country_name
165
+ @data["location_country_name"]
166
+ end
167
+
168
+ def location_country_population
169
+ @data["location_country_population"]
170
+ end
171
+
172
+ def location_country_population_density
173
+ @data["location_country_population_density"]
174
+ end
175
+
176
+ def location_country_flag_emoji
177
+ @data["location_country_flag_emoji"]
178
+ end
179
+
180
+ def location_country_flag_emoji_unicode
181
+ @data["location_country_flag_emoji_unicode"]
182
+ end
183
+
184
+ def location_country_flag_emojitwo
185
+ @data["location_country_flag_emojitwo"]
186
+ end
187
+
188
+ def location_country_flag_noto
189
+ @data["location_country_flag_noto"]
190
+ end
191
+
192
+ def location_country_flag_twemoji
193
+ @data["location_country_flag_twemoji"]
194
+ end
195
+
196
+ def location_country_flag_wikimedia
197
+ @data["location_country_flag_wikimedia"]
198
+ end
199
+
200
+ def location_country_languages
201
+ @data["location_country_languages"]
202
+ end
203
+
204
+ def location_country_tld
205
+ @data["location_country_tld"]
206
+ end
207
+
208
+ def location_region_code
209
+ @data["location_region_code"]
210
+ end
211
+
212
+ def location_region_name
213
+ @data["location_region_name"]
214
+ end
215
+
216
+ def location_city
217
+ @data["location_city"]
218
+ end
219
+
220
+ def location_postal
221
+ @data["location_postal"]
222
+ end
223
+
224
+ def location_latitude
225
+ @data["location_latitude"]
226
+ end
227
+
228
+ def location_longitude
229
+ @data["location_longitude"]
230
+ end
231
+
232
+ def location_language_code
233
+ @data["location_language_code"]
234
+ end
235
+
236
+ def location_language_name
237
+ @data["location_language_name"]
238
+ end
239
+
240
+ def location_language_native
241
+ @data["location_language_native"]
242
+ end
243
+
244
+ def location_in_eu
245
+ @data["location_in_eu"]
246
+ end
247
+
248
+ def security_is_bogon
249
+ @data["security_is_bogon"]
250
+ end
251
+
252
+ def security_is_cloud_provider
253
+ @data["security_is_cloud_provider"]
254
+ end
255
+
256
+ def security_is_tor
257
+ @data["security_is_tor"]
258
+ end
259
+
260
+ def security_is_tor_exit
261
+ @data["security_is_tor_exit"]
262
+ end
263
+
264
+ def security_is_proxy
265
+ @data["security_is_proxy"]
266
+ end
267
+
268
+ def security_is_anonymous
269
+ @data["security_is_anonymous"]
270
+ end
271
+
272
+ def security_is_abuser
273
+ @data["security_is_abuser"]
274
+ end
275
+
276
+ def security_is_attacker
277
+ @data["security_is_attacker"]
278
+ end
279
+
280
+ def security_is_threat
281
+ @data["security_is_threat"]
282
+ end
283
+
284
+ def time_zone_id
285
+ @data["time_zone_id"]
286
+ end
287
+
288
+ def time_zone_abbreviation
289
+ @data["time_zone_abbreviation"]
290
+ end
291
+
292
+ def time_zone_current_time
293
+ @data["time_zone_current_time"]
294
+ end
295
+
296
+ def time_zone_name
297
+ @data["time_zone_name"]
298
+ end
299
+
300
+ def time_zone_offset
301
+ @data["time_zone_offset"]
302
+ end
303
+
304
+ def time_zone_in_daylight_saving
305
+ @data["time_zone_in_daylight_saving"]
306
+ end
307
+ end
308
+ end