giant massive dep upgrade and dialyxir-found error emporium (#371)
[akkoma] / lib / pleroma / search / elasticsearch.ex
index 614a48bb9605fd51fedf8e54fc6a5c7fd1dd2a1c..20e03e1f0d7c40b6a7e1c44c54fd05cccb7c038f 100644 (file)
@@ -1,79 +1,33 @@
+# Akkoma: A lightweight social networking server
+# Copyright © 2022-2022 Akkoma Authors <https://git.ihatebeinga.live/IHBAGang/akkoma/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
 defmodule Pleroma.Search.Elasticsearch do
-  @behaviour Pleroma.Search
+  @behaviour Pleroma.Search.SearchBackend
 
   alias Pleroma.Activity
   alias Pleroma.Object.Fetcher
-  alias Pleroma.Web.MastodonAPI.StatusView
-  alias Pleroma.Web.MastodonAPI.AccountView
   alias Pleroma.Web.ActivityPub.Visibility
   alias Pleroma.Search.Elasticsearch.Parsers
-  alias Pleroma.Web.Endpoint
 
-  def es_query(:activity, query) do
+  def es_query(:activity, query, offset, limit) do
     must = Parsers.Activity.parse(query)
 
-    if must == [] do
-      :skip
-    else
-      %{
-        size: 50,
-        terminate_after: 50,
-        timeout: "5s",
-        sort: [
-          "_score",
-          %{_timestamp: %{order: "desc", format: "basic_date_time"}}
-        ],
-        query: %{
-          bool: %{
-            must: must
-          }
-        }
-      }
-    end
-  end
-
-  def es_query(:user, query) do
-    must = Parsers.User.parse(query)
-
-    if must == [] do
-      :skip
-    else
-      %{
-        size: 50,
-        terminate_after: 50,
-        timeout: "5s",
-        sort: [
-          "_score"
-        ],
-        query: %{
-          bool: %{
-            must: must
-          }
-        }
-      }
-    end
-  end
-
-  def es_query(:hashtag, query) do
-    must = Parsers.Hashtag.parse(query)
-
-    if must == [] do
-      :skip
-    else
-      %{
-        size: 50,
-        terminate_after: 50,
-        timeout: "5s",
-        sort: [
-          "_score"
-        ],
-        query: %{
-          bool: %{
-            must: Parsers.Hashtag.parse(query)
-          }
+    %{
+      size: limit,
+      from: offset,
+      terminate_after: 50,
+      timeout: "5s",
+      sort: [
+        "_score",
+        %{"_timestamp" => %{order: "desc", format: "basic_date_time"}}
+      ],
+      query: %{
+        bool: %{
+          must: must
         }
       }
-    end
+    }
   end
 
   defp maybe_fetch(:activity, search_query) do
@@ -86,8 +40,10 @@ defmodule Pleroma.Search.Elasticsearch do
     end
   end
 
-  @impl Pleroma.Search
-  def search(%{assigns: %{user: user}} = _conn, %{q: query} = _params, _options) do
+  def search(user, query, options) do
+    limit = Enum.min([Keyword.get(options, :limit), 40])
+    offset = Keyword.get(options, :offset, 0)
+
     parsed_query =
       query
       |> String.trim()
@@ -100,30 +56,17 @@ defmodule Pleroma.Search.Elasticsearch do
 
     activity_task =
       Task.async(fn ->
-        q = es_query(:activity, parsed_query)
-
-        Pleroma.Elasticsearch.search(:activities, q)
-        |> Enum.filter(fn x -> Visibility.visible_for_user?(x, user) end)
-      end)
-
-    user_task =
-      Task.async(fn ->
-        q = es_query(:user, parsed_query)
-
-        Pleroma.Elasticsearch.search(:users, q)
-        |> Enum.filter(fn x -> Pleroma.User.visible_for(x, user) == :visible end)
-      end)
-
-    hashtag_task =
-      Task.async(fn ->
-        q = es_query(:hashtag, parsed_query)
-
-        Pleroma.Elasticsearch.search(:hashtags, q)
+        q = es_query(:activity, parsed_query, offset, limit)
+
+        :activities
+        |> Pleroma.Search.Elasticsearch.Store.search(q)
+        |> Enum.filter(fn x ->
+          x.data["type"] == "Create" && x.object.data["type"] == "Note" &&
+            Visibility.visible_for_user?(x, user)
+        end)
       end)
 
     activity_results = Task.await(activity_task)
-    user_results = Task.await(user_task)
-    hashtag_results = Task.await(hashtag_task)
     direct_activity = Task.await(activity_fetch_task)
 
     activity_results =
@@ -133,25 +76,16 @@ defmodule Pleroma.Search.Elasticsearch do
         [direct_activity | activity_results]
       end
 
-    %{
-      "accounts" =>
-        AccountView.render("index.json",
-          users: user_results,
-          for: user
-        ),
-      "hashtags" =>
-        Enum.map(hashtag_results, fn x ->
-          %{
-            url: Endpoint.url() <> "/tag/" <> x,
-            name: x
-          }
-        end),
-      "statuses" =>
-        StatusView.render("index.json",
-          activities: activity_results,
-          for: user,
-          as: :activity
-        )
-    }
+    activity_results
+  end
+
+  @impl true
+  def add_to_index(activity) do
+    Elasticsearch.put_document(Pleroma.Search.Elasticsearch.Cluster, activity, "activities")
+  end
+
+  @impl true
+  def remove_from_index(object) do
+    Elasticsearch.delete_document(Pleroma.Search.Elasticsearch.Cluster, object, "activities")
   end
 end