Show release metadata after scanning

This commit is contained in:
Claudio Ortolina
2025-02-15 17:56:48 +00:00
parent 337b1bb75d
commit bb6e805e7b
4 changed files with 149 additions and 14 deletions
+25
View File
@@ -19,6 +19,18 @@ defmodule MusicBrainz.ReleaseSearchResult do
}
end
def format(release_search_result) do
sorted_frequencies =
release_search_result.media
|> Enum.frequencies_by(& &1.format)
|> Enum.sort_by(fn {_, count} -> count end)
case sorted_frequencies do
[{format, _}] -> parse_format(format)
_ -> :multi
end
end
defp parse_release_group(rg) do
%{
id: rg["id"],
@@ -36,4 +48,17 @@ defmodule MusicBrainz.ReleaseSearchResult do
}
end)
end
defp parse_format("CD"), do: :cd
defp parse_format("DVD-Audio"), do: :dvd
defp parse_format("DVD-Video"), do: :dvd
defp parse_format("Blu-ray"), do: :blu_ray
defp parse_format(maybe_vinyl) do
if String.contains?(maybe_vinyl, "Vinyl") do
:vinyl
else
:unknown
end
end
end
@@ -1,6 +1,7 @@
defmodule MusicLibraryWeb.RecordLive.BarcodeScannerComponent do
use MusicLibraryWeb, :live_component
alias MusicLibraryWeb.RecordComponents
alias MusicLibrary.Records
require Logger
@@ -10,9 +11,8 @@ defmodule MusicLibraryWeb.RecordLive.BarcodeScannerComponent do
{:ok,
socket
|> assign(:camera, :pending)
|> assign(:barcodes, MapSet.new())
|> assign(:releases, [
%MusicBrainz.ReleaseSearchResult{
|> assign(:releases, %{
"639842709422" => %MusicBrainz.ReleaseSearchResult{
id: "dc393148-be34-4056-be66-b2b95905c5c1",
title: "Equally Cursed and Blessed",
release_group: %{
@@ -25,7 +25,7 @@ defmodule MusicLibraryWeb.RecordLive.BarcodeScannerComponent do
barcode: "639842709422",
media: [%{format: "CD", disc_count: 5, track_count: 11}]
}
])}
})}
end
@impl true
@@ -67,13 +67,13 @@ defmodule MusicLibraryWeb.RecordLive.BarcodeScannerComponent do
<video :if={!(@camera == :denied)} class="w-full hidden" id="camera-preview"></video>
</div>
<div :if={length(@releases) > 0} class="mt-4 flex justify-center">
<div :if={map_size(@releases) > 0} class="mt-4 flex justify-center">
<.button phx-click={JS.push("import_releases", target: "#barcode-scanner")}>
{gettext("Import releases")}
</.button>
</div>
<ul class="divide-y divide-zinc-100 dark:divide-slate-300/30 mt-5">
<.result :for={release <- @releases} id={release.id} release={release} />
<.result :for={{_barcode, release} <- @releases} id={release.id} release={release} />
</ul>
</div>
"""
@@ -85,7 +85,7 @@ defmodule MusicLibraryWeb.RecordLive.BarcodeScannerComponent do
defp result(assigns) do
~H"""
<li id={@id} class="flex justify-between gap-x-6 py-5 hover:bg-zinc-50 dark:hover:bg-zinc-700">
<div class="shrink-0 flex items-center justify-between w-full px-4">
<div class="flex items-center justify-between w-full px-4">
<div class="min-w-0 flex-auto">
<h1 class="text-sm leading-6 text-zinc-700 dark:text-zinc-400">
{@release.artists}
@@ -94,7 +94,9 @@ defmodule MusicLibraryWeb.RecordLive.BarcodeScannerComponent do
{@release.title}
</h2>
<p class="mt-1 text-xs leading-5 text-zinc-500 dark:text-zinc-400">
{Records.Record.format_release(@release.date)} · {@release.barcode}
{release_format_label(@release)} · {Records.Record.format_release(@release.date)} · {RecordComponents.type_label(
@release.release_group.type
)}
</p>
</div>
</div>
@@ -116,14 +118,33 @@ defmodule MusicLibraryWeb.RecordLive.BarcodeScannerComponent do
def handle_event("barcode_scanned", %{"number" => number}, socket) do
Logger.debug(fn -> "Scanned barcode #{number}" end)
{:ok, releases} =
Records.search_release_by_barcode(number)
socket =
socket
|> assign(barcodes: MapSet.put(socket.assigns.barcodes, number))
|> assign(:releases, releases ++ socket.assigns.releases)
case Records.search_release_by_barcode(number) do
{:ok, [best_match_release | _other_releases]} ->
best_match_release |> IO.inspect()
assign(socket, :releases, Map.put(socket.assigns.releases, number, best_match_release))
{:ok, []} ->
put_flash(
socket,
:error,
gettext("No release found for barcode %{number}", number: number)
)
{:error, _reason} ->
put_flash(
socket,
:error,
gettext("Failed to search release for barcode %{number}", number: number)
)
end
{:noreply, socket}
end
defp release_format_label(release) do
release
|> MusicBrainz.ReleaseSearchResult.format()
|> RecordComponents.format_label()
end
end
+10
View File
@@ -644,3 +644,13 @@ msgstr ""
#, elixir-autogen, elixir-format
msgid "Import releases"
msgstr ""
#: lib/music_library_web/live/record_live/barcode_scanner_component.ex:138
#, elixir-autogen, elixir-format
msgid "Failed to search release for barcode %{number}"
msgstr ""
#: lib/music_library_web/live/record_live/barcode_scanner_component.ex:131
#, elixir-autogen, elixir-format
msgid "No release found for barcode %{number}"
msgstr ""
@@ -0,0 +1,79 @@
defmodule MusicBrainz.ReleaseSearchResultTest do
use ExUnit.Case, async: true
alias MusicBrainz.ReleaseSearchResult
@single_cd %MusicBrainz.ReleaseSearchResult{
id: "dc393148-be34-4056-be66-b2b95905c5c1",
title: "Equally Cursed and Blessed",
release_group: %{
id: "c35fc446-65cc-3645-939b-1b3782e60639",
type: :album,
title: "Equally Cursed and Blessed"
},
artists: "Catatonia",
date: "1999-04-12",
barcode: "639842709422",
media: [%{format: "CD", disc_count: 5, track_count: 11}]
}
@double_cd %MusicBrainz.ReleaseSearchResult{
id: "51ebc32b-d21f-4466-9297-94b6a3e0e6ba",
title: "Rock in Rio",
release_group: %{
id: "ea6dac58-887a-35a8-86ff-08c56e6bf047",
type: :album,
title: "Rock in Rio"
},
artists: "Iron Maiden",
date: "2002-03-21",
barcode: "724353864309",
media: [
%{format: "CD", disc_count: 1, track_count: 10},
%{format: "CD", disc_count: 1, track_count: 9}
]
}
@single_vinyl %MusicBrainz.ReleaseSearchResult{
id: "3af1f610-9df1-4a48-8874-78cd64e25888",
title: "Somewhere in Time",
release_group: %{
id: "a5fe4d2d-3aab-3e86-91ad-22a3fe16c4f2",
type: :album,
title: "Somewhere in Time"
},
artists: "Iron Maiden",
date: "1986-09-29",
barcode: "5099924059718",
media: [%{format: "12\" Vinyl", disc_count: 0, track_count: 8}]
}
@multi %MusicBrainz.ReleaseSearchResult{
id: "804e4781-bc17-496e-8abd-d61c7173391c",
title: "Live With the Plovdiv Psychotic Symphony",
release_group: %{
id: "887898c3-ef40-4162-88d3-1fbc58ee2d09",
type: :album,
title: "Live With the Plovdiv Psychotic Symphony"
},
artists: "Sons of Apollo, Пловдивска филхармония",
date: "2019-08-30",
barcode: "190759669228",
media: [
%{format: "CD", disc_count: 0, track_count: 11},
%{format: "CD", disc_count: 1, track_count: 10},
%{format: "CD", disc_count: 0, track_count: 3},
%{format: "DVD-Video", disc_count: 0, track_count: 22},
%{format: "Blu-ray", disc_count: 0, track_count: 42}
]
}
describe "format/1" do
test "it returns the format of the release" do
assert ReleaseSearchResult.format(@single_cd) == :cd
assert ReleaseSearchResult.format(@single_vinyl) == :vinyl
assert ReleaseSearchResult.format(@double_cd) == :cd
assert ReleaseSearchResult.format(@multi) == :multi
end
end
end