From cb9b0d3720cdfe5e9987d70d0822032fef7a3d8a Mon Sep 17 00:00:00 2001 From: FloatingGhost Date: Tue, 11 Oct 2022 11:40:43 +0100 Subject: [PATCH] optimise notifications query --- CHANGELOG.md | 5 ++++ lib/pleroma/following_relationship.ex | 24 -------------------- lib/pleroma/notification.ex | 19 +++++++++++++++- lib/pleroma/web/mastodon_api/mastodon_api.ex | 15 ++++++++---- test/pleroma/notification_test.exs | 12 ---------- 5 files changed, 33 insertions(+), 42 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ece6af0d2..8a675a32e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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/). +## Unreleased + +## Changes +- Follows no longer override domain blocks, a domain block is final + ## 2022.10 ### Added diff --git a/lib/pleroma/following_relationship.ex b/lib/pleroma/following_relationship.ex index b101b9ee7..42db9463d 100644 --- a/lib/pleroma/following_relationship.ex +++ b/lib/pleroma/following_relationship.ex @@ -240,30 +240,6 @@ defmodule Pleroma.FollowingRelationship do 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 changeset |> validate_follower_id_following_id_inequality() diff --git a/lib/pleroma/notification.ex b/lib/pleroma/notification.ex index 593448713..3995be01f 100644 --- a/lib/pleroma/notification.ex +++ b/lib/pleroma/notification.ex @@ -138,7 +138,24 @@ defmodule Pleroma.Notification do query |> 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 defp exclude_blockers(query, user) do diff --git a/lib/pleroma/web/mastodon_api/mastodon_api.ex b/lib/pleroma/web/mastodon_api/mastodon_api.ex index 23846b36a..69bc2f0d6 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_api.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_api.ex @@ -63,11 +63,16 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPI do def get_notifications(user, params \\ %{}) do options = cast_params(params) - user - |> Notification.for_user_query(options) - |> restrict(:include_types, options) - |> restrict(:exclude_types, options) - |> restrict(:account_ap_id, options) + query = + user + |> Notification.for_user_query(options) + |> restrict(:include_types, options) + |> restrict(:exclude_types, options) + |> restrict(:account_ap_id, options) + + IO.inspect(Pleroma.Repo.to_sql(:all, query)) + + query |> Pagination.fetch_paginated(params) end diff --git a/test/pleroma/notification_test.exs b/test/pleroma/notification_test.exs index 68330465b..721836a2c 100644 --- a/test/pleroma/notification_test.exs +++ b/test/pleroma/notification_test.exs @@ -1149,18 +1149,6 @@ defmodule Pleroma.NotificationTest do assert Notification.for_user(user) == [] 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 another_user = insert(:user)