google_maps_service 0.1.0 → 0.2.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
  SHA1:
3
- metadata.gz: 8194de5bd5bef78a91fdf5f9933fed905eea1742
4
- data.tar.gz: 8f93d0c8990a0b1ef80317e50d5e067a951f8a1d
3
+ metadata.gz: 03d75b9918a795abfabe46f98659846b37979be9
4
+ data.tar.gz: 7a501e622f0d8898ad38b65b30e9957fce151aad
5
5
  SHA512:
6
- metadata.gz: 1cb6043a5dc3f03730d7cb280fe7b6925e15d2d84ab7b9bbb97a73f2c370cd6e7fb3ee65c1e3927b8a4143560943e71689c9920a1c1e26bbdcb9d275dd65fe55
7
- data.tar.gz: 91a08cee378d8ce7d9c03e6a1e4212c16ff7da6333a2181d1da90478f7bb93b0f73082656f250bdbb16b3e1cc4a749d25263f4aa85090cecb57a63d28d02bc56
6
+ metadata.gz: b67c6aac29d022afc1fb48106c436cfcec7f3370d1de7e7a5eb63f339ebe52ef198cd4f7e6797a2865ff7ea1566165ad40f6c413e92de58ccd27bc82140e965b
7
+ data.tar.gz: 972a7298efc5729bf9a1cba1f617a9dfdee1096fcc3056dcad1b705d792df8230e5fd48caed3009aeee552594a26c1ad00f2df3a362feee2898d5232fa40cf37
@@ -1,3 +1,5 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.2.1
3
+ - 2.2
4
+ - 2.1
5
+ - 2.0.0
data/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # Ruby Client for Google Maps Services
2
2
 
