google_maps_service 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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: