diff --git a/lib/pinchflat/metadata/source_metadata_storage_worker.ex b/lib/pinchflat/metadata/source_metadata_storage_worker.ex index eda6297..b922f62 100644 --- a/lib/pinchflat/metadata/source_metadata_storage_worker.ex +++ b/lib/pinchflat/metadata/source_metadata_storage_worker.ex @@ -38,9 +38,9 @@ defmodule Pinchflat.Metadata.SourceMetadataStorageWorker do - The NFO file for the source (if specified) - Downloads and stores source images (if specified) - The worker is kicked off after a source is inserted/updated - this can - take an unknown amount of time so don't rely on this data being here - before, say, the first indexing or downloading task is complete. + The worker is kicked off after a source is inserted or it's original_url + is updated - this can take an unknown amount of time so don't rely on this + data being here before, say, the first indexing or downloading task is complete. Returns :ok """ diff --git a/lib/pinchflat/sources/sources.ex b/lib/pinchflat/sources/sources.ex index f9a3658..ab6fc2e 100644 --- a/lib/pinchflat/sources/sources.ex +++ b/lib/pinchflat/sources/sources.ex @@ -237,7 +237,7 @@ defmodule Pinchflat.Sources do if run_post_commit_tasks do maybe_handle_media_tasks(changeset, source) maybe_run_indexing_task(changeset, source) - run_metadata_storage_task(source) + maybe_run_metadata_storage_task(changeset, source) end {:ok, source} @@ -276,9 +276,20 @@ defmodule Pinchflat.Sources do end end - # This runs every time to pick up any changes to the metadata - defp run_metadata_storage_task(source) do - SourceMetadataStorageWorker.kickoff_with_task(source) + defp maybe_run_metadata_storage_task(changeset, source) do + case {changeset.data, changeset.changes} do + # If the changeset is new (not persisted), fetch metadata no matter what + {%{__meta__: %{state: :built}}, _} -> + SourceMetadataStorageWorker.kickoff_with_task(source) + + # If the record has been persisted, only fetch metadata if the + # original_url has changed + {_, %{original_url: _}} -> + SourceMetadataStorageWorker.kickoff_with_task(source) + + _ -> + :ok + end end defp maybe_update_slow_indexing_task(changeset, source) do diff --git a/lib/pinchflat_web/controllers/sources/source_controller.ex b/lib/pinchflat_web/controllers/sources/source_controller.ex index 6e4b215..8de11f2 100644 --- a/lib/pinchflat_web/controllers/sources/source_controller.ex +++ b/lib/pinchflat_web/controllers/sources/source_controller.ex @@ -10,6 +10,7 @@ defmodule PinchflatWeb.Sources.SourceController do alias Pinchflat.Profiles.MediaProfile alias Pinchflat.Downloading.DownloadingHelpers alias Pinchflat.SlowIndexing.SlowIndexingHelpers + alias Pinchflat.Metadata.SourceMetadataStorageWorker def index(conn, _params) do sources = @@ -104,20 +105,38 @@ defmodule PinchflatWeb.Sources.SourceController do end def force_download(conn, %{"source_id" => id}) do - source = Sources.get_source!(id) - DownloadingHelpers.enqueue_pending_download_tasks(source) - - conn - |> put_flash(:info, "Forced download of pending media items.") - |> redirect(to: ~p"/sources/#{source}") + wrap_forced_action( + conn, + id, + "Forcing download of pending media items.", + &DownloadingHelpers.enqueue_pending_download_tasks/1 + ) end def force_index(conn, %{"source_id" => id}) do - source = Sources.get_source!(id) - SlowIndexingHelpers.kickoff_indexing_task(source, %{force: true}) + wrap_forced_action( + conn, + id, + "Index enqueued.", + &SlowIndexingHelpers.kickoff_indexing_task(&1, %{force: true}) + ) + end + + def force_metadata_refresh(conn, %{"source_id" => id}) do + wrap_forced_action( + conn, + id, + "Metadata refresh enqueued.", + &SourceMetadataStorageWorker.kickoff_with_task/1 + ) + end + + defp wrap_forced_action(conn, source_id, message, fun) do + source = Sources.get_source!(source_id) + fun.(source) conn - |> put_flash(:info, "Index enqueued.") + |> put_flash(:info, message) |> redirect(to: ~p"/sources/#{source}") end diff --git a/lib/pinchflat_web/controllers/sources/source_html.ex b/lib/pinchflat_web/controllers/sources/source_html.ex index a5a7545..ab1ef07 100644 --- a/lib/pinchflat_web/controllers/sources/source_html.ex +++ b/lib/pinchflat_web/controllers/sources/source_html.ex @@ -36,6 +36,15 @@ defmodule PinchflatWeb.Sources.SourceHTML do |> Phoenix.json_library().encode!() end + def title_filter_regex_help do + url = "https://github.com/nalgeon/sqlean/blob/main/docs/regexp.md#supported-syntax" + classes = "underline decoration-bodydark decoration-1 hover:decoration-white" + + """ + A PCRE-compatible regex. Only media with titles that match this regex will be downloaded. See here for syntax + """ + end + def output_path_template_override_help do help_button_classes = "underline decoration-bodydark decoration-1 hover:decoration-white cursor-pointer" help_button = ~s{Click here} diff --git a/lib/pinchflat_web/controllers/sources/source_html/actions_dropdown.html.heex b/lib/pinchflat_web/controllers/sources/source_html/actions_dropdown.html.heex index 16a0829..964395c 100644 --- a/lib/pinchflat_web/controllers/sources/source_html/actions_dropdown.html.heex +++ b/lib/pinchflat_web/controllers/sources/source_html/actions_dropdown.html.heex @@ -30,6 +30,15 @@ Force Index + <:option> + <.link + href={~p"/sources/#{@source}/force_metadata_refresh"} + method="post" + data-confirm="Are you sure you want to refresh this source's metadata?" + > + Refresh Metadata + + <:option>
diff --git a/lib/pinchflat_web/controllers/sources/source_html/source_form.html.heex b/lib/pinchflat_web/controllers/sources/source_html/source_form.html.heex index 33ea259..6a53a3a 100644 --- a/lib/pinchflat_web/controllers/sources/source_html/source_form.html.heex +++ b/lib/pinchflat_web/controllers/sources/source_html/source_form.html.heex @@ -23,7 +23,7 @@ field={f[:custom_name]} type="text" label="Custom Name" - help="Something descriptive. Does not impact indexing or downloading" + help="Does not impact indexing or downloading. Will be inferred from the source if left blank" /> <.input field={f[:original_url]} type="text" label="Source URL" help="URL of a channel or playlist (required)" /> @@ -111,7 +111,8 @@ type="text" label="Title Filter Regex" placeholder="(?i)^How to Bike$" - help="A PCRE-compatible regex. Only media with titles that match this regex will be downloaded. Look up 'SQLean Regex docs' for more" + help={title_filter_regex_help()} + html_help={true} />
source.id}) end + + test "updating will not kickoff a metadata storage worker other attrs change" do + source = source_fixture() + update_attrs = %{name: "some new name"} + + assert {:ok, %Source{}} = Sources.update_source(source, update_attrs) + + refute_enqueued(worker: SourceMetadataStorageWorker) + end end describe "update_source/3 when testing options" do diff --git a/test/pinchflat_web/controllers/source_controller_test.exs b/test/pinchflat_web/controllers/source_controller_test.exs index c0ecc5f..8599688 100644 --- a/test/pinchflat_web/controllers/source_controller_test.exs +++ b/test/pinchflat_web/controllers/source_controller_test.exs @@ -9,6 +9,7 @@ defmodule PinchflatWeb.SourceControllerTest do alias Pinchflat.Repo alias Pinchflat.Settings alias Pinchflat.Downloading.MediaDownloadWorker + alias Pinchflat.Metadata.SourceMetadataStorageWorker alias Pinchflat.SlowIndexing.MediaCollectionIndexingWorker setup do @@ -215,6 +216,23 @@ defmodule PinchflatWeb.SourceControllerTest do end end + describe "force_metadata_refresh" do + test "forces a metadata refresh", %{conn: conn} do + source = source_fixture() + + assert [] = all_enqueued(worker: SourceMetadataStorageWorker) + post(conn, ~p"/sources/#{source.id}/force_metadata_refresh") + assert [_] = all_enqueued(worker: SourceMetadataStorageWorker) + end + + test "redirects to the source page", %{conn: conn} do + source = source_fixture() + + conn = post(conn, ~p"/sources/#{source.id}/force_metadata_refresh") + assert redirected_to(conn) == ~p"/sources/#{source.id}" + end + end + defp create_source(_) do source = source_fixture() media_item = media_item_with_attachments(%{source_id: source.id})