gcloud 0.10.0 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +8 -8
  2. data/CHANGELOG.md +36 -0
  3. data/lib/gcloud/backoff.rb +5 -5
  4. data/lib/gcloud/bigquery.rb +24 -0
  5. data/lib/gcloud/bigquery/connection.rb +32 -25
  6. data/lib/gcloud/bigquery/data.rb +99 -1
  7. data/lib/gcloud/bigquery/dataset.rb +5 -13
  8. data/lib/gcloud/bigquery/dataset/list.rb +124 -2
  9. data/lib/gcloud/bigquery/job/list.rb +125 -2
  10. data/lib/gcloud/bigquery/project.rb +30 -27
  11. data/lib/gcloud/bigquery/query_data.rb +102 -1
  12. data/lib/gcloud/bigquery/table.rb +17 -2
  13. data/lib/gcloud/bigquery/table/list.rb +132 -3
  14. data/lib/gcloud/datastore.rb +30 -19
  15. data/lib/gcloud/datastore/dataset.rb +2 -22
  16. data/lib/gcloud/datastore/dataset/lookup_results.rb +160 -4
  17. data/lib/gcloud/datastore/dataset/query_results.rb +229 -23
  18. data/lib/gcloud/datastore/transaction.rb +2 -5
  19. data/lib/gcloud/dns.rb +20 -0
  20. data/lib/gcloud/dns/change/list.rb +109 -6
  21. data/lib/gcloud/dns/connection.rb +18 -9
  22. data/lib/gcloud/dns/project.rb +4 -8
  23. data/lib/gcloud/dns/record/list.rb +96 -13
  24. data/lib/gcloud/dns/zone.rb +9 -24
  25. data/lib/gcloud/dns/zone/list.rb +102 -5
  26. data/lib/gcloud/dns/zone/transaction.rb +1 -1
  27. data/lib/gcloud/logging.rb +19 -0
  28. data/lib/gcloud/logging/entry/list.rb +83 -14
  29. data/lib/gcloud/logging/metric/list.rb +89 -12
  30. data/lib/gcloud/logging/project.rb +18 -30
  31. data/lib/gcloud/logging/resource_descriptor/list.rb +105 -6
  32. data/lib/gcloud/logging/sink/list.rb +89 -12
  33. data/lib/gcloud/pubsub.rb +23 -0
  34. data/lib/gcloud/pubsub/project.rb +21 -29
  35. data/lib/gcloud/pubsub/service.rb +1 -3
  36. data/lib/gcloud/pubsub/subscription/list.rb +167 -13
  37. data/lib/gcloud/pubsub/topic.rb +15 -13
  38. data/lib/gcloud/pubsub/topic/batch.rb +10 -4
  39. data/lib/gcloud/pubsub/topic/list.rb +134 -8
  40. data/lib/gcloud/resource_manager.rb +24 -0
  41. data/lib/gcloud/resource_manager/connection.rb +18 -9
  42. data/lib/gcloud/resource_manager/manager.rb +7 -4
  43. data/lib/gcloud/resource_manager/project/list.rb +93 -14
  44. data/lib/gcloud/storage.rb +63 -0
  45. data/lib/gcloud/storage/bucket.rb +100 -61
  46. data/lib/gcloud/storage/bucket/list.rb +132 -8
  47. data/lib/gcloud/storage/connection.rb +68 -44
  48. data/lib/gcloud/storage/errors.rb +9 -3
  49. data/lib/gcloud/storage/file.rb +48 -4
  50. data/lib/gcloud/storage/file/list.rb +151 -15
  51. data/lib/gcloud/storage/file/verifier.rb +3 -3
  52. data/lib/gcloud/storage/project.rb +15 -30
  53. data/lib/gcloud/translate.rb +20 -0
  54. data/lib/gcloud/translate/connection.rb +12 -3
  55. data/lib/gcloud/version.rb +1 -1
  56. data/lib/gcloud/vision.rb +20 -0
  57. data/lib/gcloud/vision/connection.rb +10 -1
  58. data/lib/gcloud/vision/image.rb +15 -18
  59. metadata +16 -2
