From 6b7ab73f68fc069da2a97f98ddcf452ce7912373 Mon Sep 17 00:00:00 2001 From: Kieran Eglin Date: Tue, 26 Nov 2024 11:16:26 -0800 Subject: [PATCH] Added logic to ignore downloads that aren't in the right live state --- .../downloading/media_download_worker.ex | 4 ++++ lib/pinchflat/downloading/media_downloader.ex | 15 +++++++++++- lib/pinchflat/yt_dlp/media.ex | 24 +++++++++++++++++-- 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/lib/pinchflat/downloading/media_download_worker.ex b/lib/pinchflat/downloading/media_download_worker.ex index 989668e..6b9f942 100644 --- a/lib/pinchflat/downloading/media_download_worker.ex +++ b/lib/pinchflat/downloading/media_download_worker.ex @@ -94,6 +94,10 @@ defmodule Pinchflat.Downloading.MediaDownloadWorker do {:recovered, _} -> {:error, :retry} + # TODO: test + {:error, :unsuitable_for_download} -> + {:ok, :non_retry} + {:error, message} -> action_on_error(message) end diff --git a/lib/pinchflat/downloading/media_downloader.ex b/lib/pinchflat/downloading/media_downloader.ex index df5ea4f..e94665d 100644 --- a/lib/pinchflat/downloading/media_downloader.ex +++ b/lib/pinchflat/downloading/media_downloader.ex @@ -37,6 +37,14 @@ defmodule Pinchflat.Downloading.MediaDownloader do {:ok, parsed_json} -> update_media_item_from_parsed_json(media_with_preloads, parsed_json) + # TODO: test + {:error, :unsuitable_for_download} -> + Logger.warning( + "Media item ##{media_with_preloads.id} isn't suitable for download yet. May be an active or processing live stream" + ) + + {:error, :unsuitable_for_download} + {:error, message, _exit_code} -> Logger.error("yt-dlp download error for media item ##{media_with_preloads.id}: #{inspect(message)}") @@ -108,7 +116,12 @@ defmodule Pinchflat.Downloading.MediaDownloader do {:ok, options} = DownloadOptionBuilder.build(item_with_preloads, override_opts) runner_opts = [output_filepath: output_filepath, use_cookies: item_with_preloads.source.use_cookies] - YtDlpMedia.download(url, options, runner_opts) + # TODO: test + case YtDlpMedia.get_downloadable_status(url) do + {:ok, :downloadable} -> YtDlpMedia.download(url, options, runner_opts) + {:ok, :ignorable} -> {:error, :unsuitable_for_download} + err -> err + end end defp recoverable_errors do diff --git a/lib/pinchflat/yt_dlp/media.ex b/lib/pinchflat/yt_dlp/media.ex index cdd8dea..253a378 100644 --- a/lib/pinchflat/yt_dlp/media.ex +++ b/lib/pinchflat/yt_dlp/media.ex @@ -49,6 +49,19 @@ defmodule Pinchflat.YtDlp.Media do end end + # TODO: test + def get_downloadable_status(url) do + case backend_runner().run(url, [:simulate, :skip_download], "%(.{live_status})j") do + {:ok, output} -> + output + |> Phoenix.json_library().decode!() + |> parse_downloadable_status() + + err -> + err + end + end + @doc """ Downloads a thumbnail for a single piece of media. Usually used for downloading thumbnails for internal use @@ -71,11 +84,10 @@ defmodule Pinchflat.YtDlp.Media do Returns {:ok, %Media{}} | {:error, any, ...}. """ def get_media_attributes(url, command_opts \\ [], addl_opts \\ []) do - runner = Application.get_env(:pinchflat, :yt_dlp_runner) all_command_opts = [:simulate, :skip_download] ++ command_opts output_template = indexing_output_template() - case runner.run(url, all_command_opts, output_template, addl_opts) do + case backend_runner().run(url, all_command_opts, output_template, addl_opts) do {:ok, output} -> output |> Phoenix.json_library().decode!() @@ -147,6 +159,14 @@ defmodule Pinchflat.YtDlp.Media do defp parse_uploaded_at(%{"upload_date" => nil}), do: nil defp parse_uploaded_at(response), do: MetadataFileHelpers.parse_upload_date(response["upload_date"]) + defp parse_downloadable_status(response) do + case response["live_status"] do + status when status in ["is_live", "is_upcoming", "post_live"] -> {:ok, :ignorable} + status when status in ["was_live", "not_live"] -> {:ok, :downloadable} + _ -> {:error, "Unknown live status: #{response["live_status"]}"} + end + end + defp backend_runner do # This approach lets us mock the command for testing Application.get_env(:pinchflat, :yt_dlp_runner)