--- /dev/null
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.MigrationHelper do
+ alias Pleroma.User
+ alias Pleroma.Object
+ alias Pleroma.Notification
+ alias Pleroma.Repo
+
+ import Ecto.Query
+
+ def fill_in_notification_types do
+ query =
+ from(n in Pleroma.Notification,
+ where: is_nil(n.type),
+ preload: :activity
+ )
+
+ query
+ |> Repo.all()
+ |> Enum.each(fn notification ->
+ type =
+ notification.activity
+ |> type_from_activity()
+
+ notification
+ |> Notification.changeset(%{type: type})
+ |> Repo.update()
+ end)
+ end
+
+ # This is copied over from Notifications to keep this stable.
+ defp type_from_activity(%{data: %{"type" => type}} = activity) do
+ case type do
+ "Follow" ->
+ accepted_function = fn activity ->
+ with %User{} = follower <- User.get_by_ap_id(activity.data["actor"]),
+ %User{} = followed <- User.get_by_ap_id(activity.data["object"]) do
+ Pleroma.FollowingRelationship.following?(follower, followed)
+ end
+ end
+
+ if accepted_function.(activity) do
+ "follow"
+ else
+ "follow_request"
+ end
+
+ "Announce" ->
+ "reblog"
+
+ "Like" ->
+ "favourite"
+
+ "Move" ->
+ "move"
+
+ "EmojiReact" ->
+ "pleroma:emoji_reaction"
+
+ # Compatibility with old reactions
+ "EmojiReaction" ->
+ "pleroma:emoji_reaction"
+
+ "Create" ->
+ activity
+ |> type_from_activity_object()
+
+ t ->
+ raise "No notification type for activity type #{t}"
+ end
+ end
+
+ defp type_from_activity_object(%{data: %{"type" => "Create", "object" => %{}}}), do: "mention"
+
+ defp type_from_activity_object(%{data: %{"type" => "Create"}} = activity) do
+ object = Object.get_by_ap_id(activity.data["object"])
+
+ case object && object.data["type"] do
+ "ChatMessage" -> "pleroma:chat_mention"
+ _ -> "mention"
+ end
+ end
+end
timestamps()
end
- def fill_in_notification_types do
- query =
- from(n in __MODULE__,
- where: is_nil(n.type),
- preload: :activity
- )
-
- query
- |> Repo.all()
- |> Enum.each(fn notification ->
- type =
- notification.activity
- |> type_from_activity(no_cachex: true)
-
- notification
- |> changeset(%{type: type})
- |> Repo.update()
- end)
- end
-
def update_notification_type(user, activity) do
with %__MODULE__{} = notification <-
Repo.get_by(__MODULE__, user_id: user.id, activity_id: activity.id) do
{:ok, notifications}
end
- defp type_from_activity(%{data: %{"type" => type}} = activity, opts \\ []) do
+ defp type_from_activity(%{data: %{"type" => type}} = activity) do
case type do
"Follow" ->
- accepted_function =
- if Keyword.get(opts, :no_cachex, false) do
- # A special function to make this usable in a migration.
- fn activity ->
- with %User{} = follower <- User.get_by_ap_id(activity.data["actor"]),
- %User{} = followed <- User.get_by_ap_id(activity.data["object"]) do
- Pleroma.FollowingRelationship.following?(follower, followed)
- end
- end
- else
- &Activity.follow_accepted?/1
- end
-
- if accepted_function.(activity) do
+ if Activity.follow_accepted?(activity) do
"follow"
else
"follow_request"
use Ecto.Migration
def up do
- Pleroma.Notification.fill_in_notification_types()
+ Pleroma.MigrationHelper.fill_in_notification_types()
end
def down do
--- /dev/null
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.MigrationHelperTest do
+ use Pleroma.DataCase
+
+ alias Pleroma.Activity
+ alias Pleroma.MigrationHelper
+ alias Pleroma.Notification
+ alias Pleroma.Repo
+ alias Pleroma.Web.CommonAPI
+
+ import Pleroma.Factory
+
+ describe "fill_in_notification_types" do
+ test "it fills in missing notification types" do
+ user = insert(:user)
+ other_user = insert(:user)
+
+ {:ok, post} = CommonAPI.post(user, %{status: "yeah, @#{other_user.nickname}"})
+ {:ok, chat} = CommonAPI.post_chat_message(user, other_user, "yo")
+ {:ok, react} = CommonAPI.react_with_emoji(post.id, other_user, "☕")
+ {:ok, like} = CommonAPI.favorite(other_user, post.id)
+ {:ok, react_2} = CommonAPI.react_with_emoji(post.id, other_user, "☕")
+
+ data =
+ react_2.data
+ |> Map.put("type", "EmojiReaction")
+
+ {:ok, react_2} =
+ react_2
+ |> Activity.change(%{data: data})
+ |> Repo.update()
+
+ assert {5, nil} = Repo.update_all(Notification, set: [type: nil])
+
+ MigrationHelper.fill_in_notification_types()
+
+ assert %{type: "mention"} =
+ Repo.get_by(Notification, user_id: other_user.id, activity_id: post.id)
+
+ assert %{type: "favourite"} =
+ Repo.get_by(Notification, user_id: user.id, activity_id: like.id)
+
+ assert %{type: "pleroma:emoji_reaction"} =
+ Repo.get_by(Notification, user_id: user.id, activity_id: react.id)
+
+ assert %{type: "pleroma:emoji_reaction"} =
+ Repo.get_by(Notification, user_id: user.id, activity_id: react_2.id)
+
+ assert %{type: "pleroma:chat_mention"} =
+ Repo.get_by(Notification, user_id: other_user.id, activity_id: chat.id)
+ end
+ end
+end
import Pleroma.Factory
import Mock
- alias Pleroma.Activity
alias Pleroma.FollowingRelationship
alias Pleroma.Notification
alias Pleroma.Repo
alias Pleroma.Web.Push
alias Pleroma.Web.Streamer
- describe "fill_in_notification_types" do
- test "it fills in missing notification types" do
- user = insert(:user)
- other_user = insert(:user)
-
- {:ok, post} = CommonAPI.post(user, %{status: "yeah, @#{other_user.nickname}"})
- {:ok, chat} = CommonAPI.post_chat_message(user, other_user, "yo")
- {:ok, react} = CommonAPI.react_with_emoji(post.id, other_user, "☕")
- {:ok, like} = CommonAPI.favorite(other_user, post.id)
- {:ok, react_2} = CommonAPI.react_with_emoji(post.id, other_user, "☕")
-
- data =
- react_2.data
- |> Map.put("type", "EmojiReaction")
-
- {:ok, react_2} =
- react_2
- |> Activity.change(%{data: data})
- |> Repo.update()
-
- assert {5, nil} = Repo.update_all(Notification, set: [type: nil])
-
- Notification.fill_in_notification_types()
-
- assert %{type: "mention"} =
- Repo.get_by(Notification, user_id: other_user.id, activity_id: post.id)
-
- assert %{type: "favourite"} =
- Repo.get_by(Notification, user_id: user.id, activity_id: like.id)
-
- assert %{type: "pleroma:emoji_reaction"} =
- Repo.get_by(Notification, user_id: user.id, activity_id: react.id)
-
- assert %{type: "pleroma:emoji_reaction"} =
- Repo.get_by(Notification, user_id: user.id, activity_id: react_2.id)
-
- assert %{type: "pleroma:chat_mention"} =
- Repo.get_by(Notification, user_id: other_user.id, activity_id: chat.id)
- end
- end
-
describe "create_notifications" do
test "creates a notification for an emoji reaction" do
user = insert(:user)