module ContentAddressableFile::ActsAsUploadedFile::InstanceMethods

Public Instance Methods

close() click to toggle source

Part of complying to the IO interface. It delegates to the internally opened IO object.

# File lib/content_addressable_file/acts_as_uploaded_file.rb, line 124
def close
  io.close if @io
end
delete() click to toggle source

Calls `#delete` on the storages, which deletes the file from the storage.

# File lib/content_addressable_file/acts_as_uploaded_file.rb, line 142
def delete
  all_storages(:delete, id)
end
download(*args) { |tempfile| ... } click to toggle source

Calls `#download` on the storages if the storage that has the file implements it, otherwise streams content into a newly created Tempfile.

If the file exists in multiple storages, any that allows download will be pinned.

If a block is given, the opened Tempfile object is yielded to the block, and at the end of the block it's automatically closed and deleted. In this case the return value of the method is the block return value.

If no block is given, the opened Tempfile is returned.

content_addressable.download
#=> #<File:/var/folders/.../20180302-33119-1h1vjbq.jpg>

# or

content_addressable.download { |tempfile| tempfile.read }
# tempfile is deleted
#=> "..."
# File lib/content_addressable_file/acts_as_uploaded_file.rb, line 70
def download(*args)
  if any_storage(:respond_to?, :download)
    tempfile = pin_storage(:download, id, *args)
  else
    tempfile = Tempfile.new(['content-addressable', id], binmode: true)
    stream(tempfile, *args)
    tempfile.open
  end

  block_given? ? yield(tempfile) : tempfile
ensure
  tempfile.close! if ($ERROR_INFO || block_given?) && tempfile
end
eof?() click to toggle source

Part of complying to the IO interface. It delegates to the internally opened IO object.

# File lib/content_addressable_file/acts_as_uploaded_file.rb, line 112
def eof?
  io.eof?
end
exists?() click to toggle source

Calls `#exists?` on the storages, which checks whether the file exists on any of the storages.

# File lib/content_addressable_file/acts_as_uploaded_file.rb, line 136
def exists?
  pin_storage(:exists?, id)
end
io() click to toggle source

Returns an opened IO object for the uploaded file by calling `#open` on the storage.

# File lib/content_addressable_file/acts_as_uploaded_file.rb, line 158
def io
  @io ||= pin_storage(:open, id)
end
open(*args) { |io| ... } click to toggle source

Calls `#open` on the storages to open the uploaded file for reading. Most storages will return a lazy IO object which dynamically retrieves file content from the storage as the object is being read.

If a block is given, the opened IO object is yielded to the block, and at the end of the block it's automatically closed. In this case the return value of the method is the block return value.

If no block is given, the opened IO object is returned.

@example

content_addressable.open #=> IO object returned by the storage
content_addressable.read #=> "..."
content_addressable.close

# or

content_addressable.open { |io| io.read }
#=> "..."
# File lib/content_addressable_file/acts_as_uploaded_file.rb, line 35
def open(*args)
  return to_io unless block_given?

  begin
    @io = pin_storage(:open, id, *args)
    yield @io
  ensure
    @io&.close
    @io = nil
  end
end
Also aliased as: safe_open
read(*args) click to toggle source

Part of complying to the IO interface. It delegates to the internally opened IO object.

# File lib/content_addressable_file/acts_as_uploaded_file.rb, line 106
def read(*args)
  io.read(*args)
end
rewind() click to toggle source

Part of complying to the IO interface. It delegates to the internally opened IO object.

# File lib/content_addressable_file/acts_as_uploaded_file.rb, line 118
def rewind
  io.rewind
end
safe_open(*args)
Alias for: open
storage() click to toggle source

Returns the storage that this file was uploaded to.

# File lib/content_addressable_file/acts_as_uploaded_file.rb, line 152
def storage
  pin_storage(:exists?, id) && @pin_storage
end
stream(destination, *args) click to toggle source

Streams uploaded file content into the specified destination. The destination object is given directly to `IO.copy_stream`, so it can be either a path on disk or an object that responds to `#write`.

If the uploaded file is already opened, it will be simply rewinded after streaming finishes. Otherwise the uploaded file is opened and then closed after streaming.

content_addressable.stream(StringIO.new)
# or
content_addressable.stream("/path/to/destination")
# File lib/content_addressable_file/acts_as_uploaded_file.rb, line 95
def stream(destination, *args)
  if @io
    IO.copy_stream(io, destination)
    io.rewind
  else
    safe_open(*args) { |io| IO.copy_stream(io, destination) }
  end
end
to_io() click to toggle source

Returns an opened IO object for the uploaded file.

# File lib/content_addressable_file/acts_as_uploaded_file.rb, line 147
def to_io
  io
end
url(**options) click to toggle source

Calls `#url` on the storage where the file is first found, forwarding any given URL options.

# File lib/content_addressable_file/acts_as_uploaded_file.rb, line 130
def url(**options)
  pin_storage(:url, id, **options)
end

Private Instance Methods

all_storages(method, *args) click to toggle source

rubocop:disable Style/RescueModifier

# File lib/content_addressable_file/acts_as_uploaded_file.rb, line 165
def all_storages(method, *args)
  self.class.storages.map do |storage|
    storage.send(method, *args) rescue next
  end
end
any_storage(method, *args) click to toggle source
# File lib/content_addressable_file/acts_as_uploaded_file.rb, line 171
def any_storage(method, *args)
  self.class.storages.each do |storage|
    result = storage.send(method, *args) rescue next
    break result if result
  end
end
pin_storage(method, *args) click to toggle source
# File lib/content_addressable_file/acts_as_uploaded_file.rb, line 178
def pin_storage(method, *args)
  @pin_storage = self.class.storages.find do |storage|
    storage.send(:exists?, id) rescue next
  end

  @pin_storage&.send(method, *args)
end