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

@@ -40,7 +40,7 @@ defmodule Mobilizon.Service.Activity.Member do
Actors.get_member(member_id)
end
@spec get_author(Member.t(), Member.t() | nil) :: String.t() | integer()
@spec get_author(Member.t(), Member.t() | nil) :: integer()
defp get_author(%Member{actor_id: actor_id}, options) do
moderator = Keyword.get(options, :moderator)

View File

@@ -3,10 +3,12 @@ defmodule Mobilizon.Service.ErrorPage do
Render an error page
"""
@spec init :: :ok | {:error, File.posix()}
def init do
render_error_page()
end
@spec render_error_page :: :ok | {:error, File.posix()}
defp render_error_page do
content =
Phoenix.View.render_to_string(Mobilizon.Web.ErrorView, "500.html", conn: %Plug.Conn{})

View File

@@ -65,6 +65,7 @@ defmodule Mobilizon.Service.Formatter do
end
end
@spec hashtag_handler(String.t(), String.t(), any(), map()) :: {String.t(), map()}
def hashtag_handler("#" <> tag = tag_text, _buffer, _opts, acc) do
tag = String.downcase(tag)
url = "#{Endpoint.url()}/tag/#{tag}"
@@ -100,6 +101,7 @@ defmodule Mobilizon.Service.Formatter do
@doc """
Escapes a special characters in mention names.
"""
@spec mentions_escape(String.t(), Keyword.t()) :: String.t()
def mentions_escape(text, options \\ []) do
options =
Keyword.merge(options,
@@ -111,6 +113,11 @@ defmodule Mobilizon.Service.Formatter do
Linkify.link(text, options)
end
@spec html_escape(
{text :: String.t(), mentions :: list(), hashtags :: list()},
type :: String.t()
) :: {String.t(), list(), list()}
@spec html_escape(text :: String.t(), type :: String.t()) :: String.t()
def html_escape({text, mentions, hashtags}, type) do
{html_escape(text, type), mentions, hashtags}
end
@@ -131,6 +138,7 @@ defmodule Mobilizon.Service.Formatter do
|> Enum.join("")
end
@spec truncate(String.t(), non_neg_integer(), String.t()) :: String.t()
def truncate(text, max_length \\ 200, omission \\ "...") do
# Remove trailing whitespace
text = Regex.replace(~r/([^ \t\r\n])([ \t]+$)/u, text, "\\g{1}")
@@ -143,6 +151,7 @@ defmodule Mobilizon.Service.Formatter do
end
end
@spec linkify_opts :: Keyword.t()
defp linkify_opts do
Mobilizon.Config.get(__MODULE__) ++
[
@@ -186,5 +195,6 @@ defmodule Mobilizon.Service.Formatter do
|> (&" #{&1}").()
end
@spec tag_text_strip(String.t()) :: String.t()
defp tag_text_strip(tag), do: tag |> String.trim("#") |> String.downcase()
end

View File

@@ -9,6 +9,7 @@ defmodule Mobilizon.Service.HTTP.ActivityPub do
recv_timeout: 20_000
]
@spec client(Keyword.t()) :: Tesla.Client.t()
def client(options \\ []) do
headers = Keyword.get(options, :headers, [])
adapter = Application.get_env(:tesla, __MODULE__, [])[:adapter] || Tesla.Adapter.Hackney
@@ -27,10 +28,12 @@ defmodule Mobilizon.Service.HTTP.ActivityPub do
Tesla.client(middleware, {adapter, opts})
end
@spec get(Tesla.Client.t(), String.t()) :: Tesla.Env.t()
def get(client, url) do
Tesla.get(client, url)
end
@spec post(Tesla.Client.t(), String.t(), map() | String.t()) :: Tesla.Env.t()
def post(client, url, data) do
Tesla.post(client, url, data)
end

View File

@@ -19,7 +19,7 @@ defmodule Mobilizon.Service.Notifications.Scheduler do
require Logger
@spec trigger_notifications_for_participant(Participant.t()) :: {:ok, nil}
@spec trigger_notifications_for_participant(Participant.t()) :: {:ok, Oban.Job.t() | nil}
def trigger_notifications_for_participant(%Participant{} = participant) do
before_event_notification(participant)
on_day_notification(participant)
@@ -27,6 +27,7 @@ defmodule Mobilizon.Service.Notifications.Scheduler do
{:ok, nil}
end
@spec before_event_notification(Participant.t()) :: {:ok, nil}
def before_event_notification(%Participant{
id: participant_id,
event: %Event{begins_on: begins_on},
@@ -46,6 +47,7 @@ defmodule Mobilizon.Service.Notifications.Scheduler do
def before_event_notification(_), do: {:ok, nil}
@spec on_day_notification(Participant.t()) :: {:ok, Oban.Job.t() | nil | String.t()}
def on_day_notification(%Participant{
event: %Event{begins_on: begins_on},
actor: %Actor{user_id: user_id}
@@ -90,6 +92,7 @@ defmodule Mobilizon.Service.Notifications.Scheduler do
def on_day_notification(_), do: {:ok, nil}
@spec weekly_notification(Participant.t()) :: {:ok, Oban.Job.t() | nil | String.t()}
def weekly_notification(%Participant{
event: %Event{begins_on: begins_on},
actor: %Actor{user_id: user_id}
@@ -144,6 +147,7 @@ defmodule Mobilizon.Service.Notifications.Scheduler do
def weekly_notification(_), do: {:ok, nil}
@spec pending_participation_notification(Event.t(), Keyword.t()) :: {:ok, Oban.Job.t() | nil}
def pending_participation_notification(event, options \\ [])
def pending_participation_notification(

View File

@@ -18,6 +18,7 @@ defmodule Mobilizon.Service.Notifier do
@callback send(User.t(), list(Activity.t()), Keyword.t()) :: {:ok, any()} | {:error, String.t()}
@spec notify(User.t(), Activity.t(), Keyword.t()) :: :ok
def notify(%User{} = user, %Activity{} = activity, opts \\ []) do
Enum.each(providers(opts), & &1.send(user, activity, opts))
end

View File

@@ -8,6 +8,8 @@ defmodule Mobilizon.Service.RichMedia.Parsers.MetaTagsParser do
Module to parse meta tags data in HTML pages
"""
@spec parse(String.t(), map(), String.t(), String.t(), atom(), atom(), list(atom())) ::
{:ok, map()} | {:error, String.t()}
def parse(
html,
data,
@@ -35,10 +37,12 @@ defmodule Mobilizon.Service.RichMedia.Parsers.MetaTagsParser do
end
end
@spec get_elements(String.t(), atom(), String.t()) :: Floki.html_tree()
defp get_elements(html, key_name, prefix) do
html |> Floki.parse_document!() |> Floki.find("meta[#{to_string(key_name)}^='#{prefix}:']")
end
@spec normalize_attributes(Floki.html_node(), String.t(), atom(), atom(), list(atom())) :: map()
defp normalize_attributes(html_node, prefix, key_name, value_name, allowed_attributes) do
{_tag, attributes, _children} = html_node
@@ -55,6 +59,7 @@ defmodule Mobilizon.Service.RichMedia.Parsers.MetaTagsParser do
end
end
@spec maybe_put_title(map(), String.t()) :: map()
defp maybe_put_title(%{title: _} = meta, _), do: meta
defp maybe_put_title(meta, html) when meta != %{} do
@@ -66,6 +71,7 @@ defmodule Mobilizon.Service.RichMedia.Parsers.MetaTagsParser do
defp maybe_put_title(meta, _), do: meta
@spec maybe_put_description(map(), String.t()) :: map()
defp maybe_put_description(%{description: _} = meta, _), do: meta
defp maybe_put_description(meta, html) when meta != %{} do

View File

@@ -15,6 +15,7 @@ defmodule Mobilizon.Service.RichMedia.Parsers.OEmbed do
ssl: [{:versions, [:"tlsv1.2"]}]
]
@spec parse(String.t(), map()) :: {:ok, map()} | {:error, String.t()}
def parse(html, _data) do
Logger.debug("Using OEmbed parser")

