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.Web.WebFinger, domain: nil, update_nickname_on_user_fet
config :pleroma, Pleroma.Search,
module: Pleroma.Search.DatabaseSearch,
extensions: %{
# this features is placed in the ':extensions' section for clarity
# as this is not in the upstream, at least not yet
search_type_media: true
# these features are placed in the ':extensions' section for clarity
# as they are not in the upstream, at least not yet
search_type_media: true,
search_option_following: true
}
config :pleroma, Pleroma.Search.Meilisearch,

View File

@ -37,6 +37,10 @@ defmodule Pleroma.Activity.Queries do
from(a in query, where: a.actor == ^ap_id)
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
Enum.find(
activities,

View File

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

View File

@ -2,6 +2,12 @@
# Copyright © 2022-2022 Akkoma Authors <https://git.ihatebeinga.live/IHBAGang/akkoma/>
# 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
@behaviour Pleroma.Search.SearchBackend
@ -9,6 +15,7 @@ defmodule Pleroma.Search.Elasticsearch do
alias Pleroma.Object.Fetcher
alias Pleroma.Web.ActivityPub.Visibility
alias Pleroma.Search.Elasticsearch.Parsers
alias Pleroma.User
def es_query(:activity, query, offset, limit) do
must = Parsers.Activity.parse(query)
@ -41,8 +48,12 @@ defmodule Pleroma.Search.Elasticsearch do
end
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])
offset = Keyword.get(options, :offset, 0)
following = can_search_following && Keyword.get(options, :following, false)
only_media = Keyword.get(options, :only_media, false)
parsed_query =
@ -62,11 +73,21 @@ defmodule Pleroma.Search.Elasticsearch do
:activities
|> Pleroma.Search.Elasticsearch.Store.search(q)
|> Enum.filter(fn x ->
x.data["type"] == "Create" && x.object.data["type"] == "Note" &&
Visibility.visible_for_user?(x, user) &&
# i'm not going to implement this very seriously because the support for
# elasticsearch is already kinda broken
if only_media, do: length(x.object.data["attachment"]) > 0, else: true
Enum.all?([
x.data["type"] == "Create",
x.object.data["type"] == "Note",
Visibility.visible_for_user?(x, user),
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)

View File

@ -76,9 +76,13 @@ defmodule Pleroma.Search.Meilisearch do
end
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])
offset = Keyword.get(options, :offset, 0)
author = Keyword.get(options, :author)
following = can_search_following && Keyword.get(options, :following, false)
only_media = Keyword.get(options, :only_media, false)
res =
@ -98,6 +102,7 @@ defmodule Pleroma.Search.Meilisearch do
|> maybe_restrict_local(user)
|> maybe_restrict_author(author)
|> maybe_restrict_blocked(user)
|> maybe_restrict_following(user, following)
|> maybe_restrict_media(only_media)
|> maybe_fetch(user, query)
|> order_by([object: obj], desc: obj.data["published"])

View File

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