Normalize poll votes to Answer objects

This commit is contained in:
rinpatch 2019-05-22 21:17:57 +03:00
parent 10ca1f91de
commit 19c90d47c4
4 changed files with 51 additions and 18 deletions

View file

@ -194,7 +194,7 @@ def stream_out(activity) do
if activity.data["type"] in ["Create", "Announce", "Delete"] do if activity.data["type"] in ["Create", "Announce", "Delete"] do
object = Object.normalize(activity) object = Object.normalize(activity)
# Do not stream out poll replies # Do not stream out poll replies
unless object.data["name"] do unless object.data["type"] == "Answer" do
Pleroma.Web.Streamer.stream("user", activity) Pleroma.Web.Streamer.stream("user", activity)
Pleroma.Web.Streamer.stream("list", activity) Pleroma.Web.Streamer.stream("list", activity)
@ -493,7 +493,6 @@ defp fetch_activities_for_context_query(context, opts) do
from(activity in Activity) from(activity in Activity)
|> restrict_blocked(opts) |> restrict_blocked(opts)
|> restrict_poll_replies(opts)
|> restrict_recipients(recipients, opts["user"]) |> restrict_recipients(recipients, opts["user"])
|> where( |> where(
[activity], [activity],
@ -833,16 +832,6 @@ defp restrict_muted_reblogs(query, %{"muting_user" => %User{info: info}}) do
defp restrict_muted_reblogs(query, _), do: query defp restrict_muted_reblogs(query, _), do: query
defp restrict_poll_replies(query, %{"include_poll_replies" => "true"}), do: query
defp restrict_poll_replies(query, _) do
if has_named_binding?(query, :object) do
from([activity, object: o] in query, where: fragment("?->'name' is null", o.data))
else
query
end
end
defp maybe_preload_objects(query, %{"skip_preload" => true}), do: query defp maybe_preload_objects(query, %{"skip_preload" => true}), do: query
defp maybe_preload_objects(query, _) do defp maybe_preload_objects(query, _) do
@ -896,7 +885,6 @@ def fetch_activities_query(recipients, opts \\ %{}) do
|> restrict_pinned(opts) |> restrict_pinned(opts)
|> restrict_muted_reblogs(opts) |> restrict_muted_reblogs(opts)
|> Activity.restrict_deactivated_users() |> Activity.restrict_deactivated_users()
|> restrict_poll_replies(opts)
end end
def fetch_activities(recipients, opts \\ %{}) do def fetch_activities(recipients, opts \\ %{}) do

View file

@ -35,6 +35,7 @@ def fix_object(object) do
|> fix_likes |> fix_likes
|> fix_addressing |> fix_addressing
|> fix_summary |> fix_summary
|> fix_type
end end
def fix_summary(%{"summary" => nil} = object) do def fix_summary(%{"summary" => nil} = object) do
@ -328,6 +329,18 @@ def fix_content_map(%{"contentMap" => content_map} = object) do
def fix_content_map(object), do: object def fix_content_map(object), do: object
def fix_type(%{"inReplyTo" => reply_id} = object) when is_binary(reply_id) do
reply = Object.normalize(reply_id)
if reply.data["type"] == "Question" and object["name"] do
Map.put(object, "type", "Answer")
else
object
end
end
def fix_type(object), do: object
defp mastodon_follow_hack(%{"id" => id, "actor" => follower_id}, followed) do defp mastodon_follow_hack(%{"id" => id, "actor" => follower_id}, followed) do
with true <- id =~ "follows", with true <- id =~ "follows",
%User{local: true} = follower <- User.get_cached_by_ap_id(follower_id), %User{local: true} = follower <- User.get_cached_by_ap_id(follower_id),
@ -398,7 +411,7 @@ def handle_incoming(%{"id" => id}) when not (is_binary(id) and length(id) > 8),
# - tags # - tags
# - emoji # - emoji
def handle_incoming(%{"type" => "Create", "object" => %{"type" => objtype} = object} = data) def handle_incoming(%{"type" => "Create", "object" => %{"type" => objtype} = object} = data)
when objtype in ["Article", "Note", "Video", "Page", "Question"] do when objtype in ["Article", "Note", "Video", "Page", "Question", "Answer"] do
actor = Containment.get_actor(data) actor = Containment.get_actor(data)
data = data =
@ -731,6 +744,7 @@ def prepare_object(object) do
|> set_reply_to_uri |> set_reply_to_uri
|> strip_internal_fields |> strip_internal_fields
|> strip_internal_tags |> strip_internal_tags
|> set_type
end end
# @doc # @doc
@ -895,6 +909,12 @@ def set_sensitive(object) do
Map.put(object, "sensitive", "nsfw" in tags) Map.put(object, "sensitive", "nsfw" in tags)
end end
def set_type(%{"type" => "Answer"} = object) do
Map.put(object, "type", "Note")
end
def set_type(object), do: object
def add_attributed_to(object) do def add_attributed_to(object) do
attributed_to = object["attributedTo"] || object["actor"] attributed_to = object["attributedTo"] || object["actor"]

View file

@ -19,7 +19,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do
require Logger require Logger
@supported_object_types ["Article", "Note", "Video", "Page", "Question"] @supported_object_types ["Article", "Note", "Video", "Page", "Question", "Answer"]
@supported_report_states ~w(open closed resolved) @supported_report_states ~w(open closed resolved)
@valid_visibilities ~w(public unlisted private direct) @valid_visibilities ~w(public unlisted private direct)

View file

@ -130,7 +130,7 @@ test "it works for incoming questions" do
end) end)
end end
test "in increments vote counters on question activities" do test "it rewrites Note votes to Answers and increments vote counters on question activities" do
user = insert(:user) user = insert(:user)
{:ok, activity} = {:ok, activity} =
@ -148,8 +148,9 @@ test "in increments vote counters on question activities" do
|> Kernel.put_in(["object", "inReplyTo"], object.data["id"]) |> Kernel.put_in(["object", "inReplyTo"], object.data["id"])
|> Kernel.put_in(["object", "to"], user.ap_id) |> Kernel.put_in(["object", "to"], user.ap_id)
{:ok, %Activity{local: false}} = Transmogrifier.handle_incoming(data) {:ok, %Activity{local: false} = activity} = Transmogrifier.handle_incoming(data)
answer_object = Object.normalize(activity)
assert answer_object.data["type"] == "Answer"
object = Object.get_by_ap_id(object.data["id"]) object = Object.get_by_ap_id(object.data["id"])
assert Enum.any?( assert Enum.any?(
@ -1257,4 +1258,28 @@ test "successfully reserializes a message with AS2 objects in IR" do
{:ok, _} = Transmogrifier.prepare_outgoing(activity.data) {:ok, _} = Transmogrifier.prepare_outgoing(activity.data)
end end
end end
test "Rewrites Answers to Notes" do
user = insert(:user)
{:ok, poll_activity} =
CommonAPI.post(user, %{
"status" => "suya...",
"poll" => %{"options" => ["suya", "suya.", "suya.."], "expires_in" => 10}
})
poll_object = Object.normalize(poll_activity)
# TODO: Replace with CommonAPI vote creation when implemented
data =
File.read!("test/fixtures/mastodon-vote.json")
|> Poison.decode!()
|> Kernel.put_in(["to"], user.ap_id)
|> Kernel.put_in(["object", "inReplyTo"], poll_object.data["id"])
|> Kernel.put_in(["object", "to"], user.ap_id)
{:ok, %Activity{local: false} = activity} = Transmogrifier.handle_incoming(data)
{:ok, data} = Transmogrifier.prepare_outgoing(activity.data)
assert data["object"]["type"] == "Note"
end
end end