[#1505] Added Mastodon-compatible replies collection to Note federated representation.

This commit is contained in:
Ivan Tashkinov 2020-01-22 21:10:17 +03:00
commit cf96c40057
6 changed files with 145 additions and 1 deletions

View file

@ -329,4 +329,23 @@ defmodule Pleroma.Activity do
_ -> nil
end
end
def replies(activity, opts \\ []) do
object = Object.normalize(activity)
query =
Activity
|> Queries.by_type("Create")
|> Queries.by_object_in_reply_to_id(object.data["id"], skip_preloading: true)
|> order_by([activity], asc: activity.id)
if opts[:self_only] do
where(query, [a], a.actor == ^activity.actor)
else
query
end
end
def self_replies(activity, opts \\ []),
do: replies(activity, Keyword.put(opts, :self_only, true))
end

View file

@ -7,7 +7,7 @@ defmodule Pleroma.Activity.Queries do
Contains queries for Activity.
"""
import Ecto.Query, only: [from: 2]
import Ecto.Query, only: [from: 2, where: 3]
@type query :: Ecto.Queryable.t() | Activity.t()
@ -63,6 +63,22 @@ defmodule Pleroma.Activity.Queries do
)
end
@spec by_object_id(query, String.t()) :: query
def by_object_in_reply_to_id(query, in_reply_to_id, opts \\ []) do
query =
if opts[:skip_preloading] do
Activity.with_joined_object(query)
else
Activity.with_preloaded_object(query)
end
where(
query,
[activity, object: o],
fragment("(?)->>'inReplyTo' = ?", o.data, ^to_string(in_reply_to_id))
)
end
@spec by_type(query, String.t()) :: query
def by_type(query \\ Activity, activity_type) do
from(

View file

@ -903,6 +903,49 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
def set_reply_to_uri(obj), do: obj
@doc """
Serialized Mastodon-compatible `replies` collection containing _self-replies_.
Based on Mastodon's ActivityPub::NoteSerializer#replies.
"""
def set_replies(obj) do
limit = Pleroma.Config.get([:mastodon_compatibility, :federated_note_replies_limit], 0)
replies_uris =
with true <- limit > 0 || nil,
%Activity{} = activity <- Activity.get_create_by_object_ap_id(obj["id"]) do
activity
|> Activity.self_replies()
|> select([a], fragment("?->>'id'", a.data))
|> limit(^limit)
|> Repo.all()
end
set_replies(obj, replies_uris || [])
end
defp set_replies(obj, replies_uris) when replies_uris in [nil, []] do
obj
end
defp set_replies(obj, replies_uris) do
# Note: stubs (Mastodon doesn't make separate requests via those URIs in FetchRepliesService)
masto_replies_uri = nil
masto_replies_next_page_uri = nil
replies_collection = %{
"type" => "Collection",
"id" => masto_replies_uri,
"first" => %{
"type" => "Collection",
"part_of" => masto_replies_uri,
"items" => replies_uris,
"next" => masto_replies_next_page_uri
}
}
Map.merge(obj, %{"replies" => replies_collection})
end
# Prepares the object of an outgoing create activity.
def prepare_object(object) do
object
@ -914,6 +957,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|> prepare_attachments
|> set_conversation
|> set_reply_to_uri
|> set_replies
|> strip_internal_fields
|> strip_internal_tags
|> set_type