total rebase
[anni] / lib / pleroma / migration_helper / notification_backfill.ex
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.MigrationHelper.NotificationBackfill do
6   alias Pleroma.Object
7   alias Pleroma.Repo
8   alias Pleroma.User
9
10   import Ecto.Query
11
12   def fill_in_notification_types do
13     query =
14       from(n in Pleroma.Notification,
15         where: is_nil(n.type),
16         preload: :activity
17       )
18
19     query
20     |> Repo.chunk_stream(100)
21     |> Enum.each(fn notification ->
22       if notification.activity do
23         type = type_from_activity(notification.activity)
24
25         notification
26         |> Ecto.Changeset.change(%{type: type})
27         |> Repo.update()
28       end
29     end)
30   end
31
32   defp get_by_ap_id(ap_id) do
33     q =
34       from(u in User,
35         select: u.id
36       )
37
38     Repo.get_by(q, ap_id: ap_id)
39   end
40
41   # This is copied over from Notifications to keep this stable.
42   defp type_from_activity(%{data: %{"type" => type}} = activity) do
43     case type do
44       "Follow" ->
45         accepted_function = fn activity ->
46           with %User{} = follower <- get_by_ap_id(activity.data["actor"]),
47                %User{} = followed <- get_by_ap_id(activity.data["object"]) do
48             Pleroma.FollowingRelationship.following?(follower, followed)
49           end
50         end
51
52         if accepted_function.(activity) do
53           "follow"
54         else
55           "follow_request"
56         end
57
58       "Announce" ->
59         "reblog"
60
61       "Like" ->
62         "favourite"
63
64       "Move" ->
65         "move"
66
67       "EmojiReact" ->
68         "pleroma:emoji_reaction"
69
70       # Compatibility with old reactions
71       "EmojiReaction" ->
72         "pleroma:emoji_reaction"
73
74       "Create" ->
75         type_from_activity_object(activity)
76
77       t ->
78         raise "No notification type for activity type #{t}"
79     end
80   end
81
82   defp type_from_activity_object(%{data: %{"type" => "Create", "object" => %{}}}), do: "mention"
83
84   defp type_from_activity_object(%{data: %{"type" => "Create"}} = activity) do
85     object = Object.get_by_ap_id(activity.data["object"])
86
87     case object && object.data["type"] do
88       "ChatMessage" -> "pleroma:chat_mention"
89       _ -> "mention"
90     end
91   end
92 end