Hooked up script runner for indexing
This commit is contained in:
@@ -16,10 +16,14 @@ defmodule Pinchflat.Downloading.DownloadingHelpers do
|
||||
alias Pinchflat.Media.MediaItem
|
||||
alias Pinchflat.Downloading.MediaDownloadWorker
|
||||
|
||||
alias Pinchflat.Lifecycle.UserScripts.CommandRunner, as: UserScriptRunner
|
||||
|
||||
@doc """
|
||||
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.
|
||||
|
||||
You can optionally set the `kickoff_delay` option to delay when the jobs are enqueued.
|
||||
|
||||
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
|
||||
@@ -30,8 +34,6 @@ defmodule Pinchflat.Downloading.DownloadingHelpers do
|
||||
def enqueue_pending_download_tasks(source, opts \\ [])
|
||||
|
||||
def enqueue_pending_download_tasks(%Source{download_media: true} = source, opts) do
|
||||
# TODO: test
|
||||
# TODO: doc
|
||||
kickoff_delay = Keyword.get(opts, :kickoff_delay, 0)
|
||||
|
||||
source
|
||||
@@ -59,11 +61,11 @@ defmodule Pinchflat.Downloading.DownloadingHelpers do
|
||||
downloaded, based on the source's download settings and whether media is
|
||||
considered pending.
|
||||
|
||||
You can optionally set the `kickoff_delay` option to delay when the jobs are enqueued.
|
||||
|
||||
Returns {:ok, %Task{}} | {:error, :should_not_download} | {:error, any()}
|
||||
"""
|
||||
def kickoff_download_if_pending(%MediaItem{} = media_item, opts \\ []) do
|
||||
# TODO: test
|
||||
# TODO: doc
|
||||
kickoff_delay = Keyword.get(opts, :kickoff_delay, 0)
|
||||
media_item = Repo.preload(media_item, :source)
|
||||
|
||||
@@ -107,4 +109,32 @@ defmodule Pinchflat.Downloading.DownloadingHelpers do
|
||||
|> Repo.all()
|
||||
|> Enum.map(&MediaDownloadWorker.kickoff_with_task/1)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Creates a media item from the attributes returned by the video backend
|
||||
(read: yt-dlp) and runs the user script with a `media_indexed` event type.
|
||||
|
||||
Only runs the user script if the media item was created successfully and the media item
|
||||
doesn't already exist in the database.
|
||||
|
||||
Returns {:ok, %MediaItem{}} | {:error, any()}
|
||||
"""
|
||||
def create_media_item_and_run_script(%Source{} = source, media_attrs_struct) do
|
||||
media_already_exists =
|
||||
MediaQuery.new()
|
||||
|> where(^dynamic(^MediaQuery.for_source(source) and ^MediaQuery.media_id(media_attrs_struct.media_id)))
|
||||
|> Repo.exists?()
|
||||
|
||||
case Media.create_media_item_from_backend_attrs(source, media_attrs_struct) do
|
||||
{:ok, media_item} ->
|
||||
if !media_already_exists do
|
||||
UserScriptRunner.run(:media_indexed, media_item)
|
||||
end
|
||||
|
||||
{:ok, media_item}
|
||||
|
||||
err ->
|
||||
err
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -10,7 +10,6 @@ defmodule Pinchflat.FastIndexing.FastIndexingHelpers do
|
||||
use Pinchflat.Media.MediaQuery
|
||||
|
||||
alias Pinchflat.Repo
|
||||
alias Pinchflat.Media
|
||||
alias Pinchflat.Sources.Source
|
||||
alias Pinchflat.FastIndexing.YoutubeRss
|
||||
alias Pinchflat.Downloading.DownloadingHelpers
|
||||
@@ -43,7 +42,6 @@ defmodule Pinchflat.FastIndexing.FastIndexingHelpers do
|
||||
end)
|
||||
|
||||
# Wait 5s before enqueuing downloads to give the post-indexing user script a chance to run
|
||||
# TODO: test
|
||||
DownloadingHelpers.enqueue_pending_download_tasks(source, kickoff_delay: 5)
|
||||
|
||||
Enum.filter(maybe_new_media_items, & &1)
|
||||
@@ -59,8 +57,8 @@ defmodule Pinchflat.FastIndexing.FastIndexingHelpers do
|
||||
url = "https://www.youtube.com/watch?v=#{media_id}"
|
||||
|
||||
case YtDlpMedia.get_media_attributes(url) do
|
||||
{:ok, media_attrs} ->
|
||||
Media.create_media_item_from_backend_attrs(source, media_attrs)
|
||||
{:ok, media_attrs_struct} ->
|
||||
DownloadingHelpers.create_media_item_and_run_script(source, media_attrs_struct)
|
||||
|
||||
err ->
|
||||
err
|
||||
|
||||
@@ -12,6 +12,7 @@ defmodule Pinchflat.Lifecycle.UserScripts.CommandRunner do
|
||||
@behaviour UserScriptCommandRunner
|
||||
|
||||
@event_types [
|
||||
:media_indexed,
|
||||
:media_downloaded,
|
||||
:media_deleted
|
||||
]
|
||||
|
||||
@@ -35,6 +35,8 @@ defmodule Pinchflat.Media.MediaQuery do
|
||||
def culling_prevented, do: dynamic([mi], mi.prevent_culling == true)
|
||||
def culled, do: dynamic([mi], not is_nil(mi.culled_at))
|
||||
def redownloaded, do: dynamic([mi], not is_nil(mi.media_redownloaded_at))
|
||||
def media_id(nil), do: dynamic(false)
|
||||
def media_id(media_id), do: dynamic([mi], mi.media_id == ^media_id)
|
||||
|
||||
def upload_date_after_source_cutoff do
|
||||
dynamic([mi, source], is_nil(source.download_cutoff_date) or mi.upload_date >= source.download_cutoff_date)
|
||||
|
||||
@@ -8,7 +8,6 @@ defmodule Pinchflat.SlowIndexing.SlowIndexingHelpers do
|
||||
require Logger
|
||||
|
||||
alias Pinchflat.Repo
|
||||
alias Pinchflat.Media
|
||||
alias Pinchflat.Tasks
|
||||
alias Pinchflat.Sources
|
||||
alias Pinchflat.Sources.Source
|
||||
@@ -39,6 +38,9 @@ defmodule Pinchflat.SlowIndexing.SlowIndexingHelpers do
|
||||
item belonging to the source. You can't tell me the method name isn't descriptive!
|
||||
Returns a list of media items or changesets (if the media item couldn't be created).
|
||||
|
||||
For each new media item, the method will also run a user script with the `media_indexed`
|
||||
event, if the script is present.
|
||||
|
||||
Indexing is slow and usually returns a list of all media data at once for record creation.
|
||||
To help with this, we use a file follower to watch the file that yt-dlp writes to
|
||||
so we can create media items as they come in. This parallelizes the process and adds
|
||||
@@ -64,8 +66,8 @@ defmodule Pinchflat.SlowIndexing.SlowIndexingHelpers do
|
||||
source = Repo.reload!(source)
|
||||
|
||||
result =
|
||||
Enum.map(media_attributes, fn media_attrs ->
|
||||
case Media.create_media_item_from_backend_attrs(source, media_attrs) do
|
||||
Enum.map(media_attributes, fn media_attrs_struct ->
|
||||
case DownloadingHelpers.create_media_item_and_run_script(source, media_attrs_struct) do
|
||||
{:ok, media_item} -> media_item
|
||||
{:error, changeset} -> changeset
|
||||
end
|
||||
@@ -73,7 +75,6 @@ defmodule Pinchflat.SlowIndexing.SlowIndexingHelpers do
|
||||
|
||||
Sources.update_source(source, %{last_indexed_at: DateTime.utc_now()})
|
||||
# Wait 5s before enqueuing downloads to give the post-indexing user script a chance to run
|
||||
# TODO: test
|
||||
DownloadingHelpers.enqueue_pending_download_tasks(source, kickoff_delay: 5)
|
||||
|
||||
result
|
||||
@@ -120,15 +121,14 @@ defmodule Pinchflat.SlowIndexing.SlowIndexingHelpers do
|
||||
end)
|
||||
end
|
||||
|
||||
defp create_media_item_and_enqueue_download(source, media_attrs) do
|
||||
defp create_media_item_and_enqueue_download(source, media_attrs_struct) do
|
||||
# Reload because the source may have been updated during the (long-running) indexing process
|
||||
# and important settings like `download_media` may have changed.
|
||||
source = Repo.reload!(source)
|
||||
|
||||
case Media.create_media_item_from_backend_attrs(source, media_attrs) do
|
||||
case DownloadingHelpers.create_media_item_and_run_script(source, media_attrs_struct) do
|
||||
{:ok, %MediaItem{} = media_item} ->
|
||||
# Wait 5s before enqueuing downloads to give the post-indexing user script a chance to run
|
||||
# TODO: test
|
||||
DownloadingHelpers.kickoff_download_if_pending(media_item, kickoff_delay: 5)
|
||||
|
||||
{:error, changeset} ->
|
||||
|
||||
Reference in New Issue
Block a user