diff --git a/lib/pleroma/application.ex b/lib/pleroma/application.ex index adccd7c5d..a78924dfa 100644 --- a/lib/pleroma/application.ex +++ b/lib/pleroma/application.ex @@ -156,7 +156,8 @@ 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("translations", default_ttl: :timer.hours(24 * 30), limit: 2500) + build_cachex("translations", default_ttl: :timer.hours(24 * 30), limit: 2500), + build_cachex("instances", default_ttl: :timer.hours(24), limit: 2500) ] end diff --git a/lib/pleroma/instances/instance.ex b/lib/pleroma/instances/instance.ex index 7b3ba79c9..0627aec64 100644 --- a/lib/pleroma/instances/instance.ex +++ b/lib/pleroma/instances/instance.ex @@ -5,6 +5,8 @@ defmodule Pleroma.Instances.Instance do @moduledoc "Instance." + @cachex Pleroma.Config.get([:cachex, :provider], Cachex) + alias Pleroma.Instances alias Pleroma.Instances.Instance alias Pleroma.Repo @@ -158,9 +160,17 @@ defmodule Pleroma.Instances.Instance do favicon = scrape_favicon(uri) nodeinfo = scrape_nodeinfo(uri) - existing_record - |> changeset(%{host: host, favicon: favicon, nodeinfo: nodeinfo, metadata_updated_at: NaiveDateTime.utc_now()}) - |> Repo.update() + {:ok, instance} = + existing_record + |> changeset(%{ + host: host, + favicon: favicon, + nodeinfo: nodeinfo, + metadata_updated_at: NaiveDateTime.utc_now() + }) + |> Repo.update() + + @cachex.put(:instances_cache, "instances:#{host}", instance) else {:discard, "Does not require update"} end @@ -169,9 +179,18 @@ defmodule Pleroma.Instances.Instance do nodeinfo = scrape_nodeinfo(uri) Logger.info("Creating metadata for #{host}") - %Instance{} - |> changeset(%{host: host, favicon: favicon, nodeinfo: nodeinfo, metadata_updated_at: NaiveDateTime.utc_now()}) - |> Repo.insert() + + {:ok, instance} = + %Instance{} + |> changeset(%{ + host: host, + favicon: favicon, + nodeinfo: nodeinfo, + metadata_updated_at: NaiveDateTime.utc_now() + }) + |> Repo.insert() + + @cachex.put(:instances_cache, "instances:#{host}", instance) end end @@ -255,4 +274,21 @@ defmodule Pleroma.Instances.Instance do end) |> Stream.run() end + + def get_by_url(url_or_host) do + url = host(url_or_host) + Repo.get_by(Instance, host: url) + end + + def get_cached_by_url(url_or_host) do + url = host(url_or_host) + + @cachex.fetch!(:instances_cache, "instances:#{url}", fn _ -> + with %Instance{} = instance <- get_by_url(url) do + {:ok, instance} + else + _ -> {:ignore, nil} + end + end) + end end diff --git a/lib/pleroma/web/activity_pub/side_effects.ex b/lib/pleroma/web/activity_pub/side_effects.ex index a3830e408..46434ad5b 100644 --- a/lib/pleroma/web/activity_pub/side_effects.ex +++ b/lib/pleroma/web/activity_pub/side_effects.ex @@ -210,7 +210,11 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do reply_depth = (meta[:depth] || 0) + 1 IO.puts("QUEUE!") - Pleroma.Workers.NodeInfoFetcherWorker.enqueue("process", %{"domain" => activity.data["actor"]}) + + Pleroma.Workers.NodeInfoFetcherWorker.enqueue("process", %{ + "domain" => activity.data["actor"] + }) + # FIXME: Force inReplyTo to replies if Pleroma.Web.Federator.allowed_thread_distance?(reply_depth) and object.data["replies"] != nil do diff --git a/lib/pleroma/web/mastodon_api/views/account_view.ex b/lib/pleroma/web/mastodon_api/views/account_view.ex index 06acf0a26..8172a81fb 100644 --- a/lib/pleroma/web/mastodon_api/views/account_view.ex +++ b/lib/pleroma/web/mastodon_api/views/account_view.ex @@ -186,6 +186,16 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do render_many(targets, AccountView, "relationship.json", render_opts) end + def render("instance.json", %{instance: %Pleroma.Instances.Instance{} = instance}) do + %{ + name: instance.host, + favicon: instance.favicon |> MediaProxy.url(), + nodeinfo: instance.nodeinfo + } + end + + def render("instance.json", _), do: nil + defp do_render("show.json", %{user: user} = opts) do user = User.sanitize_html(user, User.html_filter_policy(opts[:for])) display_name = user.name || user.nickname @@ -230,17 +240,19 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do %{} end - favicon = - if Pleroma.Config.get([:instances_favicons, :enabled]) do - user - |> Map.get(:ap_id, "") - |> URI.parse() - |> URI.merge("/") - |> Pleroma.Instances.Instance.get_or_update_favicon() - |> MediaProxy.url() - else - nil - end + instance = with {:ok, instance} <- Pleroma.Instances.Instance.get_cached_by_url(user.ap_id) do + instance + else + _ -> + nil + end + + favicon = if is_nil(instance) do + nil + else + instance.favicon + |> MediaProxy.url() + end %{ id: to_string(user.id), @@ -271,7 +283,9 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do } }, last_status_at: user.last_status_at, - + akkoma: %{ + instance: render("instance.json", %{instance: instance}) + }, # Pleroma extensions # Note: it's insecure to output :email but fully-qualified nickname may serve as safe stub fqn: User.full_nickname(user), diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex index b3a35526e..8bb192bad 100644 --- a/lib/pleroma/web/mastodon_api/views/status_view.ex +++ b/lib/pleroma/web/mastodon_api/views/status_view.ex @@ -421,6 +421,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do nil end + def render("history.json", %{activity: %{data: %{"object" => _object}} = activity} = opts) do object = Object.normalize(activity, fetch: false) diff --git a/lib/pleroma/workers/nodeinfo_fetcher_worker.ex b/lib/pleroma/workers/nodeinfo_fetcher_worker.ex index 5a58de268..0ac395cdc 100644 --- a/lib/pleroma/workers/nodeinfo_fetcher_worker.ex +++ b/lib/pleroma/workers/nodeinfo_fetcher_worker.ex @@ -8,9 +8,10 @@ defmodule Pleroma.Workers.NodeInfoFetcherWorker do def perform(%Job{ args: %{"op" => "process", "domain" => domain} }) do - uri = domain - |> URI.parse() - |> URI.merge("/") + uri = + domain + |> URI.parse() + |> URI.merge("/") Instance.update_metadata(uri) end