From 1931fc0bda244e47fabcf38972f893f08552b6c1 Mon Sep 17 00:00:00 2001 From: Kieran Eglin Date: Wed, 3 Apr 2024 10:15:16 -0700 Subject: [PATCH] Added column and UI to prevent automatic deletion --- lib/pinchflat/media/media.ex | 2 +- lib/pinchflat/media/media_item.ex | 2 ++ lib/pinchflat/media/media_query.ex | 4 ++++ .../media_item_html/media_item_form.html.heex | 7 +++++++ ...403164943_add_culled_at_to_media_items.exs | 1 + .../media_retention_worker_test.exs | 12 +++++++++++ test/pinchflat/media_test.exs | 21 +++++++++++++++++++ 7 files changed, 48 insertions(+), 1 deletion(-) diff --git a/lib/pinchflat/media/media.ex b/lib/pinchflat/media/media.ex index eb0f9c1..d58f657 100644 --- a/lib/pinchflat/media/media.ex +++ b/lib/pinchflat/media/media.ex @@ -22,7 +22,6 @@ defmodule Pinchflat.Media do Repo.all(MediaItem) end - # TODO: add attr for excluding media items from this list (ie: keep forever) @doc """ Returns a list of media_items that are cullable based on the retention period of the source they belong to. @@ -34,6 +33,7 @@ defmodule Pinchflat.Media do |> MediaQuery.join_sources() |> MediaQuery.with_media_filepath() |> MediaQuery.with_passed_retention_period() + |> MediaQuery.with_no_culling_prevention() |> Repo.all() end diff --git a/lib/pinchflat/media/media_item.ex b/lib/pinchflat/media/media_item.ex index 595d893..52633b2 100644 --- a/lib/pinchflat/media/media_item.ex +++ b/lib/pinchflat/media/media_item.ex @@ -33,6 +33,7 @@ defmodule Pinchflat.Media.MediaItem do :nfo_filepath, # These are user or system controlled fields :prevent_download, + :prevent_culling, :culled_at ] # Pretty much all the fields captured at index are required. @@ -74,6 +75,7 @@ defmodule Pinchflat.Media.MediaItem do field :subtitle_filepaths, {:array, {:array, :string}}, default: [] field :prevent_download, :boolean, default: false + field :prevent_culling, :boolean, default: false field :culled_at, :utc_datetime field :matching_search_term, :string, virtual: true diff --git a/lib/pinchflat/media/media_query.ex b/lib/pinchflat/media/media_query.ex index da30300..7b7a3c7 100644 --- a/lib/pinchflat/media/media_query.ex +++ b/lib/pinchflat/media/media_query.ex @@ -49,6 +49,10 @@ defmodule Pinchflat.Media.MediaQuery do ) end + def with_no_culling_prevention(query) do + where(query, [mi], mi.prevent_culling == false) + end + def with_id(query, id) do where(query, [mi], mi.id == ^id) end diff --git a/lib/pinchflat_web/controllers/media_items/media_item_html/media_item_form.html.heex b/lib/pinchflat_web/controllers/media_items/media_item_html/media_item_form.html.heex index acfa301..1311346 100644 --- a/lib/pinchflat_web/controllers/media_items/media_item_html/media_item_form.html.heex +++ b/lib/pinchflat_web/controllers/media_items/media_item_html/media_item_form.html.heex @@ -20,5 +20,12 @@ help="Checking excludes this media item from being downloaded" /> + <.input + field={f[:prevent_culling]} + type="toggle" + label="Prevent Automatic Deletion" + help="Checking excludes media from being automatically deleted based on media retention rules" + /> + <.button class="my-10 sm:mb-7.5 w-full sm:w-auto" rounding="rounded-lg">Save Media Item diff --git a/priv/repo/migrations/20240403164943_add_culled_at_to_media_items.exs b/priv/repo/migrations/20240403164943_add_culled_at_to_media_items.exs index 8ac2d6f..284dc40 100644 --- a/priv/repo/migrations/20240403164943_add_culled_at_to_media_items.exs +++ b/priv/repo/migrations/20240403164943_add_culled_at_to_media_items.exs @@ -4,6 +4,7 @@ defmodule Pinchflat.Repo.Migrations.AddCulledAtToMediaItems do def change do alter table(:media_items) do add :culled_at, :utc_datetime + add :prevent_culling, :boolean, default: false end end end diff --git a/test/pinchflat/downloading/media_retention_worker_test.exs b/test/pinchflat/downloading/media_retention_worker_test.exs index e0aa5c2..a77fd76 100644 --- a/test/pinchflat/downloading/media_retention_worker_test.exs +++ b/test/pinchflat/downloading/media_retention_worker_test.exs @@ -4,6 +4,7 @@ defmodule Pinchflat.Downloading.MediaRetentionWorkerTest do import Pinchflat.MediaFixtures import Pinchflat.SourcesFixtures + alias Pinchflat.Media alias Pinchflat.Downloading.MediaRetentionWorker describe "perform/1" do @@ -36,6 +37,17 @@ defmodule Pinchflat.Downloading.MediaRetentionWorkerTest do assert Repo.reload!(old_media_item).culled_at assert DateTime.diff(now(), Repo.reload!(old_media_item).culled_at) < 1 end + + test "doesn't cull media items that have prevent_culling set" do + {_source, old_media_item, _new_media_item} = prepare_records() + + Media.update_media_item(old_media_item, %{prevent_culling: true}) + + perform_job(MediaRetentionWorker, %{}) + + assert File.exists?(old_media_item.media_filepath) + assert Repo.reload!(old_media_item).media_filepath + end end defp prepare_records do diff --git a/test/pinchflat/media_test.exs b/test/pinchflat/media_test.exs index 35bd3dd..3d46571 100644 --- a/test/pinchflat/media_test.exs +++ b/test/pinchflat/media_test.exs @@ -107,6 +107,27 @@ defmodule Pinchflat.MediaTest do assert Media.list_cullable_media_items() == [expected_media_item] end + + test "doesn't return items that are set to prevent culling" do + source = source_fixture(%{retention_period_days: 2}) + + _media_item = + media_item_fixture(%{ + source_id: source.id, + media_filepath: "/video/#{Faker.File.file_name(:video)}", + media_downloaded_at: now_minus(3, :days), + prevent_culling: true + }) + + expected_media_item = + media_item_fixture(%{ + source_id: source.id, + media_filepath: "/video/#{Faker.File.file_name(:video)}", + media_downloaded_at: now_minus(3, :days) + }) + + assert Media.list_cullable_media_items() == [expected_media_item] + end end describe "list_pending_media_items_for/1" do