Updates media item creation to update on conflict
This commit is contained in:
parent
c9f3f585c0
commit
404d6feb99
5 changed files with 50 additions and 12 deletions
|
|
@ -184,14 +184,25 @@ defmodule Pinchflat.Media do
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Creates a media item from the attributes returned by the video backend
|
Creates a media item from the attributes returned by the video backend
|
||||||
(read: yt-dlp)
|
(read: yt-dlp).
|
||||||
|
|
||||||
|
Unlike `create_media_item`, this will attempt an update if the media_item
|
||||||
|
already exists. This is so that future indexing can pick up attributes that
|
||||||
|
we may not have asked for in the past (eg: upload_date)
|
||||||
|
|
||||||
Returns {:ok, %MediaItem{}} | {:error, %Ecto.Changeset{}}
|
Returns {:ok, %MediaItem{}} | {:error, %Ecto.Changeset{}}
|
||||||
"""
|
"""
|
||||||
def create_media_item_from_backend_attrs(source, media_attrs_struct) do
|
def create_media_item_from_backend_attrs(source, media_attrs_struct) do
|
||||||
%{source_id: source.id}
|
attrs = Map.merge(%{source_id: source.id}, Map.from_struct(media_attrs_struct))
|
||||||
|> Map.merge(Map.from_struct(media_attrs_struct))
|
|
||||||
|> create_media_item()
|
%MediaItem{}
|
||||||
|
|> MediaItem.changeset(attrs)
|
||||||
|
|> Repo.insert(
|
||||||
|
on_conflict: [
|
||||||
|
set: Map.to_list(attrs)
|
||||||
|
],
|
||||||
|
conflict_target: [:source_id, :media_id]
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
|
|
|
||||||
|
|
@ -598,9 +598,14 @@ defmodule PinchflatWeb.CoreComponents do
|
||||||
def list_items_from_map(assigns) do
|
def list_items_from_map(assigns) do
|
||||||
attrs =
|
attrs =
|
||||||
Enum.filter(assigns.map, fn
|
Enum.filter(assigns.map, fn
|
||||||
{_, %{__struct__: _}} -> false
|
{_, %{__struct__: s}} when s not in [Date, DateTime] ->
|
||||||
{_, [%{__meta__: _} | _]} -> false
|
false
|
||||||
_ -> true
|
|
||||||
|
{_, [%{__meta__: _} | _]} ->
|
||||||
|
false
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
true
|
||||||
end)
|
end)
|
||||||
|
|
||||||
assigns = assign(assigns, iterable_attributes: attrs)
|
assigns = assign(assigns, iterable_attributes: attrs)
|
||||||
|
|
|
||||||
|
|
@ -378,6 +378,7 @@ defmodule Pinchflat.MediaTest do
|
||||||
}
|
}
|
||||||
|
|
||||||
assert {:ok, %MediaItem{} = media_item} = Media.create_media_item(valid_attrs)
|
assert {:ok, %MediaItem{} = media_item} = Media.create_media_item(valid_attrs)
|
||||||
|
|
||||||
assert media_item.title == valid_attrs.title
|
assert media_item.title == valid_attrs.title
|
||||||
assert media_item.media_id == valid_attrs.media_id
|
assert media_item.media_id == valid_attrs.media_id
|
||||||
assert media_item.media_filepath == valid_attrs.media_filepath
|
assert media_item.media_filepath == valid_attrs.media_filepath
|
||||||
|
|
@ -398,12 +399,30 @@ defmodule Pinchflat.MediaTest do
|
||||||
|> YtDlpMedia.response_to_struct()
|
|> YtDlpMedia.response_to_struct()
|
||||||
|
|
||||||
assert {:ok, %MediaItem{} = media_item} = Media.create_media_item_from_backend_attrs(source, media_attrs)
|
assert {:ok, %MediaItem{} = media_item} = Media.create_media_item_from_backend_attrs(source, media_attrs)
|
||||||
|
|
||||||
assert media_item.source_id == source.id
|
assert media_item.source_id == source.id
|
||||||
assert media_item.title == media_attrs.title
|
assert media_item.title == media_attrs.title
|
||||||
assert media_item.media_id == media_attrs.media_id
|
assert media_item.media_id == media_attrs.media_id
|
||||||
assert media_item.original_url == media_attrs.original_url
|
assert media_item.original_url == media_attrs.original_url
|
||||||
assert media_item.description == media_attrs.description
|
assert media_item.description == media_attrs.description
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "updates the media item if it already exists" do
|
||||||
|
source = source_fixture()
|
||||||
|
|
||||||
|
media_attrs =
|
||||||
|
media_attributes_return_fixture()
|
||||||
|
|> Phoenix.json_library().decode!()
|
||||||
|
|> YtDlpMedia.response_to_struct()
|
||||||
|
|
||||||
|
different_attrs = %YtDlpMedia{media_attrs | title: "Different title"}
|
||||||
|
|
||||||
|
assert {:ok, %MediaItem{} = media_item_1} = Media.create_media_item_from_backend_attrs(source, media_attrs)
|
||||||
|
assert {:ok, %MediaItem{} = media_item_2} = Media.create_media_item_from_backend_attrs(source, different_attrs)
|
||||||
|
|
||||||
|
assert media_item_1.id == media_item_2.id
|
||||||
|
assert media_item_2.title == different_attrs.title
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "update_media_item/2" do
|
describe "update_media_item/2" do
|
||||||
|
|
|
||||||
|
|
@ -49,10 +49,11 @@ defmodule Pinchflat.Tasks.MediaItemTasksTest do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "won't duplicate media_items based on media_id and source", %{source: source} do
|
test "won't duplicate media_items based on media_id and source", %{source: source} do
|
||||||
assert {:ok, _} = MediaItemTasks.index_and_enqueue_download_for_media_item(source, @media_url)
|
assert {:ok, mi_1} = MediaItemTasks.index_and_enqueue_download_for_media_item(source, @media_url)
|
||||||
assert {:error, _} = MediaItemTasks.index_and_enqueue_download_for_media_item(source, @media_url)
|
assert {:ok, mi_2} = MediaItemTasks.index_and_enqueue_download_for_media_item(source, @media_url)
|
||||||
|
|
||||||
assert Repo.aggregate(MediaItem, :count) == 1
|
assert Repo.aggregate(MediaItem, :count) == 1
|
||||||
|
assert mi_1.id == mi_2.id
|
||||||
end
|
end
|
||||||
|
|
||||||
test "enqueues a download job", %{source: source} do
|
test "enqueues a download job", %{source: source} do
|
||||||
|
|
|
||||||
|
|
@ -168,12 +168,14 @@ defmodule Pinchflat.Tasks.SourceTasksTest do
|
||||||
Enum.map(media_items_other_source, & &1.media_id)
|
Enum.map(media_items_other_source, & &1.media_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "it returns a list of media_items or changesets", %{source: source} do
|
test "it returns a list of media_items", %{source: source} do
|
||||||
first_run = SourceTasks.index_and_enqueue_download_for_media_items(source)
|
first_run = SourceTasks.index_and_enqueue_download_for_media_items(source)
|
||||||
duplicate_run = SourceTasks.index_and_enqueue_download_for_media_items(source)
|
duplicate_run = SourceTasks.index_and_enqueue_download_for_media_items(source)
|
||||||
|
|
||||||
assert Enum.all?(first_run, fn %MediaItem{} -> true end)
|
first_ids = Enum.map(first_run, & &1.id)
|
||||||
assert Enum.all?(duplicate_run, fn %Ecto.Changeset{} -> true end)
|
duplicate_ids = Enum.map(duplicate_run, & &1.id)
|
||||||
|
|
||||||
|
assert first_ids == duplicate_ids
|
||||||
end
|
end
|
||||||
|
|
||||||
test "it updates the source's last_indexed_at field", %{source: source} do
|
test "it updates the source's last_indexed_at field", %{source: source} do
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue