Rename video-related modules to be media-related (#50)

* Added test from before that I forgor

* Renamed video-related modules to media
This commit is contained in:
Kieran 2024-03-04 17:46:33 -08:00 committed by GitHub
parent f55cdc80dd
commit 90a0022d85
21 changed files with 128 additions and 109 deletions

View file

@ -12,7 +12,7 @@ alias Pinchflat.Media
alias Pinchflat.Profiles
alias Pinchflat.Sources
alias Pinchflat.MediaClient.{SourceDetails, VideoDownloader}
alias Pinchflat.MediaClient.{SourceDetails, MediaDownloader}
alias Pinchflat.Metadata.{Zipper, ThumbnailFetcher}
alias Pinchflat.Utils.FilesystemUtils.FileFollowerServer

View file

@ -1,7 +1,7 @@
import Config
config :pinchflat,
media_directory: Path.join([File.cwd!(), "tmp", "videos"]),
media_directory: Path.join([File.cwd!(), "tmp", "media"]),
metadata_directory: Path.join([File.cwd!(), "tmp", "metadata"]),
tmpfile_directory: Path.join([File.cwd!(), "tmp", "tmpfiles"])

View file

@ -3,7 +3,7 @@ import Config
config :pinchflat,
# Specifying backend data here makes mocking and local testing SUPER easy
yt_dlp_executable: Path.join([File.cwd!(), "/test/support/scripts/yt-dlp-mocks/repeater.sh"]),
media_directory: Path.join([System.tmp_dir!(), "test", "videos"]),
media_directory: Path.join([System.tmp_dir!(), "test", "media"]),
metadata_directory: Path.join([System.tmp_dir!(), "test", "metadata"]),
tmpfile_directory: Path.join([System.tmp_dir!(), "test", "tmpfiles"]),
file_watcher_poll_interval: 50

View file

@ -1,10 +1,10 @@
defmodule Pinchflat.MediaClient.Backends.YtDlp.Video do
defmodule Pinchflat.MediaClient.Backends.YtDlp.Media do
@moduledoc """
Contains utilities for working with singular videos
Contains utilities for working with singular pieces of media
"""
@doc """
Downloads a single video (and possibly its metadata) directly to its
Downloads a single piece of media (and possibly its metadata) directly to its
final destination. Returns the parsed JSON output from yt-dlp.
Returns {:ok, map()} | {:error, any, ...}.

View file

@ -1,7 +1,7 @@
defmodule Pinchflat.MediaClient.Backends.YtDlp.VideoCollection do
defmodule Pinchflat.MediaClient.Backends.YtDlp.MediaCollection do
@moduledoc """
Contains utilities for working with collections of
videos (aka: a source [ie: channels, playlists]).
media (aka: a source [ie: channels, playlists]).
"""
require Logger
@ -10,7 +10,7 @@ defmodule Pinchflat.MediaClient.Backends.YtDlp.VideoCollection do
alias Pinchflat.Utils.FilesystemUtils
@doc """
Returns a list of maps representing the videos in the collection.
Returns a list of maps representing the media in the collection.
Options:
- :file_listener_handler - a function that will be called with the path to the

View file

@ -4,7 +4,7 @@ defmodule Pinchflat.MediaClient.Backends.YtDlp.MetadataFileHelpers do
out-of-band of the normal yt-dlp backend process.
The idea is that I don't want to craft a complicated yt-dlp command,
instead focusing on downloading the video as the user wants it then
instead focusing on downloading the media as the user wants it then
I can use the result of that here to grab the additional information
needed
"""

View file

@ -1,8 +1,8 @@
defmodule Pinchflat.MediaClient.VideoDownloader do
defmodule Pinchflat.MediaClient.MediaDownloader do
@moduledoc """
This is the integration layer for actually downloading videos.
This is the integration layer for actually downloading medias.
It takes into account the media profile's settings in order
to download the video with the desired options.
to download the media with the desired options.
Technically hardcodes the yt-dlp backend for now, but should leave
it open-ish for future expansion (just in case).
@ -12,13 +12,13 @@ defmodule Pinchflat.MediaClient.VideoDownloader do
alias Pinchflat.Media
alias Pinchflat.Media.MediaItem
alias Pinchflat.MediaClient.Backends.YtDlp.Video, as: YtDlpVideo
alias Pinchflat.MediaClient.Backends.YtDlp.Media, as: YtDlpMedia
alias Pinchflat.Profiles.Options.YtDlp.DownloadOptionBuilder, as: YtDlpDownloadOptionBuilder
alias Pinchflat.MediaClient.Backends.YtDlp.MetadataParser, as: YtDlpMetadataParser
alias Pinchflat.MediaClient.Backends.YtDlp.MetadataFileHelpers, as: YtDlpMetadataHelpers
@doc """
Downloads a video for a media item, updating the media item based on the metadata
Downloads media for a media item, updating the media item based on the metadata
returned by the backend. Also saves the entire metadata response to the associated
media_metadata record.
@ -57,10 +57,10 @@ defmodule Pinchflat.MediaClient.VideoDownloader do
defp download_with_options(url, item_with_preloads, backend) do
option_builder = option_builder(backend)
video_backend = video_backend(backend)
media_backend = media_backend(backend)
{:ok, options} = option_builder.build(item_with_preloads)
video_backend.download(url, options)
media_backend.download(url, options)
end
defp option_builder(backend) do
@ -69,9 +69,9 @@ defmodule Pinchflat.MediaClient.VideoDownloader do
end
end
defp video_backend(backend) do
defp media_backend(backend) do
case backend do
:yt_dlp -> YtDlpVideo
:yt_dlp -> YtDlpMedia
end
end

View file

@ -7,7 +7,7 @@ defmodule Pinchflat.MediaClient.SourceDetails do
"""
alias Pinchflat.Sources.Source
alias Pinchflat.MediaClient.Backends.YtDlp.VideoCollection, as: YtDlpSource
alias Pinchflat.MediaClient.Backends.YtDlp.MediaCollection, as: YtDlpSource
@doc """
Gets a source's ID and name from its URL using the given backend.
@ -19,7 +19,7 @@ defmodule Pinchflat.MediaClient.SourceDetails do
end
@doc """
Returns a list of basic video data mapsfor the given source URL OR
Returns a list of basic media data maps for the given source URL OR
source record using the given backend.
Options:

View file

@ -44,10 +44,10 @@ defmodule Pinchflat.Profiles.MediaProfile do
field :embed_metadata, :boolean, default: true
# NOTE: these do NOT speed up indexing - the indexer still has to go
# through the entire collection to determine if a video is a short or
# through the entire collection to determine if a media is a short or
# a livestream.
# NOTE: these can BOTH be set to :only which will download shorts and
# livestreams _only_ and ignore regular videos. The redundant case
# livestreams _only_ and ignore regular media. The redundant case
# is when one is set to :only and the other is set to :exclude.
# See `build_format_clauses` in the Media context for more.
field :shorts_behaviour, Ecto.Enum, values: ~w(include exclude only)a, default: :include

View file

@ -15,7 +15,7 @@ defmodule Pinchflat.Tasks.SourceTasks do
alias Pinchflat.Media.MediaItem
alias Pinchflat.MediaClient.SourceDetails
alias Pinchflat.Workers.MediaIndexingWorker
alias Pinchflat.Workers.VideoDownloadWorker
alias Pinchflat.Workers.MediaDownloadWorker
alias Pinchflat.Utils.FilesystemUtils.FileFollowerServer
@doc """
@ -75,7 +75,7 @@ defmodule Pinchflat.Tasks.SourceTasks do
end
@doc """
Starts tasks for downloading videos for any of a sources _pending_ media items.
Starts tasks for downloading media for any of a sources _pending_ media items.
Jobs are not enqueued if the source is set to not download media. This will return :ok.
NOTE: this starts a download for each media item that is pending,
@ -91,7 +91,7 @@ defmodule Pinchflat.Tasks.SourceTasks do
|> Enum.each(fn media_item ->
media_item
|> Map.take([:id])
|> VideoDownloadWorker.new()
|> MediaDownloadWorker.new()
|> Tasks.create_job_with_task(media_item)
end)
end
@ -161,7 +161,7 @@ defmodule Pinchflat.Tasks.SourceTasks do
media_item
|> Map.take([:id])
|> VideoDownloadWorker.new()
|> MediaDownloadWorker.new()
|> Tasks.create_job_with_task(media_item)
end

View file

@ -1,4 +1,4 @@
defmodule Pinchflat.Workers.VideoDownloadWorker do
defmodule Pinchflat.Workers.MediaDownloadWorker do
@moduledoc false
use Oban.Worker,
@ -9,7 +9,7 @@ defmodule Pinchflat.Workers.VideoDownloadWorker do
alias Pinchflat.Repo
alias Pinchflat.Media
alias Pinchflat.Tasks
alias Pinchflat.MediaClient.VideoDownloader
alias Pinchflat.MediaClient.MediaDownloader
alias Pinchflat.Workers.FilesystemDataWorker
@impl Oban.Worker
@ -34,7 +34,7 @@ defmodule Pinchflat.Workers.VideoDownloadWorker do
end
defp download_media_and_schedule_jobs(media_item) do
case VideoDownloader.download_for_media_item(media_item) do
case MediaDownloader.download_for_media_item(media_item) do
{:ok, _} ->
schedule_filesystem_data_worker(media_item)
{:ok, media_item}

View file

@ -4,7 +4,7 @@ defmodule Pinchflat.MediaClient.Backends.YtDlp.CommandRunnerTest do
alias Pinchflat.MediaClient.Backends.YtDlp.CommandRunner, as: Runner
@original_executable Application.compile_env(:pinchflat, :yt_dlp_executable)
@video_url "https://www.youtube.com/watch?v=-LHXuyzpex0"
@media_url "https://www.youtube.com/watch?v=-LHXuyzpex0"
setup do
on_exit(&reset_executable/0)
@ -12,54 +12,54 @@ defmodule Pinchflat.MediaClient.Backends.YtDlp.CommandRunnerTest do
describe "run/4" do
test "it returns the output and status when the command succeeds" do
assert {:ok, _output} = Runner.run(@video_url, [], "")
assert {:ok, _output} = Runner.run(@media_url, [], "")
end
test "it converts symbol k-v arg keys to kebab case" do
assert {:ok, output} = Runner.run(@video_url, [buffer_size: 1024], "")
assert {:ok, output} = Runner.run(@media_url, [buffer_size: 1024], "")
assert String.contains?(output, "--buffer-size 1024")
end
test "it keeps string k-v arg keys untouched" do
assert {:ok, output} = Runner.run(@video_url, [{"--under_score", 1024}], "")
assert {:ok, output} = Runner.run(@media_url, [{"--under_score", 1024}], "")
assert String.contains?(output, "--under_score 1024")
end
test "it converts symbol arg keys to kebab case" do
assert {:ok, output} = Runner.run(@video_url, [:ignore_errors], "")
assert {:ok, output} = Runner.run(@media_url, [:ignore_errors], "")
assert String.contains?(output, "--ignore-errors")
end
test "it keeps string arg keys untouched" do
assert {:ok, output} = Runner.run(@video_url, ["-v"], "")
assert {:ok, output} = Runner.run(@media_url, ["-v"], "")
assert String.contains?(output, "-v")
refute String.contains?(output, "--v")
end
test "it includes the video url as the first argument" do
assert {:ok, output} = Runner.run(@video_url, [:ignore_errors], "")
test "it includes the media url as the first argument" do
assert {:ok, output} = Runner.run(@media_url, [:ignore_errors], "")
assert String.contains?(output, "#{@video_url} --ignore-errors")
assert String.contains?(output, "#{@media_url} --ignore-errors")
end
test "it automatically includes the --print-to-file flag" do
assert {:ok, output} = Runner.run(@video_url, [], "%(id)s")
assert {:ok, output} = Runner.run(@media_url, [], "%(id)s")
assert String.contains?(output, "--print-to-file %(id)s /tmp/")
end
test "it returns the output and status when the command fails" do
wrap_executable("/bin/false", fn ->
assert {:error, "", 1} = Runner.run(@video_url, [], "")
assert {:error, "", 1} = Runner.run(@media_url, [], "")
end)
end
test "optionally lets you specify an output_filepath" do
assert {:ok, output} = Runner.run(@video_url, [], "%(id)s", output_filepath: "/tmp/yt-dlp-output.json")
assert {:ok, output} = Runner.run(@media_url, [], "%(id)s", output_filepath: "/tmp/yt-dlp-output.json")
assert String.contains?(output, "--print-to-file %(id)s /tmp/yt-dlp-output.json")
end

View file

@ -1,9 +1,9 @@
defmodule Pinchflat.MediaClient.Backends.YtDlp.VideoCollectionTest do
defmodule Pinchflat.MediaClient.Backends.YtDlp.MediaCollectionTest do
use Pinchflat.DataCase
import Mox
import Pinchflat.SourcesFixtures
alias Pinchflat.MediaClient.Backends.YtDlp.VideoCollection
alias Pinchflat.MediaClient.Backends.YtDlp.MediaCollection
@channel_url "https://www.youtube.com/c/TheUselessTrials"
@ -16,7 +16,7 @@ defmodule Pinchflat.MediaClient.Backends.YtDlp.VideoCollectionTest do
end)
assert {:ok, [%{"id" => "video1"}, %{"id" => "video2"}, %{"id" => "video3"}]} =
VideoCollection.get_media_attributes(@channel_url)
MediaCollection.get_media_attributes(@channel_url)
end
test "it passes the expected default args" do
@ -27,13 +27,13 @@ defmodule Pinchflat.MediaClient.Backends.YtDlp.VideoCollectionTest do
{:ok, ""}
end)
assert {:ok, _} = VideoCollection.get_media_attributes(@channel_url)
assert {:ok, _} = MediaCollection.get_media_attributes(@channel_url)
end
test "returns the error straight through when the command fails" do
expect(YtDlpRunnerMock, :run, fn _url, _opts, _ot, _addl_opts -> {:error, "Big issue", 1} end)
assert {:error, "Big issue", 1} = VideoCollection.get_media_attributes(@channel_url)
assert {:error, "Big issue", 1} = MediaCollection.get_media_attributes(@channel_url)
end
test "passes the explict tmpfile path to runner" do
@ -44,7 +44,7 @@ defmodule Pinchflat.MediaClient.Backends.YtDlp.VideoCollectionTest do
{:ok, ""}
end)
assert {:ok, _} = VideoCollection.get_media_attributes(@channel_url)
assert {:ok, _} = MediaCollection.get_media_attributes(@channel_url)
end
test "supports an optional file_listener_handler that gets passed a filename" do
@ -55,7 +55,7 @@ defmodule Pinchflat.MediaClient.Backends.YtDlp.VideoCollectionTest do
send(current_self, {:handler, filename})
end
assert {:ok, _} = VideoCollection.get_media_attributes(@channel_url, file_listener_handler: handler)
assert {:ok, _} = MediaCollection.get_media_attributes(@channel_url, file_listener_handler: handler)
assert_receive {:handler, filename}
assert String.ends_with?(filename, ".json")
@ -73,7 +73,7 @@ defmodule Pinchflat.MediaClient.Backends.YtDlp.VideoCollectionTest do
})
end)
assert {:ok, res} = VideoCollection.get_source_details(@channel_url)
assert {:ok, res} = MediaCollection.get_source_details(@channel_url)
assert %{
channel_id: "UCQH2",
@ -91,19 +91,19 @@ defmodule Pinchflat.MediaClient.Backends.YtDlp.VideoCollectionTest do
{:ok, "{}"}
end)
assert {:ok, _} = VideoCollection.get_source_details(@channel_url)
assert {:ok, _} = MediaCollection.get_source_details(@channel_url)
end
test "it returns an error if the runner returns an error" do
expect(YtDlpRunnerMock, :run, fn _url, _opts, _ot -> {:error, "Big issue", 1} end)
assert {:error, "Big issue", 1} = VideoCollection.get_source_details(@channel_url)
assert {:error, "Big issue", 1} = MediaCollection.get_source_details(@channel_url)
end
test "it returns an error if the output is not JSON" do
expect(YtDlpRunnerMock, :run, fn _url, _opts, _ot -> {:ok, "Not JSON"} end)
assert {:error, %Jason.DecodeError{}} = VideoCollection.get_source_details(@channel_url)
assert {:error, %Jason.DecodeError{}} = MediaCollection.get_source_details(@channel_url)
end
end
end

