Implement media-only support for status search

w/ some refactors and updates
This commit is contained in:
itepechi 2023-09-16 07:08:07 +09:00
parent c5000d67a6
commit ea932d1e20
6 changed files with 37 additions and 6 deletions

View File

@ -26,6 +26,7 @@ defmodule Pleroma.Search.DatabaseSearch do
limit = Enum.min([Keyword.get(options, :limit), 40])
offset = Keyword.get(options, :offset, 0)
author = Keyword.get(options, :author)
only_media = Keyword.get(options, :only_media, false)
search_function =
if :persistent_term.get({Pleroma.Repo, :postgres_version}) >= 11 do
@ -43,6 +44,7 @@ defmodule Pleroma.Search.DatabaseSearch do
|> maybe_restrict_local(user)
|> maybe_restrict_author(author)
|> maybe_restrict_blocked(user)
|> maybe_only_media(only_media)
|> Pagination.fetch_paginated(
%{"offset" => offset, "limit" => limit, "skip_order" => index_type == :rum},
:offset
@ -173,4 +175,12 @@ defmodule Pleroma.Search.DatabaseSearch do
_ -> activities
end
end
def maybe_only_media(q, true) do
from([a, o] in q,
where: fragment("not (?)->'attachment' = (?)", o.data, ^[])
)
end
def maybe_only_media(q, _), do: q
end

View File

@ -43,6 +43,7 @@ defmodule Pleroma.Search.Elasticsearch do
def search(user, query, options) do
limit = Enum.min([Keyword.get(options, :limit), 40])
offset = Keyword.get(options, :offset, 0)
only_media = Keyword.get(options, :only_media, false)
parsed_query =
query
@ -62,7 +63,10 @@ defmodule Pleroma.Search.Elasticsearch do
|> 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)
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
end)
end)

View File

@ -32,7 +32,7 @@ defmodule Pleroma.Search.Elasticsearch.Store do
{:ok, results}
else
{:error, e} ->
Logger.error(e)
Logger.error("Unable to search with Elasiticsearch: #{inspect(e)}")
{:error, e}
end
end
@ -44,7 +44,7 @@ defmodule Pleroma.Search.Elasticsearch.Store do
|> Pleroma.Activity.all_by_ids_with_object()
else
e ->
Logger.error(e)
Logger.error("Unable to search with Elasiticsearch: #{inspect(e)}")
[]
end
end

View File

@ -79,6 +79,7 @@ defmodule Pleroma.Search.Meilisearch do
limit = Enum.min([Keyword.get(options, :limit), 40])
offset = Keyword.get(options, :offset, 0)
author = Keyword.get(options, :author)
only_media = Keyword.get(options, :only_media, false)
res =
meili_post(
@ -93,11 +94,11 @@ defmodule Pleroma.Search.Meilisearch do
hits
|> Activity.create_by_object_ap_id()
|> Activity.with_preloaded_object()
|> Activity.with_preloaded_object()
|> Activity.restrict_deactivated_users()
|> maybe_restrict_local(user)
|> maybe_restrict_author(author)
|> maybe_restrict_blocked(user)
|> maybe_only_media(only_media)
|> maybe_fetch(user, query)
|> order_by([object: obj], desc: obj.data["published"])
|> Pleroma.Repo.all()

View File

@ -75,7 +75,7 @@ defmodule Pleroma.Web.ApiSpec.SearchOperation do
Operation.parameter(
:type,
:query,
%Schema{type: :string, enum: ["accounts", "hashtags", "statuses"]},
%Schema{type: :string, enum: ["accounts", "hashtags", "statuses", "media"]},
"Search type"
),
Operation.parameter(:q, :query, %Schema{type: :string}, "What to search for",

View File

@ -47,7 +47,7 @@ defmodule Pleroma.Web.MastodonAPI.SearchController do
query = String.trim(query)
options = search_options(params, user)
timeout = Keyword.get(Repo.config(), :timeout, 15_000)
default_values = %{"statuses" => [], "accounts" => [], "hashtags" => []}
default_values = %{"statuses" => [], "media" => [], "accounts" => [], "hashtags" => []}
result =
default_values
@ -107,6 +107,22 @@ defmodule Pleroma.Web.MastodonAPI.SearchController do
)
end
defp resource_search(_, "media", query, options) do
statuses =
with_fallback(fn ->
Pleroma.Search.search(
query,
Keyword.put(options, :only_media, true)
)
end)
StatusView.render("index.json",
activities: statuses,
for: options[:for_user],
as: :activity
)
end
defp resource_search(:v2, "hashtags", query, options) do
tags_path = Endpoint.url() <> "/tag/"