cure-google-api-client 0.8.7.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +178 -0
  3. data/Gemfile +9 -0
  4. data/LICENSE +202 -0
  5. data/README.md +218 -0
  6. data/Rakefile +41 -0
  7. data/google-api-client.gemspec +43 -0
  8. data/lib/cacerts.pem +2183 -0
  9. data/lib/compat/multi_json.rb +19 -0
  10. data/lib/google/api_client.rb +750 -0
  11. data/lib/google/api_client/auth/compute_service_account.rb +28 -0
  12. data/lib/google/api_client/auth/file_storage.rb +59 -0
  13. data/lib/google/api_client/auth/installed_app.rb +126 -0
  14. data/lib/google/api_client/auth/jwt_asserter.rb +126 -0
  15. data/lib/google/api_client/auth/key_utils.rb +93 -0
  16. data/lib/google/api_client/auth/pkcs12.rb +41 -0
  17. data/lib/google/api_client/auth/storage.rb +102 -0
  18. data/lib/google/api_client/auth/storages/file_store.rb +58 -0
  19. data/lib/google/api_client/auth/storages/redis_store.rb +54 -0
  20. data/lib/google/api_client/batch.rb +326 -0
  21. data/lib/google/api_client/charset.rb +33 -0
  22. data/lib/google/api_client/client_secrets.rb +179 -0
  23. data/lib/google/api_client/discovery.rb +19 -0
  24. data/lib/google/api_client/discovery/api.rb +310 -0
  25. data/lib/google/api_client/discovery/media.rb +77 -0
  26. data/lib/google/api_client/discovery/method.rb +363 -0
  27. data/lib/google/api_client/discovery/resource.rb +156 -0
  28. data/lib/google/api_client/discovery/schema.rb +117 -0
  29. data/lib/google/api_client/environment.rb +42 -0
  30. data/lib/google/api_client/errors.rb +65 -0
  31. data/lib/google/api_client/gzip.rb +28 -0
  32. data/lib/google/api_client/logging.rb +32 -0
  33. data/lib/google/api_client/media.rb +259 -0
  34. data/lib/google/api_client/railtie.rb +18 -0
  35. data/lib/google/api_client/reference.rb +27 -0
  36. data/lib/google/api_client/request.rb +350 -0
  37. data/lib/google/api_client/result.rb +255 -0
  38. data/lib/google/api_client/service.rb +233 -0
  39. data/lib/google/api_client/service/batch.rb +110 -0
  40. data/lib/google/api_client/service/request.rb +144 -0
  41. data/lib/google/api_client/service/resource.rb +40 -0
  42. data/lib/google/api_client/service/result.rb +162 -0
  43. data/lib/google/api_client/service/simple_file_store.rb +151 -0
  44. data/lib/google/api_client/service/stub_generator.rb +61 -0
  45. data/lib/google/api_client/service_account.rb +21 -0
  46. data/lib/google/api_client/version.rb +26 -0
  47. data/spec/google/api_client/auth/storage_spec.rb +122 -0
  48. data/spec/google/api_client/auth/storages/file_store_spec.rb +40 -0
  49. data/spec/google/api_client/auth/storages/redis_store_spec.rb +70 -0
  50. data/spec/google/api_client/batch_spec.rb +248 -0
  51. data/spec/google/api_client/client_secrets_spec.rb +53 -0
  52. data/spec/google/api_client/discovery_spec.rb +708 -0
  53. data/spec/google/api_client/gzip_spec.rb +98 -0
  54. data/spec/google/api_client/media_spec.rb +178 -0
  55. data/spec/google/api_client/request_spec.rb +29 -0
  56. data/spec/google/api_client/result_spec.rb +207 -0
  57. data/spec/google/api_client/service_account_spec.rb +169 -0
  58. data/spec/google/api_client/service_spec.rb +618 -0
  59. data/spec/google/api_client/simple_file_store_spec.rb +133 -0
  60. data/spec/google/api_client_spec.rb +352 -0
  61. data/spec/spec_helper.rb +66 -0
  62. metadata +339 -0