View file

@ -1,10 +1,10 @@
defmodule Pinchflat.MediaClient.Backends.YtDlp.VideoTest do
defmodule Pinchflat.MediaClient.Backends.YtDlp.MediaTest do
use Pinchflat.DataCase
import Mox
alias Pinchflat.MediaClient.Backends.YtDlp.Video
alias Pinchflat.MediaClient.Backends.YtDlp.Media
@video_url "https://www.youtube.com/watch?v=TiZPUDkDYbk"
@media_url "https://www.youtube.com/watch?v=TiZPUDkDYbk"
setup :verify_on_exit!
@ -16,14 +16,14 @@ defmodule Pinchflat.MediaClient.Backends.YtDlp.VideoTest do
describe "download/2" do
test "it calls the backend runner with the expected arguments" do
expect(YtDlpRunnerMock, :run, fn @video_url, opts, ot ->
expect(YtDlpRunnerMock, :run, fn @media_url, opts, ot ->
assert [:no_simulate] = opts
assert "after_move:%()j" = ot
{:ok, render_metadata(:media_metadata)}
end)
assert {:ok, _} = Video.download(@video_url)
assert {:ok, _} = Media.download(@media_url)
end
test "it passes along additional options" do
@ -33,7 +33,7 @@ defmodule Pinchflat.MediaClient.Backends.YtDlp.VideoTest do
{:ok, "{}"}
end)
assert {:ok, _} = Video.download(@video_url, [:custom_arg])
assert {:ok, _} = Media.download(@media_url, [:custom_arg])
end
test "it parses and returns the generated file as JSON" do
@ -42,7 +42,7 @@ defmodule Pinchflat.MediaClient.Backends.YtDlp.VideoTest do
end)
assert {:ok, %{"title" => "Trying to Wheelie Without the Rear Brake"}} =
Video.download(@video_url)
Media.download(@media_url)
end
test "it returns errors" do
@ -50,7 +50,7 @@ defmodule Pinchflat.MediaClient.Backends.YtDlp.VideoTest do
{:error, "something"}
end)
assert {:error, "something"} = Video.download(@video_url)
assert {:error, "something"} = Media.download(@media_url)
end
end
end

