giant massive dep upgrade and dialyxir-found error emporium (#371)
[akkoma] / lib / pleroma / search / meilisearch.ex
index 8745d539d799a3a4e6b12b06a5e7cae0f3e8fdd4..8fcf9310a2b60ddb594dc71929ce4501d8ec0fa2 100644 (file)
@@ -4,26 +4,62 @@ defmodule Pleroma.Search.Meilisearch do
 
   alias Pleroma.Activity
 
-  import Pleroma.Activity.Search
+  import Pleroma.Search.DatabaseSearch
   import Ecto.Query
 
-  defp meili_headers() do
+  @behaviour Pleroma.Search.SearchBackend
+
+  defp meili_headers do
     private_key = Pleroma.Config.get([Pleroma.Search.Meilisearch, :private_key])
 
-    if is_nil(private_key), do: [], else: [{"X-Meili-API-Key", private_key}]
+    [{"Content-Type", "application/json"}] ++
+      if is_nil(private_key), do: [], else: [{"Authorization", "Bearer #{private_key}"}]
+  end
+
+  def meili_get(path) do
+    endpoint = Pleroma.Config.get([Pleroma.Search.Meilisearch, :url])
+
+    result =
+      Pleroma.HTTP.get(
+        Path.join(endpoint, path),
+        meili_headers()
+      )
+
+    with {:ok, res} <- result do
+      {:ok, Jason.decode!(res.body)}
+    end
   end
 
-  def meili_post!(path, params) do
+  def meili_post(path, params) do
     endpoint = Pleroma.Config.get([Pleroma.Search.Meilisearch, :url])
 
-    {:ok, result} =
+    result =
       Pleroma.HTTP.post(
         Path.join(endpoint, path),
         Jason.encode!(params),
         meili_headers()
       )
 
-    Jason.decode!(result.body)
+    with {:ok, res} <- result do
+      {:ok, Jason.decode!(res.body)}
+    end
+  end
+
+  def meili_put(path, params) do
+    endpoint = Pleroma.Config.get([Pleroma.Search.Meilisearch, :url])
+
+    result =
+      Pleroma.HTTP.request(
+        :put,
+        Path.join(endpoint, path),
+        Jason.encode!(params),
+        meili_headers(),
+        []
+      )
+
+    with {:ok, res} <- result do
+      {:ok, Jason.decode!(res.body)}
+    end
   end
 
   def meili_delete!(path) do
@@ -35,7 +71,7 @@ defmodule Pleroma.Search.Meilisearch do
         Path.join(endpoint, path),
         "",
         meili_headers(),
-        timeout: :infinity
+        []
       )
   end
 
@@ -44,34 +80,40 @@ defmodule Pleroma.Search.Meilisearch do
     offset = Keyword.get(options, :offset, 0)
     author = Keyword.get(options, :author)
 
-    result =
-      meili_post!(
+    res =
+      meili_post(
         "/indexes/objects/search",
         %{q: query, offset: offset, limit: limit}
       )
 
-    hits = result["hits"] |> Enum.map(& &1["ap"])
-
-    try do
-      hits
-      |> Activity.create_by_object_ap_id()
-      |> Activity.with_preloaded_object()
-      |> Activity.with_preloaded_object()
-      |> Activity.restrict_deactivated_users()
-      |> maybe_restrict_local(user)
-      |> maybe_restrict_author(author)
-      |> maybe_restrict_blocked(user)
-      |> maybe_fetch(user, query)
-      |> order_by([object: obj], desc: obj.data["published"])
-      |> Pleroma.Repo.all()
-    rescue
-      _ -> maybe_fetch([], user, query)
+    with {:ok, result} <- res do
+      hits = result["hits"] |> Enum.map(& &1["ap"])
+
+      try do
+        hits
+        |> Activity.create_by_object_ap_id()
+        |> Activity.with_preloaded_object()
+        |> Activity.with_preloaded_object()
+        |> Activity.restrict_deactivated_users()
+        |> maybe_restrict_local(user)
+        |> maybe_restrict_author(author)
+        |> maybe_restrict_blocked(user)
+        |> maybe_fetch(user, query)
+        |> order_by([object: obj], desc: obj.data["published"])
+        |> Pleroma.Repo.all()
+      rescue
+        _ -> maybe_fetch([], user, query)
+      end
     end
   end
 
   def object_to_search_data(object) do
+    # Only index public or unlisted Notes
     if not is_nil(object) and object.data["type"] == "Note" and
-         Pleroma.Constants.as_public() in object.data["to"] do
+         not is_nil(object.data["content"]) and
+         (Pleroma.Constants.as_public() in object.data["to"] or
+            Pleroma.Constants.as_public() in object.data["cc"]) and
+         String.length(object.data["content"]) > 1 do
       data = object.data
 
       content_str =
@@ -86,7 +128,7 @@ defmodule Pleroma.Search.Meilisearch do
           trimmed
         end
 
-      if String.length(content) > 1 do
+      if String.length(content) > 1 and not is_nil(data["published"]) do
         {:ok, published, _} = DateTime.from_iso8601(data["published"])
 
         %{
@@ -99,22 +141,29 @@ defmodule Pleroma.Search.Meilisearch do
     end
   end
 
+  @impl true
   def add_to_index(activity) do
-    maybe_search_data = object_to_search_data(activity)
+    maybe_search_data = object_to_search_data(activity.object)
 
     if activity.data["type"] == "Create" and maybe_search_data do
       result =
-        meili_post!(
+        meili_put(
           "/indexes/objects/documents",
           [maybe_search_data]
         )
 
-      if not Map.has_key?(result, "updateId") do
-        Logger.error("Failed to add activity #{activity.id} to index: #{inspect(result)}")
+      with {:ok, res} <- result,
+           true <- Map.has_key?(res, "taskUid") do
+        {:ok, res}
+      else
+        err ->
+          Logger.error("Failed to add activity #{activity.id} to index: #{inspect(result)}")
+          {:error, err}
       end
     end
   end
 
+  @impl true
   def remove_from_index(object) do
     meili_delete!("/indexes/objects/documents/#{object.id}")
   end