Class: Shrine::Storage::GoogleCloudStorage
- Inherits:
-
Object
- Object
- Shrine::Storage::GoogleCloudStorage
- Defined in:
- lib/shrine/storage/google_cloud_storage.rb
Defined Under Namespace
Classes: ProcIO
Instance Attribute Summary collapse
-
#bucket ⇒ Object
readonly
Returns the value of attribute bucket.
-
#host ⇒ Object
readonly
Returns the value of attribute host.
-
#prefix ⇒ Object
readonly
Returns the value of attribute prefix.
Instance Method Summary collapse
-
#clear!(&block) ⇒ Object
deletes all objects from the storage If block is givem, deletes only objects for which the block evaluates to true.
-
#delete(id) ⇒ Object
deletes the file from the storage.
-
#exists?(id) ⇒ Boolean
checks if the file exists on the storage.
-
#initialize(project: nil, bucket:, prefix: nil, host: nil, default_acl: nil, object_options: {}, credentials: nil, public: false) ⇒ GoogleCloudStorage
constructor
Initialize a Shrine::Storage for GCS allowing for auto-discovery of the Google::Cloud::Storage client.
- #object_name(id) ⇒ Object
-
#open(id, rewindable: true, **options) ⇒ Down::ChunkedIO
Opens the remote file and returns it as ‘Down::ChunkedIO` object.
-
#presign(id, **options) ⇒ Object
returns request data (:method, :url, and :headers) for direct uploads.
-
#upload(io, id, shrine_metadata: {}, **options) ⇒ Object
If the file is an UploadFile from GCS, issues a copy command, otherwise it uploads a file.
-
#url(id, **options) ⇒ Object
URL to the remote file, accepts options for customizing the URL.
Constructor Details
#initialize(project: nil, bucket:, prefix: nil, host: nil, default_acl: nil, object_options: {}, credentials: nil, public: false) ⇒ GoogleCloudStorage
Initialize a Shrine::Storage for GCS allowing for auto-discovery of the Google::Cloud::Storage client.
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/shrine/storage/google_cloud_storage.rb', line 13 def initialize(project: nil, bucket:, prefix: nil, host: nil, default_acl: nil, object_options: {}, credentials: nil, public: false) @project = project @bucket = bucket @prefix = prefix @host = host @object_options = @storage = nil @credentials = credentials @default_acl = if public && default_acl && default_acl != "publicRead" raise Shrine::Error, "You can not set both public and default_acl" elsif public "publicRead" else default_acl end end |
Instance Attribute Details
#bucket ⇒ Object (readonly)
Returns the value of attribute bucket.
8 9 10 |
# File 'lib/shrine/storage/google_cloud_storage.rb', line 8 def bucket @bucket end |
#host ⇒ Object (readonly)
Returns the value of attribute host.
8 9 10 |
# File 'lib/shrine/storage/google_cloud_storage.rb', line 8 def host @host end |
#prefix ⇒ Object (readonly)
Returns the value of attribute prefix.
8 9 10 |
# File 'lib/shrine/storage/google_cloud_storage.rb', line 8 def prefix @prefix end |
Instance Method Details
#clear!(&block) ⇒ Object
deletes all objects from the storage If block is givem, deletes only objects for which the block evaluates to true.
clear! # or clear! { |file| file.updated_at < 1.week.ago }
125 126 127 128 129 130 131 132 133 |
# File 'lib/shrine/storage/google_cloud_storage.rb', line 125 def clear!(&block) prefix = "#{@prefix}/" if @prefix files = get_bucket.files prefix: prefix loop do files.each { |file| delete_file(file) if block.nil? || block.call(file) } files = files.next or break end end |
#delete(id) ⇒ Object
deletes the file from the storage
113 114 115 116 |
# File 'lib/shrine/storage/google_cloud_storage.rb', line 113 def delete(id) file = get_file(id) delete_file(file) unless file.nil? end |
#exists?(id) ⇒ Boolean
checks if the file exists on the storage
106 107 108 109 110 |
# File 'lib/shrine/storage/google_cloud_storage.rb', line 106 def exists?(id) file = get_file(id) return false if file.nil? file.exists? end |
#object_name(id) ⇒ Object
147 148 149 |
# File 'lib/shrine/storage/google_cloud_storage.rb', line 147 def object_name(id) @prefix ? "#{@prefix}/#{id}" : id end |
#open(id, rewindable: true, **options) ⇒ Down::ChunkedIO
Opens the remote file and returns it as ‘Down::ChunkedIO` object.
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/shrine/storage/google_cloud_storage.rb', line 84 def open(id, rewindable: true, **) file = get_file(id) raise Shrine::FileNotFound, "file #{id.inspect} not found on storage" unless file # create enumerator which lazily yields chunks of downloaded content chunks = Enumerator.new do |yielder| # trick to get google client to stream the download proc_io = ProcIO.new { |data| yielder << data } file.download(proc_io, verify: :none, **) end # wrap chunks in an IO-like object which downloads when needed Down::ChunkedIO.new( chunks: chunks, size: file.size, rewindable: rewindable, data: { file: file }, ) end |
#presign(id, **options) ⇒ Object
returns request data (:method, :url, and :headers) for direct uploads
136 137 138 139 140 141 142 143 144 145 |
# File 'lib/shrine/storage/google_cloud_storage.rb', line 136 def presign(id, **) url = storage.signed_url(@bucket, object_name(id), method: "PUT", **) headers = {} headers["Content-Type"] = [:content_type] if [:content_type] headers["Content-MD5"] = [:content_md5] if [:content_md5] headers.merge!([:headers]) if [:headers] { method: :put, url: url, headers: headers } end |
#upload(io, id, shrine_metadata: {}, **options) ⇒ Object
If the file is an UploadFile from GCS, issues a copy command, otherwise it uploads a file.
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/shrine/storage/google_cloud_storage.rb', line 34 def upload(io, id, shrine_metadata: {}, **) if copyable?(io) existing_file = get_bucket(io.storage.bucket).file(io.storage.object_name(io.id)) file = existing_file.copy( @bucket, # dest_bucket_or_path - the bucket to copy the file to object_name(id), # dest_path - the path to copy the file to in the given bucket acl: .fetch(:acl) { @default_acl } ) do |f| # Workaround a bug in File#copy where the content-type is not copied if you provide a block # See https://github.com/renchap/shrine-google_cloud_storage/issues/36 # See https://github.com/googleapis/google-cloud-ruby/issues/4254 f.content_type = existing_file.content_type # update the additional options @object_options.merge().each_pair do |key, value| f.send("#{key}=", value) end end file else with_file(io) do |file| = @object_options.merge( content_type: ["mime_type"], acl: .fetch(:acl) { @default_acl } ).merge() get_bucket.create_file( file, object_name(id), # path ** ) end end end |
#url(id, **options) ⇒ Object
URL to the remote file, accepts options for customizing the URL
70 71 72 73 74 75 76 77 78 79 |
# File 'lib/shrine/storage/google_cloud_storage.rb', line 70 def url(id, **) if .key? :expires signed_url = storage.signed_url(@bucket, object_name(id), **) signed_url.gsub!(/storage.googleapis.com\/#{@bucket}/, @host) if @host signed_url else host = @host || "storage.googleapis.com/#{@bucket}" "https://#{host}/#{Addressable::URI.encode_component(object_name(id), Addressable::URI::CharacterClasses::PATH)}" end end |