1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
5 defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
6 use Pleroma.Web, :controller
8 import Pleroma.Web.ControllerHelper, only: [add_link_headers: 2]
10 alias Pleroma.Bookmark
12 alias Pleroma.Pagination
15 alias Pleroma.Web.ActivityPub.ActivityPub
16 alias Pleroma.Web.CommonAPI
17 alias Pleroma.Web.MastodonAPI.AccountView
18 alias Pleroma.Web.MastodonAPI.MastodonView
19 alias Pleroma.Web.MastodonAPI.StatusView
23 action_fallback(Pleroma.Web.MastodonAPI.FallbackController)
25 defp mastodonized_emoji do
26 Pleroma.Emoji.get_all()
27 |> Enum.map(fn {shortcode, %Pleroma.Emoji{file: relative_url, tags: tags}} ->
28 url = to_string(URI.merge(Web.base_url(), relative_url))
31 "shortcode" => shortcode,
33 "visible_in_picker" => true,
36 # Assuming that a comma is authorized in the category name
37 "category" => (tags -- ["Custom"]) |> Enum.join(",")
42 def custom_emojis(conn, _params) do
43 mastodon_emoji = mastodonized_emoji()
44 json(conn, mastodon_emoji)
47 def follows(%{assigns: %{user: follower}} = conn, %{"uri" => uri}) do
48 with {_, %User{} = followed} <- {:followed, User.get_cached_by_nickname(uri)},
49 {_, true} <- {:followed, follower.id != followed.id},
50 {:ok, follower, followed, _} <- CommonAPI.follow(follower, followed) do
52 |> put_view(AccountView)
53 |> render("show.json", %{user: followed, for: follower})
60 |> put_status(:forbidden)
61 |> json(%{error: message})
65 def mutes(%{assigns: %{user: user}} = conn, _) do
66 with muted_accounts <- User.muted_users(user) do
67 res = AccountView.render("index.json", users: muted_accounts, for: user, as: :user)
72 def blocks(%{assigns: %{user: user}} = conn, _) do
73 with blocked_accounts <- User.blocked_users(user) do
74 res = AccountView.render("index.json", users: blocked_accounts, for: user, as: :user)
79 def favourites(%{assigns: %{user: user}} = conn, params) do
82 |> Map.put("type", "Create")
83 |> Map.put("favorited_by", user.ap_id)
84 |> Map.put("blocking_user", user)
87 ActivityPub.fetch_activities([], params)
91 |> add_link_headers(activities)
92 |> put_view(StatusView)
93 |> render("index.json", %{activities: activities, for: user, as: :activity})
96 def bookmarks(%{assigns: %{user: user}} = conn, params) do
97 user = User.get_cached_by_id(user.id)
100 Bookmark.for_user_query(user.id)
101 |> Pagination.fetch_paginated(params)
105 |> Enum.map(fn b -> Map.put(b.activity, :bookmark, Map.delete(b, :activity)) end)
108 |> add_link_headers(bookmarks)
109 |> put_view(StatusView)
110 |> render("index.json", %{activities: activities, for: user, as: :activity})
113 def index(%{assigns: %{user: user}} = conn, _params) do
114 token = get_session(conn, :oauth_token)
117 mastodon_emoji = mastodonized_emoji()
119 limit = Config.get([:instance, :limit])
121 accounts = Map.put(%{}, user.id, AccountView.render("show.json", %{user: user, for: user}))
126 streaming_api_base_url: Pleroma.Web.Endpoint.websocket_url(),
129 domain: Pleroma.Web.Endpoint.host(),
132 unfollow_modal: false,
135 auto_play_gif: false,
136 display_sensitive_media: false,
137 reduce_motion: false,
138 max_toot_chars: limit,
139 mascot: User.get_mascot(user)["url"]
141 poll_limits: Config.get([:instance, :poll_limits]),
143 delete_others_notice: present?(user.info.is_moderator),
144 admin: present?(user.info.is_admin)
148 default_privacy: user.info.default_scope,
149 default_sensitive: false,
150 allow_content_types: Config.get([:instance, :allowed_post_formats])
152 media_attachments: %{
153 accept_content_types: [
169 user.info.settings ||
199 push_subscription: nil,
201 custom_emojis: mastodon_emoji,
208 |> put_view(MastodonView)
209 |> render("index.html", %{initial_state: initial_state})
212 |> put_session(:return_to, conn.request_path)
213 |> redirect(to: "/web/login")
217 def put_settings(%{assigns: %{user: user}} = conn, %{"data" => settings} = _params) do
218 with {:ok, _} <- User.update_info(user, &User.Info.mastodon_settings_update(&1, settings)) do
223 |> put_status(:internal_server_error)
224 |> json(%{error: inspect(e)})
228 # Stubs for unimplemented mastodon api
230 def empty_array(conn, _) do
231 Logger.debug("Unimplemented, returning an empty array")
235 def empty_object(conn, _) do
236 Logger.debug("Unimplemented, returning an empty object")
240 defp present?(nil), do: false
241 defp present?(false), do: false
242 defp present?(_), do: true