[#1234] Merge remote-tracking branch 'remotes/upstream/develop' into 1234-mastodon...
[akkoma] / lib / pleroma / activity / search.ex
index f2fdfffe12051c34773531e15d440e51f629ea28..f847ac2381faa0d25678aa79503a8cc1752ba24c 100644 (file)
@@ -5,14 +5,19 @@
 defmodule Pleroma.Activity.Search do
   alias Pleroma.Activity
   alias Pleroma.Object.Fetcher
-  alias Pleroma.Repo
+  alias Pleroma.Pagination
   alias Pleroma.User
   alias Pleroma.Web.ActivityPub.Visibility
 
+  require Pleroma.Constants
+
   import Ecto.Query
 
-  def search(user, search_query) do
+  def search(user, search_query, options \\ []) do
     index_type = if Pleroma.Config.get([:database, :rum_enabled]), do: :rum, else: :gin
+    limit = Enum.min([Keyword.get(options, :limit), 40])
+    offset = Keyword.get(options, :offset, 0)
+    author = Keyword.get(options, :author)
 
     Activity
     |> Activity.with_preloaded_object()
@@ -20,15 +25,23 @@ defmodule Pleroma.Activity.Search do
     |> restrict_public()
     |> query_with(index_type, search_query)
     |> maybe_restrict_local(user)
-    |> Repo.all()
+    |> maybe_restrict_author(author)
+    |> Pagination.fetch_paginated(%{"offset" => offset, "limit" => limit}, :offset)
     |> maybe_fetch(user, search_query)
   end
 
+  def maybe_restrict_author(query, %User{} = author) do
+    from([a, o] in query,
+      where: a.actor == ^author.ap_id
+    )
+  end
+
+  def maybe_restrict_author(query, _), do: query
+
   defp restrict_public(q) do
     from([a, o] in q,
       where: fragment("?->>'type' = 'Create'", a.data),
-      where: "https://www.w3.org/ns/activitystreams#Public" in a.recipients,
-      limit: 40
+      where: ^Pleroma.Constants.as_public() in a.recipients
     )
   end
 
@@ -39,8 +52,7 @@ defmodule Pleroma.Activity.Search do
           "to_tsvector('english', ?->>'content') @@ plainto_tsquery('english', ?)",
           o.data,
           ^search_query
-        ),
-      order_by: [desc: :id]
+        )
     )
   end
 
@@ -56,11 +68,18 @@ defmodule Pleroma.Activity.Search do
     )
   end
 
-  # users can search everything
-  defp maybe_restrict_local(q, %User{}), do: q
+  defp maybe_restrict_local(q, user) do
+    limit = Pleroma.Config.get([:instance, :limit_to_local_content], :unauthenticated)
+
+    case {limit, user} do
+      {:all, _} -> restrict_local(q)
+      {:unauthenticated, %User{}} -> q
+      {:unauthenticated, _} -> restrict_local(q)
+      {false, _} -> q
+    end
+  end
 
-  # unauthenticated users can only search local activities
-  defp maybe_restrict_local(q, _), do: where(q, local: true)
+  defp restrict_local(q), do: where(q, local: true)
 
   defp maybe_fetch(activities, user, search_query) do
     with true <- Regex.match?(~r/https?:/, search_query),