@@ -19,6 +19,7 @@ require "gcloud/backoff"
19
19
  require "gcloud/upload"
20
20
  require "google/api_client"
21
21
  require "mime/types"
22
+ require "digest/sha2"
22
23
 
23
24
  module Gcloud
24
25
  module Storage
@@ -52,7 +53,7 @@ module Gcloud
52
53
  params["pageToken"] = options[:token] if options[:token]
53
54
  params["maxResults"] = options[:max] if options[:max]
54
55
 
55
- @client.execute(
56
+ execute(
56
57
  api_method: @storage.buckets.list,
57
58
  parameters: params
58
59
  )
@@ -61,7 +62,7 @@ module Gcloud
61
62
  ##
62
63
  # Retrieves bucket by name.
63
64
  def get_bucket bucket_name
64
- @client.execute(
65
+ execute(
65
66
  api_method: @storage.buckets.get,
66
67
  parameters: { bucket: bucket_name }
67
68
  )
@@ -74,13 +75,11 @@ module Gcloud
74
75
  predefinedDefaultObjectAcl: options[:default_acl]
75
76
  }.delete_if { |_, v| v.nil? }
76
77
 
77
- incremental_backoff options do
78
- @client.execute(
79
- api_method: @storage.buckets.insert,
80
- parameters: params,
81
- body_object: insert_bucket_request(bucket_name, options)
82
- )
83
- end
78
+ execute(
79
+ api_method: @storage.buckets.insert,
80
+ parameters: params,
81
+ body_object: insert_bucket_request(bucket_name, options)
82
+ )
84
83
  end
85
84
 
86
85
  ##
@@ -91,7 +90,7 @@ module Gcloud
91
90
  predefinedDefaultObjectAcl: options[:predefined_default_acl]
92
91
  }.delete_if { |_, v| v.nil? }
93
92
 