View file

@ -23,7 +23,7 @@ defmodule Pinchflat.MediaClient.Backends.YtDlp.MediaParserTest do
end
describe "parse_for_media_item/1 when testing media metadata" do
test "it extracts the video filepath", %{metadata: metadata} do
test "it extracts the media filepath", %{metadata: metadata} do
result = Parser.parse_for_media_item(metadata)
assert String.contains?(result.media_filepath, "bwRHIkYqYJo")
@ -67,7 +67,7 @@ defmodule Pinchflat.MediaClient.Backends.YtDlp.MediaParserTest do
assert [["al", _], ["de", _], ["en", _], ["za", _]] = result.subtitle_filepaths
end
test "doesn't freak out if the video has no subtitles", %{metadata: metadata} do
test "doesn't freak out if the media has no subtitles", %{metadata: metadata} do
metadata = Map.put(metadata, "requested_subtitles", %{})
result = Parser.parse_for_media_item(metadata)
@ -91,7 +91,7 @@ defmodule Pinchflat.MediaClient.Backends.YtDlp.MediaParserTest do
assert String.ends_with?(result.thumbnail_filepath, ".webp")
end
test "doesn't freak out if the video has no thumbnails", %{metadata: metadata} do
test "doesn't freak out if the media has no thumbnails", %{metadata: metadata} do
metadata = Map.put(metadata, "thumbnails", %{})
result = Parser.parse_for_media_item(metadata)
@ -115,7 +115,7 @@ defmodule Pinchflat.MediaClient.Backends.YtDlp.MediaParserTest do
assert String.ends_with?(result.metadata_filepath, ".info.json")
end
test "doesn't freak out if the video has no infojson", %{metadata: metadata} do
test "doesn't freak out if the media has no infojson", %{metadata: metadata} do
metadata = Map.put(metadata, "infojson_filename", nil)
result = Parser.parse_for_media_item(metadata)

