Remove duplicated entries in users' following lists
This commit is contained in:
parent
0f8892686a
commit
2c303afc8b
|
@ -12,6 +12,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
- Support for Mastodon's remote interaction
|
||||
- Mix Tasks: `mix pleroma.database bump_all_conversations`
|
||||
- Mix Tasks: `mix pleroma.database remove_embedded_objects`
|
||||
- Mix Tasks: `mix pleroma.database update_users_following_followers_counts`
|
||||
- Mix Tasks: `mix pleroma.user toggle_confirmed`
|
||||
- Federation: Support for reports
|
||||
- Configuration: `safe_dm_mentions` option
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
defmodule Mix.Tasks.Pleroma.Database do
|
||||
alias Mix.Tasks.Pleroma.Common
|
||||
alias Pleroma.Conversation
|
||||
alias Pleroma.Repo
|
||||
alias Pleroma.User
|
||||
require Logger
|
||||
use Mix.Task
|
||||
|
||||
|
@ -25,6 +27,9 @@ defmodule Mix.Tasks.Pleroma.Database do
|
|||
|
||||
mix pleroma.database bump_all_conversations
|
||||
|
||||
## Remove duplicated items from following and update followers count for all users
|
||||
|
||||
mix pleroma.database update_users_following_followers_counts
|
||||
"""
|
||||
def run(["remove_embedded_objects" | args]) do
|
||||
{options, [], []} =
|
||||
|
@ -38,7 +43,7 @@ def run(["remove_embedded_objects" | args]) do
|
|||
Common.start_pleroma()
|
||||
Logger.info("Removing embedded objects")
|
||||
|
||||
Pleroma.Repo.query!(
|
||||
Repo.query!(
|
||||
"update activities set data = jsonb_set(data, '{object}'::text[], data->'object'->'id') where data->'object'->>'id' is not null;",
|
||||
[],
|
||||
timeout: :infinity
|
||||
|
@ -47,7 +52,7 @@ def run(["remove_embedded_objects" | args]) do
|
|||
if Keyword.get(options, :vacuum) do
|
||||
Logger.info("Runnning VACUUM FULL")
|
||||
|
||||
Pleroma.Repo.query!(
|
||||
Repo.query!(
|
||||
"vacuum full;",
|
||||
[],
|
||||
timeout: :infinity
|
||||
|
@ -59,4 +64,12 @@ def run(["bump_all_conversations"]) do
|
|||
Common.start_pleroma()
|
||||
Conversation.bump_for_all_activities()
|
||||
end
|
||||
|
||||
def run(["update_users_following_followers_counts"]) do
|
||||
Common.start_pleroma()
|
||||
|
||||
users = Repo.all(User)
|
||||
Enum.each(users, &User.remove_duplicated_following/1)
|
||||
Enum.each(users, &User.update_follower_count/1)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -166,7 +166,7 @@ def remote_user_creation(params) do
|
|||
|
||||
def update_changeset(struct, params \\ %{}) do
|
||||
struct
|
||||
|> cast(params, [:bio, :name, :avatar])
|
||||
|> cast(params, [:bio, :name, :avatar, :following])
|
||||
|> unique_constraint(:nickname)
|
||||
|> validate_format(:nickname, local_nickname_regex())
|
||||
|> validate_length(:bio, max: 5000)
|
||||
|
@ -709,6 +709,18 @@ def update_follower_count(%User{} = user) do
|
|||
end
|
||||
end
|
||||
|
||||
def remove_duplicated_following(%User{following: following} = user) do
|
||||
uniq_following = Enum.uniq(following)
|
||||
|
||||
if length(following) == length(uniq_following) do
|
||||
{:ok, user}
|
||||
else
|
||||
user
|
||||
|> update_changeset(%{following: uniq_following})
|
||||
|> update_and_set_cache()
|
||||
end
|
||||
end
|
||||
|
||||
@spec get_users_from_set([String.t()], boolean()) :: [User.t()]
|
||||
def get_users_from_set(ap_ids, local_only \\ true) do
|
||||
criteria = %{ap_id: ap_ids, deactivated: false}
|
||||
|
|
49
test/tasks/database_test.exs
Normal file
49
test/tasks/database_test.exs
Normal file
|
@ -0,0 +1,49 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Mix.Tasks.Pleroma.DatabaseTest do
|
||||
alias Pleroma.Repo
|
||||
alias Pleroma.User
|
||||
use Pleroma.DataCase
|
||||
|
||||
import Pleroma.Factory
|
||||
|
||||
setup_all do
|
||||
Mix.shell(Mix.Shell.Process)
|
||||
|
||||
on_exit(fn ->
|
||||
Mix.shell(Mix.Shell.IO)
|
||||
end)
|
||||
|
||||
:ok
|
||||
end
|
||||
|
||||
describe "running update_users_following_followers_counts" do
|
||||
test "following and followers count are updated" do
|
||||
[user, user2] = insert_pair(:user)
|
||||
{:ok, %User{following: following, info: info} = user} = User.follow(user, user2)
|
||||
|
||||
assert length(following) == 2
|
||||
assert info.follower_count == 0
|
||||
|
||||
info_cng = Ecto.Changeset.change(info, %{follower_count: 3})
|
||||
|
||||
{:ok, user} =
|
||||
user
|
||||
|> Ecto.Changeset.change(%{following: following ++ following})
|
||||
|> Ecto.Changeset.put_embed(:info, info_cng)
|
||||
|> Repo.update()
|
||||
|
||||
assert length(user.following) == 4
|
||||
assert user.info.follower_count == 3
|
||||
|
||||
assert :ok == Mix.Tasks.Pleroma.Database.run(["update_users_following_followers_counts"])
|
||||
|
||||
user = User.get_by_id(user.id)
|
||||
|
||||
assert length(user.following) == 2
|
||||
assert user.info.follower_count == 0
|
||||
end
|
||||
end
|
||||
end
|
|
@ -3,6 +3,7 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Mix.Tasks.Pleroma.UserTest do
|
||||
alias Pleroma.Repo
|
||||
alias Pleroma.User
|
||||
use Pleroma.DataCase
|
||||
|
||||
|
|
|
@ -626,6 +626,37 @@ test "it sets the info->follower_count property" do
|
|||
end
|
||||
end
|
||||
|
||||
describe "remove duplicates from following list" do
|
||||
test "it removes duplicates" do
|
||||
user = insert(:user)
|
||||
follower = insert(:user)
|
||||
|
||||
{:ok, %User{following: following} = follower} = User.follow(follower, user)
|
||||
assert length(following) == 2
|
||||
|
||||
{:ok, follower} =
|
||||
follower
|
||||
|> User.update_changeset(%{following: following ++ following})
|
||||
|> Repo.update()
|
||||
|
||||
assert length(follower.following) == 4
|
||||
|
||||
{:ok, follower} = User.remove_duplicated_following(follower)
|
||||
assert length(follower.following) == 2
|
||||
end
|
||||
|
||||
test "it does nothing when following is uniq" do
|
||||
user = insert(:user)
|
||||
follower = insert(:user)
|
||||
|
||||
{:ok, follower} = User.follow(follower, user)
|
||||
assert length(follower.following) == 2
|
||||
|
||||
{:ok, follower} = User.remove_duplicated_following(follower)
|
||||
assert length(follower.following) == 2
|
||||
end
|
||||
end
|
||||
|
||||
describe "follow_import" do
|
||||
test "it imports user followings from list" do
|
||||
[user1, user2, user3] = insert_list(3, :user)
|
||||
|
|
Loading…
Reference in a new issue