diff --git a/lib/pinchflat/fast_indexing/fast_indexing_helpers.ex b/lib/pinchflat/fast_indexing/fast_indexing_helpers.ex index 67540e6..292cfdb 100644 --- a/lib/pinchflat/fast_indexing/fast_indexing_helpers.ex +++ b/lib/pinchflat/fast_indexing/fast_indexing_helpers.ex @@ -68,7 +68,7 @@ defmodule Pinchflat.FastIndexing.FastIndexingHelpers do defp create_media_item_from_media_id(source, media_id) do url = "https://www.youtube.com/watch?v=#{media_id}" - case YtDlpMedia.get_media_attributes(url, use_cookies: source.use_cookies) do + case YtDlpMedia.get_media_attributes(url, [], use_cookies: source.use_cookies) do {:ok, media_attrs} -> Media.create_media_item_from_backend_attrs(source, media_attrs) diff --git a/lib/pinchflat/slow_indexing/slow_indexing_helpers.ex b/lib/pinchflat/slow_indexing/slow_indexing_helpers.ex index 7b82a1f..b2b4432 100644 --- a/lib/pinchflat/slow_indexing/slow_indexing_helpers.ex +++ b/lib/pinchflat/slow_indexing/slow_indexing_helpers.ex @@ -95,7 +95,7 @@ defmodule Pinchflat.SlowIndexing.SlowIndexingHelpers do handler = fn filepath -> setup_file_follower_watcher(pid, filepath, source) end runner_opts = [file_listener_handler: handler, use_cookies: source.use_cookies] - result = MediaCollection.get_media_attributes_for_collection(source.original_url, runner_opts) + result = MediaCollection.get_media_attributes_for_collection(source.original_url, [], runner_opts) FileFollowerServer.stop(pid) diff --git a/lib/pinchflat/yt_dlp/media.ex b/lib/pinchflat/yt_dlp/media.ex index fda7984..816e423 100644 --- a/lib/pinchflat/yt_dlp/media.ex +++ b/lib/pinchflat/yt_dlp/media.ex @@ -63,15 +63,17 @@ defmodule Pinchflat.YtDlp.Media do @doc """ Returns a map representing the media at the given URL. + Optionally takes a list of additional command options to pass to yt-dlp + or configuration-related options to pass to the runner. Returns {:ok, %Media{}} | {:error, any, ...}. """ - def get_media_attributes(url, addl_opts \\ []) do + def get_media_attributes(url, command_opts \\ [], addl_opts \\ []) do runner = Application.get_env(:pinchflat, :yt_dlp_runner) - command_opts = [:simulate, :skip_download] + all_command_opts = [:simulate, :skip_download] ++ command_opts output_template = indexing_output_template() - case runner.run(url, command_opts, output_template, addl_opts) do + case runner.run(url, all_command_opts, output_template, addl_opts) do {:ok, output} -> output |> Phoenix.json_library().decode!() diff --git a/lib/pinchflat/yt_dlp/media_collection.ex b/lib/pinchflat/yt_dlp/media_collection.ex index 1b0035a..fe92072 100644 --- a/lib/pinchflat/yt_dlp/media_collection.ex +++ b/lib/pinchflat/yt_dlp/media_collection.ex @@ -11,20 +11,23 @@ defmodule Pinchflat.YtDlp.MediaCollection do @doc """ Returns a list of maps representing the media in the collection. + Optionally takes a list of additional command options to pass to yt-dlp + or configuration-related options to pass to the runner. - Options: + Runner Options: - :file_listener_handler - a function that will be called with the path to the file that will be written to when yt-dlp is done. This is useful for setting up a file watcher to know when the file is ready to be read. + - :use_cookies - whether or not to use user-provided cookies when fetching the media details Returns {:ok, [map()]} | {:error, any, ...}. """ - def get_media_attributes_for_collection(url, addl_opts \\ []) do + def get_media_attributes_for_collection(url, command_opts \\ [], addl_opts \\ []) do runner = Application.get_env(:pinchflat, :yt_dlp_runner) # `ignore_no_formats_error` is necessary because yt-dlp will error out if # the first video has not released yet (ie: is a premier). We don't care about # available formats since we're just getting the media details - command_opts = [:simulate, :skip_download, :ignore_no_formats_error, :no_warnings] + all_command_opts = [:simulate, :skip_download, :ignore_no_formats_error, :no_warnings] ++ command_opts use_cookies = Keyword.get(addl_opts, :use_cookies, false) output_template = YtDlpMedia.indexing_output_template() output_filepath = FilesystemUtils.generate_metadata_tmpfile(:json) @@ -35,7 +38,7 @@ defmodule Pinchflat.YtDlp.MediaCollection do file_listener_handler.(output_filepath) end - case runner.run(url, command_opts, output_template, runner_opts) do + case runner.run(url, all_command_opts, output_template, runner_opts) do {:ok, output} -> parsed_lines = output diff --git a/test/pinchflat/yt_dlp/media_collection_test.exs b/test/pinchflat/yt_dlp/media_collection_test.exs index 5d14b7c..6f112b3 100644 --- a/test/pinchflat/yt_dlp/media_collection_test.exs +++ b/test/pinchflat/yt_dlp/media_collection_test.exs @@ -35,6 +35,16 @@ defmodule Pinchflat.YtDlp.MediaCollectionTest do assert {:error, "Big issue", 1} = MediaCollection.get_media_attributes_for_collection(@channel_url) end + test "passes long additional command options" do + expect(YtDlpRunnerMock, :run, fn _url, opts, _ot, _addl_opts -> + assert :foo in opts + + {:ok, ""} + end) + + assert {:ok, _} = MediaCollection.get_media_attributes_for_collection(@channel_url, [:foo]) + end + test "passes additional args to runner" do expect(YtDlpRunnerMock, :run, fn _url, _opts, _ot, addl_opts -> assert [{:output_filepath, filepath} | _] = addl_opts @@ -56,7 +66,7 @@ defmodule Pinchflat.YtDlp.MediaCollectionTest do end assert {:ok, _} = - MediaCollection.get_media_attributes_for_collection(@channel_url, file_listener_handler: handler) + MediaCollection.get_media_attributes_for_collection(@channel_url, [], file_listener_handler: handler) assert_receive {:handler, filename} assert String.ends_with?(filename, ".json") diff --git a/test/pinchflat/yt_dlp/media_test.exs b/test/pinchflat/yt_dlp/media_test.exs index 0366827..9963b1e 100644 --- a/test/pinchflat/yt_dlp/media_test.exs +++ b/test/pinchflat/yt_dlp/media_test.exs @@ -120,13 +120,22 @@ defmodule Pinchflat.YtDlp.MediaTest do assert {:ok, _} = Media.get_media_attributes(@media_url) end + test "passes along additional command options" do + expect(YtDlpRunnerMock, :run, fn _url, opts, _ot, _addl -> + assert [:simulate, :skip_download, :custom_arg] = opts + {:ok, media_attributes_return_fixture()} + end) + + assert {:ok, _} = Media.get_media_attributes(@media_url, [:custom_arg]) + end + test "passes along additional options" do expect(YtDlpRunnerMock, :run, fn _url, _opts, _ot, addl -> assert [addl_arg: true] = addl {:ok, media_attributes_return_fixture()} end) - assert {:ok, _} = Media.get_media_attributes(@media_url, addl_arg: true) + assert {:ok, _} = Media.get_media_attributes(@media_url, [], addl_arg: true) end test "returns the error straight through when the command fails" do