mobilizon.chapril.org-mobil.../lib/mobilizon_web/api/utils.ex
Thomas Citharel aef841e192 Introduce backend for reports
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
2019-07-23 13:49:22 +02:00

136 lines
4.1 KiB
Elixir

defmodule MobilizonWeb.API.Utils do
@moduledoc """
Utils for API
"""
alias Mobilizon.Actors.Actor
alias Mobilizon.Service.Formatter
@doc """
Determines the full audience based on mentions for a public audience
Audience is:
* `to` : the mentionned actors, the eventual actor we're replying to and the public
* `cc` : the actor's followers
"""
@spec to_for_actor_and_mentions(Actor.t(), list(), map(), String.t()) :: {list(), list()}
def to_for_actor_and_mentions(%Actor{} = actor, mentions, inReplyTo, "public") do
mentioned_actors = Enum.map(mentions, fn {_, %{url: url}} -> url end)
to = ["https://www.w3.org/ns/activitystreams#Public" | mentioned_actors]
cc = [actor.followers_url]
if inReplyTo do
{Enum.uniq([inReplyTo.actor | to]), cc}
else
{to, cc}
end
end
@doc """
Determines the full audience based on mentions based on a unlisted audience
Audience is:
* `to` : the mentionned actors, actor's followers and the eventual actor we're replying to
* `cc` : public
"""
@spec to_for_actor_and_mentions(Actor.t(), list(), map(), String.t()) :: {list(), list()}
def to_for_actor_and_mentions(%Actor{} = actor, mentions, inReplyTo, "unlisted") do
mentioned_actors = Enum.map(mentions, fn {_, %{url: url}} -> url end)
to = [actor.followers_url | mentioned_actors]
cc = ["https://www.w3.org/ns/activitystreams#Public"]
if inReplyTo do
{Enum.uniq([inReplyTo.actor | to]), cc}
else
{to, cc}
end
end
@doc """
Determines the full audience based on mentions based on a private audience
Audience is:
* `to` : the mentionned actors, actor's followers and the eventual actor we're replying to
* `cc` : none
"""
@spec to_for_actor_and_mentions(Actor.t(), list(), map(), String.t()) :: {list(), list()}
def to_for_actor_and_mentions(%Actor{} = actor, mentions, inReplyTo, "private") do
{to, cc} = to_for_actor_and_mentions(actor, mentions, inReplyTo, "direct")
{[actor.followers_url | to], cc}
end
@doc """
Determines the full audience based on mentions based on a direct audience
Audience is:
* `to` : the mentionned actors and the eventual actor we're replying to
* `cc` : none
"""
@spec to_for_actor_and_mentions(Actor.t(), list(), map(), String.t()) :: {list(), list()}
def to_for_actor_and_mentions(_actor, mentions, inReplyTo, "direct") do
mentioned_actors = Enum.map(mentions, fn {_, %{url: url}} -> url end)
if inReplyTo do
{Enum.uniq([inReplyTo.actor | mentioned_actors]), []}
else
{mentioned_actors, []}
end
end
@doc """
Creates HTML content from text and mentions
"""
@spec make_content_html(String.t(), list(), list(), String.t()) :: String.t()
def make_content_html(
status,
mentions,
tags,
content_type
),
do: format_input(status, mentions, tags, content_type)
def format_input(text, mentions, tags, "text/plain") do
text
|> Formatter.html_escape("text/plain")
|> String.replace(~r/\r?\n/, "<br>")
|> (&{[], &1}).()
|> Formatter.add_links()
|> Formatter.add_actor_links(mentions)
|> Formatter.add_hashtag_links(tags)
|> Formatter.finalize()
end
def format_input(text, mentions, _tags, "text/html") do
text
|> Formatter.html_escape("text/html")
|> String.replace(~r/\r?\n/, "<br>")
|> (&{[], &1}).()
|> Formatter.add_actor_links(mentions)
|> Formatter.finalize()
end
# def format_input(text, mentions, tags, "text/markdown") do
# text
# |> Earmark.as_html!()
# |> Formatter.html_escape("text/html")
# |> String.replace(~r/\r?\n/, "")
# |> (&{[], &1}).()
# |> Formatter.add_actor_links(mentions)
# |> Formatter.add_hashtag_links(tags)
# |> Formatter.finalize()
# end
def make_report_content_html(nil), do: {:ok, {nil, [], []}}
def make_report_content_html(comment) do
max_size = Mobilizon.CommonConfig.get([:instance, :max_report_comment_size], 1000)
if String.length(comment) <= max_size do
{:ok, Formatter.html_escape(comment, "text/plain")}
else
{:error, "Comment must be up to #{max_size} characters"}
end
end
end