72 lines
1.8 KiB
Elixir
72 lines
1.8 KiB
Elixir
|
defmodule Clacks.Actor do
|
||
|
require Logger
|
||
|
use Ecto.Schema
|
||
|
import Ecto.Changeset
|
||
|
import Ecto.Query
|
||
|
alias Clacks.Repo
|
||
|
|
||
|
@type t() :: %__MODULE__{}
|
||
|
|
||
|
@primary_key {:id, FlakeId.Ecto.Type, autogenerate: true}
|
||
|
|
||
|
schema "actors" do
|
||
|
field :ap_id, :string
|
||
|
field :nickname, :string
|
||
|
field :local, :boolean
|
||
|
field :data, :map
|
||
|
|
||
|
belongs_to :user, Clacks.User
|
||
|
|
||
|
timestamps()
|
||
|
end
|
||
|
|
||
|
def changeset(%__MODULE__{} = schema, attrs) do
|
||
|
schema
|
||
|
|> cast(attrs, [:ap_id, :nickname, :local, :data])
|
||
|
|> validate_required([:ap_id, :nickname, :local, :data])
|
||
|
end
|
||
|
|
||
|
@spec get_by_ap_id(ap_id :: String.t(), force_refetch :: boolean()) :: t() | nil
|
||
|
def get_by_ap_id(ap_id, force_refetch \\ false) when is_binary(ap_id) do
|
||
|
if force_refetch do
|
||
|
fetch(ap_id)
|
||
|
else
|
||
|
get_cached_by_ap_id(ap_id) || fetch(ap_id)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
@spec get_cached_by_ap_id(ap_id :: String.t()) :: t() | nil
|
||
|
def get_cached_by_ap_id(ap_id) when is_binary(ap_id) do
|
||
|
Repo.one(from a in __MODULE__, where: a.ap_id == ^ap_id)
|
||
|
end
|
||
|
|
||
|
@spec fetch(ap_id :: String.t()) :: t() | nil
|
||
|
def fetch(ap_id) when is_binary(ap_id) do
|
||
|
case Clacks.ActivityPub.Fetcher.fetch_actor(ap_id) do
|
||
|
nil ->
|
||
|
nil
|
||
|
|
||
|
data ->
|
||
|
ap_id = data["id"]
|
||
|
existing = get_cached_by_ap_id(ap_id) |> Repo.preload(:user)
|
||
|
|
||
|
changeset =
|
||
|
changeset(existing || %__MODULE__{}, %{
|
||
|
ap_id: ap_id,
|
||
|
nickname: data["preferredUsername"] <> "@" <> URI.parse(ap_id).host,
|
||
|
local: false,
|
||
|
data: data
|
||
|
})
|
||
|
|
||
|
case Repo.insert_or_update(changeset) do
|
||
|
{:ok, actor} ->
|
||
|
actor
|
||
|
|
||
|
{:error, changeset} ->
|
||
|
Logger.error("Couldn't store remote actor #{ap_id}: #{inspect(changeset)}")
|
||
|
nil
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|