Merge branch 'spc-fix-3' into 'develop'
[akkoma] / lib / pleroma / spc_fixes / spc_fixes.ex
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 alias Pleroma.Repo
6 alias Pleroma.User
7 alias Pleroma.Activity
8 alias Pleroma.Object
9 import Ecto.Query
10
11 defmodule Pleroma.SpcFixes do
12 def upgrade_users do
13 query =
14 from(u in User,
15 where: fragment("? like ?", u.ap_id, "https://shitposter.club/user/%")
16 )
17
18 {:ok, file} = File.read("lib/pleroma/spc_fixes/users_conversion.txt")
19
20 # Mapping of old ap_id to new ap_id and vice reversa
21 mapping =
22 file
23 |> String.trim()
24 |> String.split("\n")
25 |> Enum.map(fn line ->
26 line
27 |> String.split("\t")
28 end)
29 |> Enum.reduce(%{}, fn [_id, old_ap_id, new_ap_id], acc ->
30 acc
31 |> Map.put(String.trim(old_ap_id), String.trim(new_ap_id))
32 |> Map.put(String.trim(new_ap_id), String.trim(old_ap_id))
33 end)
34
35 # First, refetch all the old users.
36 _old_users =
37 query
38 |> Repo.all()
39 |> Enum.each(fn user ->
40 with ap_id when is_binary(ap_id) <- mapping[user.ap_id] do
41 # This fetches and updates the user.
42 User.get_or_fetch_by_ap_id(ap_id)
43 end
44 end)
45
46 # Now, fix follow relationships.
47 query =
48 from(u in User,
49 where: fragment("? like ?", u.ap_id, "https://shitposter.club/users/%")
50 )
51
52 query
53 |> Repo.all()
54 |> Enum.each(fn user ->
55 old_follower_address = User.ap_followers(user)
56
57 # Fix users
58 query =
59 from(u in User,
60 where: ^old_follower_address in u.following,
61 update: [
62 push: [following: ^user.follower_address]
63 ]
64 )
65
66 Repo.update_all(query, [])
67
68 # Fix activities
69 query =
70 from(a in Activity,
71 where: fragment("?->>'actor' = ?", a.data, ^mapping[user.ap_id]),
72 update: [
73 set: [
74 data:
75 fragment(
76 "jsonb_set(jsonb_set(?, '{actor}', ?), '{to}', (?->'to')::jsonb || ?)",
77 a.data,
78 ^user.ap_id,
79 a.data,
80 ^[user.follower_address]
81 ),
82 actor: ^user.ap_id
83 ],
84 push: [
85 recipients: ^user.follower_address
86 ]
87 ]
88 )
89
90 Repo.update_all(query, [])
91
92 # Fix objects
93 query =
94 from(a in Object,
95 where: fragment("?->>'actor' = ?", a.data, ^mapping[user.ap_id]),
96 update: [
97 set: [
98 data:
99 fragment(
100 "jsonb_set(jsonb_set(?, '{actor}', ?), '{to}', (?->'to')::jsonb || ?)",
101 a.data,
102 ^user.ap_id,
103 a.data,
104 ^[user.follower_address]
105 )
106 ]
107 ]
108 )
109
110 Repo.update_all(query, [])
111 end)
112 end
113 end