diff --git a/.formatter.exs b/.formatter.exs index 98279b9..c5f250f 100644 --- a/.formatter.exs +++ b/.formatter.exs @@ -1,5 +1,5 @@ [ - import_deps: [:oban, :ecto, :ecto_sql, :phoenix, :tesla], + import_deps: [:oban, :oban_web, :ecto, :ecto_sql, :phoenix, :tesla], subdirectories: ["priv/*/migrations"], plugins: [Phoenix.LiveView.HTMLFormatter], inputs: ["*.{heex,ex,exs}", "{config,lib,test}/**/*.{heex,ex,exs}", "priv/*/seeds.exs"] diff --git a/lib/core/syndication.ex b/lib/core/syndication.ex index 981b95b..d5f1099 100644 --- a/lib/core/syndication.ex +++ b/lib/core/syndication.ex @@ -74,12 +74,22 @@ defmodule Core.Syndication do end def refresh_bluesky_account(%Schema.BlueskyAccount{} = bluesky_account) do - with {:ok, refresh_resp} <- - Syndication.BlueskyClient.refresh_session(bluesky_account), - {:ok, attrs} <- parse_bluesky_token_resp(refresh_resp) do - bluesky_account - |> Syndication.BlueskyAccount.refresh_changeset(attrs) - |> Core.Repo.update() + if DateTime.compare(DateTime.utc_now(), bluesky_account.access_jwt_exp) == :lt do + {:ok, bluesky_account} + else + with {:ok, refresh_resp} <- + Syndication.BlueskyClient.refresh_session(bluesky_account), + {:ok, attrs} <- parse_bluesky_token_resp(refresh_resp) do + %{"bluesky_account_id" => bluesky_account.id} + |> Core.Syndication.BlueskyRefreshWorker.new( + scheduled_at: DateTime.add(bluesky_account.refresh_jwt_exp, -1, :day) + ) + |> Oban.insert() + + bluesky_account + |> Syndication.BlueskyAccount.refresh_changeset(attrs) + |> Core.Repo.update() + end end end @@ -87,7 +97,7 @@ defmodule Core.Syndication do post = Core.Repo.preload(post, [:bluesky_post]) if post.syndicate_to_bluesky && is_nil(post.bluesky_post) do - bluesky_account = get_bluesky_account!() + {:ok, bluesky_account} = get_bluesky_account!() |> refresh_bluesky_account() with {:ok, resp} <- Syndication.BlueskyClient.post_status(bluesky_account, post.body) do post diff --git a/lib/core/syndication/bluesky_refresh_worker.ex b/lib/core/syndication/bluesky_refresh_worker.ex new file mode 100644 index 0000000..3b09544 --- /dev/null +++ b/lib/core/syndication/bluesky_refresh_worker.ex @@ -0,0 +1,12 @@ +defmodule Core.Syndication.BlueskyRefreshWorker do + use Oban.Worker + + @impl true + def perform(%Oban.Job{args: %{"bluesky_account_id" => id}}) do + if bluesky_account = Core.Repo.get(Schema.BlueskyAccount, id) do + Core.Syndication.refresh_bluesky_account(bluesky_account) + else + {:cancel, "bluesky account not found"} + end + end +end diff --git a/lib/web/components/layouts/app.html.heex b/lib/web/components/layouts/app.html.heex index 0330348..ac21cf0 100644 --- a/lib/web/components/layouts/app.html.heex +++ b/lib/web/components/layouts/app.html.heex @@ -9,6 +9,8 @@ <nav> <ul class="flex flex-row gap-x-2"> <li><.link navigate={~p"/admin/writing"}>admin</.link></li> + <li><.link navigate={~p"/admin/dashboard"}>dashboard</.link></li> + <li><.link navigate={~p"/admin/oban"}>oban</.link></li> </ul> </nav> </section> diff --git a/lib/web/router.ex b/lib/web/router.ex index 6c540e4..ea0893b 100644 --- a/lib/web/router.ex +++ b/lib/web/router.ex @@ -1,6 +1,8 @@ defmodule Web.Router do use Web, :router + import Phoenix.LiveDashboard.Router + import Oban.Web.Router import Web.UserAuth pipeline :browser do @@ -35,6 +37,9 @@ defmodule Web.Router do scope "/admin", Web do pipe_through [:browser, :require_authenticated_user] + live_dashboard "/dashboard" + oban_dashboard "/oban" + live_session :require_authenticated_user, on_mount: [{Web.UserAuth, :ensure_authenticated}] do live "/users/settings", UserSettingsLive, :edit diff --git a/mix.exs b/mix.exs index 9492cf2..993bbba 100644 --- a/mix.exs +++ b/mix.exs @@ -65,6 +65,7 @@ defmodule SlaonelyButSurely.MixProject do {:flop, "~> 0.26.1"}, {:flop_phoenix, "~> 0.24.1"}, {:oban, "~> 2.19"}, + {:oban_web, "~> 2.11"}, {:igniter, "~> 0.5", only: [:dev]}, {:ueberauth, "~> 0.10"}, {:ueberauth_mastodon, "~> 0.3.0"}, diff --git a/mix.lock b/mix.lock index b34d993..34dda9d 100644 --- a/mix.lock +++ b/mix.lock @@ -42,6 +42,8 @@ "nimble_options": {:hex, :nimble_options, "1.1.1", "e3a492d54d85fc3fd7c5baf411d9d2852922f66e69476317787a7b2bb000a61b", [:mix], [], "hexpm", "821b2470ca9442c4b6984882fe9bb0389371b8ddec4d45a9504f00a66f650b44"}, "nimble_pool": {:hex, :nimble_pool, "1.1.0", "bf9c29fbdcba3564a8b800d1eeb5a3c58f36e1e11d7b7fb2e084a643f645f06b", [:mix], [], "hexpm", "af2e4e6b34197db81f7aad230c1118eac993acc0dae6bc83bac0126d4ae0813a"}, "oban": {:hex, :oban, "2.19.4", "045adb10db1161dceb75c254782f97cdc6596e7044af456a59decb6d06da73c1", [:mix], [{:ecto_sql, "~> 3.10", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:ecto_sqlite3, "~> 0.9", [hex: :ecto_sqlite3, repo: "hexpm", optional: true]}, {:igniter, "~> 0.5", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: true]}, {:myxql, "~> 0.7", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.16", [hex: :postgrex, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "5fcc6219e6464525b808d97add17896e724131f498444a292071bf8991c99f97"}, + "oban_met": {:hex, :oban_met, "1.0.2", "6a94e0711f70ad4dded62309e103cd85f3500bf6de7bfd5234fc20fb7121b870", [:mix], [{:oban, "~> 2.19", [hex: :oban, repo: "hexpm", optional: false]}], "hexpm", "e9103a9f3ad5a1751143b490b1ee572855a93956ad958b119ccee62c70984473"}, + "oban_web": {:hex, :oban_web, "2.11.3", "dc4991263fae8ce21391ebcaebfc0a144ef434bf65f0a9fdafc2dd00424069b8", [:mix], [{:jason, "~> 1.2", [hex: :jason, repo: "hexpm", optional: false]}, {:oban, "~> 2.19", [hex: :oban, repo: "hexpm", optional: false]}, {:oban_met, "~> 1.0", [hex: :oban_met, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.7", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 3.3 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_live_view, "~> 1.0", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}, {:phoenix_pubsub, "~> 2.1", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}], "hexpm", "ec414e84cc283c3a06309a1167428a7ece0a5cc179c92b835b77c878278adf9b"}, "owl": {:hex, :owl, "0.12.2", "65906b525e5c3ef51bab6cba7687152be017aebe1da077bb719a5ee9f7e60762", [:mix], [{:ucwidth, "~> 0.2", [hex: :ucwidth, repo: "hexpm", optional: true]}], "hexpm", "6398efa9e1fea70a04d24231e10dcd66c1ac1aa2da418d20ef5357ec61de2880"}, "parse_trans": {:hex, :parse_trans, "3.4.1", "6e6aa8167cb44cc8f39441d05193be6e6f4e7c2946cb2759f015f8c56b76e5ff", [:rebar3], [], "hexpm", "620a406ce75dada827b82e453c19cf06776be266f5a67cff34e1ef2cbb60e49a"}, "phoenix": {:hex, :phoenix, "1.7.19", "36617efe5afbd821099a8b994ff4618a340a5bfb25531a1802c4d4c634017a57", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.1", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.7", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:websock_adapter, "~> 0.5.3", [hex: :websock_adapter, repo: "hexpm", optional: false]}], "hexpm", "ba4dc14458278773f905f8ae6c2ec743d52c3a35b6b353733f64f02dfe096cd6"},