googlemaps-services 1.0.0 → 1.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: c10843ca035ec6fe71bd6edc2a338d2c0eee8c22
4
- data.tar.gz: 092b6d0d9398c95482a74ad88fd4192af0061517
3
+ metadata.gz: 79eb630dafebed0e332508c6dc831f9277c0265e
4
+ data.tar.gz: fe3a16fb698d040c80ad5cdedaf97234d3b6c3bf
5
5
  SHA512:
6
- metadata.gz: c08995e5da233ce70dc80694b8b5d479cb5a9ce05a253aef8df59bfa696a8e6f5861f1fa9495b393cf21163dd7eb84fc8aa056fe3691c2f552571db4cdff23ac
7
- data.tar.gz: 046dca085ea8c8d7000e7bab4adbadbbd680758feb3d752e919e823a4ac5bfc1144c312527db141a7a501c05277b35db294c7acff4d87e8e7a503ee2eec5fc6d
6
+ metadata.gz: 561e0cc11204546985cc8a970f95cbb6b4c90453af643b2f5edbd71525278e06f0a39be13f18927105462d250e407adc250acd2fa82041a900e31a4f1cec6e42
7
+ data.tar.gz: 1c6ae80c50a9038f2273b7da4f416bf0a759b9d6ba542a0359aa3e60f74d7404a0eb6e6ceb2a957ace35c7c4f45250322c7110cf9c1cd25c71cc2dbdf3b8c43f
@@ -1,6 +1,7 @@
1
1
  require "googlemaps/services/exceptions"
2
2
  require "googlemaps/services/version"
3
3
  require "googlemaps/services/util"
4
+ require "nokogiri"
4
5
  require "net/http"
5
6
  require "json"
6
7
 
@@ -38,10 +39,12 @@ module GoogleMaps
38
39
  attr_accessor :queries_per_second
39
40
  # @return [Symbol] keeps track of sent queries.
40
41
  attr_accessor :sent_times
42
+ # @return [Symbol] Response format. Either :json or :xml
43
+ attr_accessor :response_format
41
44
 
42
45
  def initialize(key:, client_id: nil, client_secret: nil, timeout: nil,
43
46
  connect_timeout: nil, read_timeout: nil,retry_timeout: 60, request_opts: nil,
44
- queries_per_second: 10, channel: nil)
47
+ queries_per_second: 10, channel: nil, response_format: :json)
45
48
  if !key && !(client_secret && client_id)
46
49
  raise StandardError, "Must provide API key or enterprise credentials when creationg client."
47
50
  end
@@ -85,6 +88,11 @@ module GoogleMaps
85
88
 
86
89
  self.queries_per_second = queries_per_second
87
90
  self.sent_times = Array.new
91
+
92
+ if response_format
93
+ raise StandardError, "Unsupported response format. Should be either :json or :xml." unless [:json, :xml].include? response_format
94
+ self.response_format = response_format
95
+ end
88
96
  end
89
97
 
90
98
  # Performs HTTP GET requests with credentials, returning the body as JSON or XML
@@ -167,7 +175,12 @@ module GoogleMaps
167
175
  if extract_body
168
176
  result = extract_body.call(resp)
169
177
  else
170
- result = get_json_body(resp)
178
+ case self.response_format
179
+ when :xml # XML response
180
+ result = get_xml_body(resp)
181
+ else # JSON response
182
+ result = get_json_body(resp)
183
+ end
171
184
  end
172
185
  self.sent_times.push(Util.current_time)
173
186
  return result
@@ -191,7 +204,7 @@ module GoogleMaps
191
204
  return resp["location"]
192
205
  end
193
206
 
194
- if resp.code.to_i != 200
207
+ if status_code != 200
195
208
  raise HTTPError.new(resp.code)
196
209
  end
197
210
 
@@ -199,7 +212,7 @@ module GoogleMaps
199
212
  begin
200
213
  body = JSON.parse(resp.body)
201
214
  rescue JSON::ParserError
202
- raise APIError.new(status_code), "Received a malformed response."
215
+ raise APIError.new(status_code), "Received a malformed JSON response."
203
216
  end
204
217
 
205
218
  api_status = body["status"]
@@ -218,6 +231,46 @@ module GoogleMaps
218
231
  end
219
232
  end
220
233
 
