When importing a record, stream all its releases
This commit is contained in:
@@ -1,10 +1,11 @@
|
|||||||
defmodule MusicBrainz.APIBehaviour do
|
defmodule MusicBrainz.APIBehaviour do
|
||||||
@type musicbrainz_id :: String.t()
|
@type musicbrainz_id :: String.t()
|
||||||
@type config :: MusicBrainz.Config.t()
|
@type config :: MusicBrainz.Config.t()
|
||||||
|
@type limit :: pos_integer()
|
||||||
|
|
||||||
@callback get_release_group(musicbrainz_id, config) :: {:ok, map()} | {:error, String.t()}
|
@callback get_release_group(musicbrainz_id, config) :: {:ok, map()} | {:error, String.t()}
|
||||||
|
|
||||||
@callback get_releases(musicbrainz_id, config) :: {:ok, map()} | {:error, String.t()}
|
@callback get_releases(musicbrainz_id, limit, config) :: {:ok, map()} | {:error, String.t()}
|
||||||
|
|
||||||
@callback get_release(musicbrainz_id, config) :: {:ok, map()} | {:error, String.t()}
|
@callback get_release(musicbrainz_id, config) :: {:ok, map()} | {:error, String.t()}
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ defmodule MusicBrainz.APIImpl do
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
@behaviour MusicBrainz.APIBehaviour
|
@behaviour MusicBrainz.APIBehaviour
|
||||||
|
@base_url "https://musicbrainz.org/ws/2"
|
||||||
|
|
||||||
require Logger
|
require Logger
|
||||||
|
|
||||||
@@ -288,9 +289,17 @@ defmodule MusicBrainz.APIImpl do
|
|||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def get_releases(release_group_id, config) do
|
def get_releases(release_group_id, opts, config) do
|
||||||
|
Keyword.validate!(opts, [:limit, :offset])
|
||||||
|
|
||||||
|
opts =
|
||||||
|
Keyword.merge(opts,
|
||||||
|
fmt: "json",
|
||||||
|
"release-group": release_group_id
|
||||||
|
)
|
||||||
|
|
||||||
url =
|
url =
|
||||||
"https://musicbrainz.org/ws/2/release?fmt=json&limit=100&release-group=#{release_group_id}"
|
@base_url <> "/release?" <> URI.encode_query(opts)
|
||||||
|
|
||||||
json_get(url, config)
|
json_get(url, config)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -226,14 +226,29 @@ defmodule MusicLibrary.Records do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# TODO: paginate and merge as needed
|
|
||||||
defp merge_releases(musicbrainz_id, musicbrainz_data) do
|
defp merge_releases(musicbrainz_id, musicbrainz_data) do
|
||||||
with {:ok, data} <-
|
with {:ok, releases} <- stream_releases(musicbrainz_id) do
|
||||||
music_brainz_config().api.get_releases(
|
{:ok, Map.put(musicbrainz_data, "releases", releases)}
|
||||||
musicbrainz_id,
|
end
|
||||||
music_brainz_config()
|
end
|
||||||
) do
|
|
||||||
{:ok, Map.put(musicbrainz_data, "releases", data["releases"])}
|
defp stream_releases(musicbrainz_id) do
|
||||||
|
do_stream_releases(musicbrainz_id, [], 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp do_stream_releases(musicbrainz_id, releases, offset) do
|
||||||
|
limit = 100
|
||||||
|
opts = [limit: limit, offset: offset]
|
||||||
|
|
||||||
|
case music_brainz_config().api.get_releases(musicbrainz_id, opts, music_brainz_config()) do
|
||||||
|
{:ok, data} ->
|
||||||
|
%{"releases" => new_releases} = data
|
||||||
|
|
||||||
|
if Enum.count(new_releases) < limit do
|
||||||
|
{:ok, releases ++ new_releases}
|
||||||
|
else
|
||||||
|
do_stream_releases(musicbrainz_id, releases ++ new_releases, offset + 100)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ defmodule MusicLibrary.RecordsTest do
|
|||||||
{:ok, release_group(:lockdown_trilogy)}
|
{:ok, release_group(:lockdown_trilogy)}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
expect(APIBehaviourMock, :get_releases, fn ^release_group_id, _config ->
|
expect(APIBehaviourMock, :get_releases, fn ^release_group_id, _opts, _config ->
|
||||||
{:ok, %{"releases" => release_group(:lockdown_trilogy)["releases"]}}
|
{:ok, %{"releases" => release_group(:lockdown_trilogy)["releases"]}}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
@@ -207,7 +207,7 @@ defmodule MusicLibrary.RecordsTest do
|
|||||||
{:ok, release_group}
|
{:ok, release_group}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
expect(APIBehaviourMock, :get_releases, fn ^release_group_id, _config ->
|
expect(APIBehaviourMock, :get_releases, fn ^release_group_id, _opts, _config ->
|
||||||
{:ok, %{"releases" => release_group["releases"]}}
|
{:ok, %{"releases" => release_group["releases"]}}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
@@ -264,7 +264,7 @@ defmodule MusicLibrary.RecordsTest do
|
|||||||
{:ok, release_group}
|
{:ok, release_group}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
expect(APIBehaviourMock, :get_releases, fn ^release_group_id, _config ->
|
expect(APIBehaviourMock, :get_releases, fn ^release_group_id, _opts, _config ->
|
||||||
{:ok, %{"releases" => release_group["releases"]}}
|
{:ok, %{"releases" => release_group["releases"]}}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|||||||
@@ -271,7 +271,7 @@ defmodule MusicLibraryWeb.CollectionLive.IndexTest do
|
|||||||
{:ok, release_group}
|
{:ok, release_group}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
expect(APIBehaviourMock, :get_releases, fn ^first_result_id, _config ->
|
expect(APIBehaviourMock, :get_releases, fn ^first_result_id, _opts, _config ->
|
||||||
{:ok, %{"releases" => release_group["releases"]}}
|
{:ok, %{"releases" => release_group["releases"]}}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|||||||
@@ -193,7 +193,7 @@ defmodule MusicLibraryWeb.StatsLive.IndexTest do
|
|||||||
{:ok, release_group}
|
{:ok, release_group}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
expect(APIBehaviourMock, :get_releases, fn ^release_group_id, _config ->
|
expect(APIBehaviourMock, :get_releases, fn ^release_group_id, _opts, _config ->
|
||||||
{:ok, %{"releases" => release_group["releases"]}}
|
{:ok, %{"releases" => release_group["releases"]}}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user