google-cloud-storage 1.9.0 → 1.10.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,10 +1,10 @@
1
- # Copyright 2017 Google Inc. All rights reserved.
1
+ # Copyright 2017 Google LLC
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
5
5
  # You may obtain a copy of the License at
6
6
  #
7
- # http://www.apache.org/licenses/LICENSE-2.0
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
8
  #
9
9
  # Unless required by applicable law or agreed to in writing, software
10
10
  # distributed under the License is distributed on an "AS IS" BASIS,
@@ -208,7 +208,7 @@ module Google
208
208
  ##
209
209
  # Raise an error unless an active service is available.
210
210
  def ensure_service!
211
- fail "Must have active connection" unless service
211
+ raise "Must have active connection" unless service
212
212
  end
213
213
  end
214
214
  end
@@ -1,10 +1,10 @@
1
- # Copyright 2017 Google Inc. All rights reserved.
1
+ # Copyright 2017 Google LLC
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
5
5
  # You may obtain a copy of the License at
6
6
  #
7
- # http://www.apache.org/licenses/LICENSE-2.0
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
8
  #
9
9
  # Unless required by applicable law or agreed to in writing, software
10
10
  # distributed under the License is distributed on an "AS IS" BASIS,
@@ -199,7 +199,7 @@ module Google
199
199
  # @private New Policy from a
200
200
  # Google::Apis::StorageV1::Policy object.
201
201
  def self.from_gapi gapi
202
- roles = gapi.bindings.each_with_object({}) do |binding, memo|
202
+ roles = Array(gapi.bindings).each_with_object({}) do |binding, memo|
203
203
  memo[binding.role] = binding.members.to_a
204
204
  end
205
205
  new gapi.etag, roles
@@ -1,10 +1,10 @@
1
- # Copyright 2014 Google Inc. All rights reserved.
1
+ # Copyright 2014 Google LLC
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
5
5
  # You may obtain a copy of the License at
6
6
  #
7
- # http://www.apache.org/licenses/LICENSE-2.0
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
8
  #
9
9
  # Unless required by applicable law or agreed to in writing, software
10
10
  # distributed under the License is distributed on an "AS IS" BASIS,
@@ -1,10 +1,10 @@
1
- # Copyright 2014 Google Inc. All rights reserved.
1
+ # Copyright 2014 Google LLC
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
5
5
  # You may obtain a copy of the License at
6
6
  #
7
- # http://www.apache.org/licenses/LICENSE-2.0
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
8
  #
9
9
  # Unless required by applicable law or agreed to in writing, software
10
10
  # distributed under the License is distributed on an "AS IS" BASIS,
@@ -13,7 +13,6 @@
13
13
  # limitations under the License.
14
14
 
15
15
 
16
- require "google/cloud/env"
17
16
  require "google/cloud/storage/errors"
18
17
  require "google/cloud/storage/service"
19
18
  require "google/cloud/storage/credentials"
@@ -75,16 +74,7 @@ module Google
75
74
  def project_id
76
75
  service.project
77
76
  end
78
- alias_method :project, :project_id
79
-
80
- ##
81
- # @private Default project.
82
- def self.default_project_id
83
- ENV["STORAGE_PROJECT"] ||
84
- ENV["GOOGLE_CLOUD_PROJECT"] ||
85
- ENV["GCLOUD_PROJECT"] ||
86
- Google::Cloud.env.project_id
87
- end
77
+ alias project project_id
88
78
 
89
79
  ##
90
80
  # Retrieves a list of buckets for the given project.
@@ -147,7 +137,7 @@ module Google
147
137
  Bucket::List.from_gapi \
148
138
  gapi, service, prefix, max, user_project: user_project
149
139
  end
150
- alias_method :find_buckets, :buckets
140
+ alias find_buckets buckets
151
141
 
152
142
  ##
153
143
  # Retrieves bucket by name.
@@ -210,7 +200,7 @@ module Google
210
200
  rescue Google::Cloud::NotFoundError
211
201
  nil
212
202
  end
