google-cloud-storage 1.9.0 → 1.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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