# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ActivityPub.ActivityPub do
alias Pleroma.Web.Streamer
alias Pleroma.Web.WebFinger
alias Pleroma.Workers.BackgroundWorker
+ alias Pleroma.Workers.PollWorker
import Ecto.Query
import Pleroma.Web.ActivityPub.Utils
require Logger
require Pleroma.Constants
+ @behaviour Pleroma.Web.ActivityPub.ActivityPub.Persisting
+ @behaviour Pleroma.Web.ActivityPub.ActivityPub.Streaming
+
defp get_recipients(%{"type" => "Create"} = data) do
to = Map.get(data, "to", [])
cc = Map.get(data, "cc", [])
defp check_actor_is_active(actor) when is_binary(actor) do
case User.get_cached_by_ap_id(actor) do
- %User{deactivated: deactivated} -> not deactivated
+ %User{is_active: true} -> true
_ -> false
end
end
defp increase_replies_count_if_reply(_create_data), do: :noop
@object_types ~w[ChatMessage Question Answer Audio Video Event Article]
- @spec persist(map(), keyword()) :: {:ok, Activity.t() | Object.t()}
+ @impl true
def persist(%{"type" => type} = object, meta) when type in @object_types do
with {:ok, object} <- Object.create(object) do
{:ok, object, meta}
end
end
+ @impl true
def persist(object, meta) do
with local <- Keyword.fetch!(meta, :local),
{recipients, _, _} <- get_recipients(object),
# Splice in the child object if we have one.
activity = Maps.put_if_present(activity, :object, object)
- BackgroundWorker.enqueue("fetch_data_for_activity", %{"activity_id" => activity.id})
+ ConcurrentLimiter.limit(Pleroma.Web.RichMedia.Helpers, fn ->
+ Task.start(fn -> Pleroma.Web.RichMedia.Helpers.fetch_data_for_activity(activity) end)
+ end)
{:ok, activity}
else
Streamer.stream("participation", participations)
end
+ @impl true
def stream_out_participations(%Object{data: %{"context" => context}}, user) do
with %Conversation{} = conversation <- Conversation.get_for_ap_id(context) do
conversation = Repo.preload(conversation, :participations)
end
end
+ @impl true
def stream_out_participations(_, _), do: :noop
+ @impl true
def stream_out(%Activity{data: %{"type" => data_type}} = activity)
when data_type in ["Create", "Announce", "Delete"] do
activity
|> Streamer.stream(activity)
end
+ @impl true
def stream_out(_activity) do
:noop
end
{:quick_insert, false, activity} <- {:quick_insert, quick_insert?, activity},
{:ok, _actor} <- increase_note_count_if_public(actor, activity),
_ <- notify_and_stream(activity),
+ :ok <- maybe_schedule_poll_notifications(activity),
:ok <- maybe_federate(activity) do
{:ok, activity}
else
end
end
+ defp maybe_schedule_poll_notifications(activity) do
+ PollWorker.schedule_poll_end(activity)
+ :ok
+ end
+
@spec listen(map()) :: {:ok, Activity.t()} | {:error, any()}
def listen(%{to: to, actor: actor, context: context, object: object} = params) do
additional = params[:additional] || %{}
:ok <-
maybe_federate(stripped_activity) do
User.all_superusers()
+ |> Enum.filter(fn user -> user.ap_id != actor end)
|> Enum.filter(fn user -> not is_nil(user.email) end)
|> Enum.each(fn superuser ->
superuser
|> Enum.reverse()
end
- def fetch_user_activities(user, reading_user, params \\ %{}) do
+ def fetch_user_activities(user, reading_user, params \\ %{})
+
+ def fetch_user_activities(user, reading_user, %{total: true} = params) do
+ result = fetch_activities_for_user(user, reading_user, params)
+
+ Keyword.put(result, :items, Enum.reverse(result[:items]))
+ end
+
+ def fetch_user_activities(user, reading_user, params) do
+ user
+ |> fetch_activities_for_user(reading_user, params)
+ |> Enum.reverse()
+ end
+
+ defp fetch_activities_for_user(user, reading_user, params) do
params =
params
|> Map.put(:type, ["Create", "Announce"])
|> Map.put(:muting_user, reading_user)
end
+ pagination_type = Map.get(params, :pagination_type) || :keyset
+
%{
godmode: params[:godmode],
reading_user: reading_user
}
|> user_activities_recipients()
- |> fetch_activities(params)
- |> Enum.reverse()
+ |> fetch_activities(params, pagination_type)
+ end
+
+ def fetch_statuses(reading_user, %{total: true} = params) do
+ result = fetch_activities_for_reading_user(reading_user, params)
+ Keyword.put(result, :items, Enum.reverse(result[:items]))
end
def fetch_statuses(reading_user, params) do
+ reading_user
+ |> fetch_activities_for_reading_user(params)
+ |> Enum.reverse()
+ end
+
+ defp fetch_activities_for_reading_user(reading_user, params) do
params = Map.put(params, :type, ["Create", "Announce"])
%{
}
|> user_activities_recipients()
|> fetch_activities(params, :offset)
- |> Enum.reverse()
end
defp user_activities_recipients(%{godmode: true}), do: []
defp restrict_local(query, _), do: query
+ defp restrict_remote(query, %{remote: true}) do
+ from(activity in query, where: activity.local == false)
+ end
+
+ defp restrict_remote(query, _), do: query
+
defp restrict_actor(query, %{actor_id: actor_id}) do
from(activity in query, where: activity.actor == ^actor_id)
end
|> restrict_tag_all(opts)
|> restrict_since(opts)
|> restrict_local(opts)
+ |> restrict_remote(opts)
|> restrict_actor(opts)
|> restrict_type(opts)
|> restrict_state(opts)