[Enhancement] Add setting to restrict filenames to ASCII characters (#660)

* Added a new column for restricting filenames

* Adds restrict-filenames to command runner

* Added UI to settings form
This commit is contained in:
Kieran 2025-03-17 14:58:25 -07:00 committed by GitHub
parent ee2db3e9b7
commit 030f5fbdfe
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 57 additions and 17 deletions

View file

@ -16,7 +16,8 @@ defmodule Pinchflat.Settings.Setting do
:audio_codec_preference, :audio_codec_preference,
:youtube_api_key, :youtube_api_key,
:extractor_sleep_interval_seconds, :extractor_sleep_interval_seconds,
:download_throughput_limit :download_throughput_limit,
:restrict_filenames
] ]
@required_fields [ @required_fields [
@ -38,6 +39,7 @@ defmodule Pinchflat.Settings.Setting do
field :extractor_sleep_interval_seconds, :integer, default: 0 field :extractor_sleep_interval_seconds, :integer, default: 0
# This is a string because it accepts values like "100K" or "4.2M" # This is a string because it accepts values like "100K" or "4.2M"
field :download_throughput_limit, :string field :download_throughput_limit, :string
field :restrict_filenames, :boolean, default: false
field :video_codec_preference, :string field :video_codec_preference, :string
field :audio_codec_preference, :string field :audio_codec_preference, :string

View file

@ -35,7 +35,7 @@ defmodule Pinchflat.YtDlp.CommandRunner do
output_filepath = generate_output_filepath(addl_opts) output_filepath = generate_output_filepath(addl_opts)
print_to_file_opts = [{:print_to_file, output_template}, output_filepath] print_to_file_opts = [{:print_to_file, output_template}, output_filepath]
user_configured_opts = cookie_file_options(addl_opts) ++ rate_limit_opts(addl_opts) user_configured_opts = cookie_file_options(addl_opts) ++ rate_limit_options(addl_opts) ++ misc_options()
# These must stay in exactly this order, hence why I'm giving it its own variable. # These must stay in exactly this order, hence why I'm giving it its own variable.
all_opts = command_opts ++ print_to_file_opts ++ user_configured_opts ++ global_options() all_opts = command_opts ++ print_to_file_opts ++ user_configured_opts ++ global_options()
formatted_command_opts = [url] ++ CliUtils.parse_options(all_opts) formatted_command_opts = [url] ++ CliUtils.parse_options(all_opts)
@ -116,7 +116,22 @@ defmodule Pinchflat.YtDlp.CommandRunner do
end end
end end
defp rate_limit_opts(addl_opts) do defp add_cookie_file do
base_dir = Application.get_env(:pinchflat, :extras_directory)
filename_options_map = %{cookies: "cookies.txt"}
Enum.reduce(filename_options_map, [], fn {opt_name, filename}, acc ->
filepath = Path.join(base_dir, filename)
if FSUtils.exists_and_nonempty?(filepath) do
[{opt_name, filepath} | acc]
else
acc
end
end)
end
defp rate_limit_options(addl_opts) do
throughput_limit = Settings.get!(:download_throughput_limit) throughput_limit = Settings.get!(:download_throughput_limit)
sleep_interval_opts = sleep_interval_opts(addl_opts) sleep_interval_opts = sleep_interval_opts(addl_opts)
throughput_option = if throughput_limit, do: [limit_rate: throughput_limit], else: [] throughput_option = if throughput_limit, do: [limit_rate: throughput_limit], else: []
@ -138,19 +153,8 @@ defmodule Pinchflat.YtDlp.CommandRunner do
end end
end end
defp add_cookie_file do defp misc_options do
base_dir = Application.get_env(:pinchflat, :extras_directory) if Settings.get!(:restrict_filenames), do: [:restrict_filenames], else: []
filename_options_map = %{cookies: "cookies.txt"}
Enum.reduce(filename_options_map, [], fn {opt_name, filename}, acc ->
filepath = Path.join(base_dir, filename)
if FSUtils.exists_and_nonempty?(filepath) do
[{opt_name, filepath} | acc]
else
acc
end
end)
end end
defp backend_executable do defp backend_executable do

View file

@ -54,7 +54,14 @@
field={f[:download_throughput_limit]} field={f[:download_throughput_limit]}
placeholder="4.2M" placeholder="4.2M"
label="Download Throughput" label="Download Throughput"
help="Sets the max throughput when downloading media. Examples: '50K' or '4.2M'. Leave blank to disable" help="Sets the max bytes-per-second throughput when downloading media. Examples: '50K' or '4.2M'. Leave blank to disable"
/>
<.input
field={f[:restrict_filenames]}
type="toggle"
label="Restrict Filenames"
help="Restrict filenames to only ASCII characters and avoid ampersands/spaces in filenames"
/> />
</section> </section>
</section> </section>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 503 KiB

After

Width:  |  Height:  |  Size: 506 KiB

Before After
Before After

View file

@ -0,0 +1,9 @@
defmodule Pinchflat.Repo.Migrations.AddRestrictFilenamesToSettings do
use Ecto.Migration
def change do
alter table(:settings) do
add :restrict_filenames, :boolean, default: false
end
end
end

View file

@ -162,6 +162,24 @@ defmodule Pinchflat.YtDlp.CommandRunnerTest do
end end
end end
describe "run/4 when testing misc options" do
test "includes --restrict-filenames when enabled" do
Settings.set(restrict_filenames: true)
assert {:ok, output} = Runner.run(@media_url, :foo, [], "")
assert String.contains?(output, "--restrict-filenames")
end
test "doesn't include --restrict-filenames when disabled" do
Settings.set(restrict_filenames: false)
assert {:ok, output} = Runner.run(@media_url, :foo, [], "")
refute String.contains?(output, "--restrict-filenames")
end
end
describe "version/0" do describe "version/0" do
test "adds the version arg" do test "adds the version arg" do
assert {:ok, output} = Runner.version() assert {:ok, output} = Runner.version()