Ensured metadata is deleted when other files are deleted
This commit is contained in:
parent
dc264897d6
commit
3ae4ddf822
4 changed files with 78 additions and 6 deletions
|
|
@ -9,6 +9,7 @@ defmodule Pinchflat.Media do
|
||||||
alias Pinchflat.Tasks
|
alias Pinchflat.Tasks
|
||||||
alias Pinchflat.Media.MediaItem
|
alias Pinchflat.Media.MediaItem
|
||||||
alias Pinchflat.Sources.Source
|
alias Pinchflat.Sources.Source
|
||||||
|
alias Pinchflat.Media.MediaMetadata
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Returns the list of media_items. Returns [%MediaItem{}, ...].
|
Returns the list of media_items. Returns [%MediaItem{}, ...].
|
||||||
|
|
@ -103,6 +104,21 @@ defmodule Pinchflat.Media do
|
||||||
|> Enum.filter(&is_binary/1)
|
|> Enum.filter(&is_binary/1)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Produces a flat list of the filesystem paths for a media_item's metadata files.
|
||||||
|
Returns an empty list if the media_item has no metadata.
|
||||||
|
|
||||||
|
Returns [binary()] | []
|
||||||
|
"""
|
||||||
|
def metadata_filepaths(media_item) do
|
||||||
|
metadata = Repo.preload(media_item, :metadata).metadata || %MediaMetadata{}
|
||||||
|
mapped_struct = Map.from_struct(metadata)
|
||||||
|
|
||||||
|
MediaMetadata.filepath_attributes()
|
||||||
|
|> Enum.map(fn field -> mapped_struct[field] end)
|
||||||
|
|> Enum.filter(&is_binary/1)
|
||||||
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Creates a media_item. Returns {:ok, %MediaItem{}} | {:error, %Ecto.Changeset{}}.
|
Creates a media_item. Returns {:ok, %MediaItem{}} | {:error, %Ecto.Changeset{}}.
|
||||||
"""
|
"""
|
||||||
|
|
@ -137,15 +153,23 @@ defmodule Pinchflat.Media do
|
||||||
Returns {:ok, %MediaItem{}}
|
Returns {:ok, %MediaItem{}}
|
||||||
"""
|
"""
|
||||||
def delete_attachments(media_item) do
|
def delete_attachments(media_item) do
|
||||||
|
media_item = Repo.preload(media_item, :metadata)
|
||||||
|
|
||||||
media_item
|
media_item
|
||||||
|> media_filepaths()
|
|> media_filepaths()
|
||||||
|
|> Enum.concat(metadata_filepaths(media_item))
|
||||||
|> Enum.each(&File.rm/1)
|
|> Enum.each(&File.rm/1)
|
||||||
|
|
||||||
# Fails if the directory is not empty
|
# rmdir will attempt to delete the directory, but only if it is empty
|
||||||
case File.rmdir(Path.dirname(media_item.media_filepath)) do
|
if media_item.media_filepath do
|
||||||
:ok -> {:ok, media_item}
|
File.rmdir(Path.dirname(media_item.media_filepath))
|
||||||
{:error, :eexist} -> {:ok, media_item}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if media_item.metadata && media_item.metadata.metadata_filepath do
|
||||||
|
File.rmdir(Path.dirname(media_item.metadata.metadata_filepath))
|
||||||
|
end
|
||||||
|
|
||||||
|
{:ok, media_item}
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
|
|
|
||||||
|
|
@ -29,4 +29,9 @@ defmodule Pinchflat.Media.MediaMetadata do
|
||||||
|> validate_required(@required_fields)
|
|> validate_required(@required_fields)
|
||||||
|> unique_constraint([:media_item_id])
|
|> unique_constraint([:media_item_id])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc false
|
||||||
|
def filepath_attributes do
|
||||||
|
~w(metadata_filepath thumbnail_filepath)a
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,6 @@ defmodule Pinchflat.MediaClient.Backends.YtDlp.MetadataFileHelpers do
|
||||||
needed
|
needed
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# TODO: ensure media metadata is deleted when the media item is deleted
|
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Compresses and stores metadata for a media item, returning the filepath.
|
Compresses and stores metadata for a media item, returning the filepath.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
defmodule Pinchflat.MediaTest do
|
defmodule Pinchflat.MediaTest do
|
||||||
use Pinchflat.DataCase
|
use Pinchflat.DataCase
|
||||||
|
|
||||||
|
import Mox
|
||||||
import Pinchflat.TasksFixtures
|
import Pinchflat.TasksFixtures
|
||||||
import Pinchflat.MediaFixtures
|
import Pinchflat.MediaFixtures
|
||||||
import Pinchflat.ProfilesFixtures
|
import Pinchflat.ProfilesFixtures
|
||||||
|
|
@ -8,6 +9,9 @@ defmodule Pinchflat.MediaTest do
|
||||||
|
|
||||||
alias Pinchflat.Media
|
alias Pinchflat.Media
|
||||||
alias Pinchflat.Media.MediaItem
|
alias Pinchflat.Media.MediaItem
|
||||||
|
alias Pinchflat.MediaClient.Backends.YtDlp.MetadataFileHelpers
|
||||||
|
|
||||||
|
setup :verify_on_exit!
|
||||||
|
|
||||||
@invalid_attrs %{title: nil, media_id: nil, media_filepath: nil}
|
@invalid_attrs %{title: nil, media_id: nil, media_filepath: nil}
|
||||||
|
|
||||||
|
|
@ -261,6 +265,27 @@ defmodule Pinchflat.MediaTest do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "metadata_filepaths" do
|
||||||
|
test "returns filepaths in a flat list" do
|
||||||
|
filepaths = %{
|
||||||
|
metadata_filepath: "/metadata.json.gz",
|
||||||
|
thumbnail_filepath: "/thumbnail.jpg"
|
||||||
|
}
|
||||||
|
|
||||||
|
media_item = media_item_fixture(%{metadata: filepaths})
|
||||||
|
|
||||||
|
assert Media.metadata_filepaths(media_item) == [
|
||||||
|
"/metadata.json.gz",
|
||||||
|
"/thumbnail.jpg"
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
test "returns an empty list when there is no metadata" do
|
||||||
|
media_item = media_item_fixture()
|
||||||
|
assert Media.metadata_filepaths(media_item) == []
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "create_media_item/1" do
|
describe "create_media_item/1" do
|
||||||
test "creating with valid data creates a media_item" do
|
test "creating with valid data creates a media_item" do
|
||||||
valid_attrs = %{
|
valid_attrs = %{
|
||||||
|
|
@ -330,6 +355,26 @@ defmodule Pinchflat.MediaTest do
|
||||||
refute File.exists?(media_item.media_filepath)
|
refute File.exists?(media_item.media_filepath)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "deletes the media item's metadata files" do
|
||||||
|
stub(HTTPClientMock, :get, fn _url, _headers, _opts -> {:ok, ""} end)
|
||||||
|
media_item = Repo.preload(media_item_with_attachments(), :metadata)
|
||||||
|
|
||||||
|
update_attrs = %{
|
||||||
|
metadata: %{
|
||||||
|
metadata_filepath: MetadataFileHelpers.compress_and_store_metadata_for(media_item, %{}),
|
||||||
|
thumbnail_filepath:
|
||||||
|
MetadataFileHelpers.download_and_store_thumbnail_for(media_item, %{
|
||||||
|
"thumbnail" => "https://example.com/thumbnail.jpg"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{:ok, updated_media_item} = Media.update_media_item(media_item, update_attrs)
|
||||||
|
|
||||||
|
assert {:ok, _} = Media.delete_attachments(updated_media_item)
|
||||||
|
refute File.exists?(updated_media_item.metadata.metadata_filepath)
|
||||||
|
end
|
||||||
|
|
||||||
test "does not delete the media item" do
|
test "does not delete the media item" do
|
||||||
media_item = media_item_with_attachments()
|
media_item = media_item_with_attachments()
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue