From 73171e069e15b2a1206bb193b58e793e3fa08541 Mon Sep 17 00:00:00 2001 From: Kieran Eglin Date: Wed, 31 Jan 2024 10:31:35 -0800 Subject: [PATCH] Adds subtitle_filepaths to media_item --- lib/pinchflat/media/media_item.ex | 6 +++++- .../backends/yt_dlp/metadata_parser.ex | 8 ++++++-- ...0131182114_add_subtitles_to_media_item.exs | 9 +++++++++ .../backends/yt_dlp/metadata_parser_test.exs | 20 ++++++++++++++++--- .../media_client/video_downloader_test.exs | 3 ++- 5 files changed, 39 insertions(+), 7 deletions(-) create mode 100644 priv/repo/migrations/20240131182114_add_subtitles_to_media_item.exs diff --git a/lib/pinchflat/media/media_item.ex b/lib/pinchflat/media/media_item.ex index a15427a..baa3d7e 100644 --- a/lib/pinchflat/media/media_item.ex +++ b/lib/pinchflat/media/media_item.ex @@ -11,12 +11,16 @@ defmodule Pinchflat.Media.MediaItem do alias Pinchflat.Media.MediaMetadata @required_fields ~w(media_id channel_id)a - @allowed_fields ~w(title media_id video_filepath channel_id)a + @allowed_fields ~w(title media_id video_filepath channel_id subtitle_filepaths)a schema "media_items" do field :title, :string field :media_id, :string field :video_filepath, :string + # This is an array of [iso-2 language, filepath] pairs. Probably could + # be an associated record, but I don't see the benefit right now. + # Will very likely revisit because I can't leave well-enough alone. + field :subtitle_filepaths, {:array, {:array, :string}}, default: [] belongs_to :channel, Channel diff --git a/lib/pinchflat/media_client/backends/yt_dlp/metadata_parser.ex b/lib/pinchflat/media_client/backends/yt_dlp/metadata_parser.ex index c7a9a7a..4fc3104 100644 --- a/lib/pinchflat/media_client/backends/yt_dlp/metadata_parser.ex +++ b/lib/pinchflat/media_client/backends/yt_dlp/metadata_parser.ex @@ -36,10 +36,14 @@ defmodule Pinchflat.MediaClient.Backends.YtDlp.MetadataParser do defp parse_subtitle_metadata(metadata) do subtitle_map = metadata["requested_subtitles"] || %{} + # IDEA: if needed, consider filtering out subtitles that don't exist on-disk + subtitle_filepaths = + subtitle_map + |> Enum.map(fn {lang, attrs} -> [lang, attrs["filepath"]] end) + |> Enum.sort(fn [lang_a, _], [lang_b, _] -> lang_a < lang_b end) %{ - # IDEA: if needed, consider filtering out subtitles that don't exist on-disk - subtitles: Enum.map(subtitle_map, fn {lang, attrs} -> [lang, attrs["filepath"]] end) + subtitle_filepaths: subtitle_filepaths } end end diff --git a/priv/repo/migrations/20240131182114_add_subtitles_to_media_item.exs b/priv/repo/migrations/20240131182114_add_subtitles_to_media_item.exs new file mode 100644 index 0000000..30f8b0f --- /dev/null +++ b/priv/repo/migrations/20240131182114_add_subtitles_to_media_item.exs @@ -0,0 +1,9 @@ +defmodule Pinchflat.Repo.Migrations.AddSubtitleFilepathsToMediaItem do + use Ecto.Migration + + def change do + alter table(:media_items) do + add :subtitle_filepaths, {:array, {:array, :string}}, default: [] + end + end +end diff --git a/test/pinchflat/media_client/backends/yt_dlp/metadata_parser_test.exs b/test/pinchflat/media_client/backends/yt_dlp/metadata_parser_test.exs index 079422e..313a78b 100644 --- a/test/pinchflat/media_client/backends/yt_dlp/metadata_parser_test.exs +++ b/test/pinchflat/media_client/backends/yt_dlp/metadata_parser_test.exs @@ -47,18 +47,32 @@ defmodule Pinchflat.MediaClient.Backends.YtDlp.MediaParserTest do test "extracts the subtitle filepaths", %{metadata: metadata} do result = Parser.parse_for_media_item(metadata) - assert [["de", german_filepath], ["en", english_filepath]] = result.subtitles + assert [["de", german_filepath], ["en", english_filepath]] = result.subtitle_filepaths assert String.ends_with?(english_filepath, ".en.srt") assert String.ends_with?(german_filepath, ".de.srt") end + test "sorts the subtitle filepaths by language", %{metadata: metadata} do + metadata = + Map.put(metadata, "requested_subtitles", %{ + "en" => %{"filepath" => "en.srt"}, + "za" => %{"filepath" => "za.srt"}, + "de" => %{"filepath" => "de.srt"}, + "al" => %{"filepath" => "al.srt"} + }) + + result = Parser.parse_for_media_item(metadata) + + assert [["al", _], ["de", _], ["en", _], ["za", _]] = result.subtitle_filepaths + end + test "doesn't freak out if the video has no subtitles", %{metadata: metadata} do metadata = Map.put(metadata, "requested_subtitles", %{}) result = Parser.parse_for_media_item(metadata) - assert result.subtitles == [] + assert result.subtitle_filepaths == [] end test "doesn't freak out if the requested_subtitles key is missing", %{metadata: metadata} do @@ -66,7 +80,7 @@ defmodule Pinchflat.MediaClient.Backends.YtDlp.MediaParserTest do result = Parser.parse_for_media_item(metadata) - assert result.subtitles == [] + assert result.subtitle_filepaths == [] end end end diff --git a/test/pinchflat/media_client/video_downloader_test.exs b/test/pinchflat/media_client/video_downloader_test.exs index 77b2c44..f172d3e 100644 --- a/test/pinchflat/media_client/video_downloader_test.exs +++ b/test/pinchflat/media_client/video_downloader_test.exs @@ -33,10 +33,11 @@ defmodule Pinchflat.MediaClient.VideoDownloaderTest do {:ok, render_metadata(:media_metadata)} end) - assert %{video_filepath: nil, title: nil} = media_item + assert %{video_filepath: nil, title: nil, subtitle_filepaths: []} = media_item assert {:ok, updated_media_item} = VideoDownloader.download_for_media_item(media_item) assert updated_media_item.video_filepath assert updated_media_item.title + assert length(updated_media_item.subtitle_filepaths) > 0 end test "it saves the metadata to the database", %{media_item: media_item} do