From b0f83aea29be0b25075d19b35d5ff98ef8fbd000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?marcin=20miko=C5=82ajczak?= Date: Thu, 16 Jun 2022 18:12:30 +0200 Subject: [PATCH 1/3] Store mutes expiration date MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: marcin mikołajczak --- lib/pleroma/user.ex | 19 +++++++-- lib/pleroma/user_relationship.ex | 39 ++++++++++++++----- lib/pleroma/web/api_spec/schemas/account.ex | 1 + .../controllers/account_controller.ex | 3 +- .../web/mastodon_api/views/account_view.ex | 11 ++++++ ...3_add_expires_at_to_user_relationships.exs | 13 +++++++ 6 files changed, 73 insertions(+), 13 deletions(-) create mode 100644 priv/repo/migrations/20220616163503_add_expires_at_to_user_relationships.exs diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 747a83e8d..88837b91a 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -1461,15 +1461,28 @@ defmodule Pleroma.User do notifications? = Map.get(params, :notifications, true) expires_in = Map.get(params, :expires_in, 0) - with {:ok, user_mute} <- UserRelationship.create_mute(muter, mutee), + expires_at = + if expires_in > 0 do + NaiveDateTime.utc_now() + |> NaiveDateTime.add(expires_in) + else + nil + end + + with {:ok, user_mute} <- UserRelationship.create_mute(muter, mutee, expires_at), {:ok, user_notification_mute} <- - (notifications? && UserRelationship.create_notification_mute(muter, mutee)) || + (notifications? && + UserRelationship.create_notification_mute( + muter, + mutee, + expires_at + )) || {:ok, nil} do if expires_in > 0 do Pleroma.Workers.MuteExpireWorker.enqueue( "unmute_user", %{"muter_id" => muter.id, "mutee_id" => mutee.id}, - schedule_in: expires_in + scheduled_at: expires_at ) end diff --git a/lib/pleroma/user_relationship.ex b/lib/pleroma/user_relationship.ex index 1432a1d83..f35f3ac63 100644 --- a/lib/pleroma/user_relationship.ex +++ b/lib/pleroma/user_relationship.ex @@ -18,16 +18,17 @@ defmodule Pleroma.UserRelationship do belongs_to(:source, User, type: FlakeId.Ecto.CompatType) belongs_to(:target, User, type: FlakeId.Ecto.CompatType) field(:relationship_type, Pleroma.UserRelationship.Type) + field(:expires_at, :naive_datetime) timestamps(updated_at: false) end for relationship_type <- Keyword.keys(Pleroma.UserRelationship.Type.__enum_map__()) do - # `def create_block/2`, `def create_mute/2`, `def create_reblog_mute/2`, - # `def create_notification_mute/2`, `def create_inverse_subscription/2`, - # `def endorsement/2` - def unquote(:"create_#{relationship_type}")(source, target), - do: create(unquote(relationship_type), source, target) + # `def create_block/3`, `def create_mute/3`, `def create_reblog_mute/3`, + # `def create_notification_mute/3`, `def create_inverse_subscription/3`, + # `def endorsement/3` + def unquote(:"create_#{relationship_type}")(source, target, expires_at \\ nil), + do: create(unquote(relationship_type), source, target, expires_at) # `def delete_block/2`, `def delete_mute/2`, `def delete_reblog_mute/2`, # `def delete_notification_mute/2`, `def delete_inverse_subscription/2`, @@ -37,9 +38,15 @@ defmodule Pleroma.UserRelationship do # `def block_exists?/2`, `def mute_exists?/2`, `def reblog_mute_exists?/2`, # `def notification_mute_exists?/2`, `def inverse_subscription_exists?/2`, - # `def inverse_endorsement?/2` + # `def inverse_endorsement_exists?/2` def unquote(:"#{relationship_type}_exists?")(source, target), do: exists?(unquote(relationship_type), source, target) + + # `def get_block_expire_date/2`, `def get_mute_expire_date/2`, + # `def get_reblog_mute_expire_date/2`, `def get_notification_mute_exists?/2`, + # `def get_inverse_subscription_expire_date/2`, `def get_inverse_endorsement_expire_date/2` + def unquote(:"get_#{relationship_type}_expire_date")(source, target), + do: get_expire_date(unquote(relationship_type), source, target) end def user_relationship_types, do: Keyword.keys(user_relationship_mappings()) @@ -48,7 +55,7 @@ defmodule Pleroma.UserRelationship do def changeset(%UserRelationship{} = user_relationship, params \\ %{}) do user_relationship - |> cast(params, [:relationship_type, :source_id, :target_id]) + |> cast(params, [:relationship_type, :source_id, :target_id, :expires_at]) |> validate_required([:relationship_type, :source_id, :target_id]) |> unique_constraint(:relationship_type, name: :user_relationships_source_id_relationship_type_target_id_index @@ -62,12 +69,26 @@ defmodule Pleroma.UserRelationship do |> Repo.exists?() end - def create(relationship_type, %User{} = source, %User{} = target) do + def get_expire_date(relationship_type, %User{} = source, %User{} = target) do + %UserRelationship{expires_at: expires_at} = + UserRelationship + |> where( + relationship_type: ^relationship_type, + source_id: ^source.id, + target_id: ^target.id + ) + |> Repo.one!() + + expires_at + end + + def create(relationship_type, %User{} = source, %User{} = target, expires_at \\ nil) do %UserRelationship{} |> changeset(%{ relationship_type: relationship_type, source_id: source.id, - target_id: target.id + target_id: target.id, + expires_at: expires_at }) |> Repo.insert( on_conflict: {:replace_all_except, [:id]}, diff --git a/lib/pleroma/web/api_spec/schemas/account.ex b/lib/pleroma/web/api_spec/schemas/account.ex index e8a529f2e..8aeb821a8 100644 --- a/lib/pleroma/web/api_spec/schemas/account.ex +++ b/lib/pleroma/web/api_spec/schemas/account.ex @@ -33,6 +33,7 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Account do header: %Schema{type: :string, format: :uri}, id: FlakeID, locked: %Schema{type: :boolean}, + mute_expires_at: %Schema{type: :string, format: "date-time", nullable: true}, note: %Schema{type: :string, format: :html}, statuses_count: %Schema{type: :integer}, url: %Schema{type: :string, format: :uri}, diff --git a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex index 50c12a1b1..eb59a0a96 100644 --- a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex @@ -499,7 +499,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do users: users, for: user, as: :user, - embed_relationships: embed_relationships?(params) + embed_relationships: embed_relationships?(params), + mutes: true ) end diff --git a/lib/pleroma/web/mastodon_api/views/account_view.ex b/lib/pleroma/web/mastodon_api/views/account_view.ex index 988eedbb1..2260bf5da 100644 --- a/lib/pleroma/web/mastodon_api/views/account_view.ex +++ b/lib/pleroma/web/mastodon_api/views/account_view.ex @@ -311,6 +311,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do |> maybe_put_unread_conversation_count(user, opts[:for]) |> maybe_put_unread_notification_count(user, opts[:for]) |> maybe_put_email_address(user, opts[:for]) + |> maybe_put_mute_expires_at(user, opts[:for], opts) |> maybe_show_birthday(user, opts[:for]) end @@ -434,6 +435,16 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do defp maybe_put_email_address(data, _, _), do: data + defp maybe_put_mute_expires_at(data, %User{} = user, target, %{mutes: true}) do + Map.put( + data, + :mute_expires_at, + UserRelationship.get_mute_expire_date(target, user) + ) + end + + defp maybe_put_mute_expires_at(data, _, _, _), do: data + defp maybe_show_birthday(data, %User{id: user_id} = user, %User{id: user_id}) do data |> Kernel.put_in([:pleroma, :birthday], user.birthday) diff --git a/priv/repo/migrations/20220616163503_add_expires_at_to_user_relationships.exs b/priv/repo/migrations/20220616163503_add_expires_at_to_user_relationships.exs new file mode 100644 index 000000000..c0594d647 --- /dev/null +++ b/priv/repo/migrations/20220616163503_add_expires_at_to_user_relationships.exs @@ -0,0 +1,13 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2022 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Repo.Migrations.AddExpiresAtToUserRelationships do + use Ecto.Migration + + def change do + alter table(:user_relationships) do + add_if_not_exists(:expires_at, :naive_datetime) + end + end +end From 0b16ce79f91c0f7c99cf11567e29b1adb139ff35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?marcin=20miko=C5=82ajczak?= Date: Fri, 8 Jul 2022 20:54:12 +0200 Subject: [PATCH 2/3] Add test for rendering mute expiration date MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: marcin mikołajczak --- .../mastodon_api/views/account_view_test.exs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/test/pleroma/web/mastodon_api/views/account_view_test.exs b/test/pleroma/web/mastodon_api/views/account_view_test.exs index 8ed37fe58..cc45ce4e9 100644 --- a/test/pleroma/web/mastodon_api/views/account_view_test.exs +++ b/test/pleroma/web/mastodon_api/views/account_view_test.exs @@ -634,4 +634,21 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do |> assert() end end + + test "renders mute expiration date" do + user = insert(:user) + other_user = insert(:user) + + {:ok, _user_relationships} = + User.mute(user, other_user, %{notifications: true, expires_in: 24 * 60 * 60}) + + %{ + mute_expires_at: mute_expires_at + } = AccountView.render("show.json", %{user: other_user, for: user, mutes: true}) + + assert NaiveDateTime.diff( + mute_expires_at, + NaiveDateTime.utc_now() |> NaiveDateTime.add(24 * 60 * 60) + ) in -3..3 + end end From 597f56b4c4db3c63ff66fc93717d3b20655e1543 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?marcin=20miko=C5=82ajczak?= Date: Sat, 16 Jul 2022 16:09:47 +0200 Subject: [PATCH 3/3] Use :utc_datetime MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: marcin mikołajczak --- lib/pleroma/user.ex | 4 ++-- lib/pleroma/user_relationship.ex | 2 +- .../20220616163503_add_expires_at_to_user_relationships.exs | 2 +- test/pleroma/web/mastodon_api/views/account_view_test.exs | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 88837b91a..44754879a 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -1463,8 +1463,8 @@ defmodule Pleroma.User do expires_at = if expires_in > 0 do - NaiveDateTime.utc_now() - |> NaiveDateTime.add(expires_in) + DateTime.utc_now() + |> DateTime.add(expires_in) else nil end diff --git a/lib/pleroma/user_relationship.ex b/lib/pleroma/user_relationship.ex index f35f3ac63..5b3e593d3 100644 --- a/lib/pleroma/user_relationship.ex +++ b/lib/pleroma/user_relationship.ex @@ -18,7 +18,7 @@ defmodule Pleroma.UserRelationship do belongs_to(:source, User, type: FlakeId.Ecto.CompatType) belongs_to(:target, User, type: FlakeId.Ecto.CompatType) field(:relationship_type, Pleroma.UserRelationship.Type) - field(:expires_at, :naive_datetime) + field(:expires_at, :utc_datetime) timestamps(updated_at: false) end diff --git a/priv/repo/migrations/20220616163503_add_expires_at_to_user_relationships.exs b/priv/repo/migrations/20220616163503_add_expires_at_to_user_relationships.exs index c0594d647..9e117e376 100644 --- a/priv/repo/migrations/20220616163503_add_expires_at_to_user_relationships.exs +++ b/priv/repo/migrations/20220616163503_add_expires_at_to_user_relationships.exs @@ -7,7 +7,7 @@ defmodule Pleroma.Repo.Migrations.AddExpiresAtToUserRelationships do def change do alter table(:user_relationships) do - add_if_not_exists(:expires_at, :naive_datetime) + add_if_not_exists(:expires_at, :utc_datetime) end end end diff --git a/test/pleroma/web/mastodon_api/views/account_view_test.exs b/test/pleroma/web/mastodon_api/views/account_view_test.exs index cc45ce4e9..8fa946d43 100644 --- a/test/pleroma/web/mastodon_api/views/account_view_test.exs +++ b/test/pleroma/web/mastodon_api/views/account_view_test.exs @@ -646,9 +646,9 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do mute_expires_at: mute_expires_at } = AccountView.render("show.json", %{user: other_user, for: user, mutes: true}) - assert NaiveDateTime.diff( + assert DateTime.diff( mute_expires_at, - NaiveDateTime.utc_now() |> NaiveDateTime.add(24 * 60 * 60) + DateTime.utc_now() |> DateTime.add(24 * 60 * 60) ) in -3..3 end end