Skip to content

Commit

Permalink
[Enhancement] Allow forcing a refresh of source metadata (#194)
Browse files Browse the repository at this point in the history
* Stopped sources from fetching metadata on every update

* Added action button to force a metadata refresh
  • Loading branch information
kieraneglin authored Apr 18, 2024
1 parent 526bc0c commit 98c2812
Show file tree
Hide file tree
Showing 9 changed files with 98 additions and 20 deletions.
6 changes: 3 additions & 3 deletions lib/pinchflat/metadata/source_metadata_storage_worker.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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
"""
Expand Down
19 changes: 15 additions & 4 deletions lib/pinchflat/sources/sources.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down Expand Up @@ -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
Expand Down
37 changes: 28 additions & 9 deletions lib/pinchflat_web/controllers/sources/source_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand Down Expand Up @@ -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

Expand Down
9 changes: 9 additions & 0 deletions lib/pinchflat_web/controllers/sources/source_html.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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. <a href="#{url}" class="#{classes}" target="_blank">See here</a> 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{<span class="#{help_button_classes}" x-on:click="$dispatch('load-template')">Click here</span>}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,15 @@
Force Index
</.link>
</:option>
<: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
</.link>
</:option>
<:option>
<div class="h-px w-full bg-bodydark2"></div>
</:option>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)" />
Expand Down Expand Up @@ -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}
/>

<section
Expand Down
1 change: 1 addition & 0 deletions lib/pinchflat_web/router.ex
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ defmodule PinchflatWeb.Router do
resources "/sources", Sources.SourceController do
post "/force_download", Sources.SourceController, :force_download
post "/force_index", Sources.SourceController, :force_index
post "/force_metadata_refresh", Sources.SourceController, :force_metadata_refresh

resources "/media", MediaItems.MediaItemController, only: [:show, :edit, :update, :delete] do
post "/force_download", MediaItems.MediaItemController, :force_download
Expand Down
14 changes: 12 additions & 2 deletions test/pinchflat/sources_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -514,14 +514,24 @@ defmodule Pinchflat.SourcesTest do
assert source.index_frequency_minutes == 0
end

test "updating will kickoff a metadata storage worker" do
test "updating will kickoff a metadata storage worker if the original_url changes" do
expect(YtDlpRunnerMock, :run, &playlist_mock/3)
source = source_fixture()
update_attrs = %{name: "some updated name"}
update_attrs = %{original_url: "https://www.youtube.com/channel/cba321"}

assert {:ok, %Source{} = source} = Sources.update_source(source, update_attrs)

assert_enqueued(worker: SourceMetadataStorageWorker, args: %{"id" => 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
Expand Down
18 changes: 18 additions & 0 deletions test/pinchflat_web/controllers/source_controller_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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})
Expand Down

0 comments on commit 98c2812

Please sign in to comment.