forked from mirrors/akkoma
Add route to get object like activities
This commit is contained in:
parent
36711e1c83
commit
581edd5a91
5 changed files with 101 additions and 0 deletions
|
@ -54,6 +54,36 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
|
|||
end
|
||||
end
|
||||
|
||||
def object_likes(conn, %{"uuid" => uuid, "page" => page}) do
|
||||
with ap_id <- o_status_url(conn, :object, uuid),
|
||||
%Object{} = object <- Object.get_cached_by_ap_id(ap_id),
|
||||
{_, true} <- {:public?, ActivityPub.is_public?(object)},
|
||||
likes <- Utils.get_object_likes(object) do
|
||||
{page, _} = Integer.parse(page)
|
||||
|
||||
conn
|
||||
|> put_resp_header("content-type", "application/activity+json")
|
||||
|> json(ObjectView.render("likes.json", ap_id, likes, page))
|
||||
else
|
||||
{:public?, false} ->
|
||||
{:error, :not_found}
|
||||
end
|
||||
end
|
||||
|
||||
def object_likes(conn, %{"uuid" => uuid}) do
|
||||
with ap_id <- o_status_url(conn, :object, uuid),
|
||||
%Object{} = object <- Object.get_cached_by_ap_id(ap_id),
|
||||
{_, true} <- {:public?, ActivityPub.is_public?(object)},
|
||||
likes <- Utils.get_object_likes(object) do
|
||||
conn
|
||||
|> put_resp_header("content-type", "application/activity+json")
|
||||
|> json(ObjectView.render("likes.json", ap_id, likes))
|
||||
else
|
||||
{:public?, false} ->
|
||||
{:error, :not_found}
|
||||
end
|
||||
end
|
||||
|
||||
def activity(conn, %{"uuid" => uuid}) do
|
||||
with ap_id <- o_status_url(conn, :activity, uuid),
|
||||
%Activity{} = activity <- Activity.normalize(ap_id),
|
||||
|
|
|
@ -231,6 +231,27 @@ defmodule Pleroma.Web.ActivityPub.Utils do
|
|||
Repo.one(query)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Returns like activities targeting an object
|
||||
"""
|
||||
def get_object_likes(%{data: %{"id" => id}}) do
|
||||
query =
|
||||
from(
|
||||
activity in Activity,
|
||||
# this is to use the index
|
||||
where:
|
||||
fragment(
|
||||
"coalesce((?)->'object'->>'id', (?)->>'object') = ?",
|
||||
activity.data,
|
||||
activity.data,
|
||||
^id
|
||||
),
|
||||
where: fragment("(?)->>'type' = 'Like'", activity.data)
|
||||
)
|
||||
|
||||
Repo.all(query)
|
||||
end
|
||||
|
||||
def make_like_data(%User{ap_id: ap_id} = actor, %{data: %{"id" => id}} = object, activity_id) do
|
||||
data = %{
|
||||
"type" => "Like",
|
||||
|
|
|
@ -35,4 +35,38 @@ defmodule Pleroma.Web.ActivityPub.ObjectView do
|
|||
|
||||
Map.merge(base, additional)
|
||||
end
|
||||
|
||||
def render("likes.json", ap_id, likes, page) do
|
||||
collection(likes, "#{ap_id}/likes", page)
|
||||
|> Map.merge(Pleroma.Web.ActivityPub.Utils.make_json_ld_header())
|
||||
end
|
||||
|
||||
def render("likes.json", ap_id, likes) do
|
||||
%{
|
||||
"id" => "#{ap_id}/likes",
|
||||
"type" => "OrderedCollection",
|
||||
"totalItems" => length(likes),
|
||||
"first" => collection(likes, "#{ap_id}/followers", 1)
|
||||
}
|
||||
|> Map.merge(Pleroma.Web.ActivityPub.Utils.make_json_ld_header())
|
||||
end
|
||||
|
||||
def collection(collection, iri, page) do
|
||||
offset = (page - 1) * 10
|
||||
items = Enum.slice(collection, offset, 10)
|
||||
items = Enum.map(items, fn object -> Transmogrifier.prepare_object(object.data) end)
|
||||
total = length(collection)
|
||||
|
||||
map = %{
|
||||
"id" => "#{iri}?page=#{page}",
|
||||
"type" => "OrderedCollectionPage",
|
||||
"partOf" => iri,
|
||||
"totalItems" => total,
|
||||
"orderedItems" => items
|
||||
}
|
||||
|
||||
if offset < total do
|
||||
Map.put(map, "next", "#{iri}?page=#{page + 1}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -421,6 +421,7 @@ defmodule Pleroma.Web.Router do
|
|||
get("/users/:nickname/followers", ActivityPubController, :followers)
|
||||
get("/users/:nickname/following", ActivityPubController, :following)
|
||||
get("/users/:nickname/outbox", ActivityPubController, :outbox)
|
||||
get("/objects/:uuid/likes", ActivityPubController, :object_likes)
|
||||
end
|
||||
|
||||
pipeline :activitypub_client do
|
||||
|
|
|
@ -89,6 +89,21 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
|
|||
end
|
||||
end
|
||||
|
||||
describe "/object/:uuid/likes" do
|
||||
test "it returns the like activities in a collection", %{conn: conn} do
|
||||
like = insert(:like_activity)
|
||||
uuid = String.split(like.data["object"], "/") |> List.last()
|
||||
|
||||
result =
|
||||
conn
|
||||
|> put_req_header("accept", "application/activity+json")
|
||||
|> get("/objects/#{uuid}/likes")
|
||||
|> json_response(200)
|
||||
|
||||
assert List.first(result["first"]["orderedItems"])["id"] == like.data["id"]
|
||||
end
|
||||
end
|
||||
|
||||
describe "/activities/:uuid" do
|
||||
test "it returns a json representation of the activity", %{conn: conn} do
|
||||
activity = insert(:note_activity)
|
||||
|
|
Loading…
Reference in a new issue