Add object getting/fetching

This commit is contained in:
Shadowfacts 2019-09-30 16:52:50 -04:00
parent 6318c16afe
commit db9564cbae
Signed by: shadowfacts
GPG Key ID: 94A5AB95422746E5
2 changed files with 73 additions and 0 deletions

View File

@ -57,6 +57,19 @@ defmodule Clacks.ActivityPub do
} }
end end
@spec synthesized_create(object :: map()) :: map()
def synthesized_create(object) do
%{
"@context" => @context,
"type" => "Create",
"object" => object,
# Mastodon doesn't include 'actor' in notes
"actor" => object["actor"] || object["attributedTo"],
"to" => object["to"],
"cc" => object["cc"]
}
end
@spec object_id(id :: String.t()) :: String.t() @spec object_id(id :: String.t()) :: String.t()
def object_id(id) do def object_id(id) do
url = Application.get_env(:clacks, ClacksWeb.Endpoint)[:url] url = Application.get_env(:clacks, ClacksWeb.Endpoint)[:url]

View File

@ -1,6 +1,9 @@
defmodule Clacks.Object do defmodule Clacks.Object do
require Logger
use Ecto.Schema use Ecto.Schema
import Ecto.Changeset import Ecto.Changeset
alias Clacks.Repo
import Ecto.Query
@type t() :: %__MODULE__{} @type t() :: %__MODULE__{}
@ -15,4 +18,61 @@ defmodule Clacks.Object do
|> cast(attrs, [:data]) |> cast(attrs, [:data])
|> validate_required([:data]) |> validate_required([:data])
end end
@spec get_by_ap_id(
ap_id :: String.t(),
force_refetch :: boolean(),
synthesize_create :: boolean()
) :: t() | nil
def get_by_ap_id(ap_id, force_refetch \\ false, synthesize_create \\ true)
when is_binary(ap_id) do
if force_refetch do
fetch(ap_id, synthesize_create)
else
get_cached_by_ap_id(ap_id) || fetch(ap_id, synthesize_create)
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 o in __MODULE__, where: fragment("?->>'id'", o.data) == ^ap_id)
end
@spec fetch(ap_id :: String.t(), synthesize_create :: boolean()) :: t() | nil
def fetch(ap_id, synthesize_create \\ true) when is_binary(ap_id) do
case Clacks.ActivityPub.Fetcher.fetch_object(ap_id) do
nil ->
nil
data ->
existing = get_cached_by_ap_id(data["id"])
changeset =
changeset(existing || %__MODULE__{}, %{
data: data
})
case Repo.insert_or_update(changeset) do
{:ok, object} ->
if synthesize_create do
create = Clacks.ActivityPub.synthesized_create(data)
changeset =
Clacks.Activity.changeset(%Clacks.Activity{}, %{
data: create,
local: false,
actor: data["actor"]
})
{:ok, _create} = Repo.insert_or_update(changeset)
end
object
{:error, changeset} ->
Logger.error("Couldn't store remote object #{ap_id}: #{inspect(changeset)}")
nil
end
end
end
end end