View file

@ -1,9 +1,9 @@
defmodule Pinchflat.MediaClient.VideoDownloaderTest do
defmodule Pinchflat.MediaClient.MediaDownloaderTest do
use Pinchflat.DataCase
import Mox
import Pinchflat.MediaFixtures
alias Pinchflat.MediaClient.VideoDownloader
alias Pinchflat.MediaClient.MediaDownloader
setup :verify_on_exit!
@ -30,7 +30,7 @@ defmodule Pinchflat.MediaClient.VideoDownloaderTest do
{:ok, render_metadata(:media_metadata)}
end)
assert {:ok, _} = VideoDownloader.download_for_media_item(media_item)
assert {:ok, _} = MediaDownloader.download_for_media_item(media_item)
end
test "it saves the metadata filepatha to the database", %{media_item: media_item} do
@ -39,7 +39,7 @@ defmodule Pinchflat.MediaClient.VideoDownloaderTest do
end)
assert is_nil(media_item.metadata)
assert {:ok, updated_media_item} = VideoDownloader.download_for_media_item(media_item)
assert {:ok, updated_media_item} = MediaDownloader.download_for_media_item(media_item)
assert updated_media_item.metadata.metadata_filepath =~ "media_items/#{media_item.id}/metadata.json.gz"
assert updated_media_item.metadata.thumbnail_filepath =~ "media_items/#{media_item.id}/maxresdefault.jpg"
@ -50,7 +50,7 @@ defmodule Pinchflat.MediaClient.VideoDownloaderTest do
{:error, :some_error}
end)
assert {:error, :some_error} = VideoDownloader.download_for_media_item(media_item)
assert {:error, :some_error} = MediaDownloader.download_for_media_item(media_item)
end
end
@ -65,41 +65,41 @@ defmodule Pinchflat.MediaClient.VideoDownloaderTest do
test "it sets the media_downloaded_at", %{media_item: media_item} do
assert media_item.media_downloaded_at == nil
assert {:ok, updated_media_item} = VideoDownloader.download_for_media_item(media_item)
assert {:ok, updated_media_item} = MediaDownloader.download_for_media_item(media_item)
assert DateTime.diff(DateTime.utc_now(), updated_media_item.media_downloaded_at) < 2
end
test "it extracts the title", %{media_item: media_item} do
assert {:ok, updated_media_item} = VideoDownloader.download_for_media_item(media_item)
assert {:ok, updated_media_item} = MediaDownloader.download_for_media_item(media_item)
assert updated_media_item.title == "Trying to Wheelie Without the Rear Brake"
end
test "it extracts the description", %{media_item: media_item} do
assert {:ok, updated_media_item} = VideoDownloader.download_for_media_item(media_item)
assert {:ok, updated_media_item} = MediaDownloader.download_for_media_item(media_item)
assert is_binary(updated_media_item.description)
end
test "it extracts the media_filepath", %{media_item: media_item} do
assert media_item.media_filepath == nil
assert {:ok, updated_media_item} = VideoDownloader.download_for_media_item(media_item)
assert {:ok, updated_media_item} = MediaDownloader.download_for_media_item(media_item)
assert String.ends_with?(updated_media_item.media_filepath, ".mkv")
end
test "it extracts the subtitle_filepaths", %{media_item: media_item} do
assert media_item.subtitle_filepaths == []
assert {:ok, updated_media_item} = VideoDownloader.download_for_media_item(media_item)
assert {:ok, updated_media_item} = MediaDownloader.download_for_media_item(media_item)
assert [["de", _], ["en", _] | _rest] = updated_media_item.subtitle_filepaths
end
test "it extracts the thumbnail_filepath", %{media_item: media_item} do
assert media_item.thumbnail_filepath == nil
assert {:ok, updated_media_item} = VideoDownloader.download_for_media_item(media_item)
assert {:ok, updated_media_item} = MediaDownloader.download_for_media_item(media_item)
assert String.ends_with?(updated_media_item.thumbnail_filepath, ".webp")
end
test "it extracts the metadata_filepath", %{media_item: media_item} do
assert media_item.metadata_filepath == nil
assert {:ok, updated_media_item} = VideoDownloader.download_for_media_item(media_item)
assert {:ok, updated_media_item} = MediaDownloader.download_for_media_item(media_item)
assert String.ends_with?(updated_media_item.metadata_filepath, ".info.json")
end
end

