Integrate refresh of Last.fm data (both per artist and batch)
This commit is contained in:
+1
-1
@@ -93,7 +93,7 @@ config :phoenix, :json_library, JSON
|
|||||||
|
|
||||||
config :music_library, Oban,
|
config :music_library, Oban,
|
||||||
engine: Oban.Engines.Lite,
|
engine: Oban.Engines.Lite,
|
||||||
queues: [default: 10, heavy_writes: 1, music_brainz: 1, discogs: 1, wikipedia: 1],
|
queues: [default: 10, heavy_writes: 1, music_brainz: 1, discogs: 1, wikipedia: 1, last_fm: 1],
|
||||||
repo: MusicLibrary.BackgroundRepo,
|
repo: MusicLibrary.BackgroundRepo,
|
||||||
plugins: [
|
plugins: [
|
||||||
{Oban.Plugins.Cron,
|
{Oban.Plugins.Cron,
|
||||||
|
|||||||
@@ -22,4 +22,10 @@ defmodule MusicLibrary.Artists.Batch do
|
|||||||
Artists.refresh_wikipedia_data_async(artist_info)
|
Artists.refresh_wikipedia_data_async(artist_info)
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def refresh_lastfm_data do
|
||||||
|
Batch.run_on_all(from(r in ArtistInfo), "artist_info", fn artist_info ->
|
||||||
|
Artists.fetch_lastfm_data_async(artist_info.id)
|
||||||
|
end)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ defmodule MusicLibrary.Worker.FetchArtistInfo do
|
|||||||
with {:ok, _artist_info} <- MusicLibrary.Artists.fetch_artist_info(artist_id),
|
with {:ok, _artist_info} <- MusicLibrary.Artists.fetch_artist_info(artist_id),
|
||||||
{:ok, _artist_info} <- MusicLibrary.Artists.fetch_wikipedia_data(artist_id),
|
{:ok, _artist_info} <- MusicLibrary.Artists.fetch_wikipedia_data(artist_id),
|
||||||
{:ok, _artist_info} <- MusicLibrary.Artists.fetch_image(artist_id) do
|
{:ok, _artist_info} <- MusicLibrary.Artists.fetch_image(artist_id) do
|
||||||
|
# fetch_lastfm_data returns {:ok, _} even on API errors, so it won't block embeddings
|
||||||
|
MusicLibrary.Artists.fetch_lastfm_data(artist_id)
|
||||||
regenerate_record_embeddings(artist_id)
|
regenerate_record_embeddings(artist_id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,11 +1,16 @@
|
|||||||
defmodule MusicLibrary.Worker.FetchArtistLastFmData do
|
defmodule MusicLibrary.Worker.FetchArtistLastFmData do
|
||||||
use Oban.Worker, queue: :default, max_attempts: 3
|
use Oban.Worker, queue: :last_fm, max_attempts: 3
|
||||||
|
|
||||||
@impl Oban.Worker
|
@impl Oban.Worker
|
||||||
def perform(%Oban.Job{args: %{"id" => artist_id}}) do
|
def perform(%Oban.Job{args: %{"id" => artist_id}}) do
|
||||||
case MusicLibrary.Artists.fetch_lastfm_data(artist_id) do
|
result =
|
||||||
{:ok, _artist_info} -> :ok
|
case MusicLibrary.Artists.fetch_lastfm_data(artist_id) do
|
||||||
error -> error
|
{:ok, _artist_info} -> :ok
|
||||||
end
|
error -> error
|
||||||
|
end
|
||||||
|
|
||||||
|
Process.sleep(500)
|
||||||
|
|
||||||
|
result
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -198,6 +198,18 @@ defmodule MusicLibraryWeb.ArtistLive.Show do
|
|||||||
/>
|
/>
|
||||||
{gettext("Refresh Wikipedia")}
|
{gettext("Refresh Wikipedia")}
|
||||||
</.dropdown_link>
|
</.dropdown_link>
|
||||||
|
<.dropdown_link
|
||||||
|
id={"actions-#{@artist.musicbrainz_id}-refresh-lastfm"}
|
||||||
|
phx-click={JS.push("refresh_lastfm_data", value: %{id: @artist.musicbrainz_id})}
|
||||||
|
>
|
||||||
|
<.icon
|
||||||
|
name="hero-arrow-path"
|
||||||
|
class="h-4 w-4 mr-1 phx-click-loading:animate-spin"
|
||||||
|
aria-hidden="true"
|
||||||
|
data-slot="icon"
|
||||||
|
/>
|
||||||
|
{gettext("Refresh Last.fm")}
|
||||||
|
</.dropdown_link>
|
||||||
</.focus_wrap>
|
</.focus_wrap>
|
||||||
</.dropdown>
|
</.dropdown>
|
||||||
</.button_group>
|
</.button_group>
|
||||||
@@ -444,6 +456,14 @@ defmodule MusicLibraryWeb.ArtistLive.Show do
|
|||||||
data: @artist_info.wikipedia_data,
|
data: @artist_info.wikipedia_data,
|
||||||
type: :json
|
type: :json
|
||||||
}
|
}
|
||||||
|
),
|
||||||
|
if(@artist_info.lastfm_data != %{},
|
||||||
|
do: %{
|
||||||
|
name: "lastfm",
|
||||||
|
title: gettext("Last.fm"),
|
||||||
|
data: @artist_info.lastfm_data,
|
||||||
|
type: :json
|
||||||
|
}
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
& &1
|
& &1
|
||||||
@@ -538,6 +558,28 @@ defmodule MusicLibraryWeb.ArtistLive.Show do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def handle_event("refresh_lastfm_data", %{"id" => id}, socket) do
|
||||||
|
case Artists.fetch_lastfm_data(id) do
|
||||||
|
{:ok, artist_info} ->
|
||||||
|
id
|
||||||
|
|> Records.get_artist_records()
|
||||||
|
|> Enum.each(&Records.generate_embedding_async/1)
|
||||||
|
|
||||||
|
{:noreply,
|
||||||
|
socket
|
||||||
|
|> assign(:artist_info, artist_info)
|
||||||
|
|> put_toast(:info, gettext("Last.fm data refreshed successfully"))}
|
||||||
|
|
||||||
|
{:error, reason} ->
|
||||||
|
{:noreply,
|
||||||
|
socket
|
||||||
|
|> put_toast(
|
||||||
|
:error,
|
||||||
|
gettext("Error refreshing Last.fm data") <> "," <> inspect(reason)
|
||||||
|
)}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def handle_event("refresh_artist_image", %{"id" => id}, socket) do
|
def handle_event("refresh_artist_image", %{"id" => id}, socket) do
|
||||||
case Artists.fetch_image(id) do
|
case Artists.fetch_image(id) do
|
||||||
{:ok, artist_info} ->
|
{:ok, artist_info} ->
|
||||||
|
|||||||
@@ -110,6 +110,19 @@ defmodule MusicLibraryWeb.MaintenanceLive.Index do
|
|||||||
<.loading :if={@refresh_artists_wikipedia_jobs > 0} class="size-4" />
|
<.loading :if={@refresh_artists_wikipedia_jobs > 0} class="size-4" />
|
||||||
{gettext("Refresh Wikipedia data")}
|
{gettext("Refresh Wikipedia data")}
|
||||||
</.button>
|
</.button>
|
||||||
|
<.button
|
||||||
|
type="button"
|
||||||
|
phx-click="refresh_artists_lastfm_data"
|
||||||
|
disabled={@refresh_artists_lastfm_jobs > 0}
|
||||||
|
data-confirm={
|
||||||
|
gettext(
|
||||||
|
"Are you sure you want to refresh Last.fm data for all artists? This operation can take a long time to complete."
|
||||||
|
)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<.loading :if={@refresh_artists_lastfm_jobs > 0} class="size-4" />
|
||||||
|
{gettext("Refresh Last.fm data")}
|
||||||
|
</.button>
|
||||||
</.button_group>
|
</.button_group>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -191,6 +204,10 @@ defmodule MusicLibraryWeb.MaintenanceLive.Index do
|
|||||||
:refresh_artists_wikipedia_jobs,
|
:refresh_artists_wikipedia_jobs,
|
||||||
count_jobs("MusicLibrary.Worker.ArtistRefreshWikipediaData")
|
count_jobs("MusicLibrary.Worker.ArtistRefreshWikipediaData")
|
||||||
)
|
)
|
||||||
|
|> assign(
|
||||||
|
:refresh_artists_lastfm_jobs,
|
||||||
|
count_jobs("MusicLibrary.Worker.FetchArtistLastFmData")
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp count_jobs(worker) do
|
defp count_jobs(worker) do
|
||||||
@@ -244,6 +261,14 @@ defmodule MusicLibraryWeb.MaintenanceLive.Index do
|
|||||||
|> put_toast(:info, gettext("Operation started in the background."))}
|
|> put_toast(:info, gettext("Operation started in the background."))}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def handle_event("refresh_artists_lastfm_data", _params, socket) do
|
||||||
|
Artists.Batch.refresh_lastfm_data()
|
||||||
|
|
||||||
|
{:noreply,
|
||||||
|
socket
|
||||||
|
|> put_toast(:info, gettext("Operation started in the background."))}
|
||||||
|
end
|
||||||
|
|
||||||
def handle_event("db_vacuum", _params, socket) do
|
def handle_event("db_vacuum", _params, socket) do
|
||||||
case Repo.vacuum() do
|
case Repo.vacuum() do
|
||||||
{:ok, _result} ->
|
{:ok, _result} ->
|
||||||
|
|||||||
@@ -2028,3 +2028,33 @@ msgstr ""
|
|||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "The application has been updated."
|
msgid "The application has been updated."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/music_library_web/live/maintenance_live/index.ex
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Are you sure you want to refresh Last.fm data for all artists? This operation can take a long time to complete."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/music_library_web/live/artist_live/show.ex
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Error refreshing Last.fm data"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/music_library_web/live/artist_live/show.ex
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Last.fm"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/music_library_web/live/artist_live/show.ex
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Last.fm data refreshed successfully"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/music_library_web/live/artist_live/show.ex
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Refresh Last.fm"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/music_library_web/live/maintenance_live/index.ex
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Refresh Last.fm data"
|
||||||
|
msgstr ""
|
||||||
|
|||||||
@@ -2028,3 +2028,33 @@ msgstr ""
|
|||||||
#, elixir-autogen, elixir-format, fuzzy
|
#, elixir-autogen, elixir-format, fuzzy
|
||||||
msgid "The application has been updated."
|
msgid "The application has been updated."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/music_library_web/live/maintenance_live/index.ex
|
||||||
|
#, elixir-autogen, elixir-format, fuzzy
|
||||||
|
msgid "Are you sure you want to refresh Last.fm data for all artists? This operation can take a long time to complete."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/music_library_web/live/artist_live/show.ex
|
||||||
|
#, elixir-autogen, elixir-format, fuzzy
|
||||||
|
msgid "Error refreshing Last.fm data"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/music_library_web/live/artist_live/show.ex
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Last.fm"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/music_library_web/live/artist_live/show.ex
|
||||||
|
#, elixir-autogen, elixir-format, fuzzy
|
||||||
|
msgid "Last.fm data refreshed successfully"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/music_library_web/live/artist_live/show.ex
|
||||||
|
#, elixir-autogen, elixir-format, fuzzy
|
||||||
|
msgid "Refresh Last.fm"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/music_library_web/live/maintenance_live/index.ex
|
||||||
|
#, elixir-autogen, elixir-format, fuzzy
|
||||||
|
msgid "Refresh Last.fm data"
|
||||||
|
msgstr ""
|
||||||
|
|||||||
Reference in New Issue
Block a user