diff --git a/lib/pleroma/web/activity_pub/mrf/inline_quote_policy.ex b/lib/pleroma/web/activity_pub/mrf/inline_quote_policy.ex index 46013fc5e9..7de4935f21 100644 --- a/lib/pleroma/web/activity_pub/mrf/inline_quote_policy.ex +++ b/lib/pleroma/web/activity_pub/mrf/inline_quote_policy.ex @@ -6,8 +6,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.InlineQuotePolicy do @moduledoc "Force a quote line into the message content." @behaviour Pleroma.Web.ActivityPub.MRF.Policy - defp build_inline_quote(prefix, url, br) do - "#{String.duplicate("
", br)}#{prefix}: #{url}
" + defp build_inline_quote(prefix, url) do + "

#{prefix}: #{url}
" end defp filter_object(%{"quoteUrl" => quote_url} = object) do @@ -18,12 +18,13 @@ defp filter_object(%{"quoteUrl" => quote_url} = object) do else prefix = Pleroma.Config.get([:mrf_inline_quote, :prefix]) - inline_quote = + content = if String.ends_with?(content, "

"), - do: build_inline_quote(prefix, quote_url, 0), - else: build_inline_quote(prefix, quote_url, 2) + do: + String.trim_trailing(content, "

") <> + build_inline_quote(prefix, quote_url) <> "

", + else: content <> build_inline_quote(prefix, quote_url) - content = content <> inline_quote Map.put(object, "content", content) end end diff --git a/lib/pleroma/web/activity_pub/object_validators/article_note_page_validator.ex b/lib/pleroma/web/activity_pub/object_validators/article_note_page_validator.ex index 3568ca20a5..6c11dac6fa 100644 --- a/lib/pleroma/web/activity_pub/object_validators/article_note_page_validator.ex +++ b/lib/pleroma/web/activity_pub/object_validators/article_note_page_validator.ex @@ -67,7 +67,13 @@ defp fix_replies(data), do: data defp fix_quote_url(%{"quoteUrl" => _quote_url} = data), do: data - # Fix for Fedibird + # Fedibird + # https://github.com/fedibird/mastodon/commit/dbd7ae6cf58a92ec67c512296b4daaea0d01e6ac + defp fix_quote_url(%{"quoteUri" => quote_url} = data) do + Map.put(data, "quoteUrl", quote_url) + end + + # Old Fedibird (bug) # https://github.com/fedibird/mastodon/issues/9 defp fix_quote_url(%{"quoteURL" => quote_url} = data) do Map.put(data, "quoteUrl", quote_url) diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index 9548a5d20b..22ff1a7abf 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -181,7 +181,15 @@ def fix_quote_url(%{"quoteUrl" => quote_url} = object, options) end end - # Fix for Fedibird + # Fedibird + # https://github.com/fedibird/mastodon/commit/dbd7ae6cf58a92ec67c512296b4daaea0d01e6ac + def fix_quote_url(%{"quoteUri" => quote_url} = object, options) do + object + |> Map.put("quoteUrl", quote_url) + |> fix_quote_url(options) + end + + # Old Fedibird (bug) # https://github.com/fedibird/mastodon/issues/9 def fix_quote_url(%{"quoteURL" => quote_url} = object, options) do object @@ -661,6 +669,17 @@ def set_reply_to_uri(%{"inReplyTo" => in_reply_to} = object) when is_binary(in_r def set_reply_to_uri(obj), do: obj + def set_quote_url(%{"quoteUrl" => quote_url} = object) when is_binary(quote_url) do + Map.merge(object, %{ + # Fedibird quote + "quoteUri" => quote_url, + # Misskey quote + "_misskey_quote" => quote_url + }) + end + + def set_quote_url(obj), do: obj + @doc """ Serialized Mastodon-compatible `replies` collection containing _self-replies_. Based on Mastodon's ActivityPub::NoteSerializer#replies. @@ -715,6 +734,7 @@ def prepare_object(object) do |> prepare_attachments |> set_conversation |> set_reply_to_uri + |> set_quote_url |> set_replies |> strip_internal_fields |> strip_internal_tags diff --git a/priv/static/schemas/litepub-0.1.jsonld b/priv/static/schemas/litepub-0.1.jsonld index 7802b39467..568a75ce0f 100644 --- a/priv/static/schemas/litepub-0.1.jsonld +++ b/priv/static/schemas/litepub-0.1.jsonld @@ -17,6 +17,8 @@ "ostatus": "http://ostatus.org#", "schema": "http://schema.org#", "toot": "http://joinmastodon.org/ns#", + "misskey": "https://misskey-hub.net/ns#", + "fedibird": "http://fedibird.com/ns#", "value": "schema:value", "sensitive": "as:sensitive", "litepub": "http://litepub.social/ns#", @@ -27,6 +29,8 @@ "@type": "@id" }, "quoteUrl": "as:quoteUrl", + "quoteUri": "fedibird:quoteUri", + "_misskey_quote": "misskey:_misskey_quote", "oauthRegistrationEndpoint": { "@id": "litepub:oauthRegistrationEndpoint", "@type": "@id" diff --git a/test/fixtures/quote_post/fedibird_quote_uri.json b/test/fixtures/quote_post/fedibird_quote_uri.json new file mode 100644 index 0000000000..7c328fdb92 --- /dev/null +++ b/test/fixtures/quote_post/fedibird_quote_uri.json @@ -0,0 +1,54 @@ +{ + "@context": [ + "https://www.w3.org/ns/activitystreams", + { + "ostatus": "http://ostatus.org#", + "atomUri": "ostatus:atomUri", + "inReplyToAtomUri": "ostatus:inReplyToAtomUri", + "conversation": "ostatus:conversation", + "sensitive": "as:sensitive", + "toot": "http://joinmastodon.org/ns#", + "votersCount": "toot:votersCount", + "fedibird": "http://fedibird.com/ns#", + "quoteUri": "fedibird:quoteUri", + "expiry": "fedibird:expiry" + } + ], + "id": "https://fedibird.com/users/noellabo/statuses/107699335988346142", + "type": "Note", + "summary": null, + "inReplyTo": null, + "published": "2022-01-28T09:17:30Z", + "url": "https://fedibird.com/@noellabo/107699335988346142", + "attributedTo": "https://fedibird.com/users/noellabo", + "to": [ + "https://www.w3.org/ns/activitystreams#Public" + ], + "cc": [ + "https://fedibird.com/users/noellabo/followers" + ], + "sensitive": false, + "atomUri": "https://fedibird.com/users/noellabo/statuses/107699335988346142", + "inReplyToAtomUri": null, + "conversation": "tag:fedibird.com,2022-01-28:objectId=107699335988345290:objectType=Conversation", + "context": "https://fedibird.com/contexts/107699335988345290", + "quoteUri": "https://fedibird.com/users/yamako/statuses/107699333438289729", + "_misskey_quote": "https://fedibird.com/users/yamako/statuses/107699333438289729", + "_misskey_content": "美味しそう", + "content": "

