[Enhancement] Filter media based on min and/or max duration (#356)

* Added duration limits to source model

* Added duration limits to source form

* Added validation for min/max amounts

* Added duration checks to pending query

* Moved min/max filters up in source form

* Removed debugger
This commit is contained in:
Kieran
2024-08-14 14:20:50 -07:00
committed by GitHub
parent 8e9f02c807
commit af8235c6b3
8 changed files with 154 additions and 1 deletions
+10 -1
View File
@@ -75,6 +75,14 @@ defmodule Pinchflat.Media.MediaQuery do
)
end
def meets_min_and_max_duration do
dynamic(
[mi, source],
(is_nil(source.min_duration_seconds) or fragment("duration_seconds >= ?", source.min_duration_seconds)) and
(is_nil(source.max_duration_seconds) or fragment("duration_seconds <= ?", source.max_duration_seconds))
)
end
def past_retention_period do
dynamic(
[mi, source],
@@ -123,7 +131,8 @@ defmodule Pinchflat.Media.MediaQuery do
not (^download_prevented()) and
^upload_date_after_source_cutoff() and
^format_matching_profile_preference() and
^matches_source_title_regex()
^matches_source_title_regex() and
^meets_min_and_max_duration()
)
end
+17
View File
@@ -37,6 +37,8 @@ defmodule Pinchflat.Sources.Source do
media_profile_id
output_path_template_override
marked_for_deletion_at
min_duration_seconds
max_duration_seconds
)a
# Expensive API calls are made when a source is inserted/updated so
@@ -84,6 +86,9 @@ defmodule Pinchflat.Sources.Source do
field :title_filter_regex, :string
field :output_path_template_override, :string
field :min_duration_seconds, :integer
field :max_duration_seconds, :integer
field :series_directory, :string
field :nfo_filepath, :string
field :poster_filepath, :string
@@ -118,6 +123,7 @@ defmodule Pinchflat.Sources.Source do
|> dynamic_default(:uuid, fn _ -> Ecto.UUID.generate() end)
|> validate_required(required_fields)
|> validate_title_regex()
|> validate_min_and_max_durations()
|> validate_number(:retention_period_days, greater_than_or_equal_to: 0)
# Ensures it ends with `.{{ ext }}` or `.%(ext)s` or similar (with a little wiggle room)
|> validate_format(:output_path_template_override, MediaProfile.ext_regex(), message: "must end with .{{ ext }}")
@@ -164,6 +170,17 @@ defmodule Pinchflat.Sources.Source do
defp validate_title_regex(changeset), do: changeset
defp validate_min_and_max_durations(changeset) do
min_duration = get_change(changeset, :min_duration_seconds)
max_duration = get_change(changeset, :max_duration_seconds)
case {min_duration, max_duration} do
{min, max} when is_nil(min) or is_nil(max) -> changeset
{min, max} when min >= max -> add_error(changeset, :max_duration_seconds, "must be greater than minumum duration")
_ -> changeset
end
end
defimpl Jason.Encoder, for: Source do
def encode(value, opts) do
value
@@ -62,6 +62,7 @@ defmodule PinchflatWeb.Sources.SourceController do
| id: nil,
uuid: nil,
custom_name: nil,
description: nil,
collection_name: nil,
collection_id: nil,
collection_type: nil,
@@ -93,6 +93,24 @@
help="Uses your YouTube cookies for this source (if configured). Used for downloading private playlists and videos. See docs for important details"
/>
<section x-show="advancedMode">
<.input
field={f[:min_duration_seconds]}
type="number"
label="Minimum Duration (seconds)"
min="0"
help="Minimum duration of the media to be downloaded. Can be blank"
/>
<.input
field={f[:max_duration_seconds]}
type="number"
label="Maximum Duration (seconds)"
min="0"
help="Maximum duration of the media to be downloaded. Can be blank"
/>
</section>
<.input
field={f[:download_cutoff_date]}
type="text"