Merge branch 'develop' into feature/1893-remote-emoji-packs-pagination
This commit is contained in:
commit
346cc3ac24
54 changed files with 908 additions and 187 deletions
|
|
@ -2,11 +2,11 @@ defmodule Mix.Tasks.Pleroma.Email do
|
|||
use Mix.Task
|
||||
import Mix.Pleroma
|
||||
|
||||
@shortdoc "Simple Email test"
|
||||
@shortdoc "Email administrative tasks"
|
||||
@moduledoc File.read!("docs/administration/CLI_tasks/email.md")
|
||||
|
||||
def run(["test" | args]) do
|
||||
Mix.Pleroma.start_pleroma()
|
||||
start_pleroma()
|
||||
|
||||
{options, [], []} =
|
||||
OptionParser.parse(
|
||||
|
|
@ -21,4 +21,20 @@ defmodule Mix.Tasks.Pleroma.Email do
|
|||
|
||||
shell_info("Test email has been sent to #{inspect(email.to)} from #{inspect(email.from)}")
|
||||
end
|
||||
|
||||
def run(["resend_confirmation_emails"]) do
|
||||
start_pleroma()
|
||||
|
||||
shell_info("Sending emails to all unconfirmed users")
|
||||
|
||||
Pleroma.User.Query.build(%{
|
||||
local: true,
|
||||
deactivated: false,
|
||||
confirmation_pending: true,
|
||||
invisible: false
|
||||
})
|
||||
|> Pleroma.Repo.chunk_stream(500)
|
||||
|> Stream.each(&Pleroma.User.try_send_confirmation_email(&1))
|
||||
|> Stream.run()
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -21,10 +21,19 @@ defmodule Mix.Tasks.Pleroma.Relay do
|
|||
end
|
||||
end
|
||||
|
||||
def run(["unfollow", target]) do
|
||||
def run(["unfollow", target | rest]) do
|
||||
start_pleroma()
|
||||
|
||||
with {:ok, _activity} <- Relay.unfollow(target) do
|
||||
{options, [], []} =
|
||||
OptionParser.parse(
|
||||
rest,
|
||||
strict: [force: :boolean],
|
||||
aliases: [f: :force]
|
||||
)
|
||||
|
||||
force = Keyword.get(options, :force, false)
|
||||
|
||||
with {:ok, _activity} <- Relay.unfollow(target, %{force: force}) do
|
||||
# put this task to sleep to allow the genserver to push out the messages
|
||||
:timer.sleep(500)
|
||||
else
|
||||
|
|
|
|||
|
|
@ -196,17 +196,24 @@ defmodule Mix.Tasks.Pleroma.User do
|
|||
OptionParser.parse(
|
||||
rest,
|
||||
strict: [
|
||||
moderator: :boolean,
|
||||
admin: :boolean,
|
||||
locked: :boolean
|
||||
confirmed: :boolean,
|
||||
locked: :boolean,
|
||||
moderator: :boolean
|
||||
]
|
||||
)
|
||||
|
||||
with %User{local: true} = user <- User.get_cached_by_nickname(nickname) do
|
||||
user =
|
||||
case Keyword.get(options, :moderator) do
|
||||
case Keyword.get(options, :admin) do
|
||||
nil -> user
|
||||
value -> set_moderator(user, value)
|
||||
value -> set_admin(user, value)
|
||||
end
|
||||
|
||||
user =
|
||||
case Keyword.get(options, :confirmed) do
|
||||
nil -> user
|
||||
value -> set_confirmed(user, value)
|
||||
end
|
||||
|
||||
user =
|
||||
|
|
@ -216,9 +223,9 @@ defmodule Mix.Tasks.Pleroma.User do
|
|||
end
|
||||
|
||||
_user =
|
||||
case Keyword.get(options, :admin) do
|
||||
case Keyword.get(options, :moderator) do
|
||||
nil -> user
|
||||
value -> set_admin(user, value)
|
||||
value -> set_moderator(user, value)
|
||||
end
|
||||
else
|
||||
_ ->
|
||||
|
|
@ -353,6 +360,42 @@ defmodule Mix.Tasks.Pleroma.User do
|
|||
end
|
||||
end
|
||||
|
||||
def run(["confirm_all"]) do
|
||||
start_pleroma()
|
||||
|
||||
Pleroma.User.Query.build(%{
|
||||
local: true,
|
||||
deactivated: false,
|
||||
is_moderator: false,
|
||||
is_admin: false,
|
||||
invisible: false
|
||||
})
|
||||
|> Pleroma.Repo.chunk_stream(500, :batches)
|
||||
|> Stream.each(fn users ->
|
||||
users
|
||||
|> Enum.each(fn user -> User.need_confirmation(user, false) end)
|
||||
end)
|
||||
|> Stream.run()
|
||||
end
|
||||
|
||||
def run(["unconfirm_all"]) do
|
||||
start_pleroma()
|
||||
|
||||
Pleroma.User.Query.build(%{
|
||||
local: true,
|
||||
deactivated: false,
|
||||
is_moderator: false,
|
||||
is_admin: false,
|
||||
invisible: false
|
||||
})
|
||||
|> Pleroma.Repo.chunk_stream(500, :batches)
|
||||
|> Stream.each(fn users ->
|
||||
users
|
||||
|> Enum.each(fn user -> User.need_confirmation(user, true) end)
|
||||
end)
|
||||
|> Stream.run()
|
||||
end
|
||||
|
||||
def run(["sign_out", nickname]) do
|
||||
start_pleroma()
|
||||
|
||||
|
|
@ -410,4 +453,11 @@ defmodule Mix.Tasks.Pleroma.User do
|
|||
shell_info("Locked status of #{user.nickname}: #{user.locked}")
|
||||
user
|
||||
end
|
||||
|
||||
defp set_confirmed(user, value) do
|
||||
{:ok, user} = User.need_confirmation(user, !value)
|
||||
|
||||
shell_info("Confirmation pending status of #{user.nickname}: #{user.confirmation_pending}")
|
||||
user
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -56,7 +56,6 @@ defmodule Pleroma.Application do
|
|||
Pleroma.ApplicationRequirements.verify!()
|
||||
setup_instrumenters()
|
||||
load_custom_modules()
|
||||
check_system_commands()
|
||||
Pleroma.Docs.JSON.compile()
|
||||
|
||||
adapter = Application.get_env(:tesla, :adapter)
|
||||
|
|
@ -260,21 +259,4 @@ defmodule Pleroma.Application do
|
|||
end
|
||||
|
||||
defp http_children(_, _), do: []
|
||||
|
||||
defp check_system_commands do
|
||||
filters = Config.get([Pleroma.Upload, :filters])
|
||||
|
||||
check_filter = fn filter, command_required ->
|
||||
with true <- filter in filters,
|
||||
false <- Pleroma.Utils.command_available?(command_required) do
|
||||
Logger.error(
|
||||
"#{filter} is specified in list of Pleroma.Upload filters, but the #{command_required} command is not found"
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
check_filter.(Pleroma.Upload.Filters.Exiftool, "exiftool")
|
||||
check_filter.(Pleroma.Upload.Filters.Mogrify, "mogrify")
|
||||
check_filter.(Pleroma.Upload.Filters.Mogrifun, "mogrify")
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -9,6 +9,9 @@ defmodule Pleroma.ApplicationRequirements do
|
|||
|
||||
defmodule VerifyError, do: defexception([:message])
|
||||
|
||||
alias Pleroma.Config
|
||||
alias Pleroma.Helpers.MediaHelper
|
||||
|
||||
import Ecto.Query
|
||||
|
||||
require Logger
|
||||
|
|
@ -16,7 +19,8 @@ defmodule Pleroma.ApplicationRequirements do
|
|||
@spec verify!() :: :ok | VerifyError.t()
|
||||
def verify! do
|
||||
:ok
|
||||
|> check_confirmation_accounts!
|
||||
|> check_system_commands!()
|
||||
|> check_confirmation_accounts!()
|
||||
|> check_migrations_applied!()
|
||||
|> check_welcome_message_config!()
|
||||
|> check_rum!()
|
||||
|
|
@ -48,7 +52,9 @@ defmodule Pleroma.ApplicationRequirements do
|
|||
if Pleroma.Config.get([:instance, :account_activation_required]) &&
|
||||
not Pleroma.Config.get([Pleroma.Emails.Mailer, :enabled]) do
|
||||
Logger.error(
|
||||
"Account activation enabled, but no Mailer settings enabled.\nPlease set config :pleroma, :instance, account_activation_required: false\nOtherwise setup and enable Mailer."
|
||||
"Account activation enabled, but no Mailer settings enabled.\n" <>
|
||||
"Please set config :pleroma, :instance, account_activation_required: false\n" <>
|
||||
"Otherwise setup and enable Mailer."
|
||||
)
|
||||
|
||||
{:error,
|
||||
|
|
@ -81,7 +87,9 @@ defmodule Pleroma.ApplicationRequirements do
|
|||
Enum.map(down_migrations, fn {:down, id, name} -> "- #{name} (#{id})\n" end)
|
||||
|
||||
Logger.error(
|
||||
"The following migrations were not applied:\n#{down_migrations_text}If you want to start Pleroma anyway, set\nconfig :pleroma, :i_am_aware_this_may_cause_data_loss, disable_migration_check: true"
|
||||
"The following migrations were not applied:\n#{down_migrations_text}" <>
|
||||
"If you want to start Pleroma anyway, set\n" <>
|
||||
"config :pleroma, :i_am_aware_this_may_cause_data_loss, disable_migration_check: true"
|
||||
)
|
||||
|
||||
{:error, "Unapplied Migrations detected"}
|
||||
|
|
@ -124,14 +132,22 @@ defmodule Pleroma.ApplicationRequirements do
|
|||
case {setting, migrate} do
|
||||
{true, false} ->
|
||||
Logger.error(
|
||||
"Use `RUM` index is enabled, but were not applied migrations for it.\nIf you want to start Pleroma anyway, set\nconfig :pleroma, :database, rum_enabled: false\nOtherwise apply the following migrations:\n`mix ecto.migrate --migrations-path priv/repo/optional_migrations/rum_indexing/`"
|
||||
"Use `RUM` index is enabled, but were not applied migrations for it.\n" <>
|
||||
"If you want to start Pleroma anyway, set\n" <>
|
||||
"config :pleroma, :database, rum_enabled: false\n" <>
|
||||
"Otherwise apply the following migrations:\n" <>
|
||||
"`mix ecto.migrate --migrations-path priv/repo/optional_migrations/rum_indexing/`"
|
||||
)
|
||||
|
||||
{:error, "Unapplied RUM Migrations detected"}
|
||||
|
||||
{false, true} ->
|
||||
Logger.error(
|
||||
"Detected applied migrations to use `RUM` index, but `RUM` isn't enable in settings.\nIf you want to use `RUM`, set\nconfig :pleroma, :database, rum_enabled: true\nOtherwise roll `RUM` migrations back.\n`mix ecto.rollback --migrations-path priv/repo/optional_migrations/rum_indexing/`"
|
||||
"Detected applied migrations to use `RUM` index, but `RUM` isn't enable in settings.\n" <>
|
||||
"If you want to use `RUM`, set\n" <>
|
||||
"config :pleroma, :database, rum_enabled: true\n" <>
|
||||
"Otherwise roll `RUM` migrations back.\n" <>
|
||||
"`mix ecto.rollback --migrations-path priv/repo/optional_migrations/rum_indexing/`"
|
||||
)
|
||||
|
||||
{:error, "RUM Migrations detected"}
|
||||
|
|
@ -140,4 +156,50 @@ defmodule Pleroma.ApplicationRequirements do
|
|||
:ok
|
||||
end
|
||||
end
|
||||
|
||||
defp check_system_commands!(:ok) do
|
||||
filter_commands_statuses = [
|
||||
check_filter(Pleroma.Upload.Filters.Exiftool, "exiftool"),
|
||||
check_filter(Pleroma.Upload.Filters.Mogrify, "mogrify"),
|
||||
check_filter(Pleroma.Upload.Filters.Mogrifun, "mogrify")
|
||||
]
|
||||
|
||||
preview_proxy_commands_status =
|
||||
if !Config.get([:media_preview_proxy, :enabled]) or
|
||||
MediaHelper.missing_dependencies() == [] do
|
||||
true
|
||||
else
|
||||
Logger.error(
|
||||
"The following dependencies required by Media preview proxy " <>
|
||||
"(which is currently enabled) are not installed: " <>
|
||||
inspect(MediaHelper.missing_dependencies())
|
||||
)
|
||||
|
||||
false
|
||||
end
|
||||
|
||||
if Enum.all?([preview_proxy_commands_status | filter_commands_statuses], & &1) do
|
||||
:ok
|
||||
else
|
||||
{:error,
|
||||
"System commands missing. Check logs and see `docs/installation` for more details."}
|
||||
end
|
||||
end
|
||||
|
||||
defp check_system_commands!(result), do: result
|
||||
|
||||
defp check_filter(filter, command_required) do
|
||||
filters = Config.get([Pleroma.Upload, :filters])
|
||||
|
||||
if filter in filters and not Pleroma.Utils.command_available?(command_required) do
|
||||
Logger.error(
|
||||
"#{filter} is specified in list of Pleroma.Upload filters, but the " <>
|
||||
"#{command_required} command is not found"
|
||||
)
|
||||
|
||||
false
|
||||
else
|
||||
true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -33,34 +33,8 @@ defmodule Pleroma.Config.DeprecationWarnings do
|
|||
end
|
||||
end
|
||||
|
||||
def mrf_user_allowlist do
|
||||
config = Config.get(:mrf_user_allowlist)
|
||||
|
||||
if config && Enum.any?(config, fn {k, _} -> is_atom(k) end) do
|
||||
rewritten =
|
||||
Enum.reduce(Config.get(:mrf_user_allowlist), Map.new(), fn {k, v}, acc ->
|
||||
Map.put(acc, to_string(k), v)
|
||||
end)
|
||||
|
||||
Config.put(:mrf_user_allowlist, rewritten)
|
||||
|
||||
Logger.error("""
|
||||
!!!DEPRECATION WARNING!!!
|
||||
As of Pleroma 2.0.7, the `mrf_user_allowlist` setting changed of format.
|
||||
Pleroma 2.1 will remove support for the old format. Please change your configuration to match this:
|
||||
|
||||
config :pleroma, :mrf_user_allowlist, #{inspect(rewritten, pretty: true)}
|
||||
""")
|
||||
|
||||
:error
|
||||
else
|
||||
:ok
|
||||
end
|
||||
end
|
||||
|
||||
def warn do
|
||||
with :ok <- check_hellthread_threshold(),
|
||||
:ok <- mrf_user_allowlist(),
|
||||
:ok <- check_old_mrf_config(),
|
||||
:ok <- check_media_proxy_whitelist_config(),
|
||||
:ok <- check_welcome_message_config(),
|
||||
|
|
@ -83,9 +57,9 @@ defmodule Pleroma.Config.DeprecationWarnings do
|
|||
if use_old_config do
|
||||
Logger.error("""
|
||||
!!!DEPRECATION WARNING!!!
|
||||
Your config is using the old namespace for Welcome messages configuration. You need to change to the new namespace:
|
||||
\n* `config :pleroma, :instance, welcome_user_nickname` is now `config :pleroma, :welcome, :direct_message, :sender_nickname`
|
||||
\n* `config :pleroma, :instance, welcome_message` is now `config :pleroma, :welcome, :direct_message, :message`
|
||||
Your config is using the old namespace for Welcome messages configuration. You need to convert to the new namespace. e.g.,
|
||||
\n* `config :pleroma, :instance, welcome_user_nickname` and `config :pleroma, :instance, welcome_message` are now equal to:
|
||||
\n* `config :pleroma, :welcome, direct_message: [enabled: true, sender_nickname: "NICKNAME", message: "Your welcome message"]`"
|
||||
""")
|
||||
|
||||
:error
|
||||
|
|
@ -148,7 +122,7 @@ defmodule Pleroma.Config.DeprecationWarnings do
|
|||
if timeout = pool_config[:await_up_timeout] do
|
||||
Logger.warn("""
|
||||
!!!DEPRECATION WARNING!!!
|
||||
Your config is using old setting name `await_up_timeout` instead of `connect_timeout`. Setting should work for now, but you are advised to change format to scheme with port to prevent possible issues later.
|
||||
Your config is using old setting `config :pleroma, :connections_pool, await_up_timeout`. Please change to `config :pleroma, :connections_pool, connect_timeout` to ensure compatibility with future releases.
|
||||
""")
|
||||
|
||||
Config.put(:connections_pool, Keyword.put_new(pool_config, :connect_timeout, timeout))
|
||||
|
|
|
|||
|
|
@ -9,6 +9,18 @@ defmodule Pleroma.Helpers.MediaHelper do
|
|||
|
||||
alias Pleroma.HTTP
|
||||
|
||||
require Logger
|
||||
|
||||
def missing_dependencies do
|
||||
Enum.reduce([imagemagick: "convert", ffmpeg: "ffmpeg"], [], fn {sym, executable}, acc ->
|
||||
if Pleroma.Utils.command_available?(executable) do
|
||||
acc
|
||||
else
|
||||
[sym | acc]
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
def image_resize(url, options) do
|
||||
with executable when is_binary(executable) <- System.find_executable("convert"),
|
||||
{:ok, args} <- prepare_image_resize_args(options),
|
||||
|
|
|
|||
12
lib/pleroma/http/web_push.ex
Normal file
12
lib/pleroma/http/web_push.ex
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.HTTP.WebPush do
|
||||
@moduledoc false
|
||||
|
||||
def post(url, payload, headers) do
|
||||
list_headers = Map.to_list(headers)
|
||||
Pleroma.HTTP.post(url, payload, list_headers)
|
||||
end
|
||||
end
|
||||
|
|
@ -813,7 +813,8 @@ defmodule Pleroma.User do
|
|||
def send_welcome_email(_), do: {:ok, :noop}
|
||||
|
||||
@spec try_send_confirmation_email(User.t()) :: {:ok, :enqueued | :noop}
|
||||
def try_send_confirmation_email(%User{confirmation_pending: true} = user) do
|
||||
def try_send_confirmation_email(%User{confirmation_pending: true, email: email} = user)
|
||||
when is_binary(email) do
|
||||
if Config.get([:instance, :account_activation_required]) do
|
||||
send_confirmation_email(user)
|
||||
{:ok, :enqueued}
|
||||
|
|
@ -914,9 +915,7 @@ defmodule Pleroma.User do
|
|||
FollowingRelationship.unfollow(follower, followed)
|
||||
{:ok, followed} = update_follower_count(followed)
|
||||
|
||||
{:ok, follower} =
|
||||
follower
|
||||
|> update_following_count()
|
||||
{:ok, follower} = update_following_count(follower)
|
||||
|
||||
{:ok, follower, followed}
|
||||
|
||||
|
|
@ -2071,6 +2070,13 @@ defmodule Pleroma.User do
|
|||
Enum.map(users, &toggle_confirmation/1)
|
||||
end
|
||||
|
||||
@spec need_confirmation(User.t(), boolean()) :: {:ok, User.t()} | {:error, Changeset.t()}
|
||||
def need_confirmation(%User{} = user, bool) do
|
||||
user
|
||||
|> confirmation_changeset(need_confirmation: bool)
|
||||
|> update_and_set_cache()
|
||||
end
|
||||
|
||||
def get_mascot(%{mascot: %{} = mascot}) when not is_nil(mascot) do
|
||||
mascot
|
||||
end
|
||||
|
|
@ -2285,7 +2291,9 @@ defmodule Pleroma.User do
|
|||
|
||||
# if pinned activity was scheduled for deletion, we reschedule it for deletion
|
||||
if data["expires_at"] do
|
||||
{:ok, expires_at, _} = DateTime.from_iso8601(data["expires_at"])
|
||||
# MRF.ActivityExpirationPolicy used UTC timestamps for expires_at in original implementation
|
||||
{:ok, expires_at} =
|
||||
data["expires_at"] |> Pleroma.EctoType.ActivityPub.ObjectValidators.DateTime.cast()
|
||||
|
||||
Pleroma.Workers.PurgeExpiredActivity.enqueue(%{
|
||||
activity_id: id,
|
||||
|
|
|
|||
|
|
@ -110,12 +110,12 @@ defmodule Pleroma.User.Query do
|
|||
where(query, [u], fragment("? && ?", u.tags, ^tags))
|
||||
end
|
||||
|
||||
defp compose_query({:is_admin, _}, query) do
|
||||
where(query, [u], u.is_admin)
|
||||
defp compose_query({:is_admin, bool}, query) do
|
||||
where(query, [u], u.is_admin == ^bool)
|
||||
end
|
||||
|
||||
defp compose_query({:is_moderator, _}, query) do
|
||||
where(query, [u], u.is_moderator)
|
||||
defp compose_query({:is_moderator, bool}, query) do
|
||||
where(query, [u], u.is_moderator == ^bool)
|
||||
end
|
||||
|
||||
defp compose_query({:super_users, _}, query) do
|
||||
|
|
@ -148,6 +148,10 @@ defmodule Pleroma.User.Query do
|
|||
where(query, [u], u.deactivated == ^true)
|
||||
end
|
||||
|
||||
defp compose_query({:confirmation_pending, bool}, query) do
|
||||
where(query, [u], u.confirmation_pending == ^bool)
|
||||
end
|
||||
|
||||
defp compose_query({:need_approval, _}, query) do
|
||||
where(query, [u], u.approval_pending)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -3,8 +3,10 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.User.Search do
|
||||
alias Pleroma.EctoType.ActivityPub.ObjectValidators.Uri, as: UriType
|
||||
alias Pleroma.Pagination
|
||||
alias Pleroma.User
|
||||
|
||||
import Ecto.Query
|
||||
|
||||
@limit 20
|
||||
|
|
@ -19,16 +21,47 @@ defmodule Pleroma.User.Search do
|
|||
|
||||
query_string = format_query(query_string)
|
||||
|
||||
maybe_resolve(resolve, for_user, query_string)
|
||||
# If this returns anything, it should bounce to the top
|
||||
maybe_resolved = maybe_resolve(resolve, for_user, query_string)
|
||||
|
||||
top_user_ids =
|
||||
[]
|
||||
|> maybe_add_resolved(maybe_resolved)
|
||||
|> maybe_add_ap_id_match(query_string)
|
||||
|> maybe_add_uri_match(query_string)
|
||||
|
||||
results =
|
||||
query_string
|
||||
|> search_query(for_user, following)
|
||||
|> search_query(for_user, following, top_user_ids)
|
||||
|> Pagination.fetch_paginated(%{"offset" => offset, "limit" => result_limit}, :offset)
|
||||
|
||||
results
|
||||
end
|
||||
|
||||
defp maybe_add_resolved(list, {:ok, %User{} = user}) do
|
||||
[user.id | list]
|
||||
end
|
||||
|
||||
defp maybe_add_resolved(list, _), do: list
|
||||
|
||||
defp maybe_add_ap_id_match(list, query) do
|
||||
if user = User.get_cached_by_ap_id(query) do
|
||||
[user.id | list]
|
||||
else
|
||||
list
|
||||
end
|
||||
end
|
||||
|
||||
defp maybe_add_uri_match(list, query) do
|
||||
with {:ok, query} <- UriType.cast(query),
|
||||
q = from(u in User, where: u.uri == ^query, select: u.id),
|
||||
users = Pleroma.Repo.all(q) do
|
||||
users ++ list
|
||||
else
|
||||
_ -> list
|
||||
end
|
||||
end
|
||||
|
||||
defp format_query(query_string) do
|
||||
# Strip the beginning @ off if there is a query
|
||||
query_string = String.trim_leading(query_string, "@")
|
||||
|
|
@ -47,7 +80,7 @@ defmodule Pleroma.User.Search do
|
|||
end
|
||||
end
|
||||
|
||||
defp search_query(query_string, for_user, following) do
|
||||
defp search_query(query_string, for_user, following, top_user_ids) do
|
||||
for_user
|
||||
|> base_query(following)
|
||||
|> filter_blocked_user(for_user)
|
||||
|
|
@ -56,13 +89,20 @@ defmodule Pleroma.User.Search do
|
|||
|> filter_internal_users()
|
||||
|> filter_blocked_domains(for_user)
|
||||
|> fts_search(query_string)
|
||||
|> select_top_users(top_user_ids)
|
||||
|> trigram_rank(query_string)
|
||||
|> boost_search_rank(for_user)
|
||||
|> boost_search_rank(for_user, top_user_ids)
|
||||
|> subquery()
|
||||
|> order_by(desc: :search_rank)
|
||||
|> maybe_restrict_local(for_user)
|
||||
end
|
||||
|
||||
defp select_top_users(query, top_user_ids) do
|
||||
from(u in query,
|
||||
or_where: u.id in ^top_user_ids
|
||||
)
|
||||
end
|
||||
|
||||
defp fts_search(query, query_string) do
|
||||
query_string = to_tsquery(query_string)
|
||||
|
||||
|
|
@ -180,7 +220,7 @@ defmodule Pleroma.User.Search do
|
|||
|
||||
defp local_domain, do: Pleroma.Config.get([Pleroma.Web.Endpoint, :url, :host])
|
||||
|
||||
defp boost_search_rank(query, %User{} = for_user) do
|
||||
defp boost_search_rank(query, %User{} = for_user, top_user_ids) do
|
||||
friends_ids = User.get_friends_ids(for_user)
|
||||
followers_ids = User.get_followers_ids(for_user)
|
||||
|
||||
|
|
@ -192,6 +232,7 @@ defmodule Pleroma.User.Search do
|
|||
CASE WHEN (?) THEN (?) * 1.5
|
||||
WHEN (?) THEN (?) * 1.3
|
||||
WHEN (?) THEN (?) * 1.1
|
||||
WHEN (?) THEN 9001
|
||||
ELSE (?) END
|
||||
""",
|
||||
u.id in ^friends_ids and u.id in ^followers_ids,
|
||||
|
|
@ -200,11 +241,26 @@ defmodule Pleroma.User.Search do
|
|||
u.search_rank,
|
||||
u.id in ^followers_ids,
|
||||
u.search_rank,
|
||||
u.id in ^top_user_ids,
|
||||
u.search_rank
|
||||
)
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
defp boost_search_rank(query, _for_user), do: query
|
||||
defp boost_search_rank(query, _for_user, top_user_ids) do
|
||||
from(u in subquery(query),
|
||||
select_merge: %{
|
||||
search_rank:
|
||||
fragment(
|
||||
"""
|
||||
CASE WHEN (?) THEN 9001
|
||||
ELSE (?) END
|
||||
""",
|
||||
u.id in ^top_user_ids,
|
||||
u.search_rank
|
||||
)
|
||||
}
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -30,12 +30,16 @@ defmodule Pleroma.Web.ActivityPub.Relay do
|
|||
end
|
||||
end
|
||||
|
||||
@spec unfollow(String.t()) :: {:ok, Activity.t()} | {:error, any()}
|
||||
def unfollow(target_instance) do
|
||||
@spec unfollow(String.t(), map()) :: {:ok, Activity.t()} | {:error, any()}
|
||||
def unfollow(target_instance, opts \\ %{}) do
|
||||
with %User{} = local_user <- get_actor(),
|
||||
{:ok, %User{} = target_user} <- User.get_or_fetch_by_ap_id(target_instance),
|
||||
{:ok, target_user} <- fetch_target_user(target_instance, opts),
|
||||
{:ok, activity} <- ActivityPub.unfollow(local_user, target_user) do
|
||||
User.unfollow(local_user, target_user)
|
||||
case target_user.id do
|
||||
nil -> User.update_following_count(local_user)
|
||||
_ -> User.unfollow(local_user, target_user)
|
||||
end
|
||||
|
||||
Logger.info("relay: unfollowed instance: #{target_instance}: id=#{activity.data["id"]}")
|
||||
{:ok, activity}
|
||||
else
|
||||
|
|
@ -43,6 +47,14 @@ defmodule Pleroma.Web.ActivityPub.Relay do
|
|||
end
|
||||
end
|
||||
|
||||
defp fetch_target_user(ap_id, opts) do
|
||||
case {opts[:force], User.get_or_fetch_by_ap_id(ap_id)} do
|
||||
{_, {:ok, %User{} = user}} -> {:ok, user}
|
||||
{true, _} -> {:ok, %User{ap_id: ap_id}}
|
||||
{_, error} -> error
|
||||
end
|
||||
end
|
||||
|
||||
@spec publish(any()) :: {:ok, Activity.t()} | {:error, any()}
|
||||
def publish(%Activity{data: %{"type" => "Create"}} = activity) do
|
||||
with %User{} = user <- get_actor(),
|
||||
|
|
|
|||
|
|
@ -515,15 +515,19 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|
|||
end
|
||||
|
||||
def handle_incoming(
|
||||
%{"type" => "Create", "object" => %{"type" => objtype}} = data,
|
||||
%{"type" => "Create", "object" => %{"type" => objtype, "id" => obj_id}} = data,
|
||||
_options
|
||||
)
|
||||
when objtype in ~w{Question Answer ChatMessage Audio Video Event Article} do
|
||||
data = Map.put(data, "object", strip_internal_fields(data["object"]))
|
||||
|
||||
with {:ok, %User{}} <- ObjectValidator.fetch_actor(data),
|
||||
nil <- Activity.get_create_by_object_ap_id(obj_id),
|
||||
{:ok, activity, _} <- Pipeline.common_pipeline(data, local: false) do
|
||||
{:ok, activity}
|
||||
else
|
||||
%Activity{} = activity -> {:ok, activity}
|
||||
e -> e
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -33,11 +33,7 @@ defmodule Pleroma.Web.AdminAPI.RelayController do
|
|||
|
||||
def follow(%{assigns: %{user: admin}, body_params: %{relay_url: target}} = conn, _) do
|
||||
with {:ok, _message} <- Relay.follow(target) do
|
||||
ModerationLog.insert_log(%{
|
||||
action: "relay_follow",
|
||||
actor: admin,
|
||||
target: target
|
||||
})
|
||||
ModerationLog.insert_log(%{action: "relay_follow", actor: admin, target: target})
|
||||
|
||||
json(conn, %{actor: target, followed_back: target in Relay.following()})
|
||||
else
|
||||
|
|
@ -48,13 +44,9 @@ defmodule Pleroma.Web.AdminAPI.RelayController do
|
|||
end
|
||||
end
|
||||
|
||||
def unfollow(%{assigns: %{user: admin}, body_params: %{relay_url: target}} = conn, _) do
|
||||
with {:ok, _message} <- Relay.unfollow(target) do
|
||||
ModerationLog.insert_log(%{
|
||||
action: "relay_unfollow",
|
||||
actor: admin,
|
||||
target: target
|
||||
})
|
||||
def unfollow(%{assigns: %{user: admin}, body_params: %{relay_url: target} = params} = conn, _) do
|
||||
with {:ok, _message} <- Relay.unfollow(target, %{force: params[:force]}) do
|
||||
ModerationLog.insert_log(%{action: "relay_unfollow", actor: admin, target: target})
|
||||
|
||||
json(conn, target)
|
||||
else
|
||||
|
|
|
|||
|
|
@ -115,6 +115,10 @@ defmodule Pleroma.Web.ApiSpec.CastAndValidate do
|
|||
%{reason: :unexpected_field, name: name, path: [name]}, params ->
|
||||
Map.delete(params, name)
|
||||
|
||||
# Filter out empty params
|
||||
%{reason: :invalid_type, path: [name_atom], value: ""}, params ->
|
||||
Map.delete(params, to_string(name_atom))
|
||||
|
||||
%{reason: :invalid_enum, name: nil, path: path, value: value}, params ->
|
||||
path = path |> Enum.reverse() |> tl() |> Enum.reverse() |> list_items_to_string()
|
||||
update_in(params, path, &List.delete(&1, value))
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.RelayOperation do
|
|||
operationId: "AdminAPI.RelayController.unfollow",
|
||||
security: [%{"oAuth" => ["write:follows"]}],
|
||||
parameters: admin_api_params(),
|
||||
requestBody: request_body("Parameters", relay_url()),
|
||||
requestBody: request_body("Parameters", relay_unfollow()),
|
||||
responses: %{
|
||||
200 =>
|
||||
Operation.response("Status", "application/json", %Schema{
|
||||
|
|
@ -91,4 +91,14 @@ defmodule Pleroma.Web.ApiSpec.Admin.RelayOperation do
|
|||
}
|
||||
}
|
||||
end
|
||||
|
||||
defp relay_unfollow do
|
||||
%Schema{
|
||||
type: :object,
|
||||
properties: %{
|
||||
relay_url: %Schema{type: :string, format: :uri},
|
||||
force: %Schema{type: :boolean, default: false}
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ defmodule Pleroma.Web.Push.Impl do
|
|||
@types ["Create", "Follow", "Announce", "Like", "Move"]
|
||||
|
||||
@doc "Performs sending notifications for user subscriptions"
|
||||
@spec perform(Notification.t()) :: list(any) | :error
|
||||
@spec perform(Notification.t()) :: list(any) | :error | {:error, :unknown_type}
|
||||
def perform(
|
||||
%{
|
||||
activity: %{data: %{"type" => activity_type}} = activity,
|
||||
|
|
@ -64,20 +64,20 @@ defmodule Pleroma.Web.Push.Impl do
|
|||
@doc "Push message to web"
|
||||
def push_message(body, sub, api_key, subscription) do
|
||||
case WebPushEncryption.send_web_push(body, sub, api_key) do
|
||||
{:ok, %{status_code: code}} when 400 <= code and code < 500 ->
|
||||
{:ok, %{status: code}} when code in 400..499 ->
|
||||
Logger.debug("Removing subscription record")
|
||||
Repo.delete!(subscription)
|
||||
:ok
|
||||
|
||||
{:ok, %{status_code: code}} when 200 <= code and code < 300 ->
|
||||
{:ok, %{status: code}} when code in 200..299 ->
|
||||
:ok
|
||||
|
||||
{:ok, %{status_code: code}} ->
|
||||
{:ok, %{status: code}} ->
|
||||
Logger.error("Web Push Notification failed with code: #{code}")
|
||||
:error
|
||||
|
||||
_ ->
|
||||
Logger.error("Web Push Notification failed with unknown error")
|
||||
error ->
|
||||
Logger.error("Web Push Notification failed with #{inspect(error)}")
|
||||
:error
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue