[Enhancement] Support Multiple YouTube API Keys (#606)

* feat: multiple YouTube API keys

* fix: requested changes
This commit is contained in:
rebel onion 2025-02-10 13:30:28 -06:00 committed by GitHub
parent b62d5c201b
commit 28f0d8ca6e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 85 additions and 10 deletions

View file

@ -12,6 +12,8 @@ defmodule Pinchflat.FastIndexing.YoutubeApi do
@behaviour YoutubeBehaviour
@agent_name {:global, __MODULE__.KeyIndex}
@doc """
Determines if the YouTube API is enabled for fast indexing by checking
if the user has an API key set
@ -19,7 +21,7 @@ defmodule Pinchflat.FastIndexing.YoutubeApi do
Returns boolean()
"""
@impl YoutubeBehaviour
def enabled?(), do: is_binary(api_key())
def enabled?, do: Enum.any?(api_keys())
@doc """
Fetches the recent media IDs from the YouTube API for a given source.
@ -74,8 +76,45 @@ defmodule Pinchflat.FastIndexing.YoutubeApi do
|> FunctionUtils.wrap_ok()
end
defp api_key do
Settings.get!(:youtube_api_key)
defp api_keys do
case Settings.get!(:youtube_api_key) do
nil ->
[]
keys ->
keys
|> String.split(",")
|> Enum.map(&String.trim/1)
|> Enum.reject(&(&1 == ""))
end
end
defp get_or_start_api_key_agent do
case Agent.start(fn -> 0 end, name: @agent_name) do
{:ok, pid} -> pid
{:error, {:already_started, pid}} -> pid
end
end
# Gets the next API key in round-robin fashion
defp next_api_key do
keys = api_keys()
case keys do
[] ->
nil
keys ->
pid = get_or_start_api_key_agent()
current_index =
Agent.get_and_update(pid, fn current ->
{current, rem(current + 1, length(keys))}
end)
Logger.debug("Using YouTube API key: #{Enum.at(keys, current_index)}")
Enum.at(keys, current_index)
end
end
defp construct_api_endpoint(playlist_id) do
@ -83,7 +122,7 @@ defmodule Pinchflat.FastIndexing.YoutubeApi do
property_type = "contentDetails"
max_results = 50
"#{api_base}?part=#{property_type}&maxResults=#{max_results}&playlistId=#{playlist_id}&key=#{api_key()}"
"#{api_base}?part=#{property_type}&maxResults=#{max_results}&playlistId=#{playlist_id}&key=#{next_api_key()}"
end
defp http_client do

View file

@ -34,9 +34,9 @@
<.input
field={f[:youtube_api_key]}
placeholder="ABC123"
placeholder="ABC123,DEF456"
type="text"
label="YouTube API Key"
label="YouTube API Key(s)"
help={youtube_api_help()}
html_help={true}
inputclass="font-mono text-sm mr-4"