Merge branch 'develop' of https://git.pleroma.social/pleroma/pleroma into develop
[akkoma] / lib / pleroma / web / mastodon_api / controllers / list_controller.ex
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.Web.MastodonAPI.ListController do
6 use Pleroma.Web, :controller
7
8 alias Pleroma.Plugs.OAuthScopesPlug
9 alias Pleroma.User
10 alias Pleroma.Web.MastodonAPI.AccountView
11
12 @oauth_read_actions [:index, :show, :list_accounts]
13
14 plug(Pleroma.Web.ApiSpec.CastAndValidate)
15 plug(:list_by_id_and_user when action not in [:index, :create])
16 plug(OAuthScopesPlug, %{scopes: ["read:lists"]} when action in @oauth_read_actions)
17 plug(OAuthScopesPlug, %{scopes: ["write:lists"]} when action not in @oauth_read_actions)
18
19 action_fallback(Pleroma.Web.MastodonAPI.FallbackController)
20
21 defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.ListOperation
22
23 # GET /api/v1/lists
24 def index(%{assigns: %{user: user}} = conn, opts) do
25 lists = Pleroma.List.for_user(user, opts)
26 render(conn, "index.json", lists: lists)
27 end
28
29 # POST /api/v1/lists
30 def create(%{assigns: %{user: user}, body_params: %{title: title}} = conn, _) do
31 with {:ok, %Pleroma.List{} = list} <- Pleroma.List.create(title, user) do
32 render(conn, "show.json", list: list)
33 end
34 end
35
36 # GET /api/v1/lists/:id
37 def show(%{assigns: %{list: list}} = conn, _) do
38 render(conn, "show.json", list: list)
39 end
40
41 # PUT /api/v1/lists/:id
42 def update(%{assigns: %{list: list}, body_params: %{title: title}} = conn, _) do
43 with {:ok, list} <- Pleroma.List.rename(list, title) do
44 render(conn, "show.json", list: list)
45 end
46 end
47
48 # DELETE /api/v1/lists/:id
49 def delete(%{assigns: %{list: list}} = conn, _) do
50 with {:ok, _list} <- Pleroma.List.delete(list) do
51 json(conn, %{})
52 end
53 end
54
55 # GET /api/v1/lists/:id/accounts
56 def list_accounts(%{assigns: %{user: user, list: list}} = conn, _) do
57 with {:ok, users} <- Pleroma.List.get_following(list) do
58 conn
59 |> put_view(AccountView)
60 |> render("index.json", for: user, users: users, as: :user)
61 end
62 end
63
64 # POST /api/v1/lists/:id/accounts
65 def add_to_list(%{assigns: %{list: list}, body_params: %{account_ids: account_ids}} = conn, _) do
66 Enum.each(account_ids, fn account_id ->
67 with %User{} = followed <- User.get_cached_by_id(account_id) do
68 Pleroma.List.follow(list, followed)
69 end
70 end)
71
72 json(conn, %{})
73 end
74
75 # DELETE /api/v1/lists/:id/accounts
76 def remove_from_list(
77 %{assigns: %{list: list}, body_params: %{account_ids: account_ids}} = conn,
78 _
79 ) do
80 Enum.each(account_ids, fn account_id ->
81 with %User{} = followed <- User.get_cached_by_id(account_id) do
82 Pleroma.List.unfollow(list, followed)
83 end
84 end)
85
86 json(conn, %{})
87 end
88
89 defp list_by_id_and_user(%{assigns: %{user: user}, params: %{id: id}} = conn, _) do
90 case Pleroma.List.get(id, user) do
91 %Pleroma.List{} = list -> assign(conn, :list, list)
92 nil -> conn |> render_error(:not_found, "List not found") |> halt()
93 end
94 end
95 end