aboutsummaryrefslogtreecommitdiff
path: root/lib/pleroma/user
diff options
context:
space:
mode:
Diffstat (limited to 'lib/pleroma/user')
-rw-r--r--lib/pleroma/user/info.ex478
-rw-r--r--lib/pleroma/user/query.ex56
-rw-r--r--lib/pleroma/user/search.ex160
3 files changed, 100 insertions, 594 deletions
diff --git a/lib/pleroma/user/info.ex b/lib/pleroma/user/info.ex
deleted file mode 100644
index 4b5b43d7f..000000000
--- a/lib/pleroma/user/info.ex
+++ /dev/null
@@ -1,478 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.User.Info do
- use Ecto.Schema
- import Ecto.Changeset
-
- alias Pleroma.User.Info
-
- @type t :: %__MODULE__{}
-
- embedded_schema do
- field(:banner, :map, default: %{})
- field(:background, :map, default: %{})
- field(:source_data, :map, default: %{})
- field(:note_count, :integer, default: 0)
- field(:follower_count, :integer, default: 0)
- # Should be filled in only for remote users
- field(:following_count, :integer, default: nil)
- field(:locked, :boolean, default: false)
- field(:confirmation_pending, :boolean, default: false)
- field(:password_reset_pending, :boolean, default: false)
- field(:confirmation_token, :string, default: nil)
- field(:default_scope, :string, default: "public")
- field(:blocks, {:array, :string}, default: [])
- field(:domain_blocks, {:array, :string}, default: [])
- field(:mutes, {:array, :string}, default: [])
- field(:muted_reblogs, {:array, :string}, default: [])
- field(:muted_notifications, {:array, :string}, default: [])
- field(:subscribers, {:array, :string}, default: [])
- field(:deactivated, :boolean, default: false)
- field(:no_rich_text, :boolean, default: false)
- field(:ap_enabled, :boolean, default: false)
- field(:is_moderator, :boolean, default: false)
- field(:is_admin, :boolean, default: false)
- field(:show_role, :boolean, default: true)
- field(:keys, :string, default: nil)
- field(:settings, :map, default: nil)
- field(:magic_key, :string, default: nil)
- field(:uri, :string, default: nil)
- field(:topic, :string, default: nil)
- field(:hub, :string, default: nil)
- field(:salmon, :string, default: nil)
- field(:hide_followers_count, :boolean, default: false)
- field(:hide_follows_count, :boolean, default: false)
- field(:hide_followers, :boolean, default: false)
- field(:hide_follows, :boolean, default: false)
- field(:hide_favorites, :boolean, default: true)
- field(:unread_conversation_count, :integer, default: 0)
- field(:pinned_activities, {:array, :string}, default: [])
- field(:email_notifications, :map, default: %{"digest" => false})
- field(:mascot, :map, default: nil)
- field(:emoji, {:array, :map}, default: [])
- field(:pleroma_settings_store, :map, default: %{})
- field(:fields, {:array, :map}, default: nil)
- field(:raw_fields, {:array, :map}, default: [])
- field(:discoverable, :boolean, default: false)
-
- field(:notification_settings, :map,
- default: %{
- "followers" => true,
- "follows" => true,
- "non_follows" => true,
- "non_followers" => true
- }
- )
-
- field(:skip_thread_containment, :boolean, default: false)
-
- # Found in the wild
- # ap_id -> Where is this used?
- # bio -> Where is this used?
- # avatar -> Where is this used?
- # fqn -> Where is this used?
- # host -> Where is this used?
- # subject _> Where is this used?
- end
-
- def set_activation_status(info, deactivated) do
- params = %{deactivated: deactivated}
-
- info
- |> cast(params, [:deactivated])
- |> validate_required([:deactivated])
- end
-
- def set_password_reset_pending(info, pending) do
- params = %{password_reset_pending: pending}
-
- info
- |> cast(params, [:password_reset_pending])
- |> validate_required([:password_reset_pending])
- end
-
- def update_notification_settings(info, settings) do
- settings =
- settings
- |> Enum.map(fn {k, v} -> {k, v in [true, "true", "True", "1"]} end)
- |> Map.new()
-
- notification_settings =
- info.notification_settings
- |> Map.merge(settings)
- |> Map.take(["followers", "follows", "non_follows", "non_followers"])
-
- params = %{notification_settings: notification_settings}
-
- info
- |> cast(params, [:notification_settings])
- |> validate_required([:notification_settings])
- end
-
- @doc """
- Update email notifications in the given User.Info struct.
-
- Examples:
-
- iex> update_email_notifications(%Pleroma.User.Info{email_notifications: %{"digest" => false}}, %{"digest" => true})
- %Pleroma.User.Info{email_notifications: %{"digest" => true}}
-
- """
- @spec update_email_notifications(t(), map()) :: Ecto.Changeset.t()
- def update_email_notifications(info, settings) do
- email_notifications =
- info.email_notifications
- |> Map.merge(settings)
- |> Map.take(["digest"])
-
- params = %{email_notifications: email_notifications}
- fields = [:email_notifications]
-
- info
- |> cast(params, fields)
- |> validate_required(fields)
- end
-
- def add_to_note_count(info, number) do
- set_note_count(info, info.note_count + number)
- end
-
- def set_note_count(info, number) do
- params = %{note_count: Enum.max([0, number])}
-
- info
- |> cast(params, [:note_count])
- |> validate_required([:note_count])
- end
-
- def set_follower_count(info, number) do
- params = %{follower_count: Enum.max([0, number])}
-
- info
- |> cast(params, [:follower_count])
- |> validate_required([:follower_count])
- end
-
- def set_mutes(info, mutes) do
- params = %{mutes: mutes}
-
- info
- |> cast(params, [:mutes])
- |> validate_required([:mutes])
- end
-
- @spec set_notification_mutes(Changeset.t(), [String.t()], boolean()) :: Changeset.t()
- def set_notification_mutes(changeset, muted_notifications, notifications?) do
- if notifications? do
- put_change(changeset, :muted_notifications, muted_notifications)
- |> validate_required([:muted_notifications])
- else
- changeset
- end
- end
-
- def set_blocks(info, blocks) do
- params = %{blocks: blocks}
-
- info
- |> cast(params, [:blocks])
- |> validate_required([:blocks])
- end
-
- def set_subscribers(info, subscribers) do
- params = %{subscribers: subscribers}
-
- info
- |> cast(params, [:subscribers])
- |> validate_required([:subscribers])
- end
-
- @spec add_to_mutes(Info.t(), String.t(), boolean()) :: Changeset.t()
- def add_to_mutes(info, muted, notifications?) do
- info
- |> set_mutes(Enum.uniq([muted | info.mutes]))
- |> set_notification_mutes(
- Enum.uniq([muted | info.muted_notifications]),
- notifications?
- )
- end
-
- @spec remove_from_mutes(Info.t(), String.t()) :: Changeset.t()
- def remove_from_mutes(info, muted) do
- info
- |> set_mutes(List.delete(info.mutes, muted))
- |> set_notification_mutes(List.delete(info.muted_notifications, muted), true)
- end
-
- def add_to_block(info, blocked) do
- set_blocks(info, Enum.uniq([blocked | info.blocks]))
- end
-
- def remove_from_block(info, blocked) do
- set_blocks(info, List.delete(info.blocks, blocked))
- end
-
- def add_to_subscribers(info, subscribed) do
- set_subscribers(info, Enum.uniq([subscribed | info.subscribers]))
- end
-
- def remove_from_subscribers(info, subscribed) do
- set_subscribers(info, List.delete(info.subscribers, subscribed))
- end
-
- def set_domain_blocks(info, domain_blocks) do
- params = %{domain_blocks: domain_blocks}
-
- info
- |> cast(params, [:domain_blocks])
- |> validate_required([:domain_blocks])
- end
-
- def add_to_domain_block(info, domain_blocked) do
- set_domain_blocks(info, Enum.uniq([domain_blocked | info.domain_blocks]))
- end
-
- def remove_from_domain_block(info, domain_blocked) do
- set_domain_blocks(info, List.delete(info.domain_blocks, domain_blocked))
- end
-
- def set_keys(info, keys) do
- params = %{keys: keys}
-
- info
- |> cast(params, [:keys])
- |> validate_required([:keys])
- end
-
- def remote_user_creation(info, params) do
- params =
- if Map.has_key?(params, :fields) do
- Map.put(params, :fields, Enum.map(params[:fields], &truncate_field/1))
- else
- params
- end
-
- info
- |> cast(params, [
- :ap_enabled,
- :source_data,
- :banner,
- :locked,
- :magic_key,
- :uri,
- :hub,
- :topic,
- :salmon,
- :hide_followers,
- :hide_follows,
- :hide_followers_count,
- :hide_follows_count,
- :follower_count,
- :fields,
- :following_count,
- :discoverable
- ])
- |> validate_fields(true)
- end
-
- def user_upgrade(info, params, remote? \\ false) do
- info
- |> cast(params, [
- :ap_enabled,
- :source_data,
- :banner,
- :locked,
- :magic_key,
- :follower_count,
- :following_count,
- :hide_follows,
- :fields,
- :hide_followers,
- :discoverable,
- :hide_followers_count,
- :hide_follows_count
- ])
- |> validate_fields(remote?)
- end
-
- def profile_update(info, params) do
- info
- |> cast(params, [
- :locked,
- :no_rich_text,
- :default_scope,
- :banner,
- :hide_follows,
- :hide_followers,
- :hide_followers_count,
- :hide_follows_count,
- :hide_favorites,
- :background,
- :show_role,
- :skip_thread_containment,
- :fields,
- :raw_fields,
- :pleroma_settings_store,
- :discoverable
- ])
- |> validate_fields()
- end
-
- def validate_fields(changeset, remote? \\ false) do
- limit_name = if remote?, do: :max_remote_account_fields, else: :max_account_fields
- limit = Pleroma.Config.get([:instance, limit_name], 0)
-
- changeset
- |> validate_length(:fields, max: limit)
- |> validate_change(:fields, fn :fields, fields ->
- if Enum.all?(fields, &valid_field?/1) do
- []
- else
- [fields: "invalid"]
- end
- end)
- end
-
- defp valid_field?(%{"name" => name, "value" => value}) do
- name_limit = Pleroma.Config.get([:instance, :account_field_name_length], 255)
- value_limit = Pleroma.Config.get([:instance, :account_field_value_length], 255)
-
- is_binary(name) && is_binary(value) && String.length(name) <= name_limit &&
- String.length(value) <= value_limit
- end
-
- defp valid_field?(_), do: false
-
- defp truncate_field(%{"name" => name, "value" => value}) do
- {name, _chopped} =
- String.split_at(name, Pleroma.Config.get([:instance, :account_field_name_length], 255))
-
- {value, _chopped} =
- String.split_at(value, Pleroma.Config.get([:instance, :account_field_value_length], 255))
-
- %{"name" => name, "value" => value}
- end
-
- @spec confirmation_changeset(Info.t(), keyword()) :: Changeset.t()
- def confirmation_changeset(info, opts) do
- need_confirmation? = Keyword.get(opts, :need_confirmation)
-
- params =
- if need_confirmation? do
- %{
- confirmation_pending: true,
- confirmation_token: :crypto.strong_rand_bytes(32) |> Base.url_encode64()
- }
- else
- %{
- confirmation_pending: false,
- confirmation_token: nil
- }
- end
-
- cast(info, params, [:confirmation_pending, :confirmation_token])
- end
-
- def mastodon_settings_update(info, settings) do
- params = %{settings: settings}
-
- info
- |> cast(params, [:settings])
- |> validate_required([:settings])
- end
-
- def mascot_update(info, url) do
- params = %{mascot: url}
-
- info
- |> cast(params, [:mascot])
- |> validate_required([:mascot])
- end
-
- def set_source_data(info, source_data) do
- params = %{source_data: source_data}
-
- info
- |> cast(params, [:source_data])
- |> validate_required([:source_data])
- end
-
- def admin_api_update(info, params) do
- info
- |> cast(params, [
- :is_moderator,
- :is_admin,
- :show_role
- ])
- end
-
- def add_pinnned_activity(info, %Pleroma.Activity{id: id}) do
- if id not in info.pinned_activities do
- max_pinned_statuses = Pleroma.Config.get([:instance, :max_pinned_statuses], 0)
- params = %{pinned_activities: info.pinned_activities ++ [id]}
-
- info
- |> cast(params, [:pinned_activities])
- |> validate_length(:pinned_activities,
- max: max_pinned_statuses,
- message: "You have already pinned the maximum number of statuses"
- )
- else
- change(info)
- end
- end
-
- def remove_pinnned_activity(info, %Pleroma.Activity{id: id}) do
- params = %{pinned_activities: List.delete(info.pinned_activities, id)}
-
- cast(info, params, [:pinned_activities])
- end
-
- def roles(%Info{is_moderator: is_moderator, is_admin: is_admin}) do
- %{
- admin: is_admin,
- moderator: is_moderator
- }
- end
-
- def add_reblog_mute(info, ap_id) do
- params = %{muted_reblogs: info.muted_reblogs ++ [ap_id]}
-
- cast(info, params, [:muted_reblogs])
- end
-
- def remove_reblog_mute(info, ap_id) do
- params = %{muted_reblogs: List.delete(info.muted_reblogs, ap_id)}
-
- cast(info, params, [:muted_reblogs])
- end
-
- # ``fields`` is an array of mastodon profile field, containing ``{"name": "…", "value": "…"}``.
- # For example: [{"name": "Pronoun", "value": "she/her"}, …]
- def fields(%{fields: nil, source_data: %{"attachment" => attachment}}) do
- limit = Pleroma.Config.get([:instance, :max_remote_account_fields], 0)
-
- attachment
- |> Enum.filter(fn %{"type" => t} -> t == "PropertyValue" end)
- |> Enum.map(fn fields -> Map.take(fields, ["name", "value"]) end)
- |> Enum.take(limit)
- end
-
- def fields(%{fields: nil}), do: []
-
- def fields(%{fields: fields}), do: fields
-
- def follow_information_update(info, params) do
- info
- |> cast(params, [
- :hide_followers,
- :hide_follows,
- :follower_count,
- :following_count,
- :hide_followers_count,
- :hide_follows_count
- ])
- end
-end
diff --git a/lib/pleroma/user/query.ex b/lib/pleroma/user/query.ex
index 2baf016cf..364bc1c89 100644
--- a/lib/pleroma/user/query.ex
+++ b/lib/pleroma/user/query.ex
@@ -28,6 +28,8 @@ defmodule Pleroma.User.Query do
"""
import Ecto.Query
import Pleroma.Web.AdminAPI.Search, only: [not_empty_string: 1]
+
+ alias Pleroma.FollowingRelationship
alias Pleroma.User
@type criteria ::
@@ -56,7 +58,6 @@ defmodule Pleroma.User.Query do
@ilike_criteria [:nickname, :name, :query]
@equal_criteria [:email]
- @role_criteria [:is_admin, :is_moderator]
@contains_criteria [:ap_id, :nickname]
@spec build(criteria()) :: Query.t()
@@ -100,15 +101,19 @@ defmodule Pleroma.User.Query do
Enum.reduce(tags, query, &prepare_tag_criteria/2)
end
- defp compose_query({key, _}, query) when key in @role_criteria do
- where(query, [u], fragment("(?->? @> 'true')", u.info, ^to_string(key)))
+ defp compose_query({:is_admin, _}, query) do
+ where(query, [u], u.is_admin)
+ end
+
+ defp compose_query({:is_moderator, _}, query) do
+ where(query, [u], u.is_moderator)
end
defp compose_query({:super_users, _}, query) do
where(
query,
[u],
- fragment("?->'is_admin' @> 'true' OR ?->'is_moderator' @> 'true'", u.info, u.info)
+ u.is_admin or u.is_moderator
)
end
@@ -117,7 +122,13 @@ defmodule Pleroma.User.Query do
defp compose_query({:external, _}, query), do: location_query(query, false)
defp compose_query({:active, _}, query) do
- where(query, [u], fragment("not (?->'deactivated' @> 'true')", u.info))
+ User.restrict_deactivated(query)
+ |> where([u], not is_nil(u.nickname))
+ end
+
+ defp compose_query({:legacy_active, _}, query) do
+ query
+ |> where([u], fragment("not (?->'deactivated' @> 'true')", u.info))
|> where([u], not is_nil(u.nickname))
end
@@ -126,22 +137,45 @@ defmodule Pleroma.User.Query do
end
defp compose_query({:deactivated, true}, query) do
- where(query, [u], fragment("?->'deactivated' @> 'true'", u.info))
+ where(query, [u], u.deactivated == ^true)
|> where([u], not is_nil(u.nickname))
end
- defp compose_query({:followers, %User{id: id, follower_address: follower_address}}, query) do
- where(query, [u], fragment("? <@ ?", ^[follower_address], u.following))
+ defp compose_query({:followers, %User{id: id}}, query) do
+ query
|> where([u], u.id != ^id)
+ |> join(:inner, [u], r in FollowingRelationship,
+ as: :relationships,
+ on: r.following_id == ^id and r.follower_id == u.id
+ )
+ |> where([relationships: r], r.state == "accept")
end
- defp compose_query({:friends, %User{id: id, following: following}}, query) do
- where(query, [u], u.follower_address in ^following)
+ defp compose_query({:friends, %User{id: id}}, query) do
+ query
|> where([u], u.id != ^id)
+ |> join(:inner, [u], r in FollowingRelationship,
+ as: :relationships,
+ on: r.following_id == u.id and r.follower_id == ^id
+ )
+ |> where([relationships: r], r.state == "accept")
end
defp compose_query({:recipients_from_activity, to}, query) do
- where(query, [u], u.ap_id in ^to or fragment("? && ?", u.following, ^to))
+ query
+ |> join(:left, [u], r in FollowingRelationship,
+ as: :relationships,
+ on: r.follower_id == u.id
+ )
+ |> join(:left, [relationships: r], f in User,
+ as: :following,
+ on: f.id == r.following_id
+ )
+ |> where(
+ [u, following: f, relationships: r],
+ u.ap_id in ^to or (f.follower_address in ^to and r.state == "accept")
+ )
+ |> distinct(true)
end
defp compose_query({:order_by, key}, query) do
diff --git a/lib/pleroma/user/search.ex b/lib/pleroma/user/search.ex
index 6fb2c2352..09664db76 100644
--- a/lib/pleroma/user/search.ex
+++ b/lib/pleroma/user/search.ex
@@ -4,11 +4,9 @@
defmodule Pleroma.User.Search do
alias Pleroma.Pagination
- alias Pleroma.Repo
alias Pleroma.User
import Ecto.Query
- @similarity_threshold 0.25
@limit 20
def search(query_string, opts \\ []) do
@@ -23,18 +21,10 @@ defmodule Pleroma.User.Search do
maybe_resolve(resolve, for_user, query_string)
- {:ok, results} =
- Repo.transaction(fn ->
- Ecto.Adapters.SQL.query(
- Repo,
- "select set_limit(#{@similarity_threshold})",
- []
- )
-
- query_string
- |> search_query(for_user, following)
- |> Pagination.fetch_paginated(%{"offset" => offset, "limit" => result_limit}, :offset)
- end)
+ results =
+ query_string
+ |> search_query(for_user, following)
+ |> Pagination.fetch_paginated(%{"offset" => offset, "limit" => result_limit}, :offset)
results
end
@@ -56,26 +46,66 @@ defmodule Pleroma.User.Search do
|> base_query(following)
|> filter_blocked_user(for_user)
|> filter_blocked_domains(for_user)
- |> search_subqueries(query_string)
- |> union_subqueries
- |> distinct_query()
- |> boost_search_rank_query(for_user)
+ |> fts_search(query_string)
+ |> trigram_rank(query_string)
+ |> boost_search_rank(for_user)
|> subquery()
|> order_by(desc: :search_rank)
|> maybe_restrict_local(for_user)
end
+ defp fts_search(query, query_string) do
+ query_string = to_tsquery(query_string)
+
+ from(
+ u in query,
+ where:
+ fragment(
+ """
+ (to_tsvector('simple', ?) || to_tsvector('simple', ?)) @@ to_tsquery('simple', ?)
+ """,
+ u.name,
+ u.nickname,
+ ^query_string
+ )
+ )
+ end
+
+ defp to_tsquery(query_string) do
+ String.trim_trailing(query_string, "@" <> local_domain())
+ |> String.replace(~r/[!-\/|@|[-`|{-~|:-?]+/, " ")
+ |> String.trim()
+ |> String.split()
+ |> Enum.map(&(&1 <> ":*"))
+ |> Enum.join(" | ")
+ end
+
+ defp trigram_rank(query, query_string) do
+ from(
+ u in query,
+ select_merge: %{
+ search_rank:
+ fragment(
+ "similarity(?, trim(? || ' ' || coalesce(?, '')))",
+ ^query_string,
+ u.nickname,
+ u.name
+ )
+ }
+ )
+ end
+
defp base_query(_user, false), do: User
defp base_query(user, true), do: User.get_followers_query(user)
- defp filter_blocked_user(query, %User{info: %{blocks: blocks}})
+ defp filter_blocked_user(query, %User{blocks: blocks})
when length(blocks) > 0 do
from(q in query, where: not (q.ap_id in ^blocks))
end
defp filter_blocked_user(query, _), do: query
- defp filter_blocked_domains(query, %User{info: %{domain_blocks: domain_blocks}})
+ defp filter_blocked_domains(query, %User{domain_blocks: domain_blocks})
when length(domain_blocks) > 0 do
domains = Enum.join(domain_blocks, ",")
@@ -87,21 +117,6 @@ defmodule Pleroma.User.Search do
defp filter_blocked_domains(query, _), do: query
- defp union_subqueries({fts_subquery, trigram_subquery}) do
- from(s in trigram_subquery, union_all: ^fts_subquery)
- end
-
- defp search_subqueries(base_query, query_string) do
- {
- fts_search_subquery(base_query, query_string),
- trigram_search_subquery(base_query, query_string)
- }
- end
-
- defp distinct_query(q) do
- from(s in subquery(q), order_by: s.search_type, distinct: s.id)
- end
-
defp maybe_resolve(true, user, query) do
case {limit(), user} do
{:all, _} -> :noop
@@ -126,9 +141,9 @@ defmodule Pleroma.User.Search do
defp restrict_local(q), do: where(q, [u], u.local == true)
- defp boost_search_rank_query(query, nil), do: query
+ defp local_domain, do: Pleroma.Config.get([Pleroma.Web.Endpoint, :url, :host])
- defp boost_search_rank_query(query, for_user) do
+ defp boost_search_rank(query, %User{} = for_user) do
friends_ids = User.get_friends_ids(for_user)
followers_ids = User.get_followers_ids(for_user)
@@ -137,8 +152,8 @@ defmodule Pleroma.User.Search do
search_rank:
fragment(
"""
- CASE WHEN (?) THEN 0.5 + (?) * 1.3
- WHEN (?) THEN 0.5 + (?) * 1.2
+ CASE WHEN (?) THEN (?) * 1.5
+ WHEN (?) THEN (?) * 1.3
WHEN (?) THEN (?) * 1.1
ELSE (?) END
""",
@@ -154,70 +169,5 @@ defmodule Pleroma.User.Search do
)
end
- @spec fts_search_subquery(User.t() | Ecto.Query.t(), String.t()) :: Ecto.Query.t()
- defp fts_search_subquery(query, term) do
- processed_query =
- String.trim_trailing(term, "@" <> local_domain())
- |> String.replace(~r/[!-\/|@|[-`|{-~|:-?]+/, " ")
- |> String.trim()
- |> String.split()
- |> Enum.map(&(&1 <> ":*"))
- |> Enum.join(" | ")
-
- from(
- u in query,
- select_merge: %{
- search_type: ^0,
- search_rank:
- fragment(
- """
- ts_rank_cd(
- setweight(to_tsvector('simple', regexp_replace(?, '\\W', ' ', 'g')), 'A') ||
- setweight(to_tsvector('simple', regexp_replace(coalesce(?, ''), '\\W', ' ', 'g')), 'B'),
- to_tsquery('simple', ?),
- 32
- )
- """,
- u.nickname,
- u.name,
- ^processed_query
- )
- },
- where:
- fragment(
- """
- (setweight(to_tsvector('simple', regexp_replace(?, '\\W', ' ', 'g')), 'A') ||
- setweight(to_tsvector('simple', regexp_replace(coalesce(?, ''), '\\W', ' ', 'g')), 'B')) @@ to_tsquery('simple', ?)
- """,
- u.nickname,
- u.name,
- ^processed_query
- )
- )
- |> User.restrict_deactivated()
- end
-
- @spec trigram_search_subquery(User.t() | Ecto.Query.t(), String.t()) :: Ecto.Query.t()
- defp trigram_search_subquery(query, term) do
- term = String.trim_trailing(term, "@" <> local_domain())
-
- from(
- u in query,
- select_merge: %{
- # ^1 gives 'Postgrex expected a binary, got 1' for some weird reason
- search_type: fragment("?", 1),
- search_rank:
- fragment(
- "similarity(?, trim(? || ' ' || coalesce(?, '')))",
- ^term,
- u.nickname,
- u.name
- )
- },
- where: fragment("trim(? || ' ' || coalesce(?, '')) % ?", u.nickname, u.name, ^term)
- )
- |> User.restrict_deactivated()
- end
-
- defp local_domain, do: Pleroma.Config.get([Pleroma.Web.Endpoint, :url, :host])
+ defp boost_search_rank(query, _for_user), do: query
end