Mastodon API: Add exclude_visibilities parameter to the timeline and notification endpoints
This commit is contained in:
parent
e3b4a3e96b
commit
a97b642289
9 changed files with 297 additions and 44 deletions
|
|
@ -17,6 +17,7 @@ defmodule Pleroma.Notification do
|
|||
|
||||
import Ecto.Query
|
||||
import Ecto.Changeset
|
||||
require Logger
|
||||
|
||||
@type t :: %__MODULE__{}
|
||||
|
||||
|
|
@ -34,43 +35,92 @@ defmodule Pleroma.Notification do
|
|||
end
|
||||
|
||||
def for_user_query(user, opts \\ []) do
|
||||
query =
|
||||
Notification
|
||||
|> where(user_id: ^user.id)
|
||||
Notification
|
||||
|> where(user_id: ^user.id)
|
||||
|> where(
|
||||
[n, a],
|
||||
fragment(
|
||||
"? not in (SELECT ap_id FROM users WHERE info->'deactivated' @> 'true')",
|
||||
a.actor
|
||||
)
|
||||
)
|
||||
|> join(:inner, [n], activity in assoc(n, :activity))
|
||||
|> join(:left, [n, a], object in Object,
|
||||
on:
|
||||
fragment(
|
||||
"(?->>'id') = COALESCE((? -> 'object'::text) ->> 'id'::text)",
|
||||
object.data,
|
||||
a.data
|
||||
)
|
||||
)
|
||||
|> preload([n, a, o], activity: {a, object: o})
|
||||
|> exclude_muted(user, opts)
|
||||
|> exclude_visibility(opts)
|
||||
end
|
||||
|
||||
defp exclude_muted(query, _, %{with_muted: true}) do
|
||||
query
|
||||
end
|
||||
|
||||
defp exclude_muted(query, user, _opts) do
|
||||
query
|
||||
|> where([n, a], a.actor not in ^user.info.muted_notifications)
|
||||
|> where([n, a], a.actor not in ^user.info.blocks)
|
||||
|> where(
|
||||
[n, a],
|
||||
fragment("substring(? from '.*://([^/]*)')", a.actor) not in ^user.info.domain_blocks
|
||||
)
|
||||
|> join(:left, [n, a], tm in Pleroma.ThreadMute,
|
||||
on: tm.user_id == ^user.id and tm.context == fragment("?->>'context'", a.data)
|
||||
)
|
||||
|> where([n, a, o, tm], is_nil(tm.user_id))
|
||||
end
|
||||
|
||||
@valid_visibilities ~w[direct unlisted public private]
|
||||
|
||||
defp exclude_visibility(query, %{exclude_visibilities: visibility})
|
||||
when is_list(visibility) do
|
||||
if Enum.all?(visibility, &(&1 in @valid_visibilities)) do
|
||||
query
|
||||
|> where(
|
||||
[n, a],
|
||||
fragment(
|
||||
"? not in (SELECT ap_id FROM users WHERE info->'deactivated' @> 'true')",
|
||||
a.actor
|
||||
not fragment(
|
||||
"activity_visibility(?, ?, ?) = ANY (?)",
|
||||
a.actor,
|
||||
a.recipients,
|
||||
a.data,
|
||||
^visibility
|
||||
)
|
||||
)
|
||||
|> join(:inner, [n], activity in assoc(n, :activity))
|
||||
|> join(:left, [n, a], object in Object,
|
||||
on:
|
||||
fragment(
|
||||
"(?->>'id') = COALESCE((? -> 'object'::text) ->> 'id'::text)",
|
||||
object.data,
|
||||
a.data
|
||||
)
|
||||
)
|
||||
|> preload([n, a, o], activity: {a, object: o})
|
||||
|
||||
if opts[:with_muted] do
|
||||
query
|
||||
else
|
||||
where(query, [n, a], a.actor not in ^user.info.muted_notifications)
|
||||
|> where([n, a], a.actor not in ^user.info.blocks)
|
||||
|> where(
|
||||
[n, a],
|
||||
fragment("substring(? from '.*://([^/]*)')", a.actor) not in ^user.info.domain_blocks
|
||||
)
|
||||
|> join(:left, [n, a], tm in Pleroma.ThreadMute,
|
||||
on: tm.user_id == ^user.id and tm.context == fragment("?->>'context'", a.data)
|
||||
)
|
||||
|> where([n, a, o, tm], is_nil(tm.user_id))
|
||||
Logger.error("Could not exclude visibility to #{visibility}")
|
||||
query
|
||||
end
|
||||
end
|
||||
|
||||
defp exclude_visibility(query, %{exclude_visibilities: visibility})
|
||||
when visibility in @valid_visibilities do
|
||||
query
|
||||
|> where(
|
||||
[n, a],
|
||||
not fragment(
|
||||
"activity_visibility(?, ?, ?) = (?)",
|
||||
a.actor,
|
||||
a.recipients,
|
||||
a.data,
|
||||
^visibility
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
defp exclude_visibility(query, %{exclude_visibilities: visibility})
|
||||
when visibility not in @valid_visibilities do
|
||||
Logger.error("Could not exclude visibility to #{visibility}")
|
||||
query
|
||||
end
|
||||
|
||||
defp exclude_visibility(query, _visibility), do: query
|
||||
|
||||
def for_user(user, opts \\ %{}) do
|
||||
user
|
||||
|> for_user_query(opts)
|
||||
|
|
|
|||
|
|
@ -596,6 +596,49 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|
|||
|
||||
defp restrict_visibility(query, _visibility), do: query
|
||||
|
||||
defp exclude_visibility(query, %{"exclude_visibilities" => visibility})
|
||||
when is_list(visibility) do
|
||||
if Enum.all?(visibility, &(&1 in @valid_visibilities)) do
|
||||
from(
|
||||
a in query,
|
||||
where:
|
||||
not fragment(
|
||||
"activity_visibility(?, ?, ?) = ANY (?)",
|
||||
a.actor,
|
||||
a.recipients,
|
||||
a.data,
|
||||
^visibility
|
||||
)
|
||||
)
|
||||
else
|
||||
Logger.error("Could not exclude visibility to #{visibility}")
|
||||
query
|
||||
end
|
||||
end
|
||||
|
||||
defp exclude_visibility(query, %{"exclude_visibilities" => visibility})
|
||||
when visibility in @valid_visibilities do
|
||||
from(
|
||||
a in query,
|
||||
where:
|
||||
not fragment(
|
||||
"activity_visibility(?, ?, ?) = ?",
|
||||
a.actor,
|
||||
a.recipients,
|
||||
a.data,
|
||||
^visibility
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
defp exclude_visibility(query, %{"exclude_visibilities" => visibility})
|
||||
when visibility not in @valid_visibilities do
|
||||
Logger.error("Could not exclude visibility to #{visibility}")
|
||||
query
|
||||
end
|
||||
|
||||
defp exclude_visibility(query, _visibility), do: query
|
||||
|
||||
defp restrict_thread_visibility(query, _, %{skip_thread_containment: true} = _),
|
||||
do: query
|
||||
|
||||
|
|
@ -960,6 +1003,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|
|||
|> restrict_muted_reblogs(opts)
|
||||
|> Activity.restrict_deactivated_users()
|
||||
|> exclude_poll_votes(opts)
|
||||
|> exclude_visibility(opts)
|
||||
end
|
||||
|
||||
def fetch_activities(recipients, opts \\ %{}, pagination \\ :keyset) do
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPI do
|
|||
defp cast_params(params) do
|
||||
param_types = %{
|
||||
exclude_types: {:array, :string},
|
||||
exclude_visibilities: {:array, :string},
|
||||
reblogs: :boolean,
|
||||
with_muted: :boolean
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue