diff --git a/config/config.exs b/config/config.exs index 7b8d29a..a25b014 100644 --- a/config/config.exs +++ b/config/config.exs @@ -49,16 +49,7 @@ config :pinchflat, PinchflatWeb.Endpoint, config :pinchflat, Oban, engine: Oban.Engines.Lite, - repo: Pinchflat.Repo, - # Keep old jobs for 30 days for display in the UI - plugins: [ - {Oban.Plugins.Pruner, max_age: 30 * 24 * 60 * 60}, - {Oban.Plugins.Cron, - crontab: [ - {"0 1 * * *", Pinchflat.Downloading.MediaRetentionWorker}, - {"0 2 * * *", Pinchflat.Downloading.MediaQualityUpgradeWorker} - ]} - ] + repo: Pinchflat.Repo # Configures the mailer # diff --git a/config/runtime.exs b/config/runtime.exs index 4f0a5ca..5624bfe 100644 --- a/config/runtime.exs +++ b/config/runtime.exs @@ -43,6 +43,11 @@ config :pinchflat, Pinchflat.Repo, # Some users may want to increase the number of workers that use yt-dlp to improve speeds # Others may want to decrease the number of these workers to lessen the chance of an IP ban {yt_dlp_worker_count, _} = Integer.parse(System.get_env("YT_DLP_WORKER_CONCURRENCY", "2")) +# Used to set the cron for the yt-dlp update worker. The reason for this is +# to avoid all instances of PF updating yt-dlp at the same time, which 1) +# could result in rate limiting and 2) gives me time to react if an update +# breaks something +%{hour: current_hour, minute: current_minute} = DateTime.utc_now() config :pinchflat, Oban, queues: [ @@ -52,6 +57,16 @@ config :pinchflat, Oban, media_fetching: yt_dlp_worker_count, remote_metadata: yt_dlp_worker_count, local_data: 8 + ], + plugins: [ + # Keep old jobs for 30 days for display in the UI + {Oban.Plugins.Pruner, max_age: 30 * 24 * 60 * 60}, + {Oban.Plugins.Cron, + crontab: [ + {"#{current_minute} #{current_hour} * * *", Pinchflat.YtDlp.UpdateWorker}, + {"0 1 * * *", Pinchflat.Downloading.MediaRetentionWorker}, + {"0 2 * * *", Pinchflat.Downloading.MediaQualityUpgradeWorker} + ]} ] if config_env() == :prod do diff --git a/lib/pinchflat/yt_dlp/update_worker.ex b/lib/pinchflat/yt_dlp/update_worker.ex new file mode 100644 index 0000000..daa7aac --- /dev/null +++ b/lib/pinchflat/yt_dlp/update_worker.ex @@ -0,0 +1,34 @@ +defmodule Pinchflat.YtDlp.UpdateWorker do + @moduledoc false + + use Oban.Worker, + queue: :local_data, + tags: ["local_data"] + + require Logger + + alias Pinchflat.Settings + + @doc """ + Updates yt-dlp and saves the version to the settings. + + This worker is scheduled to run via the Oban Cron plugin. + + Returns :ok + """ + @impl Oban.Worker + def perform(%Oban.Job{}) do + Logger.info("Updating yt-dlp") + + yt_dlp_runner().update() + + {:ok, yt_dlp_version} = yt_dlp_runner().version() + Settings.set(yt_dlp_version: yt_dlp_version) + + :ok + end + + defp yt_dlp_runner do + Application.get_env(:pinchflat, :yt_dlp_runner) + end +end diff --git a/test/pinchflat/yt_dlp/update_worker_test.exs b/test/pinchflat/yt_dlp/update_worker_test.exs new file mode 100644 index 0000000..fed0510 --- /dev/null +++ b/test/pinchflat/yt_dlp/update_worker_test.exs @@ -0,0 +1,24 @@ +defmodule Pinchflat.YtDlp.UpdateWorkerTest do + use Pinchflat.DataCase + + alias Pinchflat.Settings + alias Pinchflat.YtDlp.UpdateWorker + + describe "perform/1" do + test "calls the yt-dlp runner to update yt-dlp" do + expect(YtDlpRunnerMock, :update, fn -> {:ok, ""} end) + expect(YtDlpRunnerMock, :version, fn -> {:ok, ""} end) + + perform_job(UpdateWorker, %{}) + end + + test "saves the new version to the database" do + expect(YtDlpRunnerMock, :update, fn -> {:ok, ""} end) + expect(YtDlpRunnerMock, :version, fn -> {:ok, "1.2.3"} end) + + perform_job(UpdateWorker, %{}) + + assert {:ok, "1.2.3"} = Settings.get(:yt_dlp_version) + end + end +end