diff --git a/lib/pinchflat/downloading/download_option_builder.ex b/lib/pinchflat/downloading/download_option_builder.ex index ebb3667..0627bd6 100644 --- a/lib/pinchflat/downloading/download_option_builder.ex +++ b/lib/pinchflat/downloading/download_option_builder.ex @@ -193,7 +193,7 @@ defmodule Pinchflat.Downloading.DownloadOptionBuilder do "source_custom_name" => source.custom_name, "source_collection_id" => source.collection_id, "source_collection_name" => source.collection_name, - "source_collection_type" => source.collection_type, + "source_collection_type" => to_string(source.collection_type), "media_upload_date_index" => media_item_with_preloads.upload_date_index |> to_string() diff --git a/lib/pinchflat/downloading/output_path_builder.ex b/lib/pinchflat/downloading/output_path_builder.ex index 89d3f6c..d4f6e27 100644 --- a/lib/pinchflat/downloading/output_path_builder.ex +++ b/lib/pinchflat/downloading/output_path_builder.ex @@ -9,13 +9,23 @@ defmodule Pinchflat.Downloading.OutputPathBuilder do Builds the actual final filepath from a given template. Optionally, you can pass in a map of additional options to be used in the template. + Custom options are recursively expanded _once_ so you can nest custom options + one-deep if needed. + Translates liquid-style templates into yt-dlp-style templates, leaving yt-dlp syntax intact. """ def build(template_string, additional_template_options \\ %{}) do combined_options = Map.merge(custom_yt_dlp_option_map(), additional_template_options) - TemplateParser.parse(template_string, combined_options, &identifier_fn/2) + expanded_options = + Enum.map(combined_options, fn {key, value} -> + {:ok, parse_result} = TemplateParser.parse(value, combined_options, &identifier_fn/2) + + {key, parse_result} + end) + + TemplateParser.parse(template_string, Map.new(expanded_options), &identifier_fn/2) end # The `nil` case simply wraps the identifier in yt-dlp-style syntax. This assumes that @@ -43,6 +53,7 @@ defmodule Pinchflat.Downloading.OutputPathBuilder do "upload_yyyy_mm_dd" => "%(upload_date>%Y-%m-%d)S", "season_from_date" => "%(upload_date>%Y)S", "season_episode_from_date" => "s%(upload_date>%Y)Se%(upload_date>%m%d)S", + "season_episode_index_from_date" => "s%(upload_date>%Y)Se%(upload_date>%m%d)S{{ media_upload_date_index }}", "artist_name" => "%(artist,creator,uploader,uploader_id)S" } end 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 6395214..aae74ce 100644 --- a/lib/pinchflat_web/controllers/media_profiles/media_profile_html.ex +++ b/lib/pinchflat_web/controllers/media_profiles/media_profile_html.ex @@ -63,7 +63,11 @@ defmodule PinchflatWeb.MediaProfiles.MediaProfileHTML do source_collection_name: "the YouTube name of the sources that use this profile (often the same as source_custom_name)", source_collection_type: "the collection type of the sources using this profile. Either 'channel' or 'playlist'", - artist_name: "the name of the artist with fallbacks to other uploader fields" + artist_name: "the name of the artist with fallbacks to other uploader fields", + season_from_date: "alias for upload_year", + season_episode_from_date: "the upload date formatted as sYYYYeMMDD", + season_episode_index_from_date: + "the upload date formatted as sYYYYeMMDDII where II is an index to prevent date collisions" } end @@ -94,7 +98,7 @@ defmodule PinchflatWeb.MediaProfiles.MediaProfileHTML do end defp media_center_output_template do - "/shows/{{ source_custom_name }}/Season {{ season_from_date }}/{{ season_episode_from_date }} - {{ title }}.{{ ext }}" + "/shows/{{ source_custom_name }}/Season {{ season_from_date }}/{{ season_episode_index_from_date }} - {{ title }}.{{ ext }}" end defp audio_output_template do diff --git a/test/pinchflat/downloading/output_path_builder_test.exs b/test/pinchflat/downloading/output_path_builder_test.exs index 57051f6..c9a6660 100644 --- a/test/pinchflat/downloading/output_path_builder_test.exs +++ b/test/pinchflat/downloading/output_path_builder_test.exs @@ -27,5 +27,15 @@ defmodule Pinchflat.Downloading.OutputPathBuilderTest do assert res == "/videos/%(title)s.%(ext)s" end + + test "recursively expands variables" do + additional_options = %{ + "media_upload_date_index" => "99" + } + + assert {:ok, res} = OutputPathBuilder.build("{{ season_episode_index_from_date }}.{{ ext }}", additional_options) + + assert res == "s%(upload_date>%Y)Se%(upload_date>%m%d)S99.%(ext)S" + end end end