View file

@ -19,7 +19,7 @@ defmodule Pinchflat.Profiles.Options.YtDlp.DownloadOptionBuilderTest do
test "it generates an expanded output path based on the given template", %{media_item: media_item} do
assert {:ok, res} = DownloadOptionBuilder.build(media_item)
assert {:output, "/tmp/test/videos/%(title)S.%(ext)s"} in res
assert {:output, "/tmp/test/media/%(title)S.%(ext)s"} in res
end
test "it respects custom output path options", %{media_item: media_item} do
@ -28,7 +28,7 @@ defmodule Pinchflat.Profiles.Options.YtDlp.DownloadOptionBuilderTest do
assert {:ok, res} = DownloadOptionBuilder.build(media_item)
assert {:output, "/tmp/test/videos/#{media_item.source.custom_name}.%(ext)s"} in res
assert {:output, "/tmp/test/media/#{media_item.source.custom_name}.%(ext)s"} in res
end
end

View file

@ -10,7 +10,7 @@ defmodule Pinchflat.SourcesTest do
alias Pinchflat.Tasks.SourceTasks
alias Pinchflat.Sources.Source
alias Pinchflat.Workers.MediaIndexingWorker
alias Pinchflat.Workers.VideoDownloadWorker
alias Pinchflat.Workers.MediaDownloadWorker
@invalid_source_attrs %{name: nil, collection_id: nil}
@ -269,9 +269,9 @@ defmodule Pinchflat.SourcesTest do
media_item = media_item_fixture(source_id: source.id, media_filepath: nil)
update_attrs = %{download_media: true}
refute_enqueued(worker: VideoDownloadWorker)
refute_enqueued(worker: MediaDownloadWorker)
assert {:ok, %Source{}} = Sources.update_source(source, update_attrs)
assert_enqueued(worker: VideoDownloadWorker, args: %{"id" => media_item.id})
assert_enqueued(worker: MediaDownloadWorker, args: %{"id" => media_item.id})
end
test "disabling the download_media attribute will cancel the download task" do
@ -280,9 +280,9 @@ defmodule Pinchflat.SourcesTest do
update_attrs = %{download_media: false}
SourceTasks.enqueue_pending_media_tasks(source)
assert_enqueued(worker: VideoDownloadWorker, args: %{"id" => media_item.id})
assert_enqueued(worker: MediaDownloadWorker, args: %{"id" => media_item.id})
assert {:ok, %Source{}} = Sources.update_source(source, update_attrs)
refute_enqueued(worker: VideoDownloadWorker)
refute_enqueued(worker: MediaDownloadWorker)
end
test "updates with invalid data returns error changeset" do

