diff --git a/.iex.exs b/.iex.exs new file mode 100644 index 0000000..bc26864 --- /dev/null +++ b/.iex.exs @@ -0,0 +1,14 @@ +alias Pinchflat.Repo + +alias Pinchflat.Tasks.Task +alias Pinchflat.Media.MediaItem +alias Pinchflat.Media.MediaMetadata +alias Pinchflat.MediaSource.Channel +alias Pinchflat.Profiles.MediaProfile + +alias Pinchflat.Tasks +alias Pinchflat.Media +alias Pinchflat.Profiles +alias Pinchflat.MediaSource + +alias Pinchflat.MediaClient.{ChannelDetails, VideoDownloader} diff --git a/lib/pinchflat/profiles/options/yt_dlp/option_builder.ex b/lib/pinchflat/profiles/options/yt_dlp/option_builder.ex index ce99e1f..ffbf3ca 100644 --- a/lib/pinchflat/profiles/options/yt_dlp/option_builder.ex +++ b/lib/pinchflat/profiles/options/yt_dlp/option_builder.ex @@ -15,22 +15,62 @@ defmodule Pinchflat.Profiles.Options.YtDlp.OptionBuilder do these options """ def build(%MediaProfile{} = media_profile) do - {:ok, output_path} = OutputPathBuilder.build(media_profile.output_path_template) - # NOTE: I'll be hardcoding most things for now (esp. options to help me test) - # add more configuration later as I build out the models. Walk before you can run! # NOTE: Looks like you can put different media types in different directories. # see: https://github.com/yt-dlp/yt-dlp#output-template - {:ok, - [ - :embed_metadata, - :embed_thumbnail, - :embed_subs, - :no_progress, - sub_langs: "en.*", - output: Path.join(base_directory(), output_path) - ]} + + built_options = + default_options() ++ + subtitle_options(media_profile) ++ + output_options(media_profile) + + {:ok, built_options} + end + + # This will be updated a lot as I add new options to profiles + defp default_options do + [ + :embed_metadata, + :embed_thumbnail, + :no_progress + ] + end + + defp subtitle_options(media_profile) do + mapped_struct = Map.from_struct(media_profile) + + Enum.reduce(mapped_struct, [], fn attr, acc -> + case {attr, media_profile} do + {{:download_subs, true}, _} -> + # Force SRT for now - MAY provide as an option in the future + acc ++ [:write_subs, convert_subs: "srt"] + + {{:download_auto_subs, true}, %{download_subs: true}} -> + acc ++ [:write_auto_subs] + + {{:embed_subs, true}, _} -> + acc ++ [:embed_subs] + + {{:sub_langs, sub_langs}, %{download_subs: true}} -> + acc ++ [sub_langs: sub_langs] + + {{:sub_langs, sub_langs}, %{embed_subs: true}} -> + acc ++ [sub_langs: sub_langs] + + _ -> + acc + end + end) + end + + defp output_options(media_profile) do + {:ok, output_path} = OutputPathBuilder.build(media_profile.output_path_template) + + [ + output: Path.join(base_directory(), output_path) + ] end defp base_directory do diff --git a/test/pinchflat/profiles/options/yt_dlp/option_builder_test.exs b/test/pinchflat/profiles/options/yt_dlp/option_builder_test.exs index b274731..0753d2d 100644 --- a/test/pinchflat/profiles/options/yt_dlp/option_builder_test.exs +++ b/test/pinchflat/profiles/options/yt_dlp/option_builder_test.exs @@ -15,4 +15,83 @@ defmodule Pinchflat.Profiles.Options.YtDlp.OptionBuilderTest do assert {:output, "/tmp/videos/%(title)S.%(ext)s"} in res end end + + describe "build/1 when testing subtitle options" do + test "includes :write_subs option when specified" do + media_profile = %MediaProfile{@media_profile | download_subs: true} + + assert {:ok, res} = OptionBuilder.build(media_profile) + + assert :write_subs in res + end + + test "forces SRT format when download_subs is true" do + media_profile = %MediaProfile{@media_profile | download_subs: true} + + assert {:ok, res} = OptionBuilder.build(media_profile) + + assert {:convert_subs, "srt"} in res + end + + test "includes :write_auto_subs option when specified" do + media_profile = %MediaProfile{@media_profile | download_subs: true, download_auto_subs: true} + + assert {:ok, res} = OptionBuilder.build(media_profile) + + assert :write_auto_subs in res + end + + test "doesn't include :write_auto_subs option when download_subs is false" do + media_profile = %MediaProfile{@media_profile | download_subs: false, download_auto_subs: true} + + assert {:ok, res} = OptionBuilder.build(media_profile) + + refute :write_auto_subs in res + end + + test "includes :embed_subs option when specified" do + media_profile = %MediaProfile{@media_profile | embed_subs: true} + + assert {:ok, res} = OptionBuilder.build(media_profile) + + assert :embed_subs in res + end + + test "includes sub_langs option when download_subs is true" do + media_profile = %MediaProfile{@media_profile | download_subs: true, sub_langs: "en"} + + assert {:ok, res} = OptionBuilder.build(media_profile) + + assert {:sub_langs, "en"} in res + end + + test "includes sub_langs option when embed_subs is true" do + media_profile = %MediaProfile{@media_profile | embed_subs: true, sub_langs: "en"} + + assert {:ok, res} = OptionBuilder.build(media_profile) + + assert {:sub_langs, "en"} in res + end + + test "doesn't include sub_langs option when neither downloading nor embedding" do + media_profile = %MediaProfile{ + @media_profile + | embed_subs: false, + download_subs: false, + sub_langs: "en" + } + + assert {:ok, res} = OptionBuilder.build(media_profile) + + refute {:sub_langs, "en"} in res + end + + test "other struct attributes are ignored" do + media_profile = %MediaProfile{@media_profile | id: -1} + + assert {:ok, res} = OptionBuilder.build(media_profile) + + refute {:id, -1} in res + end + end end