class ActiveStorage::Service::OpenStackService
ActiveStorage
provider for OpenStack
Attributes
client[R]
container[R]
Public Class Methods
new(container:, credentials:, public: false, connection_options: {})
click to toggle source
Calls superclass method
# File lib/active_storage/service/open_stack_service.rb, line 11 def initialize(container:, credentials:, public: false, connection_options: {}) super() settings = credentials.reverse_merge(connection_options: connection_options) @public = public @client = Fog::OpenStack::Storage.new(settings) @container = Fog::OpenStack.escape(container) end
Public Instance Methods
delete(key)
click to toggle source
# File lib/active_storage/service/open_stack_service.rb, line 65 def delete(key) instrument :delete, key: key do client.delete_object(container, key) rescue Fog::OpenStack::Storage::NotFound false end end
delete_prefixed(prefix)
click to toggle source
# File lib/active_storage/service/open_stack_service.rb, line 73 def delete_prefixed(prefix) instrument :delete, prefix: prefix do directory = client.directories.get(container) filtered_files = client.files(directory: directory, prefix: prefix) filtered_files = filtered_files.map(&:key) client.delete_multiple_objects(container, filtered_files) end end
download(key, &block)
click to toggle source
# File lib/active_storage/service/open_stack_service.rb, line 37 def download(key, &block) if block_given? instrument :streaming_download, key: key do object_for(key, &block) end else instrument :download, key: key do object_for(key).body end end rescue Fog::OpenStack::Storage::NotFound raise ActiveStorage::FileNotFoundError if defined?(ActiveStorage::FileNotFoundError) end
download_chunk(key, range)
click to toggle source
# File lib/active_storage/service/open_stack_service.rb, line 51 def download_chunk(key, range) instrument :download_chunk, key: key, range: range do chunk_buffer = [] object_for(key) do |chunk| chunk_buffer << chunk end chunk_buffer.join[range] rescue Fog::OpenStack::Storage::NotFound raise ActiveStorage::FileNotFoundError if defined?(ActiveStorage::FileNotFoundError) end end
exist?(key)
click to toggle source
# File lib/active_storage/service/open_stack_service.rb, line 83 def exist?(key) instrument :exist, key: key do |payload| answer = head_for(key) payload[:exist] = answer.present? rescue Fog::OpenStack::Storage::NotFound payload[:exist] = false end end
headers_for_direct_upload(_key, content_type:, checksum:, **)
click to toggle source
# File lib/active_storage/service/open_stack_service.rb, line 123 def headers_for_direct_upload(_key, content_type:, checksum:, **) { 'Content-Type' => content_type, 'ETag' => convert_base64digest_to_hexdigest(checksum) } end
update_metadata(key, content_type:, disposition: nil, filename: nil, **)
click to toggle source
# File lib/active_storage/service/open_stack_service.rb, line 130 def update_metadata(key, content_type:, disposition: nil, filename: nil, **) instrument :update_metadata, key: key, content_type: content_type, disposition: disposition do params = { 'Content-Type' => content_type } if disposition && filename params['Content-Disposition'] = content_disposition_with( type: disposition, filename: ActiveStorage::Filename.wrap(filename) ) end client.post_object(container, key, params) true rescue Fog::OpenStack::Storage::NotFound raise ActiveStorage::FileNotFoundError if defined?(ActiveStorage::FileNotFoundError) end end
upload(key, io, checksum: nil, disposition: nil, content_type: nil, filename: nil, **)
click to toggle source
# File lib/active_storage/service/open_stack_service.rb, line 20 def upload(key, io, checksum: nil, disposition: nil, content_type: nil, filename: nil, **) instrument :upload, key: key, checksum: checksum do params = { 'Content-Type' => content_type || guess_content_type(io) } params['ETag'] = convert_base64digest_to_hexdigest(checksum) if checksum if disposition && filename params['Content-Disposition'] = content_disposition_with(type: disposition, filename: filename) end begin client.put_object(container, key, io, params) rescue Excon::Error::UnprocessableEntity raise ActiveStorage::IntegrityError end end end
url(key, **options)
click to toggle source
Calls superclass method
# File lib/active_storage/service/open_stack_service.rb, line 92 def url(key, **options) if ActiveStorage.version < Gem::Version.new('6.1-alpha') instrument :url, key: key do |payload| private_url(key, **options).tap do |generated_url| payload[:url] = generated_url end end else super end end
url_for_direct_upload(key, expires_in:, filename: nil, **)
click to toggle source
# File lib/active_storage/service/open_stack_service.rb, line 104 def url_for_direct_upload(key, expires_in:, filename: nil, **) instrument :url, key: key do |payload| expire_at = unix_timestamp_expires_at(expires_in) generated_url = client.create_temp_url( container, key, expire_at, 'PUT', port: 443, **(filename ? { filename: ActiveStorage::Filename.wrap(filename).to_s } : {}), scheme: 'https' ) payload[:url] = generated_url generated_url end end
Private Instance Methods
convert_base64digest_to_hexdigest(base64digest)
click to toggle source
ActiveStorage
sends a `Digest::MD5.base64digest` checksum OpenStack expects a `Digest::MD5.hexdigest` ETag
# File lib/active_storage/service/open_stack_service.rb, line 159 def convert_base64digest_to_hexdigest(base64digest) base64digest.unpack1('m0').unpack1('H*') end
guess_content_type(io)
click to toggle source
# File lib/active_storage/service/open_stack_service.rb, line 167 def guess_content_type(io) Marcel::MimeType.for io, name: io.try(:original_filename), declared_type: io.try(:content_type) end
head_for(key)
click to toggle source
# File lib/active_storage/service/open_stack_service.rb, line 149 def head_for(key) client.head_object(container, key) end
object_for(key, &block)
click to toggle source
# File lib/active_storage/service/open_stack_service.rb, line 153 def object_for(key, &block) client.get_object(container, key, &block) end
private_url(key, expires_in:, filename:, disposition:, **)
click to toggle source
# File lib/active_storage/service/open_stack_service.rb, line 173 def private_url(key, expires_in:, filename:, disposition:, **) expire_at = unix_timestamp_expires_at(expires_in) generated_url = client.get_object_https_url(container, key, expire_at, filename: filename.sanitized) generated_url += '&inline' if disposition.to_s != 'attachment' # unfortunately OpenStack Swift cannot overwrite the content type of an object via a temp url # so we just ignore the content_type argument here generated_url end
public_url(key, **)
click to toggle source
# File lib/active_storage/service/open_stack_service.rb, line 183 def public_url(key, **) client.public_url(container, key) end
unix_timestamp_expires_at(seconds_from_now)
click to toggle source
# File lib/active_storage/service/open_stack_service.rb, line 163 def unix_timestamp_expires_at(seconds_from_now) Time.current.advance(seconds: seconds_from_now).to_i end