Add "local" params to users search

This commit is contained in:
Maxim Filippov 2019-03-01 20:13:02 +03:00
parent adac745512
commit 5b08b470f6
6 changed files with 87 additions and 39 deletions

View File

@ -20,13 +20,14 @@ Authentication is required and the user must be an admin.
]
```
## `/api/pleroma/admin/users/search?query={query}`
## `/api/pleroma/admin/users/search?query={query}&local={local}`
### Search users
### Search users by name or nickname
- Method `GET`
- Params:
- `query`
- `query`: **string** search term
- `local`: **bool** whether to return only local users
- Response:
```JSON

View File

@ -755,18 +755,25 @@ defmodule Pleroma.User do
Repo.all(query)
end
def search(query, resolve \\ false, for_user \\ nil, limit \\ 20) do
def search(term, options \\ %{}) do
# Strip the beginning @ off if there is a query
query = String.trim_leading(query, "@")
term = String.trim_leading(term, "@")
query = options[:query] || User
if resolve, do: get_or_fetch(query)
if options[:resolve], do: get_or_fetch(term)
fts_results = do_search(fts_search_subquery(query), for_user, %{limit: limit})
fts_results =
do_search(fts_search_subquery(term, query), options[:for_user], %{
limit: options[:limit]
})
{:ok, trigram_results} =
Repo.transaction(fn ->
Ecto.Adapters.SQL.query(Repo, "select set_limit(0.25)", [])
do_search(trigram_search_subquery(query), for_user, %{limit: limit})
do_search(trigram_search_subquery(term, query), options[:for_user], %{
limit: options[:limit]
})
end)
Enum.uniq_by(fts_results ++ trigram_results, & &1.id)
@ -809,9 +816,9 @@ defmodule Pleroma.User do
boost_search_results(results, for_user)
end
defp fts_search_subquery(query) do
defp fts_search_subquery(term, query) do
processed_query =
query
term
|> String.replace(~r/\W+/, " ")
|> String.trim()
|> String.split()
@ -819,7 +826,7 @@ defmodule Pleroma.User do
|> Enum.join(" | ")
from(
u in User,
u in query,
select_merge: %{
search_rank:
fragment(
@ -849,19 +856,19 @@ defmodule Pleroma.User do
)
end
defp trigram_search_subquery(query) do
defp trigram_search_subquery(term, query) do
from(
u in User,
u in query,
select_merge: %{
search_rank:
fragment(
"similarity(?, trim(? || ' ' || coalesce(?, '')))",
^query,
^term,
u.nickname,
u.name
)
},
where: fragment("trim(? || ' ' || coalesce(?, '')) % ?", u.nickname, u.name, ^query)
where: fragment("trim(? || ' ' || coalesce(?, '')) % ?", u.nickname, u.name, ^term)
)
end
@ -1018,6 +1025,14 @@ defmodule Pleroma.User do
update_and_set_cache(cng)
end
def maybe_local_user_query(local) when local == true do
local_user_query()
end
def maybe_local_user_query(local) when local == false do
User
end
def local_user_query do
from(
u in User,

View File

@ -78,8 +78,14 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
)
end
def search_users(%{assigns: %{user: admin}} = conn, %{"query" => query}) do
users = User.search(query, true, admin, @users_page_size)
def search_users(%{assigns: %{user: admin}} = conn, %{"query" => term} = params) do
users =
User.search(term,
query: User.maybe_local_user_query(params["local"] == "true"),
resolve: true,
for_user: admin,
limit: @users_page_size
)
conn
|> json(

View File

@ -894,7 +894,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
end
def search2(%{assigns: %{user: user}} = conn, %{"q" => query} = params) do
accounts = User.search(query, params["resolve"] == "true", user)
accounts = User.search(query, resolve: params["resolve"] == "true", for_user: user)
statuses = status_search(user, query)
@ -919,7 +919,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
end
def search(%{assigns: %{user: user}} = conn, %{"q" => query} = params) do
accounts = User.search(query, params["resolve"] == "true", user)
accounts = User.search(query, resolve: params["resolve"] == "true", for_user: user)
statuses = status_search(user, query)
@ -941,7 +941,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
end
def account_search(%{assigns: %{user: user}} = conn, %{"q" => query} = params) do
accounts = User.search(query, params["resolve"] == "true", user)
accounts = User.search(query, resolve: params["resolve"] == "true", for_user: user)
res = AccountView.render("accounts.json", users: accounts, for: user, as: :user)

View File

@ -702,7 +702,7 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
end
def search_user(%{assigns: %{user: user}} = conn, %{"query" => query}) do
users = User.search(query, true, user)
users = User.search(query, resolve: true, for_user: user)
conn
|> put_view(UserView)

View File

@ -388,25 +388,51 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
}
end
test "GET /api/pleroma/admin/users/search" do
admin = insert(:user, info: %{is_admin: true})
user = insert(:user, nickname: "bob")
describe "GET /api/pleroma/admin/users/search" do
test "regular search" do
admin = insert(:user, info: %{is_admin: true})
user = insert(:user, nickname: "bob")
conn =
build_conn()
|> assign(:user, admin)
|> get("/api/pleroma/admin/users/search?query=bo")
conn =
build_conn()
|> assign(:user, admin)
|> get("/api/pleroma/admin/users/search?query=bo")
assert json_response(conn, 200) == %{
"count" => 1,
"page_size" => 50,
"users" => [
%{
"deactivated" => user.info.deactivated,
"id" => user.id,
"nickname" => user.nickname
}
]
}
assert json_response(conn, 200) == %{
"count" => 1,
"page_size" => 50,
"users" => [
%{
"deactivated" => user.info.deactivated,
"id" => user.id,
"nickname" => user.nickname
}
]
}
end
test "only local users" do
admin = insert(:user, info: %{is_admin: true})
user = insert(:user, nickname: "bob")
insert(:user, nickname: "bobb", local: false)
conn =
build_conn()
|> assign(:user, admin)
|> get("/api/pleroma/admin/users/search?query=bo&local=true")
assert json_response(conn, 200) == %{
"count" => 1,
"page_size" => 50,
"users" => [
%{
"deactivated" => user.info.deactivated,
"id" => user.id,
"nickname" => user.nickname
}
]
}
end
end
end