From 013e2c505786dff311bcc8bf23631d6a1a1636ef Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Tue, 7 Jul 2020 11:13:38 +0200 Subject: [PATCH] Use instances table instead of Cachex --- lib/pleroma/application.ex | 1 - lib/pleroma/instances.ex | 28 ----------- lib/pleroma/instances/instance.ex | 55 +++++++++++++++++++++- lib/pleroma/web/mastodon_api/views/account_view.ex | 3 +- .../20200707112859_instances_add_favicon.exs | 10 ++++ 5 files changed, 65 insertions(+), 32 deletions(-) create mode 100644 priv/repo/migrations/20200707112859_instances_add_favicon.exs diff --git a/lib/pleroma/application.ex b/lib/pleroma/application.ex index c7fc95f75..9615af122 100644 --- a/lib/pleroma/application.ex +++ b/lib/pleroma/application.ex @@ -150,7 +150,6 @@ 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 c9b1ed4ce..557e8decf 100644 --- a/lib/pleroma/instances.ex +++ b/lib/pleroma/instances.ex @@ -37,32 +37,4 @@ 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/instances/instance.ex b/lib/pleroma/instances/instance.ex index 74458c09a..b97e229e5 100644 --- a/lib/pleroma/instances/instance.ex +++ b/lib/pleroma/instances/instance.ex @@ -17,6 +17,8 @@ defmodule Pleroma.Instances.Instance do schema "instances" do field(:host, :string) field(:unreachable_since, :naive_datetime_usec) + field(:favicon, :string) + field(:favicon_updated_at, :naive_datetime) timestamps() end @@ -25,7 +27,7 @@ defmodule Pleroma.Instances.Instance do def changeset(struct, params \\ %{}) do struct - |> cast(params, [:host, :unreachable_since]) + |> cast(params, [:host, :unreachable_since, :favicon, :favicon_updated_at]) |> validate_required([:host]) |> unique_constraint(:host) end @@ -120,4 +122,55 @@ defmodule Pleroma.Instances.Instance do end defp parse_datetime(datetime), do: datetime + + def get_or_update_favicon(%URI{host: host} = instance_uri) do + existing_record = Repo.get_by(Instance, %{host: host}) + now = NaiveDateTime.utc_now() + + if existing_record && existing_record.favicon && + NaiveDateTime.diff(now, existing_record.favicon_updated_at) < 86_400 do + existing_record.favicon + else + favicon = scrape_favicon(instance_uri) + + cond do + is_binary(favicon) && existing_record -> + existing_record + |> changeset(%{favicon: favicon, favicon_updated_at: now}) + |> Repo.update() + + favicon + + is_binary(favicon) -> + %Instance{} + |> changeset(%{host: host, favicon: favicon, favicon_updated_at: now}) + |> Repo.insert() + + favicon + + true -> + nil + end + end + end + + defp scrape_favicon(%URI{} = instance_uri) do + try do + with {:ok, %Tesla.Env{body: html}} <- + Pleroma.HTTP.get(to_string(instance_uri), [{:Accept, "text/html"}]), + favicon_rel <- + html + |> Floki.parse_document!() + |> Floki.attribute("link[rel=icon]", "href") + |> List.first(), + favicon <- URI.merge(instance_uri, favicon_rel) |> to_string(), + true <- is_binary(favicon) do + favicon + 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 3ee50dfd0..db5739254 100644 --- a/lib/pleroma/web/mastodon_api/views/account_view.ex +++ b/lib/pleroma/web/mastodon_api/views/account_view.ex @@ -209,8 +209,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do |> Map.get(:ap_id, "") |> URI.parse() |> URI.merge("/") - |> to_string() - |> Pleroma.Instances.get_cached_favicon() + |> Pleroma.Instances.Instance.get_or_update_favicon() |> MediaProxy.url() %{ diff --git a/priv/repo/migrations/20200707112859_instances_add_favicon.exs b/priv/repo/migrations/20200707112859_instances_add_favicon.exs new file mode 100644 index 000000000..5538749dc --- /dev/null +++ b/priv/repo/migrations/20200707112859_instances_add_favicon.exs @@ -0,0 +1,10 @@ +defmodule Pleroma.Repo.Migrations.InstancesAddFavicon do + use Ecto.Migration + + def change do + alter table(:instances) do + add(:favicon, :string) + add(:favicon_updated_at, :naive_datetime) + end + end +end