geocoder 1.5.0 → 1.6.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +29 -2
  3. data/LICENSE +1 -1
  4. data/README.md +15 -17
  5. data/bin/console +7 -0
  6. data/examples/autoexpire_cache_redis.rb +2 -0
  7. data/lib/easting_northing.rb +171 -0
  8. data/lib/geocoder/calculations.rb +1 -1
  9. data/lib/geocoder/ip_address.rb +13 -0
  10. data/lib/geocoder/lookup.rb +8 -4
  11. data/lib/geocoder/lookups/baidu_ip.rb +1 -1
  12. data/lib/geocoder/lookups/ban_data_gouv_fr.rb +13 -0
  13. data/lib/geocoder/lookups/base.rb +7 -2
  14. data/lib/geocoder/lookups/bing.rb +2 -1
  15. data/lib/geocoder/lookups/esri.rb +38 -13
  16. data/lib/geocoder/lookups/freegeoip.rb +7 -7
  17. data/lib/geocoder/lookups/here.rb +28 -22
  18. data/lib/geocoder/lookups/ip2location.rb +7 -14
  19. data/lib/geocoder/lookups/ipapi_com.rb +2 -1
  20. data/lib/geocoder/lookups/ipdata_co.rb +5 -4
  21. data/lib/geocoder/lookups/ipgeolocation.rb +51 -0
  22. data/lib/geocoder/lookups/ipinfo_io.rb +2 -11
  23. data/lib/geocoder/lookups/ipregistry.rb +68 -0
  24. data/lib/geocoder/lookups/ipstack.rb +2 -2
  25. data/lib/geocoder/lookups/maxmind.rb +2 -2
  26. data/lib/geocoder/lookups/maxmind_geoip2.rb +4 -7
  27. data/lib/geocoder/lookups/nationaal_georegister_nl.rb +38 -0
  28. data/lib/geocoder/lookups/osmnames.rb +57 -0
  29. data/lib/geocoder/lookups/pelias.rb +2 -3
  30. data/lib/geocoder/lookups/pickpoint.rb +1 -1
  31. data/lib/geocoder/lookups/pointpin.rb +3 -3
  32. data/lib/geocoder/lookups/smarty_streets.rb +13 -3
  33. data/lib/geocoder/lookups/telize.rb +2 -2
  34. data/lib/geocoder/lookups/tencent.rb +59 -0
  35. data/lib/geocoder/lookups/uk_ordnance_survey_names.rb +59 -0
  36. data/lib/geocoder/lookups/yandex.rb +2 -2
  37. data/lib/geocoder/query.rb +14 -0
  38. data/lib/geocoder/railtie.rb +1 -1
  39. data/lib/geocoder/results/baidu.rb +0 -4
  40. data/lib/geocoder/results/ban_data_gouv_fr.rb +1 -1
  41. data/lib/geocoder/results/here.rb +4 -1
  42. data/lib/geocoder/results/ipgeolocation.rb +59 -0
  43. data/lib/geocoder/results/ipregistry.rb +308 -0
  44. data/lib/geocoder/results/nationaal_georegister_nl.rb +62 -0
  45. data/lib/geocoder/results/osmnames.rb +56 -0
  46. data/lib/geocoder/results/smarty_streets.rb +48 -18
  47. data/lib/geocoder/results/tencent.rb +72 -0
  48. data/lib/geocoder/results/uk_ordnance_survey_names.rb +59 -0
  49. data/lib/geocoder/results/yandex.rb +217 -59
  50. data/lib/geocoder/sql.rb +4 -4
  51. data/lib/geocoder/stores/active_record.rb +1 -1
  52. data/lib/geocoder/version.rb +1 -1
  53. data/lib/hash_recursive_merge.rb +1 -2
  54. data/lib/maxmind_database.rb +3 -3
  55. metadata +18 -13
  56. data/lib/geocoder/lookups/geocoder_us.rb +0 -51
  57. data/lib/geocoder/lookups/mapzen.rb +0 -15
  58. data/lib/geocoder/results/geocoder_us.rb +0 -39
  59. data/lib/geocoder/results/mapzen.rb +0 -5
@@ -53,7 +53,8 @@ module Geocoder::Lookup
53
53
 
54
54
  def query_url_params(query)
55
55
  {
56
- key: configuration.api_key
56
+ key: configuration.api_key,
57
+ language: (query.language || configuration.language)
57
58
  }.merge(super)
58
59
  end
59
60
 
@@ -40,31 +40,56 @@ module Geocoder::Lookup
40
40
  else
41
41
  params[:text] = query.sanitized_text
