Mastodon API: Add support for posting polls

This commit is contained in:
rinpatch 2019-05-18 13:29:28 +03:00
parent 642a67dd44
commit fd920c8973
4 changed files with 82 additions and 9 deletions

View File

@ -149,6 +149,7 @@ def post(user, %{"status" => status} = data) do
data,
visibility
),
{poll, mentions, tags} <- make_poll_data(data, mentions, tags),
{to, cc} <- to_for_user_and_mentions(user, mentions, in_reply_to, visibility),
context <- make_context(in_reply_to),
cw <- data["spoiler_text"] || "",
@ -164,7 +165,8 @@ def post(user, %{"status" => status} = data) do
in_reply_to,
tags,
cw,
cc
cc,
poll
),
object <-
Map.put(

View File

@ -102,6 +102,48 @@ def to_for_user_and_mentions(_user, mentions, inReplyTo, "direct") do
end
end
def make_poll_data(
%{"poll" => %{"options" => options, "expires_in" => expires_in}} = data,
mentions,
tags
)
when is_list(options) and is_integer(expires_in) do
content_type = get_content_type(data["content_type"])
# XXX: There is probably a more performant/cleaner way to do this
{poll, {mentions, tags}} =
Enum.map_reduce(options, {mentions, tags}, fn option, {mentions, tags} ->
# TODO: Custom emoji
{option, mentions_merge, tags_merge} = format_input(option, content_type)
mentions = mentions ++ mentions_merge
tags = tags ++ tags_merge
{%{
"name" => option,
"type" => "Note",
"replies" => %{"type" => "Collection", "totalItems" => 0}
}, {mentions, tags}}
end)
end_time =
NaiveDateTime.utc_now()
|> NaiveDateTime.add(expires_in)
|> NaiveDateTime.to_iso8601()
poll =
if Pleroma.Web.ControllerHelper.truthy_param?(data["poll"]["multiple"]) do
%{"type" => "Question", "anyOf" => poll, "closed" => end_time}
else
%{"type" => "Question", "oneOf" => poll, "closed" => end_time}
end
{poll, mentions, tags}
end
def make_poll_data(data, mentions, tags) do
IO.inspect(data, label: "data")
{%{}, mentions, tags}
end
def make_content_html(
status,
attachments,
@ -223,8 +265,11 @@ def make_note_data(
in_reply_to,
tags,
cw \\ nil,
cc \\ []
cc \\ [],
merge \\ %{}
) do
IO.inspect(merge, label: "merge")
object = %{
"type" => "Note",
"to" => to,
@ -237,14 +282,17 @@ def make_note_data(
"tag" => tags |> Enum.map(fn {_, tag} -> tag end) |> Enum.uniq()
}
if in_reply_to do
in_reply_to_object = Object.normalize(in_reply_to)
object =
if in_reply_to do
in_reply_to_object = Object.normalize(in_reply_to)
object
|> Map.put("inReplyTo", in_reply_to_object.data["id"])
else
object
end
object
|> Map.put("inReplyTo", in_reply_to_object.data["id"])
else
object
end
Map.merge(object, merge)
end
def format_naive_asctime(date) do

View File

@ -132,6 +132,28 @@ test "posting a status", %{conn: conn} do
refute id == third_id
end
test "posting a poll", %{conn: conn} do
user = insert(:user)
time = NaiveDateTime.utc_now()
conn =
conn
|> assign(:user, user)
|> post("/api/v1/statuses", %{
"status" => "Who is the best girl?",
"poll" => %{"options" => ["Rei", "Asuka", "Misato"], "expires_in" => 420}
})
response = json_response(conn, 200)
assert Enum.all?(response["poll"]["options"], fn %{"title" => title} ->
title in ["Rei", "Asuka", "Misato"]
end)
assert NaiveDateTime.diff(NaiveDateTime.from_iso8601!(response["poll"]["expires_at"]), time) in 420..430
refute response["poll"]["expred"]
end
test "posting a sensitive status", %{conn: conn} do
user = insert(:user)

View File

@ -103,6 +103,7 @@ test "a note activity" do
muted: false,
pinned: false,
sensitive: false,
poll: nil,
spoiler_text: HtmlSanitizeEx.basic_html(note.data["object"]["summary"]),
visibility: "public",
media_attachments: [],