[#1505] Background fetching of incoming activities' `replies` collections.
authorIvan Tashkinov <ivantashkinov@gmail.com>
Sat, 25 Jan 2020 07:47:30 +0000 (10:47 +0300)
committerIvan Tashkinov <ivantashkinov@gmail.com>
Sat, 25 Jan 2020 07:47:30 +0000 (10:47 +0300)
config/config.exs
lib/pleroma/web/activity_pub/transmogrifier.ex
lib/pleroma/workers/remote_fetcher_worker.ex [new file with mode: 0644]
test/support/oban_helpers.ex
test/web/activity_pub/transmogrifier_test.exs

index 60642c467489d7eecd0be5c9f5a38d18222522c8..5f72df8a0aa3c274f8d5e73522e0d8ad1f120bf7 100644 (file)
@@ -501,6 +501,7 @@ config :pleroma, Oban,
     transmogrifier: 20,
     scheduled_activities: 10,
     background: 5,
+    remote_fetcher: 2,
     attachments_cleanup: 5
   ]
 
index 9e712ab75b2257d45411bde100e1e43af622d3b0..d129334c2a075fcd37d06b5a14d8d68f323fafbe 100644 (file)
@@ -424,7 +424,13 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
           ])
       }
 
-      ActivityPub.create(params)
+      with {:ok, created_activity} <- ActivityPub.create(params) do
+        for reply_id <- replies(object) do
+          Pleroma.Workers.RemoteFetcherWorker.enqueue("fetch_remote", %{"id" => reply_id})
+        end
+
+        {:ok, created_activity}
+      end
     else
       %Activity{} = activity -> {:ok, activity}
       _e -> :error
@@ -946,6 +952,13 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
     Map.merge(obj, %{"replies" => replies_collection})
   end
 
+  def replies(%{"replies" => replies = %{}}) do
+    replies = with %{} <- replies["first"], do: replies["first"], else: (_ -> replies)
+    replies["items"] || []
+  end
+
+  def replies(_), do: []
+
   # Prepares the object of an outgoing create activity.
   def prepare_object(object) do
     object
diff --git a/lib/pleroma/workers/remote_fetcher_worker.ex b/lib/pleroma/workers/remote_fetcher_worker.ex
new file mode 100644 (file)
index 0000000..60eafe2
--- /dev/null
@@ -0,0 +1,20 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Workers.RemoteFetcherWorker do
+  alias Pleroma.Object.Fetcher
+
+  use Pleroma.Workers.WorkerHelper, queue: "remote_fetcher"
+
+  @impl Oban.Worker
+  def perform(
+        %{
+          "op" => "fetch_remote",
+          "id" => id
+        },
+        _job
+      ) do
+    Fetcher.fetch_object_from_id!(id)
+  end
+end
index 72792c0648a89a7f5d9a8df2199dfe74665cf4c5..0e3b654df304fad1632d0a4a808951ceea17978c 100644 (file)
@@ -9,6 +9,10 @@ defmodule Pleroma.Tests.ObanHelpers do
 
   alias Pleroma.Repo
 
+  def wipe_all do
+    Repo.delete_all(Oban.Job)
+  end
+
   def perform_all do
     Oban.Job
     |> Repo.all()
index 418b8a1cae1092daafbae56536107b119a4083a3..0fefb60da7d4304ec0a86b730d14c244d54b5b9c 100644 (file)
@@ -3,7 +3,9 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
+  use Oban.Testing, repo: Pleroma.Repo
   use Pleroma.DataCase
+
   alias Pleroma.Activity
   alias Pleroma.Object
   alias Pleroma.Object.Fetcher
@@ -1329,6 +1331,52 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
     end
   end
 
+  describe "handle_incoming:`replies` handling" do
+    setup do
+      data =
+        File.read!("test/fixtures/mastodon-post-activity.json")
+        |> Poison.decode!()
+
+      items = ["https://shitposter.club/notice/2827873", "https://shitposter.club/notice/7387606"]
+      collection = %{"items" => items}
+      %{data: data, items: items, collection: collection}
+    end
+
+    test "it schedules background fetching of wrapped `replies` collection items", %{
+      data: data,
+      items: items,
+      collection: collection
+    } do
+      replies = %{"first" => collection}
+
+      object = Map.put(data["object"], "replies", replies)
+      data = Map.put(data, "object", object)
+      {:ok, _activity} = Transmogrifier.handle_incoming(data)
+
+      for id <- items do
+        job_args = %{"op" => "fetch_remote", "id" => id}
+        assert_enqueued(worker: Pleroma.Workers.RemoteFetcherWorker, args: job_args)
+      end
+    end
+
+    test "it schedules background fetching of unwrapped `replies` collection items", %{
+      data: data,
+      items: items,
+      collection: collection
+    } do
+      replies = collection
+
+      object = Map.put(data["object"], "replies", replies)
+      data = Map.put(data, "object", object)
+      {:ok, _activity} = Transmogrifier.handle_incoming(data)
+
+      for id <- items do
+        job_args = %{"op" => "fetch_remote", "id" => id}
+        assert_enqueued(worker: Pleroma.Workers.RemoteFetcherWorker, args: job_args)
+      end
+    end
+  end
+
   describe "prepare outgoing" do
     test "it inlines private announced objects" do
       user = insert(:user)