Add expires_in param for account mutes
authorRoman Chvanikov <chvanikoff@pm.me>
Tue, 8 Sep 2020 10:26:44 +0000 (13:26 +0300)
committerRoman Chvanikov <chvanikoff@pm.me>
Tue, 8 Sep 2020 10:26:44 +0000 (13:26 +0300)
config/config.exs
lib/pleroma/user.ex
lib/pleroma/web/api_spec/operations/account_operation.ex
lib/pleroma/web/mastodon_api/controllers/account_controller.ex
lib/pleroma/workers/mute_expire_worker.ex [new file with mode: 0644]
test/notification_test.exs
test/user_test.exs
test/web/mastodon_api/controllers/notification_controller_test.exs
test/web/mastodon_api/views/account_view_test.exs

index ed37b93c0712429ea35f2cebf7472ca766a80391..0649f3078ae02ece21f99a01680b3d52cf77d264 100644 (file)
@@ -541,7 +541,8 @@ config :pleroma, Oban,
     background: 5,
     remote_fetcher: 2,
     attachments_cleanup: 5,
-    new_users_digest: 1
+    new_users_digest: 1,
+    mute_expire: 5
   ],
   plugins: [Oban.Plugins.Pruner],
   crontab: [
@@ -672,7 +673,7 @@ config :pleroma, :static_fe, enabled: false
 # With no frontend configuration, the bundled files from the `static` directory will
 # be used.
 #
-# config :pleroma, :frontends, 
+# config :pleroma, :frontends,
 # primary: %{"name" => "pleroma-fe", "ref" => "develop"},
 # admin: %{"name" => "admin-fe", "ref" => "stable"},
 # available: %{...}
index 94c96de8db55dd7274c95aeb9af7e4edc4bc1297..040db8d80c46c941d983e971a7437806ef57966b 100644 (file)
@@ -1356,14 +1356,34 @@ defmodule Pleroma.User do
     |> Repo.all()
   end
 
-  @spec mute(User.t(), User.t(), boolean()) ::
+  @spec mute(User.t(), User.t(), map()) ::
           {:ok, list(UserRelationship.t())} | {:error, String.t()}
-  def mute(%User{} = muter, %User{} = mutee, notifications? \\ true) do
-    add_to_mutes(muter, mutee, notifications?)
+  def mute(%User{} = muter, %User{} = mutee, params \\ %{}) do
+    notifications? = Map.get(params, :notifications, true)
+    expires_in = Map.get(params, :expires_in, 0)
+
+    with {:ok, user_mute} <- UserRelationship.create_mute(muter, mutee),
+         {:ok, user_notification_mute} <-
+           (notifications? && UserRelationship.create_notification_mute(muter, mutee)) ||
+             {:ok, nil} do
+      with seconds when seconds > 0 <- expires_in do
+        Pleroma.Workers.MuteExpireWorker.enqueue(
+          "unmute",
+          %{"muter" => muter.id, "mutee" => mutee.id},
+          schedule_in: expires_in
+        )
+      end
+
+      {:ok, Enum.filter([user_mute, user_notification_mute], & &1)}
+    end
   end
 
   def unmute(%User{} = muter, %User{} = mutee) do
-    remove_from_mutes(muter, mutee)
+    with {:ok, user_mute} <- UserRelationship.delete_mute(muter, mutee),
+         {:ok, user_notification_mute} <-
+           UserRelationship.delete_notification_mute(muter, mutee) do
+      {:ok, [user_mute, user_notification_mute]}
+    end
   end
 
   def subscribe(%User{} = subscriber, %User{} = target) do
@@ -2379,23 +2399,6 @@ defmodule Pleroma.User do
     UserRelationship.delete_block(user, blocked)
   end
 
-  defp add_to_mutes(%User{} = user, %User{} = muted_user, notifications?) do
-    with {:ok, user_mute} <- UserRelationship.create_mute(user, muted_user),
-         {:ok, user_notification_mute} <-
-           (notifications? && UserRelationship.create_notification_mute(user, muted_user)) ||
-             {:ok, nil} do
-      {:ok, Enum.filter([user_mute, user_notification_mute], & &1)}
-    end
-  end
-
-  defp remove_from_mutes(user, %User{} = muted_user) do
-    with {:ok, user_mute} <- UserRelationship.delete_mute(user, muted_user),
-         {:ok, user_notification_mute} <-
-           UserRelationship.delete_notification_mute(user, muted_user) do
-      {:ok, [user_mute, user_notification_mute]}
-    end
-  end
-
   def set_invisible(user, invisible) do
     params = %{invisible: invisible}
 
index aaebc9b5cb72c3e3f991f64eb14c6dc6f16fca41..de715a077605ae86cc18a9b707e39164e3711f95 100644 (file)
@@ -262,6 +262,12 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
           :query,
           %Schema{allOf: [BooleanLike], default: true},
           "Mute notifications in addition to statuses? Defaults to `true`."
+        ),
+        Operation.parameter(
+          :expires_in,
+          :query,
+          %Schema{type: :integer, default: 0},
+          "Expire the mute in `expires_in` seconds. Default 0 for infinity"
         )
       ],
       responses: %{
@@ -718,10 +724,17 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
           nullable: true,
           description: "Mute notifications in addition to statuses? Defaults to true.",
           default: true
+        },
+        expires_in: %Schema{
+          type: :integer,
+          nullable: true,
+          description: "Expire the mute in `expires_in` seconds. Default 0 for infinity",
+          default: 0
         }
       },
       example: %{
-        "notifications" => true
+        "notifications" => true,
+        "expires_in" => 86_400
       }
     }
   end
