Refactoring of Actors context

This commit is contained in:
miffigriffy
2019-09-09 00:52:49 +02:00
parent 3a4a006c44
commit 4418275223
36 changed files with 1145 additions and 1345 deletions

View File

@@ -32,7 +32,7 @@ defmodule MobilizonWeb.API.Follows do
def accept(%Actor{} = follower, %Actor{} = followed) do
with %Follower{approved: false, id: follow_id, url: follow_url} = follow <-
Actor.following?(follower, followed),
Actors.following?(follower, followed),
activity_follow_url <- "#{MobilizonWeb.Endpoint.url()}/accept/follow/#{follow_id}",
data <-
ActivityPub.Utils.make_follow_data(followed, follower, follow_url),

View File

@@ -1,20 +1,21 @@
defmodule MobilizonWeb.API.Search do
@moduledoc """
API for Search
API for search.
"""
alias Mobilizon.Service.ActivityPub
alias Mobilizon.Actors
alias Mobilizon.Actors.Actor
alias Mobilizon.Actors.ActorType
alias Mobilizon.Events
alias Mobilizon.Events.{Event, Comment}
alias Mobilizon.Service.ActivityPub
alias Mobilizon.Storage.Page
require Logger
@doc """
Search actors
Searches actors.
"""
@spec search_actors(String.t(), integer(), integer(), String.t()) ::
{:ok, %{total: integer(), elements: list(Actor.t())}} | {:error, any()}
@spec search_actors(String.t(), integer | nil, integer | nil, ActorType.t()) ::
{:ok, Page.t()} | {:error, String.t()}
def search_actors(search, page \\ 1, limit \\ 10, result_type) do
search = String.trim(search)
@@ -22,31 +23,33 @@ defmodule MobilizonWeb.API.Search do
search == "" ->
{:error, "Search can't be empty"}
# Some URLs could be domain.tld/@username, so keep this condition above handle_search? function
url_search?(search) ->
# If this is not an actor, skip
# Some URLs could be domain.tld/@username, so keep this condition above
# the `is_handle` function
is_url(search) ->
# skip, if it's not an actor
case process_from_url(search) do
%{:total => total, :elements => [%Actor{}] = elements} ->
{:ok, %{total: total, elements: elements}}
%Page{total: _total, elements: _elements} = page ->
{:ok, page}
_ ->
{:ok, %{total: 0, elements: []}}
end
handle_search?(search) ->
is_handle(search) ->
{:ok, process_from_username(search)}
true ->
{:ok,
Actors.find_and_count_actors_by_username_or_name(search, [result_type], page, limit)}
page = Actors.build_actors_by_username_or_name_page(search, [result_type], page, limit)
{:ok, page}
end
end
@doc """
Search events
"""
@spec search_events(String.t(), integer(), integer()) ::
{:ok, %{total: integer(), elements: list(Event.t())}} | {:error, any()}
@spec search_events(String.t(), integer | nil, integer | nil) ::
{:ok, Page.t()} | {:error, String.t()}
def search_events(search, page \\ 1, limit \\ 10) do
search = String.trim(search)
@@ -54,11 +57,11 @@ defmodule MobilizonWeb.API.Search do
search == "" ->
{:error, "Search can't be empty"}
url_search?(search) ->
# If this is not an event, skip
is_url(search) ->
# skip, if it's w not an actor
case process_from_url(search) do
{total = total, [%Event{} = elements]} ->
{:ok, %{total: total, elements: elements}}
%Page{total: _total, elements: _elements} = page ->
{:ok, page}
_ ->
{:ok, %{total: 0, elements: []}}
@@ -70,43 +73,36 @@ defmodule MobilizonWeb.API.Search do
end
# If the search string is an username
@spec process_from_username(String.t()) :: %{total: integer(), elements: [Actor.t()]}
@spec process_from_username(String.t()) :: Page.t()
defp process_from_username(search) do
case ActivityPub.find_or_make_actor_from_nickname(search) do
{:ok, actor} ->
%{total: 1, elements: [actor]}
%Page{total: 1, elements: [actor]}
{:error, _err} ->
Logger.debug(fn -> "Unable to find or make actor '#{search}'" end)
%{total: 0, elements: []}
%Page{total: 0, elements: []}
end
end
# If the search string is an URL
@spec process_from_url(String.t()) :: %{
total: integer(),
elements: [Actor.t() | Event.t() | Comment.t()]
}
@spec process_from_url(String.t()) :: Page.t()
defp process_from_url(search) do
case ActivityPub.fetch_object_from_url(search) do
{:ok, object} ->
%{total: 1, elements: [object]}
%Page{total: 1, elements: [object]}
{:error, _err} ->
Logger.debug(fn -> "Unable to find or make object from URL '#{search}'" end)
%{total: 0, elements: []}
%Page{total: 0, elements: []}
end
end
# Is the search an URL search?
@spec url_search?(String.t()) :: boolean
defp url_search?(search) do
String.starts_with?(search, "https://") or String.starts_with?(search, "http://")
end
@spec is_url(String.t()) :: boolean
defp is_url(search), do: String.starts_with?(search, ["http://", "https://"])
# Is the search an handle search?
@spec handle_search?(String.t()) :: boolean
defp handle_search?(search) do
String.match?(search, ~r/@/)
end
@spec is_handle(String.t()) :: boolean
defp is_handle(search), do: String.match?(search, ~r/@/)
end

