X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;f=lib%2Fpleroma%2Fweb%2Fmastodon_api%2Fviews%2Fstatus_view.ex;h=0ef65b3521a623fad0337da6c52cf25265818365;hb=be5e2c4dbba63831ea6a0617556e686969b5080f;hp=d398f7853088e9ba9d456f30ad09cc9c04d66355;hpb=74d8fadf3745a4b4203c2cead35b741554ccc439;p=akkoma
diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex
index d398f7853..0ef65b352 100644
--- a/lib/pleroma/web/mastodon_api/views/status_view.ex
+++ b/lib/pleroma/web/mastodon_api/views/status_view.ex
@@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors
+# Copyright © 2017-2020 Pleroma Authors
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.MastodonAPI.StatusView do
@@ -9,15 +9,16 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
alias Pleroma.Activity
alias Pleroma.ActivityExpiration
- alias Pleroma.Conversation
- alias Pleroma.Conversation.Participation
+ alias Pleroma.FollowingRelationship
alias Pleroma.HTML
alias Pleroma.Object
alias Pleroma.Repo
alias Pleroma.User
+ alias Pleroma.UserRelationship
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.CommonAPI.Utils
alias Pleroma.Web.MastodonAPI.AccountView
+ alias Pleroma.Web.MastodonAPI.PollView
alias Pleroma.Web.MastodonAPI.StatusView
alias Pleroma.Web.MediaProxy
@@ -71,11 +72,48 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
present?(user && user.ap_id in (object.data["announcements"] || []))
end
+ def relationships_opts(_reading_user = nil, _actors) do
+ %{user_relationships: [], following_relationships: []}
+ end
+
+ def relationships_opts(reading_user, actors) do
+ user_relationships =
+ UserRelationship.dictionary(
+ [reading_user],
+ actors,
+ [:block, :mute, :notification_mute, :reblog_mute],
+ [:block, :inverse_subscription]
+ )
+
+ following_relationships = FollowingRelationship.all_between_user_sets([reading_user], actors)
+
+ %{user_relationships: user_relationships, following_relationships: following_relationships}
+ end
+
def render("index.json", opts) do
- replied_to_activities = get_replied_to_activities(opts.activities)
- opts = Map.put(opts, :replied_to_activities, replied_to_activities)
+ # To do: check AdminAPIControllerTest on the reasons behind nil activities in the list
+ activities = Enum.filter(opts.activities, & &1)
+ replied_to_activities = get_replied_to_activities(activities)
+
+ parent_activities =
+ activities
+ |> Enum.filter(&(&1.data["type"] == "Announce" && &1.data["object"]))
+ |> Enum.map(&Object.normalize(&1).data["id"])
+ |> Activity.create_by_object_ap_id()
+ |> Activity.with_preloaded_object(:left)
+ |> Activity.with_preloaded_bookmark(opts[:for])
+ |> Activity.with_set_thread_muted_field(opts[:for])
+ |> Repo.all()
+
+ actors = Enum.map(activities ++ parent_activities, &get_user(&1.data["actor"]))
- safe_render_many(opts.activities, StatusView, "show.json", opts)
+ opts =
+ opts
+ |> Map.put(:replied_to_activities, replied_to_activities)
+ |> Map.put(:parent_activities, parent_activities)
+ |> Map.put(:relationships, relationships_opts(opts[:for], actors))
+
+ safe_render_many(activities, StatusView, "show.json", opts)
end
def render(
@@ -86,17 +124,25 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
created_at = Utils.to_masto_date(activity.data["published"])
activity_object = Object.normalize(activity)
- reblogged_activity =
- Activity.create_by_object_ap_id(activity_object.data["id"])
- |> Activity.with_preloaded_bookmark(opts[:for])
- |> Activity.with_set_thread_muted_field(opts[:for])
- |> Repo.one()
+ reblogged_parent_activity =
+ if opts[:parent_activities] do
+ Activity.Queries.find_by_object_ap_id(
+ opts[:parent_activities],
+ activity_object.data["id"]
+ )
+ else
+ Activity.create_by_object_ap_id(activity_object.data["id"])
+ |> Activity.with_preloaded_bookmark(opts[:for])
+ |> Activity.with_set_thread_muted_field(opts[:for])
+ |> Repo.one()
+ end
- reblogged = render("show.json", Map.put(opts, :activity, reblogged_activity))
+ reblog_rendering_opts = Map.put(opts, :activity, reblogged_parent_activity)
+ reblogged = render("show.json", reblog_rendering_opts)
favorited = opts[:for] && opts[:for].ap_id in (activity_object.data["likes"] || [])
- bookmarked = Activity.get_bookmark(reblogged_activity, opts[:for]) != nil
+ bookmarked = Activity.get_bookmark(reblogged_parent_activity, opts[:for]) != nil
mentions =
activity.recipients
@@ -108,7 +154,12 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
id: to_string(activity.id),
uri: activity_object.data["id"],
url: activity_object.data["id"],
- account: AccountView.render("account.json", %{user: user, for: opts[:for]}),
+ account:
+ AccountView.render("show.json", %{
+ user: user,
+ for: opts[:for],
+ relationships: opts[:relationships]
+ }),
in_reply_to_id: nil,
in_reply_to_account_id: nil,
reblog: reblogged,
@@ -117,14 +168,14 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
reblogs_count: 0,
replies_count: 0,
favourites_count: 0,
- reblogged: reblogged?(reblogged_activity, opts[:for]),
+ reblogged: reblogged?(reblogged_parent_activity, opts[:for]),
favourited: present?(favorited),
bookmarked: present?(bookmarked),
muted: false,
pinned: pinned?(activity, user),
sensitive: false,
spoiler_text: "",
- visibility: "public",
+ visibility: get_visibility(activity),
media_attachments: reblogged[:media_attachments] || [],
mentions: mentions,
tags: reblogged[:tags] || [],
@@ -176,9 +227,11 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
expires_at =
with true <- client_posted_this_activity,
- expiration when not is_nil(expiration) <-
+ %ActivityExpiration{scheduled_at: scheduled_at} <-
ActivityExpiration.get_by_activity_id(activity.id) do
- expiration.scheduled_at
+ scheduled_at
+ else
+ _ -> nil
end
thread_muted? =
@@ -217,21 +270,6 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
summary = object.data["summary"] || ""
- summary_html =
- summary
- |> HTML.get_cached_scrubbed_html_for_activity(
- User.html_filter_policy(opts[:for]),
- activity,
- "mastoapi:summary"
- )
-
- summary_plaintext =
- summary
- |> HTML.get_cached_stripped_html_for_activity(
- activity,
- "mastoapi:summary"
- )
-
card = render("card.json", Pleroma.Web.RichMedia.Helpers.fetch_data_for_activity(activity))
url =
@@ -242,23 +280,51 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
end
direct_conversation_id =
- with {_, true} <- {:include_id, opts[:with_direct_conversation_id]},
- {_, %User{} = for_user} <- {:for_user, opts[:for]},
- %{data: %{"context" => context}} when is_binary(context) <- activity,
- %Conversation{} = conversation <- Conversation.get_for_ap_id(context),
- %Participation{id: participation_id} <-
- Participation.for_user_and_conversation(for_user, conversation) do
- participation_id
+ with {_, nil} <- {:direct_conversation_id, opts[:direct_conversation_id]},
+ {_, true} <- {:include_id, opts[:with_direct_conversation_id]},
+ {_, %User{} = for_user} <- {:for_user, opts[:for]} do
+ Activity.direct_conversation_id(activity, for_user)
else
+ {:direct_conversation_id, participation_id} when is_integer(participation_id) ->
+ participation_id
+
_e ->
nil
end
+ emoji_reactions =
+ with %{data: %{"reactions" => emoji_reactions}} <- object do
+ Enum.map(emoji_reactions, fn [emoji, users] ->
+ %{
+ name: emoji,
+ count: length(users),
+ me: !!(opts[:for] && opts[:for].ap_id in users)
+ }
+ end)
+ else
+ _ -> []
+ end
+
+ muted =
+ thread_muted? ||
+ UserRelationship.exists?(
+ get_in(opts, [:relationships, :user_relationships]),
+ :mute,
+ opts[:for],
+ user,
+ fn for_user, user -> User.mutes?(for_user, user) end
+ )
+
%{
id: to_string(activity.id),
uri: object.data["id"],
url: url,
- account: AccountView.render("account.json", %{user: user, for: opts[:for]}),
+ account:
+ AccountView.render("show.json", %{
+ user: user,
+ for: opts[:for],
+ relationships: opts[:relationships]
+ }),
in_reply_to_id: reply_to && to_string(reply_to.id),
in_reply_to_account_id: reply_to_user && to_string(reply_to_user.id),
reblog: nil,
@@ -271,13 +337,13 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
reblogged: reblogged?(activity, opts[:for]),
favourited: present?(favorited),
bookmarked: present?(bookmarked),
- muted: thread_muted? || User.mutes?(opts[:for], user),
+ muted: muted,
pinned: pinned?(activity, user),
sensitive: sensitive,
- spoiler_text: summary_html,
+ spoiler_text: summary,
visibility: get_visibility(object),
media_attachments: attachments,
- poll: render("poll.json", %{object: object, for: opts[:for]}),
+ poll: render(PollView, "show.json", object: object, for: opts[:for]),
mentions: mentions,
tags: build_tags(tags),
application: %{
@@ -291,10 +357,11 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
conversation_id: get_context_id(activity),
in_reply_to_account_acct: reply_to_user && reply_to_user.nickname,
content: %{"text/plain" => content_plaintext},
- spoiler_text: %{"text/plain" => summary_plaintext},
+ spoiler_text: %{"text/plain" => summary},
expires_at: expires_at,
direct_conversation_id: direct_conversation_id,
- thread_muted: thread_muted?
+ thread_muted: thread_muted?,
+ emoji_reactions: emoji_reactions
}
}
end
@@ -323,11 +390,9 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
nil
end
- site_name = rich_media[:site_name] || page_url_data.host
-
%{
type: "link",
- provider_name: site_name,
+ provider_name: page_url_data.host,
provider_url: page_url_data.scheme <> "://" <> page_url_data.host,
url: page_url,
image: image_url |> MediaProxy.url(),
@@ -376,7 +441,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
%{
id: activity.id,
- account: AccountView.render("account.json", %{user: user, for: opts[:for]}),
+ account: AccountView.render("show.json", %{user: user, for: opts[:for]}),
created_at: created_at,
title: object.data["title"] |> HTML.strip_tags(),
artist: object.data["artist"] |> HTML.strip_tags(),
@@ -389,75 +454,6 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
safe_render_many(opts.activities, StatusView, "listen.json", opts)
end
- def render("poll.json", %{object: object} = opts) do
- {multiple, options} =
- case object.data do
- %{"anyOf" => options} when is_list(options) -> {true, options}
- %{"oneOf" => options} when is_list(options) -> {false, options}
- _ -> {nil, nil}
- end
-
- if options do
- {end_time, expired} =
- case object.data["closed"] || object.data["endTime"] do
- end_time when is_binary(end_time) ->
- end_time =
- (object.data["closed"] || object.data["endTime"])
- |> NaiveDateTime.from_iso8601!()
-
- expired =
- end_time
- |> NaiveDateTime.compare(NaiveDateTime.utc_now())
- |> case do
- :lt -> true
- _ -> false
- end
-
- end_time = Utils.to_masto_date(end_time)
-
- {end_time, expired}
-
- _ ->
- {nil, false}
- end
-
- voted =
- if opts[:for] do
- existing_votes =
- Pleroma.Web.ActivityPub.Utils.get_existing_votes(opts[:for].ap_id, object)
-
- existing_votes != [] or opts[:for].ap_id == object.data["actor"]
- else
- false
- end
-
- {options, votes_count} =
- Enum.map_reduce(options, 0, fn %{"name" => name} = option, count ->
- current_count = option["replies"]["totalItems"] || 0
-
- {%{
- title: HTML.strip_tags(name),
- votes_count: current_count
- }, current_count + count}
- end)
-
- %{
- # Mastodon uses separate ids for polls, but an object can't have
- # more than one poll embedded so object id is fine
- id: to_string(object.id),
- expires_at: end_time,
- expired: expired,
- multiple: multiple,
- votes_count: votes_count,
- options: options,
- voted: voted,
- emojis: build_emojis(object.data["emoji"])
- }
- else
- nil
- end
- end
-
def render("context.json", %{activity: activity, activities: activities, user: user}) do
%{ancestors: ancestors, descendants: descendants} =
activities
@@ -491,7 +487,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
end
end
- def render_content(%{data: %{"type" => "Video"}} = object) do
+ def render_content(%{data: %{"type" => object_type}} = object)
+ when object_type in ["Video", "Event"] do
with name when not is_nil(name) and name != "" <- object.data["name"] do
"
#{name}
#{object.data["content"]}"
else
@@ -566,6 +563,6 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
defp present?(false), do: false
defp present?(_), do: true
- defp pinned?(%Activity{id: id}, %User{info: %{pinned_activities: pinned_activities}}),
+ defp pinned?(%Activity{id: id}, %User{pinned_activities: pinned_activities}),
do: id in pinned_activities
end