Can scrobble individual discs
This commit is contained in:
@@ -35,28 +35,73 @@ defmodule MusicLibrary.ScrobbleActivity do
|
|||||||
{scrobbles, _finished_at} =
|
{scrobbles, _finished_at} =
|
||||||
release_with_tracks
|
release_with_tracks
|
||||||
|> MusicBrainz.Release.tracks()
|
|> MusicBrainz.Release.tracks()
|
||||||
|> Enum.map_reduce(started_at, fn track, time ->
|
|> to_scrobbles(release_with_tracks, started_at)
|
||||||
album_artist =
|
|
||||||
if release_with_tracks.artists !== track.artists do
|
|
||||||
main_artist_name(release_with_tracks.artists)
|
|
||||||
end
|
|
||||||
|
|
||||||
time = time |> DateTime.add(track.length, :millisecond)
|
|
||||||
|
|
||||||
scrobble = %Scrobble{
|
|
||||||
artist: main_artist_name(track.artists),
|
|
||||||
album: release_with_tracks.title,
|
|
||||||
album_artist: album_artist,
|
|
||||||
track: track.title,
|
|
||||||
timestamp: DateTime.to_unix(time)
|
|
||||||
}
|
|
||||||
|
|
||||||
{scrobble, time}
|
|
||||||
end)
|
|
||||||
|
|
||||||
LastFm.scrobble(scrobbles, session_key)
|
LastFm.scrobble(scrobbles, session_key)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def scrobble_medium(number, release_with_tracks, opts) when is_list(opts) do
|
||||||
|
case Enum.sort(opts) do
|
||||||
|
[finished_at: _, started_at: _] ->
|
||||||
|
raise ArgumentError, """
|
||||||
|
Cannot scobble a medium with both started_at and finished_at.
|
||||||
|
Remove either of them.
|
||||||
|
"""
|
||||||
|
|
||||||
|
[started_at: started_at] ->
|
||||||
|
scrobble_medium(number, release_with_tracks, {:started_at, started_at})
|
||||||
|
|
||||||
|
[finished_at: finished_at] ->
|
||||||
|
scrobble_medium(number, release_with_tracks, {:finished_at, finished_at})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def scrobble_medium(number, release_with_tracks, {:finished_at, finished_at}) do
|
||||||
|
medium_duration =
|
||||||
|
release_with_tracks.media
|
||||||
|
|> Enum.find(fn medium -> medium.number == number end)
|
||||||
|
|> Release.medium_duration()
|
||||||
|
|
||||||
|
started_at = DateTime.add(finished_at, -medium_duration, :millisecond)
|
||||||
|
scrobble_medium(number, release_with_tracks, {:started_at, started_at})
|
||||||
|
end
|
||||||
|
|
||||||
|
def scrobble_medium(number, release_with_tracks, {:started_at, started_at}) do
|
||||||
|
session_key = Secrets.get!("last_fm_session_key").value
|
||||||
|
|
||||||
|
medium =
|
||||||
|
release_with_tracks.media
|
||||||
|
|> Enum.find(fn medium -> medium.number == number end)
|
||||||
|
|
||||||
|
{scrobbles, _finished_at} =
|
||||||
|
medium.tracks
|
||||||
|
|> to_scrobbles(release_with_tracks, started_at)
|
||||||
|
|
||||||
|
LastFm.scrobble(scrobbles, session_key)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp to_scrobbles(tracks, release_with_tracks, started_at) do
|
||||||
|
tracks
|
||||||
|
|> Enum.map_reduce(started_at, fn track, time ->
|
||||||
|
album_artist =
|
||||||
|
if release_with_tracks.artists !== track.artists do
|
||||||
|
main_artist_name(release_with_tracks.artists)
|
||||||
|
end
|
||||||
|
|
||||||
|
time = time |> DateTime.add(track.length, :millisecond)
|
||||||
|
|
||||||
|
scrobble = %Scrobble{
|
||||||
|
artist: main_artist_name(track.artists),
|
||||||
|
album: release_with_tracks.title,
|
||||||
|
album_artist: album_artist,
|
||||||
|
track: track.title,
|
||||||
|
timestamp: DateTime.to_unix(time)
|
||||||
|
}
|
||||||
|
|
||||||
|
{scrobble, time}
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
defp main_artist_name([]), do: nil
|
defp main_artist_name([]), do: nil
|
||||||
defp main_artist_name([artist | _rest]), do: artist.name
|
defp main_artist_name([artist | _rest]), do: artist.name
|
||||||
|
|
||||||
|
|||||||
@@ -66,12 +66,24 @@ defmodule MusicLibraryWeb.ReleaseComponent do
|
|||||||
</div>
|
</div>
|
||||||
</:failed>
|
</:failed>
|
||||||
<div :for={medium <- release_with_tracks.media} class="space-y-4">
|
<div :for={medium <- release_with_tracks.media} class="space-y-4">
|
||||||
<h4
|
<div class="flex justify-between items-center gap-4">
|
||||||
:if={MusicBrainz.Release.media_count(release_with_tracks) > 1}
|
<h4
|
||||||
class="text-sm font-semibold text-zinc-700 dark:text-zinc-300"
|
:if={MusicBrainz.Release.media_count(release_with_tracks) > 1}
|
||||||
>
|
class="text-sm font-semibold text-zinc-700 dark:text-zinc-300"
|
||||||
{medium_title(medium)}
|
>
|
||||||
</h4>
|
{medium_title(medium)}
|
||||||
|
</h4>
|
||||||
|
<Fluxon.Components.Button.button
|
||||||
|
:if={@can_scrobble?}
|
||||||
|
size="xs"
|
||||||
|
phx-click="scrobble_medium"
|
||||||
|
phx-value-number={medium.number}
|
||||||
|
phx-target={@myself}
|
||||||
|
phx-disable-with={gettext("Scrobbling...")}
|
||||||
|
>
|
||||||
|
{gettext("Scrobble disc")}
|
||||||
|
</Fluxon.Components.Button.button>
|
||||||
|
</div>
|
||||||
<ul id={"disc-#{medium.number}"} class="w-full table table-auto">
|
<ul id={"disc-#{medium.number}"} class="w-full table table-auto">
|
||||||
<li
|
<li
|
||||||
:for={track <- medium.tracks}
|
:for={track <- medium.tracks}
|
||||||
@@ -140,6 +152,33 @@ defmodule MusicLibraryWeb.ReleaseComponent do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def handle_event("scrobble_medium", %{"number" => number}, socket) do
|
||||||
|
release_with_tracks_async_result =
|
||||||
|
socket.assigns.release_with_tracks
|
||||||
|
|
||||||
|
number = String.to_integer(number)
|
||||||
|
|
||||||
|
if release_with_tracks =
|
||||||
|
release_with_tracks_async_result && release_with_tracks_async_result.result do
|
||||||
|
case ScrobbleActivity.scrobble_medium(number, release_with_tracks,
|
||||||
|
finished_at: DateTime.utc_now()
|
||||||
|
) do
|
||||||
|
{:ok, _} ->
|
||||||
|
{:noreply,
|
||||||
|
socket
|
||||||
|
|> put_flash(:info, gettext("Disc scrobbled successfully"))}
|
||||||
|
|
||||||
|
{:error, reason} ->
|
||||||
|
{:noreply,
|
||||||
|
socket
|
||||||
|
|> put_flash(
|
||||||
|
:error,
|
||||||
|
gettext("Error scrobbling disc") <> "," <> inspect(reason)
|
||||||
|
)}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
defp medium_duration(medium) do
|
defp medium_duration(medium) do
|
||||||
medium
|
medium
|
||||||
|> MusicBrainz.Release.medium_duration()
|
|> MusicBrainz.Release.medium_duration()
|
||||||
|
|||||||
@@ -819,3 +819,8 @@ msgstr ""
|
|||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Error scrobbling disc"
|
msgid "Error scrobbling disc"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/music_library_web/components/release_component.ex
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Scrobble disc"
|
||||||
|
msgstr ""
|
||||||
|
|||||||
@@ -819,3 +819,8 @@ msgstr ""
|
|||||||
#, elixir-autogen, elixir-format, fuzzy
|
#, elixir-autogen, elixir-format, fuzzy
|
||||||
msgid "Error scrobbling disc"
|
msgid "Error scrobbling disc"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/music_library_web/components/release_component.ex
|
||||||
|
#, elixir-autogen, elixir-format, fuzzy
|
||||||
|
msgid "Scrobble disc"
|
||||||
|
msgstr ""
|
||||||
|
|||||||
Reference in New Issue
Block a user