View File

@@ -31,7 +31,7 @@ defmodule MobilizonWeb.ActivityPubController do
def following(conn, %{"name" => name, "page" => page}) do
with {page, ""} <- Integer.parse(page),
%Actor{} = actor <- Actors.get_local_actor_by_name_with_everything(name) do
%Actor{} = actor <- Actors.get_local_actor_by_name_with_preload(name) do
conn
|> put_resp_header("content-type", "application/activity+json")
|> json(ActorView.render("following.json", %{actor: actor, page: page}))
@@ -39,7 +39,7 @@ defmodule MobilizonWeb.ActivityPubController do
end
def following(conn, %{"name" => name}) do
with %Actor{} = actor <- Actors.get_local_actor_by_name_with_everything(name) do
with %Actor{} = actor <- Actors.get_local_actor_by_name_with_preload(name) do
conn
|> put_resp_header("content-type", "application/activity+json")
|> json(ActorView.render("following.json", %{actor: actor}))
@@ -48,7 +48,7 @@ defmodule MobilizonWeb.ActivityPubController do
def followers(conn, %{"name" => name, "page" => page}) do
with {page, ""} <- Integer.parse(page),
%Actor{} = actor <- Actors.get_local_actor_by_name_with_everything(name) do
%Actor{} = actor <- Actors.get_local_actor_by_name_with_preload(name) do
conn
|> put_resp_header("content-type", "application/activity+json")
|> json(ActorView.render("followers.json", %{actor: actor, page: page}))
@@ -56,7 +56,7 @@ defmodule MobilizonWeb.ActivityPubController do
end
def followers(conn, %{"name" => name}) do
with %Actor{} = actor <- Actors.get_local_actor_by_name_with_everything(name) do
with %Actor{} = actor <- Actors.get_local_actor_by_name_with_preload(name) do
conn
|> put_resp_header("content-type", "application/activity+json")
|> json(ActorView.render("followers.json", %{actor: actor}))

View File

@@ -76,7 +76,7 @@ defmodule MobilizonWeb.Resolvers.Group do
) do
with {:ok, %Actor{} = group} <- Actors.get_group_by_actor_id(group_id),
{:is_owned, %Actor{}} <- User.owns_actor(user, actor_id),
{:ok, %Member{} = member} <- Member.get_member(actor_id, group.id),
{:ok, %Member{} = member} <- Actors.get_member(actor_id, group.id),
{:is_admin, true} <- Member.is_administrator(member),
group <- Actors.delete_group!(group) do
{:ok, %{id: group.id}}
@@ -109,9 +109,9 @@ defmodule MobilizonWeb.Resolvers.Group do
) do
with {:is_owned, %Actor{} = actor} <- User.owns_actor(user, actor_id),
{:ok, %Actor{} = group} <- Actors.get_group_by_actor_id(group_id),
{:error, :member_not_found} <- Member.get_member(actor.id, group.id),
{:error, :member_not_found} <- Actors.get_member(actor.id, group.id),
{:is_able_to_join, true} <- {:is_able_to_join, Member.can_be_joined(group)},
role <- Mobilizon.Actors.get_default_member_role(group),
role <- Member.get_default_member_role(group),
{:ok, _} <- Actors.create_member(%{parent_id: group.id, actor_id: actor.id, role: role}) do
{
:ok,
@@ -149,7 +149,7 @@ defmodule MobilizonWeb.Resolvers.Group do
%{context: %{current_user: user}}
) do
with {:is_owned, %Actor{} = actor} <- User.owns_actor(user, actor_id),
{:ok, %Member{} = member} <- Member.get_member(actor.id, group_id),
{:ok, %Member{} = member} <- Actors.get_member(actor.id, group_id),
{:only_administrator, false} <-
{:only_administrator, check_that_member_is_not_last_administrator(group_id, actor_id)},
{:ok, _} <-
@@ -176,7 +176,7 @@ defmodule MobilizonWeb.Resolvers.Group do
# and that it's the actor requesting leaving the group we return true
@spec check_that_member_is_not_last_administrator(integer(), integer()) :: boolean()
defp check_that_member_is_not_last_administrator(group_id, actor_id) do
case Member.list_administrator_members_for_group(group_id) do
case Actors.list_administrator_members_for_group(group_id) do
[%Member{actor: %Actor{id: member_actor_id}}] ->
actor_id == member_actor_id

View File

