Packages

ActiveStorage-like file storage for Phoenix. All things file uploads for your Phoenix app.

Current section

Files

Jump to
phoenix_contrib_storage lib storage uploader.ex
Raw

lib/storage/uploader.ex

defmodule Storage.Uploader do
@moduledoc """
Handles file uploads and creates blobs.
"""
alias Storage.Blob
@doc """
Uploads a file and creates a blob record.
## Options
- `:filename` - The original filename (required)
- `:content_type` - MIME type of the file (inferred from filename if not provided)
- `:service_name` - Storage service to use (defaults to configured default)
- `:metadata` - Additional metadata to store with the blob
## Examples
# Upload from file path
Storage.Uploader.put("/path/to/file.jpg", filename: "avatar.jpg")
# Upload binary data
Storage.Uploader.put(file_binary,
filename: "document.pdf",
content_type: "application/pdf"
)
# Upload with metadata
Storage.Uploader.put(file_data,
filename: "image.jpg",
metadata: %{alt_text: "Profile picture", user_id: 123}
)
"""
def put(file_data, opts \\ []) do
filename = Keyword.get(opts, :filename) ||
raise ArgumentError, "filename is required"
content_type = Keyword.get(opts, :content_type) ||
MIME.from_path(filename)
service_name = Keyword.get(opts, :service_name) ||
Storage.Config.default_service()
metadata = Keyword.get(opts, :metadata, %{})
# Normalize file data
normalized_data = normalize_file_data(file_data)
attrs = %{
filename: filename,
content_type: content_type,
service_name: service_name,
metadata: metadata
}
try do
blob = Blob.create_and_upload!(normalized_data, attrs)
{:ok, blob}
rescue
error -> {:error, error}
end
end
@doc """
Same as `put/2` but raises on error.
"""
def put!(file_data, opts \\ []) do
case put(file_data, opts) do
{:ok, blob} -> blob
{:error, error} -> raise error
end
end
# Private functions
defp normalize_file_data(path) when is_binary(path) do
if File.exists?(path) do
File.read!(path)
else
path # Assume it's binary data
end
end
defp normalize_file_data(%{path: path}) do
File.read!(path)
end
defp normalize_file_data(data) when is_binary(data) do
data
end
defp normalize_file_data(%Plug.Upload{path: path}) do
File.read!(path)
end
end