234
+ # Extracts the XML body of the HTTP response.
235
+ #
236
+ # @private
237
+ #
238
+ # @param [Net::HTTPResponse] resp HTTP response object.
239
+ #
240
+ # @return [Nokogiri::XML::Document] Valid XML document.
241
+ def get_xml_body(resp)
242
+ status_code = resp.code.to_i
243
+ if status_code >= 300 && status_code < 400
244
+ return resp["location"]
245
+ end
246
+
247
+ if status_code != 200
248
+ raise HTTPError.new(resp.code)
249
+ end
250
+
251
+ begin
252
+ doc = Nokogiri::XML.parse(resp.body)
253
+ rescue
254
+ raise APIError.new(status_code), "Received a malformed XML response."
255
+ end
256
+
257
+ api_status = doc.xpath("//status").first.text
258
+ if api_status == "OK" || api_status == "ZERO_RESULTS"
259
+ return doc
260
+ end
261
+
262
+ if api_status == "OVER_QUERY_LIMIT"
263
+ raise RetriableRequest
264
+ end
265
+
266
+ error_message = doc.xpath("//error_message")
267
+ if error_message
268
+ raise APIError.new(api_status), error_message.text
269
+ else
270
+ raise APIError.new(api_status)
271
+ end
272
+ end
273
+
221
274
  # Returns the path and query string portion of the request URL, first adding any necessary parameters.
222
275
  #
223
276
  # @private
@@ -247,7 +300,7 @@ module GoogleMaps
247
300
  raise StandardError, "Must provide API key for this API. It does not accept enterprise credentials."
248
301
  end
249
302
 
250
- private :get_json_body, :generate_auth_url
303
+ private :get_json_body, :get_xml_body, :generate_auth_url
251
304
  end
252
305
 
253
306
  end
@@ -42,7 +42,7 @@ module GoogleMaps
42
42
  # The traffic_model parameter may only be specified for requests where the travel mode is driving, and where the
43
43
  # request includes a departure_time.
44
44
  #