213
- alias_method :find_bucket, :bucket
203
+ alias find_bucket bucket
214
204
 
215
205
  ##
216
206
  # Creates a new bucket with optional attributes. Also accepts a block
@@ -1,10 +1,10 @@
1
- # Copyright 2014 Google Inc. All rights reserved.
1
+ # Copyright 2014 Google LLC
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
5
5
  # You may obtain a copy of the License at
6
6
  #
7
- # http://www.apache.org/licenses/LICENSE-2.0
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
8
  #
9
9
  # Unless required by applicable law or agreed to in writing, software
10
10
  # distributed under the License is distributed on an "AS IS" BASIS,
@@ -48,10 +48,12 @@ module Google
48
48
  @service.client_options.open_timeout_sec = timeout
49
49
  @service.client_options.read_timeout_sec = timeout
50
50
  @service.client_options.send_timeout_sec = timeout
51
+ @service.client_options.transparent_gzip_decompression = false
51
52
  @service.request_options.retries = retries || 3
52
53
  @service.request_options.header ||= {}
53
54
  @service.request_options.header["x-goog-api-client"] = \
54
55
  "gl-ruby/#{RUBY_VERSION} gccl/#{Google::Cloud::Storage::VERSION}"
56
+ @service.request_options.header["Accept-Encoding"] = "gzip"
55
57
  @service.authorization = @credentials.client if @credentials
56
58
  end
57
59
 
@@ -133,8 +135,9 @@ module Google
133
135
  ##
134
136
  # Creates a new bucket ACL.
135
137
  def insert_bucket_acl bucket_name, entity, role, user_project: nil
136
- new_acl = Google::Apis::StorageV1::BucketAccessControl.new({
137
- entity: entity, role: role }.delete_if { |_k, v| v.nil? })
138
+ new_acl = Google::Apis::StorageV1::BucketAccessControl.new(
139
+ { entity: entity, role: role }.delete_if { |_k, v| v.nil? }
140
+ )
138
141
  execute do
139
142
  service.insert_bucket_access_control \
140
143
  bucket_name, new_acl, user_project: user_project(user_project)
@@ -162,8 +165,9 @@ module Google
162
165
  ##
163
166
  # Creates a new default ACL.
164
167
  def insert_default_acl bucket_name, entity, role, user_project: nil
165
- new_acl = Google::Apis::StorageV1::ObjectAccessControl.new({
166
- entity: entity, role: role }.delete_if { |_k, v| v.nil? })
168
+ new_acl = Google::Apis::StorageV1::ObjectAccessControl.new(
169
+ { entity: entity, role: role }.delete_if { |_k, v| v.nil? }
170
+ )
167
171
  execute do
168
172
  service.insert_default_object_access_control \
169
173
  bucket_name, new_acl, user_project: user_project(user_project)
@@ -222,12 +226,13 @@ module Google
222
226
  def insert_notification bucket_name, topic_name, custom_attrs: nil,
223
227
  event_types: nil, prefix: nil, payload: nil,
224
228
  user_project: nil
225
- new_notification = Google::Apis::StorageV1::Notification.new({
226
- custom_attributes: custom_attrs,
227
- event_types: event_types(event_types),
228
- object_name_prefix: prefix,
229
- payload_format: payload_format(payload),
230
- topic: topic_path(topic_name) }.delete_if { |_k, v| v.nil? })
229
+ new_notification = Google::Apis::StorageV1::Notification.new(
230
+ { custom_attributes: custom_attrs,
231
+ event_types: event_types(event_types),
232
+ object_name_prefix: prefix,
233
+ payload_format: payload_format(payload),
234
+ topic: topic_path(topic_name) }.delete_if { |_k, v| v.nil? }
235
+ )
231
236
 
232
237
  execute do
233
238
  service.insert_notification \
@@ -274,12 +279,13 @@ module Google
274
279
  content_encoding: nil, content_language: nil,
275
280
  content_type: nil, crc32c: nil, md5: nil, metadata: nil,
276
281
  storage_class: nil, key: nil, user_project: nil
