google_maps_juice 1.0.0 → 1.1.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 81dd523f6c0a801f8b8e15d0589525cd683359f4b85d0427f9b697d1ade77f5d
4
- data.tar.gz: 2fb1b05f6a92b3770771a5ae74de3ccd09f411f66dabde16d38160f151f48d66
3
+ metadata.gz: f26ed08354506950932680c98e078c385bce57047a1b99bcab2a122bc26c2112
4
+ data.tar.gz: 9ea5e1e090fb76f2189468cacfdd9e6993a45936501d78f1bd6ee018a99c80b0
5
5
  SHA512:
6
- metadata.gz: cdc4a09d044ecd8549b5a7851c1fda06be8a1ff4677df0e3173dfdabadfbb9b791789a3fe4a4a8d1dbc1d353f2382812ddc6dbb912915b679598502dd0254212
7
- data.tar.gz: 646b96bb8275a1230eb16a19d6472e56bd0f31218e0580976f1e9a4c88f738604885a156d92927fcb5060e54ab0ea077bc66c77e4f351eb12384ef63b3ac5260
6
+ metadata.gz: dc3ae38123522b60496ff3094678f1aef15dbda36fc4eecd0dc0cc3f18f3389c54b995064e384167ec33e945ab2f8de9766ae80c8bdf8e1086ccb855acfe9cbd
7
+ data.tar.gz: 612b4cd78edf58cc7ac7c9ba67884c37b32130d7d4eb065aabeaf5cfb9011b3652e684eae4d78fef0f7ceb65584a45721a0a1d1e3de8b20746c7737659bea9c3
@@ -1 +1 @@
1
- 2.5.0
1
+ 2.6.3
@@ -1,9 +1,9 @@
1
1
  sudo: false
2
2
  language: ruby
3
3
  rvm:
4
- - 2.5.0
4
+ - 2.6.3
5
5
 
6
- before_install: gem install bundler -v 1.16.4
6
+ before_install: gem install bundler -v 1.17.2
7
7
 
8
8
  install: bundle install
9
9
 
data/README.md CHANGED
@@ -17,6 +17,7 @@ This gem aims at progressively covering a fair amount of those widely-used servi
17
17
 
18
18
  * Geocoding
19
19
  * Time Zone
20
+ * Directions
20
21
 
21
22
  Contributors are welcome!
22
23
 
@@ -72,13 +73,13 @@ This is especially useful in some "hybrid" scenario, where an API key is shared
72
73
 
73
74
  ## Error Handling
74
75
 
75
- If Google servers respond with a non-successful HTTP status code, i.e. `4xx` or `5xx`, a `GoogleMapsJuice::Error` is raised with a message of the form `'HTTP 503 - Error details as returned by the server'`.
76
+ If Google servers respond with a non-successful HTTP status code, i.e. `4xx` or `5xx`, a `GoogleMapsJuice::ResponseError` is raised with a message of the form `'HTTP 503 - Error details as returned by the server'`.
76
77
 
77
78
  API errors are also handled, based on the `status` attribute of Google's JSON response, and the optional `error_message` attribute.
78
79
 
79
80
  * `GoogleMapsJuice::ZeroResults` is raised when `status` is `'ZERO_RESULTS'`
80
81
  * `GoogleMapsJuice::ApiLimitError` is raised when `status` is `'OVER_DAILY_LIMIT'` or `'OVER_QUERY_LIMIT'`
81
- * `GoogleMapsJuice::Error` is raised when `status` is not `OK` with a message of the form `API <status> - <error_message>`
82
+ * `GoogleMapsJuice::ResponseError` is raised when `status` is not `OK` with a message of the form `API <status> - <error_message>`
82
83
 
83
84
 
84
85
  ## Geocoding
@@ -181,6 +182,57 @@ The `by_location` method returns a `GoogleMapsJuice::Timezone::Response`. It's a
181
182
  * `dst_offset`: the offset for daylight-savings time in seconds
182
183
 
183
184
 
