Skip to content

Commit

Permalink
Adds option on sources to not download media (index only)
Browse files Browse the repository at this point in the history
  • Loading branch information
kieraneglin committed Feb 6, 2024
1 parent af5e6cb commit ac19f32
Show file tree
Hide file tree
Showing 10 changed files with 70 additions and 12 deletions.
4 changes: 4 additions & 0 deletions lib/pinchflat/media_client/video_downloader.ex
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ defmodule Pinchflat.MediaClient.VideoDownloader do
returned by the backend. Also saves the entire metadata response to the associated
media_metadata record.
NOTE: related methods (like the download worker) won't download if the source is set
to not download media. However, I'm not enforcing that here since I need this for testing.
This may change in the future but I'm not stressed.
Returns {:ok, %MediaItem{}} | {:error, any, ...any}
"""
def download_for_media_item(%MediaItem{} = media_item, backend \\ :yt_dlp) do
Expand Down
2 changes: 2 additions & 0 deletions lib/pinchflat/media_source/source.ex
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ defmodule Pinchflat.MediaSource.Source do
collection_type
friendly_name
index_frequency_minutes
download_media
original_url
media_profile_id
)a
Expand All @@ -27,6 +28,7 @@ defmodule Pinchflat.MediaSource.Source do
field :collection_id, :string
field :collection_type, Ecto.Enum, values: [:channel, :playlist]
field :index_frequency_minutes, :integer, default: 60 * 24
field :download_media, :boolean, default: true
# This should only be used for user reference going forward
# as the collection_id should be used for all API calls
field :original_url, :string
Expand Down
7 changes: 6 additions & 1 deletion lib/pinchflat/tasks/source_tasks.ex
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ defmodule Pinchflat.Tasks.SourceTasks do

@doc """
Starts tasks for downloading videos 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,
not just the ones that were indexed in this job run. This should ensure
Expand All @@ -45,7 +46,7 @@ defmodule Pinchflat.Tasks.SourceTasks do
Returns :ok
"""
def enqueue_pending_media_downloads(%Source{} = source) do
def enqueue_pending_media_downloads(%Source{download_media: true} = source) do
source
|> Media.list_pending_media_items_for()
|> Enum.each(fn media_item ->
Expand All @@ -55,4 +56,8 @@ defmodule Pinchflat.Tasks.SourceTasks do
|> Tasks.create_job_with_task(media_item)
end)
end

def enqueue_pending_media_downloads(%Source{download_media: false} = _source) do
:ok
end
end
20 changes: 17 additions & 3 deletions lib/pinchflat/workers/video_download_worker.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,32 @@ defmodule Pinchflat.Workers.VideoDownloadWorker do
unique: [period: :infinity, states: [:available, :scheduled, :retryable, :executing]],
tags: ["media_item", "media_fetching"]

alias Pinchflat.Repo
alias Pinchflat.Media
alias Pinchflat.MediaClient.VideoDownloader

@impl Oban.Worker
@doc """
For a given media item, download the video and save the metadata.
For a given media item, download the media alongside any options.
Does not download media if its source is set to not download media.
Returns {:ok, %MediaItem{}} | {:error, any, ...any}
Returns :ok | {:ok, %MediaItem{}} | {:error, any, ...any}
"""
def perform(%Oban.Job{args: %{"id" => media_item_id}}) do
media_item = Media.get_media_item!(media_item_id)
media_item =
media_item_id
|> Media.get_media_item!()
|> Repo.preload(:source)

# If the source is set to not download media, perform a no-op
if media_item.source.download_media do
download_media(media_item)
else
:ok
end
end

defp download_media(media_item) do
case VideoDownloader.download_for_media_item(media_item) do
{:ok, _} -> {:ok, media_item}
err -> err
Expand Down
2 changes: 1 addition & 1 deletion lib/pinchflat_web/components/core_components.ex
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,7 @@ defmodule PinchflatWeb.CoreComponents do

def list(assigns) do
~H"""
<div class="mt-14">
<div class="mt-2 mb-14">
<dl class="-my-4 divide-y divide-zinc-100">
<div :for={item <- @item} class="flex gap-4 py-4 text-sm leading-6 sm:gap-8">
<dt class="w-1/4 flex-none text-zinc-500"><%= item.title %></dt>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,16 @@
</:actions>
</.header>

<h3 class="mt-14">Relationships</h3>
<.list>
<:item title="media_profile">
<.link href={~p"/media_profiles/#{@source.media_profile}"}>
<%= @source.media_profile.name %>
</.link>
</:item>

<:item
:for={attr <- ~w(collection_type collection_name collection_id original_url friendly_name)a}
title={attr}
>
<%= Map.get(@source, attr) %>
</:item>
</.list>

<h3>Attributes</h3>
<.list_items_from_map map={Map.from_struct(@source)} />

<.back navigate={~p"/media_sources/sources"}>Back to sources</.back>
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
label="Index Frequency"
/>

<.input field={f[:download_media]} type="checkbox" label="Download Media?" />

<:actions>
<.button>Save Source</.button>
</:actions>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
defmodule Pinchflat.Repo.Migrations.AddDownloadMediaToSources do
use Ecto.Migration

def change do
alter table(:sources) do
add :download_media, :boolean, default: true, null: false
end
end
end
16 changes: 16 additions & 0 deletions test/pinchflat/tasks/source_tasks_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -75,5 +75,21 @@ defmodule Pinchflat.Tasks.SourceTasksTest do

assert [_] = Tasks.list_tasks_for(:media_item_id, media_item.id)
end

test "it does not create a job if the source is set to not download" do
source = source_fixture(download_media: false)

assert :ok = SourceTasks.enqueue_pending_media_downloads(source)

refute_enqueued(worker: VideoDownloadWorker)
end

test "it does not attach tasks if the source is set to not download" do
source = source_fixture(download_media: false)
media_item = media_item_fixture(source_id: source.id, media_filepath: nil)

assert :ok = SourceTasks.enqueue_pending_media_downloads(source)
assert [] = Tasks.list_tasks_for(:media_item_id, media_item.id)
end
end
end
9 changes: 9 additions & 0 deletions test/pinchflat/workers/video_download_worker_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ defmodule Pinchflat.Workers.VideoDownloadWorkerTest do
import Mox
import Pinchflat.MediaFixtures

alias Pinchflat.MediaSource
alias Pinchflat.Workers.VideoDownloadWorker

setup :verify_on_exit!
Expand Down Expand Up @@ -55,5 +56,13 @@ defmodule Pinchflat.Workers.VideoDownloadWorkerTest do
assert job.state == "retryable"
end)
end

test "it does not download if the source is set to not download", %{media_item: media_item} do
expect(YtDlpRunnerMock, :run, 0, fn _url, _opts, _ot -> :ok end)

MediaSource.update_source(media_item.source, %{download_media: false})

perform_job(VideoDownloadWorker, %{id: media_item.id})
end
end
end

0 comments on commit ac19f32

Please sign in to comment.