diff options
| author | dcc <dcc@logografos.com> | 2023-09-02 00:52:52 -0700 |
|---|---|---|
| committer | dcc <dcc@logografos.com> | 2023-09-02 00:52:52 -0700 |
| commit | 3a4773c3c2bd0bbef244eb519b07208da9108e49 (patch) | |
| tree | 973567a6f3abb37bfb0f785b1cad14ed55840ef5 /lib/pleroma/web/mastodon_api/controllers/suggestion_controller.ex | |
| download | anni-3a4773c3c2bd0bbef244eb519b07208da9108e49.tar.gz anni-3a4773c3c2bd0bbef244eb519b07208da9108e49.tar.bz2 anni-3a4773c3c2bd0bbef244eb519b07208da9108e49.zip | |
First
Diffstat (limited to 'lib/pleroma/web/mastodon_api/controllers/suggestion_controller.ex')
| -rw-r--r-- | lib/pleroma/web/mastodon_api/controllers/suggestion_controller.ex | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/lib/pleroma/web/mastodon_api/controllers/suggestion_controller.ex b/lib/pleroma/web/mastodon_api/controllers/suggestion_controller.ex new file mode 100644 index 0000000..69ae70a --- /dev/null +++ b/lib/pleroma/web/mastodon_api/controllers/suggestion_controller.ex @@ -0,0 +1,120 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.MastodonAPI.SuggestionController do + use Pleroma.Web, :controller + import Ecto.Query + alias Pleroma.FollowingRelationship + alias Pleroma.User + alias Pleroma.UserRelationship + + require Logger + + plug(Pleroma.Web.ApiSpec.CastAndValidate) + plug(Pleroma.Web.Plugs.OAuthScopesPlug, %{scopes: ["read"]} when action in [:index, :index2]) + plug(Pleroma.Web.Plugs.OAuthScopesPlug, %{scopes: ["write"]} when action in [:dismiss]) + + def open_api_operation(action) do + operation = String.to_existing_atom("#{action}_operation") + apply(__MODULE__, operation, []) + end + + def index_operation do + %OpenApiSpex.Operation{ + tags: ["Suggestions"], + summary: "Follow suggestions (Not implemented)", + operationId: "SuggestionController.index", + responses: %{ + 200 => Pleroma.Web.ApiSpec.Helpers.empty_array_response() + } + } + end + + def index2_operation do + %OpenApiSpex.Operation{ + tags: ["Suggestions"], + summary: "Follow suggestions", + operationId: "SuggestionController.index2", + responses: %{ + 200 => Pleroma.Web.ApiSpec.Helpers.empty_array_response() + } + } + end + + def dismiss_operation do + %OpenApiSpex.Operation{ + tags: ["Suggestions"], + summary: "Remove a suggestion", + operationId: "SuggestionController.dismiss", + parameters: [ + OpenApiSpex.Operation.parameter( + :account_id, + :path, + %OpenApiSpex.Schema{type: :string}, + "Account to dismiss", + required: true + ) + ], + responses: %{ + 200 => Pleroma.Web.ApiSpec.Helpers.empty_object_response() + } + } + end + + @doc "GET /api/v1/suggestions" + def index(conn, params), + do: Pleroma.Web.MastodonAPI.MastodonAPIController.empty_array(conn, params) + + @doc "GET /api/v2/suggestions" + def index2(%{assigns: %{user: user}} = conn, params) do + limit = Map.get(params, :limit, 40) |> min(80) + + users = + %{is_suggested: true, invisible: false, limit: limit} + |> User.Query.build() + |> exclude_user(user) + |> exclude_relationships(user, [:block, :mute, :suggestion_dismiss]) + |> exclude_following(user) + |> Pleroma.Repo.all() + + render(conn, "index.json", %{ + users: users, + source: :staff, + for: user, + skip_visibility_check: true + }) + end + + defp exclude_user(query, %User{id: user_id}) do + where(query, [u], u.id != ^user_id) + end + + defp exclude_relationships(query, %User{id: user_id}, relationship_types) do + query + |> join(:left, [u], r in UserRelationship, + as: :user_relationships, + on: + r.target_id == u.id and r.source_id == ^user_id and + r.relationship_type in ^relationship_types + ) + |> where([user_relationships: r], is_nil(r.target_id)) + end + + defp exclude_following(query, %User{id: user_id}) do + query + |> join(:left, [u], r in FollowingRelationship, + as: :following_relationships, + on: r.following_id == u.id and r.follower_id == ^user_id and r.state == :follow_accept + ) + |> where([following_relationships: r], is_nil(r.following_id)) + end + + @doc "DELETE /api/v1/suggestions/:account_id" + def dismiss(%{assigns: %{user: source}} = conn, %{account_id: user_id}) do + with %User{} = target <- User.get_cached_by_id(user_id), + {:ok, _} <- UserRelationship.create(:suggestion_dismiss, source, target) do + json(conn, %{}) + end + end +end |
