Delete media items (#20)

* Added method for deleting media files and their content

* Adds controllers and methods for deleting media and files

* Improved tmpfile setup and teardown for tests

* Actually got tmpfile cleanup running once per suite run

* Finally fixed flash messages
This commit is contained in:
Kieran
2024-02-15 13:51:19 -08:00
committed by GitHub
parent 060e340558
commit 9d3b9cc063
17 changed files with 305 additions and 33 deletions
+46 -1
View File
@@ -88,6 +88,22 @@ defmodule Pinchflat.Media do
"""
def get_media_item!(id), do: Repo.get!(MediaItem, id)
@doc """
Produces a flat list of the filesystem paths for a media_item's downloaded files
Returns [binary()]
"""
def media_filepaths(media_item) do
mapped_struct = Map.from_struct(media_item)
MediaItem.filepath_attributes()
|> Enum.map(fn
:subtitle_filepaths = field -> Enum.map(mapped_struct[field], fn [_, filepath] -> filepath end)
field -> List.wrap(mapped_struct[field])
end)
|> List.flatten()
end
@doc """
Creates a media_item. Returns {:ok, %MediaItem{}} | {:error, %Ecto.Changeset{}}.
"""
@@ -107,7 +123,7 @@ defmodule Pinchflat.Media do
end
@doc """
Deletes a media_item and its associated tasks.
Deletes a media_item and its associated tasks. Will leave files on disk.
Returns {:ok, %MediaItem{}} | {:error, %Ecto.Changeset{}}.
"""
@@ -116,6 +132,35 @@ defmodule Pinchflat.Media do
Repo.delete(media_item)
end
@doc """
Deletes the media_item's associated files. Will leave the media_item in the database.
Returns {:ok, %MediaItem{}}
"""
def delete_attachments(media_item) do
media_item
|> media_filepaths()
|> Enum.each(&File.rm/1)
# Fails if the directory is not empty
case File.rmdir(Path.dirname(media_item.media_filepath)) do
:ok -> {:ok, media_item}
{:error, :eexist} -> {:ok, media_item}
end
end
@doc """
Deletes the media_item and all associated files. Attempts to delete the root directory
but only if it is empty.
Returns {:ok, %MediaItem{}}
"""
def delete_media_item_and_attachments(media_item) do
{:ok, _} = delete_attachments(media_item)
delete_media_item(media_item)
end
@doc """
Returns an `%Ecto.Changeset{}` for tracking media_item changes.
"""
+5
View File
@@ -60,4 +60,9 @@ defmodule Pinchflat.Media.MediaItem do
|> validate_required(@required_fields)
|> unique_constraint([:media_id, :source_id])
end
@doc false
def filepath_attributes do
~w(media_filepath thumbnail_filepath metadata_filepath subtitle_filepaths)a
end
end
+2
View File
@@ -56,6 +56,8 @@ defmodule Pinchflat.MediaSource do
@doc """
Deletes a source and it's associated tasks (of any state).
NOTE: will fail if the source has associated media items. Intended
for now, will almost certainly change in the future.
Returns {:ok, %Source{}} | {:error, %Ecto.Changeset{}}
"""