Serve local cover images

This commit is contained in:
Claudio Ortolina
2024-09-16 09:50:07 +01:00
parent f1160eddd4
commit afc1802399
12 changed files with 92 additions and 15 deletions
+5
View File
@@ -42,6 +42,11 @@ defmodule MusicLibrary.Records do
"""
def get_record!(id), do: Repo.get!(Record, id)
def get_image!(id) do
record = get_record!(id)
{:ok, record.image_data}
end
@doc """
Creates a record.
+29
View File
@@ -61,6 +61,14 @@ defmodule MusicLibrary.Records.Importer do
end
end
def import_cover_image(record) do
with {:ok, image_data} <- blob_get(record.image_url) do
record
|> Rec.add_image_data(image_data)
|> MusicLibrary.Repo.update!()
end
end
def import_all do
Rec
|> MusicLibrary.Repo.all()
@@ -97,4 +105,25 @@ defmodule MusicLibrary.Records.Importer do
{:error, msg}
end
end
defp blob_get(url) do
req =
Finch.build(:get, url, [
{"User-Agent", "MusicLibrary/0.1.0 ( cloud8421@gmail.com )"}
])
case Finch.request(req, MusicLibrary.Finch) do
{:ok, response} when response.status == 200 ->
{:ok, response.body}
{:ok, response} when response.status in 301..308 ->
location = :proplists.get_value("location", response.headers)
blob_get(location)
other ->
msg = "Failed to fetch data from #{url}, reason: #{inspect(other)}"
Logger.error(msg)
{:error, msg}
end
end
end
+8 -3
View File
@@ -7,7 +7,8 @@ defmodule MusicLibrary.Records.Record do
schema "records" do
field :type, Ecto.Enum, values: [:album, :ep, :live, :compilation, :single, :other]
field :title, :string
field :image, :string
field :image_url, :string
field :image_data, :binary
field :year, :integer
field :musicbrainz_id, Ecto.UUID
field :genres, {:array, :string}
@@ -25,8 +26,8 @@ defmodule MusicLibrary.Records.Record do
@doc false
def changeset(record, attrs) do
record
|> cast(attrs, [:type, :title, :musicbrainz_id, :year, :genres, :image])
|> validate_required([:type, :title, :musicbrainz_id, :year, :genres, :image])
|> cast(attrs, [:type, :title, :musicbrainz_id, :year, :genres, :image_url])
|> validate_required([:type, :title, :musicbrainz_id, :year, :genres, :image_url])
end
def add_artists(record, artists_attrs) do
@@ -34,4 +35,8 @@ defmodule MusicLibrary.Records.Record do
|> change()
|> put_embed(:artists, artists_attrs)
end
def add_image_data(record, image_data) do
change(record, image_data: image_data)
end
end
@@ -0,0 +1,17 @@
defmodule MusicLibraryWeb.ImageController do
use MusicLibraryWeb, :controller
alias MusicLibrary.Records
def show(conn, %{"record_id" => record_id}) do
{:ok, image_data} = Records.get_image!(record_id)
if image_data do
conn
|> put_resp_content_type("image/jpeg", "utf-8")
|> send_resp(200, image_data)
else
conn |> send_resp(404, "Not found")
end
end
end
@@ -36,7 +36,7 @@ defmodule MusicLibraryWeb.RecordLive.FormComponent do
label="Genres"
options={[{"Option 1", "option1"}, {"Option 2", "option2"}]}
/>
<.input field={@form[:image]} type="text" label="Image" />
<.input field={@form[:image_url]} type="text" label="Image url" />
<:actions>
<.button phx-disable-with="Saving...">Save Record</.button>
</:actions>
@@ -13,7 +13,7 @@
row_click={fn {_id, record} -> JS.navigate(~p"/records/#{record}") end}
>
<:col :let={{_id, record}} label="Image">
<img class="max-w-16" src={record.image} alt={record.title} />
<img class="max-w-16" src={~p"/images/#{record.id}"} alt={record.title} />
</:col>
<:col :let={{_id, record}} label="Artists">
<%= Enum.map(record.artists, fn a -> a.name end) %>
@@ -15,7 +15,9 @@
<:item title="Musicbrainz"><%= @record.musicbrainz_id %></:item>
<:item title="Year"><%= @record.year %></:item>
<:item title="Genres"><%= @record.genres %></:item>
<:item title="Image"><%= @record.image %></:item>
<:item title="Image">
<img class="max-w-32" src={~p"/images/#{@record.id}"} alt={@record.title} />
</:item>
</.list>
<.back navigate={~p"/records"}>Back to records</.back>
+1
View File
@@ -18,6 +18,7 @@ defmodule MusicLibraryWeb.Router do
pipe_through :browser
get "/", PageController, :home
get "/images/:record_id", ImageController, :show
live "/records", RecordLive.Index, :index
live "/records/new", RecordLive.Index, :new