[WIP] got all tests passing
This commit is contained in:
parent
6c19f096fb
commit
a202652c00
43 changed files with 219 additions and 321 deletions
9
.iex.exs
9
.iex.exs
|
|
@ -4,7 +4,6 @@ alias Pinchflat.Repo
|
|||
alias Pinchflat.Tasks.Task
|
||||
alias Pinchflat.Sources.Source
|
||||
alias Pinchflat.Media.MediaItem
|
||||
alias Pinchflat.Tasks.SourceTasks
|
||||
alias Pinchflat.Metadata.MediaMetadata
|
||||
alias Pinchflat.Profiles.MediaProfile
|
||||
|
||||
|
|
@ -14,14 +13,14 @@ alias Pinchflat.Profiles
|
|||
alias Pinchflat.Sources
|
||||
alias Pinchflat.Settings
|
||||
|
||||
alias Pinchflat.MediaClient.MediaDownloader
|
||||
alias Pinchflat.YtDlp.Backend.Media, as: YtDlpMedia
|
||||
alias Pinchflat.YtDlp.Backend.MediaCollection, as: YtDlpCollection
|
||||
alias Pinchflat.Downloading.MediaDownloader
|
||||
alias Pinchflat.YtDlp.Media, as: YtDlpMedia
|
||||
alias Pinchflat.YtDlp.MediaCollection, as: YtDlpCollection
|
||||
|
||||
alias Pinchflat.FastIndexing.YoutubeRss
|
||||
alias Pinchflat.Metadata.MetadataFileHelpers
|
||||
|
||||
alias Pinchflat.Utils.FilesystemUtils.FileFollowerServer
|
||||
alias Pinchflat.SlowIndexing.FileFollowerServer
|
||||
|
||||
defmodule IexHelpers do
|
||||
def playlist_url do
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ config :pinchflat,
|
|||
generators: [timestamp_type: :utc_datetime],
|
||||
# Specifying backend data here makes mocking and local testing SUPER easy
|
||||
yt_dlp_executable: System.find_executable("yt-dlp"),
|
||||
yt_dlp_runner: Pinchflat.YtDlp.Backend.CommandRunner,
|
||||
yt_dlp_runner: Pinchflat.YtDlp.CommandRunner,
|
||||
media_directory: "/downloads",
|
||||
# The user may or may not store metadata for their needs, but the app will always store its copy
|
||||
metadata_directory: "/config/metadata",
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ defmodule Pinchflat.Downloading.DownloadOptionBuilder do
|
|||
"""
|
||||
|
||||
alias Pinchflat.Media.MediaItem
|
||||
alias Pinchflat.Profiles.OutputPathBuilder
|
||||
alias Pinchflat.Downloading.OutputPathBuilder
|
||||
|
||||
@doc """
|
||||
Builds the options for yt-dlp to download media based on the given media's profile.
|
||||
|
|
|
|||
|
|
@ -3,18 +3,8 @@ defmodule Pinchflat.Downloading.DownloadingHelpers do
|
|||
|
||||
alias Pinchflat.Media
|
||||
alias Pinchflat.Tasks
|
||||
alias Pinchflat.Sources
|
||||
alias Pinchflat.Sources.Source
|
||||
alias Pinchflat.FastIndexing.YoutubeRss
|
||||
alias Pinchflat.Media.MediaItem
|
||||
alias Pinchflat.FastIndexing.FastIndexingWorker
|
||||
alias Pinchflat.Downloading.MediaDownloadWorker
|
||||
alias Pinchflat.FastIndexing.MediaIndexingWorker
|
||||
alias Pinchflat.YtDlp.Backend.MediaCollection
|
||||
alias Pinchflat.SlowIndexing.MediaCollectionIndexingWorker
|
||||
alias Pinchflat.Utils.FilesystemUtils.FileFollowerServer
|
||||
|
||||
alias Pinchflat.YtDlp.Backend.Media, as: YtDlpMedia
|
||||
|
||||
@doc """
|
||||
Starts tasks for downloading media for any of a sources _pending_ media items.
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@ defmodule Pinchflat.Downloading.MediaDownloadWorker do
|
|||
alias Pinchflat.Repo
|
||||
alias Pinchflat.Media
|
||||
alias Pinchflat.Tasks
|
||||
alias Pinchflat.MediaClient.MediaDownloader
|
||||
alias Pinchflat.Workers.FilesystemDataWorker
|
||||
alias Pinchflat.Downloading.MediaDownloader
|
||||
alias Pinchflat.Filesystem.FilesystemDataWorker
|
||||
|
||||
@impl Oban.Worker
|
||||
@doc """
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
defmodule Pinchflat.MediaClient.MediaDownloader do
|
||||
defmodule Pinchflat.Downloading.MediaDownloader do
|
||||
@moduledoc """
|
||||
This is the integration layer for actually downloading media.
|
||||
It takes into account the media profile's settings in order
|
||||
|
|
@ -9,7 +9,7 @@ defmodule Pinchflat.MediaClient.MediaDownloader do
|
|||
alias Pinchflat.Media
|
||||
alias Pinchflat.Media.MediaItem
|
||||
|
||||
alias Pinchflat.YtDlp.Backend.Media, as: YtDlpMedia
|
||||
alias Pinchflat.YtDlp.Media, as: YtDlpMedia
|
||||
alias Pinchflat.Downloading.DownloadOptionBuilder, as: YtDlpDownloadOptionBuilder
|
||||
alias Pinchflat.Metadata.MetadataParser, as: YtDlpMetadataParser
|
||||
alias Pinchflat.Metadata.MetadataFileHelpers, as: YtDlpMetadataHelpers
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
defmodule Pinchflat.RenderedString.Base do
|
||||
defmodule Pinchflat.Downloading.OutputPath.Base do
|
||||
@moduledoc """
|
||||
A base module for parsing rendered strings, designed as a macro to be used
|
||||
in other modules. See https://elixirforum.com/t/help-to-parse-a-template-with-nimbleparsec/47980
|
||||
|
|
@ -6,7 +6,7 @@ defmodule Pinchflat.RenderedString.Base do
|
|||
NOTE: if the needs here get any more complicated, look into using a Liquid
|
||||
template parser. No need to reinvent the wheel any more than I already have.
|
||||
|
||||
NOTE: this is effectively tested by the `Pinchflat.RenderedString.Parser`'s tests
|
||||
NOTE: this is effectively tested by the `Pinchflat.Downloading.OutputPath.Parser`'s tests
|
||||
"""
|
||||
|
||||
defmacro __using__(_opts) do
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
defmodule Pinchflat.RenderedString.Parser do
|
||||
defmodule Pinchflat.Downloading.OutputPath.Parser do
|
||||
@moduledoc """
|
||||
Parses liquid-ish-style strings into a rendered string
|
||||
|
||||
Used for turning filepath templates into real filepaths
|
||||
"""
|
||||
|
||||
use Pinchflat.RenderedString.Base
|
||||
use Pinchflat.Downloading.OutputPath.Base
|
||||
|
||||
@doc """
|
||||
Parses a string into a rendered string, using the provided variables. Optionally
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
defmodule Pinchflat.Profiles.OutputPathBuilder do
|
||||
defmodule Pinchflat.Downloading.OutputPathBuilder do
|
||||
@moduledoc """
|
||||
Builds yt-dlp-friendly output paths for downloaded media
|
||||
"""
|
||||
|
||||
alias Pinchflat.RenderedString.Parser, as: TemplateParser
|
||||
alias Pinchflat.Downloading.OutputPath.Parser, as: TemplateParser
|
||||
|
||||
@doc """
|
||||
Builds the actual final filepath from a given template. Optionally, you can pass in
|
||||
|
|
@ -1,16 +1,13 @@
|
|||
defmodule Pinchflat.FastIndexing.FastIndexingHelpers do
|
||||
alias Pinchflat.Media
|
||||
alias Pinchflat.Tasks
|
||||
alias Pinchflat.Sources
|
||||
alias Pinchflat.Sources.Source
|
||||
alias Pinchflat.FastIndexing.YoutubeRss
|
||||
alias Pinchflat.Media.MediaItem
|
||||
alias Pinchflat.FastIndexing.FastIndexingWorker
|
||||
alias Pinchflat.Downloading.MediaDownloadWorker
|
||||
alias Pinchflat.FastIndexing.MediaIndexingWorker
|
||||
alias Pinchflat.YtDlp.Backend.MediaCollection
|
||||
alias Pinchflat.SlowIndexing.MediaCollectionIndexingWorker
|
||||
alias Pinchflat.Utils.FilesystemUtils.FileFollowerServer
|
||||
|
||||
alias Pinchflat.YtDlp.Media, as: YtDlpMedia
|
||||
|
||||
@doc """
|
||||
Starts tasks for running a fast indexing task for a source's media
|
||||
|
|
@ -56,4 +53,36 @@ defmodule Pinchflat.FastIndexing.FastIndexingHelpers do
|
|||
|> Tasks.create_job_with_task(source)
|
||||
end)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Indexes a single media item for a source and enqueues a download job if the
|
||||
media should be downloaded. This method creates the media item record so it's
|
||||
the one-stop-shop for adding a media item (and possibly downloading it) just
|
||||
by a URL and source.
|
||||
|
||||
Returns {:ok, media_item} | {:error, any()}
|
||||
"""
|
||||
def index_and_enqueue_download_for_media_item(%Source{} = source, url) do
|
||||
maybe_media_item = create_media_item_from_url(source, url)
|
||||
|
||||
case maybe_media_item do
|
||||
{:ok, media_item} ->
|
||||
if source.download_media && Media.pending_download?(media_item) do
|
||||
%{id: media_item.id}
|
||||
|> MediaDownloadWorker.new()
|
||||
|> Tasks.create_job_with_task(media_item)
|
||||
end
|
||||
|
||||
{:ok, media_item}
|
||||
|
||||
err ->
|
||||
err
|
||||
end
|
||||
end
|
||||
|
||||
defp create_media_item_from_url(source, url) do
|
||||
{:ok, media_attrs} = YtDlpMedia.get_media_attributes(url)
|
||||
|
||||
Media.create_media_item_from_backend_attrs(source, media_attrs)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ defmodule Pinchflat.FastIndexing.MediaIndexingWorker do
|
|||
require Logger
|
||||
|
||||
alias Pinchflat.Sources
|
||||
alias Pinchflat.Tasks.MediaItemTasks
|
||||
alias Pinchflat.FastIndexing.FastIndexingHelpers
|
||||
|
||||
@impl Oban.Worker
|
||||
@doc """
|
||||
|
|
@ -42,7 +42,7 @@ defmodule Pinchflat.FastIndexing.MediaIndexingWorker do
|
|||
def perform(%Oban.Job{args: %{"id" => source_id, "media_url" => media_url}}) do
|
||||
source = Sources.get_source!(source_id)
|
||||
|
||||
case MediaItemTasks.index_and_enqueue_download_for_media_item(source, media_url) do
|
||||
case FastIndexingHelpers.index_and_enqueue_download_for_media_item(source, media_url) do
|
||||
{:ok, media_item} ->
|
||||
Logger.debug("Indexed and enqueued download for url: #{media_url} (media item: #{media_item.id})")
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
defmodule Pinchflat.Workers.FilesystemDataWorker do
|
||||
defmodule Pinchflat.Filesystem.FilesystemDataWorker do
|
||||
@moduledoc false
|
||||
|
||||
use Oban.Worker,
|
||||
|
|
@ -7,7 +7,7 @@ defmodule Pinchflat.Workers.FilesystemDataWorker do
|
|||
max_attempts: 1
|
||||
|
||||
alias Pinchflat.Media
|
||||
alias Pinchflat.Tasks.MediaItemTasks
|
||||
alias Pinchflat.Filesystem.FilesystemHelpers
|
||||
|
||||
@impl Oban.Worker
|
||||
@doc """
|
||||
|
|
@ -18,7 +18,7 @@ defmodule Pinchflat.Workers.FilesystemDataWorker do
|
|||
def perform(%Oban.Job{args: %{"id" => media_item_id}}) do
|
||||
media_item = Media.get_media_item!(media_item_id)
|
||||
|
||||
MediaItemTasks.compute_and_save_media_filesize(media_item)
|
||||
FilesystemHelpers.compute_and_save_media_filesize(media_item)
|
||||
|
||||
# Don't retry on failure - if it didn't work immediately there's no
|
||||
# reason to believe it will work later.
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
defmodule Pinchflat.Utils.FilesystemUtils do
|
||||
defmodule Pinchflat.Filesystem.FilesystemHelpers do
|
||||
@moduledoc """
|
||||
Utility methods for working with the filesystem
|
||||
"""
|
||||
|
||||
alias Pinchflat.Media
|
||||
alias Pinchflat.Utils.StringUtils
|
||||
|
||||
@doc """
|
||||
|
|
@ -20,4 +20,19 @@ defmodule Pinchflat.Utils.FilesystemUtils do
|
|||
|
||||
filepath
|
||||
end
|
||||
|
||||
@doc """
|
||||
Fetches the file size of a media item and saves it to the database.
|
||||
|
||||
Returns {:ok, media_item} | {:error, any()}
|
||||
"""
|
||||
def compute_and_save_media_filesize(media_item) do
|
||||
case File.stat(media_item.media_filepath) do
|
||||
{:ok, %{size: size}} ->
|
||||
Media.update_media_item(media_item, %{media_size_bytes: size})
|
||||
|
||||
err ->
|
||||
err
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
defmodule Pinchflat.Utils.FilesystemUtils.FileFollowerServer do
|
||||
defmodule Pinchflat.SlowIndexing.FileFollowerServer do
|
||||
@moduledoc """
|
||||
A GenServer that watches a file for new lines and processes them as they come in.
|
||||
This is useful for tailing log files and other similar tasks. If there's no activity
|
||||
|
|
@ -10,7 +10,6 @@ defmodule Pinchflat.SlowIndexing.MediaCollectionIndexingWorker do
|
|||
alias Pinchflat.Tasks
|
||||
alias Pinchflat.Sources
|
||||
alias Pinchflat.Sources.Source
|
||||
alias Pinchflat.Tasks.SourceTasks
|
||||
alias Pinchflat.FastIndexing.FastIndexingWorker
|
||||
alias Pinchflat.SlowIndexing.SlowIndexingHelpers
|
||||
|
||||
|
|
|
|||
|
|
@ -5,17 +5,14 @@ defmodule Pinchflat.SlowIndexing.SlowIndexingHelpers do
|
|||
alias Pinchflat.Tasks
|
||||
alias Pinchflat.Sources
|
||||
alias Pinchflat.Sources.Source
|
||||
alias Pinchflat.FastIndexing.YoutubeRss
|
||||
alias Pinchflat.Media.MediaItem
|
||||
alias Pinchflat.FastIndexing.FastIndexingWorker
|
||||
alias Pinchflat.Downloading.MediaDownloadWorker
|
||||
alias Pinchflat.FastIndexing.MediaIndexingWorker
|
||||
alias Pinchflat.YtDlp.Backend.MediaCollection
|
||||
alias Pinchflat.SlowIndexing.MediaCollectionIndexingWorker
|
||||
alias Pinchflat.Utils.FilesystemUtils.FileFollowerServer
|
||||
alias Pinchflat.YtDlp.MediaCollection
|
||||
alias Pinchflat.Downloading.DownloadingHelpers
|
||||
alias Pinchflat.SlowIndexing.FileFollowerServer
|
||||
alias Pinchflat.Downloading.MediaDownloadWorker
|
||||
alias Pinchflat.SlowIndexing.MediaCollectionIndexingWorker
|
||||
|
||||
alias Pinchflat.YtDlp.Backend.Media, as: YtDlpMedia
|
||||
alias Pinchflat.YtDlp.Media, as: YtDlpMedia
|
||||
|
||||
@doc """
|
||||
Starts tasks for indexing a source's media regardless of the source's indexing
|
||||
|
|
|
|||
|
|
@ -9,9 +9,8 @@ defmodule Pinchflat.Sources do
|
|||
alias Pinchflat.Media
|
||||
alias Pinchflat.Tasks
|
||||
alias Pinchflat.Sources.Source
|
||||
alias Pinchflat.Tasks.SourceTasks
|
||||
alias Pinchflat.Profiles.MediaProfile
|
||||
alias Pinchflat.YtDlp.Backend.MediaCollection
|
||||
alias Pinchflat.YtDlp.MediaCollection
|
||||
alias Pinchflat.Downloading.DownloadingHelpers
|
||||
alias Pinchflat.FastIndexing.FastIndexingHelpers
|
||||
alias Pinchflat.SlowIndexing.SlowIndexingHelpers
|
||||
|
|
|
|||
|
|
@ -1,61 +0,0 @@
|
|||
defmodule Pinchflat.Tasks.MediaItemTasks do
|
||||
@moduledoc """
|
||||
Contains methods used by OR used to create/manage tasks for media items.
|
||||
|
||||
Tasks/workers are meant to be thin wrappers so most of the actual work they
|
||||
do is also defined here. Essentially, a one-stop-shop for media-related tasks/workers.
|
||||
"""
|
||||
alias Pinchflat.Media
|
||||
alias Pinchflat.Tasks
|
||||
alias Pinchflat.Sources.Source
|
||||
alias Pinchflat.Downloading.MediaDownloadWorker
|
||||
|
||||
alias Pinchflat.YtDlp.Backend.Media, as: YtDlpMedia
|
||||
|
||||
@doc """
|
||||
Fetches the file size of a media item and saves it to the database.
|
||||
|
||||
Returns {:ok, media_item} | {:error, any()}
|
||||
"""
|
||||
def compute_and_save_media_filesize(media_item) do
|
||||
case File.stat(media_item.media_filepath) do
|
||||
{:ok, %{size: size}} ->
|
||||
Media.update_media_item(media_item, %{media_size_bytes: size})
|
||||
|
||||
err ->
|
||||
err
|
||||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
Indexes a single media item for a source and enqueues a download job if the
|
||||
media should be downloaded. This method creates the media item record so it's
|
||||
the one-stop-shop for adding a media item (and possibly downloading it) just
|
||||
by a URL and source.
|
||||
|
||||
Returns {:ok, media_item} | {:error, any()}
|
||||
"""
|
||||
def index_and_enqueue_download_for_media_item(%Source{} = source, url) do
|
||||
maybe_media_item = create_media_item_from_url(source, url)
|
||||
|
||||
case maybe_media_item do
|
||||
{:ok, media_item} ->
|
||||
if source.download_media && Media.pending_download?(media_item) do
|
||||
%{id: media_item.id}
|
||||
|> MediaDownloadWorker.new()
|
||||
|> Tasks.create_job_with_task(media_item)
|
||||
end
|
||||
|
||||
{:ok, media_item}
|
||||
|
||||
err ->
|
||||
err
|
||||
end
|
||||
end
|
||||
|
||||
defp create_media_item_from_url(source, url) do
|
||||
{:ok, media_attrs} = YtDlpMedia.get_media_attributes(url)
|
||||
|
||||
Media.create_media_item_from_backend_attrs(source, media_attrs)
|
||||
end
|
||||
end
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
defmodule Pinchflat.Tasks.SourceTasks do
|
||||
@moduledoc """
|
||||
Contains methods used by OR used to create/manage tasks for sources.
|
||||
|
||||
Tasks/workers are meant to be thin wrappers so most of the actual work they
|
||||
do is also defined here. Essentially, a one-stop-shop for source-related tasks/workers.
|
||||
"""
|
||||
|
||||
require Logger
|
||||
|
||||
# alias Pinchflat.Media
|
||||
# alias Pinchflat.Tasks
|
||||
# alias Pinchflat.Sources
|
||||
# alias Pinchflat.Sources.Source
|
||||
# alias Pinchflat.FastIndexing.YoutubeRss
|
||||
# alias Pinchflat.Media.MediaItem
|
||||
# alias Pinchflat.FastIndexing.FastIndexingWorker
|
||||
# alias Pinchflat.Downloading.MediaDownloadWorker
|
||||
# alias Pinchflat.FastIndexing.MediaIndexingWorker
|
||||
# alias Pinchflat.YtDlp.Backend.MediaCollection
|
||||
# alias Pinchflat.SlowIndexing.MediaCollectionIndexingWorker
|
||||
# alias Pinchflat.Utils.FilesystemUtils.FileFollowerServer
|
||||
|
||||
# alias Pinchflat.YtDlp.Backend.Media, as: YtDlpMedia
|
||||
end
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
defmodule Pinchflat.YtDlp.Backend.BackendCommandRunner do
|
||||
defmodule Pinchflat.YtDlp.BackendCommandRunner do
|
||||
@moduledoc """
|
||||
A behaviour for running CLI commands against a downloader backend (yt-dlp).
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
defmodule Pinchflat.YtDlp.Backend.CommandRunner do
|
||||
defmodule Pinchflat.YtDlp.CommandRunner do
|
||||
@moduledoc """
|
||||
Runs yt-dlp commands using the `System.cmd/3` function
|
||||
"""
|
||||
|
|
@ -6,8 +6,8 @@ defmodule Pinchflat.YtDlp.Backend.CommandRunner do
|
|||
require Logger
|
||||
|
||||
alias Pinchflat.Utils.StringUtils
|
||||
alias Pinchflat.Utils.FilesystemUtils, as: FSUtils
|
||||
alias Pinchflat.YtDlp.Backend.BackendCommandRunner
|
||||
alias Pinchflat.Filesystem.FilesystemHelpers, as: FSUtils
|
||||
alias Pinchflat.YtDlp.BackendCommandRunner
|
||||
|
||||
@behaviour BackendCommandRunner
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
defmodule Pinchflat.YtDlp.Backend.Media do
|
||||
defmodule Pinchflat.YtDlp.Media do
|
||||
@moduledoc """
|
||||
Contains utilities for working with singular pieces of media
|
||||
"""
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
defmodule Pinchflat.YtDlp.Backend.MediaCollection do
|
||||
defmodule Pinchflat.YtDlp.MediaCollection do
|
||||
@moduledoc """
|
||||
Contains utilities for working with collections of
|
||||
media (aka: a source [ie: channels, playlists]).
|
||||
|
|
@ -7,8 +7,8 @@ defmodule Pinchflat.YtDlp.Backend.MediaCollection do
|
|||
require Logger
|
||||
|
||||
alias Pinchflat.Utils.FunctionUtils
|
||||
alias Pinchflat.Utils.FilesystemUtils
|
||||
alias Pinchflat.YtDlp.Backend.Media, as: YtDlpMedia
|
||||
alias Pinchflat.Filesystem.FilesystemHelpers
|
||||
alias Pinchflat.YtDlp.Media, as: YtDlpMedia
|
||||
|
||||
@doc """
|
||||
Returns a list of maps representing the media in the collection.
|
||||
|
|
@ -24,7 +24,7 @@ defmodule Pinchflat.YtDlp.Backend.MediaCollection do
|
|||
runner = Application.get_env(:pinchflat, :yt_dlp_runner)
|
||||
command_opts = [:simulate, :skip_download]
|
||||
output_template = YtDlpMedia.indexing_output_template()
|
||||
output_filepath = FilesystemUtils.generate_metadata_tmpfile(:json)
|
||||
output_filepath = FilesystemHelpers.generate_metadata_tmpfile(:json)
|
||||
file_listener_handler = Keyword.get(addl_opts, :file_listener_handler, false)
|
||||
|
||||
if file_listener_handler do
|
||||
|
|
@ -4,7 +4,7 @@ defmodule Pinchflat.Boot.DataBackfillWorkerTest do
|
|||
import Pinchflat.MediaFixtures
|
||||
|
||||
alias Pinchflat.Boot.DataBackfillWorker
|
||||
alias Pinchflat.Workers.FilesystemDataWorker
|
||||
alias Pinchflat.Filesystem.FilesystemDataWorker
|
||||
|
||||
describe "cancel_pending_backfill_jobs/0" do
|
||||
test "cancels all pending backfill jobs" do
|
||||
|
|
|
|||
|
|
@ -2,20 +2,12 @@ defmodule Pinchflat.Downloading.DownloadingHelpersTest do
|
|||
use Pinchflat.DataCase
|
||||
|
||||
import Mox
|
||||
import Pinchflat.TasksFixtures
|
||||
import Pinchflat.MediaFixtures
|
||||
import Pinchflat.SourcesFixtures
|
||||
import Pinchflat.ProfilesFixtures
|
||||
|
||||
alias Pinchflat.Tasks
|
||||
alias Pinchflat.Tasks.Task
|
||||
alias Pinchflat.Media.MediaItem
|
||||
alias Pinchflat.FastIndexing.FastIndexingWorker
|
||||
alias Pinchflat.Downloading.MediaDownloadWorker
|
||||
alias Pinchflat.FastIndexing.MediaIndexingWorker
|
||||
alias Pinchflat.SlowIndexing.SlowIndexingHelpers
|
||||
alias Pinchflat.SlowIndexing.MediaCollectionIndexingWorker
|
||||
alias Pinchflat.Downloading.DownloadingHelpers
|
||||
alias Pinchflat.Downloading.MediaDownloadWorker
|
||||
|
||||
setup :verify_on_exit!
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ defmodule Pinchflat.Downloading.MediaDownloadWorkerTest do
|
|||
|
||||
alias Pinchflat.Sources
|
||||
alias Pinchflat.Downloading.MediaDownloadWorker
|
||||
alias Pinchflat.Workers.FilesystemDataWorker
|
||||
alias Pinchflat.Filesystem.FilesystemDataWorker
|
||||
|
||||
setup :verify_on_exit!
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
defmodule Pinchflat.MediaClient.MediaDownloaderTest do
|
||||
defmodule Pinchflat.Downloading.MediaDownloaderTest do
|
||||
use Pinchflat.DataCase
|
||||
import Mox
|
||||
import Pinchflat.MediaFixtures
|
||||
|
||||
alias Pinchflat.MediaClient.MediaDownloader
|
||||
alias Pinchflat.Downloading.MediaDownloader
|
||||
|
||||
setup :verify_on_exit!
|
||||
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
defmodule Pinchflat.RenderedString.ParserTest do
|
||||
defmodule Pinchflat.Downloading.OutputPath.ParserTest do
|
||||
use ExUnit.Case, async: true
|
||||
|
||||
alias Pinchflat.RenderedString.Parser
|
||||
alias Pinchflat.Downloading.OutputPath.Parser
|
||||
|
||||
describe "parse/3" do
|
||||
test "it returns the rendered string when the string is valid" do
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
defmodule Pinchflat.Profiles.OutputPathBuilderTest do
|
||||
defmodule Pinchflat.Downloading.OutputPathBuilderTest do
|
||||
use Pinchflat.DataCase
|
||||
|
||||
alias Pinchflat.Profiles.OutputPathBuilder
|
||||
alias Pinchflat.Downloading.OutputPathBuilder
|
||||
|
||||
describe "build/2" do
|
||||
test "it expands 'standard' curly brace variables in the template" do
|
||||
|
|
@ -9,16 +9,16 @@ defmodule Pinchflat.FastIndexing.FastIndexingHelpersTest do
|
|||
|
||||
alias Pinchflat.Tasks
|
||||
alias Pinchflat.Tasks.Task
|
||||
alias Pinchflat.Tasks.SourceTasks
|
||||
alias Pinchflat.Media.MediaItem
|
||||
alias Pinchflat.Downloading.MediaDownloadWorker
|
||||
alias Pinchflat.FastIndexing.MediaIndexingWorker
|
||||
alias Pinchflat.FastIndexing.FastIndexingHelpers
|
||||
alias Pinchflat.FastIndexing.FastIndexingWorker
|
||||
alias Pinchflat.SlowIndexing.MediaCollectionIndexingWorker
|
||||
|
||||
setup :verify_on_exit!
|
||||
|
||||
@media_url "https://www.youtube.com/watch?v=test_1"
|
||||
|
||||
describe "kickoff_fast_indexing_task/1" do
|
||||
test "it schedules a job" do
|
||||
source = source_fixture()
|
||||
|
|
@ -71,4 +71,72 @@ defmodule Pinchflat.FastIndexing.FastIndexingHelpersTest do
|
|||
refute_enqueued(worker: MediaIndexingWorker)
|
||||
end
|
||||
end
|
||||
|
||||
describe "index_and_enqueue_download_for_media_item/2" do
|
||||
setup do
|
||||
stub(YtDlpRunnerMock, :run, fn _url, _opts, _ot ->
|
||||
{:ok, media_attributes_return_fixture()}
|
||||
end)
|
||||
|
||||
{:ok, [source: source_fixture()]}
|
||||
end
|
||||
|
||||
test "creates a new media item based on the URL", %{source: source} do
|
||||
assert Repo.aggregate(MediaItem, :count) == 0
|
||||
assert {:ok, _} = FastIndexingHelpers.index_and_enqueue_download_for_media_item(source, @media_url)
|
||||
assert Repo.aggregate(MediaItem, :count) == 1
|
||||
end
|
||||
|
||||
test "won't duplicate media_items based on media_id and source", %{source: source} do
|
||||
assert {:ok, mi_1} = FastIndexingHelpers.index_and_enqueue_download_for_media_item(source, @media_url)
|
||||
assert {:ok, mi_2} = FastIndexingHelpers.index_and_enqueue_download_for_media_item(source, @media_url)
|
||||
|
||||
assert Repo.aggregate(MediaItem, :count) == 1
|
||||
assert mi_1.id == mi_2.id
|
||||
end
|
||||
|
||||
test "enqueues a download job", %{source: source} do
|
||||
assert {:ok, media_item} = FastIndexingHelpers.index_and_enqueue_download_for_media_item(source, @media_url)
|
||||
|
||||
assert_enqueued(worker: MediaDownloadWorker, args: %{"id" => media_item.id})
|
||||
end
|
||||
|
||||
test "creates a download task record", %{source: source} do
|
||||
assert {:ok, media_item} = FastIndexingHelpers.index_and_enqueue_download_for_media_item(source, @media_url)
|
||||
|
||||
assert [_] = Tasks.list_tasks_for(:media_item_id, media_item.id, "MediaDownloadWorker")
|
||||
end
|
||||
|
||||
test "does not enqueue a download job if the source does not allow it" do
|
||||
source = source_fixture(%{download_media: false})
|
||||
|
||||
assert {:ok, _} = FastIndexingHelpers.index_and_enqueue_download_for_media_item(source, @media_url)
|
||||
|
||||
refute_enqueued(worker: MediaDownloadWorker)
|
||||
end
|
||||
|
||||
test "does not enqueue a download job if the media item does not match the format rules" do
|
||||
profile = media_profile_fixture(%{shorts_behaviour: :exclude})
|
||||
source = source_fixture(%{media_profile_id: profile.id})
|
||||
|
||||
stub(YtDlpRunnerMock, :run, fn _url, _opts, _ot ->
|
||||
output =
|
||||
Phoenix.json_library().encode!(%{
|
||||
id: "video2",
|
||||
title: "Video 2",
|
||||
webpage_url: "https://example.com/shorts/video2",
|
||||
was_live: true,
|
||||
description: "desc2",
|
||||
aspect_ratio: 1.67,
|
||||
duration: 345.67,
|
||||
upload_date: "20210101"
|
||||
})
|
||||
|
||||
{:ok, output}
|
||||
end)
|
||||
|
||||
assert {:ok, _media_item} = FastIndexingHelpers.index_and_enqueue_download_for_media_item(source, @media_url)
|
||||
refute_enqueued(worker: MediaDownloadWorker)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
defmodule Pinchflat.Workers.FilesystemDataWorkerTest do
|
||||
defmodule Pinchflat.Filesystem.FilesystemDataWorkerTest do
|
||||
use Pinchflat.DataCase
|
||||
|
||||
import Pinchflat.MediaFixtures
|
||||
|
||||
alias Pinchflat.Workers.FilesystemDataWorker
|
||||
alias Pinchflat.Filesystem.FilesystemDataWorker
|
||||
|
||||
describe "perform/1" do
|
||||
test "Computes and stores the media file size" do
|
||||
36
test/pinchflat/filesystem/filesystem_helpers_test.exs
Normal file
36
test/pinchflat/filesystem/filesystem_helpers_test.exs
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
defmodule Pinchflat.Filesystem.FilesystemHelpersTest do
|
||||
use Pinchflat.DataCase
|
||||
|
||||
import Pinchflat.MediaFixtures
|
||||
|
||||
alias Pinchflat.Filesystem.FilesystemHelpers
|
||||
|
||||
describe "generate_metadata_tmpfile/1" do
|
||||
test "creates a tmpfile and returns its path" do
|
||||
res = FilesystemHelpers.generate_metadata_tmpfile(:json)
|
||||
|
||||
assert String.ends_with?(res, ".json")
|
||||
assert File.exists?(res)
|
||||
|
||||
File.rm!(res)
|
||||
end
|
||||
end
|
||||
|
||||
describe "compute_and_save_media_filesize/1" do
|
||||
test "updates the media item with the file size" do
|
||||
media_item = media_item_with_attachments()
|
||||
|
||||
refute media_item.media_size_bytes
|
||||
|
||||
assert {:ok, media_item} = FilesystemHelpers.compute_and_save_media_filesize(media_item)
|
||||
|
||||
assert Repo.reload!(media_item).media_size_bytes
|
||||
end
|
||||
|
||||
test "returns the error if operation fails" do
|
||||
media_item = media_item_fixture(%{media_filepath: "/nonexistent/file.mkv"})
|
||||
|
||||
assert {:error, _} = FilesystemHelpers.compute_and_save_media_filesize(media_item)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -11,7 +11,7 @@ defmodule Pinchflat.MediaTest do
|
|||
alias Pinchflat.Media.MediaItem
|
||||
alias Pinchflat.Metadata.MetadataFileHelpers
|
||||
|
||||
alias Pinchflat.YtDlp.Backend.Media, as: YtDlpMedia
|
||||
alias Pinchflat.YtDlp.Media, as: YtDlpMedia
|
||||
|
||||
setup :verify_on_exit!
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
defmodule Pinchflat.YtDlp.Backend.MediaParserTest do
|
||||
defmodule Pinchflat.YtDlp.MediaParserTest do
|
||||
use Pinchflat.DataCase
|
||||
|
||||
alias Pinchflat.Metadata.MetadataParser, as: Parser
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
defmodule Pinchflat.Utils.FilesystemUtils.FileFollowerServerTest do
|
||||
defmodule Pinchflat.SlowIndexing.FileFollowerServerTest do
|
||||
use ExUnit.Case, async: true
|
||||
|
||||
alias alias Pinchflat.Utils.FilesystemUtils
|
||||
alias Pinchflat.Utils.FilesystemUtils.FileFollowerServer
|
||||
alias alias Pinchflat.Filesystem.FilesystemHelpers
|
||||
alias Pinchflat.SlowIndexing.FileFollowerServer
|
||||
|
||||
setup do
|
||||
{:ok, pid} = FileFollowerServer.start_link()
|
||||
tmpfile = FilesystemUtils.generate_metadata_tmpfile(:txt)
|
||||
tmpfile = FilesystemHelpers.generate_metadata_tmpfile(:txt)
|
||||
|
||||
{:ok, %{pid: pid, tmpfile: tmpfile}}
|
||||
end
|
||||
|
|
@ -7,7 +7,6 @@ defmodule Pinchflat.SourcesTest do
|
|||
import Pinchflat.SourcesFixtures
|
||||
|
||||
alias Pinchflat.Sources
|
||||
alias Pinchflat.Tasks.SourceTasks
|
||||
alias Pinchflat.Sources.Source
|
||||
alias Pinchflat.Downloading.DownloadingHelpers
|
||||
alias Pinchflat.FastIndexing.FastIndexingWorker
|
||||
|
|
|
|||
|
|
@ -1,103 +0,0 @@
|
|||
defmodule Pinchflat.Tasks.MediaItemTasksTest do
|
||||
use Pinchflat.DataCase
|
||||
|
||||
import Mox
|
||||
import Pinchflat.MediaFixtures
|
||||
import Pinchflat.SourcesFixtures
|
||||
import Pinchflat.ProfilesFixtures
|
||||
|
||||
alias Pinchflat.Tasks
|
||||
alias Pinchflat.Media.MediaItem
|
||||
alias Pinchflat.Tasks.MediaItemTasks
|
||||
alias Pinchflat.Downloading.MediaDownloadWorker
|
||||
|
||||
setup :verify_on_exit!
|
||||
|
||||
@media_url "https://www.youtube.com/watch?v=1234"
|
||||
|
||||
describe "compute_and_save_media_filesize/1" do
|
||||
test "updates the media item with the file size" do
|
||||
media_item = media_item_with_attachments()
|
||||
|
||||
refute media_item.media_size_bytes
|
||||
|
||||
assert {:ok, media_item} = MediaItemTasks.compute_and_save_media_filesize(media_item)
|
||||
|
||||
assert Repo.reload!(media_item).media_size_bytes
|
||||
end
|
||||
|
||||
test "returns the error if operation fails" do
|
||||
media_item = media_item_fixture(%{media_filepath: "/nonexistent/file.mkv"})
|
||||
|
||||
assert {:error, _} = MediaItemTasks.compute_and_save_media_filesize(media_item)
|
||||
end
|
||||
end
|
||||
|
||||
describe "index_and_enqueue_download_for_media_item/2" do
|
||||
setup do
|
||||
stub(YtDlpRunnerMock, :run, fn _url, _opts, _ot ->
|
||||
{:ok, media_attributes_return_fixture()}
|
||||
end)
|
||||
|
||||
{:ok, [source: source_fixture()]}
|
||||
end
|
||||
|
||||
test "creates a new media item based on the URL", %{source: source} do
|
||||
assert Repo.aggregate(MediaItem, :count) == 0
|
||||
assert {:ok, _} = MediaItemTasks.index_and_enqueue_download_for_media_item(source, @media_url)
|
||||
assert Repo.aggregate(MediaItem, :count) == 1
|
||||
end
|
||||
|
||||
test "won't duplicate media_items based on media_id and source", %{source: source} do
|
||||
assert {:ok, mi_1} = MediaItemTasks.index_and_enqueue_download_for_media_item(source, @media_url)
|
||||
assert {:ok, mi_2} = MediaItemTasks.index_and_enqueue_download_for_media_item(source, @media_url)
|
||||
|
||||
assert Repo.aggregate(MediaItem, :count) == 1
|
||||
assert mi_1.id == mi_2.id
|
||||
end
|
||||
|
||||
test "enqueues a download job", %{source: source} do
|
||||
assert {:ok, media_item} = MediaItemTasks.index_and_enqueue_download_for_media_item(source, @media_url)
|
||||
|
||||
assert_enqueued(worker: MediaDownloadWorker, args: %{"id" => media_item.id})
|
||||
end
|
||||
|
||||
test "creates a download task record", %{source: source} do
|
||||
assert {:ok, media_item} = MediaItemTasks.index_and_enqueue_download_for_media_item(source, @media_url)
|
||||
|
||||
assert [_] = Tasks.list_tasks_for(:media_item_id, media_item.id, "MediaDownloadWorker")
|
||||
end
|
||||
|
||||
test "does not enqueue a download job if the source does not allow it" do
|
||||
source = source_fixture(%{download_media: false})
|
||||
|
||||
assert {:ok, _} = MediaItemTasks.index_and_enqueue_download_for_media_item(source, @media_url)
|
||||
|
||||
refute_enqueued(worker: MediaDownloadWorker)
|
||||
end
|
||||
|
||||
test "does not enqueue a download job if the media item does not match the format rules" do
|
||||
profile = media_profile_fixture(%{shorts_behaviour: :exclude})
|
||||
source = source_fixture(%{media_profile_id: profile.id})
|
||||
|
||||
stub(YtDlpRunnerMock, :run, fn _url, _opts, _ot ->
|
||||
output =
|
||||
Phoenix.json_library().encode!(%{
|
||||
id: "video2",
|
||||
title: "Video 2",
|
||||
webpage_url: "https://example.com/shorts/video2",
|
||||
was_live: true,
|
||||
description: "desc2",
|
||||
aspect_ratio: 1.67,
|
||||
duration: 345.67,
|
||||
upload_date: "20210101"
|
||||
})
|
||||
|
||||
{:ok, output}
|
||||
end)
|
||||
|
||||
assert {:ok, _media_item} = MediaItemTasks.index_and_enqueue_download_for_media_item(source, @media_url)
|
||||
refute_enqueued(worker: MediaDownloadWorker)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
defmodule Pinchflat.Tasks.SourceTasksTest do
|
||||
use Pinchflat.DataCase
|
||||
|
||||
import Mox
|
||||
import Pinchflat.TasksFixtures
|
||||
import Pinchflat.MediaFixtures
|
||||
import Pinchflat.SourcesFixtures
|
||||
import Pinchflat.ProfilesFixtures
|
||||
|
||||
alias Pinchflat.Tasks
|
||||
alias Pinchflat.Tasks.Task
|
||||
alias Pinchflat.Tasks.SourceTasks
|
||||
alias Pinchflat.Media.MediaItem
|
||||
alias Pinchflat.FastIndexing.FastIndexingWorker
|
||||
alias Pinchflat.Downloading.MediaDownloadWorker
|
||||
alias Pinchflat.FastIndexing.MediaIndexingWorker
|
||||
alias Pinchflat.SlowIndexing.MediaCollectionIndexingWorker
|
||||
|
||||
setup :verify_on_exit!
|
||||
end
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
defmodule Pinchflat.Utils.FilesystemUtilsTest do
|
||||
use ExUnit.Case, async: true
|
||||
|
||||
alias Pinchflat.Utils.FilesystemUtils
|
||||
|
||||
describe "generate_metadata_tmpfile/1" do
|
||||
test "creates a tmpfile and returns its path" do
|
||||
res = FilesystemUtils.generate_metadata_tmpfile(:json)
|
||||
|
||||
assert String.ends_with?(res, ".json")
|
||||
assert File.exists?(res)
|
||||
|
||||
File.rm!(res)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
defmodule Pinchflat.YtDlp.Backend.CommandRunnerTest do
|
||||
defmodule Pinchflat.YtDlp.CommandRunnerTest do
|
||||
use ExUnit.Case, async: true
|
||||
|
||||
alias Pinchflat.YtDlp.Backend.CommandRunner, as: Runner
|
||||
alias Pinchflat.YtDlp.CommandRunner, as: Runner
|
||||
|
||||
@original_executable Application.compile_env(:pinchflat, :yt_dlp_executable)
|
||||
@media_url "https://www.youtube.com/watch?v=-LHXuyzpex0"
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
defmodule Pinchflat.YtDlp.Backend.MediaCollectionTest do
|
||||
defmodule Pinchflat.YtDlp.MediaCollectionTest do
|
||||
use Pinchflat.DataCase
|
||||
import Mox
|
||||
import Pinchflat.SourcesFixtures
|
||||
|
||||
alias Pinchflat.YtDlp.Backend.Media
|
||||
alias Pinchflat.YtDlp.Backend.MediaCollection
|
||||
alias Pinchflat.YtDlp.Media
|
||||
alias Pinchflat.YtDlp.MediaCollection
|
||||
|
||||
@channel_url "https://www.youtube.com/c/TheUselessTrials"
|
||||
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
defmodule Pinchflat.YtDlp.Backend.MediaTest do
|
||||
defmodule Pinchflat.YtDlp.MediaTest do
|
||||
use Pinchflat.DataCase
|
||||
import Mox
|
||||
import Pinchflat.MediaFixtures
|
||||
|
||||
alias Pinchflat.YtDlp.Backend.Media
|
||||
alias Pinchflat.YtDlp.Media
|
||||
|
||||
@media_url "https://www.youtube.com/watch?v=TiZPUDkDYbk"
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
Mox.defmock(YtDlpRunnerMock, for: Pinchflat.YtDlp.Backend.BackendCommandRunner)
|
||||
Mox.defmock(YtDlpRunnerMock, for: Pinchflat.YtDlp.BackendCommandRunner)
|
||||
Application.put_env(:pinchflat, :yt_dlp_runner, YtDlpRunnerMock)
|
||||
|
||||
Mox.defmock(HTTPClientMock, for: Pinchflat.HTTP.HTTPBehaviour)
|
||||
|
|
|
|||
Loading…
Reference in a new issue