diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index e98332744..25ea112a2 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -2253,4 +2253,34 @@ defmodule Pleroma.User do |> Map.put(:bio, HTML.filter_tags(user.bio, filter)) |> Map.put(:fields, fields) end + + def get_cached_favicon(%User{} = user) do + key = "favicon:#{user.ap_id}" + Cachex.fetch!(:user_cache, key, fn _ -> get_favicon(user) end) + end + + def get_cached_favicon(_user) do + nil + end + + def get_favicon(user) do + try do + with url <- user.ap_id, + true <- is_binary(url), + {:ok, %Tesla.Env{body: html}} <- Pleroma.HTTP.get(url), + favicon_rel <- + html + |> Floki.parse_document!() + |> Floki.attribute("link[rel=icon]", "href") + |> List.first(), + favicon_url <- URI.merge(URI.parse(url), favicon_rel) |> to_string(), + true <- is_binary(favicon_url) do + favicon_url + else + _ -> nil + end + rescue + _ -> nil + end + end end diff --git a/lib/pleroma/web/mastodon_api/views/account_view.ex b/lib/pleroma/web/mastodon_api/views/account_view.ex index a6e64b4ab..efe835e3c 100644 --- a/lib/pleroma/web/mastodon_api/views/account_view.ex +++ b/lib/pleroma/web/mastodon_api/views/account_view.ex @@ -245,7 +245,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do hide_favorites: user.hide_favorites, relationship: relationship, skip_thread_containment: user.skip_thread_containment, - background_image: image_url(user.background) |> MediaProxy.url() + background_image: image_url(user.background) |> MediaProxy.url(), + favicon: User.get_cached_favicon(user) |> MediaProxy.url() } } |> maybe_put_role(user, opts[:for]) diff --git a/test/support/http_request_mock.ex b/test/support/http_request_mock.ex index da04ac6f1..4d33c6250 100644 --- a/test/support/http_request_mock.ex +++ b/test/support/http_request_mock.ex @@ -1342,6 +1342,10 @@ defmodule HttpRequestMock do {:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/relay/relay.json")}} end + def get("http://localhost:4001/users/" <> _, _, _, _) do + {:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/tesla_mock/7369654.html")}} + end + def get(url, query, body, headers) do {:error, "Mock response not implemented for GET #{inspect(url)}, #{query}, #{inspect(body)}, #{ diff --git a/test/web/mastodon_api/views/account_view_test.exs b/test/web/mastodon_api/views/account_view_test.exs index 80b1f734c..e01a7c1ee 100644 --- a/test/web/mastodon_api/views/account_view_test.exs +++ b/test/web/mastodon_api/views/account_view_test.exs @@ -75,6 +75,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do pleroma: %{ ap_id: user.ap_id, background_image: "https://example.com/images/asuka_hospital.png", + favicon: nil, confirmation_pending: false, tags: [], is_admin: false, @@ -152,6 +153,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do pleroma: %{ ap_id: user.ap_id, background_image: nil, + favicon: nil, confirmation_pending: false, tags: [], is_admin: false,