X-Git-Url: https://git.squeep.com/?a=blobdiff_plain;f=lib%2Fpleroma%2Fweb%2Factivity_pub%2Fside_effects.ex;h=9b17eba953382a2d5d9c215900b4fab8d07240b7;hb=92d3742072f4d8f1b79e142ccba2c558fcb569d9;hp=7c99c539d1141772aa0d4e7262ee53c463bbd10d;hpb=0b1c05ca1e387d4a929dce3cac7214fdaf1c2444;p=akkoma diff --git a/lib/pleroma/web/activity_pub/side_effects.ex b/lib/pleroma/web/activity_pub/side_effects.ex index 7c99c539d..9b17eba95 100644 --- a/lib/pleroma/web/activity_pub/side_effects.ex +++ b/lib/pleroma/web/activity_pub/side_effects.ex @@ -10,7 +10,6 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do collection, and so on. """ alias Pleroma.Activity - alias Pleroma.Activity.Ir.Topics alias Pleroma.Chat alias Pleroma.Chat.MessageReference alias Pleroma.FollowingRelationship @@ -29,11 +28,12 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do require Logger @cachex Pleroma.Config.get([:cachex, :provider], Cachex) - @ap_streamer Pleroma.Config.get([:side_effects, :ap_streamer], ActivityPub) @logger Pleroma.Config.get([:side_effects, :logger], Logger) @behaviour Pleroma.Web.ActivityPub.SideEffects.Handling + defp ap_streamer, do: Pleroma.Config.get([:side_effects, :ap_streamer], ActivityPub) + @impl true def handle(object, meta \\ []) @@ -199,11 +199,25 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do %User{} = user <- User.get_cached_by_ap_id(activity.data["actor"]) do {:ok, notifications} = Notification.create_notifications(activity, do_send: false) {:ok, _user} = ActivityPub.increase_note_count_if_public(user, object) + {:ok, _user} = ActivityPub.update_last_status_at_if_public(user, object) - if in_reply_to = object.data["inReplyTo"] && object.data["type"] != "Answer" do + if in_reply_to = object.data["type"] != "Answer" && object.data["inReplyTo"] do Object.increase_replies_count(in_reply_to) end + reply_depth = (meta[:depth] || 0) + 1 + + # FIXME: Force inReplyTo to replies + if Pleroma.Web.Federator.allowed_thread_distance?(reply_depth) and + object.data["replies"] != nil do + for reply_id <- object.data["replies"] do + Pleroma.Workers.RemoteFetcherWorker.enqueue("fetch_remote", %{ + "id" => reply_id, + "depth" => reply_depth + }) + end + end + ConcurrentLimiter.limit(Pleroma.Web.RichMedia.Helpers, fn -> Task.start(fn -> Pleroma.Web.RichMedia.Helpers.fetch_data_for_activity(activity) end) end) @@ -212,6 +226,8 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do meta |> add_notifications(notifications) + ap_streamer().stream_out(activity) + {:ok, activity, meta} else e -> Repo.rollback(e) @@ -232,9 +248,7 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do if !User.is_internal_user?(user) do Notification.create_notifications(object) - object - |> Topics.get_activity_topics() - |> Streamer.stream(object) + ap_streamer().stream_out(object) end {:ok, object, meta} @@ -277,10 +291,10 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do result = case deleted_object do %Object{} -> - with {:ok, deleted_object, activity} <- Object.delete(deleted_object), + with {:ok, deleted_object, _activity} <- Object.delete(deleted_object), {_, actor} when is_binary(actor) <- {:actor, deleted_object.data["actor"]}, %User{} = user <- User.get_cached_by_ap_id(actor) do - User.remove_pinnned_activity(user, activity) + User.remove_pinned_object_id(user, deleted_object.data["id"]) {:ok, user} = ActivityPub.decrease_note_count_if_public(user, deleted_object) @@ -290,8 +304,8 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do MessageReference.delete_for_object(deleted_object) - @ap_streamer.stream_out(object) - @ap_streamer.stream_out_participations(deleted_object, user) + ap_streamer().stream_out(object) + ap_streamer().stream_out_participations(deleted_object, user) :ok else {:actor, _} -> @@ -313,6 +327,63 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do end end + # Tasks this handles: + # - adds pin to user + # - removes expiration job for pinned activity, if was set for expiration + @impl true + def handle(%{data: %{"type" => "Add"} = data} = object, meta) do + with %User{} = user <- User.get_cached_by_ap_id(data["actor"]), + {:ok, _user} <- User.add_pinned_object_id(user, data["object"]) do + # if pinned activity was scheduled for deletion, we remove job + if expiration = Pleroma.Workers.PurgeExpiredActivity.get_expiration(meta[:activity_id]) do + Oban.cancel_job(expiration.id) + end + + {:ok, object, meta} + else + nil -> + {:error, :user_not_found} + + {:error, changeset} -> + if changeset.errors[:pinned_objects] do + {:error, :pinned_statuses_limit_reached} + else + changeset.errors + end + end + end + + # Tasks this handles: + # - removes pin from user + # - removes corresponding Add activity + # - if activity had expiration, recreates activity expiration job + @impl true + def handle(%{data: %{"type" => "Remove"} = data} = object, meta) do + with %User{} = user <- User.get_cached_by_ap_id(data["actor"]), + {:ok, _user} <- User.remove_pinned_object_id(user, data["object"]) do + data["object"] + |> Activity.add_by_params_query(user.ap_id, user.featured_address) + |> Repo.delete_all() + + # if pinned activity was scheduled for deletion, we reschedule it for deletion + if meta[:expires_at] do + # MRF.ActivityExpirationPolicy used UTC timestamps for expires_at in original implementation + {:ok, expires_at} = + Pleroma.EctoType.ActivityPub.ObjectValidators.DateTime.cast(meta[:expires_at]) + + Pleroma.Workers.PurgeExpiredActivity.enqueue(%{ + activity_id: meta[:activity_id], + expires_at: expires_at + }) + end + + {:ok, object, meta} + else + nil -> {:error, :user_not_found} + error -> error + end + end + # Nothing to do @impl true def handle(object, meta) do @@ -374,7 +445,7 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do end def handle_object_creation(%{"type" => objtype} = object, _activity, meta) - when objtype in ~w[Audio Video Event Article] do + when objtype in ~w[Audio Video Event Article Note Page] do with {:ok, object, meta} <- Pipeline.common_pipeline(object, meta) do {:ok, object, meta} end @@ -467,6 +538,24 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do end @impl true + def handle_after_transaction(%Pleroma.Activity{data: %{"type" => "Create"}} = activity) do + Pleroma.Elasticsearch.put_by_id(:activity, activity.id) + end + + def handle_after_transaction(%Pleroma.Activity{ + data: %{"type" => "Delete", "deleted_activity_id" => id} + }) do + Pleroma.Elasticsearch.delete_by_id(:activity, id) + end + + def handle_after_transaction(%Pleroma.Activity{}) do + :ok + end + + def handle_after_transaction(%Pleroma.Object{}) do + :ok + end + def handle_after_transaction(meta) do meta |> send_notifications()