Merge develop

This commit is contained in:
Roman Chvanikov 2019-07-09 21:21:09 +03:00
commit 371d39e160
224 changed files with 2317 additions and 678 deletions

View file

@ -7,7 +7,7 @@ defmodule Pleroma.User.Query do
User query builder module. Builds query from new query or another user query.
## Example:
query = Pleroma.User.Query(%{nickname: "nickname"})
query = Pleroma.User.Query.build(%{nickname: "nickname"})
another_query = Pleroma.User.Query.build(query, %{email: "email@example.com"})
Pleroma.Repo.all(query)
Pleroma.Repo.all(another_query)
@ -47,7 +47,10 @@ defmodule Pleroma.User.Query do
friends: User.t(),
recipients_from_activity: [String.t()],
nickname: [String.t()],
ap_id: [String.t()]
ap_id: [String.t()],
order_by: term(),
select: term(),
limit: pos_integer()
}
| %{}
@ -141,6 +144,18 @@ defmodule Pleroma.User.Query do
where(query, [u], u.ap_id in ^to or fragment("? && ?", u.following, ^to))
end
defp compose_query({:order_by, key}, query) do
order_by(query, [u], field(u, ^key))
end
defp compose_query({:select, keys}, query) do
select(query, [u], ^keys)
end
defp compose_query({:limit, limit}, query) do
limit(query, ^limit)
end
defp compose_query(_unsupported_param, query), do: query
defp prepare_tag_criteria(tag, query) do

View file

@ -43,6 +43,8 @@ defmodule Pleroma.User.Search do
defp search_query(query_string, for_user, following) do
for_user
|> base_query(following)
|> filter_blocked_user(for_user)
|> filter_blocked_domains(for_user)
|> search_subqueries(query_string)
|> union_subqueries
|> distinct_query()
@ -55,6 +57,25 @@ defmodule Pleroma.User.Search do
defp base_query(_user, false), do: User
defp base_query(user, true), do: User.get_followers_query(user)
defp filter_blocked_user(query, %User{info: %{blocks: blocks}})
when length(blocks) > 0 do
from(q in query, where: not (q.ap_id in ^blocks))
end
defp filter_blocked_user(query, _), do: query
defp filter_blocked_domains(query, %User{info: %{domain_blocks: domain_blocks}})
when length(domain_blocks) > 0 do
domains = Enum.join(domain_blocks, ",")
from(
q in query,
where: fragment("substring(ap_id from '.*://([^/]*)') NOT IN (?)", ^domains)
)
end
defp filter_blocked_domains(query, _), do: query
defp paginate(query, limit, offset) do
from(q in query, limit: ^limit, offset: ^offset)
end
@ -129,7 +150,7 @@ defmodule Pleroma.User.Search do
@spec fts_search_subquery(User.t() | Ecto.Query.t(), String.t()) :: Ecto.Query.t()
defp fts_search_subquery(query, term) do
processed_query =
term
String.trim_trailing(term, "@" <> local_domain())
|> String.replace(~r/\W+/, " ")
|> String.trim()
|> String.split()
@ -171,6 +192,8 @@ defmodule Pleroma.User.Search do
@spec trigram_search_subquery(User.t() | Ecto.Query.t(), String.t()) :: Ecto.Query.t()
defp trigram_search_subquery(query, term) do
term = String.trim_trailing(term, "@" <> local_domain())
from(
u in query,
select_merge: %{
@ -188,4 +211,6 @@ defmodule Pleroma.User.Search do
)
|> User.restrict_deactivated()
end
defp local_domain, do: Pleroma.Config.get([Pleroma.Web.Endpoint, :url, :host])
end

View file

@ -0,0 +1,60 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.User.Synchronization do
alias Pleroma.HTTP
alias Pleroma.User
@spec call([User.t()], map(), keyword()) :: {User.t(), map()}
def call(users, errors, opts \\ []) do
do_call(users, errors, opts)
end
defp do_call([user | []], errors, opts) do
updated = fetch_counters(user, errors, opts)
{user, updated}
end
defp do_call([user | others], errors, opts) do
updated = fetch_counters(user, errors, opts)
do_call(others, updated, opts)
end
defp fetch_counters(user, errors, opts) do
%{host: host} = URI.parse(user.ap_id)
info = %{}
{following, errors} = fetch_counter(user.ap_id <> "/following", host, errors, opts)
info = if following, do: Map.put(info, :following_count, following), else: info
{followers, errors} = fetch_counter(user.ap_id <> "/followers", host, errors, opts)
info = if followers, do: Map.put(info, :follower_count, followers), else: info
User.set_info_cache(user, info)
errors
end
defp available_domain?(domain, errors, opts) do
max_retries = Keyword.get(opts, :max_retries, 3)
not (Map.has_key?(errors, domain) && errors[domain] >= max_retries)
end
defp fetch_counter(url, host, errors, opts) do
with true <- available_domain?(host, errors, opts),
{:ok, %{body: body, status: code}} when code in 200..299 <-
HTTP.get(
url,
[{:Accept, "application/activity+json"}]
),
{:ok, data} <- Jason.decode(body) do
{data["totalItems"], errors}
else
false ->
{nil, errors}
_ ->
{nil, Map.update(errors, host, 1, &(&1 + 1))}
end
end
end

View file

@ -0,0 +1,32 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-onl
defmodule Pleroma.User.SynchronizationWorker do
use GenServer
def start_link do
config = Pleroma.Config.get([:instance, :external_user_synchronization])
if config[:enabled] do
GenServer.start_link(__MODULE__, interval: config[:interval])
else
:ignore
end
end
def init(opts) do
schedule_next(opts)
{:ok, opts}
end
def handle_info(:sync_follow_counters, opts) do
Pleroma.User.sync_follow_counter()
schedule_next(opts)
{:noreply, opts}
end
defp schedule_next(opts) do
Process.send_after(self(), :sync_follow_counters, opts[:interval])
end
end