# Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ActivityPub.Transmogrifier do
when not is_nil(in_reply_to) do
in_reply_to_id = prepare_in_reply_to(in_reply_to)
object = Map.put(object, "inReplyToAtomUri", in_reply_to_id)
+ depth = (options[:depth] || 0) + 1
- if Federator.allowed_incoming_reply_depth?(options[:depth]) do
+ if Federator.allowed_thread_distance?(depth) do
with {:ok, replied_object} <- get_obj_helper(in_reply_to_id, options),
- %Activity{} = _ <- Activity.get_create_by_object_ap_id(replied_object.data["id"]) do
+ %Activity{} <- Activity.get_create_by_object_ap_id(replied_object.data["id"]) do
object
|> Map.put("inReplyTo", replied_object.data["id"])
|> Map.put("inReplyToAtomUri", object["inReplyToAtomUri"] || in_reply_to_id)
Map.put(object, "url", url["href"])
end
- def fix_url(%{"type" => "Video", "url" => url} = object) when is_list(url) do
+ def fix_url(%{"type" => object_type, "url" => url} = object)
+ when object_type in ["Video", "Audio"] and is_list(url) do
first_element = Enum.at(url, 0)
link_element = Enum.find(url, fn x -> is_map(x) and x["mimeType"] == "text/html" end)
def fix_type(%{"inReplyTo" => reply_id, "name" => _} = object, options)
when is_binary(reply_id) do
- with true <- Federator.allowed_incoming_reply_depth?(options[:depth]),
+ with true <- Federator.allowed_thread_distance?(options[:depth]),
{:ok, %{data: %{"type" => "Question"} = _} = _} <- get_obj_helper(reply_id, options) do
Map.put(object, "type", "Answer")
else
%{"type" => "Create", "object" => %{"type" => objtype} = object} = data,
options
)
- when objtype in ["Article", "Event", "Note", "Video", "Page", "Question", "Answer"] do
+ when objtype in ["Article", "Event", "Note", "Video", "Page", "Question", "Answer", "Audio"] do
actor = Containment.get_actor(data)
data =
with nil <- Activity.get_create_by_object_ap_id(object["id"]),
{:ok, %User{} = user} <- User.get_or_fetch_by_ap_id(data["actor"]) do
- options = Keyword.put(options, :depth, (options[:depth] || 0) + 1)
- object = fix_object(data["object"], options)
+ object = fix_object(object, options)
params = %{
to: data["to"],
}
with {:ok, created_activity} <- ActivityPub.create(params) do
- for reply_id <- replies(object) do
- Pleroma.Workers.RemoteFetcherWorker.enqueue("fetch_remote", %{"id" => reply_id})
+ reply_depth = (options[:depth] || 0) + 1
+
+ if Federator.allowed_thread_distance?(reply_depth) do
+ for reply_id <- replies(object) do
+ Pleroma.Workers.RemoteFetcherWorker.enqueue("fetch_remote", %{
+ "id" => reply_id,
+ "depth" => reply_depth
+ })
+ end
end
{:ok, created_activity}
|> fix_addressing
with {:ok, %User{} = user} <- User.get_or_fetch_by_ap_id(data["actor"]) do
- options = Keyword.put(options, :depth, (options[:depth] || 0) + 1)
+ reply_depth = (options[:depth] || 0) + 1
+ options = Keyword.put(options, :depth, reply_depth)
object = fix_object(object, options)
params = %{
{_, {:ok, follower}} <- {:follow, User.follow(follower, followed)},
{_, {:ok, _}} <-
{:follow_state_update, Utils.update_follow_state_for_all(activity, "accept")},
- {:ok, _relationship} <- FollowingRelationship.update(follower, followed, "accept") do
+ {:ok, _relationship} <-
+ FollowingRelationship.update(follower, followed, :follow_accept) do
ActivityPub.accept(%{
to: [follower.ap_id],
actor: followed,
else
{:user_blocked, true} ->
{:ok, _} = Utils.update_follow_state_for_all(activity, "reject")
- {:ok, _relationship} = FollowingRelationship.update(follower, followed, "reject")
+ {:ok, _relationship} = FollowingRelationship.update(follower, followed, :follow_reject)
ActivityPub.reject(%{
to: [follower.ap_id],
{:follow, {:error, _}} ->
{:ok, _} = Utils.update_follow_state_for_all(activity, "reject")
- {:ok, _relationship} = FollowingRelationship.update(follower, followed, "reject")
+ {:ok, _relationship} = FollowingRelationship.update(follower, followed, :follow_reject)
ActivityPub.reject(%{
to: [follower.ap_id],
})
{:user_locked, true} ->
- {:ok, _relationship} = FollowingRelationship.update(follower, followed, "pending")
+ {:ok, _relationship} = FollowingRelationship.update(follower, followed, :follow_pending)
:noop
end
{:ok, follow_activity} <- get_follow_activity(follow_object, followed),
{:ok, follow_activity} <- Utils.update_follow_state_for_all(follow_activity, "accept"),
%User{local: true} = follower <- User.get_cached_by_ap_id(follow_activity.data["actor"]),
- {:ok, _relationship} <- FollowingRelationship.update(follower, followed, "accept") do
+ {:ok, _relationship} <- FollowingRelationship.update(follower, followed, :follow_accept) do
ActivityPub.accept(%{
to: follow_activity.data["to"],
type: "Accept",
{:ok, follow_activity} <- get_follow_activity(follow_object, followed),
{:ok, follow_activity} <- Utils.update_follow_state_for_all(follow_activity, "reject"),
%User{local: true} = follower <- User.get_cached_by_ap_id(follow_activity.data["actor"]),
- {:ok, _relationship} <- FollowingRelationship.update(follower, followed, "reject"),
+ {:ok, _relationship} <- FollowingRelationship.update(follower, followed, :follow_reject),
{:ok, activity} <-
ActivityPub.reject(%{
to: follow_activity.data["to"],
"star" => "⭐"
}
- @doc "Rewrite misskey likes into EmojiReactions"
+ @doc "Rewrite misskey likes into EmojiReacts"
def handle_incoming(
%{
"type" => "Like",
options
) do
data
- |> Map.put("type", "EmojiReaction")
+ |> Map.put("type", "EmojiReact")
|> Map.put("content", @misskey_reactions[reaction] || reaction)
|> handle_incoming(options)
end
def handle_incoming(
%{
- "type" => "EmojiReaction",
+ "type" => "EmojiReact",
"object" => object_id,
"actor" => _actor,
"id" => id,
def handle_incoming(
%{
"type" => "Undo",
- "object" => %{"type" => "EmojiReaction", "id" => reaction_activity_id},
+ "object" => %{"type" => "EmojiReact", "id" => reaction_activity_id},
"actor" => _actor,
"id" => id
} = data,
Serialized Mastodon-compatible `replies` collection containing _self-replies_.
Based on Mastodon's ActivityPub::NoteSerializer#replies.
"""
- def set_replies(obj) do
- limit = Pleroma.Config.get([:activitypub, :note_replies_output_limit], 0)
-
+ def set_replies(obj_data) do
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))
+ with limit when limit > 0 <-
+ Pleroma.Config.get([:activitypub, :note_replies_output_limit], 0),
+ %Object{} = object <- Object.get_cached_by_ap_id(obj_data["id"]) do
+ object
+ |> Object.self_replies()
+ |> select([o], fragment("?->>'id'", o.data))
|> limit(^limit)
|> Repo.all()
+ else
+ _ -> []
end
- set_replies(obj, replies_uris || [])
+ set_replies(obj_data, replies_uris)
end
- defp set_replies(obj, replies_uris) when replies_uris in [nil, []] do
+ defp set_replies(obj, []) 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
- }
+ "items" => replies_uris
}
Map.merge(obj, %{"replies" => replies_collection})
end
- def replies(%{"replies" => replies = %{}}) do
- replies =
- if is_map(replies["first"]) do
- replies["first"]
- else
- replies
- end
+ def replies(%{"replies" => %{"first" => %{"items" => items}}}) when not is_nil(items) do
+ items
+ end
- replies["items"] || []
+ def replies(%{"replies" => %{"items" => items}}) when not is_nil(items) do
+ items
end
def replies(_), do: []
end
def add_mention_tags(object) do
- mentions =
- object
- |> Utils.get_notified_from_object()
- |> Enum.map(&build_mention_tag/1)
+ {enabled_receivers, disabled_receivers} = Utils.get_notified_from_object(object)
+ potential_receivers = enabled_receivers ++ disabled_receivers
+ mentions = Enum.map(potential_receivers, &build_mention_tag/1)
tags = object["tag"] || []
-
Map.put(object, "tag", tags ++ mentions)
end