class EchoUploads::File

Attributes

file[RW]

Public Class Methods

default_key_proc() click to toggle source

Returns a proc that takes as its only argument an ActionDispatch::UploadedFile and returns a key string.

# File lib/echo_uploads/file.rb, line 26
def self.default_key_proc
  ->(file) do
    digest = Digest::SHA512.new
    file.rewind
    until file.eof?
      digest.update file.read(1000)
    end
    digest.hexdigest
  end
end
prune_temporary!() click to toggle source
# File lib/echo_uploads/file.rb, line 105
def self.prune_temporary!
  where(temporary: true).where(['expires_at < ?', Time.now]).each do |file_meta|
    file_meta.destroy
  end
end

Public Instance Methods

compute_mime!(options) click to toggle source
# File lib/echo_uploads/file.rb, line 14
def compute_mime!(options)
  if file and file.is_a?(::EchoUploads::MappedFile)
    name = file.mapped_filename
  else
    name = original_filename
  end
  type = MIME::Types.type_for(name).first
  self.mime_type = type ? type.content_type : 'application/octet-stream'
end
delete_file_conditionally() click to toggle source

Deletes the file on disk if and only if no other instances of EchoUpload::File reference it.

# File lib/echo_uploads/file.rb, line 39
def delete_file_conditionally
  unless self.class.where(key: key).where(['id != ?', id]).exists?
    storage.delete key
  end
end
original_filename() click to toggle source
# File lib/echo_uploads/file.rb, line 45
def original_filename
  original_basename + original_extension
end
path() click to toggle source
# File lib/echo_uploads/file.rb, line 49
def path
  storage.path key
end
persist!(attr, options) click to toggle source

Pass in an attribute name, an ActionDispatch::Http::UploadedFile, and an options hash. Must set file attribute first.

# File lib/echo_uploads/file.rb, line 55
def persist!(attr, options)
  unless(
    file.is_a?(ActionDispatch::Http::UploadedFile) or
    file.is_a?(Rack::Test::UploadedFile)
  )
    raise(
      "Expected #file to be a ActionDispatch::Http::UploadedFile "+
      "or Rack::Test::UploadedFile, but was #{file.inspect}"
    )
  end
  
  # Configure and save the metadata object.
  self.key = options[:key].call file # Normally, this is .default_key_proc.
  self.owner_attr = attr
  self.original_extension = ::File.extname(file.original_filename)
  self.original_basename = ::File.basename(file.original_filename, original_extension)
  self.size = file.size
  compute_mime! options
  if options[:storage].is_a? String
    self.storage_type = options[:storage]
  else
    self.storage_type = options[:storage].name
  end
  save!

  # Write the file to the filestore. It's possible that #file is an instance of
  # EchoUploads::MappedFile, which is a subclass of
  # ActionDispatch::Http::UploadedFile.
  if file.is_a?(ActionDispatch::Http::UploadedFile)
    storage.write key, file.tempfile, self
  else
    storage.write key, file, self
  end
  
  # If we mapped the files, they were temporarily written to tmp/echo_uploads.
  # Delete them.
  if file.is_a?(::EchoUploads::MappedFile) and ::File.exists?(file.path)
    ::File.delete file.path
  end

  # Prune any expired temporary files. (Unless automatic pruning was turned off in
  # the app config.)
  unless (
    Rails.configuration.echo_uploads.respond_to?(:prune_tmp_files_on_upload) and
    !Rails.configuration.echo_uploads.prune_tmp_files_on_upload
  )
    self.class.prune_temporary!
  end
end
read() click to toggle source
# File lib/echo_uploads/file.rb, line 111
def read
  storage.read key
end
storage() click to toggle source
# File lib/echo_uploads/file.rb, line 115
def storage
  class_from_string(storage_type).new
end

Private Instance Methods

class_from_string(name) click to toggle source
# File lib/echo_uploads/file.rb, line 121
def class_from_string(name)
  name.split('::').inject(Object) do |mod, klass|
    mod.const_get klass
  end
end