diff --git a/lib/pinchflat/downloading/download_option_builder.ex b/lib/pinchflat/downloading/download_option_builder.ex
index ab2b56a..be73d64 100644
--- a/lib/pinchflat/downloading/download_option_builder.ex
+++ b/lib/pinchflat/downloading/download_option_builder.ex
@@ -6,8 +6,10 @@ defmodule Pinchflat.Downloading.DownloadOptionBuilder do
alias Pinchflat.Sources
alias Pinchflat.Sources.Source
alias Pinchflat.Media.MediaItem
+ alias Pinchflat.Media.MediaQuery
alias Pinchflat.Downloading.OutputPathBuilder
alias Pinchflat.Downloading.QualityOptionBuilder
+ alias Pinchflat.Repo
alias Pinchflat.Utils.FilesystemUtils, as: FSUtils
@@ -209,10 +211,28 @@ defmodule Pinchflat.Downloading.DownloadOptionBuilder do
"source_collection_name" => source.collection_name,
"source_collection_type" => to_string(source.collection_type),
"media_playlist_index" => pad_int(media_item_with_preloads.playlist_index),
+ "media_playlist_index_reversed" => pad_int(calculate_reversed_playlist_index(media_item_with_preloads)),
"media_upload_date_index" => pad_int(media_item_with_preloads.upload_date_index)
}
end
+ defp calculate_reversed_playlist_index(media_item_with_preloads) do
+ source = media_item_with_preloads.source
+ current_index = media_item_with_preloads.playlist_index || 0
+
+ max_index =
+ MediaQuery.new()
+ |> where(^MediaQuery.for_source(source))
+ |> Repo.aggregate(:max, :playlist_index)
+
+ case {max_index, current_index} do
+ {nil, _} -> 0
+ {max, _} when max <= 0 -> 0
+ {max, current} when current > 0 -> max - current + 1
+ _ -> 0
+ end
+ end
+
# I don't love the string manipulation here, but what can ya' do.
# It's dependent on the output_path_template being a string ending `.{{ ext }}`
# (or equivalent), but that's validated by the MediaProfile schema.
diff --git a/lib/pinchflat/downloading/output_path_builder.ex b/lib/pinchflat/downloading/output_path_builder.ex
index 1c1392f..1d56606 100644
--- a/lib/pinchflat/downloading/output_path_builder.ex
+++ b/lib/pinchflat/downloading/output_path_builder.ex
@@ -56,6 +56,7 @@ defmodule Pinchflat.Downloading.OutputPathBuilder do
"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",
"static_season__episode_by_index" => "Season 1/s01e{{ media_playlist_index }}",
+ "static_season__episode_by_index_reversed" => "Season 1/s01e{{ media_playlist_index_reversed }}",
"static_season__episode_by_date" => "Season 1/s01e%(upload_date>%y%m%d)S",
"season_by_year__episode_by_date" => "Season %(upload_date>%Y)S/s%(upload_date>%Y)Se%(upload_date>%m%d)S",
"season_by_year__episode_by_date_and_index" =>
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 72beafe..32d7523 100644
--- a/lib/pinchflat_web/controllers/media_profiles/media_profile_html.ex
+++ b/lib/pinchflat_web/controllers/media_profiles/media_profile_html.ex
@@ -63,6 +63,8 @@ defmodule PinchflatWeb.MediaProfiles.MediaProfileHTML do
"same as the above but it handles dates better. This is the recommended option",
static_season__episode_by_index:
"Season 1/s01eXX where XX is the video's position in the playlist. Only recommended for playlists (not channels) that don't change",
+ static_season__episode_by_index_reversed:
+ "Season 1/s01eXX where XX is the video's position in the playlist in reversed order (last video is episode 1).",
static_season__episode_by_date:
"Season 1/s01eYYMMDD. Recommended for playlists that might change or where order isn't important"
]
@@ -86,6 +88,8 @@ defmodule PinchflatWeb.MediaProfiles.MediaProfileHTML do
"the upload date formatted as sYYYYeMMDDII where II is an index to prevent date collisions",
media_playlist_index:
"the place of the media item in the playlist. Do not use with channels. May not work if the playlist is updated",
+ media_playlist_index_reversed:
+ "the place of the media item in the playlist in reversed order (last video is 1). Do not use with channels. May not work if the playlist is updated",
media_item_id: "the ID of the media item in Pinchflat's database",
source_id: "the ID of the source in Pinchflat's database",
media_profile_id: "the ID of the media profile in Pinchflat's database"