From 618711691b9f08bf0545d22c82aa1da89c52a31e Mon Sep 17 00:00:00 2001 From: Kieran Date: Tue, 16 Apr 2024 17:37:39 -0700 Subject: [PATCH] [Bugfix]: Misc. bugfixes 2024-04-16 (#189) * Manually installed mutagen * Stopped upgrade form from submitting on enter * Gracefully handle duplicate enqueued downloads * Update metadata thumbnail fetcher to use the best jpg available --- assets/js/app.js | 11 ++++++++++ dev.Dockerfile | 3 +++ .../metadata/metadata_file_helpers.ex | 9 +++++++- .../layouts/partials/upgrade_button_live.ex | 3 ++- .../media_items/media_item_controller.ex | 8 ++++++- selfhosted.Dockerfile | 3 +++ test/pinchflat/media_test.exs | 12 +++------- .../metadata/metadata_file_helpers_test.exs | 22 ++++++++++++------- .../media_item_controller_test.exs | 9 ++++++++ 9 files changed, 60 insertions(+), 20 deletions(-) diff --git a/assets/js/app.js b/assets/js/app.js index f161731..90fa638 100644 --- a/assets/js/app.js +++ b/assets/js/app.js @@ -36,6 +36,17 @@ let liveSocket = new LiveSocket('/live', Socket, { window.Alpine.clone(from, to) } } + }, + hooks: { + supressEnterSubmission: { + mounted() { + this.el.addEventListener('keypress', (event) => { + if (event.key === 'Enter') { + event.preventDefault() + } + }) + } + } } }) diff --git a/dev.Dockerfile b/dev.Dockerfile index 9acbd3c..c6e6132 100644 --- a/dev.Dockerfile +++ b/dev.Dockerfile @@ -29,6 +29,9 @@ RUN yt-dlp -U # Download Apprise RUN python3 -m pip install -U apprise --break-system-packages +# Download Mutagen for music thumbnail generation +RUN python3 -m pip install -U mutagen --break-system-packages + # Set the locale RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && locale-gen ENV LANG en_US.UTF-8 diff --git a/lib/pinchflat/metadata/metadata_file_helpers.ex b/lib/pinchflat/metadata/metadata_file_helpers.ex index 959d1ca..a804ecd 100644 --- a/lib/pinchflat/metadata/metadata_file_helpers.ex +++ b/lib/pinchflat/metadata/metadata_file_helpers.ex @@ -54,11 +54,18 @@ defmodule Pinchflat.Metadata.MetadataFileHelpers do @doc """ Downloads and stores a thumbnail for a media item, returning the filepath. + Chooses the highest quality jpg thumbnail available. Returns binary() """ def download_and_store_thumbnail_for(database_record, metadata_map) do - thumbnail_url = metadata_map["thumbnail"] + thumbnail_url = + metadata_map["thumbnails"] + |> Enum.filter(&(&1["preference"] && String.ends_with?(&1["url"], ".jpg"))) + |> Enum.sort(&(&1["preference"] >= &2["preference"])) + |> List.first() + |> Map.get("url") + filepath = generate_filepath_for(database_record, Path.basename(thumbnail_url)) thumbnail_blob = fetch_thumbnail_from_url(thumbnail_url) diff --git a/lib/pinchflat_web/components/layouts/partials/upgrade_button_live.ex b/lib/pinchflat_web/components/layouts/partials/upgrade_button_live.ex index 959edae..17e1ac2 100644 --- a/lib/pinchflat_web/components/layouts/partials/upgrade_button_live.ex +++ b/lib/pinchflat_web/components/layouts/partials/upgrade_button_live.ex @@ -3,10 +3,11 @@ defmodule Pinchflat.UpgradeButtonLive do def render(assigns) do ~H""" -
+ <.input type="text" name="unlock-pro-textbox" value="" />
+ <%!-- The setTimeout is so the modal has time to disappear before it's removed --%> <.button class="w-full mt-4" type="button" diff --git a/lib/pinchflat_web/controllers/media_items/media_item_controller.ex b/lib/pinchflat_web/controllers/media_items/media_item_controller.ex index d348fee..278ef23 100644 --- a/lib/pinchflat_web/controllers/media_items/media_item_controller.ex +++ b/lib/pinchflat_web/controllers/media_items/media_item_controller.ex @@ -50,7 +50,13 @@ defmodule PinchflatWeb.MediaItems.MediaItemController do def force_download(conn, %{"media_item_id" => id}) do media_item = Media.get_media_item!(id) - {:ok, _} = MediaDownloadWorker.kickoff_with_task(media_item, %{force: true}) + + :ok = + case MediaDownloadWorker.kickoff_with_task(media_item, %{force: true}) do + {:ok, _} -> :ok + {:error, :duplicate_job} -> :ok + err -> err + end conn |> put_flash(:info, "Download task enqueued.") diff --git a/selfhosted.Dockerfile b/selfhosted.Dockerfile index 62b2c70..fd3bd91 100644 --- a/selfhosted.Dockerfile +++ b/selfhosted.Dockerfile @@ -90,6 +90,9 @@ RUN yt-dlp -U # Download Apprise RUN python3 -m pip install -U apprise --break-system-packages +# Download Mutagen for music thumbnail generation +RUN python3 -m pip install -U mutagen --break-system-packages + # Set the locale RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && locale-gen ENV LANG en_US.UTF-8 diff --git a/test/pinchflat/media_test.exs b/test/pinchflat/media_test.exs index fad36c0..f972259 100644 --- a/test/pinchflat/media_test.exs +++ b/test/pinchflat/media_test.exs @@ -731,9 +731,7 @@ defmodule Pinchflat.MediaTest do metadata: %{ metadata_filepath: MetadataFileHelpers.compress_and_store_metadata_for(media_item, %{}), thumbnail_filepath: - MetadataFileHelpers.download_and_store_thumbnail_for(media_item, %{ - "thumbnail" => "https://example.com/thumbnail.jpg" - }) + MetadataFileHelpers.download_and_store_thumbnail_for(media_item, render_parsed_metadata(:media_metadata)) } } @@ -760,9 +758,7 @@ defmodule Pinchflat.MediaTest do metadata: %{ metadata_filepath: MetadataFileHelpers.compress_and_store_metadata_for(media_item, %{}), thumbnail_filepath: - MetadataFileHelpers.download_and_store_thumbnail_for(media_item, %{ - "thumbnail" => "https://example.com/thumbnail.jpg" - }) + MetadataFileHelpers.download_and_store_thumbnail_for(media_item, render_parsed_metadata(:media_metadata)) } } @@ -831,9 +827,7 @@ defmodule Pinchflat.MediaTest do metadata: %{ metadata_filepath: MetadataFileHelpers.compress_and_store_metadata_for(media_item, %{}), thumbnail_filepath: - MetadataFileHelpers.download_and_store_thumbnail_for(media_item, %{ - "thumbnail" => "https://example.com/thumbnail.jpg" - }) + MetadataFileHelpers.download_and_store_thumbnail_for(media_item, render_parsed_metadata(:media_metadata)) } } diff --git a/test/pinchflat/metadata/metadata_file_helpers_test.exs b/test/pinchflat/metadata/metadata_file_helpers_test.exs index 4e2c73b..554afd2 100644 --- a/test/pinchflat/metadata/metadata_file_helpers_test.exs +++ b/test/pinchflat/metadata/metadata_file_helpers_test.exs @@ -54,13 +54,11 @@ defmodule Pinchflat.Metadata.MetadataFileHelpersTest do describe "download_and_store_thumbnail_for/2" do setup do # This tests that the HTTP endpoint is being called with every test - expect(HTTPClientMock, :get, fn url, _headers, _opts -> - assert url =~ "example.com" - + expect(HTTPClientMock, :get, fn _url, _headers, _opts -> {:ok, "thumbnail data"} end) - metadata = %{"thumbnail" => "example.com/thumbnail.jpg"} + metadata = render_parsed_metadata(:media_metadata) {:ok, %{metadata: metadata}} end @@ -68,7 +66,7 @@ defmodule Pinchflat.Metadata.MetadataFileHelpersTest do test "returns the filepath", %{media_item: media_item, metadata: metadata} do filepath = Helpers.download_and_store_thumbnail_for(media_item, metadata) - assert filepath =~ ~r{/media_items/#{media_item.id}/thumbnail.jpg} + assert filepath =~ ~r{/media_items/#{media_item.id}/maxresdefault.jpg} end test "creates folder structure based on passed record", %{media_item: media_item, metadata: metadata} do @@ -77,11 +75,19 @@ defmodule Pinchflat.Metadata.MetadataFileHelpersTest do assert File.exists?(Path.dirname(filepath)) end - test "the filename and extension is based on the URL", %{media_item: media_item} do - metadata = %{"thumbnail" => "example.com/maxres.webp"} + test "chooses the highest preference jpg thumbnail available", %{media_item: media_item} do + metadata = %{ + "thumbnails" => [ + %{"url" => "https://i.ytimg.com/vi/ABC123/img_1.jpg", "preference" => -1}, + %{"url" => "https://i.ytimg.com/vi/ABC123/img_2.jpg", "preference" => 1}, + %{"url" => "https://i.ytimg.com/vi/ABC123/img_3.jpg", "preference" => -10}, + %{"url" => "https://i.ytimg.com/vi/ABC123/img_4.webp", "preference" => 10} + ] + } + filepath = Helpers.download_and_store_thumbnail_for(media_item, metadata) - assert Path.basename(filepath) == "maxres.webp" + assert filepath =~ ~r{/media_items/#{media_item.id}/img_2.jpg} end end diff --git a/test/pinchflat_web/controllers/media_item_controller_test.exs b/test/pinchflat_web/controllers/media_item_controller_test.exs index b0c8847..5a2dbd9 100644 --- a/test/pinchflat_web/controllers/media_item_controller_test.exs +++ b/test/pinchflat_web/controllers/media_item_controller_test.exs @@ -97,6 +97,15 @@ defmodule PinchflatWeb.MediaItemControllerTest do assert [_] = all_enqueued(worker: MediaDownloadWorker) end + test "doesn't freak out if the task is a duplicate", %{conn: conn} do + media_item = media_item_fixture() + + MediaDownloadWorker.kickoff_with_task(media_item, %{force: true}) + + post(conn, ~p"/sources/#{media_item.source_id}/media/#{media_item.id}/force_download") + assert [_] = all_enqueued(worker: MediaDownloadWorker) + end + test "forces a download even if one wouldn't normally run", %{conn: conn} do media_item = media_item_fixture(%{media_filepath: nil})