Add convenience to store images

This commit is contained in:
Claudio Ortolina
2025-09-01 11:03:30 +03:00
parent a605610c9d
commit db843bf061
3 changed files with 59 additions and 0 deletions
+13
View File
@@ -2,9 +2,22 @@ defmodule MusicLibrary.Assets do
alias MusicLibrary.Assets.Asset
alias MusicLibrary.Repo
@doc """
Store any file type - the responsibility to correctly populate format and
properties is left to the caller.
"""
def store(params) do
%Asset{}
|> Asset.changeset(params)
|> Repo.insert()
end
@doc """
Store image files - properties will be computed automatically.
"""
def store_image(params) do
%Asset{}
|> Asset.image_changeset(params)
|> Repo.insert()
end
end
+30
View File
@@ -3,6 +3,8 @@ defmodule MusicLibrary.Assets.Asset do
import Ecto.Changeset
alias Vix.Vips.Image
@primary_key {:hash, :string, autogenerate: false}
schema "assets" do
field :content, :binary
@@ -20,6 +22,15 @@ defmodule MusicLibrary.Assets.Asset do
|> unique_constraint(:hash)
end
def image_changeset(asset, attrs) do
asset
|> cast(attrs, [:content, :format])
|> validate_required([:content, :format])
|> generate_hash()
|> generate_properties()
|> unique_constraint(:hash)
end
defp generate_hash(changeset) do
case get_change(changeset, :content) do
nil ->
@@ -30,6 +41,25 @@ defmodule MusicLibrary.Assets.Asset do
end
end
defp generate_properties(changeset) do
case get_change(changeset, :content) do
nil ->
changeset
content ->
put_change(changeset, :properties, get_image_properties(content))
end
end
defp get_image_properties(content) do
{:ok, image} = Image.new_from_buffer(content)
%{
"width" => Image.width(image),
"height" => Image.height(image)
}
end
defp hash(content) do
:crypto.hash(:sha256, content) |> Base.encode16()
end