Refactor Mobilizon.Federation.ActivityPub and add typespecs

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
Thomas Citharel
2021-09-28 19:40:37 +02:00
parent 41f086e2c9
commit b5d9b82bdd
125 changed files with 2497 additions and 1673 deletions

View File

@@ -46,7 +46,7 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Discussion do
end
@impl Converter
@spec as_to_model_data(map) :: map() | {:error, any()}
@spec as_to_model_data(map) :: map() | {:error, atom()}
def as_to_model_data(%{"type" => "Note", "name" => name} = object) when is_valid_string(name) do
case extract_actors(object) do
%{actor_id: actor_id, creator_id: creator_id} ->
@@ -57,7 +57,8 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Discussion do
end
end
@spec extract_actors(map()) :: %{actor_id: String.t(), creator_id: String.t()} | {:error, any()}
@spec extract_actors(map()) ::
%{actor_id: String.t(), creator_id: String.t()} | {:error, atom()}
defp extract_actors(%{"actor" => creator_url, "attributedTo" => actor_url} = _object)
when is_valid_string(creator_url) and is_valid_string(actor_url) do
with {:ok, %Actor{id: creator_id, suspended: false}} <-

View File

@@ -45,50 +45,51 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Event do
Converts an AP object data to our internal data structure.
"""
@impl Converter
@spec as_to_model_data(map) :: map() | {:error, any()} | :error
@spec as_to_model_data(map) :: map() | {:error, atom()}
def as_to_model_data(object) do
with {:ok, %Actor{id: actor_id}, attributed_to} <-
maybe_fetch_actor_and_attributed_to_id(object),
{:address, address_id} <-
{:address, get_address(object["location"])},
{:tags, tags} <- {:tags, fetch_tags(object["tag"])},
{:mentions, mentions} <- {:mentions, fetch_mentions(object["tag"])},
{:visibility, visibility} <- {:visibility, get_visibility(object)},
{:options, options} <- {:options, get_options(object)},
{:metadata, metadata} <- {:metadata, get_metdata(object)},
[description: description, picture_id: picture_id, medias: medias] <-
process_pictures(object, actor_id) do
%{
title: object["name"],
description: description,
organizer_actor_id: actor_id,
attributed_to_id: if(is_nil(attributed_to), do: nil, else: attributed_to.id),
picture_id: picture_id,
medias: medias,
begins_on: object["startTime"],
ends_on: object["endTime"],
category: object["category"],
visibility: visibility,
join_options: Map.get(object, "joinMode", "free"),
local: is_local(object["id"]),
options: options,
metadata: metadata,
status: object |> Map.get("ical:status", "CONFIRMED") |> String.downcase(),
online_address: object |> Map.get("attachment", []) |> get_online_address(),
phone_address: object["phoneAddress"],
draft: object["draft"] == true,
url: object["id"],
uuid: object["uuid"],
tags: tags,
mentions: mentions,
physical_address_id: address_id,
updated_at: object["updated"],
publish_at: object["published"],
language: object["inLanguage"]
}
else
{:error, _err} ->
:error
case maybe_fetch_actor_and_attributed_to_id(object) do
{:ok, %Actor{id: actor_id}, attributed_to} ->
address_id = get_address(object["location"])
tags = fetch_tags(object["tag"])
mentions = fetch_mentions(object["tag"])
visibility = get_visibility(object)
options = get_options(object)
metadata = get_metdata(object)
[description: description, picture_id: picture_id, medias: medias] =
process_pictures(object, actor_id)
%{
title: object["name"],
description: description,
organizer_actor_id: actor_id,
attributed_to_id: if(is_nil(attributed_to), do: nil, else: attributed_to.id),
picture_id: picture_id,
medias: medias,
begins_on: object["startTime"],
ends_on: object["endTime"],
category: object["category"],
visibility: visibility,
join_options: Map.get(object, "joinMode", "free"),
local: is_local(object["id"]),
options: options,
metadata: metadata,
status: object |> Map.get("ical:status", "CONFIRMED") |> String.downcase(),
online_address: object |> Map.get("attachment", []) |> get_online_address(),
phone_address: object["phoneAddress"],
draft: object["draft"] == true,
url: object["id"],
uuid: object["uuid"],
tags: tags,
mentions: mentions,
physical_address_id: address_id,
updated_at: object["updated"],
publish_at: object["published"],
language: object["inLanguage"]
}
{:error, err} ->
{:error, err}
end
end

View File

@@ -4,9 +4,11 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.EventMetadata do
"""
alias Mobilizon.Events.EventMetadata
alias Mobilizon.Federation.ActivityStream
@property_value "PropertyValue"
@spec metadata_to_as(EventMetadata.t()) :: map()
def metadata_to_as(%EventMetadata{type: :boolean, value: value, key: key})
when value in ["true", "false"] do
%{
@@ -47,6 +49,7 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.EventMetadata do
)
end
@spec as_to_metadata(ActivityStream.t()) :: map()
def as_to_metadata(%{"type" => @property_value, "propertyID" => key, "value" => value})
when is_boolean(value) do
%{type: :boolean, key: key, value: to_string(value)}

View File

@@ -66,6 +66,9 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Todo do
nil ->
case ActivityPub.fetch_object_from_url(todo_list_url) do
{:ok, _, %TodoList{}} ->
as_to_model_data(object)
{:ok, %TodoList{}} ->
as_to_model_data(object)