From c85998ab8a21f042ab57345a7baa9e1e27c308d1 Mon Sep 17 00:00:00 2001 From: Roger Braun Date: Thu, 4 May 2017 18:42:29 +0200 Subject: [PATCH] Parse incoming retweets. --- lib/pleroma/web/activity_pub/activity_pub.ex | 4 +- lib/pleroma/web/ostatus/ostatus.ex | 50 +++++++--- test/fixtures/share-gs.xml | 99 ++++++++++++++++++++ test/fixtures/share.xml | 54 +++++++++++ test/web/ostatus/ostatus_test.exs | 26 +++++ 5 files changed, 218 insertions(+), 15 deletions(-) create mode 100644 test/fixtures/share-gs.xml create mode 100644 test/fixtures/share.xml diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 5583a1f41..1816b2e66 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -177,7 +177,7 @@ def fetch_activities(recipients, opts \\ %{}) do |> Enum.reverse end - def announce(%User{ap_id: ap_id} = user, %Object{data: %{"id" => id}} = object) do + def announce(%User{ap_id: ap_id} = user, %Object{data: %{"id" => id}} = object, local \\ true) do data = %{ "type" => "Announce", "actor" => ap_id, @@ -186,7 +186,7 @@ def announce(%User{ap_id: ap_id} = user, %Object{data: %{"id" => id}} = object) "context" => object.data["context"] } - {:ok, activity} = insert(data) + {:ok, activity} = insert(data, local) announcements = [ap_id | (object.data["announcements"] || [])] |> Enum.uniq diff --git a/lib/pleroma/web/ostatus/ostatus.ex b/lib/pleroma/web/ostatus/ostatus.ex index f81751a25..2fab67663 100644 --- a/lib/pleroma/web/ostatus/ostatus.ex +++ b/lib/pleroma/web/ostatus/ostatus.ex @@ -25,20 +25,44 @@ def handle_incoming(xml_string) do activities = Enum.map(entries, fn (entry) -> {:xmlObj, :string, object_type } = :xmerl_xpath.string('string(/entry/activity:object-type[1])', entry) + {:xmlObj, :string, verb } = :xmerl_xpath.string('string(/entry/activity:verb[1])', entry) - case object_type do - 'http://activitystrea.ms/schema/1.0/note' -> - with {:ok, activity} <- handle_note(entry, doc), do: activity - 'http://activitystrea.ms/schema/1.0/comment' -> - with {:ok, activity} <- handle_note(entry, doc), do: activity + case verb do + 'http://activitystrea.ms/schema/1.0/share' -> + with {:ok, activity, retweeted_activity} <- handle_share(entry, doc), do: [activity, retweeted_activity] _ -> - Logger.error("Couldn't parse incoming document") - nil + case object_type do + 'http://activitystrea.ms/schema/1.0/note' -> + with {:ok, activity} <- handle_note(entry, doc), do: activity + 'http://activitystrea.ms/schema/1.0/comment' -> + with {:ok, activity} <- handle_note(entry, doc), do: activity + _ -> + Logger.error("Couldn't parse incoming document") + nil + end end end) {:ok, activities} end + def make_share(entry, doc, retweeted_activity) do + with {:ok, actor} <- find_make_or_update_user(doc), + %Object{} = object <- Object.get_cached_by_ap_id(retweeted_activity.data["object"]["id"]), + {:ok, activity, object} = ActivityPub.announce(actor, object, false) do + {:ok, activity} + end + end + + def handle_share(entry, doc) do + with [object] <- :xmerl_xpath.string('/entry/activity:object', entry), + {:ok, retweeted_activity} <- handle_note(object, object), + {:ok, activity} <- make_share(entry, doc, retweeted_activity) do + {:ok, activity, retweeted_activity} + else + e -> {:error, e} + end + end + def get_attachments(entry) do :xmerl_xpath.string('/entry/link[@rel="enclosure"]', entry) |> Enum.map(fn (enclosure) -> @@ -58,13 +82,13 @@ def get_attachments(entry) do end def handle_note(entry, doc \\ nil) do - content_html = string_from_xpath("/entry/content[1]", entry) + content_html = string_from_xpath("//content[1]", entry) [author] = :xmerl_xpath.string('//author[1]', doc) {:ok, actor} = find_make_or_update_user(author) - inReplyTo = string_from_xpath("/entry/thr:in-reply-to[1]/@ref", entry) + inReplyTo = string_from_xpath("//thr:in-reply-to[1]/@ref", entry) - context = (string_from_xpath("/entry/ostatus:conversation[1]", entry) || "") |> String.trim + context = (string_from_xpath("//ostatus:conversation[1]", entry) || "") |> String.trim attachments = get_attachments(entry) @@ -82,13 +106,13 @@ def handle_note(entry, doc \\ nil) do "https://www.w3.org/ns/activitystreams#Public" ] - mentions = :xmerl_xpath.string('/entry/link[@rel="mentioned" and @ostatus:object-type="http://activitystrea.ms/schema/1.0/person"]', entry) + mentions = :xmerl_xpath.string('//link[@rel="mentioned" and @ostatus:object-type="http://activitystrea.ms/schema/1.0/person"]', entry) |> Enum.map(fn(person) -> string_from_xpath("@href", person) end) to = to ++ mentions - date = string_from_xpath("/entry/published", entry) - id = string_from_xpath("/entry/id", entry) + date = string_from_xpath("//published", entry) + id = string_from_xpath("//id", entry) object = %{ "id" => id, diff --git a/test/fixtures/share-gs.xml b/test/fixtures/share-gs.xml new file mode 100644 index 000000000..ab5e488bd --- /dev/null +++ b/test/fixtures/share-gs.xml @@ -0,0 +1,99 @@ + + + GNU social + https://social.heldscal.la/api/statuses/user_timeline/23211.atom + lambadalambda timeline + Updates from lambadalambda on social.heldscal.la! + https://social.heldscal.la/avatar/23211-96-20170416114255.jpeg + 2017-05-03T08:05:41+00:00 + + http://activitystrea.ms/schema/1.0/person + https://social.heldscal.la/user/23211 + lambadalambda + Call me Deacon Blues. + + + + + + lambadalambda + Constance Variable + Call me Deacon Blues. + + Berlin + + + homepage + https://heldscal.la + true + + + + + + + + + + + + + tag:social.heldscal.la,2017-05-03:noticeId=2028428:objectType=note + lambadalambda repeated a notice by lain + RT @<a href="https://pleroma.soykaf.com/users/lain" class="h-card u-url p-nickname mention" title="Lain Iwakura">lain</a> Added returning the entries as xml... let's see if the mastodon hammering stops now. + + http://activitystrea.ms/schema/1.0/share + 2017-05-03T08:05:41+00:00 + 2017-05-03T08:05:41+00:00 + + http://activitystrea.ms/schema/1.0/activity + https://pleroma.soykaf.com/objects/4c1bda26-902e-4525-9fcd-b9fd44925193 + + Added returning the entries as xml... let's see if the mastodon hammering stops now. + + http://activitystrea.ms/schema/1.0/post + 2017-05-03T08:04:44+00:00 + 2017-05-03T08:04:44+00:00 + + http://activitystrea.ms/schema/1.0/person + https://pleroma.soykaf.com/users/lain + lain + Test account + + + + + + lain + Lain Iwakura + Test account + + + + http://activitystrea.ms/schema/1.0/note + https://pleroma.soykaf.com/objects/4c1bda26-902e-4525-9fcd-b9fd44925193 + New note by lain + Added returning the entries as xml... let's see if the mastodon hammering stops now. + + + + + https://pleroma.soykaf.com/contexts/ede39a2b-7cf3-4fa4-8ccd-cb97431bcc22 + + + https://pleroma.soykaf.com/users/lain/feed.atom + Lain Iwakura + + + https://social.heldscal.la/avatar/43188-96-20170429172422.jpeg + 2017-05-03T08:04:44+00:00 + + + + https://pleroma.soykaf.com/contexts/ede39a2b-7cf3-4fa4-8ccd-cb97431bcc22 + + + + + + diff --git a/test/fixtures/share.xml b/test/fixtures/share.xml new file mode 100644 index 000000000..e07b88680 --- /dev/null +++ b/test/fixtures/share.xml @@ -0,0 +1,54 @@ + + + tag:mastodon.social,2017-05-03:objectId=4934452:objectType=Status + 2017-05-03T08:21:09Z + 2017-05-03T08:21:09Z + lambadalambda shared a status by lain@pleroma.soykaf.com + + https://mastodon.social/users/lambadalambda + http://activitystrea.ms/schema/1.0/person + https://mastodon.social/users/lambadalambda + lambadalambda + lambadalambda@mastodon.social + + + + lambadalambda + Critical Value + public + + http://activitystrea.ms/schema/1.0/activity + http://activitystrea.ms/schema/1.0/share + + https://pleroma.soykaf.com/objects/4c1bda26-902e-4525-9fcd-b9fd44925193 + 2017-05-03T08:04:44Z + 2017-05-03T08:05:52Z + New status by lain@pleroma.soykaf.com + + https://pleroma.soykaf.com/users/lain + http://activitystrea.ms/schema/1.0/person + https://pleroma.soykaf.com/users/lain + lain + lain@pleroma.soykaf.com + Test account + + + + lain + Lain Iwakura + Test account + public + + http://activitystrea.ms/schema/1.0/note + http://activitystrea.ms/schema/1.0/post + Added returning the entries as xml... let's see if the mastodon hammering stops now. + + public + + + Added returning the entries as xml... let's see if the mastodon hammering stops now. + + public + + + diff --git a/test/web/ostatus/ostatus_test.exs b/test/web/ostatus/ostatus_test.exs index 94a735337..e85d7677c 100644 --- a/test/web/ostatus/ostatus_test.exs +++ b/test/web/ostatus/ostatus_test.exs @@ -70,6 +70,32 @@ test "handle incoming notes - GS, subscription, reply" do assert activity.data["object"]["inReplyTo"] == "tag:gs.archae.me,2017-04-30:noticeId=778260:objectType=note" end + test "handle incoming retweets - GS, subscription" do + incoming = File.read!("test/fixtures/share-gs.xml") + {:ok, [[activity, retweeted_activity]]} = OStatus.handle_incoming(incoming) + + assert activity.data["type"] == "Announce" + assert activity.data["actor"] == "https://social.heldscal.la/user/23211" + assert activity.data["object"] == retweeted_activity.data["object"]["id"] + refute activity.local + assert retweeted_activity.data["type"] == "Create" + assert retweeted_activity.data["actor"] == "https://pleroma.soykaf.com/users/lain" + refute retweeted_activity.local + end + + test "handle incoming retweets - Mastodon, salmon" do + incoming = File.read!("test/fixtures/share.xml") + {:ok, [[activity, retweeted_activity]]} = OStatus.handle_incoming(incoming) + + assert activity.data["type"] == "Announce" + assert activity.data["actor"] == "https://mastodon.social/users/lambadalambda" + assert activity.data["object"] == retweeted_activity.data["object"]["id"] + refute activity.local + assert retweeted_activity.data["type"] == "Create" + assert retweeted_activity.data["actor"] == "https://pleroma.soykaf.com/users/lain" + refute retweeted_activity.local + end + test "handle incoming replies" do incoming = File.read!("test/fixtures/incoming_note_activity_answer.xml") {:ok, [activity]} = OStatus.handle_incoming(incoming)