Import artists on top of existing records
This commit is contained in:
@@ -1,7 +1,10 @@
|
|||||||
defmodule MusicLibrary.Records.Importer do
|
defmodule MusicLibrary.Records.Importer do
|
||||||
alias Ecto.Multi
|
require Logger
|
||||||
|
import Ecto.Query, warn: false
|
||||||
|
|
||||||
@doc """
|
alias MusicLibrary.Records.Record, as: Rec
|
||||||
|
|
||||||
|
@moduledoc """
|
||||||
The original data from Obsidian maps records to release groups, so to find artists for a record we can
|
The original data from Obsidian maps records to release groups, so to find artists for a record we can
|
||||||
use the [lookup](https://musicbrainz.org/doc/MusicBrainz_API#Lookups) endpoint with the release group id and include the
|
use the [lookup](https://musicbrainz.org/doc/MusicBrainz_API#Lookups) endpoint with the release group id and include the
|
||||||
artist credits.
|
artist credits.
|
||||||
@@ -40,52 +43,58 @@ defmodule MusicLibrary.Records.Importer do
|
|||||||
"https://musicbrainz.org/ws/2/release-group/#{record.musicbrainz_id}?fmt=json&inc=artist-credits"
|
"https://musicbrainz.org/ws/2/release-group/#{record.musicbrainz_id}?fmt=json&inc=artist-credits"
|
||||||
|
|
||||||
with {:ok, data} <- json_get(url) do
|
with {:ok, data} <- json_get(url) do
|
||||||
current_time =
|
artists_attrs =
|
||||||
DateTime.utc_now()
|
|
||||||
|> DateTime.truncate(:second)
|
|
||||||
|
|
||||||
artist_entries =
|
|
||||||
data
|
data
|
||||||
|> get_in(["artist-credit", Access.all(), "artist"])
|
|> get_in(["artist-credit", Access.all(), "artist"])
|
||||||
|> Enum.map(fn artist ->
|
|> Enum.map(fn artist ->
|
||||||
%{
|
%{
|
||||||
name: artist["name"],
|
name: artist["name"],
|
||||||
musicbrainz_id: artist["id"],
|
musicbrainz_id: artist["id"],
|
||||||
inserted_at: current_time,
|
sort_name: artist["sort-name"],
|
||||||
updated_at: current_time
|
disambiguation: artist["disambiguation"]
|
||||||
}
|
}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
Multi.new()
|
record
|
||||||
|> Multi.insert_all(:artists, MusicLibrary.Records.Artist, artist_entries,
|
|> Rec.add_artists(artists_attrs)
|
||||||
on_conflict: :nothing,
|
|> MusicLibrary.Repo.update!()
|
||||||
returning: true
|
|
||||||
)
|
|
||||||
|> Multi.insert_all(:artists_records, MusicLibrary.Records.ArtistRecord, fn %{
|
|
||||||
artists:
|
|
||||||
{_inserted_count,
|
|
||||||
artists}
|
|
||||||
} ->
|
|
||||||
Enum.map(artists, fn a ->
|
|
||||||
%{
|
|
||||||
artist_id: a.id,
|
|
||||||
record_id: record.id,
|
|
||||||
inserted_at: current_time,
|
|
||||||
updated_at: current_time
|
|
||||||
}
|
|
||||||
end)
|
|
||||||
end)
|
|
||||||
|> MusicLibrary.Repo.transaction()
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def import_all do
|
||||||
|
Rec
|
||||||
|
|> MusicLibrary.Repo.all()
|
||||||
|
|> Enum.each(fn r ->
|
||||||
|
import_artists(r)
|
||||||
|
Process.sleep(1000)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
def import_missing do
|
||||||
|
q = from(r in Rec, where: is_nil(r.artists))
|
||||||
|
|
||||||
|
q
|
||||||
|
|> MusicLibrary.Repo.all()
|
||||||
|
|> Enum.each(fn r ->
|
||||||
|
import_artists(r)
|
||||||
|
Process.sleep(1000)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
defp json_get(url) do
|
defp json_get(url) do
|
||||||
case Finch.build(:get, url) |> Finch.request(MusicLibrary.Finch) 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} when response.status == 200 ->
|
||||||
{:ok, Jason.decode!(response.body)}
|
{:ok, Jason.decode!(response.body)}
|
||||||
|
|
||||||
other ->
|
other ->
|
||||||
{:error, "Failed to fetch data from #{url}, reason: #{inspect(other)}"}
|
msg = "Failed to fetch data from #{url}, reason: #{inspect(other)}"
|
||||||
|
Logger.error(msg)
|
||||||
|
{:error, msg}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ defmodule MusicLibrary.Records.Record do
|
|||||||
|
|
||||||
embeds_many :artists, Artist do
|
embeds_many :artists, Artist do
|
||||||
field :name, :string
|
field :name, :string
|
||||||
|
field :sort_name, :string
|
||||||
|
field :disambiguation, :string
|
||||||
field :musicbrainz_id, Ecto.UUID
|
field :musicbrainz_id, Ecto.UUID
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -23,8 +25,8 @@ defmodule MusicLibrary.Records.Record do
|
|||||||
@doc false
|
@doc false
|
||||||
def changeset(record, attrs) do
|
def changeset(record, attrs) do
|
||||||
record
|
record
|
||||||
|> cast(attrs, [:type, :title, :musicbrainz_id, :year, :genres, :image])
|
|> cast(attrs, [:type, :title, :musicbrainz_id, :year, :genres, :image, :artists])
|
||||||
|> validate_required([:type, :title, :musicbrainz_id, :year, :genres, :image])
|
|> validate_required([:type, :title, :musicbrainz_id, :year, :genres, :image, :artists])
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_artists(record, artists_attrs) do
|
def add_artists(record, artists_attrs) do
|
||||||
|
|||||||
Reference in New Issue
Block a user