Various refactoring and typespec improvements

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
Thomas Citharel
2021-09-24 16:46:42 +02:00
parent d235653876
commit 1893d9f55b
142 changed files with 1854 additions and 1297 deletions

View File

@@ -15,15 +15,8 @@ defmodule Mobilizon.GraphQL.API.Events do
"""
@spec create_event(map) :: {:ok, Activity.t(), Event.t()} | any
def create_event(args) do
with organizer_actor <- Map.get(args, :organizer_actor),
args <- extract_pictures_from_event_body(args, organizer_actor),
args <-
Map.update(args, :picture, nil, fn picture ->
process_picture(picture, organizer_actor)
end) do
# For now we don't federate drafts but it will be needed if we want to edit them as groups
ActivityPub.create(:event, args, should_federate(args))
end
# For now we don't federate drafts but it will be needed if we want to edit them as groups
ActivityPub.create(:event, prepare_args(args), should_federate(args))
end
@doc """
@@ -31,23 +24,28 @@ defmodule Mobilizon.GraphQL.API.Events do
"""
@spec update_event(map, Event.t()) :: {:ok, Activity.t(), Event.t()} | any
def update_event(args, %Event{} = event) do
with organizer_actor <- Map.get(args, :organizer_actor),
args <- extract_pictures_from_event_body(args, organizer_actor),
args <-
Map.update(args, :picture, nil, fn picture ->
process_picture(picture, organizer_actor)
end) do
ActivityPub.update(event, args, should_federate(args))
end
ActivityPub.update(event, prepare_args(args), should_federate(args))
end
@doc """
Trigger the deletion of an event
"""
@spec delete_event(Event.t(), Actor.t(), boolean()) :: {:ok, Activity.t(), Entity.t()} | any()
def delete_event(%Event{} = event, %Actor{} = actor, federate \\ true) do
ActivityPub.delete(event, actor, federate)
end
@spec prepare_args(map) :: map
defp prepare_args(args) do
organizer_actor = Map.get(args, :organizer_actor)
args
|> extract_pictures_from_event_body(organizer_actor)
|> Map.update(:picture, nil, fn picture ->
process_picture(picture, organizer_actor)
end)
end
defp process_picture(nil, _), do: nil
defp process_picture(%{media_id: _picture_id} = args, _), do: args
@@ -75,6 +73,7 @@ defmodule Mobilizon.GraphQL.API.Events do
defp extract_pictures_from_event_body(args, _), do: args
@spec should_federate(map()) :: boolean
defp should_federate(%{attributed_to_id: attributed_to_id}) when not is_nil(attributed_to_id),
do: true

View File

@@ -7,72 +7,80 @@ defmodule Mobilizon.GraphQL.API.Follows do
alias Mobilizon.Actors.{Actor, Follower}
alias Mobilizon.Federation.ActivityPub
alias Mobilizon.Federation.ActivityPub.Activity
require Logger
@doc """
Make an actor (`follower`) follow another (`followed`).
"""
@spec follow(follower :: Actor.t(), followed :: Actor.t()) ::
{:ok, Mobilizon.Federation.ActivityPub.Activity.t(), Mobilizon.Actors.Follower.t()}
| {:error, String.t()}
def follow(%Actor{} = follower, %Actor{} = followed) do
case ActivityPub.follow(follower, followed) do
{:ok, activity, follow} ->
{:ok, activity, follow}
{:error, e} ->
Logger.warn("Error while following actor: #{inspect(e)}")
{:error, e}
e ->
Logger.warn("Error while following actor: #{inspect(e)}")
{:error, e}
end
ActivityPub.follow(follower, followed)
end
@doc """
Make an actor (`follower`) unfollow another (`followed`).
"""
@spec unfollow(follower :: Actor.t(), followed :: Actor.t()) ::
{:ok, Mobilizon.Federation.ActivityPub.Activity.t(), Mobilizon.Actors.Follower.t()}
| {:error, String.t()}
def unfollow(%Actor{} = follower, %Actor{} = followed) do
case ActivityPub.unfollow(follower, followed) do
{:ok, activity, follow} ->
{:ok, activity, follow}
e ->
Logger.warn("Error while unfollowing actor: #{inspect(e)}")
{:error, e}
end
ActivityPub.unfollow(follower, followed)
end
def accept(%Actor{} = follower, %Actor{} = followed) do
Logger.debug("We're trying to accept a follow")
@doc """
Make an actor (`followed`) accept the follow from another (`follower`).
"""
@spec accept(follower :: Actor.t(), followed :: Actor.t()) ::
{:ok, Mobilizon.Federation.ActivityPub.Activity.t(), Mobilizon.Actors.Follower.t()}
| {:error, String.t()}
def accept(%Actor{url: follower_url} = follower, %Actor{url: followed_url} = followed) do
Logger.debug(
"We're trying to accept a follow: #{followed_url} is accepting #{follower_url} follow request."
)
case Actors.is_following(follower, followed) do
%Follower{approved: false} = follow ->
ActivityPub.accept(
:follow,
follow,
true
)
with %Follower{approved: false} = follow <-
Actors.is_following(follower, followed),
{:ok, %Activity{} = activity, %Follower{approved: true} = follow} <-
ActivityPub.accept(
:follow,
follow,
true
) do
{:ok, activity, follow}
else
%Follower{approved: true} ->
{:error, "Follow already accepted"}
nil ->
{:error, "Can't accept follow: #{follower_url} is not following #{followed_url}."}
end
end
def reject(%Actor{} = follower, %Actor{} = followed) do
Logger.debug("We're trying to reject a follow")
@doc """
Make an actor (`followed`) reject the follow from another (`follower`).
"""
@spec reject(follower :: Actor.t(), followed :: Actor.t()) ::
{:ok, Mobilizon.Federation.ActivityPub.Activity.t(), Mobilizon.Actors.Follower.t()}
| {:error, String.t()}
def reject(%Actor{url: follower_url} = follower, %Actor{url: followed_url} = followed) do
Logger.debug(
"We're trying to reject a follow: #{followed_url} is rejecting #{follower_url} follow request."
)
with {:follower, %Follower{} = follow} <-
{:follower, Actors.is_following(follower, followed)},
{:ok, %Activity{} = activity, %Follower{} = follow} <-
ActivityPub.reject(
:follow,
follow,
true
) do
{:ok, activity, follow}
else
{:follower, nil} ->
{:error, "Follow not found"}
{:follower, %Follower{approved: true}} ->
case Actors.is_following(follower, followed) do
%Follower{approved: true} ->
{:error, "Follow already accepted"}
%Follower{} = follow ->
ActivityPub.reject(
:follow,
follow,
true
)
nil ->
{:error, "Follow not found"}
end
end
end

View File

@@ -11,23 +11,23 @@ defmodule Mobilizon.GraphQL.API.Participations do
alias Mobilizon.Service.Notifications.Scheduler
alias Mobilizon.Web.Email.Participation
@spec join(Event.t(), Actor.t(), map()) :: {:ok, Activity.t(), Participant.t()}
@spec join(Event.t(), Actor.t(), map()) ::
{:ok, Activity.t(), Participant.t()} | {:error, :already_participant}
def join(%Event{id: event_id} = event, %Actor{id: actor_id} = actor, args \\ %{}) do
with {:error, :participant_not_found} <-
Mobilizon.Events.get_participant(event_id, actor_id, args),
{:ok, activity, participant} <-
ActivityPub.join(event, actor, Map.get(args, :local, true), %{metadata: args}) do
{:ok, activity, participant}
case Mobilizon.Events.get_participant(event_id, actor_id, args) do
{:ok, %Participant{}} ->
{:error, :already_participant}
{:error, :participant_not_found} ->
ActivityPub.join(event, actor, Map.get(args, :local, true), %{metadata: args})
end
end
@spec leave(Event.t(), Actor.t()) :: {:ok, Activity.t(), Participant.t()}
def leave(%Event{} = event, %Actor{} = actor, args \\ %{}) do
with {:ok, activity, participant} <-
ActivityPub.leave(event, actor, Map.get(args, :local, true), %{metadata: args}) do
{:ok, activity, participant}
end
end
@spec leave(Event.t(), Actor.t(), map()) ::
{:ok, Activity.t(), Participant.t()}
| {:error, :is_only_organizer | :participant_not_found | Ecto.Changeset.t()}
def leave(%Event{} = event, %Actor{} = actor, args \\ %{}),
do: ActivityPub.leave(event, actor, Map.get(args, :local, true), %{metadata: args})
@doc """
Update participation status
@@ -36,7 +36,6 @@ defmodule Mobilizon.GraphQL.API.Participations do
def update(%Participant{} = participation, %Actor{} = moderator, :participant),
do: accept(participation, moderator)
@spec update(Participant.t(), Actor.t(), atom()) :: {:ok, Activity.t(), Participant.t()}
def update(%Participant{} = participation, %Actor{} = _moderator, :not_approved) do
with {:ok, %Participant{} = participant} <-
Events.update_participant(participation, %{role: :not_approved}) do
@@ -45,7 +44,6 @@ defmodule Mobilizon.GraphQL.API.Participations do
end
end
@spec update(Participant.t(), Actor.t(), atom()) :: {:ok, Activity.t(), Participant.t()}
def update(%Participant{} = participation, %Actor{} = moderator, :rejected),
do: reject(participation, moderator)

View File

@@ -59,8 +59,8 @@ defmodule Mobilizon.GraphQL.API.Search do
@doc """
Search events
"""
@spec search_events(String.t(), integer | nil, integer | nil) ::
{:ok, Page.t()} | {:error, String.t()}
@spec search_events(map(), integer | nil, integer | nil) ::
{:ok, Page.t()}
def search_events(%{term: term} = args, page \\ 1, limit \\ 10) do
term = String.trim(term)
@@ -78,6 +78,7 @@ defmodule Mobilizon.GraphQL.API.Search do
end
end
@spec interact(String.t()) :: {:ok, struct()} | {:error, :not_found}
def interact(uri) do
case ActivityPub.fetch_object_from_url(uri) do
{:ok, object} ->