Media downloading indexing options (round 2) (#14)

* Adds options + option builder + metadata parsing for media thumbnails

* Added release-type options to media profile; built option parser for indexing operations

* Added new media_profile options to creation form; made show helper for rendering database items

* Added options for downloading/embedding metadata

* Adds option on sources to not download media (index only)

* reformatted docs
This commit is contained in:
Kieran
2024-02-06 18:36:41 -08:00
committed by GitHub
parent b19c01e3ed
commit 9e4fbfa35d
31 changed files with 2317 additions and 1731 deletions
@@ -0,0 +1,161 @@
defmodule Pinchflat.Profiles.Options.YtDlp.DownloadOptionBuilderTest do
use ExUnit.Case, async: true
alias Pinchflat.Profiles.MediaProfile
alias Pinchflat.Profiles.Options.YtDlp.DownloadOptionBuilder
@media_profile %MediaProfile{
output_path_template: "{{ title }}.%(ext)s"
}
describe "build/1" do
test "it generates an expanded output path based on the given template" do
assert {:ok, res} = DownloadOptionBuilder.build(@media_profile)
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} = DownloadOptionBuilder.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} = DownloadOptionBuilder.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} = DownloadOptionBuilder.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} = DownloadOptionBuilder.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} = DownloadOptionBuilder.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} = DownloadOptionBuilder.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} = DownloadOptionBuilder.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} = DownloadOptionBuilder.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} = DownloadOptionBuilder.build(media_profile)
refute {:id, -1} in res
end
end
describe "build/1 when testing thumbnail options" do
test "includes :write_thumbnail option when specified" do
media_profile = %MediaProfile{@media_profile | download_thumbnail: true}
assert {:ok, res} = DownloadOptionBuilder.build(media_profile)
assert :write_thumbnail in res
end
test "includes :embed_thumbnail option when specified" do
media_profile = %MediaProfile{@media_profile | embed_thumbnail: true}
assert {:ok, res} = DownloadOptionBuilder.build(media_profile)
assert :embed_thumbnail in res
end
test "doesn't include these options when not specified" do
media_profile = %MediaProfile{
@media_profile
| embed_thumbnail: false,
download_thumbnail: false
}
assert {:ok, res} = DownloadOptionBuilder.build(media_profile)
refute :write_thumbnail in res
refute :embed_thumbnail in res
end
end
describe "build/1 when testing metadata options" do
test "includes :write_info_json option when specified" do
media_profile = %MediaProfile{@media_profile | download_metadata: true}
assert {:ok, res} = DownloadOptionBuilder.build(media_profile)
assert :write_info_json in res
assert :clean_info_json in res
end
test "includes :embed_metadata option when specified" do
media_profile = %MediaProfile{@media_profile | embed_metadata: true}
assert {:ok, res} = DownloadOptionBuilder.build(media_profile)
assert :embed_metadata in res
end
test "doesn't include these options when not specified" do
media_profile = %MediaProfile{
@media_profile
| embed_metadata: false,
download_metadata: false
}
assert {:ok, res} = DownloadOptionBuilder.build(media_profile)
refute :write_info_json in res
refute :clean_info_json in res
refute :embed_metadata in res
end
end
end
@@ -0,0 +1,104 @@
defmodule Pinchflat.Profiles.Options.YtDlp.IndexOptionBuilderTest do
use ExUnit.Case, async: true
alias Pinchflat.Profiles.MediaProfile
alias Pinchflat.Profiles.Options.YtDlp.IndexOptionBuilder
@media_profile %MediaProfile{
output_path_template: "{{ title }}.%(ext)s",
shorts_behaviour: :include,
livestream_behaviour: :include
}
describe "build/1 when testing release type options" do
test "adds correct filter when shorts_behaviour is :only" do
media_profile = %MediaProfile{@media_profile | shorts_behaviour: :only}
assert {:ok, res} = IndexOptionBuilder.build(media_profile)
assert {:match_filter, "original_url*=/shorts/"} in res
refute {:match_filter, "original_url!*=/shorts/"} in res
refute {:match_filter, "!was_live"} in res
refute {:match_filter, "was_live"} in res
end
test "adds correct filter when livestream_behaviour is :only" do
media_profile = %MediaProfile{@media_profile | livestream_behaviour: :only}
assert {:ok, res} = IndexOptionBuilder.build(media_profile)
assert {:match_filter, "was_live"} in res
refute {:match_filter, "!was_live"} in res
refute {:match_filter, "!original_url*=/shorts/"} in res
refute {:match_filter, "original_url*=/shorts/"} in res
end
test "adds correct filter when both livestreams and shorts are :only" do
media_profile = %MediaProfile{
@media_profile
| shorts_behaviour: :only,
livestream_behaviour: :only
}
assert {:ok, res} = IndexOptionBuilder.build(media_profile)
assert {:match_filter, "original_url*=/shorts/"} in res
assert {:match_filter, "was_live"} in res
refute {:match_filter, "original_url!*=/shorts/"} in res
refute {:match_filter, "!was_live"} in res
end
test "adds correct filter when shorts_behaviour is :exclude" do
media_profile = %MediaProfile{@media_profile | shorts_behaviour: :exclude}
assert {:ok, res} = IndexOptionBuilder.build(media_profile)
assert {:match_filter, "original_url!*=/shorts/"} in res
refute {:match_filter, "original_url*=/shorts/"} in res
refute {:match_filter, "was_live"} in res
refute {:match_filter, "!was_live"} in res
end
test "adds correct filter when livestream_behaviour is :exclude" do
media_profile = %MediaProfile{@media_profile | livestream_behaviour: :exclude}
assert {:ok, res} = IndexOptionBuilder.build(media_profile)
assert {:match_filter, "!was_live"} in res
refute {:match_filter, "was_live"} in res
refute {:match_filter, "original_url!*=/shorts/"} in res
refute {:match_filter, "original_url*=/shorts/"} in res
end
test "adds correct filter when shorts and livestreams are both exclude" do
media_profile = %MediaProfile{
@media_profile
| shorts_behaviour: :exclude,
livestream_behaviour: :exclude
}
assert {:ok, res} = IndexOptionBuilder.build(media_profile)
assert {:match_filter, "!was_live & original_url!*=/shorts/"} in res
refute {:match_filter, "original_url!*=/shorts/"} in res
refute {:match_filter, "!was_live"} in res
refute {:match_filter, "original_url*=/shorts/"} in res
refute {:match_filter, "was_live"} in res
end
test "does not add exclusion filter if one is excluded and the other is only" do
media_profile = %MediaProfile{
@media_profile
| shorts_behaviour: :exclude,
livestream_behaviour: :only
}
assert {:ok, res} = IndexOptionBuilder.build(media_profile)
assert {:match_filter, "was_live"} in res
refute {:match_filter, "original_url!*=/shorts/"} in res
refute {:match_filter, "original_url*=/shorts/"} in res
refute {:match_filter, "!was_live"} in res
end
end
end
@@ -1,97 +0,0 @@
defmodule Pinchflat.Profiles.Options.YtDlp.OptionBuilderTest do
use ExUnit.Case, async: true
alias Pinchflat.Profiles.MediaProfile
alias Pinchflat.Profiles.Options.YtDlp.OptionBuilder
@media_profile %MediaProfile{
output_path_template: "{{ title }}.%(ext)s"
}
describe "build/1" do
test "it generates an expanded output path based on the given template" do
assert {:ok, res} = OptionBuilder.build(@media_profile)
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