185
+ ## Directions
186
+
187
+ [Google's Directions API](https://developers.google.com/maps/documentation/directions/intro#DirectionsRequests) returns the possible routes of given origin and destination geographic locations; Google's API accepts address, textual latitude/longitude value, or place ID of which you wish to calculate directions. Currently this gem implements only latitude/longitude mode.
188
+ `GoogleMapsJuice` will raise an `ArgumentError` if some unsupported param is passed, or when none of the required params are passed.
189
+
190
+ ```ruby
191
+ response = GoogleMapsJuice::Directions.find(origin: '41.8892732,12.4921921', destination: '41.9016488,12.4583003')
192
+ ```
193
+
194
+ Compared to Google's raw API request, it provides validation of both origin and destination, in order to avoid sending requests when they would fail for sure - to learn more see `spec/unit/directions_spec.rb`.
195
+
196
+ **Accepted params:**
197
+
198
+ * Both `origin` and `destination` are mandatory
199
+ * `origin` is composed by `latitude` and `longitude`, comma separated float values
200
+ * `destination` same format as `origin`
201
+
202
+
203
+ ### Directions Response
204
+
205
+ The `find` method returns a `GoogleMapsJuice::Directions::Response`. It's a `Hash` representation of Google's JSON response. However, it also provides a few useful methods:
206
+
207
+ * `results`: the `Hash` raw result
208
+
209
+ * `routes`: an `Array` of `GoogleMapsJuice::Directions::Response::Route` objects
210
+
211
+ * `first`: the first `Route` of the `routes` `List`
212
+
213
+ As described in [Google's Directions API](https://developers.google.com/maps/documentation/directions/intro#Routes), the response contains all possible routes. Each route has some attributes and one or more *legs*, wich in turn have one or more *steps*.
214
+ If no waypoints are passed, the route response will contain a single leg. Since `GoogleMapsJuice::Directions` doesn't handles waypoints yet, only the first leg is considered for each route.
215
+ The `GoogleMapsJuice::Directions::Response::Route` is a representation of a response route and provides methods to access all route's attributes:
216
+
217
+ * `summary`: a brief description of the route
218
+
219
+ * `legs`: all legs of the route, generally a single one
220
+
221
+ * `steps`: all steps of the first route's leg
222
+
223
+ * `duration`: time duration of the first route's leg
224
+
225
+ * `distance`: distance between origin and destination of first route's leg
226
+
227
+ * `start_location`: `latitude`/`longitude` of the origin first route's leg
228
+
229
+ * `end_location`: `latitude`/`longitude` of the destination first route's leg
230
+
231
+ * `start_address`: address of the origin first route's leg
232
+
233
+ * `end_address`: address of the destination first route's leg
234
+
235
+
184
236
  ## Development
185
237
 
186
238
  After checking out the repo, run `bin/setup` to install dependencies. Create a `.env` file and save your Google API key there; if you want to use a different key for testing, put it in `.env.test` and it will override the one in `.env`.
@@ -22,10 +22,10 @@ Gem::Specification.new do |spec|
22
22
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
23
  spec.require_paths = ["lib"]
24
24
 
25
- spec.add_dependency 'activesupport', '~> 5.2'
25
+ spec.add_dependency 'activesupport'
26
26
  spec.add_dependency 'excon'
27
27
 
28
- spec.add_development_dependency 'bundler', '~> 1.16'
28
+ spec.add_development_dependency 'bundler', '~> 1.17.2'
29
29
  spec.add_development_dependency 'rake', '~> 12.3'
30
30
  spec.add_development_dependency 'rspec', '~> 3.5'
31
31
  spec.add_development_dependency 'webmock', '~> 3.4'
@@ -14,8 +14,9 @@ module GoogleMapsJuice
14
14
  autoload :Endpoint, 'google_maps_juice/endpoint'
15
15
  autoload :Geocoding, 'google_maps_juice/geocoding'
16
16
  autoload :Timezone, 'google_maps_juice/timezone'
17
+ autoload :Directions, 'google_maps_juice/directions'
17
18
 
18
- class Error < Exception; end
19
- class ApiLimitError < Exception; end
20
- class ZeroResults < Exception; end
19
+ class ResponseError < RuntimeError; end
20
+ class ApiLimitError < ResponseError; end
21
+ class ZeroResults < ResponseError; end
21
22
  end
@@ -27,7 +27,7 @@ module GoogleMapsJuice
27
27
  else
28
28
  msg = "HTTP #{response.status}"
29
29
  msg += " - #{response.body}" if response.body.present?
30
- raise GoogleMapsJuice::Error, msg
30
+ raise GoogleMapsJuice::ResponseError, msg
31
31
  end
32
32
  end
33
33
 
@@ -0,0 +1,55 @@
1
+ module GoogleMapsJuice
2
+ class Directions < Endpoint
3
+
4
+ ENDPOINT = '/directions'
5
+
6
+ autoload :Response, 'google_maps_juice/directions/response'
7
+
8
+ class << self
9
+ def find(params, api_key: GoogleMapsJuice.config.api_key)
10
+ client = GoogleMapsJuice::Client.new(api_key: api_key)
11
+ new(client).find(params)
12
+ end
13
+ end
14
+
15
+ def find(params)
16
+ validate_find_params(params)
17
+ response_text = @client.get("#{ENDPOINT}/json", params)
18
+ response = JSON.parse(response_text, object_class: Response)
19
+ detect_errors(response)
20
+ end
21
+
22
+ def validate_find_params(params)
23
+ raise ArgumentError, 'Hash argument expected' unless params.is_a?(Hash)
24
+
25
+ supported_keys = %w[origin destination]
26
+ validate_supported_params(params, supported_keys)
27
+
28
+ required_keys = %w[origin destination]
29
+ validate_any_required_params(params, required_keys)
30
+
31
+ validate_geo_coordinate(params)
32
+ end
33
+
34
+ def validate_geo_coordinate(params)
35
+ raise ArgumentError, 'String argument expected' unless params.values.all?(String)
36
+
37
+ geocoords = params.values.map { |x| x.split(',') }.flatten
38
+ geocoords.map! { |x| Float(x).round(7) }
39
+ raise ArgumentError, 'Wrong geo-coordinates' if geocoords.size != 4
40
+
41
+ validate_location_params(geocoords)
42
+ end
43
+
44
+ def validate_location_params(params)
45
+ latitudes = params[0], params[2]
46
+ if latitudes.any? { |l| l.abs > 90 }
47
+ raise ArgumentError, 'Wrong latitude value'
48
+ end
49
+ longitudes = params[1], params[3]
50
+ if longitudes.any? { |l| l.abs > 180 }
51
+ raise ArgumentError, 'Wrong longitude value'
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/core_ext/hash/slice'
4
+
5
+ module GoogleMapsJuice
6
+ class Directions::Response < GoogleMapsJuice::Endpoint::Response
7
+ def results
8
+ self['routes']
9
+ end
10
+
11
+ def routes
12
+ results.map { |r| Route.new(r) }
13
+ end
14
+
15
+ def first
16
+ routes.first
17
+ end
18
+
19
+ class Route
20
+ attr_reader :route, :first_leg
21
+ def initialize(route)
22
+ @route = route
23
+ @first_leg = route['legs'].first
24
+ end
25
+
26
+ def legs
27
+ route['legs']
28
+ end
29
+
30
+ def summary
31
+ route['summary']
32
+ end
33
+
34
+ def steps
35
+ first_leg['steps']
36
+ end
37
+
38
+ def duration
39
+ first_leg['duration']
40
+ end
41
+
42
+ def distance
43
+ first_leg['distance']
44
+ end
45
+
46
+ def start_location
47
+ first_leg['start_location']
48
+ end
49
+
50
+ def end_location
51
+ first_leg['end_location']
52
+ end
53
+
54
+ def start_address
55
+ first_leg['start_address']
56
+ end
57
+
58
+ def end_address
59
+ first_leg['end_address']
60
+ end
61
+ end
62
+ end
63
+ end
@@ -14,7 +14,7 @@ module GoogleMapsJuice
14
14
  elsif response.limit_error?
15
15
  raise GoogleMapsJuice::ApiLimitError, build_error_message(response)
16
16
  elsif response.error?
17
- raise GoogleMapsJuice::Error, "API #{build_error_message(response)}"
17
+ raise GoogleMapsJuice::ResponseError, "API #{build_error_message(response)}"
18
18
  else
19
19
  response
20
20
  end
@@ -1,3 +1,3 @@
1
1
  module GoogleMapsJuice
2
- VERSION = "1.0.0"
2
+ VERSION = "1.1.0"
3
3
  end
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: google_maps_juice
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Algonauti srl
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-10-17 00:00:00.000000000 Z
11
+ date: 2020-07-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '5.2'
19
+ version: '0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '5.2'
26
+ version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: excon
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '1.16'
47
+ version: 1.17.2
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '1.16'
54
+ version: 1.17.2
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rake
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -159,6 +159,8 @@ files:
159
159
  - lib/google_maps_juice.rb
160
160
  - lib/google_maps_juice/client.rb
161
161
  - lib/google_maps_juice/configuration.rb
162
+ - lib/google_maps_juice/directions.rb
163
+ - lib/google_maps_juice/directions/response.rb
162
164
  - lib/google_maps_juice/endpoint.rb
163
165
  - lib/google_maps_juice/geocoding.rb
164
166
  - lib/google_maps_juice/geocoding/response.rb
@@ -183,8 +185,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
183
185
  - !ruby/object:Gem::Version
184
186
  version: '0'
185
187
  requirements: []
186
- rubyforge_project:
187
- rubygems_version: 2.7.3
188
+ rubygems_version: 3.0.3
188
189
  signing_key:
189
190
  specification_version: 4
190
191
  summary: 'Client for popular Google Maps API Services: Geocoding, Time Zones'