aboutsummaryrefslogtreecommitdiff
path: root/lib/pleroma/web/common_api/common_api.ex
diff options
context:
space:
mode:
authorMark Felder <feld@FreeBSD.org>2019-06-03 15:29:53 -0500
committerMark Felder <feld@FreeBSD.org>2019-06-03 15:29:53 -0500
commit6ef145b4fc3f2ddb5865e84039c3b56656529711 (patch)
treea10cab9e7561bdaa76777cfc6d0c3c6fe1f8189b /lib/pleroma/web/common_api/common_api.ex
parent5cee2fe9fea4f0c98acd49a2a288ecd44bce3d1f (diff)
parent662e95e9484a46bfc72c2edc305aefae99ff68b0 (diff)
downloadpleroma-6ef145b4fc3f2ddb5865e84039c3b56656529711.tar.gz
Merge branch 'develop' into feature/digest-email
Diffstat (limited to 'lib/pleroma/web/common_api/common_api.ex')
-rw-r--r--lib/pleroma/web/common_api/common_api.ex53
1 files changed, 51 insertions, 2 deletions
diff --git a/lib/pleroma/web/common_api/common_api.ex b/lib/pleroma/web/common_api/common_api.ex
index 5a312d673..5212d5ce5 100644
--- a/lib/pleroma/web/common_api/common_api.ex
+++ b/lib/pleroma/web/common_api/common_api.ex
@@ -119,6 +119,53 @@ defmodule Pleroma.Web.CommonAPI do
end
end
+ def vote(user, object, choices) do
+ with "Question" <- object.data["type"],
+ {:author, false} <- {:author, object.data["actor"] == user.ap_id},
+ {:existing_votes, []} <- {:existing_votes, Utils.get_existing_votes(user.ap_id, object)},
+ {options, max_count} <- get_options_and_max_count(object),
+ option_count <- Enum.count(options),
+ {:choice_check, {choices, true}} <-
+ {:choice_check, normalize_and_validate_choice_indices(choices, option_count)},
+ {:count_check, true} <- {:count_check, Enum.count(choices) <= max_count} do
+ answer_activities =
+ Enum.map(choices, fn index ->
+ answer_data = make_answer_data(user, object, Enum.at(options, index)["name"])
+
+ ActivityPub.create(%{
+ to: answer_data["to"],
+ actor: user,
+ context: object.data["context"],
+ object: answer_data,
+ additional: %{"cc" => answer_data["cc"]}
+ })
+ end)
+
+ object = Object.get_cached_by_ap_id(object.data["id"])
+ {:ok, answer_activities, object}
+ else
+ {:author, _} -> {:error, "Poll's author can't vote"}
+ {:existing_votes, _} -> {:error, "Already voted"}
+ {:choice_check, {_, false}} -> {:error, "Invalid indices"}
+ {:count_check, false} -> {:error, "Too many choices"}
+ end
+ end
+
+ defp get_options_and_max_count(object) do
+ if Map.has_key?(object.data, "anyOf") do
+ {object.data["anyOf"], Enum.count(object.data["anyOf"])}
+ else
+ {object.data["oneOf"], 1}
+ end
+ end
+
+ defp normalize_and_validate_choice_indices(choices, count) do
+ Enum.map_reduce(choices, true, fn index, valid ->
+ index = if is_binary(index), do: String.to_integer(index), else: index
+ {index, if(valid, do: index < count, else: valid)}
+ end)
+ end
+
def get_visibility(%{"visibility" => visibility}, in_reply_to)
when visibility in ~w{public unlisted private direct},
do: {visibility, get_replied_to_visibility(in_reply_to)}
@@ -154,6 +201,7 @@ defmodule Pleroma.Web.CommonAPI do
data,
visibility
),
+ {poll, poll_emoji} <- make_poll_data(data),
{to, cc} <- to_for_user_and_mentions(user, mentions, in_reply_to, visibility),
context <- make_context(in_reply_to),
cw <- data["spoiler_text"] || "",
@@ -171,13 +219,14 @@ defmodule Pleroma.Web.CommonAPI do
tags,
cw,
cc,
- sensitive
+ sensitive,
+ poll
),
object <-
Map.put(
object,
"emoji",
- Formatter.get_emoji_map(full_payload)
+ Map.merge(Formatter.get_emoji_map(full_payload), poll_emoji)
) do
res =
ActivityPub.create(