94
- @client.execute(
93
+ execute(
95
94
  api_method: @storage.buckets.patch,
96
95
  parameters: params,
97
96
  body_object: patch_bucket_request(options)
@@ -100,19 +99,17 @@ module Gcloud
100
99
 
101
100
  ##
102
101
  # Permanently deletes an empty bucket.
103
- def delete_bucket bucket_name, opts = {}
104
- incremental_backoff opts do
105
- @client.execute(
106
- api_method: @storage.buckets.delete,
107
- parameters: { bucket: bucket_name }
108
- )
109
- end
102
+ def delete_bucket bucket_name
103
+ execute(
104
+ api_method: @storage.buckets.delete,
105
+ parameters: { bucket: bucket_name }
106
+ )
110
107
  end
111
108
 
112
109
  ##
113
110
  # Retrieves a list of ACLs for the given bucket.
114
111
  def list_bucket_acls bucket_name
115
- @client.execute(
112
+ execute(
116
113
  api_method: @storage.bucket_access_controls.list,
117
114
  parameters: { bucket: bucket_name }
118
115
  )
@@ -121,7 +118,7 @@ module Gcloud
121
118
  ##
122
119
  # Creates a new bucket ACL.
123
120
  def insert_bucket_acl bucket_name, entity, role
124
- @client.execute(
121
+ execute(
125
122
  api_method: @storage.bucket_access_controls.insert,
126
123
  parameters: { bucket: bucket_name },
127
124
  body_object: { entity: entity, role: role }
@@ -131,7 +128,7 @@ module Gcloud
131
128
  ##
132
129
  # Permanently deletes a bucket ACL.
133
130
  def delete_bucket_acl bucket_name, entity
134
- @client.execute(
131
+ execute(
135
132
  api_method: @storage.bucket_access_controls.delete,
136
133
  parameters: { bucket: bucket_name, entity: entity }
137
134
  )
@@ -140,7 +137,7 @@ module Gcloud
140
137
  ##
141
138
  # Retrieves a list of default ACLs for the given bucket.
142
139
  def list_default_acls bucket_name
143
- @client.execute(
140
+ execute(
144
141
  api_method: @storage.default_object_access_controls.list,
145
142
  parameters: { bucket: bucket_name }
146
143
  )
@@ -149,7 +146,7 @@ module Gcloud
149
146
  ##
150
147
  # Creates a new default ACL.
151
148
  def insert_default_acl bucket_name, entity, role
152
- @client.execute(
149
+ execute(
153
150
  api_method: @storage.default_object_access_controls.insert,
154
151
  parameters: { bucket: bucket_name },
155
152
  body_object: { entity: entity, role: role }
@@ -159,7 +156,7 @@ module Gcloud
159
156
  ##
160
157
  # Permanently deletes a default ACL.
161
158
  def delete_default_acl bucket_name, entity
162
- @client.execute(
159
+ execute(
163
160
  api_method: @storage.default_object_access_controls.delete,
164
161
  parameters: { bucket: bucket_name, entity: entity }
165
162
  )
@@ -177,7 +174,7 @@ module Gcloud
177
174
  versions: options[:versions]
178
175
  }.delete_if { |_, v| v.nil? }
179
176
 
180
- @client.execute(
177
+ execute(
181
178
  api_method: @storage.objects.list,
182
179
  parameters: params
183
180
  )
@@ -198,7 +195,7 @@ module Gcloud
198
195
  result = insert_file resumable, bucket_name, upload_path, media, options
199
196
  return result unless resumable
200
197
  upload = result.resumable_upload
201
- result = @client.execute upload while upload.resumable?
198
+ result = execute upload while upload.resumable?
202
199
  result
203
200
  end
204
201
 
@@ -208,17 +205,20 @@ module Gcloud
208
205
  query = { bucket: bucket_name, object: file_path }
209
206
  query[:generation] = options[:generation] if options[:generation]
210
207
 
211
- @client.execute(
208
+ request_options = {
212
209
  api_method: @storage.objects.get,
213
210
  parameters: query
214
- )
211
+ }
212
+
213
+ request_options = add_headers request_options, options
214
+ execute request_options
215
215
  end
216
216
 
217
217
  ## Copy a file from source bucket/object to a
218
218
  # destination bucket/object.
219
219
  def copy_file source_bucket_name, source_file_path,
220
220
  destination_bucket_name, destination_file_path, options = {}
221
- @client.execute(
221
+ request_options = {
222
222
  api_method: @storage.objects.copy,
223
223
  parameters: { sourceBucket: source_bucket_name,
224
224
  sourceObject: source_file_path,
@@ -226,18 +226,24 @@ module Gcloud
226
226
  destinationBucket: destination_bucket_name,
227
227
  destinationObject: destination_file_path,
228
228
  predefinedAcl: options[:acl]
229
- }.delete_if { |_, v| v.nil? })
229
+ }.delete_if { |_, v| v.nil? }
230
+ }
231
+ request_options = add_headers request_options, options
232
+ execute request_options
230
233
  end
231
234
 
232
235
  ##
233
236
  # Download contents of a file.
234
- def download_file bucket_name, file_path
235
- @client.execute(
237
+
238
+ def download_file bucket_name, file_path, options = {}
239
+ request_options = {
236
240
  api_method: @storage.objects.get,
237
241
  parameters: { bucket: bucket_name,
238
242
  object: file_path,
239
243
  alt: :media }
240
- )
244
+ }
245
+ request_options = add_headers request_options, options
246
+ execute request_options
241
247
  end
242
248
 
243
249
  ##
@@ -248,7 +254,7 @@ module Gcloud
248
254
  predefinedAcl: options[:predefined_acl]
249
255
  }.delete_if { |_, v| v.nil? }
250
256
 
251
- @client.execute(
257
+ execute(
252
258
  api_method: @storage.objects.patch,
253
259
  parameters: params,
254
260
  body_object: patch_file_request(options)
@@ -258,7 +264,7 @@ module Gcloud
258
264
  ##
259
265
  # Permanently deletes a file.
260
266
  def delete_file bucket_name, file_path
261
- @client.execute(
267
+ execute(
262
268
  api_method: @storage.objects.delete,
263
269
  parameters: { bucket: bucket_name,
264
270
  object: file_path }
@@ -268,7 +274,7 @@ module Gcloud
268
274
  ##
269
275
  # Retrieves a list of ACLs for the given file.
270
276
  def list_file_acls bucket_name, file_name
271
- @client.execute(
277
+ execute(
272
278
  api_method: @storage.object_access_controls.list,
273
279
  parameters: { bucket: bucket_name, object: file_name }
274
280
  )
@@ -280,7 +286,7 @@ module Gcloud
280
286
  query = { bucket: bucket_name, object: file_name }
281
287
  query[:generation] = options[:generation] if options[:generation]
282
288
 
283
- @client.execute(
289
+ execute(
284
290
  api_method: @storage.object_access_controls.insert,
285
291
  parameters: query,
286
292
  body_object: { entity: entity, role: role }
@@ -293,7 +299,7 @@ module Gcloud
293
299
  query = { bucket: bucket_name, object: file_name, entity: entity }
294
300
  query[:generation] = options[:generation] if options[:generation]
295
301
 
296
- @client.execute(
302
+ execute(
297
303
  api_method: @storage.object_access_controls.delete,
298
304
  parameters: query
299
305
  )
@@ -374,10 +380,14 @@ module Gcloud
374
380
  predefinedAcl: options[:acl]
375
381
  }.delete_if { |_, v| v.nil? }
376
382
 
377
- @client.execute api_method: @storage.objects.insert,
378
- media: media,
379
- parameters: params,
380
- body_object: insert_file_request(options)
383
+ request_options = {
384
+ api_method: @storage.objects.insert,
385
+ media: media,
386
+ parameters: params,
387
+ body_object: insert_file_request(options)
388
+ }
389
+ request_options = add_headers request_options, options
390
+ execute request_options
381
391
  end
382
392
 
383
393
  def file_media local_path, options, resumable
@@ -410,9 +420,23 @@ module Gcloud
410
420
  }.delete_if { |_, v| v.nil? }
411
421
  end
412
422
 
413
- def incremental_backoff options = {}
414
- Gcloud::Backoff.new(options).execute_gapi do
415
- yield
423
+ def add_headers request_options, options
424
+ headers = (request_options[:headers] ||= {})
425
+ if options[:encryption_key] || options[:encryption_key_sha256]
426
+ headers["x-goog-encryption-algorithm"] = "AES256"
427
+ end
428
+ if (key = options.delete(:encryption_key))
429
+ headers["x-goog-encryption-key"] = Base64.encode64 key
430
+ end
431
+ if (key_sha256 = options.delete(:encryption_key_sha256))
432
+ headers["x-goog-encryption-key-sha256"] = Base64.encode64 key_sha256
433
+ end
434
+ request_options
435
+ end
436
+
437
+ def execute options
438
+ Gcloud::Backoff.new.execute_gapi do
439
+ @client.execute options
416
440
  end
417
441
  end
418
442
  end
@@ -45,9 +45,15 @@ module Gcloud
45
45
 
46
46
  # @private
47
47
  def self.from_response resp
48
- new resp.data["error"]["message"],
49
- resp.data["error"]["code"],
50
- resp.data["error"]["errors"]
48
+ if resp.data && resp.data["error"]
49
+ new resp.data["error"]["message"],
50
+ resp.data["error"]["code"],
51
+ resp.data["error"]["errors"]
52
+ else
53
+ new resp.error_message,
54
+ resp.status,
55
+ nil
56
+ end
51
57
  end
52
58
  end
53
59
 
@@ -245,6 +245,17 @@ module Gcloud
245
245
  patch_gapi! metadata: metadata
246
246
  end
247
247
 
248
+ ##
249
+ # An [RFC 4648](https://tools.ietf.org/html/rfc4648#section-4)
250
+ # Base64-encoded string of the SHA256 hash of the [customer-supplied
251
+ # encryption key](https://cloud.google.com/storage/docs/encryption#customer-supplied).
252
+ # You can use this SHA256 hash to uniquely identify the AES-256 encryption
253
+ # key required to decrypt this file.
254
+ def encryption_key_sha256
255
+ return nil unless @gapi["customerEncryption"]
256
+ Base64.decode64 @gapi["customerEncryption"]["keySha256"]
257
+ end
258
+
248
259
  ##
249
260
  # Updates the file with changes made in the given block in a single
250
261
  # PATCH request. The following attributes may be set: {#cache_control=},
@@ -285,6 +296,11 @@ module Gcloud
285
296
  #
286
297
  # By default, the download is verified by calculating the MD5 digest.
287
298
  #
299
+ # If a [customer-supplied encryption
300
+ # key](https://cloud.google.com/storage/docs/encryption#customer-supplied)
301
+ # was used with {#create_file}, the `encryption_key` and
302
+ # `encryption_key_sha256` options must be provided.
303
+ #
288
304
  # @param [String] path The path on the local file system to write the data
289
305
  # to. The path provided must be writable.
290
306
  # @param [Symbol] verify The verification algoruthm used to ensure the
@@ -297,6 +313,15 @@ module Gcloud
297
313
  # * `all` - Perform all available file content verification.
298
314
  # * `none` - Don't perform file content verification.
299
315
  #
316
+ # @param [String] encryption_key Optional. The customer-supplied, AES-256
317
+ # encryption key used to encrypt the file, if one was provided to
318
+ # {#create_file}. Must be provided if `encryption_key_sha256` is
319
+ # provided.
320
+ # @param [String] encryption_key_sha256 Optional. The SHA256 hash of the
321
+ # customer-supplied, AES-256 encryption key used to encrypt the file, if
322
+ # one was provided to {#create_file}. Must be provided if
323
+ # `encryption_key` is provided.
324
+ #
300
325
  # @return [File] Returns a `::File` object on the local file system
301
326
  #
302
327
  # @example
@@ -343,9 +368,12 @@ module Gcloud
343
368
  # file = bucket.file "path/to/my-file.ext"
344
369
  # file.download "path/to/downloaded/file.ext", verify: :none
345
370
  #
346
- def download path, verify: :md5
371
+ def download path, verify: :md5, encryption_key: nil,
372
+ encryption_key_sha256: nil
347
373
  ensure_connection!
348
- resp = connection.download_file bucket, name
374
+ options = { encryption_key: encryption_key,
375
+ encryption_key_sha256: encryption_key_sha256 }
376
+ resp = connection.download_file bucket, name, options
349
377
  if resp.success?
350
378
  ::File.open path, "wb+" do |f|
351
379
  f.write resp.body
@@ -359,6 +387,11 @@ module Gcloud
359
387
  ##
360
388
  # Copy the file to a new location.
361
389
  #
390
+ # If a [customer-supplied encryption
391
+ # key](https://cloud.google.com/storage/docs/encryption#customer-supplied)
392
+ # was used with {#create_file}, the `encryption_key` and
393
+ # `encryption_key_sha256` options must be provided.
394
+ #
362
395
  # @param [String] dest_bucket_or_path Either the bucket to copy the file
363
396
  # to, or the path to copy the file to in the current bucket.
364
397
  # @param [String] dest_path If a bucket was provided in the first
@@ -383,6 +416,14 @@ module Gcloud
383
416
  # access, and allUsers get READER access.
384
417
  # @param [Integer] generation Select a specific revision of the file to
385
418
  # copy. The default is the latest version.
419
+ # @param [String] encryption_key Optional. The customer-supplied, AES-256
420
+ # encryption key used to encrypt the file, if one was provided to
421
+ # {#create_file}. Must be provided if `encryption_key_sha256` is
422
+ # provided.
423
+ # @param [String] encryption_key_sha256 Optional. The SHA256 hash of the
424
+ # customer-supplied, AES-256 encryption key used to encrypt the file, if
425
+ # one was provided to {#create_file}. Must be provided if
426
+ # `encryption_key` is provided.
386
427
  #
387
428
  # @return [Gcloud::Storage::File]
388
429
  #
@@ -413,9 +454,12 @@ module Gcloud
413
454
  # file.copy "copy/of/previous/generation/file.ext",
414
455
  # generation: 123456
415
456
  #
416
- def copy dest_bucket_or_path, dest_path = nil, acl: nil, generation: nil
457
+ def copy dest_bucket_or_path, dest_path = nil, acl: nil, generation: nil,
458
+ encryption_key: nil, encryption_key_sha256: nil
417
459
  ensure_connection!
418
- options = { acl: acl, generation: generation }
460
+ options = { acl: acl, generation: generation,
461
+ encryption_key: encryption_key,
462
+ encryption_key_sha256: encryption_key_sha256 }
419
463
  dest_bucket, dest_path, options = fix_copy_args dest_bucket_or_path,
420
464
  dest_path, options
421
465
 
@@ -22,32 +22,168 @@ module Gcloud
22
22
  # File::List is a special case Array with additional values.
23
23
  class List < DelegateClass(::Array)
24
24
  ##
25
- # If not empty, indicates that there are more buckets
26
- # that match the request and this value should be passed to
27
- # the next Gcloud::Storage::Bucket#files to continue.
25
+ # If not empty, indicates that there are more files that match the
26
+ # request and this value should be passed to the next
27
+ # {Gcloud::Storage::Bucket#files} to continue.
28
28
  attr_accessor :token
29
29
 
30
- # The list of prefixes of objects matching-but-not-listed up
31
- # to and including the requested delimiter.
30
+ # The list of prefixes of objects matching-but-not-listed up to and
31
+ # including the requested delimiter.
32
32
  attr_accessor :prefixes
33
33
 
34
34
  ##
35
- # Create a new File::List with an array of values.
36
- def initialize arr = [], token = nil, prefixes = []
35
+ # @private Create a new File::List with an array of values.
36
+ def initialize arr = []
37
37
  super arr
38
- @token = token
39
- @prefixes = prefixes
38
+ end
39
+
40
+ ##
41
+ # Whether there is a next page of files.
42
+ #
43
+ # @return [Boolean]
44
+ #
45
+ # @example
46
+ # require "gcloud"
47
+ #
48
+ # gcloud = Gcloud.new
49
+ # storage = gcloud.storage
50
+ #
51
+ # bucket = storage.bucket "my-bucket"
52
+ # files = bucket.files
53
+ # if files.next?
54
+ # next_files = files.next
55
+ # end
56
+ #
57
+ def next?
58
+ !token.nil?
59
+ end
60
+
61
+ ##
62
+ # Retrieve the next page of files.
63
+ #
64
+ # @return [File::List]
65
+ #
66
+ # @example
67
+ # require "gcloud"
68
+ #
69
+ # gcloud = Gcloud.new
70
+ # storage = gcloud.storage
71
+ #
72
+ # bucket = storage.bucket "my-bucket"
73
+ # files = bucket.files
74
+ # if files.next?
75
+ # next_files = files.next
76
+ # end
77
+ #
78
+ def next
79
+ return nil unless next?
80
+ ensure_connection!
81
+ options = {
82
+ prefix: @prefix, delimiter: @delimiter, token: @token, max: @max,
83
+ versions: @versions
84
+ }
85
+ resp = @connection.list_files @bucket, options
86
+ fail ApiError.from_response(resp) unless resp.success?
87
+ File::List.from_response resp, @connection, @bucket, @prefix,
88
+ @delimiter, @max, @versions
89
+ end
90
+
91
+ ##
92
+ # Retrieves all files by repeatedly loading {#next} until {#next?}
93
+ # returns `false`. Calls the given block once for each file, which is
94
+ # passed as the parameter.
95
+ #
96
+ # An Enumerator is returned if no block is given.
97
+ #
98
+ # This method may make several API calls until all files are retrieved.
99
+ # Be sure to use as narrow a search criteria as possible. Please use
100
+ # with caution.
101
+ #
102
+ # @param [Integer] request_limit The upper limit of API requests to make
103
+ # to load all files. Default is no limit.
104
+ # @yield [file] The block for accessing each file.
105
+ # @yieldparam [File] file The file object.
106
+ #
107
+ # @return [Enumerator]
108
+ #
109
+ # @example Iterating each file by passing a block:
110
+ # require "gcloud"
111
+ #
112
+ # gcloud = Gcloud.new
113
+ # storage = gcloud.storage
114
+ #
115
+ # bucket = storage.bucket "my-bucket"
116
+ # files = bucket.files
117
+ # files.all do |file|
118
+ # puts file.name
119
+ # end
120
+ #
121
+ # @example Using the enumerator by not passing a block:
122
+ # require "gcloud"
123
+ #
124
+ # gcloud = Gcloud.new
125
+ # storage = gcloud.storage
126
+ #
127
+ # bucket = storage.bucket "my-bucket"
128
+ # files = bucket.files
129
+ #
130
+ # all_names = files.all.map do |file|
131
+ # file.name
132
+ # end
133
+ #
134
+ # @example Limit the number of API calls made:
135
+ # require "gcloud"
136
+ #
137
+ # gcloud = Gcloud.new
138
+ # storage = gcloud.storage
139
+ #
140
+ # bucket = storage.bucket "my-bucket"
141
+ # files = bucket.files
142
+ # files.all(request_limit: 10) do |file|
143
+ # puts file.name
144
+ # end
145
+ #
146
+ def all request_limit: nil
147
+ request_limit = request_limit.to_i if request_limit
148
+ unless block_given?
149
+ return enum_for(:all, request_limit: request_limit)
150
+ end
151
+ results = self
152
+ loop do
153
+ results.each { |r| yield r }
154
+ if request_limit
155
+ request_limit -= 1
156
+ break if request_limit < 0
157
+ end
158
+ break unless results.next?
159
+ results = results.next
160
+ end
40
161
  end
41
162
 
42
163
  ##
43
164
  # @private New File::List from a response object.
44
- def self.from_response resp, conn
45
- buckets = Array(resp.data["items"]).map do |gapi_object|
165
+ def self.from_response resp, conn, bucket = nil, prefix = nil,
166
+ delimiter = nil, max = nil, versions = nil
167
+ files = new(Array(resp.data["items"]).map do |gapi_object|
46
168
  File.from_gapi gapi_object, conn
47
- end
48
- token = resp.data["nextPageToken"]
49
- prefixes = Array resp.data["prefixes"]
50
- new buckets, token, prefixes
169
+ end)
170
+ files.instance_variable_set "@token", resp.data["nextPageToken"]
171
+ files.instance_variable_set "@prefixes", Array(resp.data["prefixes"])
172
+ files.instance_variable_set "@connection", conn
173
+ files.instance_variable_set "@bucket", bucket
174
+ files.instance_variable_set "@prefix", prefix
175
+ files.instance_variable_set "@delimiter", delimiter
176
+ files.instance_variable_set "@max", max
177
+ files.instance_variable_set "@versions", versions
178
+ files
179
+ end
180
+
181
+ protected
182
+
183
+ ##
184
+ # Raise an error unless an active connection is available.
185
+ def ensure_connection!
186
+ fail "Must have active connection" unless @connection
51
187
  end
52
188
  end
53
189
  end