42
42
  end
43
- params[:token] = token
44
- params[:forStorage] = configuration[:for_storage] if configuration[:for_storage]
43
+
44
+ params[:token] = token(query)
45
+
46
+ if for_storage_value = for_storage(query)
47
+ params[:forStorage] = for_storage_value
48
+ end
45
49
  params[:sourceCountry] = configuration[:source_country] if configuration[:source_country]
46
50
  params.merge(super)
47
51
  end
48
52
 
49
- def token
50
- create_and_save_token! if !valid_token_configured? and configuration.api_key
51
- configuration[:token].to_s unless configuration[:token].nil?
53
+ def for_storage(query)
54
+ if query.options.has_key?(:for_storage)
55
+ query.options[:for_storage]
56
+ else
57
+ configuration[:for_storage]
58
+ end
59
+ end
60
+
61
+ def token(query)
62
+ token_instance = if query.options[:token]
63
+ query.options[:token]
64
+ else
65
+ configuration[:token]
66
+ end
67
+
68
+ if !valid_token_configured?(token_instance) && configuration.api_key
69
+ token_instance = create_and_save_token!(query)
70
+ end
71
+
72
+ token_instance.to_s unless token_instance.nil?
52
73
  end
53
74
 
54
- def valid_token_configured?
55
- !configuration[:token].nil? and configuration[:token].active?
75
+ def valid_token_configured?(token_instance)
76
+ !token_instance.nil? && token_instance.active?
56
77
  end
57
78
 
58
- def create_and_save_token!
59
- save_token!(create_token)
79
+ def create_and_save_token!(query)
80
+ token_instance = create_token
81
+
82
+ if query.options[:token]
83
+ query.options[:token] = token_instance
84
+ else
85
+ Geocoder.merge_into_lookup_config(:esri, token: token_instance)
86
+ end
87
+
88
+ token_instance
60
89
  end
61
90
 
62
91
  def create_token
63
92
  Geocoder::EsriToken.generate_token(*configuration.api_key)
64
93
  end
65
-
66
- def save_token!(token_instance)
67
- Geocoder.merge_into_lookup_config(:esri, token: token_instance)
68
- end
69
94
  end
70
95
  end
@@ -7,10 +7,10 @@ module Geocoder::Lookup
7
7
  def name
8
8
  "FreeGeoIP"
9
9
  end
10
-
10
+
11
11
  def supported_protocols
12
12
  if configuration[:host]
13
- [:http, :https]
13
+ [:https]
14
14
  else
15
15
  # use https for default host
16
16
  [:https]
@@ -32,8 +32,8 @@ module Geocoder::Lookup
32
32
  end
33
33
 
34
34
  def results(query)
35
- # don't look up a loopback address, just return the stored result
36
- return [reserved_result(query.text)] if query.loopback_ip_address?
35
+ # don't look up a loopback or private address, just return the stored result
36
+ return [reserved_result(query.text)] if query.internal_ip_address?
37
37
  # note: Freegeoip.net returns plain text "Not Found" on bad request
38
38
  (doc = fetch_data(query)) ? [doc] : []
39
39
  end
@@ -44,8 +44,8 @@ module Geocoder::Lookup
44
44
  "city" => "",
45
45
  "region_code" => "",
46
46
  "region_name" => "",
47
- "metrocode" => "",
48
- "zipcode" => "",
47
+ "metro_code" => "",
48
+ "zip_code" => "",
49
49
  "latitude" => "0",
50
50
  "longitude" => "0",
51
51
  "country_name" => "Reserved",
@@ -54,7 +54,7 @@ module Geocoder::Lookup
54
54
  end
55
55
 
56
56
  def host
57
- configuration[:host] || "freegeoip.net"
57
+ configuration[:host] || "freegeoip.app"
58
58
  end
59
59
  end
60
60
  end
@@ -9,13 +9,17 @@ module Geocoder::Lookup
9
9
  end
10
10
 
11
11
  def required_api_key_parts
12
- ["app_id", "app_code"]
12
+ ['api_key']
13
+ end
14
+
15
+ def supported_protocols
16
+ [:https]
13
17
  end
14
18
 
15
19
  private # ---------------------------------------------------------------
16
20
 
17
21
  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?"
22
+ "#{protocol}://#{if query.reverse_geocode? then 'reverse.' end}geocoder.ls.hereapi.com/6.2/#{if query.reverse_geocode? then 'reverse' end}geocode.json?"
19
23
  end
20
24
 
21
25
  def results(query)
@@ -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
@@ -19,15 +19,16 @@ module Geocoder::Lookup
19
19
  end
