chore: refactor sydication
This commit is contained in:
parent
fce42316e8
commit
bec40bed01
7 changed files with 155 additions and 40 deletions
|
@ -1,10 +1,22 @@
|
|||
defmodule Core.Posts do
|
||||
@moduledoc false
|
||||
|
||||
alias Core.Syndication
|
||||
alias Core.Posts.Post
|
||||
|
||||
def get!(id) do
|
||||
Core.Repo.get!(Schema.Post, id)
|
||||
Post.Query.base()
|
||||
|> Core.Repo.get!(id)
|
||||
end
|
||||
|
||||
def get(id) do
|
||||
Post.Query.base()
|
||||
|> Core.Repo.get(id)
|
||||
end
|
||||
|
||||
def get_published_post(id) do
|
||||
Post.Query.published()
|
||||
|> Core.Repo.get(id)
|
||||
end
|
||||
|
||||
def get_published_blog!(%Date{} = publish_date, slug) when is_binary(slug) do
|
||||
|
@ -70,29 +82,28 @@ defmodule Core.Posts do
|
|||
attrs
|
||||
|> change_post()
|
||||
|> Core.Repo.insert()
|
||||
|> do_syndication()
|
||||
end
|
||||
|
||||
def update_post(%Schema.Post{} = post, attrs) do
|
||||
post
|
||||
|> change_post(attrs)
|
||||
|> Core.Repo.update()
|
||||
|> do_syndication()
|
||||
end
|
||||
|
||||
def create_or_update_post(%Schema.Post{} = post, attrs) do
|
||||
post
|
||||
|> change_post(attrs)
|
||||
|> Core.Repo.insert_or_update()
|
||||
|> do_syndication()
|
||||
end
|
||||
|
||||
def publish_post(%Schema.Post{} = post, published_at \\ DateTime.utc_now()) do
|
||||
with {:ok, post} <-
|
||||
post
|
||||
|> Post.publish_changeset(published_at)
|
||||
|> Core.Repo.update(),
|
||||
{:ok, post} <- Core.Syndication.syndicate_to_mastodon(post),
|
||||
{:ok, post} <- Core.Syndication.syndicate_to_bluesky(post) do
|
||||
{:ok, post}
|
||||
end
|
||||
post
|
||||
|> Post.publish_changeset(published_at)
|
||||
|> Core.Repo.update()
|
||||
|> do_syndication()
|
||||
end
|
||||
|
||||
def delete_post(%Schema.Post{} = post, deleted_at \\ DateTime.utc_now()) do
|
||||
|
@ -105,11 +116,29 @@ defmodule Core.Posts do
|
|||
post
|
||||
|> Post.unpublish_changeset()
|
||||
|> Core.Repo.update()
|
||||
|> do_syndication()
|
||||
end
|
||||
|
||||
def undelete_post(%Schema.Post{} = post) do
|
||||
post
|
||||
|> Post.undelete_changeset()
|
||||
|> Core.Repo.update()
|
||||
|> do_syndication()
|
||||
end
|
||||
|
||||
defp do_syndication(%Schema.Post{} = post) do
|
||||
%{"post_id" => post.id}
|
||||
|> Syndication.SyndicatePostWorker.new()
|
||||
|> Oban.insert()
|
||||
|
||||
post
|
||||
end
|
||||
|
||||
defp do_syndication({:ok, %Schema.Post{} = post}) do
|
||||
do_syndication(post)
|
||||
|
||||
{:ok, post}
|
||||
end
|
||||
|
||||
defp do_syndication(other), do: other
|
||||
end
|
||||
|
|
|
@ -20,25 +20,19 @@ defmodule Core.Syndication do
|
|||
end
|
||||
|
||||
def syndicate_to_mastodon(%Schema.Post{} = post) do
|
||||
post = Core.Repo.preload(post, [:mastodon_post])
|
||||
conn = build_mastodon_client_conn()
|
||||
|
||||
if post.syndicate_to_mastodon and is_nil(post.mastodon_post) do
|
||||
conn = build_mastodon_client_conn()
|
||||
{:ok, resp} = MastodonClient.post(conn, "/api/v1/statuses", %{status: post.body})
|
||||
|
||||
{:ok, resp} = MastodonClient.post(conn, "/api/v1/statuses", %{status: post.body})
|
||||
post
|
||||
|> Ecto.build_assoc(:mastodon_post)
|
||||
|> Syndication.MastodonPost.changeset(%{
|
||||
status_id: resp.body["id"],
|
||||
url: resp.body["url"]
|
||||
})
|
||||
|> Core.Repo.insert()
|
||||
|
||||
post
|
||||
|> Ecto.build_assoc(:mastodon_post)
|
||||
|> Syndication.MastodonPost.changeset(%{
|
||||
status_id: resp.body["id"],
|
||||
url: resp.body["url"]
|
||||
})
|
||||
|> Core.Repo.insert()
|
||||
|
||||
{:ok, post}
|
||||
else
|
||||
{:ok, post}
|
||||
end
|
||||
{:ok, post}
|
||||
end
|
||||
|
||||
defp get_mastodon_access_token! do
|
||||
|
@ -94,20 +88,14 @@ defmodule Core.Syndication do
|
|||
end
|
||||
|
||||
def syndicate_to_bluesky(%Schema.Post{} = post) do
|
||||
post = Core.Repo.preload(post, [:bluesky_post])
|
||||
{:ok, bluesky_account} = get_bluesky_account!() |> refresh_bluesky_account()
|
||||
|
||||
if post.syndicate_to_bluesky && is_nil(post.bluesky_post) do
|
||||
{:ok, bluesky_account} = get_bluesky_account!() |> refresh_bluesky_account()
|
||||
with {:ok, resp} <- Syndication.BlueskyClient.post_status(bluesky_account, post.body) do
|
||||
post
|
||||
|> Ecto.build_assoc(:bluesky_post)
|
||||
|> Syndication.BlueskyPost.changeset(resp.body)
|
||||
|> Core.Repo.insert()
|
||||
|
||||
with {:ok, resp} <- Syndication.BlueskyClient.post_status(bluesky_account, post.body) do
|
||||
post
|
||||
|> Ecto.build_assoc(:bluesky_post)
|
||||
|> Syndication.BlueskyPost.changeset(resp.body)
|
||||
|> Core.Repo.insert()
|
||||
|
||||
{:ok, post}
|
||||
end
|
||||
else
|
||||
{:ok, post}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
defmodule Core.Syndication.BlueskyRefreshWorker do
|
||||
use Oban.Worker
|
||||
use Oban.Worker, unique: true, replace: [scheduled: [:scheduled_at]]
|
||||
|
||||
@impl true
|
||||
def perform(%Oban.Job{args: %{"bluesky_account_id" => id}}) do
|
||||
|
|
36
lib/core/syndication/syndicate_post_worker.ex
Normal file
36
lib/core/syndication/syndicate_post_worker.ex
Normal file
|
@ -0,0 +1,36 @@
|
|||
defmodule Core.Syndication.SyndicatePostWorker do
|
||||
use Oban.Worker, unique: true
|
||||
|
||||
alias Core.Posts
|
||||
alias Core.Syndication.SyndicateToBlueskyWorker
|
||||
alias Core.Syndication.SyndicateToMastodonWorker
|
||||
|
||||
def perform(%Oban.Job{args: %{"post_id" => post_id}}) do
|
||||
with {:ok, %Schema.Post{} = post} <- get_post(post_id) do
|
||||
syndicate_worker_args = %{"post_id" => post_id}
|
||||
|
||||
subjobs =
|
||||
[
|
||||
if(post.syndicate_to_bluesky, do: SyndicateToBlueskyWorker.new(syndicate_worker_args)),
|
||||
if(post.syndicate_to_mastodon, do: SyndicateToMastodonWorker.new(syndicate_worker_args))
|
||||
]
|
||||
|> Enum.reject(&is_nil/1)
|
||||
|> Oban.insert_all()
|
||||
|
||||
case subjobs do
|
||||
[] -> {:cancel, "post not set to syndicate"}
|
||||
_ -> :ok
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
defp get_post(post_id) do
|
||||
case Posts.get_published_post(post_id) do
|
||||
%Schema.Post{} = post ->
|
||||
{:ok, post}
|
||||
|
||||
_ ->
|
||||
{:cancel, "post does not exist or is not published"}
|
||||
end
|
||||
end
|
||||
end
|
34
lib/core/syndication/syndicate_to_bluesky_worker.ex
Normal file
34
lib/core/syndication/syndicate_to_bluesky_worker.ex
Normal file
|
@ -0,0 +1,34 @@
|
|||
defmodule Core.Syndication.SyndicateToBlueskyWorker do
|
||||
alias Core.Syndication
|
||||
use Oban.Worker, unique: true
|
||||
|
||||
alias Core.Posts
|
||||
|
||||
def perform(%Oban.Job{args: %{"post_id" => post_id}}) do
|
||||
with {:ok, post} <- get_post(post_id),
|
||||
{:ok, _bluesky_post} <- Syndication.syndicate_to_bluesky(post) do
|
||||
:ok
|
||||
end
|
||||
end
|
||||
|
||||
defp get_post(post_id) do
|
||||
case Posts.get_published_post(post_id) do
|
||||
%Schema.Post{} = post ->
|
||||
post = Core.Repo.preload(post, [:bluesky_post])
|
||||
|
||||
cond do
|
||||
not post.syndicate_to_bluesky ->
|
||||
{:cancel, "post is not marked for syndication to bluesky"}
|
||||
|
||||
not is_nil(post.bluesky_post) ->
|
||||
{:cancel, "post already syndicated to bluesky"}
|
||||
|
||||
true ->
|
||||
{:ok, post}
|
||||
end
|
||||
|
||||
_ ->
|
||||
{:cancel, "post does not exist or is not published"}
|
||||
end
|
||||
end
|
||||
end
|
28
lib/core/syndication/syndicate_to_mastodon_worker.ex
Normal file
28
lib/core/syndication/syndicate_to_mastodon_worker.ex
Normal file
|
@ -0,0 +1,28 @@
|
|||
defmodule Core.Syndication.SyndicateToMastodonWorker do
|
||||
alias Core.Syndication
|
||||
use Oban.Worker, unique: true
|
||||
|
||||
alias Core.Posts
|
||||
alias Core.Syndication
|
||||
|
||||
def perform(%Oban.Job{args: %{"post_id" => post_id}}) do
|
||||
with {:ok, post} <- get_post(post_id),
|
||||
{:ok, _mastodon_post} <- Syndication.syndicate_to_mastodon(post) do
|
||||
:ok
|
||||
end
|
||||
end
|
||||
|
||||
defp get_post(post_id) do
|
||||
case Posts.get(post_id) do
|
||||
%Schema.Post{} = post ->
|
||||
cond do
|
||||
not post.syndicate_to_mastodon -> {:cancel, "post not set to syndicate to mastodon"}
|
||||
not is_nil(post.mastodon_post) -> {:cancel, "post already syndicated to mastodon"}
|
||||
true -> {:ok, post}
|
||||
end
|
||||
|
||||
_ ->
|
||||
{:cancel, "post not found"}
|
||||
end
|
||||
end
|
||||
end
|
|
@ -28,8 +28,8 @@ defmodule Schema.Post do
|
|||
field :published_at, :utc_datetime_usec
|
||||
field :deleted_at, :utc_datetime_usec
|
||||
|
||||
field :syndicate_to_mastodon, :boolean
|
||||
field :syndicate_to_bluesky, :boolean
|
||||
field :syndicate_to_mastodon, :boolean, default: true
|
||||
field :syndicate_to_bluesky, :boolean, default: true
|
||||
|
||||
has_one :mastodon_post, Schema.MastodonPost
|
||||
has_one :bluesky_post, Schema.BlueskyPost
|
||||
|
|
Loading…
Reference in a new issue