View file

@ -12,7 +12,7 @@ defmodule Pinchflat.Tasks.SourceTasksTest do
alias Pinchflat.Tasks.SourceTasks
alias Pinchflat.Media.MediaItem
alias Pinchflat.Workers.MediaIndexingWorker
alias Pinchflat.Workers.VideoDownloadWorker
alias Pinchflat.Workers.MediaDownloadWorker
setup :verify_on_exit!
@ -116,7 +116,7 @@ defmodule Pinchflat.Tasks.SourceTasksTest do
SourceTasks.index_and_enqueue_download_for_media_items(source)
assert_enqueued(worker: VideoDownloadWorker, args: %{"id" => media_item.id})
assert_enqueued(worker: MediaDownloadWorker, args: %{"id" => media_item.id})
end
test "it does not attach tasks if the source is set to not download" do
@ -167,9 +167,9 @@ defmodule Pinchflat.Tasks.SourceTasksTest do
{:ok, ""}
end)
refute_enqueued(worker: VideoDownloadWorker)
refute_enqueued(worker: MediaDownloadWorker)
SourceTasks.index_and_enqueue_download_for_media_items(source)
assert_enqueued(worker: VideoDownloadWorker)
assert_enqueued(worker: MediaDownloadWorker)
end
test "does not enqueue downloads if the source is set to not download" do
@ -188,7 +188,7 @@ defmodule Pinchflat.Tasks.SourceTasksTest do
end)
SourceTasks.index_and_enqueue_download_for_media_items(source)
refute_enqueued(worker: VideoDownloadWorker)
refute_enqueued(worker: MediaDownloadWorker)
end
test "does not enqueue downloads for media that doesn't match the profile's format options" do
@ -218,7 +218,26 @@ defmodule Pinchflat.Tasks.SourceTasksTest do
end)
SourceTasks.index_and_enqueue_download_for_media_items(source)
refute_enqueued(worker: VideoDownloadWorker)
refute_enqueued(worker: MediaDownloadWorker)
end
test "does not enqueue multiple download jobs for the same media items", %{source: source} do
watcher_poll_interval = Application.get_env(:pinchflat, :file_watcher_poll_interval)
stub(YtDlpRunnerMock, :run, fn _url, _opts, _ot, addl_opts ->
filepath = Keyword.get(addl_opts, :output_filepath)
File.write(filepath, source_attributes_return_fixture())
# Need to add a delay to ensure the file watcher has time to read the file
:timer.sleep(watcher_poll_interval * 2)
# This also returns the final result to the yt-dlp call (like the real usage actually would do)
# so it'll attempt to create the media items and enqueue the download jobs based on this as well
{:ok, source_attributes_return_fixture()}
end)
SourceTasks.index_and_enqueue_download_for_media_items(source)
assert Repo.aggregate(MediaItem, :count, :id) == 3
assert [_, _, _] = all_enqueued(worker: MediaDownloadWorker)
end
end
@ -229,7 +248,7 @@ defmodule Pinchflat.Tasks.SourceTasksTest do
assert :ok = SourceTasks.enqueue_pending_media_tasks(source)
assert_enqueued(worker: VideoDownloadWorker, args: %{"id" => media_item.id})
assert_enqueued(worker: MediaDownloadWorker, args: %{"id" => media_item.id})
end
test "it does not enqueue a job for media items with a filepath" do
@ -238,7 +257,7 @@ defmodule Pinchflat.Tasks.SourceTasksTest do
assert :ok = SourceTasks.enqueue_pending_media_tasks(source)
refute_enqueued(worker: VideoDownloadWorker)
refute_enqueued(worker: MediaDownloadWorker)
end
test "it attaches a task to each enqueued job" do
@ -257,7 +276,7 @@ defmodule Pinchflat.Tasks.SourceTasksTest do
assert :ok = SourceTasks.enqueue_pending_media_tasks(source)
refute_enqueued(worker: VideoDownloadWorker)
refute_enqueued(worker: MediaDownloadWorker)
end
test "it does not attach tasks if the source is set to not download" do
@ -275,11 +294,11 @@ defmodule Pinchflat.Tasks.SourceTasksTest do
media_item = media_item_fixture(source_id: source.id, media_filepath: nil)
SourceTasks.enqueue_pending_media_tasks(source)
assert_enqueued(worker: VideoDownloadWorker, args: %{"id" => media_item.id})
assert_enqueued(worker: MediaDownloadWorker, args: %{"id" => media_item.id})
assert :ok = SourceTasks.dequeue_pending_media_tasks(source)
refute_enqueued(worker: VideoDownloadWorker)
refute_enqueued(worker: MediaDownloadWorker)
assert [] = Tasks.list_tasks_for(:media_item_id, media_item.id)
end
end

