First pass with Cursor

This commit is contained in:
Felix 2025-12-13 18:24:50 -05:00
parent 163e8eb8cc
commit f3a6898486
3 changed files with 25 additions and 0 deletions

View file

@ -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.

View file

@ -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" =>

View file

@ -63,6 +63,8 @@ defmodule PinchflatWeb.MediaProfiles.MediaProfileHTML do
"same as the above but it handles dates better. <strong>This is the recommended option</strong>",
static_season__episode_by_index:
"<code>Season 1/s01eXX</code> where <code>XX</code> is the video's position in the playlist. Only recommended for playlists (not channels) that don't change",
static_season__episode_by_index_reversed:
"<code>Season 1/s01eXX</code> where <code>XX</code> is the video's position in the playlist in reversed order (last video is episode 1).",
static_season__episode_by_date:
"<code>Season 1/s01eYYMMDD</code>. 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 <code>sYYYYeMMDDII</code> where <code>II</code> 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"