Class: EchoUploads::File

Inherits:
ActiveRecord::Base
  • Object
show all
Defined in:
lib/echo_uploads/file.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#fileObject

Returns the value of attribute file.



12
13
14
# File 'lib/echo_uploads/file.rb', line 12

def file
  @file
end

Class Method Details

.default_key_procObject

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



26
27
28
29
30
31
32
33
34
35
# 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!Object



105
106
107
108
109
# 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

Instance Method Details

#compute_mime!(options) ⇒ Object



14
15
16
17
18
19
20
21
22
# 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_conditionallyObject

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



39
40
41
42
43
# 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_filenameObject



45
46
47
# File 'lib/echo_uploads/file.rb', line 45

def original_filename
  original_basename + original_extension
end

#pathObject



49
50
51
# File 'lib/echo_uploads/file.rb', line 49

def path
  storage.path key
end

#persist!(attr, options) ⇒ Object

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



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# 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

#readObject



111
112
113
# File 'lib/echo_uploads/file.rb', line 111

def read
  storage.read key
end

#storageObject



115
116
117
# File 'lib/echo_uploads/file.rb', line 115

def storage
  class_from_string(storage_type).new
end