View file

@ -1,11 +1,11 @@
defmodule Pinchflat.Workers.VideoDownloadWorkerTest do
defmodule Pinchflat.Workers.MediaDownloadWorkerTest do
use Pinchflat.DataCase
import Mox
import Pinchflat.MediaFixtures
alias Pinchflat.Sources
alias Pinchflat.Workers.VideoDownloadWorker
alias Pinchflat.Workers.MediaDownloadWorker
alias Pinchflat.Workers.FilesystemDataWorker
setup :verify_on_exit!
@ -31,7 +31,7 @@ defmodule Pinchflat.Workers.VideoDownloadWorkerTest do
end)
assert media_item.media_filepath == nil
perform_job(VideoDownloadWorker, %{id: media_item.id})
perform_job(MediaDownloadWorker, %{id: media_item.id})
assert Repo.reload(media_item).media_filepath != nil
end
@ -41,22 +41,22 @@ defmodule Pinchflat.Workers.VideoDownloadWorkerTest do
end)
assert media_item.metadata == nil
perform_job(VideoDownloadWorker, %{id: media_item.id})
perform_job(MediaDownloadWorker, %{id: media_item.id})
assert Repo.reload(media_item).metadata != nil
end
test "it won't double-schedule downloading jobs", %{media_item: media_item} do
Oban.insert(VideoDownloadWorker.new(%{id: media_item.id}))
Oban.insert(VideoDownloadWorker.new(%{id: media_item.id}))
Oban.insert(MediaDownloadWorker.new(%{id: media_item.id}))
Oban.insert(MediaDownloadWorker.new(%{id: media_item.id}))
assert [_] = all_enqueued(worker: VideoDownloadWorker)
assert [_] = all_enqueued(worker: MediaDownloadWorker)
end
test "it sets the job to retryable if the download fails", %{media_item: media_item} do
expect(YtDlpRunnerMock, :run, fn _url, _opts, _ot -> {:error, "error"} end)
Oban.Testing.with_testing_mode(:inline, fn ->
{:ok, job} = Oban.insert(VideoDownloadWorker.new(%{id: media_item.id}))
{:ok, job} = Oban.insert(MediaDownloadWorker.new(%{id: media_item.id}))
assert job.state == "retryable"
end)
@ -67,7 +67,7 @@ defmodule Pinchflat.Workers.VideoDownloadWorkerTest do
Sources.update_source(media_item.source, %{download_media: false})
perform_job(VideoDownloadWorker, %{id: media_item.id})
perform_job(MediaDownloadWorker, %{id: media_item.id})
end
test "it schedules a filesystem data worker", %{media_item: media_item} do
@ -77,7 +77,7 @@ defmodule Pinchflat.Workers.VideoDownloadWorkerTest do
assert [] = all_enqueued(worker: FilesystemDataWorker)
perform_job(VideoDownloadWorker, %{id: media_item.id})
perform_job(MediaDownloadWorker, %{id: media_item.id})
assert [_] = all_enqueued(worker: FilesystemDataWorker)
end

