Pipeline Ingestion: Audio (Part 2)
authorHaelwenn (lanodan) Monnier <contact@hacktivis.me>
Tue, 18 Aug 2020 22:05:48 +0000 (00:05 +0200)
committerHaelwenn (lanodan) Monnier <contact@hacktivis.me>
Tue, 18 Aug 2020 22:06:31 +0000 (00:06 +0200)
lib/pleroma/web/activity_pub/activity_pub.ex
lib/pleroma/web/activity_pub/object_validators/attachment_validator.ex
lib/pleroma/web/activity_pub/object_validators/audio_validator.ex
lib/pleroma/web/activity_pub/object_validators/create_generic_validator.ex
lib/pleroma/web/activity_pub/object_validators/note_validator.ex
lib/pleroma/web/activity_pub/object_validators/question_validator.ex
lib/pleroma/web/activity_pub/transmogrifier.ex
test/fixtures/tesla_mock/funkwhale_create_audio.json [new file with mode: 0644]
test/web/activity_pub/transmogrifier/audio_handling_test.exs
test/web/activity_pub/transmogrifier/question_handling_test.exs

index bde1fe708a35a8f0ac310cc18a1eb3fe6d156d9a..db18674940f74670f774aa8f5355aebc0e6f56f7 100644 (file)
@@ -85,7 +85,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
 
   defp increase_replies_count_if_reply(_create_data), do: :noop
 
-  @object_types ["ChatMessage", "Question", "Answer"]
+  @object_types ~w[ChatMessage Question Answer Audio]
   @spec persist(map(), keyword()) :: {:ok, Activity.t() | Object.t()}
   def persist(%{"type" => type} = object, meta) when type in @object_types do
     with {:ok, object} <- Object.create(object) do
index f53bb02bec8d3261ec76e00cf1948b4907fb5c9e..c8b1482802dd1b01202e3ced6e2d1ee23a46f88e 100644 (file)
@@ -41,34 +41,34 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidator do
   end
 
   def fix_media_type(data) do
-    data =
-      data
-      |> Map.put_new("mediaType", data["mimeType"])
+    data = Map.put_new(data, "mediaType", data["mimeType"])
 
     if MIME.valid?(data["mediaType"]) do
       data
     else
-      data
-      |> Map.put("mediaType", "application/octet-stream")
+      Map.put(data, "mediaType", "application/octet-stream")
     end
   end
 
-  def fix_url(data) do
-    case data["url"] do
-      url when is_binary(url) ->
-        data
-        |> Map.put(
-          "url",
-          [
-            %{
-              "href" => url,
-              "type" => "Link",
-              "mediaType" => data["mediaType"]
-            }
-          ]
-        )
-
-      _ ->
+  defp handle_href(href, mediaType) do
+    [
+      %{
+        "href" => href,
+        "type" => "Link",
+        "mediaType" => mediaType
+      }
+    ]
+  end
+
+  defp fix_url(data) do
+    cond do
+      is_binary(data["url"]) ->
+        Map.put(data, "url", handle_href(data["url"], data["mediaType"]))
+
+      is_binary(data["href"]) and data["url"] == nil ->
+        Map.put(data, "url", handle_href(data["href"], data["mediaType"]))
+
+      true ->
         data
     end
   end
index 5d9bf345f512d9bf0a9a5e7c51cb08019a4fdbb2..d1869f18809ad7e8a068246546a9da004b7f841b 100644 (file)
@@ -41,7 +41,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AudioValidator do
     field(:like_count, :integer, default: 0)
     field(:announcement_count, :integer, default: 0)
     field(:inReplyTo, :string)
-    field(:uri, ObjectValidators.Uri)
+    field(:url, ObjectValidators.Uri)
     # short identifier for PleromaFE to group statuses by context
     field(:context_id, :integer)
 
@@ -66,10 +66,24 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AudioValidator do
     |> changeset(data)
   end
 
