Add activity getting/fetching

This commit is contained in:
Shadowfacts 2019-09-30 17:02:03 -04:00
parent db9564cbae
commit 7548cbe40c
Signed by: shadowfacts
GPG Key ID: 94A5AB95422746E5
5 changed files with 63 additions and 9 deletions

View File

@ -1,6 +1,9 @@
defmodule Clacks.Activity do defmodule Clacks.Activity 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__{}
@ -21,4 +24,49 @@ defmodule Clacks.Activity do
|> cast(attrs, [:data, :local, :actor]) |> cast(attrs, [:data, :local, :actor])
|> validate_required([:data, :local, :actor]) |> validate_required([:data, :local, :actor])
end 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) 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) do
Repo.one(from a in __MODULE__, where: fragment("?->>'id'", a.data) == ^ap_id)
end
@spec fetch(ap_id :: String.t()) :: t() | nil
def fetch(ap_id) do
case Clacks.ActivityPub.Fetcher.fetch_activity(ap_id) do
nil ->
nil
data ->
actor = data["actor"] || data["attributedTo"]
existing = get_cached_by_ap_id(data["id"])
changeset =
changeset(existing || %__MODULE__{}, %{
data: data,
local: false,
actor: actor
})
case Repo.insert_or_update(changeset) do
{:ok, activity} ->
_ = Clacks.Actor.get_by_ap_id(actor)
activity
{:error, changeset} ->
Logger.error("Couldn't store remote activity #{ap_id}: #{inspect(changeset)}")
nil
end
end
end
end end

View File

@ -63,7 +63,6 @@ defmodule Clacks.ActivityPub do
"@context" => @context, "@context" => @context,
"type" => "Create", "type" => "Create",
"object" => object, "object" => object,
# Mastodon doesn't include 'actor' in notes
"actor" => object["actor"] || object["attributedTo"], "actor" => object["actor"] || object["attributedTo"],
"to" => object["to"], "to" => object["to"],
"cc" => object["cc"] "cc" => object["cc"]

View File

@ -28,6 +28,11 @@ defmodule Clacks.ActivityPub.Fetcher do
end end
end end
@spec fetch_activity(id :: String.t()) :: map() | nil
def fetch_activity(id) do
fetch_object(id)
end
@spec fetch(uri :: String.t()) :: map() | nil @spec fetch(uri :: String.t()) :: map() | nil
defp fetch(uri) do defp fetch(uri) do
Logger.debug("Attempting to fetch AP object at #{uri}") Logger.debug("Attempting to fetch AP object at #{uri}")

View File

@ -27,7 +27,7 @@ defmodule Clacks.Actor do
end end
@spec get_by_ap_id(ap_id :: String.t(), force_refetch :: boolean()) :: t() | nil @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 def get_by_ap_id(ap_id, force_refetch \\ false) do
if force_refetch do if force_refetch do
fetch(ap_id) fetch(ap_id)
else else
@ -36,12 +36,12 @@ defmodule Clacks.Actor do
end end
@spec get_cached_by_ap_id(ap_id :: String.t()) :: t() | nil @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 def get_cached_by_ap_id(ap_id) do
Repo.one(from a in __MODULE__, where: a.ap_id == ^ap_id) Repo.one(from a in __MODULE__, where: a.ap_id == ^ap_id)
end end
@spec fetch(ap_id :: String.t()) :: t() | nil @spec fetch(ap_id :: String.t()) :: t() | nil
def fetch(ap_id) when is_binary(ap_id) do def fetch(ap_id) do
case Clacks.ActivityPub.Fetcher.fetch_actor(ap_id) do case Clacks.ActivityPub.Fetcher.fetch_actor(ap_id) do
nil -> nil ->
nil nil

View File

@ -24,8 +24,7 @@ defmodule Clacks.Object do
force_refetch :: boolean(), force_refetch :: boolean(),
synthesize_create :: boolean() synthesize_create :: boolean()
) :: t() | nil ) :: t() | nil
def get_by_ap_id(ap_id, force_refetch \\ false, synthesize_create \\ true) def get_by_ap_id(ap_id, force_refetch \\ false, synthesize_create \\ true) do
when is_binary(ap_id) do
if force_refetch do if force_refetch do
fetch(ap_id, synthesize_create) fetch(ap_id, synthesize_create)
else else
@ -34,12 +33,12 @@ defmodule Clacks.Object do
end end
@spec get_cached_by_ap_id(ap_id :: String.t()) :: t() | nil @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 def get_cached_by_ap_id(ap_id) do
Repo.one(from o in __MODULE__, where: fragment("?->>'id'", o.data) == ^ap_id) Repo.one(from o in __MODULE__, where: fragment("?->>'id'", o.data) == ^ap_id)
end end
@spec fetch(ap_id :: String.t(), synthesize_create :: boolean()) :: t() | nil @spec fetch(ap_id :: String.t(), synthesize_create :: boolean()) :: t() | nil
def fetch(ap_id, synthesize_create \\ true) when is_binary(ap_id) do def fetch(ap_id, synthesize_create \\ true) do
case Clacks.ActivityPub.Fetcher.fetch_object(ap_id) do case Clacks.ActivityPub.Fetcher.fetch_object(ap_id) do
nil -> nil ->
nil nil
@ -54,6 +53,9 @@ defmodule Clacks.Object do
case Repo.insert_or_update(changeset) do case Repo.insert_or_update(changeset) do
{:ok, object} -> {:ok, object} ->
actor = data["actor"] || data["attributedTo"]
_ = Clacks.Actor.get_by_ap_id(actor)
if synthesize_create do if synthesize_create do
create = Clacks.ActivityPub.synthesized_create(data) create = Clacks.ActivityPub.synthesized_create(data)
@ -61,7 +63,7 @@ defmodule Clacks.Object do
Clacks.Activity.changeset(%Clacks.Activity{}, %{ Clacks.Activity.changeset(%Clacks.Activity{}, %{
data: create, data: create,
local: false, local: false,
actor: data["actor"] actor: actor
}) })
{:ok, _create} = Repo.insert_or_update(changeset) {:ok, _create} = Repo.insert_or_update(changeset)