20
20
 
21
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)
22
+ params = super
23
+ if configuration.has_key?(:package)
24
+ params.merge!(package: configuration[:package])
25
+ end
26
+ params
27
27
  end
28
28
 
29
29
  def results(query)
30
- return [reserved_result(query.text)] if query.loopback_ip_address?
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?
31
32
  return [] unless doc = fetch_data(query)
32
33
  if doc["response"] == "INVALID ACCOUNT"
33
34
  raise_error(Geocoder::InvalidApiKey) || Geocoder.log(:warn, "INVALID ACCOUNT")
@@ -62,13 +63,5 @@ module Geocoder::Lookup
62
63
  }
63
64
  end
64
65
 
65
- def query_url_params(query)
66
- params = super
67
- if configuration.has_key?(:package)
68
- params.merge!(package: configuration[:package])
69
- end
70
- params
71
- end
72
-
73
66
  end
74
67
  end
@@ -34,7 +34,8 @@ module Geocoder::Lookup
34
34
  end
35
35
 
36
36
  def results(query)
37
- 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?
38
39
 
39
40
  return [] unless doc = fetch_data(query)
40
41
 
@@ -13,7 +13,9 @@ 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 # ---------------------------------------------------------------
@@ -23,9 +25,8 @@ module Geocoder::Lookup
23
25
  end
24
26
 
25
27
  def results(query)
26
- Geocoder.configure(:ipdata_co => {:http_headers => { "api-key" => configuration.api_key }}) if configuration.api_key
27
- # don't look up a loopback address, just return the stored result
28
- 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?
29
30
  # note: Ipdata.co returns plain text on bad request
30
31
  (doc = fetch_data(query)) ? [doc] : []
31
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
@@ -8,15 +8,6 @@ module Geocoder::Lookup
8
8
  "Ipinfo.io"
9
9
  end
10
10
 
11
- # HTTPS available only for paid plans
12
- def supported_protocols
13
- if configuration.api_key
14
- [:http, :https]
15
- else
16
- [:http]
17
- end
18
- end
19
-
20
11
  private # ---------------------------------------------------------------
21
12
 
22
13
  def base_query_url(query)
@@ -26,8 +17,8 @@ module Geocoder::Lookup
26
17
  end
27
18
 
28
19
  def results(query)
29
- # don't look up a loopback address, just return the stored result
30
- return [reserved_result(query.text)] if query.loopback_ip_address?
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?
31
22
 
32
23
  if !(doc = fetch_data(query)).is_a?(Hash) or doc['error']
33
24
  []
@@ -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
@@ -34,8 +34,8 @@ module Geocoder::Lookup
34
34
  end
35
35
 
36
36
  def results(query)
37
- # don't look up a loopback address, just return the stored result
38
- 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?
39
39
 
40
40
  return [] unless doc = fetch_data(query)
41
41
 
@@ -57,8 +57,8 @@ module Geocoder::Lookup
57
57
  end
58
58
 
59
59
  def results(query)
60
- # don't look up a loopback address, just return the stored result
61
- return [reserved_result] if query.loopback_ip_address?
60
+ # don't look up a loopback or private address, just return the stored result
61
+ return [reserved_result] if query.internal_ip_address?
62
62
  doc = fetch_data(query)
63
63
  if doc and doc.is_a?(Array)
64
64
  if !data_contains_error?(doc)
@@ -32,11 +32,7 @@ module Geocoder::Lookup
32
32
  return s
33
33
  else
34
34
  raise(
35
- Geocoder::ConfigurationError,
36
- "When using MaxMind GeoIP2 you MUST specify a service name and basic_auth: " +
37
- "Geocoder.configure(:maxmind_geoip2 => {:service => ...}, " +
38
- ":basic_auth => {:user ..., :password => ...}), " +
39
- "where service is one of: #{services.inspect}"
35
+ Geocoder::ConfigurationError, "When using MaxMind GeoIP2 you must specify a service and credentials: Geocoder.configure(maxmind_geoip2: {service: ..., basic_auth: {user: ..., password: ...}}), where service is one of: #{services.inspect}"
40
36
  )
41
37
  end
42
38
  end
@@ -57,8 +53,9 @@ module Geocoder::Lookup
57
53
  end
58
54
 
59
55
  def results(query)
60
- # don't look up a loopback address
61
- return [] if query.loopback_ip_address?
56
+ # don't look up a loopback or private address, just return the stored result
57
+ return [] if query.internal_ip_address?
58
+
62
59
  doc = fetch_data(query)
63
60
  if doc
64
61
  if !data_contains_error?(doc)