mirror of
https://github.com/kieraneglin/pinchflat.git
synced 2026-01-23 18:35:23 +00:00
* [Unrelated] updated module name for existing liveview module * Updated toggle component and moved MP index table to a liveview * [WIP] reverted MP index table; added source count to MP index * Moved new live table to sources index * Added 'enabled' boolean to sources * Got 'enabled' logic working re: downloading pending media * Updated sources context to do the right thing when a source is updated * Docs and tests * Updated slow indexing to maintain its old schedule if re-enabled * Hooked up the enabled toggle to the sources page * [Unrelated] added direct links to various tabs on the sources table * More tests * Removed unneeded guard in * Removed outdated comment
184 lines
5 KiB
Elixir
184 lines
5 KiB
Elixir
defmodule PinchflatWeb.Sources.SourceController do
|
|
use PinchflatWeb, :controller
|
|
use Pinchflat.Sources.SourcesQuery
|
|
|
|
alias Pinchflat.Repo
|
|
alias Pinchflat.Tasks
|
|
alias Pinchflat.Sources
|
|
alias Pinchflat.Sources.Source
|
|
alias Pinchflat.Profiles.MediaProfile
|
|
alias Pinchflat.Media.FileSyncingWorker
|
|
alias Pinchflat.Sources.SourceDeletionWorker
|
|
alias Pinchflat.Downloading.DownloadingHelpers
|
|
alias Pinchflat.SlowIndexing.SlowIndexingHelpers
|
|
alias Pinchflat.Metadata.SourceMetadataStorageWorker
|
|
|
|
def index(conn, _params) do
|
|
render(conn, :index)
|
|
end
|
|
|
|
def new(conn, params) do
|
|
# This lets me preload the settings from another source for more efficient creation
|
|
cs_struct =
|
|
case to_string(params["template_id"]) do
|
|
"" -> %Source{}
|
|
template_id -> Repo.get(Source, template_id) || %Source{}
|
|
end
|
|
|
|
render(conn, :new,
|
|
media_profiles: media_profiles(),
|
|
layout: get_onboarding_layout(),
|
|
# Most of these don't actually _need_ to be nullified at this point,
|
|
# but if I don't do it now I know it'll bite me
|
|
changeset:
|
|
Sources.change_source(%Source{
|
|
cs_struct
|
|
| id: nil,
|
|
uuid: nil,
|
|
custom_name: nil,
|
|
description: nil,
|
|
collection_name: nil,
|
|
collection_id: nil,
|
|
collection_type: nil,
|
|
original_url: nil,
|
|
marked_for_deletion_at: nil
|
|
})
|
|
)
|
|
end
|
|
|
|
def create(conn, %{"source" => source_params}) do
|
|
case Sources.create_source(source_params) do
|
|
{:ok, source} ->
|
|
redirect_location =
|
|
if Settings.get!(:onboarding), do: ~p"/?onboarding=1", else: ~p"/sources/#{source}"
|
|
|
|
conn
|
|
|> put_flash(:info, "Source created successfully.")
|
|
|> redirect(to: redirect_location)
|
|
|
|
{:error, %Ecto.Changeset{} = changeset} ->
|
|
render(conn, :new,
|
|
changeset: changeset,
|
|
media_profiles: media_profiles(),
|
|
layout: get_onboarding_layout()
|
|
)
|
|
end
|
|
end
|
|
|
|
def show(conn, %{"id" => id}) do
|
|
source = Repo.preload(Sources.get_source!(id), :media_profile)
|
|
|
|
pending_tasks =
|
|
source
|
|
|> Tasks.list_tasks_for(nil, [:executing, :available, :scheduled, :retryable])
|
|
|> Repo.preload(:job)
|
|
|
|
render(conn, :show, source: source, pending_tasks: pending_tasks)
|
|
end
|
|
|
|
def edit(conn, %{"id" => id}) do
|
|
source = Sources.get_source!(id)
|
|
changeset = Sources.change_source(source)
|
|
|
|
render(conn, :edit, source: source, changeset: changeset, media_profiles: media_profiles())
|
|
end
|
|
|
|
def update(conn, %{"id" => id, "source" => source_params}) do
|
|
source = Sources.get_source!(id)
|
|
|
|
case Sources.update_source(source, source_params) do
|
|
{:ok, source} ->
|
|
conn
|
|
|> put_flash(:info, "Source updated successfully.")
|
|
|> redirect(to: ~p"/sources/#{source}")
|
|
|
|
{:error, %Ecto.Changeset{} = changeset} ->
|
|
render(conn, :edit,
|
|
source: source,
|
|
changeset: changeset,
|
|
media_profiles: media_profiles()
|
|
)
|
|
end
|
|
end
|
|
|
|
def delete(conn, %{"id" => id} = params) do
|
|
# This awkward comparison converts the string to a boolean
|
|
delete_files = Map.get(params, "delete_files", "") == "true"
|
|
source = Sources.get_source!(id)
|
|
|
|
{:ok, _} = Sources.update_source(source, %{marked_for_deletion_at: DateTime.utc_now()})
|
|
SourceDeletionWorker.kickoff(source, %{delete_files: delete_files})
|
|
|
|
conn
|
|
|> put_flash(:info, "Source deletion started. This may take a while to complete.")
|
|
|> redirect(to: ~p"/sources")
|
|
end
|
|
|
|
def force_download_pending(conn, %{"source_id" => id}) do
|
|
wrap_forced_action(
|
|
conn,
|
|
id,
|
|
"Forcing download of pending media items.",
|
|
&DownloadingHelpers.enqueue_pending_download_tasks/1
|
|
)
|
|
end
|
|
|
|
def force_redownload(conn, %{"source_id" => id}) do
|
|
wrap_forced_action(
|
|
conn,
|
|
id,
|
|
"Forcing re-download of downloaded media items.",
|
|
&DownloadingHelpers.kickoff_redownload_for_existing_media/1
|
|
)
|
|
end
|
|
|
|
def force_index(conn, %{"source_id" => id}) do
|
|
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
|
|
|
|
def sync_files_on_disk(conn, %{"source_id" => id}) do
|
|
wrap_forced_action(
|
|
conn,
|
|
id,
|
|
"File sync enqueued.",
|
|
&FileSyncingWorker.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, message)
|
|
|> redirect(to: ~p"/sources/#{source}")
|
|
end
|
|
|
|
defp media_profiles do
|
|
MediaProfile
|
|
|> order_by(asc: :name)
|
|
|> Repo.all()
|
|
end
|
|
|
|
defp get_onboarding_layout do
|
|
if Settings.get!(:onboarding) do
|
|
{Layouts, :onboarding}
|
|
else
|
|
{Layouts, :app}
|
|
end
|
|
end
|
|
end
|