diff --git a/lib/pleroma/application.ex b/lib/pleroma/application.ex index 9615af122..c7fc95f75 100644 --- a/lib/pleroma/application.ex +++ b/lib/pleroma/application.ex @@ -150,6 +150,7 @@ defmodule Pleroma.Application do build_cachex("emoji_packs", expiration: emoji_packs_expiration(), limit: 10), build_cachex("failed_proxy_url", limit: 2500), build_cachex("banned_urls", default_ttl: :timer.hours(24 * 30), limit: 5_000) + build_cachex("instances", default_ttl: 25_000, ttl_interval: 1000, limit: 2500) ] end diff --git a/lib/pleroma/instances.ex b/lib/pleroma/instances.ex index 557e8decf..c9b1ed4ce 100644 --- a/lib/pleroma/instances.ex +++ b/lib/pleroma/instances.ex @@ -37,4 +37,32 @@ defmodule Pleroma.Instances do url_or_host end end + + def get_cached_favicon(instance_url) when is_binary(instance_url) do + Cachex.fetch!(:instances_cache, instance_url, fn _ -> get_favicon(instance_url) end) + end + + def get_cached_favicon(_instance_url) do + nil + end + + def get_favicon(instance_url) when is_binary(instance_url) do + try do + with {:ok, %Tesla.Env{body: html}} <- + Pleroma.HTTP.get(instance_url, [{:Accept, "text/html"}]), + favicon_rel <- + html + |> Floki.parse_document!() + |> Floki.attribute("link[rel=icon]", "href") + |> List.first(), + favicon_url <- URI.merge(URI.parse(instance_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/user.ex b/lib/pleroma/user.ex index 25ea112a2..e98332744 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -2253,34 +2253,4 @@ 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 efe835e3c..3ee50dfd0 100644 --- a/lib/pleroma/web/mastodon_api/views/account_view.ex +++ b/lib/pleroma/web/mastodon_api/views/account_view.ex @@ -204,6 +204,15 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do %{} end + favicon = + user + |> Map.get(:ap_id, "") + |> URI.parse() + |> URI.merge("/") + |> to_string() + |> Pleroma.Instances.get_cached_favicon() + |> MediaProxy.url() + %{ id: to_string(user.id), username: username_from_nickname(user.nickname), @@ -246,7 +255,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do relationship: relationship, skip_thread_containment: user.skip_thread_containment, background_image: image_url(user.background) |> MediaProxy.url(), - favicon: User.get_cached_favicon(user) |> MediaProxy.url() + favicon: favicon } } |> maybe_put_role(user, opts[:for]) diff --git a/test/fixtures/tesla_mock/https___osada.macgirvin.com.html b/test/fixtures/tesla_mock/https___osada.macgirvin.com.html new file mode 100644 index 000000000..880273d74 --- /dev/null +++ b/test/fixtures/tesla_mock/https___osada.macgirvin.com.html @@ -0,0 +1,301 @@ + + + + Osada + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +

Welcome to Osada

+ +
+
+
+ + + +
+
+ + +
+
+ +
+ +
+ +
+ +
+ Remote Authentication +
+ +
+ + + +
+
+ +
+ + + + + \ No newline at end of file diff --git a/test/support/http_request_mock.ex b/test/support/http_request_mock.ex index 4d33c6250..19a202654 100644 --- a/test/support/http_request_mock.ex +++ b/test/support/http_request_mock.ex @@ -1342,10 +1342,18 @@ defmodule HttpRequestMock do {:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/relay/relay.json")}} end - def get("http://localhost:4001/users/" <> _, _, _, _) do + def get("http://localhost:4001/", _, "", Accept: "text/html") do {:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/tesla_mock/7369654.html")}} end + def get("https://osada.macgirvin.com/", _, "", Accept: "text/html") do + {:ok, + %Tesla.Env{ + status: 200, + body: File.read!("test/fixtures/tesla_mock/https___osada.macgirvin.com.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 e01a7c1ee..c4341cb28 100644 --- a/test/web/mastodon_api/views/account_view_test.exs +++ b/test/web/mastodon_api/views/account_view_test.exs @@ -75,7 +75,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do pleroma: %{ ap_id: user.ap_id, background_image: "https://example.com/images/asuka_hospital.png", - favicon: nil, + favicon: + "https://shitposter.club/plugins/Qvitter/img/gnusocial-favicons/favicon-16x16.png", confirmation_pending: false, tags: [], is_admin: false, @@ -153,7 +154,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do pleroma: %{ ap_id: user.ap_id, background_image: nil, - favicon: nil, + favicon: + "https://shitposter.club/plugins/Qvitter/img/gnusocial-favicons/favicon-16x16.png", confirmation_pending: false, tags: [], is_admin: false,