Enable artists maintenance tasks
This commit is contained in:
+1
-1
@@ -78,7 +78,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],
|
queues: [default: 10, heavy_writes: 1, music_brainz: 1, discogs: 1],
|
||||||
repo: MusicLibrary.BackgroundRepo,
|
repo: MusicLibrary.BackgroundRepo,
|
||||||
plugins: [
|
plugins: [
|
||||||
{Oban.Plugins.Cron,
|
{Oban.Plugins.Cron,
|
||||||
|
|||||||
@@ -100,6 +100,50 @@ defmodule MusicLibrary.Artists do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def refresh_musicbrainz_data(artist_id) do
|
||||||
|
with {:ok, musicbrainz_artist} <- MusicBrainz.get_artist(artist_id) do
|
||||||
|
get_artist_info!(artist_id)
|
||||||
|
|> ArtistInfo.changeset(%{musicbrainz_data: musicbrainz_artist.musicbrainz_data})
|
||||||
|
|> Repo.update()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def refresh_musicbrainz_data_async(artist_info) do
|
||||||
|
meta = %{}
|
||||||
|
params = %{"id" => artist_info.id}
|
||||||
|
|
||||||
|
params
|
||||||
|
|> Worker.ArtistRefreshMusicBrainzData.new(meta: meta)
|
||||||
|
|> BackgroundRepo.insert()
|
||||||
|
end
|
||||||
|
|
||||||
|
def refresh_discogs_data(artist_id) do
|
||||||
|
artist_info = get_artist_info!(artist_id)
|
||||||
|
|
||||||
|
if discogs_id = ArtistInfo.discogs_id(artist_info) do
|
||||||
|
case Discogs.get_artist(discogs_id) do
|
||||||
|
{:ok, discogs_artist} ->
|
||||||
|
artist_info
|
||||||
|
|> ArtistInfo.changeset(%{discogs_data: discogs_artist})
|
||||||
|
|> Repo.update()
|
||||||
|
|
||||||
|
error ->
|
||||||
|
error
|
||||||
|
end
|
||||||
|
else
|
||||||
|
{:ok, artist_info}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def refresh_discogs_data_async(artist_info) do
|
||||||
|
meta = %{}
|
||||||
|
params = %{"id" => artist_info.id}
|
||||||
|
|
||||||
|
params
|
||||||
|
|> Worker.ArtistRefreshDiscogsData.new(meta: meta)
|
||||||
|
|> BackgroundRepo.insert()
|
||||||
|
end
|
||||||
|
|
||||||
def create_artist_info(attrs) do
|
def create_artist_info(attrs) do
|
||||||
%ArtistInfo{}
|
%ArtistInfo{}
|
||||||
|> ArtistInfo.changeset(attrs)
|
|> ArtistInfo.changeset(attrs)
|
||||||
|
|||||||
@@ -71,4 +71,11 @@ defmodule MusicLibrary.Artists.ArtistInfo do
|
|||||||
|
|
||||||
def external_links(artist_info),
|
def external_links(artist_info),
|
||||||
do: ExternalLink.external_links(artist_info.musicbrainz_data, @external_link_patterns)
|
do: ExternalLink.external_links(artist_info.musicbrainz_data, @external_link_patterns)
|
||||||
|
|
||||||
|
def discogs_id(artist_info) do
|
||||||
|
case artist_info.discogs_data do
|
||||||
|
%{"id" => discogs_id} -> discogs_id
|
||||||
|
_ -> nil
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
defmodule MusicLibrary.Artists.Batch do
|
||||||
|
import Ecto.Query
|
||||||
|
|
||||||
|
alias MusicLibrary.Artists
|
||||||
|
alias MusicLibrary.Artists.ArtistInfo
|
||||||
|
alias MusicLibrary.Repo
|
||||||
|
|
||||||
|
require Logger
|
||||||
|
|
||||||
|
def refresh_musicbrainz_data do
|
||||||
|
run_on_all_artist_infos(fn artist_info ->
|
||||||
|
Artists.refresh_musicbrainz_data_async(artist_info)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
def refresh_discogs_data do
|
||||||
|
run_on_all_artist_infos(fn artist_info ->
|
||||||
|
Artists.refresh_discogs_data_async(artist_info)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp run_on_all_artist_infos(fun) do
|
||||||
|
q = from(r in ArtistInfo)
|
||||||
|
stream = Repo.stream(q, max_rows: 50)
|
||||||
|
|
||||||
|
Repo.transaction(
|
||||||
|
fn ->
|
||||||
|
Enum.reduce(stream, [], fn artist_info, acc ->
|
||||||
|
case fun.(artist_info) do
|
||||||
|
{:error, reason} ->
|
||||||
|
Logger.error(
|
||||||
|
"Failed to run function on artist_info #{artist_info.id} with #{inspect(reason)}"
|
||||||
|
)
|
||||||
|
|
||||||
|
[artist_info.id | acc]
|
||||||
|
|
||||||
|
:ok ->
|
||||||
|
acc
|
||||||
|
|
||||||
|
{:ok, _artist_info} ->
|
||||||
|
acc
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end,
|
||||||
|
timeout: :infinity
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
defmodule MusicLibrary.Worker.ArtistRefreshDiscogsData do
|
||||||
|
use Oban.Worker, queue: :discogs, max_attempts: 3
|
||||||
|
|
||||||
|
@impl Oban.Worker
|
||||||
|
def perform(%Oban.Job{args: %{"id" => artist_info_id}}) do
|
||||||
|
MusicLibrary.Artists.refresh_discogs_data(artist_info_id)
|
||||||
|
|
||||||
|
Process.sleep(100)
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
defmodule MusicLibrary.Worker.ArtistRefreshMusicBrainzData do
|
||||||
|
use Oban.Worker, queue: :music_brainz, max_attempts: 3
|
||||||
|
|
||||||
|
@impl Oban.Worker
|
||||||
|
def perform(%Oban.Job{args: %{"id" => artist_info_id}}) do
|
||||||
|
MusicLibrary.Artists.refresh_musicbrainz_data(artist_info_id)
|
||||||
|
|
||||||
|
Process.sleep(500)
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -3,7 +3,8 @@ defmodule MusicLibraryWeb.MaintenanceLive.Index do
|
|||||||
|
|
||||||
require Logger
|
require Logger
|
||||||
|
|
||||||
alias MusicLibrary.Records.Batch
|
alias MusicLibrary.Artists
|
||||||
|
alias MusicLibrary.Records
|
||||||
alias MusicLibrary.Repo
|
alias MusicLibrary.Repo
|
||||||
|
|
||||||
def mount(_params, _session, socket) do
|
def mount(_params, _session, socket) do
|
||||||
@@ -16,7 +17,7 @@ defmodule MusicLibraryWeb.MaintenanceLive.Index do
|
|||||||
end
|
end
|
||||||
|
|
||||||
def handle_event("refresh_records_musicbrainz_data", _params, socket) do
|
def handle_event("refresh_records_musicbrainz_data", _params, socket) do
|
||||||
Batch.refresh_musicbrainz_data()
|
Records.Batch.refresh_musicbrainz_data()
|
||||||
|
|
||||||
{:noreply,
|
{:noreply,
|
||||||
socket
|
socket
|
||||||
@@ -24,7 +25,23 @@ defmodule MusicLibraryWeb.MaintenanceLive.Index do
|
|||||||
end
|
end
|
||||||
|
|
||||||
def handle_event("generate_record_embeddings", _params, socket) do
|
def handle_event("generate_record_embeddings", _params, socket) do
|
||||||
Batch.generate_embeddings()
|
Records.Batch.generate_embeddings()
|
||||||
|
|
||||||
|
{:noreply,
|
||||||
|
socket
|
||||||
|
|> put_toast(:info, gettext("Operation started in the background."))}
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_event("refresh_artists_musicbrainz_data", _params, socket) do
|
||||||
|
Artists.Batch.refresh_musicbrainz_data()
|
||||||
|
|
||||||
|
{:noreply,
|
||||||
|
socket
|
||||||
|
|> put_toast(:info, gettext("Operation started in the background."))}
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_event("refresh_artists_discogs_data", _params, socket) do
|
||||||
|
Artists.Batch.refresh_discogs_data()
|
||||||
|
|
||||||
{:noreply,
|
{:noreply,
|
||||||
socket
|
socket
|
||||||
|
|||||||
@@ -48,7 +48,6 @@
|
|||||||
<ul class="mt-4">
|
<ul class="mt-4">
|
||||||
<li class="space-y-4">
|
<li class="space-y-4">
|
||||||
<.button
|
<.button
|
||||||
disabled
|
|
||||||
type="button"
|
type="button"
|
||||||
phx-click="refresh_artists_musicbrainz_data"
|
phx-click="refresh_artists_musicbrainz_data"
|
||||||
data-confirm={
|
data-confirm={
|
||||||
@@ -60,7 +59,6 @@
|
|||||||
{gettext("Refresh MusicBrainz data")}
|
{gettext("Refresh MusicBrainz data")}
|
||||||
</.button>
|
</.button>
|
||||||
<.button
|
<.button
|
||||||
disabled
|
|
||||||
type="button"
|
type="button"
|
||||||
phx-click="refresh_artists_discogs_data"
|
phx-click="refresh_artists_discogs_data"
|
||||||
data-confirm={
|
data-confirm={
|
||||||
|
|||||||
Reference in New Issue
Block a user