277
- file_obj = Google::Apis::StorageV1::Object.new({
278
- cache_control: cache_control, content_type: content_type,
279
- content_disposition: content_disposition, md5_hash: md5,
280
- content_encoding: content_encoding, crc32c: crc32c,
281
- content_language: content_language, metadata: metadata,
282
- storage_class: storage_class }.delete_if { |_k, v| v.nil? })
282
+ file_obj = Google::Apis::StorageV1::Object.new(
283
+ { cache_control: cache_control, content_type: content_type,
284
+ content_disposition: content_disposition, md5_hash: md5,
285
+ content_encoding: content_encoding, crc32c: crc32c,
286
+ content_language: content_language, metadata: metadata,
287
+ storage_class: storage_class }.delete_if { |_k, v| v.nil? }
288
+ )
283
289
  content_type ||= mime_type_for(path || Pathname(source).to_path)
284
290
 
285
291
  execute do
@@ -367,14 +373,22 @@ module Google
367
373
 
368
374
  ##
369
375
  # Download contents of a file.
376
+ #
377
+ # Returns a two-element array containing:
378
+ # * The IO object that is the usual return type of
379
+ # StorageService#get_object (for downloads)
380
+ # * The `http_resp` accessed via the monkey-patches of
381
+ # Apis::StorageV1::StorageService and Apis::Core::DownloadCommand at
382
+ # the end of this file.
370
383
  def download_file bucket_name, file_path, target_path, generation: nil,
371
384
  key: nil, user_project: nil
385
+ options = key_options key
372
386
  execute do
373
- service.get_object \
387
+ service.get_object_with_response \
374
388
  bucket_name, file_path,
375
389
  download_dest: target_path, generation: generation,
376
390
  user_project: user_project(user_project),
377
- options: key_options(key)
391
+ options: options
378
392
  end
379
393
  end
380
394
 
@@ -415,8 +429,9 @@ module Google
415
429
  # Creates a new file ACL.
416
430
  def insert_file_acl bucket_name, file_name, entity, role,
417
431
  generation: nil, user_project: nil
418
- new_acl = Google::Apis::StorageV1::ObjectAccessControl.new({
419
- entity: entity, role: role }.delete_if { |_k, v| v.nil? })
432
+ new_acl = Google::Apis::StorageV1::ObjectAccessControl.new(
433
+ { entity: entity, role: role }.delete_if { |_k, v| v.nil? }
434
+ )
420
435
  execute do
421
436
  service.insert_object_access_control \
422
437
  bucket_name, file_name, new_acl,
@@ -543,4 +558,154 @@ module Google
543
558
  end
544
559
  end
545
560
  end
