@@ -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 | |||
@@ -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 | |||
@@ -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() | |||
@@ -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 | |||
@@ -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: []) | |||
@@ -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) | |||
@@ -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 = | |||
@@ -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" | |||
} | |||
] | |||
} | |||
} |
@@ -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 |
@@ -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"] | |||