class Saviour::File

Attributes

persisted_path[R]
source[R]
storage[R]

Public Class Methods

new(uploader_klass, model, attached_as, persisted_path = nil) click to toggle source
# File lib/saviour/file.rb, line 7
def initialize(uploader_klass, model, attached_as, persisted_path = nil)
  @uploader_klass, @model, @attached_as = uploader_klass, model, attached_as
  @source_was = @source = nil
  @persisted_path = persisted_path
  @storage = @uploader_klass.storage

  if persisted_path
    @model.instance_variable_set("@__uploader_#{@attached_as}_was", ReadOnlyFile.new(persisted_path, @uploader_klass.storage))
  end
end

Public Instance Methods

==(another_file) click to toggle source
# File lib/saviour/file.rb, line 38
def ==(another_file)
  return false unless another_file.is_a?(Saviour::File)
  return false unless another_file.persisted? == persisted?

  if persisted?
    another_file.persisted_path == persisted_path
  else
    another_file.source == @source
  end
end
__maybe_with_tmpfile(source_type, file) { || ... } click to toggle source
# File lib/saviour/file.rb, line 126
def __maybe_with_tmpfile(source_type, file)
  return yield if source_type == :stream

  tmpfile = Tempfile.new([::File.basename(file.path, ".*"), ::File.extname(file.path)])
  tmpfile.binmode
  FileUtils.cp(file.path, tmpfile.path)

  begin
    yield(tmpfile)
  ensure
    tmpfile.close!
  end
end
assign(object) click to toggle source
# File lib/saviour/file.rb, line 73
def assign(object)
  raise(SourceError, "given object to #assign or #<attach_as>= must respond to `read`") if object && !object.respond_to?(:read)

  followers = @model.class.followers_per_leader_config[@attached_as]

  (followers || []).each do |x|
    attachment = @model.send(x[:attachment])
    attachment.assign(object) unless attachment.changed?
  end

  @source_data = nil
  @source = object

  if changed? && @model.instance_variable_get("@__uploader_#{@attached_as}_was").nil?
    @model.instance_variable_set("@__uploader_#{@attached_as}_was", clone)
  end

  @persisted_path = nil if object

  object
end
blank?() click to toggle source
# File lib/saviour/file.rb, line 184
def blank?
  !@source && !persisted?
end
changed?() click to toggle source
# File lib/saviour/file.rb, line 99
def changed?
  @source_was != @source
end
clone() click to toggle source
# File lib/saviour/file.rb, line 49
def clone
  return nil unless persisted?
  Saviour::File.new(@uploader_klass, @model, @attached_as, @persisted_path)
end
delete() click to toggle source
# File lib/saviour/file.rb, line 27
def delete
  @persisted_path = nil
  @source_was = nil
  @source = nil
end
dup(new_model) click to toggle source
# File lib/saviour/file.rb, line 54
def dup(new_model)
  new_file = Saviour::File.new(@uploader_klass, new_model, @attached_as)

  if persisted?
    new_file.assign(Saviour::StringSource.new(read, filename))
  elsif @source
    new_file.assign(Saviour::StringSource.new(source_data, filename_to_be_assigned))
  end

  new_file
end
exists?() click to toggle source
# File lib/saviour/file.rb, line 18
def exists?
  persisted? && @storage.exists?(@persisted_path)
end
filename() click to toggle source
# File lib/saviour/file.rb, line 103
def filename
  ::File.basename(@persisted_path) if persisted?
end
filename_to_be_assigned() click to toggle source
# File lib/saviour/file.rb, line 122
def filename_to_be_assigned
  changed? ? (SourceFilenameExtractor.new(@source).detected_filename || SecureRandom.hex) : nil
end
persisted?() click to toggle source
# File lib/saviour/file.rb, line 95
def persisted?
  !!@persisted_path
end
public_url() click to toggle source
# File lib/saviour/file.rb, line 33
def public_url
  return nil unless persisted?
  @storage.public_url(@persisted_path)
end
Also aliased as: url
read() click to toggle source
# File lib/saviour/file.rb, line 22
def read
  return nil unless persisted?
  @storage.read(@persisted_path)
end
reload() click to toggle source
# File lib/saviour/file.rb, line 66
def reload
  @model.instance_variable_set("@__uploader_#{@attached_as}", nil)
  @model.instance_variable_set("@__uploader_#{@attached_as}_was", nil)
end
source_data() click to toggle source
# File lib/saviour/file.rb, line 177
def source_data
  @source_data ||= begin
    @source.rewind if @source.respond_to?(:rewind)
    @source.read
  end
end
source_type() click to toggle source
# File lib/saviour/file.rb, line 169
def source_type
  if @source.respond_to?(:path)
    :file
  else
    :stream
  end
end
uploader() click to toggle source
# File lib/saviour/file.rb, line 188
def uploader
  @uploader ||= @uploader_klass.new(data: { model: @model, attached_as: @attached_as })
end
url()
Alias for: public_url
with_copy() { |temp_file| ... } click to toggle source
# File lib/saviour/file.rb, line 107
def with_copy
  raise CannotCopy, "must be persisted" unless persisted?

  temp_file = Tempfile.new([::File.basename(filename, ".*"), ::File.extname(filename)])
  temp_file.binmode

  begin
    @storage.read_to_file(@persisted_path, temp_file)

    yield(temp_file)
  ensure
    temp_file.close!
  end
end
write(before_write: nil) click to toggle source
# File lib/saviour/file.rb, line 140
def write(before_write: nil)
  raise(MissingSource, "You must provide a source to read from before trying to write") unless @source

  __maybe_with_tmpfile(source_type, @source) do |tmpfile|
    contents, path = case source_type
                       when :stream
                         uploader._process_as_contents(source_data, filename_to_be_assigned)
                       when :file
                         uploader._process_as_file(tmpfile, filename_to_be_assigned)
                     end
    @source_was = @source

    if path
      before_write.call(path) if before_write

      case source_type
        when :stream
          @storage.write(contents, path)
        when :file
          @storage.write_from_file(contents, path)
      end

      @persisted_path = path
      @model.instance_variable_set("@__uploader_#{@attached_as}_was", ReadOnlyFile.new(persisted_path, @storage))
      path
    end
  end
end