actor table, untested

This commit is contained in:
Moon Man 2024-08-24 16:54:30 +00:00
parent b20cd38974
commit b23cdc1c9f
3 changed files with 113 additions and 1 deletions

View File

@ -11,4 +11,5 @@ config :vonbraun,
name: "Moon Man",
nickname: "moonman",
domain: "vonbraun.discontent.top",
summary: "I am the famous Fediverse Moon"
summary: "I am the famous Fediverse Moon",
approve_followers: false

View File

@ -0,0 +1,95 @@
defmodule Vonbraun.Ecto.Schema.Actor do
use Ecto.Schema
alias Ecto.Changeset
alias Vonbraun.Repo
@primary_key {:id, :string, autogenerate: false}
schema "actors" do
field(:muted, :boolean)
field(:blocked, :naive_datetime)
field(:follows_me_state, :string)
field(:follows_me_ts, :naive_datetime)
field(:following_state, :string)
field(:following_ts, :naive_datetime)
timestamps()
end
@type t :: %__MODULE__{
muted: boolean(),
blocked: DateTime.t(),
follows_me_state: String.t(),
follows_me_ts: DateTime.t(),
following_state: String.t(),
following_ts: String.t()
}
def changeset(struct, params \\ %{}) do
struct
|> Changeset.cast(params, [
:muted,
:blocked,
:follows_me_state,
:follows_me_ts,
:following_state,
:following_ts
])
end
@spec maybe_insert(String.t()) :: {:ok, __MODULE__.t()} | {:error, Changeset.t()}
def maybe_insert(id) when is_binary(id) do
case Repo.get(__MODULE__, id) do
nil ->
Repo.insert(%__MODULE__{id: id})
actor ->
{:ok, actor}
end
end
@spec maybe_add_follower(String.t()) :: {:ok, __MODULE__.t()} | {:error, Changeset.t()}
def maybe_add_follower(id) when is_binary(id) do
with {:actor, {:ok, actor = %{:follows_me_state => follows_me_state, :blocked => blocked?}}} <-
{:actor, maybe_insert(id)} do
approve_followers? = Application.fetch_env!(:vonbraun, :approve_followers)
cond do
blocked? ->
{:ok, actor}
follows_me_state == "rejected" ->
{:ok, actor}
approve_followers? ->
changeset(actor, %{follows_me_state: "pending", follows_me_ts: DateTime.now!("Etc/UTC")})
|> Repo.update()
!approve_followers? ->
changeset(actor, %{
follows_me_state: "accepted",
follows_me_ts: DateTime.now!("Etc/UTC")
})
|> Repo.update()
end
else
{:actor, {:error, error}} ->
{:error, error}
end
end
@spec remove_follower(String.t()) :: {:ok, __MODULE__.t() | nil} | {:error, Changeset.t()}
def remove_follower(id) when is_binary(id) do
case Repo.get(__MODULE__, id) do
nil ->
{:ok, nil}
actor = %{:follows_me_state => follows_me_state} ->
if follows_me_state == "accepted" do
changeset(actor, %{follows_me_state: nil, follows_me_ts: DateTime.now!("Etc/UTC")})
|> Repo.update()
else
{:ok, actor}
end
end
end
end

View File

@ -7,5 +7,21 @@ defmodule Vonbraun.Repo.Migrations.Initial do
add(:value, :string)
timestamps()
end
# Only put state in here not AP data
create table(:actors, primary_key: false) do
add(:id, :string, primary_key: true)
add(:muted, :boolean)
add(:blocked, :naive_datetime)
add(:follows_me_state, :string)
add(:follows_me_ts, :naive_datetime)
add(:following_state, :string)
add(:following_ts, :naive_datetime)
timestamps()
end
create index(:actors, :muted)
create index(:actors, [:follows_me_state, :follows_me_ts])
create index(:actors, [:following_state, :following_ts])
end
end