Store and edit artist images as assets

This commit is contained in:
Claudio Ortolina
2025-09-18 21:24:28 +03:00
parent 83151a125b
commit f57424d610
3 changed files with 13 additions and 37 deletions
+4 -3
View File
@@ -2,6 +2,7 @@ defmodule MusicLibrary.Artists do
import Ecto.Query, warn: false import Ecto.Query, warn: false
alias MusicLibrary.Artists.ArtistInfo alias MusicLibrary.Artists.ArtistInfo
alias MusicLibrary.Assets
alias MusicLibrary.Records.{ArtistRecord, Record} alias MusicLibrary.Records.{ArtistRecord, Record}
alias MusicLibrary.Repo alias MusicLibrary.Repo
alias MusicLibrary.{BackgroundRepo, Worker} alias MusicLibrary.{BackgroundRepo, Worker}
@@ -114,11 +115,11 @@ defmodule MusicLibrary.Artists do
artist_info = get_artist_info!(artist_id) artist_info = get_artist_info!(artist_id)
with {:ok, image} <- ArtistInfo.extract_image(artist_info), with {:ok, image} <- ArtistInfo.extract_image(artist_info),
{:ok, image_data} <- Discogs.get_artist_image(image.url) do {:ok, image_data} <- Discogs.get_artist_image(image.url),
{:ok, asset} <- Assets.store_image(%{content: image_data, format: "image/jpeg"}) do
artist_info artist_info
|> ArtistInfo.changeset(%{ |> ArtistInfo.changeset(%{
image_data: image_data, image_data_hash: asset.hash
image_data_width: image.width
}) })
|> Repo.update() |> Repo.update()
end end
+1 -21
View File
@@ -3,15 +3,11 @@ defmodule MusicLibrary.Artists.ArtistInfo do
import Ecto.Changeset import Ecto.Changeset
alias MusicLibrary.Assets.Asset
@primary_key {:id, :binary_id, autogenerate: true} @primary_key {:id, :binary_id, autogenerate: true}
schema "artist_infos" do schema "artist_infos" do
field :musicbrainz_data, :map, default: %{} field :musicbrainz_data, :map, default: %{}
field :discogs_data, :map, default: %{} field :discogs_data, :map, default: %{}
field :image_data, :binary
field :image_data_hash, :string field :image_data_hash, :string
field :image_data_width, :integer
timestamps(type: :utc_datetime) timestamps(type: :utc_datetime)
end end
@@ -22,11 +18,9 @@ defmodule MusicLibrary.Artists.ArtistInfo do
:id, :id,
:musicbrainz_data, :musicbrainz_data,
:discogs_data, :discogs_data,
:image_data, :image_data_hash
:image_data_width
]) ])
|> validate_required([:musicbrainz_data]) |> validate_required([:musicbrainz_data])
|> generate_image_hash()
end end
def country(artist_info) do def country(artist_info) do
@@ -48,20 +42,6 @@ defmodule MusicLibrary.Artists.ArtistInfo do
String.slice(country_code, 0..1) String.slice(country_code, 0..1)
end end
def generate_image_hash(%__MODULE__{image_data: image_data} = artist_info) do
change(artist_info, image_data_hash: Asset.hash(image_data))
end
def generate_image_hash(changeset) do
case get_change(changeset, :image_data) do
nil ->
changeset
image_data ->
put_change(changeset, :image_data_hash, Asset.hash(image_data))
end
end
def extract_image(artist_info) when is_nil(artist_info.discogs_data) do def extract_image(artist_info) when is_nil(artist_info.discogs_data) do
{:error, :no_discogs_data} {:error, :no_discogs_data}
end end
@@ -2,8 +2,8 @@ defmodule MusicLibraryWeb.ArtistLive.FormComponent do
use MusicLibraryWeb, :live_component use MusicLibraryWeb, :live_component
alias MusicLibrary.Artists alias MusicLibrary.Artists
alias MusicLibrary.Assets
alias MusicLibrary.Assets.Transform alias MusicLibrary.Assets.Transform
alias Vix.Vips.Image
@impl true @impl true
def mount(socket) do def mount(socket) do
@@ -112,8 +112,9 @@ defmodule MusicLibraryWeb.ArtistLive.FormComponent do
artist_info_params = params["artist_info"] || %{} artist_info_params = params["artist_info"] || %{}
uploaded_images = uploaded_images =
consume_uploaded_entries(socket, :image_data, fn %{path: path}, _entry -> consume_uploaded_entries(socket, :image_data, fn %{path: path}, entry ->
{:ok, File.read!(path)} params = %{content: File.read!(path), format: entry.client_type}
{:ok, params}
end) end)
save_artist_info(socket, artist_info_params, uploaded_images) save_artist_info(socket, artist_info_params, uploaded_images)
@@ -129,15 +130,9 @@ defmodule MusicLibraryWeb.ArtistLive.FormComponent do
[] -> [] ->
artist_info_params artist_info_params
[image_data] -> [image_params] ->
{:ok, image} = Image.new_from_buffer(image_data) {:ok, asset} = Assets.store_image(image_params)
Map.put(artist_info_params, "image_data_hash", asset.hash)
image_width = Image.width(image)
Map.merge(artist_info_params, %{
"image_data" => image_data,
"image_data_width" => image_width
})
end end
case Artists.update_artist_info(socket.assigns.artist_info, params) do case Artists.update_artist_info(socket.assigns.artist_info, params) do
@@ -158,7 +153,7 @@ defmodule MusicLibraryWeb.ArtistLive.FormComponent do
defp artist_image_path(artist_info) do defp artist_image_path(artist_info) do
payload = payload =
%Transform{hash: artist_info.image_hash, width: 96} %Transform{hash: artist_info.image_data_hash}
|> Transform.encode!() |> Transform.encode!()
~p"/assets/#{payload}" ~p"/assets/#{payload}"