optimise notifications query
This commit is contained in:
parent
8af50dea36
commit
cb9b0d3720
5 changed files with 33 additions and 42 deletions
|
@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
|
|
||||||
|
## Unreleased
|
||||||
|
|
||||||
|
## Changes
|
||||||
|
- Follows no longer override domain blocks, a domain block is final
|
||||||
|
|
||||||
## 2022.10
|
## 2022.10
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
|
@ -240,30 +240,6 @@ defmodule Pleroma.FollowingRelationship do
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc """
|
|
||||||
For a query with joined activity,
|
|
||||||
keeps rows where activity's actor is followed by user -or- is NOT domain-blocked by user.
|
|
||||||
"""
|
|
||||||
def keep_following_or_not_domain_blocked(query, user) do
|
|
||||||
where(
|
|
||||||
query,
|
|
||||||
[_, activity],
|
|
||||||
fragment(
|
|
||||||
# "(actor's domain NOT in domain_blocks) OR (actor IS in followed AP IDs)"
|
|
||||||
"""
|
|
||||||
NOT (substring(? from '.*://([^/]*)') = ANY(?)) OR
|
|
||||||
? = ANY(SELECT ap_id FROM users AS u INNER JOIN following_relationships AS fr
|
|
||||||
ON u.id = fr.following_id WHERE fr.follower_id = ? AND fr.state = ?)
|
|
||||||
""",
|
|
||||||
activity.actor,
|
|
||||||
^user.domain_blocks,
|
|
||||||
activity.actor,
|
|
||||||
^User.binary_id(user.id),
|
|
||||||
^accept_state_code()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
defp validate_not_self_relationship(%Changeset{} = changeset) do
|
defp validate_not_self_relationship(%Changeset{} = changeset) do
|
||||||
changeset
|
changeset
|
||||||
|> validate_follower_id_following_id_inequality()
|
|> validate_follower_id_following_id_inequality()
|
||||||
|
|
|
@ -138,7 +138,24 @@ defmodule Pleroma.Notification do
|
||||||
|
|
||||||
query
|
query
|
||||||
|> where([n, a], a.actor not in ^blocked_ap_ids)
|
|> where([n, a], a.actor not in ^blocked_ap_ids)
|
||||||
|> FollowingRelationship.keep_following_or_not_domain_blocked(user)
|
|> restrict_domain_blocked(user)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp restrict_domain_blocked(query, user) do
|
||||||
|
where(
|
||||||
|
query,
|
||||||
|
[_, activity],
|
||||||
|
fragment(
|
||||||
|
# "(actor's domain NOT in domain_blocks)"
|
||||||
|
"""
|
||||||
|
NOT (
|
||||||
|
substring(? from '.*://([^/]*)') = ANY(?)
|
||||||
|
)
|
||||||
|
""",
|
||||||
|
activity.actor,
|
||||||
|
^user.domain_blocks
|
||||||
|
)
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp exclude_blockers(query, user) do
|
defp exclude_blockers(query, user) do
|
||||||
|
|
|
@ -63,11 +63,16 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPI do
|
||||||
def get_notifications(user, params \\ %{}) do
|
def get_notifications(user, params \\ %{}) do
|
||||||
options = cast_params(params)
|
options = cast_params(params)
|
||||||
|
|
||||||
|
query =
|
||||||
user
|
user
|
||||||
|> Notification.for_user_query(options)
|
|> Notification.for_user_query(options)
|
||||||
|> restrict(:include_types, options)
|
|> restrict(:include_types, options)
|
||||||
|> restrict(:exclude_types, options)
|
|> restrict(:exclude_types, options)
|
||||||
|> restrict(:account_ap_id, options)
|
|> restrict(:account_ap_id, options)
|
||||||
|
|
||||||
|
IO.inspect(Pleroma.Repo.to_sql(:all, query))
|
||||||
|
|
||||||
|
query
|
||||||
|> Pagination.fetch_paginated(params)
|
|> Pagination.fetch_paginated(params)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1149,18 +1149,6 @@ defmodule Pleroma.NotificationTest do
|
||||||
assert Notification.for_user(user) == []
|
assert Notification.for_user(user) == []
|
||||||
end
|
end
|
||||||
|
|
||||||
test "it returns notifications for domain-blocked but followed user" do
|
|
||||||
user = insert(:user)
|
|
||||||
blocked = insert(:user, ap_id: "http://some-domain.com")
|
|
||||||
|
|
||||||
{:ok, user} = User.block_domain(user, "some-domain.com")
|
|
||||||
{:ok, _, _} = User.follow(user, blocked)
|
|
||||||
|
|
||||||
{:ok, _activity} = CommonAPI.post(blocked, %{status: "hey @#{user.nickname}"})
|
|
||||||
|
|
||||||
assert length(Notification.for_user(user)) == 1
|
|
||||||
end
|
|
||||||
|
|
||||||
test "it doesn't return notifications for muted thread", %{user: user} do
|
test "it doesn't return notifications for muted thread", %{user: user} do
|
||||||
another_user = insert(:user)
|
another_user = insert(:user)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue