Add support for remote favicons
authorHaelwenn (lanodan) Monnier <contact@hacktivis.me>
Sun, 1 Mar 2020 08:48:32 +0000 (09:48 +0100)
committerHaelwenn (lanodan) Monnier <contact@hacktivis.me>
Wed, 8 Jul 2020 04:28:39 +0000 (06:28 +0200)
lib/pleroma/user.ex
lib/pleroma/web/mastodon_api/views/account_view.ex
test/support/http_request_mock.ex
test/web/mastodon_api/views/account_view_test.exs

index e98332744010433cecf68962182e2fe05be66016..25ea112a262c4fca130adba306b29d6e75676fc1 100644 (file)
@@ -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
index a6e64b4ab77b620f1b97fd07aae00a0a6c815e67..efe835e3c257f8dee9638d10d0cea5607fa76c35 100644 (file)
@@ -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])
index da04ac6f1e6617981c48cde5eccd9902a3df6e3c..4d33c6250917301e0b635463942a0c333b2bbea0 100644 (file)
@@ -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)}, #{
index 80b1f734c041da92081c3f120fac8ab0911a5ef3..e01a7c1eef641f40ac4b35ea6f5ae4237a54556d 100644 (file)
@@ -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,