Hooked up collection_type to form; refactored enqueue_pending_media_downloads
This commit is contained in:
parent
77b8a3e56f
commit
32bcf38d0e
8 changed files with 89 additions and 23 deletions
1
.iex.exs
1
.iex.exs
|
|
@ -2,6 +2,7 @@ alias Pinchflat.Repo
|
||||||
|
|
||||||
alias Pinchflat.Tasks.Task
|
alias Pinchflat.Tasks.Task
|
||||||
alias Pinchflat.Media.MediaItem
|
alias Pinchflat.Media.MediaItem
|
||||||
|
alias Pinchflat.Tasks.SourceTasks
|
||||||
alias Pinchflat.Media.MediaMetadata
|
alias Pinchflat.Media.MediaMetadata
|
||||||
alias Pinchflat.MediaSource.Source
|
alias Pinchflat.MediaSource.Source
|
||||||
alias Pinchflat.Profiles.MediaProfile
|
alias Pinchflat.Profiles.MediaProfile
|
||||||
|
|
|
||||||
|
|
@ -100,6 +100,8 @@ defmodule Pinchflat.MediaSource do
|
||||||
Note that this fetches source details as long as the `original_url` is present.
|
Note that this fetches source details as long as the `original_url` is present.
|
||||||
This means that it'll go for it even if a changeset is otherwise invalid. This
|
This means that it'll go for it even if a changeset is otherwise invalid. This
|
||||||
is pretty easy to change, but for MVP I'm not concerned.
|
is pretty easy to change, but for MVP I'm not concerned.
|
||||||
|
|
||||||
|
IDEA: Maybe I could discern `collection_type` based on the original URL?
|
||||||
"""
|
"""
|
||||||
def change_source_from_url(%Source{} = source, attrs) do
|
def change_source_from_url(%Source{} = source, attrs) do
|
||||||
case change_source(source, attrs) do
|
case change_source(source, attrs) do
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,16 @@ defmodule Pinchflat.MediaSource.Source do
|
||||||
alias Pinchflat.Media.MediaItem
|
alias Pinchflat.Media.MediaItem
|
||||||
alias Pinchflat.Profiles.MediaProfile
|
alias Pinchflat.Profiles.MediaProfile
|
||||||
|
|
||||||
@allowed_fields ~w(collection_name collection_id collection_type index_frequency_minutes original_url media_profile_id)a
|
@allowed_fields ~w(
|
||||||
|
collection_name
|
||||||
|
collection_id
|
||||||
|
collection_type
|
||||||
|
friendly_name
|
||||||
|
index_frequency_minutes
|
||||||
|
original_url
|
||||||
|
media_profile_id
|
||||||
|
)a
|
||||||
|
|
||||||
@required_fields @allowed_fields -- ~w(index_frequency_minutes friendly_name)a
|
@required_fields @allowed_fields -- ~w(index_frequency_minutes friendly_name)a
|
||||||
|
|
||||||
schema "sources" do
|
schema "sources" do
|
||||||
|
|
@ -17,7 +26,7 @@ defmodule Pinchflat.MediaSource.Source do
|
||||||
field :collection_name, :string
|
field :collection_name, :string
|
||||||
field :collection_id, :string
|
field :collection_id, :string
|
||||||
field :collection_type, Ecto.Enum, values: [:channel, :playlist]
|
field :collection_type, Ecto.Enum, values: [:channel, :playlist]
|
||||||
field :index_frequency_minutes, :integer
|
field :index_frequency_minutes, :integer, default: 60 * 24
|
||||||
# This should only be used for user reference going forward
|
# This should only be used for user reference going forward
|
||||||
# as the collection_id should be used for all API calls
|
# as the collection_id should be used for all API calls
|
||||||
field :original_url, :string
|
field :original_url, :string
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,11 @@ defmodule Pinchflat.Tasks.SourceTasks do
|
||||||
This module contains methods for managing tasks (workers) related to sources.
|
This module contains methods for managing tasks (workers) related to sources.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
alias Pinchflat.Media
|
||||||
alias Pinchflat.Tasks
|
alias Pinchflat.Tasks
|
||||||
alias Pinchflat.MediaSource.Source
|
alias Pinchflat.MediaSource.Source
|
||||||
alias Pinchflat.Workers.MediaIndexingWorker
|
alias Pinchflat.Workers.MediaIndexingWorker
|
||||||
|
alias Pinchflat.Workers.VideoDownloadWorker
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Starts tasks for indexing a source's media.
|
Starts tasks for indexing a source's media.
|
||||||
|
|
@ -30,4 +32,27 @@ defmodule Pinchflat.Tasks.SourceTasks do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Starts tasks for downloading videos for any of a sources _pending_ media items.
|
||||||
|
|
||||||
|
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
|
||||||
|
that any stragglers are caught if, for some reason, they weren't enqueued
|
||||||
|
or somehow got de-queued.
|
||||||
|
|
||||||
|
I'm not sure of a case where this would happen, but it's cheap insurance.
|
||||||
|
|
||||||
|
Returns :ok
|
||||||
|
"""
|
||||||
|
def enqueue_pending_media_downloads(%Source{} = source) do
|
||||||
|
source
|
||||||
|
|> Media.list_pending_media_items_for()
|
||||||
|
|> Enum.each(fn media_item ->
|
||||||
|
media_item
|
||||||
|
|> Map.take([:id])
|
||||||
|
|> VideoDownloadWorker.new()
|
||||||
|
|> Tasks.create_job_with_task(media_item)
|
||||||
|
end)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,9 @@ defmodule Pinchflat.Workers.MediaIndexingWorker do
|
||||||
tags: ["media_source", "media_indexing"]
|
tags: ["media_source", "media_indexing"]
|
||||||
|
|
||||||
alias __MODULE__
|
alias __MODULE__
|
||||||
alias Pinchflat.Media
|
|
||||||
alias Pinchflat.Tasks
|
alias Pinchflat.Tasks
|
||||||
alias Pinchflat.MediaSource
|
alias Pinchflat.MediaSource
|
||||||
alias Pinchflat.Workers.VideoDownloadWorker
|
alias Pinchflat.Tasks.SourceTasks
|
||||||
|
|
||||||
@impl Oban.Worker
|
@impl Oban.Worker
|
||||||
@doc """
|
@doc """
|
||||||
|
|
@ -49,7 +48,7 @@ defmodule Pinchflat.Workers.MediaIndexingWorker do
|
||||||
|
|
||||||
defp index_media_and_reschedule(source) do
|
defp index_media_and_reschedule(source) do
|
||||||
MediaSource.index_media_items(source)
|
MediaSource.index_media_items(source)
|
||||||
enqueue_video_downloads(source)
|
SourceTasks.enqueue_pending_media_downloads(source)
|
||||||
|
|
||||||
source
|
source
|
||||||
|> Map.take([:id])
|
|> Map.take([:id])
|
||||||
|
|
@ -60,21 +59,4 @@ defmodule Pinchflat.Workers.MediaIndexingWorker do
|
||||||
{:error, :duplicate_job} -> {:ok, :job_exists}
|
{:error, :duplicate_job} -> {:ok, :job_exists}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# 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
|
|
||||||
# that any stragglers are caught if, for some reason, they weren't enqueued
|
|
||||||
# or somehow got de-queued.
|
|
||||||
#
|
|
||||||
# I'm not sure of a case where this would happen, but it's cheap insurance.
|
|
||||||
defp enqueue_video_downloads(source) do
|
|
||||||
source
|
|
||||||
|> Media.list_pending_media_items_for()
|
|
||||||
|> Enum.each(fn media_item ->
|
|
||||||
media_item
|
|
||||||
|> Map.take([:id])
|
|
||||||
|> VideoDownloadWorker.new()
|
|
||||||
|> Tasks.create_job_with_task(media_item)
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -24,4 +24,11 @@ defmodule PinchflatWeb.MediaSources.SourceHTML do
|
||||||
{"Monthly", 30 * 24 * 60}
|
{"Monthly", 30 * 24 * 60}
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def friendly_collection_types do
|
||||||
|
[
|
||||||
|
{"Channel", "channel"},
|
||||||
|
{"Playlist", "playlist"}
|
||||||
|
]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,13 @@
|
||||||
label="Media Profile"
|
label="Media Profile"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<.input field={f[:collection_type]} type="text" label="Collection Type" />
|
<.input
|
||||||
|
field={f[:collection_type]}
|
||||||
|
options={friendly_collection_types()}
|
||||||
|
type="select"
|
||||||
|
label="Collection Type"
|
||||||
|
/>
|
||||||
|
|
||||||
<.input field={f[:original_url]} type="text" label="Source URL" />
|
<.input field={f[:original_url]} type="text" label="Source URL" />
|
||||||
|
|
||||||
<.input
|
<.input
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,14 @@ defmodule Pinchflat.Tasks.SourceTasksTest do
|
||||||
use Pinchflat.DataCase
|
use Pinchflat.DataCase
|
||||||
|
|
||||||
import Pinchflat.TasksFixtures
|
import Pinchflat.TasksFixtures
|
||||||
|
import Pinchflat.MediaFixtures
|
||||||
import Pinchflat.MediaSourceFixtures
|
import Pinchflat.MediaSourceFixtures
|
||||||
|
|
||||||
|
alias Pinchflat.Tasks
|
||||||
alias Pinchflat.Tasks.Task
|
alias Pinchflat.Tasks.Task
|
||||||
alias Pinchflat.Tasks.SourceTasks
|
alias Pinchflat.Tasks.SourceTasks
|
||||||
alias Pinchflat.Workers.MediaIndexingWorker
|
alias Pinchflat.Workers.MediaIndexingWorker
|
||||||
|
alias Pinchflat.Workers.VideoDownloadWorker
|
||||||
|
|
||||||
describe "kickoff_indexing_task/1" do
|
describe "kickoff_indexing_task/1" do
|
||||||
test "it does not schedule a job if the interval is <= 0" do
|
test "it does not schedule a job if the interval is <= 0" do
|
||||||
|
|
@ -42,4 +45,35 @@ defmodule Pinchflat.Tasks.SourceTasksTest do
|
||||||
assert_raise Ecto.NoResultsError, fn -> Repo.reload!(task) end
|
assert_raise Ecto.NoResultsError, fn -> Repo.reload!(task) end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "enqueue_pending_media_downloads/1" do
|
||||||
|
test "it enqueues a job for each pending media item" do
|
||||||
|
source = source_fixture()
|
||||||
|
media_item = media_item_fixture(source_id: source.id, media_filepath: nil)
|
||||||
|
|
||||||
|
assert :ok = SourceTasks.enqueue_pending_media_downloads(source)
|
||||||
|
|
||||||
|
assert_enqueued(worker: VideoDownloadWorker, args: %{"id" => media_item.id})
|
||||||
|
end
|
||||||
|
|
||||||
|
test "it does not enqueue a job for media items with a filepath" do
|
||||||
|
source = source_fixture()
|
||||||
|
_media_item = media_item_fixture(source_id: source.id, media_filepath: "some/filepath.mp4")
|
||||||
|
|
||||||
|
assert :ok = SourceTasks.enqueue_pending_media_downloads(source)
|
||||||
|
|
||||||
|
refute_enqueued(worker: VideoDownloadWorker)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "it attaches a task to each enqueued job" do
|
||||||
|
source = source_fixture()
|
||||||
|
media_item = media_item_fixture(source_id: source.id, media_filepath: nil)
|
||||||
|
|
||||||
|
assert [] = Tasks.list_tasks_for(:media_item_id, media_item.id)
|
||||||
|
|
||||||
|
assert :ok = SourceTasks.enqueue_pending_media_downloads(source)
|
||||||
|
|
||||||
|
assert [_] = Tasks.list_tasks_for(:media_item_id, media_item.id)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue