From fd920c897339b9cedea042dd6698d14380cedae7 Mon Sep 17 00:00:00 2001 From: rinpatch Date: Sat, 18 May 2019 13:29:28 +0300 Subject: [PATCH] Mastodon API: Add support for posting polls --- lib/pleroma/web/common_api/common_api.ex | 4 +- lib/pleroma/web/common_api/utils.ex | 64 ++++++++++++++++--- .../mastodon_api_controller_test.exs | 22 +++++++ test/web/mastodon_api/status_view_test.exs | 1 + 4 files changed, 82 insertions(+), 9 deletions(-) diff --git a/lib/pleroma/web/common_api/common_api.ex b/lib/pleroma/web/common_api/common_api.ex index b53869c75..335ae70b0 100644 --- a/lib/pleroma/web/common_api/common_api.ex +++ b/lib/pleroma/web/common_api/common_api.ex @@ -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( diff --git a/lib/pleroma/web/common_api/utils.ex b/lib/pleroma/web/common_api/utils.ex index 1dfe50b40..13cdffbbd 100644 --- a/lib/pleroma/web/common_api/utils.ex +++ b/lib/pleroma/web/common_api/utils.ex @@ -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 diff --git a/test/web/mastodon_api/mastodon_api_controller_test.exs b/test/web/mastodon_api/mastodon_api_controller_test.exs index 505e45010..ce581c092 100644 --- a/test/web/mastodon_api/mastodon_api_controller_test.exs +++ b/test/web/mastodon_api/mastodon_api_controller_test.exs @@ -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) diff --git a/test/web/mastodon_api/status_view_test.exs b/test/web/mastodon_api/status_view_test.exs index d7c800e83..9f2ebda4e 100644 --- a/test/web/mastodon_api/status_view_test.exs +++ b/test/web/mastodon_api/status_view_test.exs @@ -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: [],