45
- # @return [Hash] Valid JSON or XML response.
45
+ # @return [Array, Nokogiri::XML::NodeSet] Valid JSON or XML response.
46
46
  def query(origin:, destination:, mode: nil, waypoints: nil, alternatives: false,
47
47
  avoid: nil, language: nil, units: nil, region: nil, departure_time: nil,
48
48
  arrival_time: nil, optimize_waypoints: false, transit_mode: nil,
@@ -111,7 +111,12 @@ module GoogleMaps
111
111
  params["traffic_model"] = traffic_model
112
112
  end
113
113
 
114
- self.client.get(url: "/maps/api/directions/json", params: params)["routes"]
114
+ case self.client.response_format
115
+ when :xml
116
+ self.client.get(url: "/maps/api/directions/xml", params: params).xpath("//route")
117
+ else
118
+ self.client.get(url: "/maps/api/directions/json", params: params)["routes"]
119
+ end
115
120
  end
116
121
  end
117
122
 
@@ -36,7 +36,7 @@ module GoogleMaps
36
36
  # @param [String] traffic_model Specifies the predictive travel time model to use. Valid values are "best_guess" or "optimistic" or "pessimistic".
37
37
  # The traffic_model parameter may only be specified for requests where the travel mode is driving, and where the request includes a departure_time.
38
38
  #
39
- # @return [Hash] Matrix of distances.
39
+ # @return [Hash, Nokogiri::XML::Document] Matrix of distances.
40
40
  def query(origins:, destinations:, mode: nil, language: nil, avoid: nil,
41
41
  units: nil, departure_time: nil, arrival_time: nil, transit_mode: nil,
42
42
  transit_routing_preference: nil, traffic_model: nil)
@@ -91,7 +91,7 @@ module GoogleMaps
91
91
  params["traffic_model"] = traffic_model
92
92
  end
93
93
 
94
- self.client.get(url: "/maps/api/distancematrix/json", params: params)
94
+ self.client.get(url: "/maps/api/distancematrix/#{self.client.response_format}", params: params).class
95
95
  end
96
96
  end
97
97
  end
@@ -24,7 +24,7 @@ module GoogleMaps
24
24
  # @param [String, Array] path An encoded polyline string, or an Array of lat/lng values from which to calculate elevation data.
25
25
  # @param [Integer] samples The number of sample points along a path for which to return elevation data.
26
26
  #
27
- # @return [String] Valid JSON or XML response.
27
+ # @return [Array, Nokogiri::XML::NodeSet] Valid JSON or XML response.
28
28
  def query(locations: [], path: nil, samples: 0)
29
29
  params = {}
30
30
 
@@ -48,7 +48,12 @@ module GoogleMaps
48
48
  params = { "path" => path, "samples" => samples }
49
49
  end
50
50
 
51
- self.client.get(url: "/maps/api/elevation/json", params: params)["results"]
51
+ case self.client.response_format
52
+ when :xml
53
+ self.client.get(url: "/maps/api/elevation/xml", params: params).xpath("//result")
54
+ else
55
+ self.client.get(url: "/maps/api/elevation/json", params: params)["results"]
56
+ end
52
57
  end
53
58
  end
54
59
 
@@ -29,7 +29,7 @@ module GoogleMaps
29
29
  # @param [String] region The region code, specified as a ccTLD ("top-level domain") two-character value.
30
30
  # @param [String] language The language in which to return results.
31
31
  #
32
- # @return [String] Valid JSON or XML response.
32
+ # @return [Array, Nokogiri::XML::NodeSet] Valid JSON or XML response.
33
33
  def query(address: nil, components: nil, bounds: nil, region: nil, language: nil)
34
34
  params = {}
35
35
 
@@ -53,7 +53,12 @@ module GoogleMaps
53
53
  params["language"] = language
54
54
  end
55
55
 
56
- self.client.get(url: "/maps/api/geocode/json", params: params)["results"]
56
+ case self.client.response_format
57
+ when :xml
58
+ self.client.get(url: "/maps/api/geocode/xml", params: params).xpath("//result")
59
+ else
60
+ self.client.get(url: "/maps/api/geocode/json", params: params)["results"]
61
+ end
57
62
  end
58
63
  end
59
64
 
@@ -98,7 +103,12 @@ module GoogleMaps
98
103
  params["language"] = language
99
104
  end
100
105
 
101
- self.client.get(url: "/maps/api/geocode/json", params: params)["results"]
106
+ case self.client.response_format
107
+ when :xml
108
+ self.client.get(url: "/maps/api/geocode/xml", params: params).xpath("//result")
109
+ else
110
+ self.client.get(url: "/maps/api/geocode/json", params: params)["results"]
111
+ end
102
112
  end
103
113
  end
104
114
 
@@ -24,7 +24,7 @@ module GoogleMaps
24
24
  # @param [String] type Restricts the results to places matching the specified type. The full list of supported types is available here: https://developers.google.com/places/supported_types
25
25
  # @param [String] page_token Token from a previous search that when provided will returns the next page of results for the same search.
26
26
  #
27
- # @return [Hash] Valid JSON or XML response.
27
+ # @return [Hash, Nokogiri::XML::Document] Valid JSON or XML response.
28
28
  def search(query:, location: nil, radius: nil, language: nil, min_price: nil,
29
29
  max_price: nil, open_now: false, type: nil, page_token: nil)
30
30
  _places(url_part: "text", query: query, location: location, radius: radius,
@@ -46,7 +46,7 @@ module GoogleMaps
46
46
  # @param [String] type Restricts the results to places matching the specified type. The full list of supported types is available here: https://developers.google.com/places/supported_types
47
47
  # @param [String] page_token Token from a previous search that when provided will returns the next page of results for the same search.
48
48
  #
49
- # @return [Hash] Valid JSON or XML response.
49
+ # @return [Hash, Nokogiri::XML::Document] Valid JSON or XML response.
50
50
  def nearby(location:, radius: nil, keyword: nil, language: nil, min_price: nil,
51
51
  max_price: nil, name: nil, open_now: false, rank_by: nil, type: nil, page_token: nil)
52
52
  if rank_by == "distance"
@@ -73,7 +73,7 @@ module GoogleMaps
73
73
  # @param [TrueClass, FalseClass] open_now Return only those places that are open for business at the time the query is sent.
74
74
  # @param [String] type: Restricts the results to places matching the specified type. The full list of supported types is available here: https://developers.google.com/places/supported_types
75
75
  #
76
- # @return [Hash] Valid JSON or XML response.
76
+ # @return [Hash, Nokogiri::XML::Document] Valid JSON or XML response.
77
77
  def radar(location:, radius:, keyword: nil, min_price: nil,
78
78
  max_price: nil, name: nil, open_now: false, type: nil)
79
79
  if !(keyword || name || type)
@@ -132,7 +132,7 @@ module GoogleMaps
132
132
  params["pagetoken"] = page_token
133
133
  end
134
134
 
135
- self.client.get(url: "/maps/api/place/#{url_part}search/json", params: params)
135
+ self.client.get(url: "/maps/api/place/#{url_part}search/#{self.client.response_format}", params: params)
136
136
  end
137
137
 
138
138
 
@@ -141,14 +141,14 @@ module GoogleMaps
141
141
  # @param [String] place_id A textual identifier that uniquely identifies a place, returned from a Places search.
142
142
  # @param [String] language The language in which to return results.
143
143
  #
144
- # @return [Hash] Valid JSON or XML response.
144
+ # @return [Hash, Nokogiri::XML::Document] Valid JSON or XML response.
145
145
  def place_details(place_id:, language: nil)
146
146
  params = { "placeid" => place_id }
147
147
  if language
148
148
  params["language"] = language
149
149
  end
150
150
 
151
- self.client.get(url: "/maps/api/place/details/json", params: params)
151
+ self.client.get(url: "/maps/api/place/details/#{self.client.response_format}", params: params)
152
152
  end
153
153
 
154
154
  # Downloads a photo from the Places API.
@@ -186,7 +186,7 @@ module GoogleMaps
186
186
  # @param [String] type Restricts the results to places matching the specified type. The full list of supported types is available here: https://developers.google.com/places/web-service/autocomplete#place_types
187
187
  # @param [Hash] components A component filter for which you wish to obtain a geocode, e.g. "{'administrative_area': 'TX','country': 'US'}"
188
188
  #
189
- # @return [Array] Array of predictions.
189
+ # @return [Array, Nokogiri::XML::NodeSet] Array of predictions.
190
190
  def autocomplete(input_text:, offset: nil, location: nil, radius: nil, language: nil, type: nil, components: nil)
191
191
  _autocomplete(url_part: "", input_text: input_text, offset: offset, location: location,
192
192
  radius: radius, language: language, type: type, components: components)
@@ -200,7 +200,7 @@ module GoogleMaps
200
200
  # @param [Integer] radius Distance in meters within which to bias results.
201
201
  # @param [String] language The language in which to return results.
202
202
  #
203
- # @return [Array] Array of predictions.
203
+ # @return [Array, Nokogiri::XML::NodeSet] Array of predictions.
204
204
  def autocomplete_query(input_text:, offset: nil, location: nil, radius: nil, language: nil)
205
205
  _autocomplete(url_part: "query", input_text: input_text, offset: offset,
206
206
  location: location, radius: radius, language: language)
@@ -236,7 +236,12 @@ module GoogleMaps
236
236
  params["components"] = Convert.components(components)
237
237
  end
238
238
 
239
- self.client.get(url: "/maps/api/place/#{url_part}autocomplete/json", params: params)["predictions"]
239
+ case self.client.response_format
240
+ when :xml
241
+ self.client.get(url: "/maps/api/place/#{url_part}autocomplete/xml", params: params).xpath("//prediction")
242
+ else
243
+ self.client.get(url: "/maps/api/place/#{url_part}autocomplete/json", params: params)["predictions"]
244
+ end
240
245
  end
241
246
 
242
247
  private :_places, :_autocomplete
@@ -35,7 +35,7 @@ module GoogleMaps
35
35
  params["language"] = language
36
36
  end
37
37
 
38
- self.client.get(url: "/maps/api/timezone/json", params: params)
38
+ self.client.get(url: "/maps/api/timezone/#{self.client.response_format}", params: params)
39
39
  end
40
40
  end
41
41
 
@@ -1,5 +1,5 @@
1
1
  module GoogleMaps
2
2
  module Services
3
- VERSION = "1.0.0"
3
+ VERSION = "1.2.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,15 +1,35 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: googlemaps-services
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Faissal Elamraoui
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-09-07 00:00:00.000000000 Z
11
+ date: 2016-09-28 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: nokogiri
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 1.6.8
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '1.6'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 1.6.8
13
33
  - !ruby/object:Gem::Dependency
14
34
  name: bundler
15
35
  requirement: !ruby/object:Gem::Requirement
@@ -53,14 +73,13 @@ dependencies:
53
73
  - !ruby/object:Gem::Version
54
74
  version: '3.0'
55
75
  description: This library brings the Google Maps API Web Services to your Ruby/RoR
56
- application
76
+ application. It supports both JSON and XML response formats.
57
77
  email:
58
78
  - amr.faissal@gmail.com
59
79
  executables: []
60
80
  extensions: []
61
81
  extra_rdoc_files: []
62
82
  files:
63
- - lib/googlemaps/services.rb
64
83
  - lib/googlemaps/services/client.rb
65
84
  - lib/googlemaps/services/directions.rb
66
85
  - lib/googlemaps/services/distancematrix.rb
@@ -1 +0,0 @@
1
- require "googlemaps/services/version"