View File

@@ -30,6 +30,7 @@ defmodule Mobilizon.Service.RichMedia.Parsers.OGP do
:"image:alt"
]
@spec parse(String.t(), map()) :: {:ok, map()}
def parse(html, data) do
Logger.debug("Using OpenGraph card parser")
@@ -49,6 +50,7 @@ defmodule Mobilizon.Service.RichMedia.Parsers.OGP do
end
end
@spec transform_tags(map()) :: map()
defp transform_tags(data) do
data
|> Enum.reject(fn {_, v} -> is_nil(v) end)

View File

@@ -10,6 +10,7 @@ defmodule Mobilizon.Service.SiteMap do
@default_static_frequency :monthly
@spec generate_sitemap :: {:ok, :ok}
def generate_sitemap do
static_routes = [
{Routes.page_url(Endpoint, :index, []), :daily},
@@ -60,6 +61,7 @@ defmodule Mobilizon.Service.SiteMap do
end
# Sometimes we use naive datetimes
@spec check_date_time(any()) :: DateTime.t() | nil
defp check_date_time(%NaiveDateTime{} = datetime), do: DateTime.from_naive!(datetime, "Etc/UTC")
defp check_date_time(%DateTime{} = datetime), do: datetime
defp check_date_time(_), do: nil

View File

@@ -6,6 +6,7 @@ defmodule Mobilizon.Service.Statistics do
alias Mobilizon.{Actors, Discussions, Events, Users}
alias Mobilizon.Federation.ActivityPub.Relay
@spec get_cached_value(String.t()) :: any() | nil
def get_cached_value(key) do
case Cachex.fetch(:statistics, key, fn key ->
case create_cache(key) do