geocoder 1.3.4 → 1.3.5
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -1
- data/README.md +5 -5
- data/lib/geocoder/configuration.rb +8 -0
- data/lib/geocoder/esri_token.rb +38 -0
- data/lib/geocoder/lookups/base.rb +3 -0
- data/lib/geocoder/lookups/esri.rb +41 -4
- data/lib/geocoder/lookups/google.rb +14 -0
- data/lib/geocoder/lookups/ipapi_com.rb +25 -3
- data/lib/geocoder/lookups/pelias.rb +11 -3
- data/lib/geocoder/lookups/telize.rb +11 -3
- data/lib/geocoder/request.rb +2 -2
- data/lib/geocoder/results/geoip2.rb +3 -9
- data/lib/geocoder/results/ipapi_com.rb +0 -8
- data/lib/geocoder/results/ipinfo_io.rb +1 -9
- data/lib/geocoder/results/mapbox.rb +1 -9
- data/lib/geocoder/results/mapquest.rb +1 -8
- data/lib/geocoder/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b7f44c3ea3ee0cecd7dfaa73c96393864f578c01
|
4
|
+
data.tar.gz: 39a47431d911edda32bd8182cb051c5af49dbad0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d463d7fd2cfad2c24e5d2c7a37cb5e11285a07291f6dd0a758547727beb0651d06c2165455794e9ce26229ec067a3084dd25b4a28f11b1bc18ea9992b7164795
|
7
|
+
data.tar.gz: e17a5c5e8dff69d558f56a1c4510988c68df7c538fb42897b43f95b9b2a410a3e19c83b72eb44af176c09879c3fc5f6dcb49dc6d41a378c734b070a6d4af18af
|
data/CHANGELOG.md
CHANGED
@@ -3,10 +3,19 @@ Changelog
|
|
3
3
|
|
4
4
|
Major changes to Geocoder for each release. Please see the Git log for complete list of changes.
|
5
5
|
|
6
|
+
1.3.5 (2016 May 27)
|
7
|
+
-------------------
|
8
|
+
* Fix Rails 5 ActionDispatch include issue (thanks github.com/alepore).
|
9
|
+
* Fix bug that caused :esri lookup to ignore certain configured parameters (thanks github.com/aaronpk).
|
10
|
+
* Add reverse geocoding support to :pelias/:mapzen (thanks github.com/shinyaK14).
|
11
|
+
* Add support for custom host with :telize (thanks github.com/jwaldrip).
|
12
|
+
* Change the way :esri lookup generates cache keys for improved performance (thanks github.com/aaronpk).
|
13
|
+
* Improve HTTPS connections with :google (thanks github.com/jlhonora).
|
14
|
+
|
6
15
|
1.3.4 (2016 Apr 14)
|
7
16
|
-------------------
|
8
17
|
* Update :freegeoip host (old one is down).
|
9
|
-
* Add
|
18
|
+
* Add IP lookup :ipapi_com (thanks github.com/piotrgorecki).
|
10
19
|
|
11
20
|
1.3.3 (2016 Apr 4)
|
12
21
|
------------------
|
data/README.md
CHANGED
@@ -11,7 +11,7 @@ Compatibility
|
|
11
11
|
|
12
12
|
* Supports multiple Ruby versions: Ruby 1.9.3, 2.x, JRuby, and Rubinius.
|
13
13
|
* Supports multiple databases: MySQL, PostgreSQL, SQLite, and MongoDB (1.7.0 and higher).
|
14
|
-
* Supports Rails 3 and
|
14
|
+
* Supports Rails 3, 4, and 5. If you need to use it with Rails 2 please see the `rails2` branch (no longer maintained, limited feature set).
|
15
15
|
* Works very well outside of Rails, you just need to install either the `json` (for MRI) or `json_pure` (for JRuby) gem.
|
16
16
|
|
17
17
|
|
@@ -555,15 +555,15 @@ The [Google Places Details API](https://developers.google.com/places/documentati
|
|
555
555
|
|
556
556
|
#### ESRI (`:esri`)
|
557
557
|
|
558
|
-
* **API key**:
|
558
|
+
* **API key**: optional (set `Geocoder.configure(:esri => {:api_key => ["client_id", "client_secret"]})`)
|
559
559
|
* **Quota**: Required for some scenarios (see Terms of Service)
|
560
560
|
* **Region**: world
|
561
561
|
* **SSL support**: yes
|
562
562
|
* **Languages**: English
|
563
|
-
* **Documentation**:
|
563
|
+
* **Documentation**: https://developers.arcgis.com/rest/geocode/api-reference/overview-world-geocoding-service.htm
|
564
564
|
* **Terms of Service**: http://www.esri.com/legal/software-license
|
565
|
-
* **Limitations**:
|
566
|
-
* **Notes**: You can specify which projection you want to use by setting, for example: `Geocoder.configure(:esri => {:outSR => 102100})`.
|
565
|
+
* **Limitations**: Requires API key if results will be stored. Using API key will also remove rate limit.
|
566
|
+
* **Notes**: You can specify which projection you want to use by setting, for example: `Geocoder.configure(:esri => {:outSR => 102100})`. If you will store results, set the flag and provide API key: `Geocoder.configure(:esri => {:api_key => ["client_id", "client_secret"], :for_storage => true})`. If you want to, you can also supply an ESRI token directly: `Geocoder.configure(:esri => {:token => Geocoder::EsriToken.new('TOKEN', Time.now + 1.day})`
|
567
567
|
|
568
568
|
#### Mapzen (`:mapzen`)
|
569
569
|
|
@@ -38,6 +38,14 @@ module Geocoder
|
|
38
38
|
data
|
39
39
|
end
|
40
40
|
|
41
|
+
##
|
42
|
+
# Merge the given hash into a lookup's existing configuration.
|
43
|
+
#
|
44
|
+
def self.merge_into_lookup_config(lookup_name, options)
|
45
|
+
base = Geocoder.config[lookup_name]
|
46
|
+
Geocoder.configure(lookup_name => base.merge(options))
|
47
|
+
end
|
48
|
+
|
41
49
|
class Configuration
|
42
50
|
include Singleton
|
43
51
|
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Geocoder
|
2
|
+
class EsriToken
|
3
|
+
attr_accessor :value, :expires_at
|
4
|
+
|
5
|
+
def initialize(value, expires_at)
|
6
|
+
@value = value
|
7
|
+
@expires_at = expires_at
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_s
|
11
|
+
@value
|
12
|
+
end
|
13
|
+
|
14
|
+
def active?
|
15
|
+
@expires_at > Time.now
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.generate_token(client_id, client_secret, expires=1440)
|
19
|
+
# creates a new token that will expire in 1 day by default
|
20
|
+
getToken = Net::HTTP.post_form URI('https://www.arcgis.com/sharing/rest/oauth2/token'),
|
21
|
+
f: 'json',
|
22
|
+
client_id: client_id,
|
23
|
+
client_secret: client_secret,
|
24
|
+
grant_type: 'client_credentials',
|
25
|
+
expiration: expires # (minutes) max: 20160, default: 1 day
|
26
|
+
|
27
|
+
response = JSON.parse(getToken.body)
|
28
|
+
|
29
|
+
if response['error']
|
30
|
+
Geocoder.log(:warn, response['error'])
|
31
|
+
else
|
32
|
+
token_value = response['access_token']
|
33
|
+
expires_at = Time.now + (expires * 60)
|
34
|
+
new(token_value, expires_at)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -274,6 +274,7 @@ module Geocoder
|
|
274
274
|
uri = URI.parse(query_url(query))
|
275
275
|
Geocoder.log(:debug, "Geocoder: HTTP request being made for #{uri.to_s}")
|
276
276
|
http_client.start(uri.host, uri.port, use_ssl: use_ssl?, open_timeout: configuration.timeout, read_timeout: configuration.timeout) do |client|
|
277
|
+
configure_ssl!(client) if use_ssl?
|
277
278
|
req = Net::HTTP::Get.new(uri.request_uri, configuration.http_headers)
|
278
279
|
if configuration.basic_auth[:user] and configuration.basic_auth[:password]
|
279
280
|
req.basic_auth(
|
@@ -297,6 +298,8 @@ module Geocoder
|
|
297
298
|
end
|
298
299
|
end
|
299
300
|
|
301
|
+
def configure_ssl!(client); end
|
302
|
+
|
300
303
|
def check_api_key_configuration!(query)
|
301
304
|
key_parts = query.lookup.required_api_key_parts
|
302
305
|
if key_parts.size > Array(configuration.api_key).size
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'geocoder/lookups/base'
|
2
2
|
require "geocoder/results/esri"
|
3
|
+
require 'geocoder/esri_token'
|
3
4
|
|
4
5
|
module Geocoder::Lookup
|
5
6
|
class Esri < Base
|
@@ -9,14 +10,16 @@ module Geocoder::Lookup
|
|
9
10
|
end
|
10
11
|
|
11
12
|
def query_url(query)
|
12
|
-
|
13
|
-
|
14
|
-
"#{protocol}://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/#{search_keyword}?" +
|
15
|
-
url_query_string(query)
|
13
|
+
base_query_url(query) + url_query_string(query)
|
16
14
|
end
|
17
15
|
|
18
16
|
private # ---------------------------------------------------------------
|
19
17
|
|
18
|
+
def base_query_url(query)
|
19
|
+
action = query.reverse_geocode? ? "reverseGeocode" : "find"
|
20
|
+
"#{protocol}://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/#{action}?"
|
21
|
+
end
|
22
|
+
|
20
23
|
def results(query)
|
21
24
|
return [] unless doc = fetch_data(query)
|
22
25
|
|
@@ -31,6 +34,17 @@ module Geocoder::Lookup
|
|
31
34
|
end
|
32
35
|
end
|
33
36
|
|
37
|
+
def cache_key(query)
|
38
|
+
base_query_url(query) + hash_to_query(cache_key_params(query))
|
39
|
+
end
|
40
|
+
|
41
|
+
def cache_key_params(query)
|
42
|
+
# omit api_key and token because they may vary among requests
|
43
|
+
query_url_params(query).reject do |key,value|
|
44
|
+
[:api_key, :token].include?(key)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
34
48
|
def query_url_params(query)
|
35
49
|
params = {
|
36
50
|
:f => "pjson",
|
@@ -41,8 +55,31 @@ module Geocoder::Lookup
|
|
41
55
|
else
|
42
56
|
params[:text] = query.sanitized_text
|
43
57
|
end
|
58
|
+
params[:token] = token
|
59
|
+
params[:forStorage] = configuration[:for_storage] if configuration[:for_storage]
|
60
|
+
params[:sourceCountry] = configuration[:source_country] if configuration[:source_country]
|
44
61
|
params.merge(super)
|
45
62
|
end
|
46
63
|
|
64
|
+
def token
|
65
|
+
create_and_save_token! if !valid_token_configured? and configuration.api_key
|
66
|
+
configuration[:token].to_s unless configuration[:token].nil?
|
67
|
+
end
|
68
|
+
|
69
|
+
def valid_token_configured?
|
70
|
+
!configuration[:token].nil? and configuration[:token].active?
|
71
|
+
end
|
72
|
+
|
73
|
+
def create_and_save_token!
|
74
|
+
save_token!(create_token)
|
75
|
+
end
|
76
|
+
|
77
|
+
def create_token
|
78
|
+
Geocoder::EsriToken.generate_token(*configuration.api_key)
|
79
|
+
end
|
80
|
+
|
81
|
+
def save_token!(token_instance)
|
82
|
+
Geocoder.merge_into_lookup_config(:esri, token: token_instance)
|
83
|
+
end
|
47
84
|
end
|
48
85
|
end
|
@@ -27,6 +27,17 @@ module Geocoder::Lookup
|
|
27
27
|
|
28
28
|
private # ---------------------------------------------------------------
|
29
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
|
+
|
30
41
|
def valid_response?(response)
|
31
42
|
json = parse_json(response.body)
|
32
43
|
status = json["status"] if json
|
@@ -65,6 +76,9 @@ module Geocoder::Lookup
|
|
65
76
|
unless (components = query.options[:components]).nil?
|
66
77
|
params[:components] = components.is_a?(Array) ? components.join("|") : components
|
67
78
|
end
|
79
|
+
unless (result_type = query.options[:result_type]).nil?
|
80
|
+
params[:result_type] = result_type.is_a?(Array) ? result_type.join("|") : result_type
|
81
|
+
end
|
68
82
|
params
|
69
83
|
end
|
70
84
|
|
@@ -9,7 +9,8 @@ module Geocoder::Lookup
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def query_url(query)
|
12
|
-
|
12
|
+
domain = configuration.api_key ? "pro.ip-api.com" : "ip-api.com"
|
13
|
+
url_ = "#{protocol}://#{domain}/json/#{query.sanitized_text}"
|
13
14
|
|
14
15
|
if (params = url_query_string(query)) && !params.empty?
|
15
16
|
url_ + "?" + params
|
@@ -29,17 +30,32 @@ module Geocoder::Lookup
|
|
29
30
|
|
30
31
|
private
|
31
32
|
|
33
|
+
def parse_raw_data(raw_data)
|
34
|
+
if raw_data.chomp == "invalid key"
|
35
|
+
invalid_key_result
|
36
|
+
else
|
37
|
+
super(raw_data)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
32
41
|
def results(query)
|
33
42
|
return [reserved_result(query.text)] if query.loopback_ip_address?
|
34
43
|
|
35
|
-
|
44
|
+
return [] unless doc = fetch_data(query)
|
45
|
+
|
46
|
+
if doc["message"] == "invalid key"
|
47
|
+
raise_error(Geocoder::InvalidApiKey) || Geocoder.log(:warn, "Invalid API key.")
|
48
|
+
return []
|
49
|
+
else
|
50
|
+
return [doc]
|
51
|
+
end
|
36
52
|
end
|
37
53
|
|
38
54
|
def reserved_result(query)
|
39
55
|
{
|
40
56
|
"message" => "reserved range",
|
41
57
|
"query" => query,
|
42
|
-
"status" => fail,
|
58
|
+
"status" => "fail",
|
43
59
|
"ip" => query,
|
44
60
|
"city" => "",
|
45
61
|
"region_code" => "",
|
@@ -53,6 +69,12 @@ module Geocoder::Lookup
|
|
53
69
|
}
|
54
70
|
end
|
55
71
|
|
72
|
+
def invalid_key_result
|
73
|
+
{
|
74
|
+
"message" => "invalid key"
|
75
|
+
}
|
76
|
+
end
|
77
|
+
|
56
78
|
def query_url_params(query)
|
57
79
|
params = {}
|
58
80
|
params.merge!(fields: configuration[:fields]) if configuration.has_key?(:fields)
|
@@ -23,11 +23,19 @@ module Geocoder::Lookup
|
|
23
23
|
private
|
24
24
|
|
25
25
|
def query_url_params(query)
|
26
|
-
{
|
26
|
+
params = {
|
27
27
|
api_key: configuration.api_key,
|
28
|
-
text: query.text,
|
29
28
|
size: 1
|
30
|
-
}.merge(super
|
29
|
+
}.merge(super)
|
30
|
+
|
31
|
+
if query.reverse_geocode?
|
32
|
+
lat,lon = query.coordinates
|
33
|
+
params[:'point.lat'] = lat
|
34
|
+
params[:'point.lon'] = lon
|
35
|
+
else
|
36
|
+
params[:text] = query.text
|
37
|
+
end
|
38
|
+
params
|
31
39
|
end
|
32
40
|
|
33
41
|
def results(query)
|
@@ -9,15 +9,22 @@ module Geocoder::Lookup
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def required_api_key_parts
|
12
|
-
["key"]
|
12
|
+
configuration[:host] ? [] : ["key"]
|
13
13
|
end
|
14
14
|
|
15
15
|
def query_url(query)
|
16
|
-
|
16
|
+
if configuration[:host]
|
17
|
+
"#{protocol}://#{configuration[:host]}/geoip/#{query.sanitized_text}"
|
18
|
+
else
|
19
|
+
"#{protocol}://telize-v1.p.mashape.com/geoip/#{query.sanitized_text}?mashape-key=#{api_key}"
|
20
|
+
end
|
17
21
|
end
|
18
22
|
|
19
23
|
def supported_protocols
|
20
|
-
[
|
24
|
+
[].tap do |array|
|
25
|
+
array << :https
|
26
|
+
array << :http if configuration[:host]
|
27
|
+
end
|
21
28
|
end
|
22
29
|
|
23
30
|
private # ---------------------------------------------------------------
|
@@ -43,5 +50,6 @@ module Geocoder::Lookup
|
|
43
50
|
def api_key
|
44
51
|
configuration.api_key
|
45
52
|
end
|
53
|
+
|
46
54
|
end
|
47
55
|
end
|
data/lib/geocoder/request.rb
CHANGED
@@ -9,15 +9,9 @@ module Geocoder
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def coordinates
|
12
|
-
[latitude
|
13
|
-
|
14
|
-
|
15
|
-
def latitude
|
16
|
-
data.fetch('location', {}).fetch('latitude', 0.0)
|
17
|
-
end
|
18
|
-
|
19
|
-
def longitude
|
20
|
-
data.fetch('location', {}).fetch('longitude', 0.0)
|
12
|
+
%w[latitude longitude].map do |l|
|
13
|
+
data.fetch('location', {}).fetch(l, 0.0)
|
14
|
+
end
|
21
15
|
end
|
22
16
|
|
23
17
|
def city
|
@@ -7,16 +7,8 @@ module Geocoder::Result
|
|
7
7
|
"#{city} #{postal_code}, #{country}".sub(/^[ ,]*/, "")
|
8
8
|
end
|
9
9
|
|
10
|
-
def latitude
|
11
|
-
@data['loc'].split(',')[0].to_f
|
12
|
-
end
|
13
|
-
|
14
|
-
def longitude
|
15
|
-
@data['loc'].split(',')[1].to_f
|
16
|
-
end
|
17
|
-
|
18
10
|
def coordinates
|
19
|
-
|
11
|
+
@data['loc'].split(",").map(&:to_f)
|
20
12
|
end
|
21
13
|
|
22
14
|
def city
|
@@ -3,16 +3,8 @@ require 'geocoder/results/base'
|
|
3
3
|
module Geocoder::Result
|
4
4
|
class Mapbox < Base
|
5
5
|
|
6
|
-
def latitude
|
7
|
-
@latitude ||= @data["geometry"]["coordinates"].last.to_f
|
8
|
-
end
|
9
|
-
|
10
|
-
def longitude
|
11
|
-
@longitude ||= @data["geometry"]["coordinates"].first.to_f
|
12
|
-
end
|
13
|
-
|
14
6
|
def coordinates
|
15
|
-
[
|
7
|
+
@data["geometry"]["coordinates"].reverse.map(&:to_f)
|
16
8
|
end
|
17
9
|
|
18
10
|
def place_name
|
@@ -2,16 +2,9 @@ require 'geocoder/results/base'
|
|
2
2
|
|
3
3
|
module Geocoder::Result
|
4
4
|
class Mapquest < Base
|
5
|
-
def latitude
|
6
|
-
@data["latLng"]["lat"]
|
7
|
-
end
|
8
|
-
|
9
|
-
def longitude
|
10
|
-
@data["latLng"]["lng"]
|
11
|
-
end
|
12
5
|
|
13
6
|
def coordinates
|
14
|
-
[
|
7
|
+
%w[lat lng].map{ |l| @data["latLng"][l] }
|
15
8
|
end
|
16
9
|
|
17
10
|
def city
|
data/lib/geocoder/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: geocoder
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3.
|
4
|
+
version: 1.3.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alex Reisner
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-05-27 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Provides object geocoding (by street or IP address), reverse geocoding
|
14
14
|
(coordinates to street address), distance queries for ActiveRecord and Mongoid,
|
@@ -41,6 +41,7 @@ files:
|
|
41
41
|
- lib/geocoder/cli.rb
|
42
42
|
- lib/geocoder/configuration.rb
|
43
43
|
- lib/geocoder/configuration_hash.rb
|
44
|
+
- lib/geocoder/esri_token.rb
|
44
45
|
- lib/geocoder/exceptions.rb
|
45
46
|
- lib/geocoder/ip_address.rb
|
46
47
|
- lib/geocoder/kernel_logger.rb
|
@@ -157,7 +158,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
157
158
|
version: '0'
|
158
159
|
requirements: []
|
159
160
|
rubyforge_project:
|
160
|
-
rubygems_version: 2.
|
161
|
+
rubygems_version: 2.5.1
|
161
162
|
signing_key:
|
162
163
|
specification_version: 4
|
163
164
|
summary: Complete geocoding solution for Ruby.
|