Support the 'following' option on post searches

This commit is contained in:
itepechi 2023-09-27 05:18:27 +09:00
parent 49eda427fd
commit 66e26882e8
6 changed files with 53 additions and 8 deletions

View file

@ -867,9 +867,10 @@
config :pleroma, Pleroma.Search, config :pleroma, Pleroma.Search,
module: Pleroma.Search.DatabaseSearch, module: Pleroma.Search.DatabaseSearch,
extensions: %{ extensions: %{
# this features is placed in the ':extensions' section for clarity # these features are placed in the ':extensions' section for clarity
# as this is not in the upstream, at least not yet # as they are not in the upstream, at least not yet
search_type_media: true search_type_media: true,
search_option_following: true
} }
config :pleroma, Pleroma.Search.Meilisearch, config :pleroma, Pleroma.Search.Meilisearch,

View file

@ -37,6 +37,10 @@ def by_author(query \\ Activity, %User{ap_id: ap_id}) do
from(a in query, where: a.actor == ^ap_id) from(a in query, where: a.actor == ^ap_id)
end end
def by_authors(query \\ Activity, actors) do
from(activity in query, where: activity.actor in ^actors)
end
def find_by_object_ap_id(activities, object_ap_id) do def find_by_object_ap_id(activities, object_ap_id) do
Enum.find( Enum.find(
activities, activities,

View file

@ -23,9 +23,13 @@ def search(user, search_query, options \\ []) do
true -> :gin true -> :gin
end end
can_search_following =
Pleroma.Config.get([Pleroma.Search, :extensions, :search_option_following], true)
limit = Enum.min([Keyword.get(options, :limit), 40]) limit = Enum.min([Keyword.get(options, :limit), 40])
offset = Keyword.get(options, :offset, 0) offset = Keyword.get(options, :offset, 0)
author = Keyword.get(options, :author) author = Keyword.get(options, :author)
following = can_search_following && Keyword.get(options, :following, false)
only_media = Keyword.get(options, :only_media, false) only_media = Keyword.get(options, :only_media, false)
search_function = search_function =
@ -44,6 +48,7 @@ def search(user, search_query, options \\ []) do
|> maybe_restrict_local(user) |> maybe_restrict_local(user)
|> maybe_restrict_author(author) |> maybe_restrict_author(author)
|> maybe_restrict_blocked(user) |> maybe_restrict_blocked(user)
|> maybe_restrict_following(user, following)
|> maybe_restrict_media(only_media) |> maybe_restrict_media(only_media)
|> Pagination.fetch_paginated( |> Pagination.fetch_paginated(
%{"offset" => offset, "limit" => limit, "skip_order" => index_type == :rum}, %{"offset" => offset, "limit" => limit, "skip_order" => index_type == :rum},
@ -67,6 +72,12 @@ def maybe_restrict_author(query, %User{} = author) do
def maybe_restrict_author(query, _), do: query def maybe_restrict_author(query, _), do: query
def maybe_restrict_following(query, %User{} = user, true) do
Activity.Queries.by_authors(query, User.following_ap_ids(user))
end
def maybe_restrict_following(query, _, _), do: query
def maybe_restrict_blocked(query, %User{} = user) do def maybe_restrict_blocked(query, %User{} = user) do
Activity.Queries.exclude_authors(query, User.blocked_users_ap_ids(user)) Activity.Queries.exclude_authors(query, User.blocked_users_ap_ids(user))
end end

View file

@ -2,6 +2,12 @@
# Copyright © 2022-2022 Akkoma Authors <https://git.ihatebeinga.live/IHBAGang/akkoma/> # Copyright © 2022-2022 Akkoma Authors <https://git.ihatebeinga.live/IHBAGang/akkoma/>
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
# NOTE: Elasticsearch has never been and will never be well supported.
# If you are experiencing strange behaviour such as posts being shuffled or
# missing, or the limit option not being respected, this module is the cause.
# If this bothers you, I recommend switching to database search or Meilisearch.
# Using Elasticsearch with non-humongous web services might be overkill anyway.
defmodule Pleroma.Search.Elasticsearch do defmodule Pleroma.Search.Elasticsearch do
@behaviour Pleroma.Search.SearchBackend @behaviour Pleroma.Search.SearchBackend
@ -9,6 +15,7 @@ defmodule Pleroma.Search.Elasticsearch do
alias Pleroma.Object.Fetcher alias Pleroma.Object.Fetcher
alias Pleroma.Web.ActivityPub.Visibility alias Pleroma.Web.ActivityPub.Visibility
alias Pleroma.Search.Elasticsearch.Parsers alias Pleroma.Search.Elasticsearch.Parsers
alias Pleroma.User
def es_query(:activity, query, offset, limit) do def es_query(:activity, query, offset, limit) do
must = Parsers.Activity.parse(query) must = Parsers.Activity.parse(query)
@ -41,8 +48,12 @@ defp maybe_fetch(:activity, search_query) do
end end
def search(user, query, options) do def search(user, query, options) do
can_search_following =
Pleroma.Config.get([Pleroma.Search, :extensions, :search_option_following], true)
limit = Enum.min([Keyword.get(options, :limit), 40]) limit = Enum.min([Keyword.get(options, :limit), 40])
offset = Keyword.get(options, :offset, 0) offset = Keyword.get(options, :offset, 0)
following = can_search_following && Keyword.get(options, :following, false)
only_media = Keyword.get(options, :only_media, false) only_media = Keyword.get(options, :only_media, false)
parsed_query = parsed_query =
@ -62,11 +73,21 @@ def search(user, query, options) do
:activities :activities
|> Pleroma.Search.Elasticsearch.Store.search(q) |> Pleroma.Search.Elasticsearch.Store.search(q)
|> Enum.filter(fn x -> |> Enum.filter(fn x ->
x.data["type"] == "Create" && x.object.data["type"] == "Note" && Enum.all?([
Visibility.visible_for_user?(x, user) && x.data["type"] == "Create",
# i'm not going to implement this very seriously because the support for x.object.data["type"] == "Note",
# elasticsearch is already kinda broken Visibility.visible_for_user?(x, user),
if only_media, do: length(x.object.data["attachment"]) > 0, else: true if only_media do
length(x.object.data["attachment"]) > 0
else
true
end,
if following do
Enum.member?(User.following_ap_ids(user), x.object.data["actor"])
else
true
end
])
end) end)
end) end)

View file

@ -76,9 +76,13 @@ def meili_delete!(path) do
end end
def search(user, query, options \\ []) do def search(user, query, options \\ []) do
can_search_following =
Pleroma.Config.get([Pleroma.Search, :extensions, :search_option_following], true)
limit = Enum.min([Keyword.get(options, :limit), 40]) limit = Enum.min([Keyword.get(options, :limit), 40])
offset = Keyword.get(options, :offset, 0) offset = Keyword.get(options, :offset, 0)
author = Keyword.get(options, :author) author = Keyword.get(options, :author)
following = can_search_following && Keyword.get(options, :following, false)
only_media = Keyword.get(options, :only_media, false) only_media = Keyword.get(options, :only_media, false)
res = res =
@ -98,6 +102,7 @@ def search(user, query, options \\ []) do
|> maybe_restrict_local(user) |> maybe_restrict_local(user)
|> maybe_restrict_author(author) |> maybe_restrict_author(author)
|> maybe_restrict_blocked(user) |> maybe_restrict_blocked(user)
|> maybe_restrict_following(user, following)
|> maybe_restrict_media(only_media) |> maybe_restrict_media(only_media)
|> maybe_fetch(user, query) |> maybe_fetch(user, query)
|> order_by([object: obj], desc: obj.data["published"]) |> order_by([object: obj], desc: obj.data["published"])

View file

@ -92,6 +92,9 @@ def features do
if Config.get([Pleroma.Search, :extensions, :search_type_media], true) do if Config.get([Pleroma.Search, :extensions, :search_type_media], true) do
"bnakkoma:search_type_media" "bnakkoma:search_type_media"
end, end,
if Config.get([Pleroma.Search, :extensions, :search_option_following], true) do
"bnakkoma:search_option_following"
end,
"custom_emoji_reactions", "custom_emoji_reactions",
"pleroma:get:main/ostatus" "pleroma:get:main/ostatus"
] ]