Merge branch 'develop' into feature/digest-email
[akkoma] / lib / pleroma / web / mastodon_api / search_controller.ex
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.Web.MastodonAPI.SearchController do
6 use Pleroma.Web, :controller
7 alias Pleroma.Activity
8 alias Pleroma.User
9 alias Pleroma.Web
10 alias Pleroma.Web.MastodonAPI.AccountView
11 alias Pleroma.Web.MastodonAPI.StatusView
12
13 alias Pleroma.Web.ControllerHelper
14
15 require Logger
16
17 plug(Pleroma.Plugs.RateLimiter, :search when action in [:search, :search2, :account_search])
18
19 def search2(%{assigns: %{user: user}} = conn, %{"q" => query} = params) do
20 accounts = User.search(query, search_options(params, user))
21 statuses = Activity.search(user, query)
22 tags_path = Web.base_url() <> "/tag/"
23
24 tags =
25 query
26 |> String.split()
27 |> Enum.uniq()
28 |> Enum.filter(fn tag -> String.starts_with?(tag, "#") end)
29 |> Enum.map(fn tag -> String.slice(tag, 1..-1) end)
30 |> Enum.map(fn tag -> %{name: tag, url: tags_path <> tag} end)
31
32 res = %{
33 "accounts" => AccountView.render("accounts.json", users: accounts, for: user, as: :user),
34 "statuses" =>
35 StatusView.render("index.json", activities: statuses, for: user, as: :activity),
36 "hashtags" => tags
37 }
38
39 json(conn, res)
40 end
41
42 def search(%{assigns: %{user: user}} = conn, %{"q" => query} = params) do
43 accounts = User.search(query, search_options(params, user))
44 statuses = Activity.search(user, query)
45
46 tags =
47 query
48 |> String.split()
49 |> Enum.uniq()
50 |> Enum.filter(fn tag -> String.starts_with?(tag, "#") end)
51 |> Enum.map(fn tag -> String.slice(tag, 1..-1) end)
52
53 res = %{
54 "accounts" => AccountView.render("accounts.json", users: accounts, for: user, as: :user),
55 "statuses" =>
56 StatusView.render("index.json", activities: statuses, for: user, as: :activity),
57 "hashtags" => tags
58 }
59
60 json(conn, res)
61 end
62
63 def account_search(%{assigns: %{user: user}} = conn, %{"q" => query} = params) do
64 accounts = User.search(query, search_options(params, user))
65 res = AccountView.render("accounts.json", users: accounts, for: user, as: :user)
66
67 json(conn, res)
68 end
69
70 defp search_options(params, user) do
71 [
72 resolve: params["resolve"] == "true",
73 following: params["following"] == "true",
74 limit: ControllerHelper.fetch_integer_param(params, "limit"),
75 offset: ControllerHelper.fetch_integer_param(params, "offset"),
76 for_user: user
77 ]
78 end
79 end