diff --git a/lib/music_library/records.ex b/lib/music_library/records.ex
index 6e373d26..96f65a36 100644
--- a/lib/music_library/records.ex
+++ b/lib/music_library/records.ex
@@ -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.
diff --git a/lib/music_library/records/importer.ex b/lib/music_library/records/importer.ex
index 8fd37e8c..2a8fbd51 100644
--- a/lib/music_library/records/importer.ex
+++ b/lib/music_library/records/importer.ex
@@ -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
diff --git a/lib/music_library/records/record.ex b/lib/music_library/records/record.ex
index a4279465..e1e3390c 100644
--- a/lib/music_library/records/record.ex
+++ b/lib/music_library/records/record.ex
@@ -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
diff --git a/lib/music_library_web/controllers/image_controller.ex b/lib/music_library_web/controllers/image_controller.ex
new file mode 100644
index 00000000..4e393977
--- /dev/null
+++ b/lib/music_library_web/controllers/image_controller.ex
@@ -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
diff --git a/lib/music_library_web/live/record_live/form_component.ex b/lib/music_library_web/live/record_live/form_component.ex
index 84123f1c..0d6be204 100644
--- a/lib/music_library_web/live/record_live/form_component.ex
+++ b/lib/music_library_web/live/record_live/form_component.ex
@@ -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
diff --git a/lib/music_library_web/live/record_live/index.html.heex b/lib/music_library_web/live/record_live/index.html.heex
index e719473b..0088ae88 100644
--- a/lib/music_library_web/live/record_live/index.html.heex
+++ b/lib/music_library_web/live/record_live/index.html.heex
@@ -13,7 +13,7 @@
row_click={fn {_id, record} -> JS.navigate(~p"/records/#{record}") end}
>
<:col :let={{_id, record}} label="Image">
-
+
<:col :let={{_id, record}} label="Artists">
<%= Enum.map(record.artists, fn a -> a.name end) %>
diff --git a/lib/music_library_web/live/record_live/show.html.heex b/lib/music_library_web/live/record_live/show.html.heex
index c4ecd17e..7b4287b5 100644
--- a/lib/music_library_web/live/record_live/show.html.heex
+++ b/lib/music_library_web/live/record_live/show.html.heex
@@ -15,7 +15,9 @@
<:item title="Musicbrainz"><%= @record.musicbrainz_id %>
<:item title="Year"><%= @record.year %>
<:item title="Genres"><%= @record.genres %>
- <:item title="Image"><%= @record.image %>
+ <:item title="Image">
+
+
<.back navigate={~p"/records"}>Back to records
diff --git a/lib/music_library_web/router.ex b/lib/music_library_web/router.ex
index 5a42eccd..f2dfb5d3 100644
--- a/lib/music_library_web/router.ex
+++ b/lib/music_library_web/router.ex
@@ -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
diff --git a/priv/repo/migrations/20240916080955_store_cover_images.exs b/priv/repo/migrations/20240916080955_store_cover_images.exs
new file mode 100644
index 00000000..85534067
--- /dev/null
+++ b/priv/repo/migrations/20240916080955_store_cover_images.exs
@@ -0,0 +1,11 @@
+defmodule MusicLibrary.Repo.Migrations.StoreCoverImages do
+ use Ecto.Migration
+
+ def change do
+ rename table(:records), :image, to: :image_url
+
+ alter table(:records) do
+ add :image_data, :blob
+ end
+ end
+end
diff --git a/test/music_library/records_test.exs b/test/music_library/records_test.exs
index f475bac3..7a2565a9 100644
--- a/test/music_library/records_test.exs
+++ b/test/music_library/records_test.exs
@@ -11,7 +11,7 @@ defmodule MusicLibrary.RecordsTest do
@invalid_attrs %{
type: nil,
title: nil,
- image: nil,
+ image_url: nil,
year: nil,
musicbrainz_id: nil,
genres: nil
@@ -31,7 +31,7 @@ defmodule MusicLibrary.RecordsTest do
valid_attrs = %{
type: :album,
title: "some title",
- image: "some image",
+ image_url: "some image url",
year: 42,
musicbrainz_id: "7488a646-e31f-11e4-aace-600308960662",
genres: ["option1", "option2"]
@@ -40,7 +40,7 @@ defmodule MusicLibrary.RecordsTest do
assert {:ok, %Record{} = record} = Records.create_record(valid_attrs)
assert record.type == :album
assert record.title == "some title"
- assert record.image == "some image"
+ assert record.image_url == "some image url"
assert record.year == 42
assert record.musicbrainz_id == "7488a646-e31f-11e4-aace-600308960662"
assert record.genres == ["option1", "option2"]
@@ -56,7 +56,7 @@ defmodule MusicLibrary.RecordsTest do
update_attrs = %{
type: :ep,
title: "some updated title",
- image: "some updated image",
+ image_url: "some updated image url",
year: 43,
musicbrainz_id: "7488a646-e31f-11e4-aace-600308960668",
genres: ["option1"]
@@ -65,7 +65,7 @@ defmodule MusicLibrary.RecordsTest do
assert {:ok, %Record{} = record} = Records.update_record(record, update_attrs)
assert record.type == :ep
assert record.title == "some updated title"
- assert record.image == "some updated image"
+ assert record.image_url == "some updated image url"
assert record.year == 43
assert record.musicbrainz_id == "7488a646-e31f-11e4-aace-600308960668"
assert record.genres == ["option1"]
diff --git a/test/music_library_web/live/record_live_test.exs b/test/music_library_web/live/record_live_test.exs
index 357a010c..fe208f99 100644
--- a/test/music_library_web/live/record_live_test.exs
+++ b/test/music_library_web/live/record_live_test.exs
@@ -7,7 +7,7 @@ defmodule MusicLibraryWeb.RecordLiveTest do
@create_attrs %{
type: :album,
title: "some title",
- image: "some image",
+ image_url: "some image url",
year: 42,
musicbrainz_id: "7488a646-e31f-11e4-aace-600308960662",
genres: ["option1", "option2"]
@@ -15,12 +15,19 @@ defmodule MusicLibraryWeb.RecordLiveTest do
@update_attrs %{
type: :ep,
title: "some updated title",
- image: "some updated image",
+ image_url: "some updated image url",
year: 43,
musicbrainz_id: "7488a646-e31f-11e4-aace-600308960668",
genres: ["option1"]
}
- @invalid_attrs %{type: nil, title: nil, image: nil, year: nil, musicbrainz_id: nil, genres: []}
+ @invalid_attrs %{
+ type: nil,
+ title: nil,
+ image_url: nil,
+ year: nil,
+ musicbrainz_id: nil,
+ genres: []
+ }
defp create_record(_) do
record = record_fixture()
diff --git a/test/support/fixtures/records_fixtures.ex b/test/support/fixtures/records_fixtures.ex
index 0f8d9f17..970d19bf 100644
--- a/test/support/fixtures/records_fixtures.ex
+++ b/test/support/fixtures/records_fixtures.ex
@@ -12,7 +12,7 @@ defmodule MusicLibrary.RecordsFixtures do
attrs
|> Enum.into(%{
genres: ["option1", "option2"],
- image: "some image",
+ image_url: "some image url",
musicbrainz_id: "7488a646-e31f-11e4-aace-600308960662",
title: "some title",
type: :album,