+  defp fix_url(%{"url" => url} = data) when is_list(url) do
+    attachment =
+      Enum.find(url, fn x -> is_map(x) and String.starts_with?(x["mimeType"], "audio/") end)
+
+    link_element = Enum.find(url, fn x -> is_map(x) and x["mimeType"] == "text/html" end)
+
+    data
+    |> Map.put("attachment", [attachment])
+    |> Map.put("url", link_element["href"])
+  end
+
+  defp fix_url(data), do: data
+
   defp fix(data) do
     data
     |> CommonFixes.fix_defaults()
     |> CommonFixes.fix_attribution()
+    |> fix_url()
   end
 
   def changeset(struct, data) do
@@ -83,7 +97,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AudioValidator do
   def validate_data(data_cng) do
     data_cng
     |> validate_inclusion(:type, ["Audio"])
-    |> validate_required([:id, :actor, :attributedTo, :type, :context])
+    |> validate_required([:id, :actor, :attributedTo, :type, :context, :attachment])
     |> CommonValidations.validate_any_presence([:cc, :to])
     |> CommonValidations.validate_fields_match([:actor, :attributedTo])
     |> CommonValidations.validate_actor_presence()
index 60868eae08ac83c1fd326227bdae9548d97b777f..b3dbeea5720227abb7613382f2827c3936bace2b 100644 (file)
@@ -61,9 +61,20 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CreateGenericValidator do
     end
   end
 
+  defp fix_addressing(data, meta) do
+    if object = meta[:object_data] do
+      data
+      |> Map.put_new("to", object["to"] || [])
+      |> Map.put_new("cc", object["cc"] || [])
+    else
+      data
+    end
+  end
+
   defp fix(data, meta) do
     data
     |> fix_context(meta)
+    |> fix_addressing(meta)
   end
 
   def validate_data(cng, meta \\ []) do
index 14ae29cb6a7e58151ed59a9eee64e90d8ad92603..3e1f13a8821207a34c63c79422dfa3ef90a1a45d 100644 (file)
@@ -35,7 +35,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.NoteValidator do
     field(:like_count, :integer, default: 0)
     field(:announcement_count, :integer, default: 0)
     field(:inReplyTo, ObjectValidators.ObjectID)
-    field(:uri, ObjectValidators.Uri)
+    field(:url, ObjectValidators.Uri)
 
     field(:likes, {:array, :string}, default: [])
     field(:announcements, {:array, :string}, default: [])
index a7ca42b2fa3c71047f95edf18a45a76207085c14..712047424665ce5729423729d359575ed1397b83 100644 (file)
@@ -43,7 +43,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.QuestionValidator do
     field(:like_count, :integer, default: 0)
     field(:announcement_count, :integer, default: 0)
     field(:inReplyTo, ObjectValidators.ObjectID)
-    field(:uri, ObjectValidators.Uri)
+    field(:url, ObjectValidators.Uri)
     # short identifier for PleromaFE to group statuses by context
     field(:context_id, :integer)
 
index 6be17e0eda7b30d8076b7489d4f04be27941791b..7c860af9f1747ebde2bd25b1b9596eab3f19def3 100644 (file)
@@ -276,13 +276,12 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
     Map.put(object, "url", url["href"])
   end
 
-  def fix_url(%{"type" => object_type, "url" => url} = object)
-      when object_type in ["Video", "Audio"] and is_list(url) do
+  def fix_url(%{"type" => "Video", "url" => url} = object) when is_list(url) do
     attachment =
       Enum.find(url, fn x ->
         media_type = x["mediaType"] || x["mimeType"] || ""
 
-        is_map(x) and String.starts_with?(media_type, ["audio/", "video/"])
+        is_map(x) and String.starts_with?(media_type, "video/")
       end)
 
     link_element =
