2020-01-26 21:11:16 +01:00
|
|
|
defmodule Mobilizon.GraphQL.API.Utils do
|
2018-12-14 17:41:55 +01:00
|
|
|
@moduledoc """
|
2019-09-22 16:26:23 +02:00
|
|
|
Utils for API.
|
2018-12-14 17:41:55 +01:00
|
|
|
"""
|
2019-09-08 00:05:54 +02:00
|
|
|
|
2020-11-26 11:41:13 +01:00
|
|
|
alias Mobilizon.{Config, Medias}
|
|
|
|
alias Mobilizon.Medias.Media
|
2018-12-14 17:41:55 +01:00
|
|
|
alias Mobilizon.Service.Formatter
|
|
|
|
|
|
|
|
@doc """
|
|
|
|
Creates HTML content from text and mentions
|
|
|
|
"""
|
2019-07-26 11:30:28 +02:00
|
|
|
@spec make_content_html(String.t(), list(), String.t()) :: String.t()
|
2020-01-26 21:11:16 +01:00
|
|
|
def make_content_html(text, additional_tags, content_type) do
|
2019-07-26 11:30:28 +02:00
|
|
|
with {text, mentions, tags} <- format_input(text, content_type, []) do
|
|
|
|
{text, mentions, additional_tags ++ Enum.map(tags, fn {_, tag} -> tag end)}
|
|
|
|
end
|
|
|
|
end
|
2018-12-14 17:41:55 +01:00
|
|
|
|
2019-07-26 11:30:28 +02:00
|
|
|
def format_input(text, "text/plain", options) do
|
2018-12-14 17:41:55 +01:00
|
|
|
text
|
|
|
|
|> Formatter.html_escape("text/plain")
|
2019-07-26 11:30:28 +02:00
|
|
|
|> Formatter.linkify(options)
|
2020-01-26 21:11:16 +01:00
|
|
|
|> (fn {text, mentions, tags} -> {String.replace(text, ~r/\r?\n/, "<br>"), mentions, tags} end).()
|
2018-12-14 17:41:55 +01:00
|
|
|
end
|
|
|
|
|
2019-07-26 11:30:28 +02:00
|
|
|
def format_input(text, "text/html", options) do
|
2018-12-14 17:41:55 +01:00
|
|
|
text
|
|
|
|
|> Formatter.html_escape("text/html")
|
2019-07-26 11:30:28 +02:00
|
|
|
|> Formatter.linkify(options)
|
2018-12-14 17:41:55 +01:00
|
|
|
end
|
|
|
|
|
2019-09-09 09:31:08 +02:00
|
|
|
def make_report_content_text(nil), do: {:ok, nil}
|
2019-07-23 13:49:22 +02:00
|
|
|
|
2019-09-09 09:31:08 +02:00
|
|
|
def make_report_content_text(comment) do
|
2019-09-08 00:05:54 +02:00
|
|
|
max_size = Config.get([:instance, :max_report_comment_size], 1000)
|
2019-07-23 13:49:22 +02:00
|
|
|
|
|
|
|
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
|
2020-11-26 11:41:13 +01:00
|
|
|
|
|
|
|
@doc """
|
|
|
|
Use the data-media-id attributes to extract media from body text
|
|
|
|
"""
|
|
|
|
@spec extract_pictures_from_body(String.t(), integer() | String.t()) :: list(Media.t())
|
|
|
|
def extract_pictures_from_body(body, actor_id) do
|
|
|
|
body
|
|
|
|
|> do_extract_pictures_from_body()
|
|
|
|
|> Enum.map(&fetch_picture(&1, actor_id))
|
|
|
|
|> Enum.filter(& &1)
|
|
|
|
end
|
|
|
|
|
|
|
|
@spec do_extract_pictures_from_body(String.t()) :: list(String.t())
|
|
|
|
defp do_extract_pictures_from_body(body) when is_nil(body) or body == "", do: []
|
|
|
|
|
|
|
|
defp do_extract_pictures_from_body(body) do
|
|
|
|
{:ok, document} = Floki.parse_document(body)
|
|
|
|
|
|
|
|
document
|
|
|
|
|> Floki.attribute("img", "data-media-id")
|
|
|
|
end
|
|
|
|
|
|
|
|
@spec fetch_picture(String.t() | integer(), String.t() | integer()) :: Media.t() | nil
|
|
|
|
defp fetch_picture(id, actor_id) do
|
|
|
|
with %Media{actor_id: media_actor_id} = media <- Medias.get_media(id),
|
|
|
|
{:owns_media, true} <-
|
|
|
|
{:owns_media, check_actor_owns_media?(actor_id, media_actor_id)} do
|
|
|
|
media
|
|
|
|
else
|
|
|
|
_ -> nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
@spec check_actor_owns_media?(integer() | String.t(), integer() | String.t()) :: boolean()
|
|
|
|
defp check_actor_owns_media?(actor_id, media_actor_id) do
|
|
|
|
actor_id == media_actor_id || Mobilizon.Actors.is_member?(media_actor_id, actor_id)
|
|
|
|
end
|
2018-12-14 17:41:55 +01:00
|
|
|
end
|