mobilizon/lib/federation/activity_pub/refresher.ex

104 lines
3.2 KiB
Elixir
Raw Normal View History

defmodule Mobilizon.Federation.ActivityPub.Refresher do
@moduledoc """
Module that provides functions to explore and fetch collections on a group
"""
alias Mobilizon.Actors.Actor
alias Mobilizon.Federation.ActivityPub
alias Mobilizon.Federation.ActivityPub.{Fetcher, Transmogrifier}
require Logger
@spec fetch_group(String.t(), Actor.t()) :: :ok
def fetch_group(group_url, %Actor{} = on_behalf_of) do
with {:ok,
%Actor{
outbox_url: outbox_url,
resources_url: resources_url,
members_url: members_url,
posts_url: posts_url,
todos_url: todos_url,
discussions_url: discussions_url,
events_url: events_url
}} <-
ActivityPub.get_or_fetch_actor_by_url(group_url) do
fetch_collection(outbox_url, on_behalf_of)
fetch_collection(members_url, on_behalf_of)
fetch_collection(resources_url, on_behalf_of)
fetch_collection(posts_url, on_behalf_of)
fetch_collection(todos_url, on_behalf_of)
fetch_collection(discussions_url, on_behalf_of)
fetch_collection(events_url, on_behalf_of)
end
end
def fetch_collection(nil, _on_behalf_of), do: :error
def fetch_collection(collection_url, on_behalf_of) do
Logger.debug("Fetching and preparing collection from url")
Logger.debug(inspect(collection_url))
with {:ok, data} <- Fetcher.fetch(collection_url, on_behalf_of: on_behalf_of) do
Logger.debug("Fetch ok, passing to process_collection")
process_collection(data, on_behalf_of)
end
end
@spec fetch_element(String.t(), Actor.t()) :: any()
def fetch_element(url, %Actor{} = on_behalf_of) do
with {:ok, data} <- Fetcher.fetch(url, on_behalf_of: on_behalf_of) do
case handling_element(data) do
{:ok, _activity, entity} ->
{:ok, entity}
{:ok, entity} ->
{:ok, entity}
err ->
{:error, err}
end
end
end
defp process_collection(%{"type" => type, "orderedItems" => items}, _on_behalf_of)
when type in ["OrderedCollection", "OrderedCollectionPage"] do
Logger.debug(
"Processing an OrderedCollection / OrderedCollectionPage with has direct orderedItems"
)
Logger.debug(inspect(items))
Enum.each(items, &handling_element/1)
end
defp process_collection(%{"type" => "OrderedCollection", "first" => first}, on_behalf_of)
when is_map(first),
do: process_collection(first, on_behalf_of)
defp process_collection(%{"type" => "OrderedCollection", "first" => first}, on_behalf_of)
when is_bitstring(first) do
Logger.debug("OrderedCollection has a first property pointing to an URI")
with {:ok, data} <- Fetcher.fetch(first, on_behalf_of: on_behalf_of) do
Logger.debug("Fetched the collection for first property")
process_collection(data, on_behalf_of)
end
end
defp handling_element(data) when is_map(data) do
activity = %{
"type" => "Create",
"to" => data["to"],
"cc" => data["cc"],
"actor" => data["actor"],
"attributedTo" => data["attributedTo"],
"object" => data
}
Transmogrifier.handle_incoming(activity)
end
defp handling_element(uri) when is_binary(uri) do
ActivityPub.fetch_object_from_url(uri)
end
end