diff --git a/test/fixtures/tesla_mock/funkwhale_create_audio.json b/test/fixtures/tesla_mock/funkwhale_create_audio.json
new file mode 100644 (file)
index 0000000..fe6059c
--- /dev/null
@@ -0,0 +1,58 @@
+{
+  "@context": [
+    "https://www.w3.org/ns/activitystreams",
+    "https://w3id.org/security/v1",
+    "https://funkwhale.audio/ns",
+    {
+      "manuallyApprovesFollowers": "as:manuallyApprovesFollowers",
+      "Hashtag": "as:Hashtag"
+    }
+  ],
+  "type": "Create",
+  "id": "https://channels.tests.funkwhale.audio/federation/music/uploads/42342395-0208-4fee-a38d-259a6dae0871/activity",
+  "actor": "https://channels.tests.funkwhale.audio/federation/actors/compositions",
+  "object": {
+    "id": "https://channels.tests.funkwhale.audio/federation/music/uploads/42342395-0208-4fee-a38d-259a6dae0871",
+    "type": "Audio",
+    "name": "Compositions - Test Audio for Pleroma",
+    "attributedTo": "https://channels.tests.funkwhale.audio/federation/actors/compositions",
+    "published": "2020-03-11T10:01:52.714918+00:00",
+    "to": "https://www.w3.org/ns/activitystreams#Public",
+    "url": [
+      {
+        "type": "Link",
+        "mimeType": "audio/ogg",
+        "href": "https://channels.tests.funkwhale.audio/api/v1/listen/3901e5d8-0445-49d5-9711-e096cf32e515/?upload=42342395-0208-4fee-a38d-259a6dae0871&download=false"
+      },
+      {
+        "type": "Link",
+        "mimeType": "text/html",
+        "href": "https://channels.tests.funkwhale.audio/library/tracks/74"
+      }
+    ],
+    "content": "<p>This is a test Audio for Pleroma.</p>",
+    "mediaType": "text/html",
+    "tag": [
+      {
+        "type": "Hashtag",
+        "name": "#funkwhale"
+      },
+      {
+        "type": "Hashtag",
+        "name": "#test"
+      },
+      {
+        "type": "Hashtag",
+        "name": "#tests"
+      }
+    ],
+    "summary": "#funkwhale #test #tests",
+    "@context": [
+      "https://www.w3.org/ns/activitystreams",
+      "https://w3id.org/security/v1",
+      {
+        "manuallyApprovesFollowers": "as:manuallyApprovesFollowers"
+      }
+    ]
+  }
+}
index c74a9c45d32dbeb7d4709df42d9fca7d417aaeec..9cb53c48b5f0b8f4ff7a82a96083e4278012b441 100644 (file)
@@ -12,6 +12,11 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.AudioHandlingTest do
 
   import Pleroma.Factory
 
+  setup_all do
+    Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
+    :ok
+  end
+
   test "it works for incoming listens" do
     _user = insert(:user, ap_id: "http://mastodon.example.org/users/admin")
 
@@ -42,4 +47,34 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.AudioHandlingTest do
     assert object.data["album"] == "lain radio"
     assert object.data["length"] == 180_000
   end
+
+  test "Funkwhale Audio object" do
+    data = File.read!("test/fixtures/tesla_mock/funkwhale_create_audio.json") |> Poison.decode!()
+
+    {:ok, %Activity{local: false} = activity} = Transmogrifier.handle_incoming(data)
+
+    assert object = Object.normalize(activity, false)
+
+    assert object.data["to"] == ["https://www.w3.org/ns/activitystreams#Public"]
+
+    assert object.data["cc"] == []
+
+    assert object.data["url"] == "https://channels.tests.funkwhale.audio/library/tracks/74"
+
+    assert object.data["attachment"] == [
+             %{
+               "mediaType" => "audio/ogg",
+               "type" => "Link",
+               "name" => nil,
+               "url" => [
+                 %{
+                   "href" =>
+                     "https://channels.tests.funkwhale.audio/api/v1/listen/3901e5d8-0445-49d5-9711-e096cf32e515/?upload=42342395-0208-4fee-a38d-259a6dae0871&download=false",
+                   "mediaType" => "audio/ogg",
+                   "type" => "Link"
+                 }
+               ]
+             }
+           ]
+  end
 end
index 9fb965d7facda0efba6daf8658fc5fb9673d8451..c82361828883ef0b17fb7ede4f46a6194b52ec7d 100644 (file)
@@ -24,6 +24,8 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.QuestionHandlingTest do
 
     object = Object.normalize(activity, false)
 
+    assert object.data["url"] == "https://mastodon.sdf.org/@rinpatch/102070944809637304"
+
     assert object.data["closed"] == "2019-05-11T09:03:36Z"
 
     assert object.data["context"] == activity.data["context"]