Merge branch 'formatting-fixes' into 'develop'
[akkoma] / lib / pleroma / web / mastodon_api / mastodon_api_controller.ex
index 83003b917ae5f6b2fb05a9fb9f3c0285c72b7c21..e1256c7b642f637176e0d83dafcf5e628c031a0e 100644 (file)
@@ -24,6 +24,57 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
     end
   end
 
+  def update_credentials(%{assigns: %{user: user}} = conn, params) do
+    params = if bio = params["note"] do
+      Map.put(params, "bio", bio)
+    else
+      params
+    end
+
+    params = if name = params["display_name"] do
+      Map.put(params, "name", name)
+    else
+      params
+    end
+
+    user = if avatar = params["avatar"] do
+      with %Plug.Upload{} <- avatar,
+           {:ok, object} <- ActivityPub.upload(avatar),
+           change = Ecto.Changeset.change(user, %{avatar: object.data}),
+           {:ok, user} = Repo.update(change) do
+        user
+      else
+        _e -> user
+      end
+    else
+      user
+    end
+
+    user = if banner = params["header"] do
+      with %Plug.Upload{} <- banner,
+           {:ok, object} <- ActivityPub.upload(banner),
+           new_info <- Map.put(user.info, "banner", object.data),
+           change <- User.info_changeset(user, %{info: new_info}),
+           {:ok, user} <- Repo.update(change) do
+        user
+      else
+        _e -> user
+      end
+    else
+      user
+    end
+
+    with changeset <- User.update_changeset(user, params),
+         {:ok, user} <- Repo.update(changeset) do
+      json conn, AccountView.render("account.json", %{user: user})
+    else
+      _e ->
+        conn
+        |> put_status(403)
+        |> json(%{error: "Invalid request"})
+    end
+  end
+
   def verify_credentials(%{assigns: %{user: user}} = conn, params) do
     account = AccountView.render("account.json", %{user: user})
     json(conn, account)
@@ -62,8 +113,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
     json(conn, response)
   end
 
-  def custom_emojis(conn, _params) do
-    mastodon_emoji = Pleroma.Formatter.get_custom_emoji()
+  defp mastodonized_emoji do
+    Pleroma.Formatter.get_custom_emoji()
     |> Enum.map(fn {shortcode, relative_url} ->
       url = to_string URI.merge(Web.base_url(), relative_url)
       %{
@@ -72,6 +123,10 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
         "url" => url
       }
     end)
+  end
+
+  def custom_emojis(conn, _params) do
+    mastodon_emoji = mastodonized_emoji()
     json conn, mastodon_emoji
   end
 
@@ -172,9 +227,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
   end
 
   def reblog_status(%{assigns: %{user: user}} = conn, %{"id" => ap_id_or_id}) do
-    with {:ok, _announce, %{data: %{"id" => id}}} = CommonAPI.repeat(ap_id_or_id, user),
-         %Activity{} = activity <- Activity.get_create_activity_by_object_ap_id(id) do
-      render conn, StatusView, "status.json", %{activity: activity, for: user, as: :activity}
+    with {:ok, announce, _activity} = CommonAPI.repeat(ap_id_or_id, user) do
+      render conn, StatusView, "status.json", %{activity: announce, for: user, as: :activity}
     end
   end
 
@@ -194,23 +248,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
 
   def notifications(%{assigns: %{user: user}} = conn, params) do
     notifications = Notification.for_user(user, params)
