field(:last_active_at, :naive_datetime)
field(:disclose_client, :boolean, default: true)
field(:pinned_objects, :map, default: %{})
+ field(:is_suggested, :boolean, default: false)
embeds_one(
:notification_settings,
where(query, [u], u.is_confirmed == false)
end
+ defp compose_query({:is_suggested, bool}, query) do
+ where(query, [u], u.is_suggested == ^bool)
+ end
+
defp compose_query({:followers, %User{id: id}}, query) do
query
|> where([u], u.id != ^id)
defmodule Pleroma.Web.MastodonAPI.SuggestionController do
use Pleroma.Web, :controller
+ alias Pleroma.User
require Logger
def index2_operation do
%OpenApiSpex.Operation{
tags: ["Suggestions"],
- summary: "Follow suggestions (Not implemented)",
+ summary: "Follow suggestions",
operationId: "SuggestionController.index2",
responses: %{
200 => Pleroma.Web.ApiSpec.Helpers.empty_array_response()
do: Pleroma.Web.MastodonAPI.MastodonAPIController.empty_array(conn, params)
@doc "GET /api/v2/suggestions"
- def index2(conn, params),
- do: Pleroma.Web.MastodonAPI.MastodonAPIController.empty_array(conn, params)
+ def index2(conn, params) do
+ limit = Map.get(params, :limit, 40) |> min(80)
+
+ users =
+ %{is_suggested: true, limit: limit}
+ |> User.Query.build()
+ |> Pleroma.Repo.all()
+
+ render(conn, "index.json", %{users: users, source: :staff, skip_visibility_check: true})
+ end
end
--- /dev/null
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.MastodonAPI.SuggestionView do
+ use Pleroma.Web, :view
+ alias Pleroma.Web.MastodonAPI.AccountView
+
+ @source_types [:staff, :global, :past_interactions]
+
+ def render("index.json", %{users: users} = opts) do
+ Enum.map(users, fn user ->
+ opts =
+ opts
+ |> Map.put(:user, user)
+ |> Map.delete(:users)
+
+ render("show.json", opts)
+ end)
+ end
+
+ def render("show.json", %{source: source, user: _user} = opts) when source in @source_types do
+ %{
+ source: source,
+ account: AccountView.render("show.json", opts)
+ }
+ end
+end
--- /dev/null
+defmodule Pleroma.Repo.Migrations.AddSuggestions do
+ use Ecto.Migration
+
+ def change do
+ alter table(:users) do
+ add(:is_suggested, :boolean, default: false, null: false)
+ end
+ end
+end
assert %{internal: true} |> Query.build() |> Repo.aggregate(:count) == 2
end
end
+
+ test "is_suggested param" do
+ _user1 = insert(:user, is_suggested: false)
+ user2 = insert(:user, is_suggested: true)
+
+ assert [^user2] =
+ %{is_suggested: true}
+ |> User.Query.build()
+ |> Repo.all()
+ end
end
defmodule Pleroma.Web.MastodonAPI.SuggestionControllerTest do
use Pleroma.Web.ConnCase, async: true
+ import Pleroma.Factory
setup do: oauth_access(["read"])
assert res == []
end
- test "returns empty result (v2)", %{conn: conn} do
+ test "returns v2 suggestions", %{conn: conn} do
+ %{id: user_id} = insert(:user, is_suggested: true)
+
res =
conn
|> get("/api/v2/suggestions")
|> json_response_and_validate_schema(200)
- assert res == []
+ assert [%{"source" => "staff", "account" => %{"id" => ^user_id}}] = res
end
end
--- /dev/null
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.MastodonAPI.SuggestionViewTest do
+ use Pleroma.DataCase, async: true
+ import Pleroma.Factory
+ alias Pleroma.Web.MastodonAPI.SuggestionView, as: View
+
+ test "show.json" do
+ user = insert(:user, is_suggested: true)
+ json = View.render("show.json", %{user: user, source: :staff, skip_visibility_check: true})
+
+ assert json.source == :staff
+ assert json.account.id == user.id
+ end
+
+ test "index.json" do
+ user1 = insert(:user, is_suggested: true)
+ user2 = insert(:user, is_suggested: true)
+ user3 = insert(:user, is_suggested: true)
+
+ [suggestion1, suggestion2, suggestion3] =
+ View.render("index.json", %{
+ users: [user1, user2, user3],
+ source: :staff,
+ skip_visibility_check: true
+ })
+
+ assert suggestion1.source == :staff
+ assert suggestion2.account.id == user2.id
+ assert suggestion3.account.url == user3.ap_id
+ end
+end