index 95d8452df0447f08c540d2b5a8cbbb0a7b81958c..ca1a79f5e8d23f3b2e566e66e89cf120cf653237 100644 (file)
@@ -394,7 +394,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
 
   @doc "POST /api/v1/accounts/:id/mute"
   def mute(%{assigns: %{user: muter, account: muted}, body_params: params} = conn, _params) do
-    with {:ok, _user_relationships} <- User.mute(muter, muted, params.notifications) do
+    with {:ok, _user_relationships} <- User.mute(muter, muted, params) do
       render(conn, "relationship.json", user: muter, target: muted)
     else
       {:error, message} -> json_response(conn, :forbidden, %{error: message})
diff --git a/lib/pleroma/workers/mute_expire_worker.ex b/lib/pleroma/workers/mute_expire_worker.ex
new file mode 100644 (file)
index 0000000..b8ec939
--- /dev/null
@@ -0,0 +1,22 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Workers.MuteExpireWorker do
+  use Pleroma.Workers.WorkerHelper, queue: "mute_expire"
+
+  require Logger
+
+  @impl Oban.Worker
+  def perform(%Job{args: %{"op" => "unmute", "muter" => muter_id, "mutee" => mutee_id}}) do
+    muter = Pleroma.User.get_by_id(muter_id)
+    mutee = Pleroma.User.get_by_id(mutee_id)
+    Pleroma.User.unmute(muter, mutee)
+    :ok
+  end
+
+  def perform(any) do
+    Logger.error("Got call to perform(#{inspect(any)})")
+    :ok
+  end
+end
index a09b08675ebed1dee64e0df028960809cc2218e9..ffd737969350e99cc20f7d022ee1f94456a60ea5 100644 (file)
@@ -227,7 +227,7 @@ defmodule Pleroma.NotificationTest do
       muter = insert(:user)
       muted = insert(:user)
 
-      {:ok, _user_relationships} = User.mute(muter, muted, false)
+      {:ok, _user_relationships} = User.mute(muter, muted, %{notifications: false})
 
       {:ok, activity} = CommonAPI.post(muted, %{status: "Hi @#{muter.nickname}"})
 
@@ -1013,7 +1013,7 @@ defmodule Pleroma.NotificationTest do
 
     test "it returns notifications for muted user without notifications", %{user: user} do
       muted = insert(:user)
-      {:ok, _user_relationships} = User.mute(user, muted, false)
+      {:ok, _user_relationships} = User.mute(user, muted, %{notifications: false})
 
       {:ok, _activity} = CommonAPI.post(muted, %{status: "hey @#{user.nickname}"})
 
index 50f72549eeab1a61a683d479b27f20f185f3ed3a..b23e36be311fac73c17b4b5d3a5ff7809a5c40cc 100644 (file)
@@ -981,7 +981,7 @@ defmodule Pleroma.UserTest do
       refute User.mutes?(user, muted_user)
       refute User.muted_notifications?(user, muted_user)
 
-      {:ok, _user_relationships} = User.mute(user, muted_user, false)
+      {:ok, _user_relationships} = User.mute(user, muted_user, %{notifications: false})
 
       assert User.mutes?(user, muted_user)
       refute User.muted_notifications?(user, muted_user)
index 70ef0e8b5012aa9a15f7fe1fab7fc39015f325f7..5fd518c602c6e1e8ae626175238b4c20eb21589f 100644 (file)
@@ -502,7 +502,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do
 
     assert length(json_response_and_validate_schema(ret_conn, 200)) == 1
 
-    {:ok, _user_relationships} = User.mute(user, user2, false)
+    {:ok, _user_relationships} = User.mute(user, user2, %{notifications: false})
 
     conn = get(conn, "/api/v1/notifications")
 
index 8f37efa3c3e2b8df5fa13bfa7955ac5f898fbb3c..c34cbcfc146bb0c68038d4d5ce630eeee3daf31a 100644 (file)
@@ -277,7 +277,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
       {:ok, user} = User.follow(user, other_user)
       {:ok, other_user} = User.follow(other_user, user)
       {:ok, _subscription} = User.subscribe(user, other_user)
-      {:ok, _user_relationships} = User.mute(user, other_user, true)
+      {:ok, _user_relationships} = User.mute(user, other_user, %{notifications: true})
       {:ok, _reblog_mute} = CommonAPI.hide_reblogs(user, other_user)
 
       expected =