google_distance_matrix 0.4.0 → 0.6.3
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.
- checksums.yaml +5 -5
- data/.editorconfig +16 -0
- data/.rubocop.yml +6 -0
- data/.ruby-version +1 -1
- data/.travis.yml +4 -6
- data/CHANGELOG.md +40 -0
- data/Gemfile +2 -0
- data/README.md +0 -3
- data/Rakefile +9 -4
- data/google_distance_matrix.gemspec +21 -19
- data/lib/google_distance_matrix.rb +25 -23
- data/lib/google_distance_matrix/client.rb +32 -18
- data/lib/google_distance_matrix/client_cache.rb +9 -3
- data/lib/google_distance_matrix/configuration.rb +39 -24
- data/lib/google_distance_matrix/errors.rb +6 -3
- data/lib/google_distance_matrix/log_subscriber.rb +14 -14
- data/lib/google_distance_matrix/logger.rb +7 -5
- data/lib/google_distance_matrix/matrix.rb +45 -22
- data/lib/google_distance_matrix/place.rb +37 -28
- data/lib/google_distance_matrix/places.rb +5 -4
- data/lib/google_distance_matrix/polyline_encoder.rb +2 -2
- data/lib/google_distance_matrix/polyline_encoder/delta.rb +4 -2
- data/lib/google_distance_matrix/polyline_encoder/value_encoder.rb +13 -5
- data/lib/google_distance_matrix/railtie.rb +4 -1
- data/lib/google_distance_matrix/route.rb +22 -15
- data/lib/google_distance_matrix/routes_finder.rb +27 -29
- data/lib/google_distance_matrix/url_builder.rb +44 -16
- data/lib/google_distance_matrix/url_builder/polyline_encoder_buffer.rb +3 -0
- data/lib/google_distance_matrix/version.rb +3 -1
- data/spec/lib/google_distance_matrix/client_cache_spec.rb +27 -11
- data/spec/lib/google_distance_matrix/client_spec.rb +40 -30
- data/spec/lib/google_distance_matrix/configuration_spec.rb +36 -24
- data/spec/lib/google_distance_matrix/log_subscriber_spec.rb +13 -44
- data/spec/lib/google_distance_matrix/logger_spec.rb +16 -13
- data/spec/lib/google_distance_matrix/matrix_spec.rb +90 -57
- data/spec/lib/google_distance_matrix/place_spec.rb +38 -25
- data/spec/lib/google_distance_matrix/places_spec.rb +29 -28
- data/spec/lib/google_distance_matrix/polyline_encoder/delta_spec.rb +5 -3
- data/spec/lib/google_distance_matrix/polyline_encoder_spec.rb +7 -2
- data/spec/lib/google_distance_matrix/route_spec.rb +11 -9
- data/spec/lib/google_distance_matrix/routes_finder_spec.rb +124 -81
- data/spec/lib/google_distance_matrix/url_builder_spec.rb +97 -48
- data/spec/spec_helper.rb +3 -1
- metadata +46 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: de97d6fbd5c11056be61c2fbdade541bcd9e04f95dfdc3d3994d25e97b21476b
|
4
|
+
data.tar.gz: 71fb7ba1f8c2e707a95878219ddf99e040892d6d197a1ed5c33bed671191628e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0304ccbedb35ddde62968025032e2b3d83a962ec857d739df35e3645c4b4220e1aa554729876bcc4aa26e0a9db008ff0e67e314c23ddf4bcbef4951f9d0d13c8
|
7
|
+
data.tar.gz: 650669b42ece96bb992ffccc3738f09ab97d81c02129fdcd4ca0007c921e32fbd834126aec5af62074be5f25ad422f88be3ca454d15c47d83cf60e33ba990ede
|
data/.editorconfig
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# EditorConfig helps developers define and maintain consistent
|
2
|
+
# coding styles between different editors and IDEs
|
3
|
+
# editorconfig.org
|
4
|
+
|
5
|
+
root = true
|
6
|
+
|
7
|
+
[*]
|
8
|
+
end_of_line = lf
|
9
|
+
charset = utf-8
|
10
|
+
trim_trailing_whitespace = true
|
11
|
+
insert_final_newline = true
|
12
|
+
indent_style = space
|
13
|
+
indent_size = 2
|
14
|
+
|
15
|
+
[*.{diff,md}]
|
16
|
+
trim_trailing_whitespace = false
|
data/.rubocop.yml
ADDED
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.5.5
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,43 @@
|
|
1
|
+
## v.0.6.3
|
2
|
+
|
3
|
+
* chore: bumped dependency support up to Rails 6.1 (by mintyfresh)
|
4
|
+
|
5
|
+
## v.0.6.2
|
6
|
+
|
7
|
+
* chore: bumped dependency support up to Rails 6 (by zackchandler)
|
8
|
+
|
9
|
+
## v.0.6.1
|
10
|
+
|
11
|
+
* fix: when matrix places were built from hashes, passing hashes to route/s_for doesnt't work (by brauliomartinezlm)
|
12
|
+
* fix: place comparison was not working with == (by brauliomartinezlm)
|
13
|
+
|
14
|
+
## v.0.6.0
|
15
|
+
|
16
|
+
* Depend on activemodel & activesupport < 5.3 (by brauliomartinezlm)
|
17
|
+
* Tested with Ruby 2.5.
|
18
|
+
* Dropped support for Ruby 2.2 and below.
|
19
|
+
* Added support for `channel` (by michaelgpearce)
|
20
|
+
|
21
|
+
## v.0.5.0
|
22
|
+
|
23
|
+
This release contains breaking change where `url` has been renamed to
|
24
|
+
`sensitive_url`. A `filtered_url` method is added to make it clear that
|
25
|
+
the URL returned is filtered according to configuration while the other one
|
26
|
+
will contain sensitive information like key and signature.
|
27
|
+
|
28
|
+
The cache key is changed so it no longer uses the URL, but a digest of the URL
|
29
|
+
as key. You may set `config.cache_key_transform` to a block passing given url
|
30
|
+
through if you don't want this.
|
31
|
+
|
32
|
+
* Fixed an issue where read/write to cache used url with sensitive data and
|
33
|
+
and filtered url resulting in cache miss.
|
34
|
+
* Instrumentation payload `url` renamed `sensitive_url`.
|
35
|
+
* Instrumentation payload added `filtered_url`.
|
36
|
+
* Cache key is a digest of the `sensitive_url` so we don't store in cache the
|
37
|
+
sensitive parts of the URL.
|
38
|
+
* Digesting cache key is configurable with `cache_key_transform`. It's a callable
|
39
|
+
object expected to take the url and transform it to the key you want.
|
40
|
+
|
1
41
|
## v.0.4.0
|
2
42
|
* When mode is `driving` and `departure_time` is set all `route` objects will contain
|
3
43
|
`duration_in_traffic_in_seconds` and `duration_in_traffic_text`.
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -11,9 +11,6 @@ pull the distance matrix from Google.
|
|
11
11
|
Once you have the matrix you can fetch all routes from a given
|
12
12
|
origin or to a given destination.
|
13
13
|
|
14
|
-
The matrix may also be used as a data set for traveling salesman problem,
|
15
|
-
but to solve it you may look at <http://ai4r.org/>.
|
16
|
-
|
17
14
|
|
18
15
|
|
19
16
|
|
data/Rakefile
CHANGED
@@ -1,9 +1,14 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require 'bundler/gem_tasks'
|
4
|
+
|
5
|
+
require 'rubocop/rake_task'
|
6
|
+
RuboCop::RakeTask.new
|
7
|
+
|
8
|
+
require 'rspec/core/rake_task'
|
4
9
|
RSpec::Core::RakeTask.new(:spec) do |t|
|
5
|
-
t.rspec_opts = [
|
10
|
+
t.rspec_opts = ['-c', '-f progress', '-r ./spec/spec_helper.rb']
|
6
11
|
t.pattern = 'spec/**/*_spec.rb'
|
7
12
|
end
|
8
13
|
|
9
|
-
task default:
|
14
|
+
task default: %i[rubocop spec]
|
@@ -1,30 +1,32 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# frozen_String_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
5
|
require 'google_distance_matrix/version'
|
5
6
|
|
6
7
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
8
|
+
spec.name = 'google_distance_matrix'
|
8
9
|
spec.version = GoogleDistanceMatrix::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
11
|
-
spec.description = %
|
12
|
-
spec.summary = %
|
13
|
-
spec.homepage =
|
14
|
-
spec.license =
|
10
|
+
spec.authors = ['Thorbjørn Hermansen']
|
11
|
+
spec.email = ['thhermansen@gmail.com']
|
12
|
+
spec.description = %(Ruby client for The Google Distance Matrix API)
|
13
|
+
spec.summary = %(Ruby client for The Google Distance Matrix API)
|
14
|
+
spec.homepage = ''
|
15
|
+
spec.license = 'MIT'
|
15
16
|
|
16
|
-
spec.files = `git ls-files`.split(
|
17
|
+
spec.files = `git ls-files`.split($RS)
|
17
18
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
19
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
-
spec.require_paths = [
|
20
|
+
spec.require_paths = ['lib']
|
20
21
|
|
21
|
-
spec.add_dependency
|
22
|
-
spec.add_dependency
|
23
|
-
spec.add_dependency
|
22
|
+
spec.add_dependency 'activemodel', '>= 3.2.13', '< 6.2'
|
23
|
+
spec.add_dependency 'activesupport', '>= 3.2.13', '< 6.2'
|
24
|
+
spec.add_dependency 'google_business_api_url_signer', '~> 0.1.3'
|
24
25
|
|
25
|
-
spec.add_development_dependency
|
26
|
-
spec.add_development_dependency
|
27
|
-
spec.add_development_dependency
|
28
|
-
spec.add_development_dependency
|
29
|
-
spec.add_development_dependency
|
26
|
+
spec.add_development_dependency 'bundler'
|
27
|
+
spec.add_development_dependency 'rake'
|
28
|
+
spec.add_development_dependency 'rspec', '~> 3.8.0'
|
29
|
+
spec.add_development_dependency 'rubocop', '~> 0.59.2'
|
30
|
+
spec.add_development_dependency 'shoulda-matchers', '~> 4.0.0.rc1'
|
31
|
+
spec.add_development_dependency 'webmock', '~> 3.4.2'
|
30
32
|
end
|
@@ -1,29 +1,31 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
|
9
|
-
require
|
10
|
-
|
11
|
-
require
|
12
|
-
require
|
13
|
-
require
|
14
|
-
require
|
15
|
-
require
|
16
|
-
require
|
17
|
-
require
|
18
|
-
require
|
19
|
-
require
|
20
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'google_distance_matrix/version'
|
4
|
+
|
5
|
+
require 'cgi'
|
6
|
+
require 'json'
|
7
|
+
require 'active_model'
|
8
|
+
require 'active_support/core_ext/hash'
|
9
|
+
require 'google_business_api_url_signer'
|
10
|
+
|
11
|
+
require 'google_distance_matrix/logger'
|
12
|
+
require 'google_distance_matrix/errors'
|
13
|
+
require 'google_distance_matrix/configuration'
|
14
|
+
require 'google_distance_matrix/url_builder'
|
15
|
+
require 'google_distance_matrix/client'
|
16
|
+
require 'google_distance_matrix/client_cache'
|
17
|
+
require 'google_distance_matrix/routes_finder'
|
18
|
+
require 'google_distance_matrix/matrix'
|
19
|
+
require 'google_distance_matrix/places'
|
20
|
+
require 'google_distance_matrix/place'
|
21
|
+
require 'google_distance_matrix/route'
|
22
|
+
require 'google_distance_matrix/polyline_encoder'
|
21
23
|
|
22
24
|
require 'google_distance_matrix/railtie' if defined? Rails
|
23
25
|
|
24
|
-
|
26
|
+
# Main module for the GoogleDistanceMatrix
|
25
27
|
module GoogleDistanceMatrix
|
26
|
-
|
28
|
+
module_function
|
27
29
|
|
28
30
|
def default_configuration
|
29
31
|
@default_configuration ||= Configuration.new
|
@@ -38,4 +40,4 @@ module GoogleDistanceMatrix
|
|
38
40
|
end
|
39
41
|
end
|
40
42
|
|
41
|
-
require
|
43
|
+
require 'google_distance_matrix/log_subscriber'
|
@@ -1,4 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module GoogleDistanceMatrix
|
4
|
+
# HTTP client making request to Google's API
|
2
5
|
class Client
|
3
6
|
CLIENT_ERRORS = %w[
|
4
7
|
INVALID_REQUEST
|
@@ -6,41 +9,52 @@ module GoogleDistanceMatrix
|
|
6
9
|
OVER_QUERY_LIMIT
|
7
10
|
REQUEST_DENIED
|
8
11
|
UNKNOWN_ERROR
|
9
|
-
]
|
10
|
-
|
11
|
-
|
12
|
+
].freeze
|
13
|
+
|
14
|
+
# Make a GET request to given URL
|
15
|
+
#
|
16
|
+
# @param url The URL to Google's API we'll make a request to
|
17
|
+
# @param instrumentation A hash with instrumentation payload
|
18
|
+
# @param options Other options we don't care about, for example we'll capture
|
19
|
+
# `configuration` option which we are not using, but the ClientCache
|
20
|
+
# is using.
|
21
|
+
#
|
22
|
+
# @return Hash with data from parsed response body
|
23
|
+
def get(url, instrumentation: {}, **_options)
|
12
24
|
uri = URI.parse url
|
13
|
-
instrumentation = {url: url}.merge(options[:instrumentation] || {})
|
14
25
|
|
15
|
-
response = ActiveSupport::Notifications.instrument
|
26
|
+
response = ActiveSupport::Notifications.instrument(
|
27
|
+
'client_request_matrix_data.google_distance_matrix', instrumentation
|
28
|
+
) do
|
16
29
|
Net::HTTP.get_response uri
|
17
30
|
end
|
18
31
|
|
32
|
+
handle response, url
|
33
|
+
rescue Timeout::Error => error
|
34
|
+
raise ServerError, error
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def handle(response, url) # rubocop:disable Metrics/MethodLength
|
19
40
|
case response
|
20
41
|
when Net::HTTPSuccess
|
21
42
|
inspect_for_client_errors! response
|
22
43
|
when Net::HTTPRequestURITooLong
|
23
|
-
|
44
|
+
raise MatrixUrlTooLong.new url, UrlBuilder::MAX_URL_SIZE, response
|
24
45
|
when Net::HTTPClientError
|
25
|
-
|
46
|
+
raise ClientError, response
|
26
47
|
when Net::HTTPServerError
|
27
|
-
|
48
|
+
raise ServerError, response
|
28
49
|
else # Handle this as a request error for now. Maybe fine tune this more later.
|
29
|
-
|
50
|
+
raise ServerError, response
|
30
51
|
end
|
31
|
-
rescue Timeout::Error => error
|
32
|
-
fail ServerError.new error
|
33
52
|
end
|
34
53
|
|
35
|
-
|
36
|
-
private
|
37
|
-
|
38
54
|
def inspect_for_client_errors!(response)
|
39
|
-
status = JSON.parse(response.body).fetch
|
55
|
+
status = JSON.parse(response.body).fetch 'status'
|
40
56
|
|
41
|
-
if CLIENT_ERRORS.include? status
|
42
|
-
fail ClientError.new response, status
|
43
|
-
end
|
57
|
+
raise ClientError.new response, status if CLIENT_ERRORS.include? status
|
44
58
|
|
45
59
|
response
|
46
60
|
end
|
@@ -1,9 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module GoogleDistanceMatrix
|
4
|
+
# Cached client, which takes care of caching data from Google API
|
2
5
|
class ClientCache
|
3
6
|
attr_reader :client, :cache
|
4
7
|
|
5
|
-
|
6
|
-
|
8
|
+
# Returns a cache key for given URL
|
9
|
+
#
|
10
|
+
# @return String
|
11
|
+
def self.key(url, config)
|
12
|
+
config.cache_key_transform.call url
|
7
13
|
end
|
8
14
|
|
9
15
|
def initialize(client, cache)
|
@@ -12,7 +18,7 @@ module GoogleDistanceMatrix
|
|
12
18
|
end
|
13
19
|
|
14
20
|
def get(url, options = {})
|
15
|
-
cache.fetch self.class.key(url) do
|
21
|
+
cache.fetch self.class.key(url, options.fetch(:configuration)) do
|
16
22
|
client.get url, options
|
17
23
|
end
|
18
24
|
end
|
@@ -1,3 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'digest'
|
4
|
+
|
1
5
|
module GoogleDistanceMatrix
|
2
6
|
# Public: Configuration of matrix and it's request.
|
3
7
|
#
|
@@ -14,20 +18,21 @@ module GoogleDistanceMatrix
|
|
14
18
|
mode avoid units language
|
15
19
|
departure_time arrival_time
|
16
20
|
transit_mode transit_routing_preference
|
17
|
-
traffic_model
|
18
|
-
]
|
21
|
+
traffic_model channel
|
22
|
+
].freeze
|
19
23
|
|
20
24
|
API_DEFAULTS = {
|
21
|
-
mode:
|
22
|
-
units:
|
23
|
-
traffic_model:
|
25
|
+
mode: 'driving',
|
26
|
+
units: 'metric',
|
27
|
+
traffic_model: 'best_guess',
|
24
28
|
use_encoded_polylines: false,
|
25
29
|
protocol: 'https',
|
26
30
|
lat_lng_scale: 5,
|
27
|
-
filter_parameters_in_logged_url: [
|
31
|
+
filter_parameters_in_logged_url: %w[key signature].freeze,
|
32
|
+
cache_key_transform: ->(url) { Digest::SHA512.new.update(url).to_s }
|
28
33
|
}.with_indifferent_access
|
29
34
|
|
30
|
-
attr_accessor
|
35
|
+
attr_accessor(*ATTRIBUTES)
|
31
36
|
|
32
37
|
# The protocol to use, either http or https
|
33
38
|
attr_accessor :protocol
|
@@ -50,22 +55,38 @@ module GoogleDistanceMatrix
|
|
50
55
|
# When logging we filter sensitive parameters
|
51
56
|
attr_accessor :filter_parameters_in_logged_url
|
52
57
|
|
53
|
-
|
54
|
-
|
55
|
-
|
58
|
+
# Callable object which transform given url to key used in cache
|
59
|
+
# @see ClientCache
|
60
|
+
attr_accessor :cache_key_transform
|
61
|
+
|
62
|
+
validates :mode, inclusion: { in: %w[driving walking bicycling transit] }, allow_blank: true
|
63
|
+
validates :avoid, inclusion: { in: %w[tolls highways ferries indoor] }, allow_blank: true
|
64
|
+
validates :units, inclusion: { in: %w[metric imperial] }, allow_blank: true
|
56
65
|
|
57
66
|
validates :departure_time, format: /\A(\d+|now)\Z/, allow_blank: true
|
58
67
|
validates :arrival_time, numericality: true, allow_blank: true
|
59
68
|
|
60
|
-
validates :transit_mode,
|
61
|
-
|
62
|
-
|
69
|
+
validates :transit_mode,
|
70
|
+
inclusion: { in: %w[bus subway train tram rail] },
|
71
|
+
allow_blank: true
|
72
|
+
|
73
|
+
validates :transit_routing_preference,
|
74
|
+
inclusion: { in: %w[less_walking fewer_transfers] },
|
75
|
+
allow_blank: true
|
76
|
+
|
77
|
+
validates :traffic_model,
|
78
|
+
inclusion: { in: %w[best_guess pessimistic optimistic] },
|
79
|
+
allow_blank: true
|
63
80
|
|
64
|
-
validates :protocol, inclusion: {in: [
|
81
|
+
validates :protocol, inclusion: { in: %w[http https] }, allow_blank: true
|
65
82
|
|
66
83
|
def initialize
|
67
84
|
API_DEFAULTS.each_pair do |attr_name, value|
|
68
|
-
self[attr_name] =
|
85
|
+
self[attr_name] = begin
|
86
|
+
value.dup
|
87
|
+
rescue StandardError
|
88
|
+
value
|
89
|
+
end
|
69
90
|
end
|
70
91
|
end
|
71
92
|
|
@@ -77,7 +98,6 @@ module GoogleDistanceMatrix
|
|
77
98
|
public_send "#{attr_name}=", value
|
78
99
|
end
|
79
100
|
|
80
|
-
|
81
101
|
private
|
82
102
|
|
83
103
|
def array_param
|
@@ -85,19 +105,14 @@ module GoogleDistanceMatrix
|
|
85
105
|
attr_and_value[1].nil? || param_same_as_api_default?(attr_and_value)
|
86
106
|
end
|
87
107
|
|
88
|
-
if google_business_api_client_id.present?
|
89
|
-
|
90
|
-
end
|
91
|
-
|
92
|
-
if google_api_key.present?
|
93
|
-
out << ['key', google_api_key]
|
94
|
-
end
|
108
|
+
out << ['client', google_business_api_client_id] if google_business_api_client_id.present?
|
109
|
+
out << ['key', google_api_key] if google_api_key.present?
|
95
110
|
|
96
111
|
out
|
97
112
|
end
|
98
113
|
|
99
114
|
def param_same_as_api_default?(param)
|
100
|
-
|
115
|
+
API_DEFAULTS[param[0]] == param[1]
|
101
116
|
end
|
102
117
|
end
|
103
118
|
end
|