From b7684430bffb9cc360277cac9f5b757a5c3859fc Mon Sep 17 00:00:00 2001 From: Kieran Eglin Date: Fri, 12 Jul 2024 14:23:51 -0700 Subject: [PATCH] [WIP] started adding calls for downloading posters for playlists --- lib/pinchflat/metadata/source_image_parser.ex | 35 +++++++++++++------ .../source_metadata_storage_worker.ex | 21 ++++++++--- lib/pinchflat/yt_dlp/media_collection.ex | 12 ++++++- 3 files changed, 53 insertions(+), 15 deletions(-) diff --git a/lib/pinchflat/metadata/source_image_parser.ex b/lib/pinchflat/metadata/source_image_parser.ex index 9a0370c..c853966 100644 --- a/lib/pinchflat/metadata/source_image_parser.ex +++ b/lib/pinchflat/metadata/source_image_parser.ex @@ -27,13 +27,21 @@ defmodule Pinchflat.Metadata.SourceImageParser do defp select_useful_images(images) do labelled_images = - Enum.reduce(images, [], fn image_map, acc -> + Enum.reduce(images, %{}, fn image_map, acc -> case image_map do %{"id" => "avatar_uncropped"} -> - acc ++ [{:poster, :poster_filepath, image_map["filepath"]}] + Map.put(acc, :poster, %{ + attribute_name: :poster_filepath, + final_filename: "poster", + current_filepath: image_map["filepath"] + }) %{"id" => "banner_uncropped"} -> - acc ++ [{:fanart, :fanart_filepath, image_map["filepath"]}] + Map.put(acc, :fanart, %{ + attribute_name: :fanart_filepath, + final_filename: "fanart", + current_filepath: image_map["filepath"] + }) _ -> acc @@ -41,8 +49,13 @@ defmodule Pinchflat.Metadata.SourceImageParser do end) labelled_images - |> Enum.concat([{:banner, :banner_filepath, determine_best_banner(images)}]) - |> Enum.filter(fn {_, _, tmp_filepath} -> tmp_filepath end) + # |> add_fallback_poster() + |> Map.put(:banner, %{ + attribute_name: :banner_filepath, + final_filename: "banner", + current_filepath: determine_best_banner(images) + }) + |> Enum.filter(fn {_key, attrs} -> attrs.current_filepath end) end defp determine_best_banner(images) do @@ -58,12 +71,14 @@ defmodule Pinchflat.Metadata.SourceImageParser do Map.get(best_candidate || %{}, "filepath") end - defp move_image({filename, source_attr_name, tmp_filepath}, base_directory) do - extension = Path.extname(tmp_filepath) - final_filepath = Path.join([base_directory, "#{filename}#{extension}"]) + defp move_image({_key, attrs}, base_directory) do + extension = Path.extname(attrs.current_filepath) + final_filepath = Path.join([base_directory, "#{attrs.final_filename}#{extension}"]) - FilesystemUtils.cp_p!(tmp_filepath, final_filepath) + FilesystemUtils.cp_p!(attrs.current_filepath, final_filepath) - {source_attr_name, final_filepath} + {attrs.attribute_name, final_filepath} end + + # defp add_fallback_poster() end diff --git a/lib/pinchflat/metadata/source_metadata_storage_worker.ex b/lib/pinchflat/metadata/source_metadata_storage_worker.ex index 52ec810..b31d6ac 100644 --- a/lib/pinchflat/metadata/source_metadata_storage_worker.ex +++ b/lib/pinchflat/metadata/source_metadata_storage_worker.ex @@ -77,10 +77,8 @@ defmodule Pinchflat.Metadata.SourceMetadataStorageWorker do defp fetch_source_metadata_and_images(series_directory, source) do metadata_directory = MetadataFileHelpers.metadata_directory_for(source) - tmp_output_path = "#{tmp_directory()}/#{StringUtils.random_string(16)}/source_image.%(ext)S" - opts = [:write_all_thumbnails, convert_thumbnails: "jpg", output: tmp_output_path] - - {:ok, metadata} = MediaCollection.get_source_metadata(source.original_url, opts) + # TODO: test + {:ok, metadata} = fetch_metadata_for_source(source) metadata_image_attrs = SourceImageParser.store_source_images(metadata_directory, metadata) if source.media_profile.download_source_images && series_directory do @@ -110,6 +108,21 @@ defmodule Pinchflat.Metadata.SourceMetadataStorageWorker do end end + defp fetch_metadata_for_source(source) do + # TODO: test + tmp_output_path = "#{tmp_directory()}/#{StringUtils.random_string(16)}/source_image.%(ext)S" + base_opts = [convert_thumbnails: "jpg", output: tmp_output_path] + + opts = + if source.collection_type == :channel do + base_opts ++ [:write_all_thumbnails, playlist_items: 0] + else + base_opts ++ [:write_thumbnails, playlist_items: 1] + end + + MediaCollection.get_source_metadata(source.original_url, opts) + end + defp tmp_directory do Application.get_env(:pinchflat, :tmpfile_directory) end diff --git a/lib/pinchflat/yt_dlp/media_collection.ex b/lib/pinchflat/yt_dlp/media_collection.ex index 7e397ab..48c029f 100644 --- a/lib/pinchflat/yt_dlp/media_collection.ex +++ b/lib/pinchflat/yt_dlp/media_collection.ex @@ -99,10 +99,20 @@ defmodule Pinchflat.YtDlp.MediaCollection do as a compressed blob for possible future use. That's why it's not getting formatted like `get_source_details/1` + ! IMPORTANT ! - you'll always want to set `playlist_items: int` in `addl_opts. + This is great if you want to also return details about the videos in the playlists, + but it should be set in all cases to not over-fetch data. + For channels you should usually set this to 0 since channels return all the + metadata we need without needing to fetch the videos. On the other hand, playlists + don't return very useful images so you can set this to 1 to get the first video's + images, for instance. + Returns {:ok, map()} | {:error, any, ...}. """ def get_source_metadata(source_url, addl_opts \\ []) do - opts = [playlist_items: 0] ++ addl_opts + # TODO: test + # NOTE: don't forget to set `playlist_items` when you're calling this method! See above. + opts = [:skip_download] ++ addl_opts output_template = "playlist:%()j" with {:ok, output} <- backend_runner().run(source_url, opts, output_template),