561
+
562
+ # rubocop:disable all
563
+
564
+ # IMPORTANT: These monkey-patches of Apis::StorageV1::StorageService and
565
+ # Apis::Core::DownloadCommand must be verified and updated (if needed) for
566
+ # every upgrade of google-api-client.
567
+ #
568
+ # The purpose of these modifications is to provide access to response headers
569
+ # (in particular, the Content-Encoding header) for the #download_file method,
570
+ # above. If google-api-client is modified to expose response headers to its
571
+ # clients, this code should be removed, and #download_file updated to use that
572
+ # solution instead.
573
+ #
574
+ module Apis
575
+ module StorageV1
576
+ class StorageService
577
+ # Returns a two-element array containing:
578
+ # * The `result` that is the usual return type of #get_object.
579
+ # * The `http_resp` from DownloadCommand#execute_once.
580
+ def get_object_with_response(bucket, object, generation: nil, if_generation_match: nil, if_generation_not_match: nil, if_metageneration_match: nil, if_metageneration_not_match: nil, projection: nil, user_project: nil, fields: nil, quota_user: nil, user_ip: nil, download_dest: nil, options: nil, &block)
581
+ if download_dest.nil?
582
+ command = make_simple_command(:get, 'b/{bucket}/o/{object}', options)
583
+ else
584
+ command = make_download_command(:get, 'b/{bucket}/o/{object}', options)
585
+ command.download_dest = download_dest
586
+ end
587
+ command.response_representation = Google::Apis::StorageV1::Object::Representation
588
+ command.response_class = Google::Apis::StorageV1::Object
589
+ command.params['bucket'] = bucket unless bucket.nil?
590
+ command.params['object'] = object unless object.nil?
591
+ command.query['generation'] = generation unless generation.nil?
592
+ command.query['ifGenerationMatch'] = if_generation_match unless if_generation_match.nil?
593
+ command.query['ifGenerationNotMatch'] = if_generation_not_match unless if_generation_not_match.nil?
594
+ command.query['ifMetagenerationMatch'] = if_metageneration_match unless if_metageneration_match.nil?
595
+ command.query['ifMetagenerationNotMatch'] = if_metageneration_not_match unless if_metageneration_not_match.nil?
596
+ command.query['projection'] = projection unless projection.nil?
597
+ command.query['userProject'] = user_project unless user_project.nil?
598
+ command.query['fields'] = fields unless fields.nil?
599
+ command.query['quotaUser'] = quota_user unless quota_user.nil?
600
+ command.query['userIp'] = user_ip unless user_ip.nil?
601
+ execute_or_queue_command_with_response(command, &block)
602
+ end
603
+
604
+ # Returns a two-element array containing:
605
+ # * The `result` that is the usual return type of #execute_or_queue_command.
606
+ # * The `http_resp` from DownloadCommand#execute_once.
607
+ def execute_or_queue_command_with_response(command, &callback)
608
+ batch_command = current_batch
609
+ if batch_command
610
+ raise "Can not combine services in a batch" if Thread.current[:google_api_batch_service] != self
611
+ batch_command.add(command, &callback)
612
+ nil
613
+ else
614
+ command.execute_with_response(client, &callback)
615
+ end
616
+ end
617
+ end
618
+ end
619
+ module Core
620
+ # Streaming/resumable media download support
621
+ class DownloadCommand < ApiCommand
622
+ # Returns a two-element array containing:
623
+ # * The `result` that is the usual return type of #execute.
624
+ # * The `http_resp` from #execute_once.
625
+ def execute_with_response(client)
626
+ prepare!
627
+ begin
628
+ Retriable.retriable tries: options.retries + 1,
629
+ base_interval: 1,
630
+ multiplier: 2,
631
+ on: RETRIABLE_ERRORS do |try|
632
+ # This 2nd level retriable only catches auth errors, and supports 1 retry, which allows
633
+ # auth to be re-attempted without having to retry all sorts of other failures like
634
+ # NotFound, etc
635
+ auth_tries = (try == 1 && authorization_refreshable? ? 2 : 1)
636
+ Retriable.retriable tries: auth_tries,
637
+ on: [Google::Apis::AuthorizationError, Signet::AuthorizationError],
638
+ on_retry: proc { |*| refresh_authorization } do
639
+ execute_once_with_response(client).tap do |result|
640
+ if block_given?
641
+ yield result, nil
642
+ end
643
+ end
644
+ end
645
+ end
646
+ rescue => e
647
+ if block_given?
648
+ yield nil, e
649
+ else
650
+ raise e
651
+ end
652
+ end
653
+ ensure
654
+ release!
655
+ end
656
+
657
+ # Returns a two-element array containing:
658
+ # * The `result` that is the usual return type of #execute_once.
659
+ # * The `http_resp`.
660
+ def execute_once_with_response(client, &block)
661
+ request_header = header.dup
662
+ apply_request_options(request_header)
663
+ download_offset = nil
664
+
665
+ if @offset > 0
666
+ logger.debug { sprintf('Resuming download from offset %d', @offset) }
667
+ request_header[RANGE_HEADER] = sprintf('bytes=%d-', @offset)
668
+ end
669
+
670
+ http_res = client.get(url.to_s,
671
+ query: query,
672
+ header: request_header,
673
+ follow_redirect: true) do |res, chunk|
674
+ status = res.http_header.status_code.to_i
675
+ next unless OK_STATUS.include?(status)
676
+
677
+ download_offset ||= (status == 206 ? @offset : 0)
678
+ download_offset += chunk.bytesize
679
+
680
+ if download_offset - chunk.bytesize == @offset
681
+ next_chunk = chunk
682
+ else
683
+ # Oh no! Requested a chunk, but received the entire content
684
+ chunk_index = @offset - (download_offset - chunk.bytesize)
685
+ next_chunk = chunk.byteslice(chunk_index..-1)
686
+ next if next_chunk.nil?
687
+ end
688
+ # logger.debug { sprintf('Writing chunk (%d bytes, %d total)', chunk.length, bytes_read) }
689
+ @download_io.write(next_chunk)
690
+
691
+ @offset += next_chunk.bytesize
692
+ end
693
+
694
+ @download_io.flush
695
+
696
+ if @close_io_on_finish
697
+ result = nil
698
+ else
699
+ result = @download_io
700
+ end
701
+ check_status(http_res.status.to_i, http_res.header, http_res.body)
702
+ success([result, http_res], &block)
703
+ rescue => e
704
+ @download_io.flush
705
+ error(e, rethrow: true, &block)
706
+ end
707
+ end
708
+ end
709
+ end
710
+ # rubocop:enable all
546
711
  end
