Implement meilisearch auth
[akkoma] / lib / mix / tasks / pleroma / search / meilisearch.ex
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Mix.Tasks.Pleroma.Search.Meilisearch do
6 require Logger
7 require Pleroma.Constants
8
9 import Mix.Pleroma
10 import Ecto.Query
11
12 import Pleroma.Search.Meilisearch, only: [meili_post!: 2, meili_delete!: 1]
13
14 def run(["index"]) do
15 start_pleroma()
16
17 meili_post!(
18 "/indexes/objects/settings/ranking-rules",
19 [
20 "desc(published)",
21 "typo",
22 "words",
23 "proximity",
24 "attribute",
25 "wordsPosition",
26 "exactness"
27 ]
28 )
29
30 meili_post!(
31 "/indexes/objects/settings/searchable-attributes",
32 [
33 "content"
34 ]
35 )
36
37 chunk_size = 10_000
38
39 Pleroma.Repo.transaction(
40 fn ->
41 Pleroma.Repo.stream(
42 from(Pleroma.Object,
43 # Only index public posts which are notes and have some text
44 where:
45 fragment("data->>'type' = 'Note'") and
46 fragment("LENGTH(data->>'content') > 0") and
47 fragment("data->'to' \\? ?", ^Pleroma.Constants.as_public()),
48 order_by: [desc: fragment("data->'published'")]
49 ),
50 timeout: :infinity
51 )
52 |> Stream.map(&Pleroma.Search.Meilisearch.object_to_search_data/1)
53 |> Stream.filter(fn o -> not is_nil(o) end)
54 |> Stream.chunk_every(chunk_size)
55 |> Stream.transform(0, fn objects, acc ->
56 new_acc = acc + Enum.count(objects)
57
58 # Reset to the beginning of the line and rewrite it
59 IO.write("\r")
60 IO.write("Indexed #{new_acc} entries")
61
62 {[objects], new_acc}
63 end)
64 |> Stream.each(fn objects ->
65 result =
66 meili_post!(
67 "/indexes/objects/documents",
68 objects
69 )
70
71 if not Map.has_key?(result, "updateId") do
72 IO.puts("Failed to index: #{inspect(result)}")
73 end
74 end)
75 |> Stream.run()
76 end,
77 timeout: :infinity
78 )
79
80 IO.write("\n")
81 end
82
83 def run(["clear"]) do
84 start_pleroma()
85
86 meili_delete!("/indexes/objects/documents")
87 end
88
89 def run(["show-private-key", master_key]) do
90 start_pleroma()
91
92 endpoint = Pleroma.Config.get([Pleroma.Search.Meilisearch, :url])
93
94 {:ok, result} =
95 Pleroma.HTTP.get(
96 Path.join(endpoint, "/keys"),
97 [{"X-Meili-API-Key", master_key}]
98 )
99
100 decoded = Jason.decode!(result.body)
101
102 if decoded["private"] do
103 IO.puts(decoded["private"])
104 else
105 IO.puts("Error fetching the key, check the master key is correct: #{inspect(decoded)}")
106 end
107 end
108 end