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

@@ -70,6 +70,7 @@ defmodule Mobilizon.Activities do
[%Activity{}, ...]
"""
@spec list_activities :: list(Activity.t())
def list_activities do
Repo.all(Activity)
end
@@ -161,6 +162,7 @@ defmodule Mobilizon.Activities do
** (Ecto.NoResultsError)
"""
@spec get_activity!(integer()) :: Activity.t()
def get_activity!(id), do: Repo.get!(Activity, id)
@doc """
@@ -175,6 +177,7 @@ defmodule Mobilizon.Activities do
{:error, %Ecto.Changeset{}}
"""
@spec create_activity(map()) :: {:ok, Activity.t()} | {:error, Ecto.Changeset.t()}
def create_activity(attrs \\ %{}) do
%Activity{}
|> Activity.changeset(attrs)
@@ -186,10 +189,13 @@ defmodule Mobilizon.Activities do
Repo.preload(activity, @activity_preloads)
end
@spec object_types :: list(String.t())
def object_types, do: @object_type
@spec subjects :: list(String.t())
def subjects, do: @subjects
@spec activity_types :: list(String.t())
def activity_types, do: @activity_types
@spec filter_object_type(Query.t(), atom() | nil) :: Query.t()

View File

@@ -23,6 +23,7 @@ defmodule Mobilizon.Actors.Actor do
require Logger
@type t :: %__MODULE__{
id: integer(),
url: String.t(),
outbox_url: String.t(),
inbox_url: String.t(),

View File

@@ -299,6 +299,7 @@ defmodule Mobilizon.Actors do
@delete_actor_default_options [reserve_username: true, suspension: false]
@spec delete_actor(Actor.t(), Keyword.t()) :: {:error, Ecto.Changeset.t()} | {:ok, Oban.Job.t()}
def delete_actor(%Actor{} = actor, options \\ @delete_actor_default_options) do
delete_actor_options = Keyword.merge(@delete_actor_default_options, options)
@@ -533,7 +534,7 @@ defmodule Mobilizon.Actors do
|> Repo.one()
end
@spec get_actor_by_followers_url(String.t()) :: Actor.t()
@spec get_actor_by_followers_url(String.t()) :: Actor.t() | nil
def get_actor_by_followers_url(followers_url) do
Actor
|> where([q], q.followers_url == ^followers_url)

View File

@@ -12,6 +12,8 @@ defmodule Mobilizon.Actors.Member do
alias Mobilizon.Web.Endpoint
@type t :: %__MODULE__{
id: String.t(),
url: String.t(),
role: MemberRole.t(),
parent: Actor.t(),
actor: Actor.t(),

View File

@@ -73,6 +73,7 @@ defmodule Mobilizon.Addresses.Address do
put_change(changeset, :url, url)
end
@spec coords(nil | t) :: nil | {float, float}
def coords(nil), do: nil
def coords(%__MODULE__{} = address) do
@@ -81,6 +82,7 @@ defmodule Mobilizon.Addresses.Address do
end
end
@spec representation(nil | t) :: nil | String.t()
def representation(nil), do: nil
def representation(%__MODULE__{} = address) do

View File

@@ -9,6 +9,7 @@ defmodule Mobilizon.CLI do
"""
alias Mix.Tasks.Mobilizon.Ecto.{Migrate, Rollback}
@spec run(String.t()) :: any()
def run(args) do
[task | args] = String.split(args)
@@ -43,11 +44,13 @@ defmodule Mobilizon.CLI do
end
end
def migrate(args) do
@spec migrate(String.t()) :: any()
defp migrate(args) do
Migrate.run(args)
end
def rollback(args) do
@spec rollback(String.t()) :: any()
defp rollback(args) do
Rollback.run(args)
end
end

View File

@@ -302,9 +302,9 @@ defmodule Mobilizon.Config do
def instance_event_creation_enabled?,
do: :mobilizon |> Application.get_env(:events) |> Keyword.get(:creation)
@spec anonymous_actor_id :: binary | integer
@spec anonymous_actor_id :: integer
def anonymous_actor_id, do: get_cached_value(:anonymous_actor_id)
@spec relay_actor_id :: binary | integer
@spec relay_actor_id :: integer
def relay_actor_id, do: get_cached_value(:relay_actor_id)
@spec admin_settings :: map
def admin_settings, do: get_cached_value(:admin_config)

View File

@@ -20,6 +20,7 @@ defmodule Mobilizon.Discussions.Comment do
@type t :: %__MODULE__{
text: String.t(),
url: String.t(),
id: integer(),
local: boolean,
visibility: CommentVisibility.t(),
uuid: Ecto.UUID.t(),

View File

@@ -4,6 +4,7 @@ defmodule Mobilizon.Discussions.Discussion.TitleSlug do
"""
use EctoAutoslugField.Slug, from: [:title, :id], to: :slug
@spec build_slug([String.t()], Ecto.Changeset.t()) :: String.t()
def build_slug([title, id], %Ecto.Changeset{valid?: true}) do
[title, ShortUUID.encode!(id)]
|> Enum.join("-")
@@ -31,6 +32,7 @@ defmodule Mobilizon.Discussions.Discussion do
import Mobilizon.Web.Gettext, only: [dgettext: 2]
@type t :: %__MODULE__{
id: String.t(),
creator: Actor.t(),
actor: Actor.t(),
title: String.t(),

View File

@@ -377,8 +377,8 @@ defmodule Mobilizon.Discussions do
@doc """
Creates a discussion.
"""
@spec create_discussion(map) :: {:ok, Comment.t()} | {:error, Changeset.t()}
def create_discussion(attrs \\ %{}) do
@spec create_discussion(map()) :: {:ok, Discussion.t()} | {:error, atom(), Changeset.t(), map()}
def create_discussion(attrs) do
with {:ok, %{comment: %Comment{} = _comment, discussion: %Discussion{} = discussion}} <-
Multi.new()
|> Multi.insert(
@@ -412,19 +412,26 @@ defmodule Mobilizon.Discussions do
@doc """
Create a response to a discussion
"""
@spec reply_to_discussion(Discussion.t(), map()) :: {:ok, Discussion.t()}
@spec reply_to_discussion(Discussion.t(), map()) ::
{:ok, Discussion.t()} | {:error, atom(), Ecto.Changeset.t(), map()}
def reply_to_discussion(%Discussion{id: discussion_id} = discussion, attrs \\ %{}) do
attrs =
Map.merge(attrs, %{
discussion_id: discussion_id,
actor_id: Map.get(attrs, :creator_id, Map.get(attrs, :actor_id))
})
changeset =
Comment.changeset(
%Comment{},
attrs
)
with {:ok, %{comment: %Comment{} = comment, discussion: %Discussion{} = discussion}} <-
Multi.new()
|> Multi.insert(
:comment,
Comment.changeset(
%Comment{},
Map.merge(attrs, %{
discussion_id: discussion_id,
actor_id: Map.get(attrs, :creator_id, attrs.actor_id)
})
)
changeset
)
|> Multi.update(:discussion, fn %{comment: %Comment{id: comment_id}} ->
Discussion.changeset(
@@ -435,7 +442,7 @@ defmodule Mobilizon.Discussions do
|> Repo.transaction(),
# Discussion is not updated
%Comment{} = comment <- Repo.preload(comment, @comment_preloads) do
{:ok, Map.put(discussion, :last_comment, comment)}
{:ok, %Discussion{discussion | last_comment: comment}}
end
end
@@ -453,7 +460,8 @@ defmodule Mobilizon.Discussions do
@doc """
Delete a discussion.
"""
@spec delete_discussion(Discussion.t()) :: {:ok, Discussion.t()} | {:error, Changeset.t()}
@spec delete_discussion(Discussion.t()) ::
{:ok, %{comments: {integer() | nil, any()}}} | {:error, :comments, Changeset.t(), map()}
def delete_discussion(%Discussion{id: discussion_id}) do
Multi.new()
|> Multi.delete_all(:comments, fn _ ->
@@ -463,7 +471,7 @@ defmodule Mobilizon.Discussions do
|> Repo.transaction()
end
@spec public_comments_for_actor_query(String.t() | integer()) :: [Comment.t()]
@spec public_comments_for_actor_query(String.t() | integer()) :: Ecto.Query.t()
defp public_comments_for_actor_query(actor_id) do
Comment
|> where([c], c.actor_id == ^actor_id and c.visibility in ^@public_visibility)
@@ -471,7 +479,7 @@ defmodule Mobilizon.Discussions do
|> preload_for_comment()
end
@spec public_replies_for_thread_query(String.t() | integer()) :: [Comment.t()]
@spec public_replies_for_thread_query(String.t() | integer()) :: Ecto.Query.t()
defp public_replies_for_thread_query(comment_id) do
Comment
|> where([c], c.origin_comment_id == ^comment_id and c.visibility in ^@public_visibility)

View File

@@ -35,7 +35,7 @@ defmodule Mobilizon.Events.Event do
alias Mobilizon.Web.Router.Helpers, as: Routes
@type t :: %__MODULE__{
id: String.t(),
id: integer(),
url: String.t(),
local: boolean,
begins_on: DateTime.t(),
@@ -47,16 +47,16 @@ defmodule Mobilizon.Events.Event do
draft: boolean,
visibility: EventVisibility.t(),
join_options: JoinOptions.t(),
publish_at: DateTime.t(),
publish_at: DateTime.t() | nil,
uuid: Ecto.UUID.t(),
online_address: String.t(),
online_address: String.t() | nil,
phone_address: String.t(),
category: String.t(),
options: EventOptions.t(),
organizer_actor: Actor.t(),
attributed_to: Actor.t() | nil,
physical_address: Address.t(),
picture: Media.t(),
physical_address: Address.t() | nil,
picture: Media.t() | nil,
media: [Media.t()],
tracks: [Track.t()],
sessions: [Session.t()],

View File

@@ -282,7 +282,7 @@ defmodule Mobilizon.Events do
# We start by inserting the event and then insert a first participant if the event is not a draft
@spec do_create_event(map) ::
{:ok, Event.t()}
{:ok, %{insert: Event.t(), write: Participant.t() | nil}}
| {:error, Changeset.t()}
| {:error, :update | :write, Changeset.t(), map()}
defp do_create_event(attrs) do
@@ -368,7 +368,7 @@ defmodule Mobilizon.Events do
Deletes an event.
Raises an exception if it fails.
"""
@spec delete_event(Event.t()) :: Event.t()
@spec delete_event!(Event.t()) :: Event.t()
def delete_event!(%Event{} = event), do: Repo.delete!(event)
@doc """
@@ -457,6 +457,7 @@ defmodule Mobilizon.Events do
@spec list_organized_events_for_group(
Actor.t(),
EventVisibility.t(),
DateTime.t() | nil,
DateTime.t() | nil,
integer | nil,

View File

@@ -15,6 +15,7 @@ defmodule Mobilizon.Events.Participant do
alias Mobilizon.Web.Endpoint
@type t :: %__MODULE__{
id: String.t(),
role: ParticipantRole.t(),
url: String.t(),
event: Event.t(),

View File

@@ -4,6 +4,7 @@ defmodule Mobilizon.Posts.Post.TitleSlug do
"""
use EctoAutoslugField.Slug, from: [:title, :id], to: :slug
@spec build_slug([String.t()], any()) :: String.t() | nil
def build_slug([title, id], _changeset) do
[title, ShortUUID.encode!(id)]
|> Enum.join("-")
@@ -31,6 +32,7 @@ defmodule Mobilizon.Posts.Post do
import Mobilizon.Web.Gettext
@type t :: %__MODULE__{
id: String.t(),
url: String.t(),
local: boolean,
slug: String.t(),

View File

@@ -15,6 +15,7 @@ defmodule Mobilizon.Reports.Report do
alias Mobilizon.Web.Endpoint
@type t :: %__MODULE__{
id: integer(),
content: String.t(),
status: ReportStatus.t(),
url: String.t(),

View File

@@ -13,6 +13,7 @@ defmodule Mobilizon.Resources.Resource do
alias Mobilizon.Resources.Resource.Metadata
@type t :: %__MODULE__{
id: String.t(),
title: String.t(),
summary: String.t(),
url: String.t(),

View File

@@ -10,6 +10,7 @@ defmodule Mobilizon.Storage.Repo do
@doc """
Dynamically loads the repository url from the DATABASE_URL environment variable.
"""
@spec init(any(), any()) :: any()
def init(_, opts) do
{:ok, opts}
end

View File

@@ -10,6 +10,8 @@ defmodule Mobilizon.Todos.Todo do
alias Mobilizon.Todos.TodoList
@type t :: %__MODULE__{
id: String.t(),
url: String.t(),
status: boolean(),
title: String.t(),
due_date: DateTime.t(),

View File

@@ -10,6 +10,8 @@ defmodule Mobilizon.Todos.TodoList do
alias Mobilizon.Todos.Todo
@type t :: %__MODULE__{
id: String.t(),
url: String.t(),
title: String.t(),
todos: [Todo.t()],
actor: Actor.t(),

View File

@@ -107,7 +107,7 @@ defmodule Mobilizon.Users do
@doc """
Get an user by its activation token.
"""
@spec get_user_by_activation_token(String.t()) :: Actor.t() | nil
@spec get_user_by_activation_token(String.t()) :: User.t() | nil
def get_user_by_activation_token(token) do
token
|> user_by_activation_token_query()
@@ -117,7 +117,7 @@ defmodule Mobilizon.Users do
@doc """
Get an user by its reset password token.
"""
@spec get_user_by_reset_password_token(String.t()) :: Actor.t() | nil
@spec get_user_by_reset_password_token(String.t()) :: User.t() | nil
def get_user_by_reset_password_token(token) do
token
|> user_by_reset_password_token_query()