move to 2.5.5
[anni] / lib / pleroma / web / mastodon_api / mastodon_api.ex
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
5 defmodule Pleroma.Web.MastodonAPI.MastodonAPI do
6   import Ecto.Query
7   import Ecto.Changeset
8
9   alias Pleroma.Notification
10   alias Pleroma.Pagination
11   alias Pleroma.ScheduledActivity
12   alias Pleroma.User
13   alias Pleroma.Web.CommonAPI
14
15   @spec follow(User.t(), User.t(), map) :: {:ok, User.t()} | {:error, String.t()}
16   def follow(follower, followed, params \\ %{}) do
17     result =
18       if not User.following?(follower, followed) do
19         CommonAPI.follow(follower, followed)
20       else
21         {:ok, follower, followed, nil}
22       end
23
24     with {:ok, follower, _followed, _} <- result do
25       options = cast_params(params)
26       set_reblogs_visibility(options[:reblogs], result)
27       set_subscription(options[:notify], result)
28       {:ok, follower}
29     end
30   end
31
32   defp set_reblogs_visibility(false, {:ok, follower, followed, _}) do
33     CommonAPI.hide_reblogs(follower, followed)
34   end
35
36   defp set_reblogs_visibility(_, {:ok, follower, followed, _}) do
37     CommonAPI.show_reblogs(follower, followed)
38   end
39
40   defp set_subscription(true, {:ok, follower, followed, _}) do
41     User.subscribe(follower, followed)
42   end
43
44   defp set_subscription(false, {:ok, follower, followed, _}) do
45     User.unsubscribe(follower, followed)
46   end
47
48   defp set_subscription(_, _), do: {:ok, nil}
49
50   @spec get_followers(User.t(), map()) :: list(User.t())
51   def get_followers(user, params \\ %{}) do
52     user
53     |> User.get_followers_query()
54     |> Pagination.fetch_paginated(params)
55   end
56
57   def get_friends(user, params \\ %{}) do
58     user
59     |> User.get_friends_query()
60     |> Pagination.fetch_paginated(params)
61   end
62
63   def get_notifications(user, params \\ %{}) do
64     options =
65       cast_params(params) |> Map.update(:include_types, [], fn include_types -> include_types end)
66
67     options =
68       if ("pleroma:report" not in options.include_types and
69             User.privileged?(user, :reports_manage_reports)) or
70            User.privileged?(user, :reports_manage_reports) do
71         options
72       else
73         options
74         |> Map.update(:exclude_types, ["pleroma:report"], fn current_exclude_types ->
75           current_exclude_types ++ ["pleroma:report"]
76         end)
77       end
78
79     user
80     |> Notification.for_user_query(options)
81     |> restrict(:types, options)
82     |> restrict(:exclude_types, options)
83     |> restrict(:account_ap_id, options)
84     |> Pagination.fetch_paginated(params)
85   end
86
87   def get_scheduled_activities(user, params \\ %{}) do
88     user
89     |> ScheduledActivity.for_user_query()
90     |> Pagination.fetch_paginated(params)
91   end
92
93   defp cast_params(params) do
94     param_types = %{
95       exclude_types: {:array, :string},
96       types: {:array, :string},
97       exclude_visibilities: {:array, :string},
98       reblogs: :boolean,
99       with_muted: :boolean,
100       account_ap_id: :string,
101       notify: :boolean
102     }
103
104     changeset = cast({%{}, param_types}, params, Map.keys(param_types))
105     changeset.changes
106   end
107
108   defp restrict(query, :types, %{types: mastodon_types = [_ | _]}) do
109     where(query, [n], n.type in ^mastodon_types)
110   end
111
112   defp restrict(query, :exclude_types, %{exclude_types: mastodon_types = [_ | _]}) do
113     where(query, [n], n.type not in ^mastodon_types)
114   end
115
116   defp restrict(query, :account_ap_id, %{account_ap_id: account_ap_id}) do
117     where(query, [n, a], a.actor == ^account_ap_id)
118   end
119
120   defp restrict(query, _, _), do: query
121 end