@@ -2,12 +2,13 @@ defmodule MobilizonWeb.Resolvers.Person do
@moduledoc """
Handles the person-related GraphQL calls
"""
alias Mobilizon.Actors
alias Mobilizon.Actors.{Actor, Member}
alias Mobilizon.Users.User
alias Mobilizon.Users
alias Mobilizon.Actors.Actor
alias Mobilizon.Events
alias Mobilizon.Service.ActivityPub
alias Mobilizon.Users
alias Mobilizon.Users.User
@doc """
Find a person
@@ -206,7 +207,7 @@ defmodule MobilizonWeb.Resolvers.Person do
# We check that the actor is not the last administrator/creator of a group
@spec last_admin_of_a_group?(integer()) :: boolean()
defp last_admin_of_a_group?(actor_id) do
length(Member.list_group_id_where_last_administrator(actor_id)) > 0
length(Actors.list_group_id_where_last_administrator(actor_id)) > 0
end
@spec proxify_avatar(Actor.t()) :: Actor.t()

View File

@@ -91,7 +91,7 @@ defmodule MobilizonWeb.Resolvers.Report do
when is_moderator(role) do
with {:is_owned, %Actor{}} <- User.owns_actor(user, moderator_id),
%Report{} = report <- Reports.get_report(report_id),
%Actor{} = moderator <- Actors.get_local_actor_with_everything(moderator_id),
%Actor{} = moderator <- Actors.get_local_actor_with_preload(moderator_id),
{:ok, %Note{} = note} <-
MobilizonWeb.API.Reports.create_report_note(report, moderator, content) do
{:ok, note}
@@ -106,7 +106,7 @@ defmodule MobilizonWeb.Resolvers.Report do
when is_moderator(role) do
with {:is_owned, %Actor{}} <- User.owns_actor(user, moderator_id),
%Note{} = note <- Reports.get_note(note_id),
%Actor{} = moderator <- Actors.get_local_actor_with_everything(moderator_id),
%Actor{} = moderator <- Actors.get_local_actor_with_preload(moderator_id),
{:ok, %Note{} = note} <-
MobilizonWeb.API.Reports.delete_report_note(note, moderator) do
{:ok, %{id: note.id}}

View File

@@ -1,6 +1,7 @@
defmodule MobilizonWeb.ActivityPub.ActorView do
use MobilizonWeb, :view
alias Mobilizon.Actors
alias Mobilizon.Actors.Actor
alias Mobilizon.Service.ActivityPub
alias Mobilizon.Service.ActivityPub.Utils
@@ -47,8 +48,8 @@ defmodule MobilizonWeb.ActivityPub.ActorView do
def render("following.json", %{actor: actor, page: page}) do
%{total: total, elements: following} =
if Actor.public_visibility?(actor),
do: Actor.get_followings(actor, page),
if Actor.is_public_visibility(actor),
do: Actors.get_followings(actor, page),
else: @private_visibility_empty_collection
following
@@ -58,8 +59,8 @@ defmodule MobilizonWeb.ActivityPub.ActorView do
def render("following.json", %{actor: actor}) do
%{total: total, elements: following} =
if Actor.public_visibility?(actor),
do: Actor.get_followings(actor),
if Actor.is_public_visibility(actor),
do: Actors.get_followings(actor),
else: @private_visibility_empty_collection
%{
@@ -73,8 +74,8 @@ defmodule MobilizonWeb.ActivityPub.ActorView do
def render("followers.json", %{actor: actor, page: page}) do
%{total: total, elements: followers} =
if Actor.public_visibility?(actor),
do: Actor.get_followers(actor, page),
if Actor.is_public_visibility(actor),
do: Actors.get_followers(actor, page),
else: @private_visibility_empty_collection
followers
@@ -84,8 +85,8 @@ defmodule MobilizonWeb.ActivityPub.ActorView do
def render("followers.json", %{actor: actor}) do
%{total: total, elements: followers} =
if Actor.public_visibility?(actor),
do: Actor.get_followers(actor),
if Actor.is_public_visibility(actor),
do: Actors.get_followers(actor),
else: @private_visibility_empty_collection
%{
@@ -99,7 +100,7 @@ defmodule MobilizonWeb.ActivityPub.ActorView do
def render("outbox.json", %{actor: actor, page: page}) do
%{total: total, elements: followers} =
if Actor.public_visibility?(actor),
if Actor.is_public_visibility(actor),
do: ActivityPub.fetch_public_activities_for_actor(actor, page),
else: @private_visibility_empty_collection
@@ -110,7 +111,7 @@ defmodule MobilizonWeb.ActivityPub.ActorView do
def render("outbox.json", %{actor: actor}) do
%{total: total, elements: followers} =
if Actor.public_visibility?(actor),
if Actor.is_public_visibility(actor),
do: ActivityPub.fetch_public_activities_for_actor(actor),
else: @private_visibility_empty_collection