@@ -1,10 +1,10 @@
1
- # Copyright 2016 Google Inc. All rights reserved.
1
+ # Copyright 2016 Google LLC
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
5
5
  # You may obtain a copy of the License at
6
6
  #
7
- # http://www.apache.org/licenses/LICENSE-2.0
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
8
  #
9
9
  # Unless required by applicable law or agreed to in writing, software
10
10
  # distributed under the License is distributed on an "AS IS" BASIS,
@@ -16,7 +16,7 @@
16
16
  module Google
17
17
  module Cloud
18
18
  module Storage
19
- VERSION = "1.9.0"
19
+ VERSION = "1.10.0".freeze
20
20
  end
21
21
  end
22
22
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: google-cloud-storage
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.9.0
4
+ version: 1.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Moore
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2017-11-21 00:00:00.000000000 Z
12
+ date: 2018-02-28 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: google-cloud-core
@@ -17,28 +17,28 @@ dependencies:
17
17
  requirements:
18
18
  - - "~>"
19
19
  - !ruby/object:Gem::Version
20
- version: '1.1'
20
+ version: '1.2'
21
21
  type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
25
  - - "~>"
26
26
  - !ruby/object:Gem::Version
27
- version: '1.1'
27
+ version: '1.2'
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: google-api-client
30
30
  requirement: !ruby/object:Gem::Requirement
31
31
  requirements:
32
32
  - - "~>"
33
33
  - !ruby/object:Gem::Version
34
- version: 0.17.0
34
+ version: 0.19.0
35
35
  type: :runtime
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
39
  - - "~>"
40
40
  - !ruby/object:Gem::Version
41
- version: 0.17.0
41
+ version: 0.19.0
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: googleauth
44
44
  requirement: !ruby/object:Gem::Requirement
@@ -141,16 +141,16 @@ dependencies:
141
141
  name: rubocop
142
142
  requirement: !ruby/object:Gem::Requirement
143
143
  requirements:
144
- - - "<="
144
+ - - "~>"
145
145
  - !ruby/object:Gem::Version
146
- version: 0.35.1
146
+ version: 0.50.0
147
147
  type: :development
148
148
  prerelease: false
149
149
  version_requirements: !ruby/object:Gem::Requirement
150
150
  requirements:
151
- - - "<="
151
+ - - "~>"
152
152
  - !ruby/object:Gem::Version
153
- version: 0.35.1
153
+ version: 0.50.0
154
154
  - !ruby/object:Gem::Dependency
155
155
  name: simplecov
156
156
  requirement: !ruby/object:Gem::Requirement
@@ -243,7 +243,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
243
243
  version: '0'
244
244
  requirements: []
245
245
  rubyforge_project:
246
- rubygems_version: 2.7.2
246
+ rubygems_version: 2.7.6
247
247
  signing_key:
248
248
  specification_version: 4
249
249
  summary: API Client library for Google Cloud Storage