@@ -0,0 +1,18 @@
1
+ require 'rails/railtie'
2
+ require 'google/api_client/logging'
3
+
4
+ module Google
5
+ class APIClient
6
+
7
+ ##
8
+ # Optional support class for Rails. Currently replaces the built-in logger
9
+ # with Rails' application log.
10
+ #
11
+ class Railtie < Rails::Railtie
12
+ initializer 'google-api-client' do |app|
13
+ logger = app.config.logger || Rails.logger
14
+ Google::APIClient.logger = logger unless logger.nil?
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,27 @@
1
+ # Copyright 2010 Google Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'google/api_client/request'
16
+
17
+ module Google
18
+ class APIClient
19
+ ##
20
+ # Subclass of Request for backwards compatibility with pre-0.5.0 versions of the library
21
+ #
22
+ # @deprecated
23
+ # use {Google::APIClient::Request} instead
24
+ class Reference < Request
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,350 @@
1
+ # Copyright 2010 Google Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'faraday'
16
+ require 'faraday/request/multipart'
17
+ require 'compat/multi_json'
18
+ require 'addressable/uri'
19
+ require 'stringio'
20
+ require 'google/api_client/discovery'
21
+ require 'google/api_client/logging'
22
+
23
+ module Google
24
+ class APIClient
25
+
26
+ ##
27
+ # Represents an API request.
28
+ class Request
29
+ include Google::APIClient::Logging
30
+
31
+ MULTIPART_BOUNDARY = "-----------RubyApiMultipartPost".freeze
32
+
33
+ # @return [Hash] Request parameters
34
+ attr_reader :parameters
35
+ # @return [Hash] Additional HTTP headers
36
+ attr_reader :headers
37
+ # @return [Google::APIClient::Method] API method to invoke
38
+ attr_reader :api_method
39
+ # @return [Google::APIClient::UploadIO] File to upload
40
+ attr_accessor :media
41
+ # @return [#generated_authenticated_request] User credentials
42
+ attr_accessor :authorization
43
+ # @return [TrueClass,FalseClass] True if request should include credentials
44
+ attr_accessor :authenticated
45
+ # @return [#read, #to_str] Request body
46
+ attr_accessor :body
47
+
48
+ ##
49
+ # Build a request
50
+ #
51
+ # @param [Hash] options
52
+ # @option options [Hash, Array] :parameters
53
+ # Request parameters for the API method.
54
+ # @option options [Google::APIClient::Method] :api_method
55
+ # API method to invoke. Either :api_method or :uri must be specified
56
+ # @option options [TrueClass, FalseClass] :authenticated
57
+ # True if request should include credentials. Implicitly true if
58
+ # unspecified and :authorization present
59
+ # @option options [#generate_signed_request] :authorization
60
+ # OAuth credentials
61
+ # @option options [Google::APIClient::UploadIO] :media
62
+ # File to upload, if media upload request
63
+ # @option options [#to_json, #to_hash] :body_object
64
+ # Main body of the API request. Typically hash or object that can
65
+ # be serialized to JSON
66
+ # @option options [#read, #to_str] :body
67
+ # Raw body to send in POST/PUT requests
68
+ # @option options [String, Addressable::URI] :uri
69
+ # URI to request. Either :api_method or :uri must be specified
70
+ # @option options [String, Symbol] :http_method
71
+ # HTTP method when requesting a URI
72
+ def initialize(options={})
73
+ @parameters = Faraday::Utils::ParamsHash.new
74
+ @headers = Faraday::Utils::Headers.new
75
+
76
+ self.parameters.merge!(options[:parameters]) unless options[:parameters].nil?
77
+ self.headers.merge!(options[:headers]) unless options[:headers].nil?
78
+ self.api_method = options[:api_method]
79
+ self.authenticated = options[:authenticated]
80
+ self.authorization = options[:authorization]
81
+
82
+ # These parameters are handled differently because they're not
83
+ # parameters to the API method, but rather to the API system.
84
+ self.parameters['key'] ||= options[:key] if options[:key]
85
+ self.parameters['userIp'] ||= options[:user_ip] if options[:user_ip]
86
+
87
+ if options[:media]
88
+ self.initialize_media_upload(options)
89
+ elsif options[:body]
90
+ self.body = options[:body]
91
+ elsif options[:body_object]
92
+ self.headers['Content-Type'] ||= 'application/json'
93
+ self.body = serialize_body(options[:body_object])
94
+ else
95
+ self.body = ''
96
+ end
97
+
98
+ unless self.api_method
99
+ self.http_method = options[:http_method] || 'GET'
100
+ self.uri = options[:uri]
101
+ end
102
+ end
103
+
104
+ # @!attribute [r] upload_type
105
+ # @return [String] protocol used for upload
106
+ def upload_type
107
+ return self.parameters['uploadType'] || self.parameters['upload_type']
108
+ end
109
+
110
+ # @!attribute http_method
111
+ # @return [Symbol] HTTP method if invoking a URI
112
+ def http_method
113
+ return @http_method ||= self.api_method.http_method.to_s.downcase.to_sym
114
+ end
115
+
116
+ def http_method=(new_http_method)
117
+ if new_http_method.kind_of?(Symbol)
118
+ @http_method = new_http_method.to_s.downcase.to_sym
119
+ elsif new_http_method.respond_to?(:to_str)
120
+ @http_method = new_http_method.to_s.downcase.to_sym
121
+ else
122
+ raise TypeError,
123
+ "Expected String or Symbol, got #{new_http_method.class}."
124
+ end
125
+ end
126
+
127
+ def api_method=(new_api_method)
128
+ if new_api_method.nil? || new_api_method.kind_of?(Google::APIClient::Method)
129
+ @api_method = new_api_method
130
+ else
131
+ raise TypeError,
132
+ "Expected Google::APIClient::Method, got #{new_api_method.class}."
133
+ end
134
+ end
135
+
136
+ # @!attribute uri
137
+ # @return [Addressable::URI] URI to send request
138
+ def uri
139
+ return @uri ||= self.api_method.generate_uri(self.parameters)
140
+ end
141
+
142
+ def uri=(new_uri)
143
+ @uri = Addressable::URI.parse(new_uri)
144
+ @parameters.update(@uri.query_values) unless @uri.query_values.nil?
145
+ end
146
+
147
+
148
+ # Transmits the request with the given connection
149
+ #
150
+ # @api private
151
+ #
152
+ # @param [Faraday::Connection] connection
153
+ # the connection to transmit with
154
+ # @param [TrueValue,FalseValue] is_retry
155
+ # True if request has been previous sent
156
+ #
157
+ # @return [Google::APIClient::Result]
158
+ # result of API request
159
+ def send(connection, is_retry = false)
160
+ self.body.rewind if is_retry && self.body.respond_to?(:rewind)
161
+ env = self.to_env(connection)
162
+ logger.debug { "#{self.class} Sending API request #{env[:method]} #{env[:url].to_s} #{env[:request_headers]}" }
163
+ http_response = connection.app.call(env)
164
+ result = self.process_http_response(http_response)
165
+
166
+ logger.debug { "#{self.class} Result: #{result.status} #{result.headers}" }
167
+
168
+ # Resumamble slightly different than other upload protocols in that it requires at least
169
+ # 2 requests.
170
+ if result.status == 200 && self.upload_type == 'resumable' && self.media
171
+ upload = result.resumable_upload
172
+ unless upload.complete?
173
+ logger.debug { "#{self.class} Sending upload body" }
174
+ result = upload.send(connection)
175
+ end
176
+ end
177
+ return result
178
+ end
179
+
180
+ # Convert to an HTTP request. Returns components in order of method, URI,
181
+ # request headers, and body
182
+ #
183
+ # @api private
184
+ #
185
+ # @return [Array<(Symbol, Addressable::URI, Hash, [#read,#to_str])>]
186
+ def to_http_request
187
+ request = (
188
+ if self.api_method
189
+ self.api_method.generate_request(self.parameters, self.body, self.headers)
190
+ elsif self.uri
191
+ unless self.parameters.empty?
192
+ self.uri.query = Addressable::URI.form_encode(self.parameters)
193
+ end
194
+ [self.http_method, self.uri.to_s, self.headers, self.body]
195
+ end)
196
+ return request
197
+ end
198
+
199
+ ##
200
+ # Hashified verison of the API request
201
+ #
202
+ # @return [Hash]
203
+ def to_hash
204
+ options = {}
205
+ if self.api_method
206
+ options[:api_method] = self.api_method
207
+ options[:parameters] = self.parameters
208
+ else
209
+ options[:http_method] = self.http_method
210
+ options[:uri] = self.uri
211
+ end
212
+ options[:headers] = self.headers
213
+ options[:body] = self.body
214
+ options[:media] = self.media
215
+ unless self.authorization.nil?
216
+ options[:authorization] = self.authorization
217
+ end
218
+ return options
219
+ end
220
+
221
+ ##
222
+ # Prepares the request for execution, building a hash of parts
223
+ # suitable for sending to Faraday::Connection.
224
+ #
225
+ # @api private
226
+ #
227
+ # @param [Faraday::Connection] connection
228
+ # Connection for building the request
229
+ #
230
+ # @return [Hash]
231
+ # Encoded request
232
+ def to_env(connection)
233
+ method, uri, headers, body = self.to_http_request
234
+ http_request = connection.build_request(method) do |req|
235
+ req.url(uri.to_s)
236
+ req.headers.update(headers)
237
+ req.body = body
238
+ end
239
+
240
+ if self.authorization.respond_to?(:generate_authenticated_request)
241
+ http_request = self.authorization.generate_authenticated_request(
242
+ :request => http_request,
243
+ :connection => connection
244
+ )
245
+ end
246
+
247
+ http_request.to_env(connection)
248
+ end
249
+
250
+ ##
251
+ # Convert HTTP response to an API Result
252
+ #
253
+ # @api private
254
+ #
255
+ # @param [Faraday::Response] response
256
+ # HTTP response
257
+ #
258
+ # @return [Google::APIClient::Result]
259
+ # Processed API response
260
+ def process_http_response(response)
261
+ Result.new(self, response)
262
+ end
263
+
264
+ protected
265
+
266
+ ##
267
+ # Adjust headers & body for media uploads
268
+ #
269
+ # @api private
270
+ #
271
+ # @param [Hash] options
272
+ # @option options [Hash, Array] :parameters
273
+ # Request parameters for the API method.
274
+ # @option options [Google::APIClient::UploadIO] :media
275
+ # File to upload, if media upload request
276
+ # @option options [#to_json, #to_hash] :body_object
277
+ # Main body of the API request. Typically hash or object that can
278
+ # be serialized to JSON
279
+ # @option options [#read, #to_str] :body
280
+ # Raw body to send in POST/PUT requests
281
+ def initialize_media_upload(options)
282
+ self.media = options[:media]
283
+ case self.upload_type
284
+ when "media"
285
+ if options[:body] || options[:body_object]
286
+ raise ArgumentError, "Can not specify body & body object for simple uploads"
287
+ end
288
+ self.headers['Content-Type'] ||= self.media.content_type
289
+ self.headers['Content-Length'] ||= self.media.length.to_s
290
+ self.body = self.media
291
+ when "multipart"
292
+ unless options[:body_object]
293
+ raise ArgumentError, "Multipart requested but no body object"
294
+ end
295
+ metadata = StringIO.new(serialize_body(options[:body_object]))
296
+ build_multipart([Faraday::UploadIO.new(metadata, 'application/json', 'file.json'), self.media])
297
+ when "resumable"
298
+ file_length = self.media.length
299
+ self.headers['X-Upload-Content-Type'] = self.media.content_type
300
+ self.headers['X-Upload-Content-Length'] = file_length.to_s
301
+ if options[:body_object]
302
+ self.headers['Content-Type'] ||= 'application/json'
303
+ self.body = serialize_body(options[:body_object])
304
+ else
305
+ self.body = ''
306
+ end
307
+ end
308
+ end
309
+
310
+ ##
311
+ # Assemble a multipart message from a set of parts
312
+ #
313
+ # @api private
314
+ #
315
+ # @param [Array<[#read,#to_str]>] parts
316
+ # Array of parts to encode.
317
+ # @param [String] mime_type
318
+ # MIME type of the message
319
+ # @param [String] boundary
320
+ # Boundary for separating each part of the message
321
+ def build_multipart(parts, mime_type = 'multipart/related', boundary = MULTIPART_BOUNDARY)
322
+ env = Faraday::Env.new
323
+ env.request = Faraday::RequestOptions.new
324
+ env.request.boundary = boundary
325
+ env.request_headers = {'Content-Type' => "#{mime_type};boundary=#{boundary}"}
326
+ multipart = Faraday::Request::Multipart.new
327
+ self.body = multipart.create_multipart(env, parts.map {|part| [nil, part]})
328
+ self.headers.update(env[:request_headers])
329
+ end
330
+
331
+ ##
332
+ # Serialize body object to JSON
333
+ #
334
+ # @api private
335
+ #
336
+ # @param [#to_json,#to_hash] body
337
+ # object to serialize
338
+ #
339
+ # @return [String]
340
+ # JSON
341
+ def serialize_body(body)
342
+ return body.to_json if body.respond_to?(:to_json)
343
+ return MultiJson.dump(body.to_hash) if body.respond_to?(:to_hash)
344
+ raise TypeError, 'Could not convert body object to JSON.' +
345
+ 'Must respond to :to_json or :to_hash.'
346
+ end
347
+
348
+ end
349
+ end
350
+ end
@@ -0,0 +1,255 @@
1
+ # Copyright 2010 Google Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+
16
+ module Google
17
+ class APIClient
18
+ ##
19
+ # This class wraps a result returned by an API call.
20
+ class Result
21
+ extend Forwardable
22
+
23
+ ##
24
+ # Init the result
25
+ #
26
+ # @param [Google::APIClient::Request] request
27
+ # The original request
28
+ # @param [Faraday::Response] response
29
+ # Raw HTTP Response
30
+ def initialize(request, response)
31
+ @request = request
32
+ @response = response
33
+ @media_upload = reference if reference.kind_of?(ResumableUpload)
34
+ end
35
+
36
+ # @return [Google::APIClient::Request] Original request object
37
+ attr_reader :request
38
+ # @return [Faraday::Response] HTTP response
39
+ attr_reader :response
40
+ # @!attribute [r] reference
41
+ # @return [Google::APIClient::Request] Original request object
42
+ # @deprecated See {#request}
43
+ alias_method :reference, :request # For compatibility with pre-beta clients
44
+
45
+ # @!attribute [r] status
46
+ # @return [Fixnum] HTTP status code
47
+ # @!attribute [r] headers
48
+ # @return [Hash] HTTP response headers
49
+ # @!attribute [r] body
50
+ # @return [String] HTTP response body
51
+ def_delegators :@response, :status, :headers, :body
52
+
53
+ # @!attribute [r] resumable_upload
54
+ # @return [Google::APIClient::ResumableUpload] For resuming media uploads
55
+ def resumable_upload
56
+ @media_upload ||= (
57
+ options = self.reference.to_hash.merge(
58
+ :uri => self.headers['location'],
59
+ :media => self.reference.media
60
+ )
61
+ Google::APIClient::ResumableUpload.new(options)
62
+ )
63
+ end
64
+
65
+ ##
66
+ # Get the content type of the response
67
+ # @!attribute [r] media_type
68
+ # @return [String]
69
+ # Value of content-type header
70
+ def media_type
71
+ _, content_type = self.headers.detect do |h, v|
72
+ h.downcase == 'Content-Type'.downcase
73
+ end
74
+ if content_type
75
+ return content_type[/^([^;]*);?.*$/, 1].strip.downcase
76
+ else
77
+ return nil
78
+ end
79
+ end
80
+
81
+ ##
82
+ # Check if request failed
83
+ #
84
+ # @!attribute [r] error?
85
+ # @return [TrueClass, FalseClass]
86
+ # true if result of operation is an error
87
+ def error?
88
+ return self.response.status >= 400
89
+ end
90
+
91
+ ##
92
+ # Check if request was successful
93
+ #
94
+ # @!attribute [r] success?
95
+ # @return [TrueClass, FalseClass]
96
+ # true if result of operation was successful
97
+ def success?
98
+ return !self.error?
99
+ end
100
+
101
+ ##
102
+ # Extracts error messages from the response body
103
+ #
104
+ # @!attribute [r] error_message
105
+ # @return [String]
106
+ # error message, if available
107
+ def error_message
108
+ if self.data?
109
+ if self.data.respond_to?(:error) &&
110
+ self.data.error.respond_to?(:message)
111
+ # You're going to get a terrible error message if the response isn't
112
+ # parsed successfully as an error.
113
+ return self.data.error.message
114
+ elsif self.data['error'] && self.data['error']['message']
115
+ return self.data['error']['message']
116
+ end
117
+ end
118
+ return self.body
119
+ end
120
+
121
+ ##
122
+ # Check for parsable data in response
123
+ #
124
+ # @!attribute [r] data?
125
+ # @return [TrueClass, FalseClass]
126
+ # true if body can be parsed
127
+ def data?
128
+ !(self.body.nil? || self.body.empty? || self.media_type != 'application/json')
129
+ end
130
+
131
+ ##
132
+ # Return parsed version of the response body.
133
+ #
134
+ # @!attribute [r] data
135
+ # @return [Object, Hash, String]
136
+ # Object if body parsable from API schema, Hash if JSON, raw body if unable to parse
137
+ def data
138
+ return @data ||= (begin
139
+ if self.data?
140
+ media_type = self.media_type
141
+ data = self.body
142
+ case media_type
143
+ when 'application/json'
144
+ data = MultiJson.load(data)
145
+ # Strip data wrapper, if present
146
+ data = data['data'] if data.has_key?('data')
147
+ else
148
+ raise ArgumentError,
149
+ "Content-Type not supported for parsing: #{media_type}"
150
+ end
151
+ if @request.api_method && @request.api_method.response_schema
152
+ # Automatically parse using the schema designated for the
153
+ # response of this API method.
154
+ data = @request.api_method.response_schema.new(data)
155
+ data
156
+ else
157
+ # Otherwise, return the raw unparsed value.
158
+ # This value must be indexable like a Hash.
159
+ data
160
+ end
161
+ end
162
+ end)
163
+ end
164
+
165
+ ##
166
+ # Get the token used for requesting the next page of data
167
+ #
168
+ # @!attribute [r] next_page_token
169
+ # @return [String]
170
+ # next page token
171
+ def next_page_token
172
+ if self.data.respond_to?(:next_page_token)
173
+ return self.data.next_page_token
174
+ elsif self.data.respond_to?(:[])
175
+ return self.data["nextPageToken"]
176
+ else
177
+ raise TypeError, "Data object did not respond to #next_page_token."
178
+ end
179
+ end
180
+
181
+ ##
182
+ # Build a request for fetching the next page of data
183
+ #
184
+ # @return [Google::APIClient::Request]
185
+ # API request for retrieving next page, nil if no page token available
186
+ def next_page
187
+ return nil unless self.next_page_token
188
+ merged_parameters = Hash[self.reference.parameters].merge({
189
+ self.page_token_param => self.next_page_token
190
+ })
191
+ # Because Requests can be coerced to Hashes, we can merge them,
192
+ # preserving all context except the API method parameters that we're
193
+ # using for pagination.
194
+ return Google::APIClient::Request.new(
195
+ Hash[self.reference].merge(:parameters => merged_parameters)
196
+ )
197
+ end
198
+
199
+ ##
200
+ # Get the token used for requesting the previous page of data
201
+ #
202
+ # @!attribute [r] prev_page_token
203
+ # @return [String]
204
+ # previous page token
205
+ def prev_page_token
206
+ if self.data.respond_to?(:prev_page_token)
207
+ return self.data.prev_page_token
208
+ elsif self.data.respond_to?(:[])
209
+ return self.data["prevPageToken"]
210
+ else
211
+ raise TypeError, "Data object did not respond to #next_page_token."
212
+ end
213
+ end
214
+
215
+ ##
216
+ # Build a request for fetching the previous page of data
217
+ #
218
+ # @return [Google::APIClient::Request]
219
+ # API request for retrieving previous page, nil if no page token available
220
+ def prev_page
221
+ return nil unless self.prev_page_token
222
+ merged_parameters = Hash[self.reference.parameters].merge({
223
+ self.page_token_param => self.prev_page_token
224
+ })
225
+ # Because Requests can be coerced to Hashes, we can merge them,
226
+ # preserving all context except the API method parameters that we're
227
+ # using for pagination.
228
+ return Google::APIClient::Request.new(
229
+ Hash[self.reference].merge(:parameters => merged_parameters)
230
+ )
231
+ end
232
+
233
+ ##
234
+ # Pagination scheme used by this request/response
235
+ #
236
+ # @!attribute [r] pagination_type
237
+ # @return [Symbol]
238
+ # currently always :token
239
+ def pagination_type
240
+ return :token
241
+ end
242
+
243
+ ##
244
+ # Name of the field that contains the pagination token
245
+ #
246
+ # @!attribute [r] page_token_param
247
+ # @return [String]
248
+ # currently always 'pageToken'
249
+ def page_token_param
250
+ return "pageToken"
251
+ end
252
+
253
+ end
254
+ end
255
+ end