Hooked youtube API into fast indexing

This commit is contained in:
Kieran Eglin 2024-06-04 15:13:45 -07:00
parent 2fc5e20077
commit 9dbbf34db9
No known key found for this signature in database
GPG key ID: 193984967FCF432D
4 changed files with 61 additions and 6 deletions

View file

@ -13,12 +13,13 @@ defmodule Pinchflat.FastIndexing.FastIndexingHelpers do
alias Pinchflat.Media alias Pinchflat.Media
alias Pinchflat.Sources.Source alias Pinchflat.Sources.Source
alias Pinchflat.FastIndexing.YoutubeRss alias Pinchflat.FastIndexing.YoutubeRss
alias Pinchflat.FastIndexing.YoutubeApi
alias Pinchflat.Downloading.DownloadingHelpers alias Pinchflat.Downloading.DownloadingHelpers
alias Pinchflat.YtDlp.Media, as: YtDlpMedia alias Pinchflat.YtDlp.Media, as: YtDlpMedia
@doc """ @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 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. order of operations and how this fits into the indexing process.
@ -26,7 +27,7 @@ defmodule Pinchflat.FastIndexing.FastIndexingHelpers do
downloaded_. downloaded_.
""" """
def kickoff_download_tasks_from_youtube_rss_feed(%Source{} = source) do 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) 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) 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) Enum.filter(maybe_new_media_items, & &1)
end 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 defp list_media_items_by_media_id_for(source, media_ids) do
MediaQuery.new() MediaQuery.new()
|> where(^dynamic([mi], ^MediaQuery.for_source(source) and mi.media_id in ^media_ids)) |> where(^dynamic([mi], ^MediaQuery.for_source(source) and mi.media_id in ^media_ids))

View file

@ -1,15 +1,33 @@
defmodule Pinchflat.FastIndexing.YoutubeApi do defmodule Pinchflat.FastIndexing.YoutubeApi do
@moduledoc """ @moduledoc """
TODO Methods for interacting with the YouTube API for fast indexing
""" """
require Logger require Logger
alias Pinchflat.Sources.Source alias Pinchflat.Sources.Source
alias Pinchflat.Utils.FunctionUtils 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: 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 def get_recent_media_ids(%Source{} = source) do
api_response = api_response =
source source
@ -39,6 +57,7 @@ defmodule Pinchflat.FastIndexing.YoutubeApi do
Phoenix.json_library().decode(response) Phoenix.json_library().decode(response)
{:error, reason} -> {:error, reason} ->
Logger.error("Failed to fetch YouTube API: #{inspect(reason)}")
{:error, reason} {:error, reason}
end end
end end
@ -52,6 +71,7 @@ defmodule Pinchflat.FastIndexing.YoutubeApi do
|> Map.get("videoId", nil) |> Map.get("videoId", nil)
end) end)
|> Enum.reject(&is_nil/1) |> Enum.reject(&is_nil/1)
|> Enum.uniq()
|> FunctionUtils.wrap_ok() |> FunctionUtils.wrap_ok()
end end

View file

@ -1,3 +1,11 @@
defmodule Pinchflat.FastIndexing.YoutubeBehaviour do 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 end

View file

@ -1,17 +1,31 @@
defmodule Pinchflat.FastIndexing.YoutubeRss do defmodule Pinchflat.FastIndexing.YoutubeRss do
@moduledoc """ @moduledoc """
Methods for interacting with YouTube RSS feeds Methods for interacting with YouTube RSS feeds for fast indexing
""" """
require Logger require Logger
alias Pinchflat.Sources.Source 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 """ @doc """
Fetches the recent media IDs from a YouTube RSS feed for a given source. Fetches the recent media IDs from a YouTube RSS feed for a given source.
Returns {:ok, [binary()]} | {:error, binary()} Returns {:ok, [binary()]} | {:error, binary()}
""" """
@impl YoutubeBehaviour
def get_recent_media_ids(%Source{} = source) do def get_recent_media_ids(%Source{} = source) do
Logger.debug("Fetching recent media IDs from YouTube RSS feed for source: #{source.collection_id}") Logger.debug("Fetching recent media IDs from YouTube RSS feed for source: #{source.collection_id}")