feat: Handle follows
This commit is contained in:
parent
2959a86f8f
commit
1259d3202d
9 changed files with 121 additions and 2 deletions
13
.vscode/extensions.json
vendored
Normal file
13
.vscode/extensions.json
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
// See https://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
|
||||
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
|
||||
|
||||
// List of extensions which should be recommended for users of this workspace.
|
||||
"recommendations": [
|
||||
|
||||
],
|
||||
// List of extensions recommended by VS Code that should not be recommended for users of this workspace.
|
||||
"unwantedRecommendations": [
|
||||
|
||||
]
|
||||
}
|
||||
2
lib/activity_pub.ex
Normal file
2
lib/activity_pub.ex
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
defmodule ActivityPub do
|
||||
end
|
||||
|
|
@ -7,6 +7,8 @@ defmodule Postland do
|
|||
if it comes from the database, an external API or others.
|
||||
"""
|
||||
|
||||
use Phoenix.VerifiedRoutes, endpoint: PostlandWeb.Endpoint, router: PostlandWeb.Router
|
||||
|
||||
alias Postland.Accounts
|
||||
|
||||
def temporary_password() do
|
||||
|
|
@ -51,4 +53,8 @@ defmodule Postland do
|
|||
def setup?() do
|
||||
Accounts.solo_user() != nil
|
||||
end
|
||||
|
||||
def my_actor_id do
|
||||
url(~p"/actor")
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,10 +1,37 @@
|
|||
defmodule Postland.Activities do
|
||||
use Phoenix.VerifiedRoutes, endpoint: PostlandWeb.Endpoint, router: PostlandWeb.Router
|
||||
|
||||
alias Postland.Activity
|
||||
alias Postland.Repo
|
||||
|
||||
def process_activity(params) do
|
||||
case record_activity(params) do
|
||||
{:ok, activity} ->
|
||||
cause_effects(activity)
|
||||
|
||||
other ->
|
||||
other
|
||||
end
|
||||
end
|
||||
|
||||
def record_activity(params) do
|
||||
params
|
||||
|> Activity.changeset()
|
||||
|> Repo.insert()
|
||||
end
|
||||
|
||||
def cause_effects(%Activity{actor_id: actor_id, type: "Follow", data: %{"object" => object}} = activity) do
|
||||
if object == Postland.my_actor_id() do
|
||||
case Postland.Follows.record_inbound_request(actor_id) do
|
||||
{:ok, _follow} ->
|
||||
{:ok, activity}
|
||||
other ->
|
||||
other
|
||||
end
|
||||
else
|
||||
{:ok, activity}
|
||||
end
|
||||
end
|
||||
|
||||
def cause_effects(activity), do: activity
|
||||
end
|
||||
|
|
|
|||
29
lib/postland/follow.ex
Normal file
29
lib/postland/follow.ex
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
defmodule Postland.Follow do
|
||||
use Ecto.Schema
|
||||
|
||||
import Ecto.Changeset
|
||||
|
||||
schema "follows" do
|
||||
field :follower, :string, primary_key: true
|
||||
field :followee, :string, primary_key: true
|
||||
field :confirmed_at, :naive_datetime
|
||||
end
|
||||
|
||||
def changeset(follower, followee, confirmed \\ false) do
|
||||
attrs = %{
|
||||
follower: follower,
|
||||
followee: followee,
|
||||
confirmed_at: (if confirmed, do: NaiveDateTime.utc_now())
|
||||
}
|
||||
|
||||
%__MODULE__{}
|
||||
|> cast(attrs, [:follower, :followee, :confirmed_at])
|
||||
|> validate_required(:followee)
|
||||
|> validate_required(:follower)
|
||||
end
|
||||
|
||||
def confirm_changeset(request) do
|
||||
request
|
||||
|> cast(%{confirmed_at: NaiveDateTime.utc_now()}, [:confirmed_at])
|
||||
end
|
||||
end
|
||||
31
lib/postland/follows.ex
Normal file
31
lib/postland/follows.ex
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
defmodule Postland.Follows do
|
||||
import Ecto.Query, warn: false
|
||||
|
||||
alias Postland.Follow
|
||||
alias Postland.Repo
|
||||
|
||||
def pending_inbound_requests() do
|
||||
my_actor_id = Postland.my_actor_id()
|
||||
|
||||
from(f in Follow, where: f.followee == ^my_actor_id, where: is_nil(f.confirmed_at))
|
||||
|> Repo.all()
|
||||
end
|
||||
|
||||
def record_outbound_request(to_actor_id) do
|
||||
Postland.my_actor_id()
|
||||
|> Follow.changeset(to_actor_id)
|
||||
|> Repo.insert(conflict_target: [:followee, :follower], on_conflict: :nothing)
|
||||
end
|
||||
|
||||
def record_inbound_request(from_actor_id) do
|
||||
from_actor_id
|
||||
|> Follow.changeset(Postland.my_actor_id())
|
||||
|> Repo.insert(conflict_target: [:followee, :follower], on_conflict: :nothing)
|
||||
end
|
||||
|
||||
def confirm_request(request) do
|
||||
request
|
||||
|> Follow.confirm_changeset()
|
||||
|> Repo.update()
|
||||
end
|
||||
end
|
||||
|
|
@ -8,7 +8,7 @@ defmodule PostlandWeb.InboxController do
|
|||
|
||||
def post(conn, params) do
|
||||
if Headers.verify(conn.method, conn.request_path, conn.req_headers) do
|
||||
case Activities.record_activity(params) do
|
||||
case Activities.process_activity(params) do
|
||||
{:ok, _activity} ->
|
||||
render(conn, :ok)
|
||||
error ->
|
||||
|
|
|
|||
2
mix.lock
2
mix.lock
|
|
@ -18,7 +18,7 @@
|
|||
"finch": {:hex, :finch, "0.19.0", "c644641491ea854fc5c1bbaef36bfc764e3f08e7185e1f084e35e0672241b76d", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.6.2 or ~> 1.7", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 1.1", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "fc5324ce209125d1e2fa0fcd2634601c52a787aff1cd33ee833664a5af4ea2b6"},
|
||||
"floki": {:hex, :floki, "0.36.2", "a7da0193538c93f937714a6704369711998a51a6164a222d710ebd54020aa7a3", [:mix], [], "hexpm", "a8766c0bc92f074e5cb36c4f9961982eda84c5d2b8e979ca67f5c268ec8ed580"},
|
||||
"gettext": {:hex, :gettext, "0.26.1", "38e14ea5dcf962d1fc9f361b63ea07c0ce715a8ef1f9e82d3dfb8e67e0416715", [:mix], [{:expo, "~> 0.5.1 or ~> 1.0", [hex: :expo, repo: "hexpm", optional: false]}], "hexpm", "01ce56f188b9dc28780a52783d6529ad2bc7124f9744e571e1ee4ea88bf08734"},
|
||||
"heroicons": {:git, "https://github.com/tailwindlabs/heroicons.git", "88ab3a0d790e6a47404cba02800a6b25d2afae50", [tag: "v2.1.1", sparse: "optimized"]},
|
||||
"heroicons": {:git, "https://github.com/tailwindlabs/heroicons.git", "88ab3a0d790e6a47404cba02800a6b25d2afae50", [tag: "v2.1.1", sparse: "optimized", depth: 1]},
|
||||
"hpax": {:hex, :hpax, "1.0.0", "28dcf54509fe2152a3d040e4e3df5b265dcb6cb532029ecbacf4ce52caea3fd2", [:mix], [], "hexpm", "7f1314731d711e2ca5fdc7fd361296593fc2542570b3105595bb0bc6d0fad601"},
|
||||
"jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"},
|
||||
"mime": {:hex, :mime, "2.0.6", "8f18486773d9b15f95f4f4f1e39b710045fa1de891fada4516559967276e4dc2", [:mix], [], "hexpm", "c9945363a6b26d747389aac3643f8e0e09d30499a138ad64fe8fd1d13d9b153e"},
|
||||
|
|
|
|||
11
priv/repo/migrations/20241009214840_add_follows.exs
Normal file
11
priv/repo/migrations/20241009214840_add_follows.exs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
defmodule Postland.Repo.Migrations.AddActors do
|
||||
use Ecto.Migration
|
||||
|
||||
def change do
|
||||
create table("follows", primary_key: false) do
|
||||
add :follower, :string, primary_key: true
|
||||
add :followee, :string, primary_key: true
|
||||
add :confirmed_at, :naive_datetime
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Reference in a new issue