abstract class Latch::StoredFile

Overview

Represents a file that has been uploaded to a storage backend.

This class is JSON serializable and stores the file's location (#id), which storage it's in (#storage), and associated metadata.

NOTE The JSON format is compatible with Shrine.rb/Shrine.cr:

{
  "id": "uploads/abc123.jpg",
  "storage": "store",
  "metadata": {
    "filename": "photo.jpg",
    "size": 102400,
    "mime_type": "image/jpeg"
  }
}

Included Modules

Defined in:

latch/stored_file.cr

Constructors

Class Method Summary

Instance Method Summary

Constructor Detail

def self.new(id : String, storage_key : String, metadata : MetadataHash = MetadataHash.new) #

[View source]
def self.new(pull : JSON::PullParser) #

[View source]
def self.new(*, __pull_for_json_serializable pull : JSON::PullParser) #

[View source]

Class Method Detail

def self.adapter #

NOTE This mimics the behavior of Avram's JSON::Serializable extension.


[View source]

Instance Method Detail

def ==(other : StoredFile) : Bool #

Compares two StoredFile by their id and storage.


[View source]
def ==(other) : Bool #
Description copied from class Reference

Returns false (other can only be a Value here).


[View source]
def []?(key : String) : MetadataValue #

Aliases the #[]? method on the metadata property.

file["width"]?
# => 800
file["custom"]?
# => "value"

[View source]
def close : Nil #

Closes the file if it is open.


[View source]
def data : Hash(String, String | MetadataHash) #

Returns a hash representation suitable for JSON serialization compatible with Shrine.


[View source]
def delete : Nil #

Deletes the file from storage.

file.delete

[View source]
def download(**options) : File #

Downloads the file to a temporary file and returns it. As opposed to the block variant, this temporary file needs to be closed and deleted manually:

tempfile = file.download
tempfile.path
# => "/tmp/latch123456789.jpg"
tempfile.gets_to_end
# => "file content"
tempfile.close
tempfile.delete

[View source]
def download(**options, &) #

Downloads to a tempfile, yields it to the block, then cleans up.

file.download do |tempfile|
  process(tempfile.path)
end
# tempfile is automatically deleted

[View source]
def exists? : Bool #

Returns whether this file exists in storage.

file.exists? # => true

[View source]
def extension : String #

The non-nilable variant of the #extension? method.


[View source]
def extension? : String | Nil #

Returns the file extension based on the id or original filename.

NOTE This method relies on filename? and filename which are generated by the extract macro on Latch::Uploader. Concrete StoredFile subclasses created through the Uploader.inherited macro will have these methods available automatically.

file.extension?
# => "jpg"

[View source]
def id : String #

[View source]
def io : IO #

Returns the currently opened IO, or opens it if not already open.


[View source]
def metadata : MetadataHash #

[View source]
def open(**options, &) #

Opens the file for reading. If a block is given, yields the IO and automatically closes it afterwards. Returns the block's return value.

file.open do |io|
  io.gets_to_end
end

[View source]
def open(**options) : IO #

Opens the file and stores the IO handle internally for subsequent reads. Remember to call #close when done.

file.open
content = file.io.gets_to_end
file.close

[View source]
def opened? : Bool #

Tests whether the file has been opened or not.


[View source]
def storage : Storage #

Returns the storage instance this file is stored in.


[View source]
def storage_key : String #

[View source]
def stream(destination : IO, **options) : Nil #

Streams the file content to the given IO destination.

file.stream(response.output)

[View source]
def url(**options) : String #

Returns the URL for accessing this file.

file.url
# => "https://bucket.s3.amazonaws.com/uploads/abc123.jpg"

# for presigned URLs
file.url(expires_in: 1.hour)

[View source]
def variant_location(variant : String) : String #

Returns the location for a named variant of this file. The variant is stored as a sibling under a subdirectory matching the original basename.

file = StoredFile.new(id: "uploads/abc123.jpg", ...)
file.variant_location("sizes_large")
# => "uploads/abc123/sizes_large.jpg"

[View source]