Add a route for status quotes

Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
This commit is contained in:
marcin mikołajczak 2022-05-27 11:27:48 +02:00
parent 75c8036d2c
commit 8d1617f439
7 changed files with 126 additions and 4 deletions

View file

@ -1215,6 +1215,16 @@ defp restrict_filtered(query, %{blocking_user: %User{} = user}) do
defp restrict_filtered(query, _), do: query
defp restrict_quote_url(query, %{quote_url: quote_url}) do
IO.inspect(quote_url)
from([_activity, object] in query,
where: fragment("(?)->'quoteUrl' = ?", object.data, ^quote_url)
)
end
defp restrict_quote_url(query, _), do: query
defp exclude_poll_votes(query, %{include_poll_votes: true}), do: query
defp exclude_poll_votes(query, _) do
@ -1378,6 +1388,7 @@ def fetch_activities_query(recipients, opts \\ %{}) do
|> restrict_instance(opts)
|> restrict_announce_object_actor(opts)
|> restrict_filtered(opts)
|> restrict_quote_url(opts)
|> Activity.restrict_deactivated_users()
|> exclude_poll_votes(opts)
|> exclude_chat_messages(opts)
@ -1794,4 +1805,7 @@ def fetch_direct_messages_query do
|> restrict_visibility(%{visibility: "direct"})
|> order_by([activity], asc: activity.id)
end
def fetch_quotes(%Activity{data: %{"id" => ap_id}} = activity, params) do
end
end

View file

@ -58,7 +58,7 @@ defmacro status_object_fields do
field(:replies_count, :integer, default: 0)
field(:like_count, :integer, default: 0)
field(:announcement_count, :integer, default: 0)
field(:quote_count, :integer, default: 0)
field(:quotes_count, :integer, default: 0)
field(:inReplyTo, ObjectValidators.ObjectID)
field(:quoteUrl, ObjectValidators.ObjectID)
field(:url, ObjectValidators.Uri)

View file

@ -0,0 +1,45 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ApiSpec.PleromaStatusOperation do
alias OpenApiSpex.Operation
alias Pleroma.Web.ApiSpec.StatusOperation
alias Pleroma.Web.ApiSpec.Schemas.ApiError
alias Pleroma.Web.ApiSpec.Schemas.FlakeID
import Pleroma.Web.ApiSpec.Helpers
def open_api_operation(action) do
operation = String.to_existing_atom("#{action}_operation")
apply(__MODULE__, operation, [])
end
def quotes_operation do
%Operation{
tags: ["Retrieve status information"],
summary: "Quoted by",
description: "View quotes for a given status",
operationId: "PleromaAPI.StatusController.quotes",
parameters: [id_param() | pagination_params()],
security: [%{"oAuth" => ["read:statuses"]}],
responses: %{
200 =>
Operation.response(
"Array of Status",
"application/json",
StatusOperation.array_of_statuses()
),
403 => Operation.response("Forbidden", "application/json", ApiError),
404 => Operation.response("Not Found", "application/json", ApiError)
}
}
end
def id_param do
Operation.parameter(:id, :path, FlakeID, "Status ID",
example: "9umDrYheeY451cQnEe",
required: true
)
end
end

View file

@ -192,7 +192,7 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Status do
type: :boolean,
description: "`true` if the quoted post is visible to the user"
},
quote_count: %Schema{
quotes_count: %Schema{
type: :integer,
description: "How many statuses quoted this status"
},
@ -351,7 +351,7 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Status do
"local" => true,
"spoiler_text" => %{"text/plain" => ""},
"thread_muted" => false,
"quote_count" => 0
"quotes_count" => 0
},
"poll" => nil,
"reblog" => nil,

View file

@ -417,7 +417,7 @@ def render("show.json", %{activity: %{data: %{"object" => _object}} = activity}
parent_visible: visible_for_user?(reply_to, opts[:for]),
pinned_at: pinned_at,
content_type: opts[:with_source] && (object.data["content_type"] || "text/plain"),
quote_count: object.data["quotesCount"] || 0,
quotes_count: object.data["quotesCount"] || 0
}
}
end

View file

@ -0,0 +1,61 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.PleromaAPI.StatusController do
use Pleroma.Web, :controller
import Pleroma.Web.ControllerHelper, only: [add_link_headers: 2]
require Ecto.Query
require Pleroma.Constants
alias Pleroma.Activity
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.MastodonAPI.StatusView
alias Pleroma.Web.Plugs.OAuthScopesPlug
plug(Pleroma.Web.ApiSpec.CastAndValidate)
action_fallback(Pleroma.Web.MastodonAPI.FallbackController)
plug(
OAuthScopesPlug,
%{scopes: ["read:statuses"], fallback: :proceed_unauthenticated} when action == :quotes
)
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.PleromaStatusOperation
@doc "GET /api/v1/pleroma/statuses/:id/quotes"
def quotes(%{assigns: %{user: user}} = conn, %{id: id} = params) do
with %Activity{object: object} <- Activity.get_by_id_with_object(id) do
params =
params
|> Map.put(:type, "Create")
|> Map.put(:blocking_user, user)
|> Map.put(:quote_url, object.data["id"])
recipients =
if user do
[Pleroma.Constants.as_public()] ++ [user.ap_id | User.following(user)]
else
[Pleroma.Constants.as_public()]
end
activities =
recipients
|> ActivityPub.fetch_activities(params)
|> Enum.reverse()
conn
|> add_link_headers(activities)
|> put_view(StatusView)
|> render("index.json",
activities: activities,
for: user,
as: :activity
)
end
end
end

View file

@ -476,6 +476,8 @@ defmodule Pleroma.Web.Router do
pipe_through(:api)
get("/accounts/:id/favourites", AccountController, :favourites)
get("/accounts/:id/endorsements", AccountController, :endorsements)
get("/statuses/:id/quotes", StatusController, :quotes)
end
scope [] do