View file

@ -7,7 +7,7 @@ defmodule Pinchflat.Workers.MediaIndexingWorkerTest do
alias Pinchflat.Tasks
alias Pinchflat.Workers.MediaIndexingWorker
alias Pinchflat.Workers.VideoDownloadWorker
alias Pinchflat.Workers.MediaDownloadWorker
setup :verify_on_exit!
@ -53,7 +53,7 @@ defmodule Pinchflat.Workers.MediaIndexingWorkerTest do
source = source_fixture(index_frequency_minutes: 10)
perform_job(MediaIndexingWorker, %{id: source.id})
assert length(all_enqueued(worker: VideoDownloadWorker)) == 3
assert length(all_enqueued(worker: MediaDownloadWorker)) == 3
end
test "it starts a job for any pending media item even if it's from another run" do
@ -65,7 +65,7 @@ defmodule Pinchflat.Workers.MediaIndexingWorkerTest do
media_item_fixture(%{source_id: source.id, media_filepath: nil})
perform_job(MediaIndexingWorker, %{id: source.id})
assert length(all_enqueued(worker: VideoDownloadWorker)) == 4
assert length(all_enqueued(worker: MediaDownloadWorker)) == 4
end
test "it does not kick off a job for media items that could not be saved" do
@ -78,7 +78,7 @@ defmodule Pinchflat.Workers.MediaIndexingWorkerTest do
perform_job(MediaIndexingWorker, %{id: source.id})
# Only 3 jobs should be enqueued, since the first video is a duplicate
assert length(all_enqueued(worker: VideoDownloadWorker))
assert length(all_enqueued(worker: MediaDownloadWorker))
end
test "it reschedules the job based on the index frequency" do