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"> - {record.title} + {record.title} <: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"> + {@record.title} + <.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,