Misc refactors 2024-03-14 (#89)

* Adds method to improve cleanup of empty directories

* resolved bug where source metadata worker could call itself in an infinite loop

* Refactored file deletion for media items

* Removed useless filesystem data worker

* Updated task listing fns to take a record directly

* Refactored the way I call workers

* Improved some tests
This commit is contained in:
Kieran
2024-03-15 10:44:58 -07:00
committed by GitHub
parent 0f3329e97d
commit fbe21cb304
37 changed files with 447 additions and 416 deletions
+27 -57
View File
@@ -7,9 +7,10 @@ defmodule Pinchflat.Media do
alias Pinchflat.Repo
alias Pinchflat.Tasks
alias Pinchflat.Media.MediaItem
alias Pinchflat.Sources.Source
alias Pinchflat.Media.MediaItem
alias Pinchflat.Metadata.MediaMetadata
alias Pinchflat.Filesystem.FilesystemHelpers
@doc """
Returns the list of media_items.
@@ -141,42 +142,6 @@ 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
NOTE: this can almost certainly be made private
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()
|> Enum.filter(&is_binary/1)
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.
NOTE: this can almost certainly be made private
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 """
Creates a media_item.
@@ -223,19 +188,20 @@ defmodule Pinchflat.Media do
end
@doc """
Deletes a media_item and its associated tasks.
Can optionally delete the media_item's files.
Deletes a media_item, its associated tasks, and our internal metadata files.
Can optionally delete the media_item's media files (media, thumbnail, subtitles, etc).
Returns {:ok, %MediaItem{}} | {:error, %Ecto.Changeset{}}
"""
def delete_media_item(%MediaItem{} = media_item, opts \\ []) do
delete_files = Keyword.get(opts, :delete_files, false)
# NOTE: this should delete metadata no matter what
if delete_files do
{:ok, _} = delete_all_attachments(media_item)
{:ok, _} = delete_media_files(media_item)
end
# Should delete these no matter what
delete_internal_metadata_files(media_item)
Tasks.delete_tasks_for(media_item)
Repo.delete(media_item)
end
@@ -247,27 +213,31 @@ defmodule Pinchflat.Media do
MediaItem.changeset(media_item, attrs)
end
# NOTE: refactor this
defp delete_all_attachments(media_item) do
media_item = Repo.preload(media_item, :metadata)
defp delete_media_files(media_item) do
mapped_struct = Map.from_struct(media_item)
media_item
|> media_filepaths()
|> Enum.concat(metadata_filepaths(media_item))
|> Enum.each(&File.rm/1)
# rmdir will attempt to delete the directory, but only if it is empty
if media_item.media_filepath do
File.rmdir(Path.dirname(media_item.media_filepath))
end
if media_item.metadata && media_item.metadata.metadata_filepath do
File.rmdir(Path.dirname(media_item.metadata.metadata_filepath))
end
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()
|> Enum.filter(&is_binary/1)
|> Enum.each(&FilesystemHelpers.delete_file_and_remove_empty_directories/1)
{:ok, media_item}
end
defp delete_internal_metadata_files(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)
|> Enum.each(&FilesystemHelpers.delete_file_and_remove_empty_directories/1)
end
defp maybe_apply_cutoff_date(source) do
if source.download_cutoff_date do
dynamic([mi], mi.upload_date >= ^source.download_cutoff_date)