google-cloud-storage 0.20.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.
@@ -0,0 +1,69 @@
1
+ # Copyright 2014 Google Inc. All rights reserved.
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
+ require "pathname"
17
+ require "digest/md5"
18
+ require "digest/crc32c"
19
+ require "google/cloud/storage/errors"
20
+
21
+ module Google
22
+ module Cloud
23
+ module Storage
24
+ class File
25
+ ##
26
+ # @private
27
+ # Verifies downloaded files by creating an MD5 or CRC32c hash digest
28
+ # and comparing the value to the one from the Storage API.
29
+ module Verifier
30
+ def self.verify_md5! gcloud_file, local_file
31
+ gcloud_digest = gcloud_file.md5
32
+ local_digest = md5_for local_file
33
+ if gcloud_digest != local_digest
34
+ fail FileVerificationError.for_md5(gcloud_digest, local_digest)
35
+ end
36
+ end
37
+
38
+ def self.verify_crc32c! gcloud_file, local_file
39
+ gcloud_digest = gcloud_file.crc32c
40
+ local_digest = crc32c_for local_file
41
+ if gcloud_digest != local_digest
42
+ fail FileVerificationError.for_crc32c(gcloud_digest, local_digest)
43
+ end
44
+ end
45
+
46
+ def self.verify_md5 gcloud_file, local_file
47
+ gcloud_file.md5 == md5_for(local_file)
48
+ end
49
+
50
+ def self.verify_crc32c gcloud_file, local_file
51
+ gcloud_file.crc32c == crc32c_for(local_file)
52
+ end
53
+
54
+ def self.md5_for local_file
55
+ ::File.open(Pathname(local_file).to_path, "rb") do |f|
56
+ ::Digest::MD5.file(f).base64digest
57
+ end
58
+ end
59
+
60
+ def self.crc32c_for local_file
61
+ ::File.open(Pathname(local_file).to_path, "rb") do |f|
62
+ ::Digest::CRC32c.file(f).base64digest
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,321 @@
1
+ # Copyright 2014 Google Inc. All rights reserved.
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
+ require "google/cloud/core/gce"
17
+ require "google/cloud/storage/errors"
18
+ require "google/cloud/storage/service"
19
+ require "google/cloud/storage/credentials"
20
+ require "google/cloud/storage/bucket"
21
+ require "google/cloud/storage/bucket/cors"
22
+ require "google/cloud/storage/file"
23
+
24
+ module Google
25
+ module Cloud
26
+ module Storage
27
+ ##
28
+ # # Project
29
+ #
30
+ # Represents the project that storage buckets and files belong to.
31
+ # All data in Google Cloud Storage belongs inside a project.
32
+ # A project consists of a set of users, a set of APIs, billing,
33
+ # authentication, and monitoring settings for those APIs.
34
+ #
35
+ # Google::Cloud::Storage::Project is the main object for interacting with
36
+ # Google Storage. {Google::Cloud::Storage::Bucket} objects are created,
37
+ # read, updated, and deleted by Google::Cloud::Storage::Project.
38
+ #
39
+ # See {Google::Cloud#storage}
40
+ #
41
+ # @example
42
+ # require "google/cloud"
43
+ #
44
+ # gcloud = Google::Cloud.new
45
+ # storage = gcloud.storage
46
+ #
47
+ # bucket = storage.bucket "my-bucket"
48
+ # file = bucket.file "path/to/my-file.ext"
49
+ #
50
+ class Project
51
+ ##
52
+ # @private The Service object.
53
+ attr_accessor :service
54
+
55
+ ##
56
+ # @private Creates a new Project instance.
57
+ #
58
+ # See {Google::Cloud#storage}
59
+ def initialize service
60
+ @service = service
61
+ end
62
+
63
+ ##
64
+ # The Storage project connected to.
65
+ #
66
+ # @example
67
+ # require "google/cloud"
68
+ #
69
+ # gcloud = Google::Cloud.new "my-todo-project",
70
+ # "/path/to/keyfile.json"
71
+ # storage = gcloud.storage
72
+ #
73
+ # storage.project #=> "my-todo-project"
74
+ #
75
+ def project
76
+ service.project
77
+ end
78
+
79
+ ##
80
+ # @private Default project.
81
+ def self.default_project
82
+ ENV["STORAGE_PROJECT"] ||
83
+ ENV["GOOGLE_CLOUD_PROJECT"] ||
84
+ ENV["GCLOUD_PROJECT"] ||
85
+ Google::Cloud::Core::GCE.project_id
86
+ end
87
+
88
+ ##
89
+ # Retrieves a list of buckets for the given project.
90
+ #
91
+ # @param [String] prefix Filter results to buckets whose names begin
92
+ # with this prefix.
93
+ # @param [String] token A previously-returned page token representing
94
+ # part of the larger set of results to view.
95
+ # @param [Integer] max Maximum number of buckets to return.
96
+ #
97
+ # @return [Array<Google::Cloud::Storage::Bucket>] (See
98
+ # {Google::Cloud::Storage::Bucket::List})
99
+ #
100
+ # @example
101
+ # require "google/cloud"
102
+ #
103
+ # gcloud = Google::Cloud.new
104
+ # storage = gcloud.storage
105
+ #
106
+ # buckets = storage.buckets
107
+ # buckets.each do |bucket|
108
+ # puts bucket.name
109
+ # end
110
+ #
111
+ # @example Retrieve buckets with names that begin with a given prefix:
112
+ # require "google/cloud"
113
+ #
114
+ # gcloud = Google::Cloud.new
115
+ # storage = gcloud.storage
116
+ #
117
+ # user_buckets = storage.buckets prefix: "user-"
118
+ # user_buckets.each do |bucket|
119
+ # puts bucket.name
120
+ # end
121
+ #
122
+ # @example Retrieve all buckets: (See {Bucket::List#all})
123
+ # require "google/cloud"
124
+ #
125
+ # gcloud = Google::Cloud.new
126
+ # storage = gcloud.storage
127
+ #
128
+ # buckets = storage.buckets
129
+ # buckets.all do |bucket|
130
+ # puts bucket.name
131
+ # end
132
+ #
133
+ def buckets prefix: nil, token: nil, max: nil
134
+ options = { prefix: prefix, token: token, max: max }
135
+ gapi = service.list_buckets options
136
+ Bucket::List.from_gapi gapi, service, prefix, max
137
+ end
138
+ alias_method :find_buckets, :buckets
139
+
140
+ ##
141
+ # Retrieves bucket by name.
142
+ #
143
+ # @param [String] bucket_name Name of a bucket.
144
+ #
145
+ # @return [Google::Cloud::Storage::Bucket, nil] Returns nil if bucket
146
+ # does not exist
147
+ #
148
+ # @example
149
+ # require "google/cloud"
150
+ #
151
+ # gcloud = Google::Cloud.new
152
+ # storage = gcloud.storage
153
+ #
154
+ # bucket = storage.bucket "my-bucket"
155
+ # puts bucket.name
156
+ #
157
+ def bucket bucket_name
158
+ gapi = service.get_bucket bucket_name
159
+ Bucket.from_gapi gapi, service
160
+ rescue Google::Cloud::NotFoundError
161
+ nil
162
+ end
163
+ alias_method :find_bucket, :bucket
164
+
165
+ ##
166
+ # Creates a new bucket with optional attributes. Also accepts a block
167
+ # for defining the CORS configuration for a static website served from
168
+ # the bucket. See {Bucket::Cors} for details.
169
+ #
170
+ # The API call to create the bucket may be retried under certain
171
+ # conditions. See {Google::Cloud#storage} to control this behavior.
172
+ #
173
+ # You can pass [website
174
+ # settings](https://cloud.google.com/storage/docs/website-configuration)
175
+ # for the bucket, including a block that defines CORS rule. See
176
+ # {Bucket::Cors} for details.
177
+ #
178
+ # @see https://cloud.google.com/storage/docs/cross-origin Cross-Origin
179
+ # Resource Sharing (CORS)
180
+ # @see https://cloud.google.com/storage/docs/website-configuration How
181
+ # to Host a Static Website
182
+ #
183
+ # @param [String] bucket_name Name of a bucket.
184
+ # @param [String] acl Apply a predefined set of access controls to this
185
+ # bucket.
186
+ #
187
+ # Acceptable values are:
188
+ #
189
+ # * `auth`, `auth_read`, `authenticated`, `authenticated_read`,
190
+ # `authenticatedRead` - Project team owners get OWNER access, and
191
+ # allAuthenticatedUsers get READER access.
192
+ # * `private` - Project team owners get OWNER access.
193
+ # * `project_private`, `projectPrivate` - Project team members get
194
+ # access according to their roles.
195
+ # * `public`, `public_read`, `publicRead` - Project team owners get
196
+ # OWNER access, and allUsers get READER access.
197
+ # * `public_write`, `publicReadWrite` - Project team owners get OWNER
198
+ # access, and allUsers get WRITER access.
199
+ # @param [String] default_acl Apply a predefined set of default object
200
+ # access controls to this bucket.
201
+ #
202
+ # Acceptable values are:
203
+ #
204
+ # * `auth`, `auth_read`, `authenticated`, `authenticated_read`,
205
+ # `authenticatedRead` - File owner gets OWNER access, and
206
+ # allAuthenticatedUsers get READER access.
207
+ # * `owner_full`, `bucketOwnerFullControl` - File owner gets OWNER
208
+ # access, and project team owners get OWNER access.
209
+ # * `owner_read`, `bucketOwnerRead` - File owner gets OWNER access,
210
+ # and project team owners get READER access.
211
+ # * `private` - File owner gets OWNER access.
212
+ # * `project_private`, `projectPrivate` - File owner gets OWNER
213
+ # access, and project team members get access according to their
214
+ # roles.
215
+ # * `public`, `public_read`, `publicRead` - File owner gets OWNER
216
+ # access, and allUsers get READER access.
217
+ # @param [String] location The location of the bucket. Object data for
218
+ # objects in the bucket resides in physical storage within this
219
+ # region. Possible values include `ASIA`, `EU`, and `US`. (See the
220
+ # [developer's
221
+ # guide](https://cloud.google.com/storage/docs/bucket-locations) for
222
+ # the authoritative list. The default value is `US`.
223
+ # @param [String] logging_bucket The destination bucket for the bucket's
224
+ # logs. For more information, see [Access
225
+ # Logs](https://cloud.google.com/storage/docs/access-logs).
226
+ # @param [String] logging_prefix The prefix used to create log object
227
+ # names for the bucket. It can be at most 900 characters and must be a
228
+ # [valid object
229
+ # name](https://cloud.google.com/storage/docs/bucket-naming#objectnames)
230
+ # . By default, the object prefix is the name of the bucket for which
231
+ # the logs are enabled. For more information, see [Access
232
+ # Logs](https://cloud.google.com/storage/docs/access-logs).
233
+ # @param [Symbol, String] storage_class Defines how objects in the
234
+ # bucket are stored and determines the SLA and the cost of storage.
235
+ # Values include `:standard`, `:nearline`, and `:dra` (Durable Reduced
236
+ # Availability), as well as the strings returned by
237
+ # Bucket#storage_class. For more information, see [Storage
238
+ # Classes](https://cloud.google.com/storage/docs/storage-classes). The
239
+ # default value is `:standard`.
240
+ # @param [Boolean] versioning Whether [Object
241
+ # Versioning](https://cloud.google.com/storage/docs/object-versioning)
242
+ # is to be enabled for the bucket. The default value is `false`.
243
+ # @param [String] website_main The index page returned from a static
244
+ # website served from the bucket when a site visitor requests the top
245
+ # level directory. For more information, see [How to Host a Static
246
+ # Website
247
+ # ](https://cloud.google.com/storage/docs/website-configuration#step4).
248
+ # @param [String] website_404 The page returned from a static website
249
+ # served from the bucket when a site visitor requests a resource that
250
+ # does not exist. For more information, see [How to Host a Static
251
+ # Website
252
+ # ](https://cloud.google.com/storage/docs/website-configuration#step4).
253
+ # @yield [bucket] a block for configuring the bucket before it is
254
+ # created
255
+ # @yieldparam [Bucket] cors the bucket object to be configured
256
+ #
257
+ # @return [Google::Cloud::Storage::Bucket]
258
+ #
259
+ # @example
260
+ # require "google/cloud"
261
+ #
262
+ # gcloud = Google::Cloud.new
263
+ # storage = gcloud.storage
264
+ #
265
+ # bucket = storage.create_bucket "my-bucket"
266
+ #
267
+ # @example Configure the bucket in a block:
268
+ # require "google/cloud"
269
+ #
270
+ # gcloud = Google::Cloud.new
271
+ # storage = gcloud.storage
272
+ #
273
+ # bucket = storage.create_bucket "my-bucket" do |b|
274
+ # b.website_main = "index.html"
275
+ # b.website_404 = "not_found.html"
276
+ # b.cors.add_rule ["http://example.org", "https://example.org"],
277
+ # "*",
278
+ # response_headers: ["X-My-Custom-Header"],
279
+ # max_age: 300
280
+ # end
281
+ #
282
+ def create_bucket bucket_name, acl: nil, default_acl: nil,
283
+ location: nil, storage_class: nil,
284
+ logging_bucket: nil, logging_prefix: nil,
285
+ website_main: nil, website_404: nil, versioning: nil
286
+ new_bucket = Google::Apis::StorageV1::Bucket.new({
287
+ name: bucket_name,
288
+ location: location,
289
+ storage_class: storage_class_for(storage_class)
290
+ }.delete_if { |_, v| v.nil? })
291
+ updater = Bucket::Updater.new(new_bucket).tap do |b|
292
+ b.logging_bucket = logging_bucket unless logging_bucket.nil?
293
+ b.logging_prefix = logging_prefix unless logging_prefix.nil?
294
+ b.website_main = website_main unless website_main.nil?
295
+ b.website_404 = website_404 unless website_404.nil?
296
+ b.versioning = versioning unless versioning.nil?
297
+ end
298
+ yield updater if block_given?
299
+ updater.check_for_mutable_cors!
300
+ gapi = service.insert_bucket \
301
+ new_bucket, acl: acl_rule(acl), default_acl: acl_rule(default_acl)
302
+ Bucket.from_gapi gapi, service
303
+ end
304
+
305
+ protected
306
+
307
+ def acl_rule option_name
308
+ Bucket::Acl.predefined_rule_for option_name
309
+ end
310
+
311
+ def storage_class_for str
312
+ { "durable_reduced_availability" => "DURABLE_REDUCED_AVAILABILITY",
313
+ "dra" => "DURABLE_REDUCED_AVAILABILITY",
314
+ "durable" => "DURABLE_REDUCED_AVAILABILITY",
315
+ "nearline" => "NEARLINE",
316
+ "standard" => "STANDARD" }[str.to_s.downcase]
317
+ end
318
+ end
319
+ end
320
+ end
321
+ end
@@ -0,0 +1,310 @@
1
+ # Copyright 2014 Google Inc. All rights reserved.
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
+ require "google/cloud/storage/version"
17
+ require "google/cloud/core/grpc_backoff"
18
+ require "google/apis/storage_v1"
19
+ require "digest"
20
+ require "mime/types"
21
+ require "pathname"
22
+
23
+ module Google
24
+ module Cloud
25
+ module Storage
26
+ ##
27
+ # @private Represents the connection to Storage,
28
+ # as well as expose the API calls.
29
+ class Service
30
+ ##
31
+ # Alias to the Google Client API module
32
+ API = Google::Apis::StorageV1
33
+
34
+ # @private
35
+ attr_accessor :project
36
+
37
+ # @private
38
+ attr_accessor :credentials
39
+
40
+ ##
41
+ # Creates a new Service instance.
42
+ def initialize project, credentials, retries: nil, timeout: nil
43
+ @project = project
44
+ @credentials = credentials
45
+ @credentials = credentials
46
+ @service = API::StorageService.new
47
+ @service.client_options.application_name = "google-cloud-storage"
48
+ @service.client_options.application_version = \
49
+ Google::Cloud::Storage::VERSION
50
+ @service.request_options.retries = retries || 3
51
+ @service.request_options.timeout_sec = timeout if timeout
52
+ @service.authorization = @credentials.client
53
+ end
54
+
55
+ def service
56
+ return mocked_service if mocked_service
57
+ @service
58
+ end
59
+ attr_accessor :mocked_service
60
+
61
+ ##
62
+ # Retrieves a list of buckets for the given project.
63
+ def list_buckets prefix: nil, token: nil, max: nil
64
+ execute do
65
+ service.list_buckets @project, prefix: prefix, page_token: token,
66
+ max_results: max
67
+ end
68
+ end
69
+
70
+ ##
71
+ # Retrieves bucket by name.
72
+ # Returns Google::Apis::StorageV1::Bucket.
73
+ def get_bucket bucket_name
74
+ execute { service.get_bucket bucket_name }
75
+ end
76
+
77
+ ##
78
+ # Creates a new bucket.
79
+ # Returns Google::Apis::StorageV1::Bucket.
80
+ def insert_bucket bucket_gapi, options = {}
81
+ execute do
82
+ service.insert_bucket \
83
+ @project, bucket_gapi,
84
+ predefined_acl: options[:acl],
85
+ predefined_default_object_acl: options[:default_acl]
86
+ end
87
+ end
88
+
89
+ ##
90
+ # Updates a bucket, including its ACL metadata.
91
+ def patch_bucket bucket_name, bucket_gapi = nil, predefined_acl: nil,
92
+ predefined_default_acl: nil
93
+ bucket_gapi ||= Google::Apis::StorageV1::Bucket.new
94
+ bucket_gapi.acl = nil if predefined_acl
95
+ bucket_gapi.default_object_acl = nil if predefined_default_acl
96
+
97
+ execute do
98
+ service.patch_bucket \
99
+ bucket_name, bucket_gapi,
100
+ predefined_acl: predefined_acl,
101
+ predefined_default_object_acl: predefined_default_acl
102
+ end
103
+ end
104
+
105
+ ##
106
+ # Permanently deletes an empty bucket.
107
+ def delete_bucket bucket_name
108
+ execute { service.delete_bucket bucket_name }
109
+ end
110
+
111
+ ##
112
+ # Retrieves a list of ACLs for the given bucket.
113
+ def list_bucket_acls bucket_name
114
+ execute { service.list_bucket_access_controls bucket_name }
115
+ end
116
+
117
+ ##
118
+ # Creates a new bucket ACL.
119
+ def insert_bucket_acl bucket_name, entity, role
120
+ new_acl = Google::Apis::StorageV1::BucketAccessControl.new \
121
+ entity: entity, role: role
122
+ execute { service.insert_bucket_access_control bucket_name, new_acl }
123
+ end
124
+
125
+ ##
126
+ # Permanently deletes a bucket ACL.
127
+ def delete_bucket_acl bucket_name, entity
128
+ execute { service.delete_bucket_access_control bucket_name, entity }
129
+ end
130
+
131
+ ##
132
+ # Retrieves a list of default ACLs for the given bucket.
133
+ def list_default_acls bucket_name
134
+ execute { service.list_default_object_access_controls bucket_name }
135
+ end
136
+
137
+ ##
138
+ # Creates a new default ACL.
139
+ def insert_default_acl bucket_name, entity, role
140
+ new_acl = Google::Apis::StorageV1::ObjectAccessControl.new \
141
+ entity: entity, role: role
142
+ execute do
143
+ service.insert_default_object_access_control bucket_name, new_acl
144
+ end
145
+ end
146
+
147
+ ##
148
+ # Permanently deletes a default ACL.
149
+ def delete_default_acl bucket_name, entity
150
+ execute do
151
+ service.delete_default_object_access_control bucket_name, entity
152
+ end
153
+ end
154
+
155
+ ##
156
+ # Retrieves a list of files matching the criteria.
157
+ def list_files bucket_name, options = {}
158
+ execute do
159
+ service.list_objects \
160
+ bucket_name, delimiter: options[:delimiter],
161
+ max_results: options[:max],
162
+ page_token: options[:token],
163
+ prefix: options[:prefix],
164
+ versions: options[:versions]
165
+ end
166
+ end
167
+
168
+ ##
169
+ # Inserts a new file for the given bucket
170
+ def insert_file bucket_name, source, path = nil, acl: nil,
171
+ cache_control: nil, content_disposition: nil,
172
+ content_encoding: nil, content_language: nil,
173
+ content_type: nil, crc32c: nil, md5: nil, metadata: nil,
174
+ key: nil, key_sha256: nil
175
+ file_obj = Google::Apis::StorageV1::Object.new \
176
+ cache_control: cache_control, content_type: content_type,
177
+ content_disposition: content_disposition, md5_hash: md5,
178
+ content_encoding: content_encoding, crc32c: crc32c,
179
+ content_language: content_language, metadata: metadata
180
+ content_type ||= mime_type_for(Pathname(source).to_path)
181
+ execute do
182
+ service.insert_object \
183
+ bucket_name, file_obj,
184
+ name: path, predefined_acl: acl, upload_source: source,
185
+ content_encoding: content_encoding, content_type: content_type,
186
+ options: key_options(key: key, key_sha256: key_sha256)
187
+ end
188
+ end
189
+
190
+ ##
191
+ # Retrieves an object or its metadata.
192
+ def get_file bucket_name, file_path, generation: nil, key: nil,
193
+ key_sha256: nil
194
+ execute do
195
+ service.get_object \
196
+ bucket_name, file_path,
197
+ generation: generation,
198
+ options: key_options(key: key, key_sha256: key_sha256)
199
+ end
200
+ end
201
+
202
+ ## Copy a file from source bucket/object to a
203
+ # destination bucket/object.
204
+ def copy_file source_bucket_name, source_file_path,
205
+ destination_bucket_name, destination_file_path,
206
+ options = {}
207
+ execute do
208
+ service.copy_object \
209
+ source_bucket_name, source_file_path,
210
+ destination_bucket_name, destination_file_path,
211
+ destination_predefined_acl: options[:acl],
212
+ source_generation: options[:generation],
213
+ options: key_options(key: options[:key],
214
+ key_sha256: options[:key_sha256])
215
+ end
216
+ end
217
+
218
+ ##
219
+ # Download contents of a file.
220
+ def download_file bucket_name, file_path, target_path, generation: nil,
221
+ key: nil, key_sha256: nil
222
+ execute do
223
+ service.get_object \
224
+ bucket_name, file_path,
225
+ download_dest: target_path, generation: generation,
226
+ options: key_options(key: key, key_sha256: key_sha256)
227
+ end
228
+ end
229
+
230
+ ##
231
+ # Updates a file's metadata.
232
+ def patch_file bucket_name, file_path, file_gapi = nil,
233
+ predefined_acl: nil
234
+ file_gapi ||= Google::Apis::StorageV1::Object.new
235
+ execute do
236
+ service.patch_object \
237
+ bucket_name, file_path, file_gapi,
238
+ predefined_acl: predefined_acl
239
+ end
240
+ end
241
+
242
+ ##
243
+ # Permanently deletes a file.
244
+ def delete_file bucket_name, file_path
245
+ execute { service.delete_object bucket_name, file_path }
246
+ end
247
+
248
+ ##
249
+ # Retrieves a list of ACLs for the given file.
250
+ def list_file_acls bucket_name, file_name
251
+ execute { service.list_object_access_controls bucket_name, file_name }
252
+ end
253
+
254
+ ##
255
+ # Creates a new file ACL.
256
+ def insert_file_acl bucket_name, file_name, entity, role, options = {}
257
+ new_acl = Google::Apis::StorageV1::ObjectAccessControl.new \
258
+ entity: entity, role: role
259
+ execute do
260
+ service.insert_object_access_control \
261
+ bucket_name, file_name, new_acl, generation: options[:generation]
262
+ end
263
+ end
264
+
265
+ ##
266
+ # Permanently deletes a file ACL.
267
+ def delete_file_acl bucket_name, file_name, entity, options = {}
268
+ execute do
269
+ service.delete_object_access_control \
270
+ bucket_name, file_name, entity, generation: options[:generation]
271
+ end
272
+ end
273
+
274
+ ##
275
+ # Retrieves the mime-type for a file path.
276
+ # An empty string is returned if no mime-type can be found.
277
+ def mime_type_for path
278
+ MIME::Types.of(path).first.to_s
279
+ end
280
+
281
+ # @private
282
+ def inspect
283
+ "#{self.class}(#{@project})"
284
+ end
285
+
286
+ protected
287
+
288
+ def key_options key: nil, key_sha256: nil
289
+ options = {}
290
+ if key
291
+ headers = {}
292
+ headers["x-goog-encryption-algorithm"] = "AES256"
293
+ headers["x-goog-encryption-key"] = Base64.strict_encode64 key
294
+ key_sha256 ||= Digest::SHA256.digest key
295
+ headers["x-goog-encryption-key-sha256"] = \
296
+ Base64.strict_encode64 key_sha256
297
+ options[:header] = headers
298
+ end
299
+ options
300
+ end
301
+
302
+ def execute
303
+ yield
304
+ rescue Google::Apis::Error => e
305
+ raise Google::Cloud::Error.from_error(e)
306
+ end
307
+ end
308
+ end
309
+ end
310
+ end