diff --git a/lib/pinchflat/downloading/download_option_builder.ex b/lib/pinchflat/downloading/download_option_builder.ex
index b9233d1..8c1af52 100644
--- a/lib/pinchflat/downloading/download_option_builder.ex
+++ b/lib/pinchflat/downloading/download_option_builder.ex
@@ -22,6 +22,7 @@ defmodule Pinchflat.Downloading.DownloadOptionBuilder do
thumbnail_options(media_item_with_preloads) ++
metadata_options(media_profile) ++
quality_options(media_profile) ++
+ sponsorblock_options(media_profile) ++
output_options(media_item_with_preloads)
{:ok, built_options}
@@ -116,6 +117,17 @@ defmodule Pinchflat.Downloading.DownloadOptionBuilder do
end
end
+ defp sponsorblock_options(media_profile) do
+ categories = media_profile.sponsorblock_categories
+ behaviour = media_profile.sponsorblock_behaviour
+
+ case {behaviour, categories} do
+ {_, []} -> []
+ {:remove, _} -> [sponsorblock_remove: Enum.join(categories, ",")]
+ {:disabled, _} -> []
+ end
+ end
+
defp output_options(media_item_with_preloads) do
[
output: build_output_path_for(media_item_with_preloads.source)
diff --git a/lib/pinchflat/profiles/media_profile.ex b/lib/pinchflat/profiles/media_profile.ex
index e33568c..57a3b7f 100644
--- a/lib/pinchflat/profiles/media_profile.ex
+++ b/lib/pinchflat/profiles/media_profile.ex
@@ -21,6 +21,8 @@ defmodule Pinchflat.Profiles.MediaProfile do
download_metadata
embed_metadata
download_nfo
+ sponsorblock_behaviour
+ sponsorblock_categories
shorts_behaviour
livestream_behaviour
preferred_resolution
@@ -47,6 +49,8 @@ defmodule Pinchflat.Profiles.MediaProfile do
field :embed_metadata, :boolean, default: false
field :download_nfo, :boolean, default: false
+ field :sponsorblock_behaviour, Ecto.Enum, values: [:disabled, :remove], default: :disabled
+ field :sponsorblock_categories, {:array, :string}, default: []
# NOTE: these do NOT speed up indexing - the indexer still has to go
# through the entire collection to determine if a media is a short or
# a livestream.
diff --git a/lib/pinchflat_web/components/core_components.ex b/lib/pinchflat_web/components/core_components.ex
index 1b9e05a..f124b16 100644
--- a/lib/pinchflat_web/components/core_components.ex
+++ b/lib/pinchflat_web/components/core_components.ex
@@ -251,7 +251,7 @@ defmodule PinchflatWeb.CoreComponents do
attr :type, :string,
default: "text",
values: ~w(checkbox color date datetime-local email file hidden month number password
- toggle range radio search select tel text textarea time url week)
+ checkbox_group toggle range radio search select tel text textarea time url week)
attr :field, Phoenix.HTML.FormField, doc: "a form field struct retrieved from the form, for example: @form[:email]"
@@ -304,6 +304,33 @@ defmodule PinchflatWeb.CoreComponents do
"""
end
+ def input(%{type: "checkbox_group"} = assigns) do
+ ~H"""
+
+ <.label for={@id}>
+ <%= @label %>
<%= @label_suffix %>
+
+
+ <.help :if={@help}><%= @help %>
+ <.error :for={msg <- @errors}><%= msg %>
+
+ """
+ end
+
def input(%{type: "toggle"} = assigns) do
assigns =
assign_new(assigns, :checked, fn ->
@@ -601,6 +628,10 @@ defmodule PinchflatWeb.CoreComponents do
_ ->
true
end)
+ |> Enum.map(fn
+ {k, v} when is_list(v) -> {k, Enum.join(v, ", ")}
+ rest -> rest
+ end)
assigns = assign(assigns, iterable_attributes: attrs)
diff --git a/lib/pinchflat_web/controllers/media_profiles/media_profile_html.ex b/lib/pinchflat_web/controllers/media_profiles/media_profile_html.ex
index 159af46..8f4a67a 100644
--- a/lib/pinchflat_web/controllers/media_profiles/media_profile_html.ex
+++ b/lib/pinchflat_web/controllers/media_profiles/media_profile_html.ex
@@ -32,6 +32,26 @@ defmodule PinchflatWeb.MediaProfiles.MediaProfileHTML do
]
end
+ def friendly_sponsorblock_options do
+ [
+ {"Disabled (default)", "disabled"},
+ {"Remove Segments", "remove"}
+ ]
+ end
+
+ def frieldly_sponsorblock_categories do
+ [
+ {"Sponsor", "sponsor"},
+ {"Intro/Intermission", "intro"},
+ {"Outro/Credits", "outro"},
+ {"Self Promotion", "selfpromo"},
+ {"Preview/Recap", "preview"},
+ {"Filler Tangent", "filler"},
+ {"Interaction Reminder", "interaction"},
+ {"Non-music Section", "music_offtopic"}
+ ]
+ end
+
def custom_output_template_options do
%{
upload_day: nil,
diff --git a/lib/pinchflat_web/controllers/media_profiles/media_profile_html/media_profile_form.html.heex b/lib/pinchflat_web/controllers/media_profiles/media_profile_html/media_profile_form.html.heex
index 66073dd..36d99cc 100644
--- a/lib/pinchflat_web/controllers/media_profiles/media_profile_html/media_profile_form.html.heex
+++ b/lib/pinchflat_web/controllers/media_profiles/media_profile_html/media_profile_form.html.heex
@@ -238,6 +238,36 @@
/>
+
+ SponsorBlock Options
+
+
+
+
+ <.input
+ field={f[:sponsorblock_behaviour]}
+ options={friendly_sponsorblock_options()}
+ type="select"
+ label="SponsorBlock Behaviour"
+ help="Action to take when SponsorBlock segments are found. 'Disabled' won't take any action"
+ x-model="sponsorblockBehaviour"
+ x-init="
+ sponsorblockBehaviour = $el.value
+ $watch('selectedPreset', p => p && ($el.value = presets[p]))
+ "
+ />
+
+
+
+ <.input
+ field={f[:sponsorblock_categories]}
+ options={frieldly_sponsorblock_categories()}
+ type="checkbox_group"
+ label="SponsorBlock Categories"
+ />
+
+
+
<.button class="my-10 sm:mb-7.5 w-full sm:w-auto" rounding="rounded-lg">Save Media profile
diff --git a/priv/repo/migrations/20240328160057_add_sponsorblock_to_media_profiles.exs b/priv/repo/migrations/20240328160057_add_sponsorblock_to_media_profiles.exs
new file mode 100644
index 0000000..606a6cf
--- /dev/null
+++ b/priv/repo/migrations/20240328160057_add_sponsorblock_to_media_profiles.exs
@@ -0,0 +1,10 @@
+defmodule Pinchflat.Repo.Migrations.AddSponsorblockToMediaProfiles do
+ use Ecto.Migration
+
+ def change do
+ alter table(:media_profiles) do
+ add :sponsorblock_behaviour, :string, default: "disabled"
+ add :sponsorblock_categories, {:array, :string}, default: []
+ end
+ end
+end
diff --git a/test/pinchflat/downloading/download_option_builder_test.exs b/test/pinchflat/downloading/download_option_builder_test.exs
index e08eb80..d7bc631 100644
--- a/test/pinchflat/downloading/download_option_builder_test.exs
+++ b/test/pinchflat/downloading/download_option_builder_test.exs
@@ -222,6 +222,45 @@ defmodule Pinchflat.Downloading.DownloadOptionBuilderTest do
end
end
+ describe "build/1 when testing sponsorblock options" do
+ test "includes :sponsorblock_remove option when specified", %{media_item: media_item} do
+ media_item =
+ update_media_profile_attribute(media_item, %{
+ sponsorblock_behaviour: :remove,
+ sponsorblock_categories: ["sponsor", "intro"]
+ })
+
+ assert {:ok, res} = DownloadOptionBuilder.build(media_item)
+
+ assert {:sponsorblock_remove, "sponsor,intro"} in res
+ end
+
+ test "does not include :sponsorblock_remove option without categories", %{media_item: media_item} do
+ media_item =
+ update_media_profile_attribute(media_item, %{
+ sponsorblock_behaviour: :remove,
+ sponsorblock_categories: []
+ })
+
+ assert {:ok, res} = DownloadOptionBuilder.build(media_item)
+
+ refute {:sponsorblock_remove, ""} in res
+ refute {:sponsorblock_remove, []} in res
+ refute :sponsorblock_remove in res
+ end
+
+ test "does not include any sponsorblock options when disabled", %{media_item: media_item} do
+ media_item =
+ update_media_profile_attribute(media_item, %{sponsorblock_behaviour: :disabled})
+
+ assert {:ok, res} = DownloadOptionBuilder.build(media_item)
+
+ refute {:sponsorblock_remove, ""} in res
+ refute {:sponsorblock_remove, []} in res
+ refute :sponsorblock_remove in res
+ end
+ end
+
describe "build_output_path_for/1" do
test "builds an output path for a source", %{media_item: media_item} do
path = DownloadOptionBuilder.build_output_path_for(media_item.source)