美味しそう
QT: https://fedibird.com/@yamako/107699333438289729

", + "contentMap": { + "ja": "

美味しそう
QT: https://fedibird.com/@yamako/107699333438289729

" + }, + "attachment": [], + "tag": [], + "replies": { + "id": "https://fedibird.com/users/noellabo/statuses/107699335988346142/replies", + "type": "Collection", + "first": { + "type": "CollectionPage", + "next": "https://fedibird.com/users/noellabo/statuses/107699335988346142/replies?only_other_accounts=true&page=true", + "partOf": "https://fedibird.com/users/noellabo/statuses/107699335988346142/replies", + "items": [] + } + } +} diff --git a/test/pleroma/web/activity_pub/mrf/inline_quote_policy_test.exs b/test/pleroma/web/activity_pub/mrf/inline_quote_policy_test.exs index 8e75aaaab2..2291c1dacd 100644 --- a/test/pleroma/web/activity_pub/mrf/inline_quote_policy_test.exs +++ b/test/pleroma/web/activity_pub/mrf/inline_quote_policy_test.exs @@ -22,7 +22,7 @@ test "adds quote URL to post content" do {:ok, %{"object" => %{"content" => filtered}}} = InlineQuotePolicy.filter(activity) assert filtered == - "Nice post

RT: https://gleasonator.com/objects/1234
" + "Nice post

RT: https://gleasonator.com/objects/1234
" end test "doesn't add line breaks to markdown posts" do @@ -41,7 +41,7 @@ test "doesn't add line breaks to markdown posts" do {:ok, %{"object" => %{"content" => filtered}}} = InlineQuotePolicy.filter(activity) assert filtered == - "

Nice post

RT: https://gleasonator.com/objects/1234" + "

Nice post

RT: https://gleasonator.com/objects/1234

" end test "ignores Misskey quote posts" do diff --git a/test/pleroma/web/activity_pub/object_validators/article_note_page_validator_test.exs b/test/pleroma/web/activity_pub/object_validators/article_note_page_validator_test.exs index 1abf546adc..949b1339a6 100644 --- a/test/pleroma/web/activity_pub/object_validators/article_note_page_validator_test.exs +++ b/test/pleroma/web/activity_pub/object_validators/article_note_page_validator_test.exs @@ -43,6 +43,16 @@ test "Fedibird quote post" do assert cng.changes.quoteUrl == "https://misskey.io/notes/8vsn2izjwh" end + test "Fedibird quote post with quoteUri field" do + insert(:user, ap_id: "https://fedibird.com/users/noellabo") + + data = File.read!("test/fixtures/quote_post/fedibird_quote_uri.json") |> Jason.decode!() + cng = ArticleNotePageValidator.cast_and_validate(data) + + assert cng.valid? + assert cng.changes.quoteUrl == "https://fedibird.com/users/yamako/statuses/107699333438289729" + end + test "Misskey quote post" do insert(:user, ap_id: "https://misskey.io/users/7rkrarq81i") diff --git a/test/pleroma/web/activity_pub/transmogrifier_test.exs b/test/pleroma/web/activity_pub/transmogrifier_test.exs index bae8f1d5eb..e63a05d527 100644 --- a/test/pleroma/web/activity_pub/transmogrifier_test.exs +++ b/test/pleroma/web/activity_pub/transmogrifier_test.exs @@ -332,8 +332,11 @@ test "it prepares a quote post" do {:ok, modified} = Transmogrifier.prepare_outgoing(quote_post.data) - quoted_post = Object.normalize(quoted_post) - assert modified["object"]["quoteUrl"] == quoted_post.data["id"] + %{data: %{"id" => quote_id}} = Object.normalize(quoted_post) + + assert modified["object"]["quoteUrl"] == quote_id + assert modified["object"]["quoteUri"] == quote_id + assert modified["object"]["_misskey_quote"] == quote_id end end