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
alias Pinchflat.Sources.Source alias Pinchflat.Sources.Source
alias Pinchflat.Media.MediaItem alias Pinchflat.Media.MediaItem
alias Pinchflat.Media.MediaQuery
alias Pinchflat.Downloading.OutputPathBuilder alias Pinchflat.Downloading.OutputPathBuilder
alias Pinchflat.Downloading.QualityOptionBuilder alias Pinchflat.Downloading.QualityOptionBuilder
alias Pinchflat.Repo
alias Pinchflat.Utils.FilesystemUtils, as: FSUtils alias Pinchflat.Utils.FilesystemUtils, as: FSUtils
@ -209,10 +211,28 @@ defmodule Pinchflat.Downloading.DownloadOptionBuilder do
"source_collection_name" => source.collection_name, "source_collection_name" => source.collection_name,
"source_collection_type" => to_string(source.collection_type), "source_collection_type" => to_string(source.collection_type),
"media_playlist_index" => pad_int(media_item_with_preloads.playlist_index), "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) "media_upload_date_index" => pad_int(media_item_with_preloads.upload_date_index)
} }
end 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. # 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 }}` # It's dependent on the output_path_template being a string ending `.{{ ext }}`
# (or equivalent), but that's validated by the MediaProfile schema. # (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 }}", "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", "artist_name" => "%(artist,creator,uploader,uploader_id)S",
"static_season__episode_by_index" => "Season 1/s01e{{ media_playlist_index }}", "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", "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" => "Season %(upload_date>%Y)S/s%(upload_date>%Y)Se%(upload_date>%m%d)S",
"season_by_year__episode_by_date_and_index" => "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>", "same as the above but it handles dates better. <strong>This is the recommended option</strong>",
static_season__episode_by_index: 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", "<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: static_season__episode_by_date:
"<code>Season 1/s01eYYMMDD</code>. Recommended for playlists that might change or where order isn't important" "<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", "the upload date formatted as <code>sYYYYeMMDDII</code> where <code>II</code> is an index to prevent date collisions",
media_playlist_index: 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", "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", media_item_id: "the ID of the media item in Pinchflat's database",
source_id: "the ID of the source 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" media_profile_id: "the ID of the media profile in Pinchflat's database"