[Enhancement] Allow manual indexing/downloading (#162)

* Added controller actions and UI for forcing index and download actions

* Added forcing of downloads for media items
This commit is contained in:
Kieran
2024-04-03 14:21:10 -07:00
committed by GitHub
parent 9381c80aac
commit b872c5c20b
17 changed files with 327 additions and 80 deletions
@@ -34,6 +34,23 @@ defmodule Pinchflat.Downloading.MediaDownloadWorkerTest do
assert {:ok, task} = MediaDownloadWorker.kickoff_with_task(media_item)
assert task.media_item_id == media_item.id
end
test "can be called with additional job arguments", %{media_item: media_item} do
job_args = %{"force" => true}
assert {:ok, _} = MediaDownloadWorker.kickoff_with_task(media_item, job_args)
assert_enqueued(worker: MediaDownloadWorker, args: %{"id" => media_item.id, "force" => true})
end
test "can be called with additional job options", %{media_item: media_item} do
job_opts = [max_attempts: 5]
assert {:ok, _} = MediaDownloadWorker.kickoff_with_task(media_item, %{}, job_opts)
[job] = all_enqueued(worker: MediaDownloadWorker, args: %{"id" => media_item.id})
assert job.max_attempts == 5
end
end
describe "perform/1" do
@@ -88,6 +105,14 @@ defmodule Pinchflat.Downloading.MediaDownloadWorkerTest do
perform_job(MediaDownloadWorker, %{id: media_item.id})
end
test "downloads anyway if forced", %{media_item: media_item} do
expect(YtDlpRunnerMock, :run, fn _url, _opts, _ot -> :ok end)
Sources.update_source(media_item.source, %{download_media: false})
perform_job(MediaDownloadWorker, %{id: media_item.id, force: true})
end
test "it saves the file's size to the database", %{media_item: media_item} do
expect(YtDlpRunnerMock, :run, fn _url, _opts, _ot ->
metadata = render_parsed_metadata(:media_metadata)
@@ -14,6 +14,42 @@ defmodule Pinchflat.SlowIndexing.MediaCollectionIndexingWorkerTest do
setup :verify_on_exit!
describe "kickoff_with_task/3" do
setup do
source = source_fixture(index_frequency_minutes: 10)
{:ok, %{source: source}}
end
test "starts the worker", %{source: source} do
assert [] = all_enqueued(worker: MediaCollectionIndexingWorker)
assert {:ok, _} = MediaCollectionIndexingWorker.kickoff_with_task(source)
assert [_] = all_enqueued(worker: MediaCollectionIndexingWorker)
end
test "attaches a task", %{source: source} do
assert {:ok, task} = MediaCollectionIndexingWorker.kickoff_with_task(source)
assert task.source_id == source.id
end
test "can be called with additional job arguments", %{source: source} do
job_args = %{"force" => true}
assert {:ok, _} = MediaCollectionIndexingWorker.kickoff_with_task(source, job_args)
assert_enqueued(worker: MediaCollectionIndexingWorker, args: %{"id" => source.id, "force" => true})
end
test "can be called with additional job options", %{source: source} do
job_opts = [max_attempts: 5]
assert {:ok, _} = MediaCollectionIndexingWorker.kickoff_with_task(source, %{}, job_opts)
[job] = all_enqueued(worker: MediaCollectionIndexingWorker, args: %{"id" => source.id})
assert job.max_attempts == 5
end
end
describe "perform/1" do
test "it indexes the source if it should be indexed" do
expect(YtDlpRunnerMock, :run, fn _url, _opts, _ot, _addl_opts -> {:ok, ""} end)
@@ -31,6 +67,14 @@ defmodule Pinchflat.SlowIndexing.MediaCollectionIndexingWorkerTest do
perform_job(MediaCollectionIndexingWorker, %{id: source.id})
end
test "it indexes the source no matter what if the 'force' arg is passed" do
expect(YtDlpRunnerMock, :run, fn _url, _opts, _ot, _addl_opts -> {:ok, ""} end)
source = source_fixture(index_frequency_minutes: 0, last_indexed_at: DateTime.utc_now())
perform_job(MediaCollectionIndexingWorker, %{id: source.id, force: true})
end
test "it does not do any indexing if the source has been indexed and shouldn't be rescheduled" do
expect(YtDlpRunnerMock, :run, 0, fn _url, _opts, _ot, _addl_opts -> {:ok, ""} end)
@@ -18,7 +18,7 @@ defmodule Pinchflat.SlowIndexing.SlowIndexingHelpersTest do
setup :verify_on_exit!
describe "kickoff_indexing_task/1" do
describe "kickoff_indexing_task/3" do
test "it schedules a job" do
source = source_fixture(index_frequency_minutes: 1)
@@ -64,6 +64,25 @@ defmodule Pinchflat.SlowIndexing.SlowIndexingHelpersTest do
assert_raise Ecto.NoResultsError, fn -> Repo.reload!(task) end
end
test "can be called with additional job arguments" do
source = source_fixture(index_frequency_minutes: 1)
job_args = %{"force" => true}
assert {:ok, _} = SlowIndexingHelpers.kickoff_indexing_task(source, job_args)
assert_enqueued(worker: MediaCollectionIndexingWorker, args: %{"id" => source.id, "force" => true})
end
test "can be called with additional job options" do
source = source_fixture(index_frequency_minutes: 1)
job_opts = [max_attempts: 5]
assert {:ok, _} = SlowIndexingHelpers.kickoff_indexing_task(source, %{}, job_opts)
[job] = all_enqueued(worker: MediaCollectionIndexingWorker, args: %{"id" => source.id})
assert job.max_attempts == 5
end
end
describe "index_and_enqueue_download_for_media_items/1" do
@@ -4,6 +4,7 @@ defmodule PinchflatWeb.MediaItemControllerTest do
import Pinchflat.MediaFixtures
alias Pinchflat.Repo
alias Pinchflat.Downloading.MediaDownloadWorker
describe "show media" do
setup [:create_media_item]
@@ -87,6 +88,31 @@ defmodule PinchflatWeb.MediaItemControllerTest do
end
end
describe "force_download" do
test "enqueues download task", %{conn: conn} do
media_item = media_item_fixture()
assert [] = all_enqueued(worker: MediaDownloadWorker)
post(conn, ~p"/sources/#{media_item.source_id}/media/#{media_item.id}/force_download")
assert [_] = all_enqueued(worker: MediaDownloadWorker)
end
test "forces a download even if one wouldn't normally run", %{conn: conn} do
media_item = media_item_fixture(%{media_filepath: nil})
post(conn, ~p"/sources/#{media_item.source_id}/media/#{media_item.id}/force_download")
assert [_] = all_enqueued(worker: MediaDownloadWorker, args: %{"id" => media_item.id, "force" => true})
end
test "redirects to the show page", %{conn: conn} do
media_item = media_item_fixture()
conn = post(conn, ~p"/sources/#{media_item.source_id}/media/#{media_item.id}/force_download")
assert redirected_to(conn) == ~p"/sources/#{media_item.source_id}/media/#{media_item.id}"
end
end
describe "streaming media" do
test "returns 404 if the media isn't found", %{conn: conn} do
media_item = media_item_fixture()
@@ -8,6 +8,8 @@ defmodule PinchflatWeb.SourceControllerTest do
alias Pinchflat.Repo
alias Pinchflat.Settings
alias Pinchflat.Downloading.MediaDownloadWorker
alias Pinchflat.SlowIndexing.MediaCollectionIndexingWorker
setup do
media_profile = media_profile_fixture()
@@ -160,6 +162,59 @@ defmodule PinchflatWeb.SourceControllerTest do
end
end
describe "force_download" do
test "enqueues pending download tasks", %{conn: conn} do
source = source_fixture()
_media_item = media_item_fixture(%{source_id: source.id, media_filepath: nil})
assert [] = all_enqueued(worker: MediaDownloadWorker)
post(conn, ~p"/sources/#{source.id}/force_download")
assert [_] = all_enqueued(worker: MediaDownloadWorker)
end
test "redirects to the source page", %{conn: conn} do
source = source_fixture()
conn = post(conn, ~p"/sources/#{source.id}/force_download")
assert redirected_to(conn) == ~p"/sources/#{source.id}"
end
end
describe "force_index" do
test "forces an index", %{conn: conn} do
source = source_fixture()
assert [] = all_enqueued(worker: MediaCollectionIndexingWorker)
post(conn, ~p"/sources/#{source.id}/force_index")
assert [_] = all_enqueued(worker: MediaCollectionIndexingWorker)
end
test "forces an index even if one wouldn't normally run", %{conn: conn} do
source = source_fixture(index_frequency_minutes: 0, last_indexed_at: DateTime.utc_now())
post(conn, ~p"/sources/#{source.id}/force_index")
assert [job] = all_enqueued(worker: MediaCollectionIndexingWorker)
assert job.args == %{"id" => source.id, "force" => true}
end
test "deletes pending indexing tasks", %{conn: conn} do
source = source_fixture()
{:ok, task} = MediaCollectionIndexingWorker.kickoff_with_task(source)
job = Repo.preload(task, :job).job
assert job.state == "available"
post(conn, ~p"/sources/#{source.id}/force_index")
assert Repo.reload!(job).state == "cancelled"
end
test "redirects to the source page", %{conn: conn} do
source = source_fixture()
conn = post(conn, ~p"/sources/#{source.id}/force_index")
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})
+2
View File
@@ -21,8 +21,10 @@ defmodule PinchflatWeb.ConnCase do
quote do
# The default endpoint for testing
@endpoint PinchflatWeb.Endpoint
alias Pinchflat.Repo
use PinchflatWeb, :verified_routes
use Oban.Testing, repo: Repo
# Import conveniences for testing with connections
import Plug.Conn