logo

pleroma

My custom branche(s) on git.pleroma.social/pleroma/pleroma git clone https://hacktivis.me/git/pleroma.git

suggestion_controller.ex (3613B)


  1. # Pleroma: A lightweight social networking server
  2. # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
  3. # SPDX-License-Identifier: AGPL-3.0-only
  4. defmodule Pleroma.Web.MastodonAPI.SuggestionController do
  5. use Pleroma.Web, :controller
  6. import Ecto.Query
  7. alias Pleroma.FollowingRelationship
  8. alias Pleroma.User
  9. alias Pleroma.UserRelationship
  10. require Logger
  11. plug(Pleroma.Web.ApiSpec.CastAndValidate)
  12. plug(Pleroma.Web.Plugs.OAuthScopesPlug, %{scopes: ["read"]} when action in [:index, :index2])
  13. plug(Pleroma.Web.Plugs.OAuthScopesPlug, %{scopes: ["write"]} when action in [:dismiss])
  14. def open_api_operation(action) do
  15. operation = String.to_existing_atom("#{action}_operation")
  16. apply(__MODULE__, operation, [])
  17. end
  18. def index_operation do
  19. %OpenApiSpex.Operation{
  20. tags: ["Suggestions"],
  21. summary: "Follow suggestions (Not implemented)",
  22. operationId: "SuggestionController.index",
  23. responses: %{
  24. 200 => Pleroma.Web.ApiSpec.Helpers.empty_array_response()
  25. }
  26. }
  27. end
  28. def index2_operation do
  29. %OpenApiSpex.Operation{
  30. tags: ["Suggestions"],
  31. summary: "Follow suggestions",
  32. operationId: "SuggestionController.index2",
  33. responses: %{
  34. 200 => Pleroma.Web.ApiSpec.Helpers.empty_array_response()
  35. }
  36. }
  37. end
  38. def dismiss_operation do
  39. %OpenApiSpex.Operation{
  40. tags: ["Suggestions"],
  41. summary: "Remove a suggestion",
  42. operationId: "SuggestionController.dismiss",
  43. parameters: [
  44. OpenApiSpex.Operation.parameter(
  45. :account_id,
  46. :path,
  47. %OpenApiSpex.Schema{type: :string},
  48. "Account to dismiss",
  49. required: true
  50. )
  51. ],
  52. responses: %{
  53. 200 => Pleroma.Web.ApiSpec.Helpers.empty_object_response()
  54. }
  55. }
  56. end
  57. @doc "GET /api/v1/suggestions"
  58. def index(conn, params),
  59. do: Pleroma.Web.MastodonAPI.MastodonAPIController.empty_array(conn, params)
  60. @doc "GET /api/v2/suggestions"
  61. def index2(%{assigns: %{user: user}} = conn, params) do
  62. limit = Map.get(params, :limit, 40) |> min(80)
  63. users =
  64. %{is_suggested: true, invisible: false, limit: limit}
  65. |> User.Query.build()
  66. |> exclude_user(user)
  67. |> exclude_relationships(user, [:block, :mute, :suggestion_dismiss])
  68. |> exclude_following(user)
  69. |> Pleroma.Repo.all()
  70. render(conn, "index.json", %{
  71. users: users,
  72. source: :staff,
  73. for: user,
  74. skip_visibility_check: true
  75. })
  76. end
  77. defp exclude_user(query, %User{id: user_id}) do
  78. where(query, [u], u.id != ^user_id)
  79. end
  80. defp exclude_relationships(query, %User{id: user_id}, relationship_types) do
  81. query
  82. |> join(:left, [u], r in UserRelationship,
  83. as: :user_relationships,
  84. on:
  85. r.target_id == u.id and r.source_id == ^user_id and
  86. r.relationship_type in ^relationship_types
  87. )
  88. |> where([user_relationships: r], is_nil(r.target_id))
  89. end
  90. defp exclude_following(query, %User{id: user_id}) do
  91. query
  92. |> join(:left, [u], r in FollowingRelationship,
  93. as: :following_relationships,
  94. on: r.following_id == u.id and r.follower_id == ^user_id and r.state == :follow_accept
  95. )
  96. |> where([following_relationships: r], is_nil(r.following_id))
  97. end
  98. @doc "DELETE /api/v1/suggestions/:account_id"
  99. def dismiss(%{assigns: %{user: source}} = conn, %{account_id: user_id}) do
  100. with %User{} = target <- User.get_cached_by_id(user_id),
  101. {:ok, _} <- UserRelationship.create(:suggestion_dismiss, source, target) do
  102. json(conn, %{})
  103. end
  104. end
  105. end