diff --git a/lib/pinchflat/fast_indexing/fast_indexing_helpers.ex b/lib/pinchflat/fast_indexing/fast_indexing_helpers.ex index 62c2f99..bad6af3 100644 --- a/lib/pinchflat/fast_indexing/fast_indexing_helpers.ex +++ b/lib/pinchflat/fast_indexing/fast_indexing_helpers.ex @@ -13,12 +13,13 @@ defmodule Pinchflat.FastIndexing.FastIndexingHelpers do alias Pinchflat.Media alias Pinchflat.Sources.Source alias Pinchflat.FastIndexing.YoutubeRss + alias Pinchflat.FastIndexing.YoutubeApi alias Pinchflat.Downloading.DownloadingHelpers alias Pinchflat.YtDlp.Media, as: YtDlpMedia @doc """ - Fetches new media IDs from a source's YouTube RSS feed, indexes them, and kicks off downloading + Fetches new media IDs for a source from YT's API or RSS, indexes them, and kicks off downloading tasks for any pending media items. See comments in `FastIndexingWorker` for more info on the order of operations and how this fits into the indexing process. @@ -26,7 +27,7 @@ defmodule Pinchflat.FastIndexing.FastIndexingHelpers do downloaded_. """ def kickoff_download_tasks_from_youtube_rss_feed(%Source{} = source) do - {:ok, media_ids} = YoutubeRss.get_recent_media_ids(source) + {:ok, media_ids} = get_recent_media_ids(source) existing_media_items = list_media_items_by_media_id_for(source, media_ids) new_media_ids = media_ids -- Enum.map(existing_media_items, & &1.media_id) @@ -47,6 +48,18 @@ defmodule Pinchflat.FastIndexing.FastIndexingHelpers do Enum.filter(maybe_new_media_items, & &1) end + # If possible, use the YouTube API to fetch media IDs. If that fails, fall back to the RSS feed. + # If the YouTube API isn't set up, just use the RSS feed. + defp get_recent_media_ids(source) do + # TODO: test + with true <- YoutubeApi.enabled?(), + {:ok, media_ids} <- YoutubeApi.get_recent_media_ids(source) do + {:ok, media_ids} + else + _ -> YoutubeRss.get_recent_media_ids(source) + end + end + defp list_media_items_by_media_id_for(source, media_ids) do MediaQuery.new() |> where(^dynamic([mi], ^MediaQuery.for_source(source) and mi.media_id in ^media_ids)) diff --git a/lib/pinchflat/fast_indexing/youtube_api.ex b/lib/pinchflat/fast_indexing/youtube_api.ex index 2e2a45a..b41450e 100644 --- a/lib/pinchflat/fast_indexing/youtube_api.ex +++ b/lib/pinchflat/fast_indexing/youtube_api.ex @@ -1,15 +1,33 @@ defmodule Pinchflat.FastIndexing.YoutubeApi do @moduledoc """ - TODO + Methods for interacting with the YouTube API for fast indexing """ require Logger alias Pinchflat.Sources.Source alias Pinchflat.Utils.FunctionUtils + alias Pinchflat.FastIndexing.YoutubeBehaviour + + @behaviour YoutubeBehaviour + + @doc """ + Determines if the YouTube API is enabled for fast indexing + + Returns boolean() + """ + # TODO: test + # TODO: update this to use a user setting + @impl YoutubeBehaviour + def enabled?(), do: true # TODO: test - # TODO: make this a behaviour + @doc """ + Fetches the recent media IDs from the YouTube API for a given source. + + Returns {:ok, [binary()]} | {:error, binary()} + """ + @impl YoutubeBehaviour def get_recent_media_ids(%Source{} = source) do api_response = source @@ -39,6 +57,7 @@ defmodule Pinchflat.FastIndexing.YoutubeApi do Phoenix.json_library().decode(response) {:error, reason} -> + Logger.error("Failed to fetch YouTube API: #{inspect(reason)}") {:error, reason} end end @@ -52,6 +71,7 @@ defmodule Pinchflat.FastIndexing.YoutubeApi do |> Map.get("videoId", nil) end) |> Enum.reject(&is_nil/1) + |> Enum.uniq() |> FunctionUtils.wrap_ok() end diff --git a/lib/pinchflat/fast_indexing/youtube_behaviour.ex b/lib/pinchflat/fast_indexing/youtube_behaviour.ex index ea474de..8a6c390 100644 --- a/lib/pinchflat/fast_indexing/youtube_behaviour.ex +++ b/lib/pinchflat/fast_indexing/youtube_behaviour.ex @@ -1,3 +1,11 @@ defmodule Pinchflat.FastIndexing.YoutubeBehaviour do - # TODO + @moduledoc """ + This module defines the behaviour for clients that interface with YouTube + for the purpose of fast indexing. + """ + + alias Pinchflat.Sources.Source + + @callback enabled?() :: boolean() + @callback get_recent_media_ids(%Source{}) :: {:ok, [String.t()]} | {:error, String.t()} end diff --git a/lib/pinchflat/fast_indexing/youtube_rss.ex b/lib/pinchflat/fast_indexing/youtube_rss.ex index 8aa0e8d..4837087 100644 --- a/lib/pinchflat/fast_indexing/youtube_rss.ex +++ b/lib/pinchflat/fast_indexing/youtube_rss.ex @@ -1,17 +1,31 @@ defmodule Pinchflat.FastIndexing.YoutubeRss do @moduledoc """ - Methods for interacting with YouTube RSS feeds + Methods for interacting with YouTube RSS feeds for fast indexing """ require Logger alias Pinchflat.Sources.Source + alias Pinchflat.FastIndexing.YoutubeBehaviour + + @behaviour YoutubeBehaviour + + @doc """ + Determines if the YouTube RSS feed is enabled for fast indexing. Used to satisfy + the `YoutubeBehaviour` behaviour. + + Returns true + """ + # TODO: test + @impl YoutubeBehaviour + def enabled?(), do: true @doc """ Fetches the recent media IDs from a YouTube RSS feed for a given source. Returns {:ok, [binary()]} | {:error, binary()} """ + @impl YoutubeBehaviour def get_recent_media_ids(%Source{} = source) do Logger.debug("Fetching recent media IDs from YouTube RSS feed for source: #{source.collection_id}")