X-Git-Url: https://git.squeep.com/?a=blobdiff_plain;f=lib%2Fpleroma%2Fweb%2Fmastodon_api%2Fsearch_controller.ex;h=9072aa7a47c1a3702b8ae46b45cfd676be57d30a;hb=45e21a9df4a7b58d28624534fdde3dc9e31c6813;hp=939f7f6cb36990515cb0fcebfd2d11b46943764c;hpb=008c55e4e995f33f9fd2188568a92f135d235222;p=akkoma diff --git a/lib/pleroma/web/mastodon_api/search_controller.ex b/lib/pleroma/web/mastodon_api/search_controller.ex index 939f7f6cb..9072aa7a4 100644 --- a/lib/pleroma/web/mastodon_api/search_controller.ex +++ b/lib/pleroma/web/mastodon_api/search_controller.ex @@ -7,6 +7,7 @@ defmodule Pleroma.Web.MastodonAPI.SearchController do alias Pleroma.Activity alias Pleroma.Plugs.RateLimiter + alias Pleroma.Repo alias Pleroma.User alias Pleroma.Web alias Pleroma.Web.ControllerHelper @@ -16,43 +17,6 @@ defmodule Pleroma.Web.MastodonAPI.SearchController do require Logger plug(RateLimiter, :search when action in [:search, :search2, :account_search]) - def search2(%{assigns: %{user: user}} = conn, %{"q" => query} = params) do - accounts = with_fallback(fn -> User.search(query, search_options(params, user)) end, []) - statuses = with_fallback(fn -> Activity.search(user, query) end, []) - - tags_path = Web.base_url() <> "/tag/" - - tags = - query - |> prepare_tags - |> Enum.map(fn tag -> %{name: tag, url: tags_path <> tag} end) - - res = %{ - "accounts" => AccountView.render("accounts.json", users: accounts, for: user, as: :user), - "statuses" => - StatusView.render("index.json", activities: statuses, for: user, as: :activity), - "hashtags" => tags - } - - json(conn, res) - end - - def search(%{assigns: %{user: user}} = conn, %{"q" => query} = params) do - accounts = with_fallback(fn -> User.search(query, search_options(params, user)) end) - statuses = with_fallback(fn -> Activity.search(user, query) end) - - tags = prepare_tags(query) - - res = %{ - "accounts" => AccountView.render("accounts.json", users: accounts, for: user, as: :user), - "statuses" => - StatusView.render("index.json", activities: statuses, for: user, as: :activity), - "hashtags" => tags - } - - json(conn, res) - end - def account_search(%{assigns: %{user: user}} = conn, %{"q" => query} = params) do accounts = User.search(query, search_options(params, user)) res = AccountView.render("accounts.json", users: accounts, for: user, as: :user) @@ -60,12 +24,36 @@ defmodule Pleroma.Web.MastodonAPI.SearchController do json(conn, res) end - defp prepare_tags(query) do - query - |> String.split() - |> Enum.uniq() - |> Enum.filter(fn tag -> String.starts_with?(tag, "#") end) - |> Enum.map(fn tag -> String.slice(tag, 1..-1) end) + def search2(conn, params), do: do_search(:v2, conn, params) + def search(conn, params), do: do_search(:v1, conn, params) + + defp do_search(version, %{assigns: %{user: user}} = conn, %{"q" => query} = params) do + options = search_options(params, user) + timeout = Keyword.get(Repo.config(), :timeout, 15_000) + default_values = %{"statuses" => [], "accounts" => [], "hashtags" => []} + + result = + default_values + |> Enum.map(fn {resource, default_value} -> + if params["type"] == nil or params["type"] == resource do + {resource, fn -> resource_search(version, resource, query, options) end} + else + {resource, fn -> default_value end} + end + end) + |> Task.async_stream(fn {resource, f} -> {resource, with_fallback(f)} end, + timeout: timeout, + on_timeout: :kill_task + ) + |> Enum.reduce(default_values, fn + {:ok, {resource, result}}, acc -> + Map.put(acc, resource, result) + + _error, acc -> + acc + end) + + json(conn, result) end defp search_options(params, user) do @@ -74,8 +62,45 @@ defmodule Pleroma.Web.MastodonAPI.SearchController do following: params["following"] == "true", limit: ControllerHelper.fetch_integer_param(params, "limit"), offset: ControllerHelper.fetch_integer_param(params, "offset"), + type: params["type"], + author: get_author(params), for_user: user ] + |> Enum.filter(&elem(&1, 1)) + end + + defp resource_search(_, "accounts", query, options) do + accounts = with_fallback(fn -> User.search(query, options) end) + AccountView.render("accounts.json", users: accounts, for: options[:for_user], as: :user) + end + + defp resource_search(_, "statuses", query, options) do + statuses = with_fallback(fn -> Activity.search(options[:for_user], query, options) end) + StatusView.render("index.json", activities: statuses, for: options[:for_user], as: :activity) + end + + defp resource_search(:v2, "hashtags", query, _options) do + tags_path = Web.base_url() <> "/tag/" + + query + |> prepare_tags() + |> Enum.map(fn tag -> + tag = String.trim_leading(tag, "#") + %{name: tag, url: tags_path <> tag} + end) + end + + defp resource_search(:v1, "hashtags", query, _options) do + query + |> prepare_tags() + |> Enum.map(fn tag -> String.trim_leading(tag, "#") end) + end + + defp prepare_tags(query) do + query + |> String.split() + |> Enum.uniq() + |> Enum.filter(fn tag -> String.starts_with?(tag, "#") end) end defp with_fallback(f, fallback \\ []) do @@ -87,4 +112,9 @@ defmodule Pleroma.Web.MastodonAPI.SearchController do fallback end end + + defp get_author(%{"account_id" => account_id}) when is_binary(account_id), + do: User.get_cached_by_id(account_id) + + defp get_author(_params), do: nil end