pinchflat/lib/pinchflat_web/controllers/sources/source_controller.ex
Kieran Eglin ebf5d6afb5
[WIP]
2024-04-22 09:08:51 -07:00

181 lines
4.6 KiB
Elixir

defmodule PinchflatWeb.Sources.SourceController do
use PinchflatWeb, :controller
import Ecto.Query, warn: false
alias Pinchflat.Repo
alias Pinchflat.Tasks
alias Pinchflat.Sources
alias Pinchflat.Sources.Source
alias Pinchflat.Profiles.MediaProfile
alias Pinchflat.Downloading.DownloadingHelpers
alias Pinchflat.SlowIndexing.SlowIndexingHelpers
alias Pinchflat.Metadata.SourceMetadataStorageWorker
def index(conn, _params) do
sources =
Source
|> order_by(asc: :custom_name)
|> Repo.all()
|> Repo.preload(:media_profile)
render(conn, :index, sources: sources)
end
def new(conn, _params) do
changeset = Sources.change_source(%Source{})
render(conn, :new,
changeset: changeset,
media_profiles: media_profiles(),
layout: get_onboarding_layout()
)
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
# TODO: test
# TODO: also do for media items
# TODO: check to see if I've lost the plot here
def show_image(conn, %{"source_id" => id, "image_type" => image_type}) do
source = Sources.get_source!(id)
filepath =
case image_type do
"poster" -> source.poster_filepath
"fanart" -> source.fanart_filepath
"banner" -> source.banner_filepath
_ -> nil
end
if filepath && File.exists?(filepath) do
conn
|> put_resp_content_type(MIME.from_path(filepath))
|> send_file(200, filepath)
else
conn
|> put_status(404)
|> text("Image not found")
end
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
delete_files = Map.get(params, "delete_files", false)
source = Sources.get_source!(id)
{:ok, _source} = Sources.delete_source(source, delete_files: delete_files)
flash_message =
if delete_files do
"Source and files deleted successfully."
else
"Source deleted successfully. Files were not deleted."
end
conn
|> put_flash(:info, flash_message)
|> redirect(to: ~p"/sources")
end
def force_download(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_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
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