Merge branch 'develop' of gitssh.ihatebeinga.live:IHBAGang/pleroma into develop
[akkoma] / lib / pleroma / search / elasticsearch.ex
1 defmodule Pleroma.Search.Elasticsearch do
2 @behaviour Pleroma.Search
3
4 alias Pleroma.Web.MastodonAPI.StatusView
5 alias Pleroma.Web.MastodonAPI.AccountView
6 alias Pleroma.Web.ActivityPub.Visibility
7 alias Pleroma.Search.Elasticsearch.Parsers
8 alias Pleroma.Web.Endpoint
9
10 defp es_query(:activity, query) do
11 %{
12 size: 500,
13 terminate_after: 500,
14 timeout: "10s",
15 sort: [
16 %{"_timestamp" => "desc"}
17 ],
18 query: %{
19 bool: %{
20 must: Parsers.Activity.parse(query)
21 }
22 }
23 }
24 end
25
26 defp es_query(:user, query) do
27 %{
28 size: 50,
29 terminate_after: 50,
30 timeout: "10s",
31 sort: [
32 %{"_timestamp" => "desc"}
33 ],
34 query: %{
35 bool: %{
36 must: Parsers.User.parse(query)
37 }
38 }
39 }
40 end
41
42 defp es_query(:hashtag, query) do
43 %{
44 size: 50,
45 terminate_after: 50,
46 timeout: "10s",
47 query: %{
48 bool: %{
49 must: Parsers.Hashtag.parse(query)
50 }
51 }
52 }
53 end
54
55 @impl Pleroma.Search
56 def search(%{assigns: %{user: user}} = _conn, %{q: query} = _params, _options) do
57 parsed_query =
58 query
59 |> String.trim()
60 |> SearchParser.parse!()
61
62 activity_task =
63 Task.async(fn ->
64 q = es_query(:activity, parsed_query)
65
66 Pleroma.Elasticsearch.search(:activities, q)
67 |> Enum.filter(fn x -> Visibility.visible_for_user?(x, user) end)
68 end)
69
70 user_task =
71 Task.async(fn ->
72 q = es_query(:user, parsed_query)
73
74 Pleroma.Elasticsearch.search(:users, q)
75 |> Enum.filter(fn x -> Pleroma.User.visible_for(x, user) == :visible end)
76 end)
77
78 hashtag_task =
79 Task.async(fn ->
80 q = es_query(:hashtag, parsed_query)
81
82 Pleroma.Elasticsearch.search(:hashtags, q)
83 end)
84
85 activity_results = Task.await(activity_task)
86 user_results = Task.await(user_task)
87 hashtag_results = Task.await(hashtag_task)
88
89 %{
90 "accounts" =>
91 AccountView.render("index.json",
92 users: user_results,
93 for: user
94 ),
95 "hashtags" =>
96 Enum.map(hashtag_results, fn x ->
97 %{
98 url: Endpoint.url() <> "/tag/" <> x,
99 name: x
100 }
101 end),
102 "statuses" =>
103 StatusView.render("index.json",
104 activities: activity_results,
105 for: user,
106 as: :activity
107 )
108 }
109 end
110 end