module Shrine::UploadedFile::InstanceMethods
Attributes
The location where the file was uploaded to the storage.
A hash of file metadata that was extracted during upload.
The identifier of the storage the file is uploaded to.
Public Class Methods
Initializes the uploaded file with the given data hash.
# File lib/shrine/uploaded_file.rb, line 35 def initialize(data) @id = data[:id] || data["id"] @storage_key = data[:storage]&.to_sym || data["storage"]&.to_sym @metadata = data[:metadata] || data["metadata"] || {} fail Error, "#{data.inspect} isn't valid uploaded file data" unless @id && @storage_key storage # ensure storage is registered end
Public Instance Methods
Returns true if the other UploadedFile
is uploaded to the same storage and it has the same id
.
# File lib/shrine/uploaded_file.rb, line 226 def ==(other) self.class == other.class && self.id == other.id && self.storage_key == other.storage_key end
Shorthand for accessing metadata values.
# File lib/shrine/uploaded_file.rb, line 71 def [](key) metadata[key] end
Conform to ActiveSupport’s JSON interface.
# File lib/shrine/uploaded_file.rb, line 215 def as_json(*args) data end
Part of complying to the IO interface. It delegates to the internally opened IO object.
# File lib/shrine/uploaded_file.rb, line 171 def close io.close if opened? @io = nil end
Returns serializable hash representation of the uploaded file.
# File lib/shrine/uploaded_file.rb, line 220 def data { "id" => id, "storage" => storage_key.to_s, "metadata" => metadata } end
Calls ‘#delete` on the storage, which deletes the file from the storage.
# File lib/shrine/uploaded_file.rb, line 199 def delete storage.delete(id) end
Streams content into a newly created Tempfile and returns it.
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.
uploaded_file.download #=> #<File:/var/folders/.../20180302-33119-1h1vjbq.jpg> # or uploaded_file.download { |tempfile| tempfile.read } # tempfile is deleted
# File lib/shrine/uploaded_file.rb, line 121 def download(**options) tempfile = Tempfile.new(["shrine", ".#{extension}"], binmode: true) stream(tempfile, **options) tempfile.open block_given? ? yield(tempfile) : tempfile ensure tempfile.close! if ($! || block_given?) && tempfile end
Part of complying to the IO interface. It delegates to the internally opened IO object.
# File lib/shrine/uploaded_file.rb, line 159 def eof? io.eof? end
Calls ‘#exists?` on the storage, which checks whether the file exists on the storage.
# File lib/shrine/uploaded_file.rb, line 188 def exists? storage.exists?(id) end
The extension derived from id
if present, otherwise it’s derived from original_filename
.
# File lib/shrine/uploaded_file.rb, line 52 def extension identifier = id =~ URI::DEFAULT_PARSER.make_regexp ? id.sub(/\?.+$/, "") : id # strip query params for shrine-url result = File.extname(identifier)[1..-1] result ||= File.extname(original_filename.to_s)[1..-1] result.downcase if result end
Enables using UploadedFile
objects as hash keys.
# File lib/shrine/uploaded_file.rb, line 234 def hash [id, storage_key].hash end
Returns simplified inspect output.
# File lib/shrine/uploaded_file.rb, line 254 def inspect "#<#{self.class.inspect} storage=#{storage_key.inspect} id=#{id.inspect} metadata=#{metadata.inspect}>" end
The MIME type of the uploaded file.
# File lib/shrine/uploaded_file.rb, line 65 def mime_type metadata["mime_type"] end
Calls ‘#open` on the storage 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.
uploaded_file.open #=> IO object returned by the storage uploaded_file.read #=> "..." uploaded_file.close # or uploaded_file.open { |io| io.read } # the IO is automatically closed
# File lib/shrine/uploaded_file.rb, line 92 def open(**options) @io.close if @io @io = _open(**options) return @io unless block_given? begin yield @io ensure close @io = nil end end
Returns whether the file has already been opened.
# File lib/shrine/uploaded_file.rb, line 177 def opened? !!@io end
The filename that was extracted from the uploaded file.
# File lib/shrine/uploaded_file.rb, line 46 def original_filename metadata["filename"] end
Part of complying to the IO interface. It delegates to the internally opened IO object.
# File lib/shrine/uploaded_file.rb, line 153 def read(*args) io.read(*args) end
Uploads a new file to this file’s location and returns it.
# File lib/shrine/uploaded_file.rb, line 193 def replace(io, **options) uploader.upload(io, **options, location: id) end
Part of complying to the IO interface. It delegates to the internally opened IO object.
# File lib/shrine/uploaded_file.rb, line 165 def rewind io.rewind end
Returns the Shrine
class that this file’s class is namespaced under.
# File lib/shrine/uploaded_file.rb, line 249 def shrine_class self.class.shrine_class end
The filesize of the uploaded file.
# File lib/shrine/uploaded_file.rb, line 60 def size (@io && @io.size) || (metadata["size"] && Integer(metadata["size"])) end
Returns the storage that this file was uploaded to.
# File lib/shrine/uploaded_file.rb, line 244 def storage shrine_class.find_storage(storage_key) end
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.
uploaded_file.stream(StringIO.new) # or uploaded_file.stream("/path/to/destination")
# File lib/shrine/uploaded_file.rb, line 142 def stream(destination, **options) if opened? IO.copy_stream(io, destination) io.rewind else open(**options) { |io| IO.copy_stream(io, destination) } end end
Returns an opened IO object for the uploaded file.
# File lib/shrine/uploaded_file.rb, line 204 def to_io io end
Returns the data hash in the JSON format. Suitable for storing in a database column or passing to a background job.
# File lib/shrine/uploaded_file.rb, line 210 def to_json(*args) data.to_json(*args) end
Returns an uploader object for the corresponding storage.
# File lib/shrine/uploaded_file.rb, line 239 def uploader shrine_class.new(storage_key) end
Calls ‘#url` on the storage, forwarding any given URL options.
# File lib/shrine/uploaded_file.rb, line 182 def url(**options) storage.url(id, **options) end
Private Instance Methods
# File lib/shrine/uploaded_file.rb, line 266 def _open(**options) storage.open(id, **options) end
Returns an opened IO object for the uploaded file by calling ‘#open` on the storage.
# File lib/shrine/uploaded_file.rb, line 262 def io @io ||= _open end