3
- *This is porting of [Python Client for Google Maps Services](https://github.com/googlemaps/google-maps-services-python). All Google Maps Service APIs are supported, but some features (e.g: auto retry) are not supported right now.*
3
+ [![Gem Version](https://badge.fury.io/rb/google_maps_service.svg)](http://badge.fury.io/rb/google_maps_service) [![Build Status](https://travis-ci.org/edwardsamuel/google-maps-services-ruby.svg?branch=master)](https://travis-ci.org/edwardsamuel/google-maps-services-ruby) [![Dependency Status](https://gemnasium.com/edwardsamuel/google-maps-services-ruby.svg)](https://gemnasium.com/edwardsamuel/google-maps-services-ruby) [![Code Climate](https://codeclimate.com/github/edwardsamuel/google-maps-services-ruby/badges/gpa.svg)](https://codeclimate.com/github/edwardsamuel/google-maps-services-ruby) [![Coverage Status](https://coveralls.io/repos/edwardsamuel/google-maps-services-ruby/badge.svg?branch=master&service=github)](https://coveralls.io/github/edwardsamuel/google-maps-services-ruby?branch=master)
4
+
5
+ *This is porting of [Python Client for Google Maps Services](https://github.com/googlemaps/google-maps-services-python). All Google Maps Service APIs are supported, but some features (e.g: rate limiting) are not supported right now.*
4
6
 
5
7
  ## Description
6
8
 
@@ -129,4 +131,4 @@ For more usage examples, check out [the tests](spec/).
129
131
  [Time Zone API]: https://developers.google.com/maps/documentation/timezone/
130
132
  [Roads API]: https://developers.google.com/maps/documentation/roads/
131
133
 
132
- [issues]: https://github.com/googlemaps/google-maps-services-python/issues
134
+ [issues]: https://github.com/edwardsamuel/google-maps-services-ruby/issues
@@ -19,8 +19,9 @@ Gem::Specification.new do |spec|
19
19
 
20
20
  spec.add_runtime_dependency 'multi_json', '~> 1.11'
21
21
  spec.add_runtime_dependency 'hurley', '~> 0.1'
22
+ spec.add_runtime_dependency 'retriable', '~> 2.0.2'
22
23
  spec.add_runtime_dependency 'ruby-hmac', '~> 0.4.0'
23
- spec.add_development_dependency 'bundler', '~> 1.8'
24
+ spec.add_development_dependency 'bundler', '~> 1.7'
24
25
  spec.add_development_dependency 'rake', '~> 10.0'
25
26
  spec.add_development_dependency 'yard', '~> 0.8.7.6'
26
27
  spec.add_development_dependency 'rspec', '~> 3.3'
@@ -1,6 +1,6 @@
1
1
  module GoogleMapsService
2
2
  class << self
3
- attr_accessor :key, :client_id, :client_secret, :ssl, :connection_middleware
3
+ attr_accessor :key, :client_id, :client_secret, :connect_timeout, :read_timeout, :retry_timeout
4
4
 
5
5
  def configure
6
6
  yield self
@@ -1,12 +1,13 @@
1
1
  require 'uri'
2
2
  require 'hurley'
3
3
  require 'multi_json'
4
+ require 'retriable'
4
5
 
5
6
  module GoogleMapsService
6
7
  class Client
7
8
  USER_AGENT = "GoogleGeoApiClientRuby/#{GoogleMapsService::VERSION}"
8
9
  DEFAULT_BASE_URL = "https://maps.googleapis.com"
9
- RETRIABLE_STATUSES = [500, 503, 504]
10
+ RETRIABLE_ERRORS = [GoogleMapsService::Error::ServerError, GoogleMapsService::Error::RateLimitError]
10
11
 
11
12
  include GoogleMapsService::Directions
12
13
  include GoogleMapsService::DistanceMatrix
@@ -28,10 +29,27 @@ module GoogleMapsService
28
29
  # @return [String]
29
30
  attr_reader :client_secret
30
31
 
32
+ # Connection timeout for HTTP requests, in seconds.
33
+ # You should specify read_timeout in addition to this option.
34
+ # @return [Integer]
35
+ attr_reader :connect_timeout
36
+
37
+ # Read timeout for HTTP requests, in seconds.
38
+ # You should specify connect_timeout in addition to this
39
+ # @return [Integer]
40
+ attr_reader :read_timeout
41
+
42
+ # Timeout across multiple retriable requests, in seconds.
43
+ # @return [Integer]
44
+ attr_reader :retry_timeout
45
+
31
46
  def initialize(options={})
32
47
  @key = options[:key] || GoogleMapsService.key
33
48
  @client_id = options[:client_id] || GoogleMapsService.client_id
34
49
  @client_secret = options[:client_secret] || GoogleMapsService.client_secret
50
+ @connect_timeout = options[:connect_timeout] || GoogleMapsService.connect_timeout
51
+ @read_timeout = options[:read_timeout] || GoogleMapsService.read_timeout
52
+ @retry_timeout = options[:retry_timeout] || GoogleMapsService.retry_timeout || 60
35
53
  end
36
54
 
37
55
  # Get the current HTTP client
@@ -47,18 +65,23 @@ module GoogleMapsService
47
65
  def new_client
48
66
  client = Hurley::Client.new
49
67
  client.request_options.query_class = Hurley::Query::Flat
68
+ client.request_options.timeout = @read_timeout if @read_timeout
69
+ client.request_options.open_timeout = @connect_timeout if @connect_timeout
50
70
  client.header[:user_agent] = USER_AGENT
51
71
  client
52
72
  end
53
73
 
54
74
  def get(path, params, base_url: DEFAULT_BASE_URL, accepts_client_id: true, custom_response_decoder: nil)
55
75
  url = base_url + generate_auth_url(path, params, accepts_client_id)
56
- response = client.get url
57
76
 
58
- if custom_response_decoder
59
- return custom_response_decoder.call(response)
77
+ Retriable.retriable timeout: @retry_timeout,
78
+ on: RETRIABLE_ERRORS do |try|
79
+ response = client.get url
80
+ if custom_response_decoder
81
+ return custom_response_decoder.call(response)
82
+ end
83
+ return decode_response_body(response)
60
84
  end
61
- return decode_response_body(response)
62
85
  end
63
86
 
64
87
  # Extract and parse body response as hash. Throw an error if there is something wrong with the response.
@@ -31,18 +31,9 @@ module GoogleMapsService
31
31
  # @return [Array] Pair of lat and lng array.
32
32
  def normalize_latlng(arg)
33
33
  if arg.kind_of?(Hash)
34
- if arg.has_key?(:lat) and arg.has_key?(:lng)
35
- return arg[:lat], arg[:lng]
36
- end
37
- if arg.has_key?(:latitude) and arg.has_key?(:longitude)
38
- return arg[:latitude], arg[:longitude]
39
- end
40
- if arg.has_key?("lat") and arg.has_key?("lng")
41
- return arg["lat"], arg["lng"]
42
- end
43
- if arg.has_key?("latitude") and arg.has_key?("longitude")
44
- return arg["latitude"], arg["longitude"]
45
- end
34
+ lat = arg[:lat] || arg[:latitude] || arg["lat"] || arg["latitude"]
35
+ lng = arg[:lng] || arg[:longitude] || arg["lng"] || arg["longitude"]
36
+ return lat, lng
46
37
  elsif arg.kind_of?(Array)
47
38
  return arg[0], arg[1]
48
39
  end
@@ -137,16 +128,34 @@ module GoogleMapsService
137
128
  # @return [String]
138
129
  def bounds(arg)
139
130
  if arg.kind_of?(Hash)
140
- if arg.has_key?("southwest") && arg.has_key?("northeast")
141
- return "#{latlng(arg["southwest"])}|#{latlng(arg["northeast"])}"
142
- elsif arg.has_key?(:southwest) && arg.has_key?(:northeast)
143
- return "#{latlng(arg[:southwest])}|#{latlng(arg[:northeast])}"
144
- end
131
+ southwest = arg[:southwest] || arg["southwest"]
132
+ northeast = arg[:northeast] || arg["northeast"]
133
+ return "#{latlng(southwest)}|#{latlng(northeast)}"
145
134
  end
146
135
 
147
136
  raise ArgumentError, "Expected a bounds (southwest/northeast) Hash, but got #{arg.class}"
148
137
  end
149
138
 
139
+ # Converts an array of waypoints (path) to the format expected by the Google Maps
140
+ # server.
141
+ #
142
+ # Accept two representation of waypoint:
143
+ #
144
+ # 1. String: Name of place or comma-separated lat/lon pair.
145
+ # 2. Hash/Array: Lat/lon pair.
146
+ #
147
+ # @param [Array, String, Hash] waypoints Path.
148
+ #
149
+ # @return [String]
150
+ def waypoints(waypoints)
151
+ if waypoints.kind_of?(Array) and waypoints.length == 2 and waypoints[0].kind_of?(Numeric) and waypoints[1].kind_of?(Numeric)
152
+ waypoints = [waypoints]
153
+ end
154
+
155
+ waypoints = as_list(waypoints)
156
+ return join_list('|', waypoints.map { |k| k.kind_of?(String) ? k : latlng(k) })
157
+ end
158
+
150
159
  # Decodes a Polyline string into a list of lat/lng hash.
151
160
  #
152
161
  # See the developer docs for a detailed description of this encoding:
@@ -1,3 +1,5 @@
1
+ require_relative './validator'
2
+
1
3
  module GoogleMapsService
2
4
 
3
5
  # Performs requests to the Google Maps Directions API.
@@ -47,14 +49,7 @@ module GoogleMapsService
47
49
  destination: _convert_waypoint(destination)
48
50
  }
49
51
 
50
- if mode
51
- # NOTE(broady): the mode parameter is not validated by the Maps API
52
- # server. Check here to prevent silent failures.
53
- unless ["driving", "walking", "bicycling", "transit"].include?(mode)
54
- raise ArgumentError, "Invalid travel mode."
55
- end
56
- params[:mode] = mode
57
- end
52
+ params[:mode] = GoogleMapsService::Validator.travel_mode(mode) if mode
58
53
 
59
54
  if waypoints
60
55
  waypoints = GoogleMapsService::Convert.as_list(waypoints)
@@ -64,8 +59,8 @@ module GoogleMapsService
64
59
  params[:waypoints] = GoogleMapsService::Convert.join_list("|", waypoints)
65
60
  end
66
61
 
67
- params[:alternatives] = "true" if alternatives
68
- params[:avoid] = GoogleMapsService::Convert.join_list("|", avoid) if avoid
62
+ params[:alternatives] = 'true' if alternatives
63
+ params[:avoid] = GoogleMapsService::Convert.join_list('|', avoid) if avoid
69
64
  params[:language] = language if language
70
65
  params[:units] = units if units
71
66
  params[:region] = region if region
@@ -73,13 +68,13 @@ module GoogleMapsService
73
68
  params[:arrival_time] = GoogleMapsService::Convert.time(arrival_time) if arrival_time
74
69
 
75
70
  if departure_time and arrival_time
76
- raise ArgumentError, "Should not specify both departure_time and arrival_time."
71
+ raise ArgumentError, 'Should not specify both departure_time and arrival_time.'
77
72
  end
78
73
 
79
74
  params[:transit_mode] = GoogleMapsService::Convert.join_list("|", transit_mode) if transit_mode
80
75
  params[:transit_routing_preference] = transit_routing_preference if transit_routing_preference
81
76
 
82
- return get("/maps/api/directions/json", params)[:routes]
77
+ return get('/maps/api/directions/json', params)[:routes]
83
78
  end
84
79
 
85
80
  private
@@ -1,3 +1,5 @@
1
+ require_relative './validator'
2
+
1
3
  module GoogleMapsService
2
4
 
3
5
  # Performs requests to the Google Maps Distance Matrix API.
@@ -39,47 +41,26 @@ module GoogleMapsService
39
41
  departure_time: nil, arrival_time: nil, transit_mode: nil,
40
42
  transit_routing_preference: nil)
41
43
  params = {
42
- origins: _convert_path(origins),
43
- destinations: _convert_path(destinations)
44
+ origins: GoogleMapsService::Convert.waypoints(origins),
45
+ destinations: GoogleMapsService::Convert.waypoints(destinations)
44
46
  }
45
47
 
46
- if mode
47
- # NOTE(broady): the mode parameter is not validated by the Maps API
48
- # server. Check here to prevent silent failures.
49
- unless ["driving", "walking", "bicycling", "transit"].include?(mode)
50
- raise ArgumentError, "Invalid travel mode."
51
- end
52
- params[:mode] = mode
53
- end
54
-
55
48
  params[:language] = language if language
56
-
57
- if avoid
58
- unless ["tolls", "highways", "ferries"].include?(avoid)
59
- raise ArgumentError, "Invalid route restriction."
60
- end
61
- params[:avoid] = avoid
62
- end
63
-
49
+ params[:mode] = GoogleMapsService::Validator.travel_mode(mode) if mode
50
+ params[:avoid] = GoogleMapsService::Validator.avoid(avoid) if avoid
64
51
 
65
52
  params[:units] = units if units
66
- params[:departure_time] = convert.time(departure_time) if departure_time
67
- params[:arrival_time] = convert.time(arrival_time) if arrival_time
53
+ params[:departure_time] = GoogleMapsService::Convert.time(departure_time) if departure_time
54
+ params[:arrival_time] = GoogleMapsService::Convert.time(arrival_time) if arrival_time
68
55
 
69
56
  if departure_time and arrival_time
70
- raise ArgumentError, "Should not specify both departure_time and arrival_time."
57
+ raise ArgumentError, 'Should not specify both departure_time and arrival_time.'
71
58
  end
72
59
 
73
- params[:transit_mode] = convert.join_list("|", transit_mode) if transit_mode
60
+ params[:transit_mode] = GoogleMapsService::Convert.join_list("|", transit_mode) if transit_mode
74
61
  params[:transit_routing_preference] = transit_routing_preference if transit_routing_preference
75
62
 
76
- return get("/maps/api/distancematrix/json", params)
63
+ return get('/maps/api/distancematrix/json', params)
77
64
  end
78
-
79
- private
80
- def _convert_path(waypoints)
81
- waypoints = GoogleMapsService::Convert.as_list(waypoints)
82
- return GoogleMapsService::Convert.join_list("|", waypoints.map { |k| k.kind_of?(String) ? k : GoogleMapsService::Convert.latlng(k) })
83
- end
84
65
  end
85
66
  end
@@ -27,11 +27,7 @@ module GoogleMapsService
27
27
  #
28
28
  # :rtype: A list of snapped points.
29
29
  def snap_to_roads(path: nil, interpolate: false)
30
- if path.kind_of?(Array) and path.length == 2 and not path[0].kind_of?(Array)
31
- path = [path]
32
- end
33
-
34
- path = _convert_path(path)
30
+ path = GoogleMapsService::Convert.waypoints(path)
35
31
 
36
32
  params = {
37
33
  path: path
@@ -71,12 +67,7 @@ module GoogleMapsService
71
67
  # @return [Hash] a dict with both a list of speed limits and a list of the snapped
72
68
  # points.
73
69
  def snapped_speed_limits(path: nil)
74
-
75
- if path.kind_of?(Array) and path.length == 2 and not path[0].kind_of?(Array)
76
- path = [path]
77
- end
78
-
79
- path = _convert_path(path)
70
+ path = GoogleMapsService::Convert.waypoints(path)
80
71
 
81
72
  params = {
82
73
  path: path
@@ -89,11 +80,6 @@ module GoogleMapsService
89
80
  end
90
81
 
91
82
  private
92
- def _convert_path(paths)
93
- paths = GoogleMapsService::Convert.as_list(paths)
94
- return GoogleMapsService::Convert.join_list("|", paths.map { |k| k.kind_of?(String) ? k : GoogleMapsService::Convert.latlng(k) })
95
- end
96
-
97
83
  # Extracts a result from a Roads API HTTP response.
98
84
  def extract_roads_body(response)
99
85
  begin
@@ -132,7 +118,7 @@ module GoogleMapsService
132
118
  end
133
119
 
134
120
  unless response.status_code == 200
135
- raise GoogleMapsService::Error::HTTPError.new(response)
121
+ raise GoogleMapsService::Error::ApiError.new(response)
136
122
  end
137
123
 
138
124
  return body
@@ -0,0 +1,23 @@
1
+ require_relative './convert'
2
+
3
+ module GoogleMapsService
4
+ module Validator
5
+ module_function
6
+
7
+ def travel_mode(mode)
8
+ # NOTE(broady): the mode parameter is not validated by the Maps API
9
+ # server. Check here to prevent silent failures.
10
+ unless [:driving, :walking, :bicycling, :transit].include?(mode.to_sym)
11
+ raise ArgumentError, 'Invalid travel mode.'
12
+ end
13
+ mode
14
+ end
15
+
16
+ def avoid(avoid)
17
+ unless [:tolls, :highways, :ferries].include?(avoid.to_sym)
18
+ raise ArgumentError, 'Invalid route restriction.'
19
+ end
20
+ avoid
21
+ end
22
+ end
23
+ end
@@ -1,3 +1,3 @@
1
1
  module GoogleMapsService
2
- VERSION = "0.1.0"
2
+ VERSION = '0.2.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: google_maps_service
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Edward Samuel Pasaribu
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-13 00:00:00.000000000 Z
11
+ date: 2015-09-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: multi_json
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0.1'
41
+ - !ruby/object:Gem::Dependency
42
+ name: retriable
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 2.0.2
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 2.0.2
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: ruby-hmac
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -58,14 +72,14 @@ dependencies:
58
72
  requirements:
59
73
  - - "~>"
60
74
  - !ruby/object:Gem::Version
61
- version: '1.8'
75
+ version: '1.7'
62
76
  type: :development
63
77
  prerelease: false
64
78
  version_requirements: !ruby/object:Gem::Requirement
65
79
  requirements:
66
80
  - - "~>"
67
81
  - !ruby/object:Gem::Version
68
- version: '1.8'
82
+ version: '1.7'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: rake
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -186,6 +200,7 @@ files:
186
200
  - lib/google_maps_service/geocoding.rb
187
201
  - lib/google_maps_service/roads.rb
188
202
  - lib/google_maps_service/time_zone.rb
203
+ - lib/google_maps_service/validator.rb
189
204
  - lib/google_maps_service/version.rb
190
205
  homepage: https://github.com/edwardsamuel/google-maps-services-ruby
191
206
  licenses: