defmodule Pleroma.Web.ActivityPub.UserView do
use Pleroma.Web, :view
- alias Pleroma.Web.WebFinger
- alias Pleroma.Web.Salmon
- alias Pleroma.User
+ alias Pleroma.Keys
alias Pleroma.Repo
+ alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.Transmogrifier
alias Pleroma.Web.ActivityPub.Utils
+ alias Pleroma.Web.Endpoint
+ alias Pleroma.Web.Router.Helpers
import Ecto.Query
- def render("endpoints.json", %{user: %User{local: true} = _user}) do
- %{
- "oauthAuthorizationEndpoint" => "#{Pleroma.Web.Endpoint.url()}/oauth/authorize",
- "oauthTokenEndpoint" => "#{Pleroma.Web.Endpoint.url()}/oauth/token"
- }
- |> Map.merge(render("endpoints.json", %{user: nil}))
+ def render("endpoints.json", %{user: %User{nickname: nil, local: true} = _user}) do
+ %{"sharedInbox" => Helpers.activity_pub_url(Endpoint, :inbox)}
end
- def render("endpoints.json", _) do
+ def render("endpoints.json", %{user: %User{local: true} = _user}) do
%{
- "sharedInbox" => "#{Pleroma.Web.Endpoint.url()}/inbox"
+ "oauthAuthorizationEndpoint" => Helpers.o_auth_url(Endpoint, :authorize),
+ "oauthRegistrationEndpoint" => Helpers.mastodon_api_url(Endpoint, :create_app),
+ "oauthTokenEndpoint" => Helpers.o_auth_url(Endpoint, :token_exchange),
+ "sharedInbox" => Helpers.activity_pub_url(Endpoint, :inbox)
}
end
+ def render("endpoints.json", _), do: %{}
+
# the instance itself is not a Person, but instead an Application
def render("user.json", %{user: %{nickname: nil} = user}) do
- {:ok, user} = WebFinger.ensure_keys_present(user)
- {:ok, _, public_key} = Salmon.keys_from_pem(user.info.keys)
+ {:ok, user} = User.ensure_keys_present(user)
+ {:ok, _, public_key} = Keys.keys_from_pem(user.info.keys)
public_key = :public_key.pem_entry_encode(:SubjectPublicKeyInfo, public_key)
public_key = :public_key.pem_encode([public_key])
end
def render("user.json", %{user: user}) do
- {:ok, user} = WebFinger.ensure_keys_present(user)
- {:ok, _, public_key} = Salmon.keys_from_pem(user.info.keys)
+ {:ok, user} = User.ensure_keys_present(user)
+ {:ok, _, public_key} = Keys.keys_from_pem(user.info.keys)
public_key = :public_key.pem_entry_encode(:SubjectPublicKeyInfo, public_key)
public_key = :public_key.pem_encode([public_key])
endpoints = render("endpoints.json", %{user: user})
+ user_tags =
+ user
+ |> Transmogrifier.add_emoji_tags()
+ |> Map.get("tag", [])
+
%{
"id" => user.ap_id,
"type" => "Person",
"publicKeyPem" => public_key
},
"endpoints" => endpoints,
- "icon" => %{
- "type" => "Image",
- "url" => User.avatar_url(user)
- },
- "image" => %{
- "type" => "Image",
- "url" => User.banner_url(user)
- },
- "tag" => user.info.source_data["tag"] || []
+ "tag" => (user.info.source_data["tag"] || []) ++ user_tags
}
+ |> Map.merge(maybe_make_image(&User.avatar_url/2, "icon", user))
+ |> Map.merge(maybe_make_image(&User.banner_url/2, "image", user))
|> Map.merge(Utils.make_json_ld_header())
end
query = from(user in query, select: [:ap_id])
following = Repo.all(query)
- collection(following, "#{user.ap_id}/following", page, !user.info.hide_follows)
+ total =
+ if !user.info.hide_follows do
+ length(following)
+ else
+ 0
+ end
+
+ collection(following, "#{user.ap_id}/following", page, !user.info.hide_follows, total)
|> Map.merge(Utils.make_json_ld_header())
end
query = from(user in query, select: [:ap_id])
following = Repo.all(query)
+ total =
+ if !user.info.hide_follows do
+ length(following)
+ else
+ 0
+ end
+
%{
"id" => "#{user.ap_id}/following",
"type" => "OrderedCollection",
- "totalItems" => length(following),
+ "totalItems" => total,
"first" => collection(following, "#{user.ap_id}/following", 1, !user.info.hide_follows)
}
|> Map.merge(Utils.make_json_ld_header())
query = from(user in query, select: [:ap_id])
followers = Repo.all(query)
- collection(followers, "#{user.ap_id}/followers", page, !user.info.hide_followers)
+ total =
+ if !user.info.hide_followers do
+ length(followers)
+ else
+ 0
+ end
+
+ collection(followers, "#{user.ap_id}/followers", page, !user.info.hide_followers, total)
|> Map.merge(Utils.make_json_ld_header())
end
query = from(user in query, select: [:ap_id])
followers = Repo.all(query)
+ total =
+ if !user.info.hide_followers do
+ length(followers)
+ else
+ 0
+ end
+
%{
"id" => "#{user.ap_id}/followers",
"type" => "OrderedCollection",
- "totalItems" => length(followers),
- "first" => collection(followers, "#{user.ap_id}/followers", 1, !user.info.hide_followers)
+ "totalItems" => total,
+ "first" =>
+ collection(followers, "#{user.ap_id}/followers", 1, !user.info.hide_followers, total)
}
|> Map.merge(Utils.make_json_ld_header())
end
def render("outbox.json", %{user: user, max_id: max_qid}) do
- # XXX: technically note_count is wrong for this, but it's better than nothing
- info = User.user_info(user)
-
params = %{
"limit" => "10"
}
end
activities = ActivityPub.fetch_user_activities(user, nil, params)
- min_id = Enum.at(Enum.reverse(activities), 0).id
- max_id = Enum.at(activities, 0).id
- collection =
- Enum.map(activities, fn act ->
- {:ok, data} = Transmogrifier.prepare_outgoing(act.data)
- data
- end)
+ {max_id, min_id, collection} =
+ if length(activities) > 0 do
+ {
+ Enum.at(Enum.reverse(activities), 0).id,
+ Enum.at(activities, 0).id,
+ Enum.map(activities, fn act ->
+ {:ok, data} = Transmogrifier.prepare_outgoing(act.data)
+ data
+ end)
+ }
+ else
+ {
+ 0,
+ 0,
+ []
+ }
+ end
iri = "#{user.ap_id}/outbox"
"id" => "#{iri}?max_id=#{max_id}",
"type" => "OrderedCollectionPage",
"partOf" => iri,
- "totalItems" => info.note_count,
"orderedItems" => collection,
"next" => "#{iri}?max_id=#{min_id}"
}
%{
"id" => iri,
"type" => "OrderedCollection",
- "totalItems" => info.note_count,
"first" => page
}
|> Map.merge(Utils.make_json_ld_header())
"id" => "#{iri}?max_id=#{max_id}",
"type" => "OrderedCollectionPage",
"partOf" => iri,
- "totalItems" => -1,
"orderedItems" => collection,
"next" => "#{iri}?max_id=#{min_id}"
}
%{
"id" => iri,
"type" => "OrderedCollection",
- "totalItems" => -1,
"first" => page
}
|> Map.merge(Utils.make_json_ld_header())
map
end
end
+
+ defp maybe_make_image(func, key, user) do
+ if image = func.(user, no_default: true) do
+ %{
+ key => %{
+ "type" => "Image",
+ "url" => image
+ }
+ }
+ else
+ %{}
+ end
+ end
end