Add ability to set a default post expiry (#321)
[akkoma] / lib / pleroma / web / mastodon_api / controllers / status_controller.ex
index d9b93ca5e8fb56ec74c13e068c426b8728b48960..338a35052ae9fb7331daea2a97d9d6326ff3d76f 100644 (file)
@@ -40,7 +40,9 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
            :index,
            :show,
            :context,
-           :translate
+           :translate,
+           :show_history,
+           :show_source
          ]
   )
 
@@ -51,7 +53,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
            :create,
            :delete,
            :reblog,
-           :unreblog
+           :unreblog,
+           :update
          ]
   )
 
@@ -168,6 +171,16 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
       Map.put(params, :in_reply_to_status_id, params[:in_reply_to_id])
       |> put_application(conn)
 
+    expires_in_seconds =
+      if is_nil(user.status_ttl_days),
+        do: nil,
+        else: 60 * 60 * 24 * user.status_ttl_days
+
+    params =
+      if is_nil(expires_in_seconds),
+        do: params,
+        else: Map.put(params, :expires_in, expires_in_seconds)
+
     with {:ok, activity} <- CommonAPI.post(user, params) do
       try_render(conn, "show.json",
         activity: activity,
@@ -193,6 +206,59 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
     create(%Plug.Conn{conn | body_params: params}, %{})
   end
 
+  @doc "GET /api/v1/statuses/:id/history"
+  def show_history(%{assigns: assigns} = conn, %{id: id} = params) do
+    with user = assigns[:user],
+         %Activity{} = activity <- Activity.get_by_id_with_object(id),
+         true <- Visibility.visible_for_user?(activity, user) do
+      try_render(conn, "history.json",
+        activity: activity,
+        for: user,
+        with_direct_conversation_id: true,
+        with_muted: Map.get(params, :with_muted, false)
+      )
+    else
+      _ -> {:error, :not_found}
+    end
+  end
+
+  @doc "GET /api/v1/statuses/:id/source"
+  def show_source(%{assigns: assigns} = conn, %{id: id} = _params) do
+    with user = assigns[:user],
+         %Activity{} = activity <- Activity.get_by_id_with_object(id),
+         true <- Visibility.visible_for_user?(activity, user) do
+      try_render(conn, "source.json",
+        activity: activity,
+        for: user
+      )
+    else
+      _ -> {:error, :not_found}
+    end
+  end
+
+  @doc "PUT /api/v1/statuses/:id"
+  def update(%{assigns: %{user: user}, body_params: body_params} = conn, %{id: id} = params) do
+    with {_, %Activity{}} = {_, activity} <- {:activity, Activity.get_by_id_with_object(id)},
+         {_, true} <- {:visible, Visibility.visible_for_user?(activity, user)},
+         {_, true} <- {:is_create, activity.data["type"] == "Create"},
+         actor <- Activity.user_actor(activity),
+         {_, true} <- {:own_status, actor.id == user.id},
+         changes <- body_params |> put_application(conn),
+         {_, {:ok, _update_activity}} <- {:pipeline, CommonAPI.update(user, activity, changes)},
+         {_, %Activity{}} = {_, activity} <- {:refetched, Activity.get_by_id_with_object(id)} do
+      try_render(conn, "show.json",
+        activity: activity,
+        for: user,
+        with_direct_conversation_id: true,
+        with_muted: Map.get(params, :with_muted, false)
+      )
+    else
+      {:own_status, _} -> {:error, :forbidden}
+      {:pipeline, _} -> {:error, :internal_server_error}
+      _ -> {:error, :not_found}
+    end
+  end
+
   @doc "GET /api/v1/statuses/:id"
   def show(%{assigns: %{user: user}} = conn, %{id: id} = params) do
     with %Activity{} = activity <- Activity.get_by_id_with_object(id),
@@ -422,7 +488,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
   end
 
   @doc "GET /api/v1/statuses/:id/translations/:language"
-  def translate(%{assigns: %{user: user}} = conn, %{id: id, language: language}) do
+  def translate(%{assigns: %{user: user}} = conn, %{id: id, language: language} = params) do
     with {:enabled, true} <- {:enabled, Config.get([:translator, :enabled])},
          %Activity{} = activity <- Activity.get_by_id_with_object(id),
          {:visible, true} <- {:visible, Visibility.visible_for_user?(activity, user)},
@@ -431,6 +497,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
            fetch_or_translate(
              activity.id,
              activity.object.data["content"],
+             Map.get(params, :from, nil),
              language,
              translation_module
            ) do
@@ -449,16 +516,20 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
     end
   end
 
-  defp fetch_or_translate(status_id, text, language, translation_module) do
-    @cachex.fetch!(:user_cache, "translations:#{status_id}:#{language}", fn _ ->
-      value = translation_module.translate(text, language)
-
-      with {:ok, _, _} <- value do
-        value
-      else
-        _ -> {:ignore, value}
+  defp fetch_or_translate(status_id, text, source_language, target_language, translation_module) do
+    @cachex.fetch!(
+      :translations_cache,
+      "translations:#{status_id}:#{source_language}:#{target_language}",
+      fn _ ->
+        value = translation_module.translate(text, source_language, target_language)
+
+        with {:ok, _, _} <- value do
+          value
+        else
+          _ -> {:ignore, value}
+        end
       end
-    end)
+    )
   end
 
   defp put_application(params, %{assigns: %{token: %Token{user: %User{} = user} = token}} = _conn) do