-    result = Enum.map(notifications, fn (%{id: id, activity: activity, inserted_at: created_at}) ->
-      actor = User.get_cached_by_ap_id(activity.data["actor"])
-      created_at = NaiveDateTime.to_iso8601(created_at)
-      |> String.replace(~r/(\.\d+)?$/, ".000Z", global: false)
-      case activity.data["type"] do
-        "Create" ->
-          %{id: id, type: "mention", created_at: created_at, account: AccountView.render("account.json", %{user: actor}), status: StatusView.render("status.json", %{activity: activity, for: user})}
-        "Like" ->
-          liked_activity = Activity.get_create_activity_by_object_ap_id(activity.data["object"])
-          %{id: id, type: "favourite", created_at: created_at, account: AccountView.render("account.json", %{user: actor}), status: StatusView.render("status.json", %{activity: liked_activity, for: user})}
-        "Announce" ->
-          announced_activity = Activity.get_create_activity_by_object_ap_id(activity.data["object"])
-          %{id: id, type: "reblog", created_at: created_at, account: AccountView.render("account.json", %{user: actor}), status: StatusView.render("status.json", %{activity: announced_activity, for: user})}
-        "Follow" ->
-          %{id: id, type: "follow", created_at: created_at, account: AccountView.render("account.json", %{user: actor})}
-        _ -> nil
-      end
+    result = Enum.map(notifications, fn x ->
+      render_notification(user, x)
     end)
     |> Enum.filter(&(&1))
 
@@ -219,6 +258,33 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
     |> json(result)
   end
 
+  def get_notification(%{assigns: %{user: user}} = conn, %{"id" => id} = _params) do
+    with {:ok, notification} <- Notification.get(user, id) do
+      json(conn, render_notification(user, notification))
+    else
+      {:error, reason} ->
+        conn
+        |> put_resp_content_type("application/json")
+        |> send_resp(403, Poison.encode!(%{"error" => reason}))
+    end
+  end
+
+  def clear_notifications(%{assigns: %{user: user}} = conn, _params) do
+    Notification.clear(user)
+    json(conn, %{})
+  end
+
+  def dismiss_notification(%{assigns: %{user: user}} = conn, %{"id" => id} = _params) do
+    with {:ok, _notif} <- Notification.dismiss(user, id) do
+      json(conn, %{})
+    else
+      {:error, reason} ->
+        conn
+        |> put_resp_content_type("application/json")
+        |> send_resp(403, Poison.encode!(%{"error" => reason}))
+    end
+  end
+
   def relationships(%{assigns: %{user: user}} = conn, %{"id" => id}) do
     id = List.wrap(id)
     q = from u in User,
@@ -411,6 +477,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
     |> get_session(:oauth_token)
 
     if user && token do
+      mastodon_emoji = mastodonized_emoji()
       accounts = Map.put(%{}, user.id, AccountView.render("account.json", %{user: user}))
       initial_state = %{
         meta: %{
@@ -478,7 +545,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
         },
         push_subscription: nil,
         accounts: accounts,
-        custom_emojis: %{}
+        custom_emojis: mastodon_emoji
       } |> Poison.encode!
       conn
       |> put_layout(false)
@@ -512,7 +579,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
          {:ok, token} <- Token.exchange_token(app, auth) do
       conn
       |> put_session(:oauth_token, token.token)
-      |> redirect(to: "/web/timelines/public")
+      |> redirect(to: "/web/getting-started")
     end
   end
 
@@ -527,4 +594,23 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
     Logger.debug("Unimplemented, returning an empty array")
     json(conn, [])
   end
+
+  def render_notification(user, %{id: id, activity: activity, inserted_at: created_at} = _params) do
+    actor = User.get_cached_by_ap_id(activity.data["actor"])
+    created_at = NaiveDateTime.to_iso8601(created_at)
+    |> String.replace(~r/(\.\d+)?$/, ".000Z", global: false)
+    case activity.data["type"] do
+      "Create" ->
+        %{id: id, type: "mention", created_at: created_at, account: AccountView.render("account.json", %{user: actor}), status: StatusView.render("status.json", %{activity: activity, for: user})}
+      "Like" ->
+        liked_activity = Activity.get_create_activity_by_object_ap_id(activity.data["object"])
+        %{id: id, type: "favourite", created_at: created_at, account: AccountView.render("account.json", %{user: actor}), status: StatusView.render("status.json", %{activity: liked_activity, for: user})}
+      "Announce" ->
+        announced_activity = Activity.get_create_activity_by_object_ap_id(activity.data["object"])
+        %{id: id, type: "reblog", created_at: created_at, account: AccountView.render("account.json", %{user: actor}), status: StatusView.render("status.json", %{activity: announced_activity, for: user})}
+      "Follow" ->
+        %{id: id, type: "follow", created_at: created_at, account: AccountView.render("account.json", %{user: actor})}
+      _ -> nil
+    end
+  end
 end