Merge branch 'profile-image-descriptions' into 'develop'

Federate avatar/header descriptions

See merge request pleroma/pleroma!4264
This commit is contained in:
marcin mikołajczak 2024-10-06 20:05:36 +00:00
commit 07cfbe4ae8
7 changed files with 94 additions and 16 deletions

View file

@ -419,6 +419,11 @@ def banner_url(user, options \\ []) do
end end
end end
def image_description(image, default \\ "")
def image_description(%{"name" => name}, _default), do: name
def image_description(_, default), do: default
# Should probably be renamed or removed # Should probably be renamed or removed
@spec ap_id(User.t()) :: String.t() @spec ap_id(User.t()) :: String.t()
def ap_id(%User{nickname: nickname}), do: "#{Endpoint.url()}/users/#{nickname}" def ap_id(%User{nickname: nickname}), do: "#{Endpoint.url()}/users/#{nickname}"

View file

@ -1542,16 +1542,23 @@ defp get_actor_url(url) when is_list(url) do
defp get_actor_url(_url), do: nil defp get_actor_url(_url), do: nil
defp normalize_image(%{"url" => url}) do defp normalize_image(%{"url" => url} = data) do
%{ %{
"type" => "Image", "type" => "Image",
"url" => [%{"href" => url}] "url" => [%{"href" => url}]
} }
|> maybe_put_description(data)
end end
defp normalize_image(urls) when is_list(urls), do: urls |> List.first() |> normalize_image() defp normalize_image(urls) when is_list(urls), do: urls |> List.first() |> normalize_image()
defp normalize_image(_), do: nil defp normalize_image(_), do: nil
defp maybe_put_description(map, %{"name" => description}) when is_binary(description) do
Map.put(map, "name", description)
end
defp maybe_put_description(map, _), do: map
defp object_to_user_data(data, additional) do defp object_to_user_data(data, additional) do
fields = fields =
data data

View file

@ -129,8 +129,22 @@ def render("user.json", %{user: user}) do
"vcard:bday" => birthday, "vcard:bday" => birthday,
"webfinger" => "acct:#{User.full_nickname(user)}" "webfinger" => "acct:#{User.full_nickname(user)}"
} }
|> Map.merge(maybe_make_image(&User.avatar_url/2, "icon", user)) |> Map.merge(
|> Map.merge(maybe_make_image(&User.banner_url/2, "image", user)) maybe_make_image(
&User.avatar_url/2,
User.image_description(user.avatar, nil),
"icon",
user
)
)
|> Map.merge(
maybe_make_image(
&User.banner_url/2,
User.image_description(user.banner, nil),
"image",
user
)
)
|> Map.merge(Utils.make_json_ld_header()) |> Map.merge(Utils.make_json_ld_header())
end end
@ -305,16 +319,24 @@ def collection(collection, iri, page, show_items \\ true, total \\ nil) do
end end
end end
defp maybe_make_image(func, key, user) do defp maybe_make_image(func, description, key, user) do
if image = func.(user, no_default: true) do if image = func.(user, no_default: true) do
%{ %{
key => %{ key =>
"type" => "Image", %{
"url" => image "type" => "Image",
} "url" => image
}
|> maybe_put_description(description)
} }
else else
%{} %{}
end end
end end
defp maybe_put_description(map, description) when is_binary(description) do
Map.put(map, "name", description)
end
defp maybe_put_description(map, _description), do: map
end end

View file

@ -219,10 +219,10 @@ defp do_render("show.json", %{user: user} = opts) do
avatar = User.avatar_url(user) |> MediaProxy.url() avatar = User.avatar_url(user) |> MediaProxy.url()
avatar_static = User.avatar_url(user) |> MediaProxy.preview_url(static: true) avatar_static = User.avatar_url(user) |> MediaProxy.preview_url(static: true)
avatar_description = image_description(user.avatar) avatar_description = User.image_description(user.avatar)
header = User.banner_url(user) |> MediaProxy.url() header = User.banner_url(user) |> MediaProxy.url()
header_static = User.banner_url(user) |> MediaProxy.preview_url(static: true) header_static = User.banner_url(user) |> MediaProxy.preview_url(static: true)
header_description = image_description(user.banner) header_description = User.image_description(user.banner)
following_count = following_count =
if !user.hide_follows_count or !user.hide_follows or self, if !user.hide_follows_count or !user.hide_follows or self,
@ -349,10 +349,6 @@ defp username_from_nickname(string) when is_binary(string) do
defp username_from_nickname(_), do: nil defp username_from_nickname(_), do: nil
defp image_description(%{"name" => name}), do: name
defp image_description(_), do: ""
defp maybe_put_follow_requests_count( defp maybe_put_follow_requests_count(
data, data,
%User{id: user_id} = user, %User{id: user_id} = user,

View file

@ -232,12 +232,14 @@ test "works for bridgy actors" do
assert user.avatar == %{ assert user.avatar == %{
"type" => "Image", "type" => "Image",
"url" => [%{"href" => "https://jk.nipponalba.scot/images/profile.jpg"}] "url" => [%{"href" => "https://jk.nipponalba.scot/images/profile.jpg"}],
"name" => "profile picture"
} }
assert user.banner == %{ assert user.banner == %{
"type" => "Image", "type" => "Image",
"url" => [%{"href" => "https://jk.nipponalba.scot/images/profile.jpg"}] "url" => [%{"href" => "https://jk.nipponalba.scot/images/profile.jpg"}],
"name" => "profile picture"
} }
end end
@ -432,6 +434,35 @@ test "fetches user birthday information from misskey" do
assert user.birthday == ~D[2001-02-12] assert user.birthday == ~D[2001-02-12]
end end
test "fetches avatar description" do
user_id = "https://example.com/users/marcin"
user_data =
"test/fixtures/users_mock/user.json"
|> File.read!()
|> String.replace("{{nickname}}", "marcin")
|> Jason.decode!()
|> Map.delete("featured")
|> Map.update("icon", %{}, fn image -> Map.put(image, "name", "image description") end)
|> Jason.encode!()
Tesla.Mock.mock(fn
%{
method: :get,
url: ^user_id
} ->
%Tesla.Env{
status: 200,
body: user_data,
headers: [{"content-type", "application/activity+json"}]
}
end)
{:ok, user} = ActivityPub.make_user_from_ap_id(user_id)
assert user.avatar["name"] == "image description"
end
end end
test "it fetches the appropriate tag-restricted posts" do test "it fetches the appropriate tag-restricted posts" do

View file

@ -68,6 +68,23 @@ test "Does not add an avatar image if the user hasn't set one" do
result = UserView.render("user.json", %{user: user}) result = UserView.render("user.json", %{user: user})
assert result["icon"]["url"] == "https://someurl" assert result["icon"]["url"] == "https://someurl"
assert result["image"]["url"] == "https://somebanner" assert result["image"]["url"] == "https://somebanner"
refute result["icon"]["name"]
refute result["image"]["name"]
end
test "Avatar has a description if the user set one" do
user =
insert(:user,
avatar: %{
"url" => [%{"href" => "https://someurl"}],
"name" => "a drawing of pleroma-tan using pleroma groups"
}
)
result = UserView.render("user.json", %{user: user})
assert result["icon"]["name"] == "a drawing of pleroma-tan using pleroma groups"
end end
test "renders an invisible user with the invisible property set to true" do test "renders an invisible user with the invisible property set to true" do