Basic peertube support.
authorHaelwenn (lanodan) Monnier <contact@hacktivis.me>
Thu, 12 Jul 2018 17:06:28 +0000 (19:06 +0200)
committerHaelwenn (lanodan) Monnier <contact@hacktivis.me>
Tue, 21 Aug 2018 16:24:09 +0000 (18:24 +0200)
lib/pleroma/web/activity_pub/transmogrifier.ex
lib/pleroma/web/activity_pub/utils.ex
lib/pleroma/web/twitter_api/representers/activity_representer.ex
lib/pleroma/web/twitter_api/representers/object_representer.ex
test/fixtures/httpoison_mock/7even.json [new file with mode: 0644]
test/fixtures/httpoison_mock/peertube.moe-vid.json [new file with mode: 0644]
test/support/httpoison_mock.ex
test/web/activity_pub/activity_pub_test.exs

index 39e2bb8a9985821f8b0dc98fe7eccb61da7abecf..279bf636586fea9edc696b6045ba9ecbae77415b 100644 (file)
@@ -94,8 +94,11 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
   def fix_in_reply_to(object), do: object
 
   def fix_context(object) do
+    context = object["context"] || object["conversation"] || Utils.generate_context_id()
+
     object
-    |> Map.put("context", object["conversation"])
+    |> Map.put("context", context)
+    |> Map.put("conversation", context)
   end
 
   def fix_attachments(object) do
@@ -163,7 +166,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
   # - tags
   # - emoji
   def handle_incoming(%{"type" => "Create", "object" => %{"type" => objtype} = object} = data)
-      when objtype in ["Article", "Note"] do
+      when objtype in ["Article", "Note", "Video"] do
     actor = get_actor(data)
 
     data =
index 8b41a3becbb26cad7af645d8bd6480316bd2a8c0..7cdc1656bd34013ac64e062709d77032b687eadd 100644 (file)
@@ -128,7 +128,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do
   Inserts a full object if it is contained in an activity.
   """
   def insert_full_object(%{"object" => %{"type" => type} = object_data})
-      when is_map(object_data) and type in ["Article", "Note"] do
+      when is_map(object_data) and type in ["Article", "Note", "Video"] do
     with {:ok, _} <- Object.create(object_data) do
       :ok
     end
@@ -204,13 +204,17 @@ defmodule Pleroma.Web.ActivityPub.Utils do
   end
 
   def add_like_to_object(%Activity{data: %{"actor" => actor}}, object) do
-    with likes <- [actor | object.data["likes"] || []] |> Enum.uniq() do
+    likes = if is_list(object.data["likes"]), do: object.data["likes"], else: []
+
+    with likes <- [actor | likes] |> Enum.uniq() do
       update_likes_in_object(likes, object)
     end
   end
 
   def remove_like_from_object(%Activity{data: %{"actor" => actor}}, object) do
-    with likes <- (object.data["likes"] || []) |> List.delete(actor) do
+    likes = if is_list(object.data["likes"]), do: object.data["likes"], else: []
+
+    with likes <- likes |> List.delete(actor) do
       update_likes_in_object(likes, object)
     end
   end
@@ -357,13 +361,19 @@ defmodule Pleroma.Web.ActivityPub.Utils do
   end
 
   def add_announce_to_object(%Activity{data: %{"actor" => actor}}, object) do
-    with announcements <- [actor | object.data["announcements"] || []] |> Enum.uniq() do
+    announcements =
+      if is_list(object.data["announcements"]), do: object.data["announcements"], else: []
+
+    with announcements <- [actor | announcements] |> Enum.uniq() do
       update_element_in_object("announcement", announcements, object)
     end
   end
 
   def remove_announce_from_object(%Activity{data: %{"actor" => actor}}, object) do
-    with announcements <- (object.data["announcements"] || []) |> List.delete(actor) do
+    announcements =
+      if is_list(object.data["announcements"]), do: object.data["announcements"], else: []
+
+    with announcements <- announcements |> List.delete(actor) do
       update_element_in_object("announcement", announcements, object)
     end
   end
index 26bfb79af16d5e5b0d90cda5c9f69f3137d9db9a..9abea59a7a470cc6dc9232d04ccfe9f49bca407c 100644 (file)
@@ -170,6 +170,15 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do
       HtmlSanitizeEx.basic_html(content)
       |> Formatter.emojify(object["emoji"])
 
+    video =
+      if object["type"] == "Video" do
+        vid = [object]
+      else
+        []
+      end
+
+    attachments = (object["attachment"] || []) ++ video
+
     %{
       "id" => activity.id,
       "uri" => activity.data["object"]["id"],
@@ -181,7 +190,7 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do
       "created_at" => created_at,
       "in_reply_to_status_id" => object["inReplyToStatusId"],
       "statusnet_conversation_id" => conversation_id,
-      "attachments" => (object["attachment"] || []) |> ObjectRepresenter.enum_to_list(opts),
+      "attachments" => attachments |> ObjectRepresenter.enum_to_list(opts),
       "attentions" => attentions,
       "fave_num" => like_count,
       "repeat_num" => announcement_count,
index 9af8a1691daf0cd5f5724929755b518a852f389f..60e30191f4041e3047f3d2af294846e5cffff060 100644 (file)
@@ -7,7 +7,7 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ObjectRepresenter do
 
     %{
       url: url["href"] |> Pleroma.Web.MediaProxy.url(),
-      mimetype: url["mediaType"],
+      mimetype: url["mediaType"] || url["mimeType"],
       id: data["uuid"],
       oembed: false
     }
@@ -16,7 +16,7 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ObjectRepresenter do
   def to_map(%Object{data: %{"url" => url} = data}, _opts) when is_binary(url) do
     %{
       url: url |> Pleroma.Web.MediaProxy.url(),
-      mimetype: data["mediaType"],
+      mimetype: data["mediaType"] || url["mimeType"],
       id: data["uuid"],
       oembed: false
     }
diff --git a/test/fixtures/httpoison_mock/7even.json b/test/fixtures/httpoison_mock/7even.json
new file mode 100644 (file)
index 0000000..eb3bab1
--- /dev/null
@@ -0,0 +1 @@
+{"type":"Person","id":"https://peertube.moe/accounts/7even","following":"https://peertube.moe/accounts/7even/following","followers":"https://peertube.moe/accounts/7even/followers","inbox":"https://peertube.moe/accounts/7even/inbox","outbox":"https://peertube.moe/accounts/7even/outbox","preferredUsername":"7even","url":"https://peertube.moe/accounts/7even","name":"7even","endpoints":{"sharedInbox":"https://peertube.moe/inbox"},"uuid":"fd6a914d-0383-4aca-b740-65ed96a0dd63","publicKey":{"id":"https://peertube.moe/accounts/7even#main-key","owner":"https://peertube.moe/accounts/7even","publicKeyPem":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3vQ2uvYbDprVrq9Ti2wB\nn2J0WkewrzR/+NF4+KVl9s+FMyE4jlmnz+9WEnacKhV1x8a3SrsjLgND55WxNaPj\nabrh6lWmI0SNmHBLi1BejIVAR7CZElF3yCxG0xtNna0Hg6bhtL6I61QxnClhFunu\nDO4i6uyrUu2iXWGQDPzpWkGFrmZdyHOCNIr5PekphR/wcCluwbndO51Ku2RJAblW\nI+QlDG7ailpXyTZGUEO5yfJZX7dkCET1AsNxeBo41aPYzUN5rgRCDB/AdJXxrgZb\nsmtiObB9u+KYk9DuegPpHP3y+dapCSCvStBdPyTaPzsi1y/pOiTVfaxw0NYEJ/Cs\n0QIDAQAB\n-----END PUBLIC KEY-----"},"icon":{"type":"Image","mediaType":"image/png","url":"https://peertube.moe/static/avatars/0815978b-dd71-4797-ae3f-493a3445882a.png"},"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1",{"RsaSignature2017":"https://w3id.org/security#RsaSignature2017","Hashtag":"as:Hashtag","uuid":"http://schema.org/identifier","category":"http://schema.org/category","licence":"http://schema.org/license","sensitive":"as:sensitive","language":"http://schema.org/inLanguage","views":"http://schema.org/Number","size":"http://schema.org/Number","commentsEnabled":"http://schema.org/Boolean","support":"http://schema.org/Text"},{"likes":{"@id":"as:likes","@type":"@id"},"dislikes":{"@id":"as:dislikes","@type":"@id"},"shares":{"@id":"as:shares","@type":"@id"},"comments":{"@id":"as:comments","@type":"@id"}}],"summary":null}
\ No newline at end of file
diff --git a/test/fixtures/httpoison_mock/peertube.moe-vid.json b/test/fixtures/httpoison_mock/peertube.moe-vid.json
new file mode 100644 (file)
index 0000000..76296eb
--- /dev/null
@@ -0,0 +1 @@
+{"type":"Video","id":"https://peertube.moe/videos/watch/df5f464b-be8d-46fb-ad81-2d4c2d1630e3","name":"Friday Night","duration":"PT29S","uuid":"df5f464b-be8d-46fb-ad81-2d4c2d1630e3","tag":[{"type":"Hashtag","name":"feels"}],"views":12,"sensitive":false,"commentsEnabled":true,"published":"2018-03-23T16:43:22.988Z","updated":"2018-03-24T16:28:46.002Z","mediaType":"text/markdown","content":"tfw\r\n\r\n\r\nsong is 'my old piano' by diana ross","support":null,"icon":{"type":"Image","url":"https://peertube.moe/static/thumbnails/df5f464b-be8d-46fb-ad81-2d4c2d1630e3.jpg","mediaType":"image/jpeg","width":200,"height":110},"url":[{"type":"Link","mimeType":"video/mp4","href":"https://peertube.moe/static/webseed/df5f464b-be8d-46fb-ad81-2d4c2d1630e3-480.mp4","width":480,"size":5015880},{"type":"Link","mimeType":"application/x-bittorrent","href":"https://peertube.moe/static/torrents/df5f464b-be8d-46fb-ad81-2d4c2d1630e3-480.torrent","width":480},{"type":"Link","mimeType":"application/x-bittorrent;x-scheme-handler/magnet","href":"magnet:?xs=https%3A%2F%2Fpeertube.moe%2Fstatic%2Ftorrents%2Fdf5f464b-be8d-46fb-ad81-2d4c2d1630e3-480.torrent&xt=urn:btih:11d3af6b5c812a376c2b29cdbd46e5fb42ee730e&dn=Friday+Night&tr=wss%3A%2F%2Fpeertube.moe%3A443%2Ftracker%2Fsocket&tr=https%3A%2F%2Fpeertube.moe%2Ftracker%2Fannounce&ws=https%3A%2F%2Fpeertube.moe%2Fstatic%2Fwebseed%2Fdf5f464b-be8d-46fb-ad81-2d4c2d1630e3-480.mp4","width":480},{"type":"Link","mimeType":"video/mp4","href":"https://peertube.moe/static/webseed/df5f464b-be8d-46fb-ad81-2d4c2d1630e3-360.mp4","width":360,"size":3620040},{"type":"Link","mimeType":"application/x-bittorrent","href":"https://peertube.moe/static/torrents/df5f464b-be8d-46fb-ad81-2d4c2d1630e3-360.torrent","width":360},{"type":"Link","mimeType":"application/x-bittorrent;x-scheme-handler/magnet","href":"magnet:?xs=https%3A%2F%2Fpeertube.moe%2Fstatic%2Ftorrents%2Fdf5f464b-be8d-46fb-ad81-2d4c2d1630e3-360.torrent&xt=urn:btih:1c3885b4d7cdb46193b62b9b76e72b1409cfb297&dn=Friday+Night&tr=wss%3A%2F%2Fpeertube.moe%3A443%2Ftracker%2Fsocket&tr=https%3A%2F%2Fpeertube.moe%2Ftracker%2Fannounce&ws=https%3A%2F%2Fpeertube.moe%2Fstatic%2Fwebseed%2Fdf5f464b-be8d-46fb-ad81-2d4c2d1630e3-360.mp4","width":360},{"type":"Link","mimeType":"video/mp4","href":"https://peertube.moe/static/webseed/df5f464b-be8d-46fb-ad81-2d4c2d1630e3-240.mp4","width":240,"size":2305488},{"type":"Link","mimeType":"application/x-bittorrent","href":"https://peertube.moe/static/torrents/df5f464b-be8d-46fb-ad81-2d4c2d1630e3-240.torrent","width":240},{"type":"Link","mimeType":"application/x-bittorrent;x-scheme-handler/magnet","href":"magnet:?xs=https%3A%2F%2Fpeertube.moe%2Fstatic%2Ftorrents%2Fdf5f464b-be8d-46fb-ad81-2d4c2d1630e3-240.torrent&xt=urn:btih:ac5773352d9e26f982d2da63acfb244f01ccafa4&dn=Friday+Night&tr=wss%3A%2F%2Fpeertube.moe%3A443%2Ftracker%2Fsocket&tr=https%3A%2F%2Fpeertube.moe%2Ftracker%2Fannounce&ws=https%3A%2F%2Fpeertube.moe%2Fstatic%2Fwebseed%2Fdf5f464b-be8d-46fb-ad81-2d4c2d1630e3-240.mp4","width":240},{"type":"Link","mimeType":"video/mp4","href":"https://peertube.moe/static/webseed/df5f464b-be8d-46fb-ad81-2d4c2d1630e3-720.mp4","width":720,"size":7928231},{"type":"Link","mimeType":"application/x-bittorrent","href":"https://peertube.moe/static/torrents/df5f464b-be8d-46fb-ad81-2d4c2d1630e3-720.torrent","width":720},{"type":"Link","mimeType":"application/x-bittorrent;x-scheme-handler/magnet","href":"magnet:?xs=https%3A%2F%2Fpeertube.moe%2Fstatic%2Ftorrents%2Fdf5f464b-be8d-46fb-ad81-2d4c2d1630e3-720.torrent&xt=urn:btih:b591068f4533c4e2865bb4cbb89887aecccdc523&dn=Friday+Night&tr=wss%3A%2F%2Fpeertube.moe%3A443%2Ftracker%2Fsocket&tr=https%3A%2F%2Fpeertube.moe%2Ftracker%2Fannounce&ws=https%3A%2F%2Fpeertube.moe%2Fstatic%2Fwebseed%2Fdf5f464b-be8d-46fb-ad81-2d4c2d1630e3-720.mp4","width":720},{"type":"Link","mimeType":"text/html","href":"https://peertube.moe/videos/watch/df5f464b-be8d-46fb-ad81-2d4c2d1630e3"}],"likes":{"id":"https://peertube.moe/videos/watch/df5f464b-be8d-46fb-ad81-2d4c2d1630e3/likes","type":"OrderedCollection","totalItems":0,"orderedItems":[]},"dislikes":{"id":"https://peertube.moe/videos/watch/df5f464b-be8d-46fb-ad81-2d4c2d1630e3/dislikes","type":"OrderedCollection","totalItems":0,"orderedItems":[]},"shares":{"id":"https://peertube.moe/videos/watch/df5f464b-be8d-46fb-ad81-2d4c2d1630e3/announces","type":"OrderedCollection","totalItems":2,"orderedItems":["https://peertube.moe/videos/watch/df5f464b-be8d-46fb-ad81-2d4c2d1630e3/announces/465","https://peertube.moe/videos/watch/df5f464b-be8d-46fb-ad81-2d4c2d1630e3/announces/1"]},"comments":{"id":"https://peertube.moe/videos/watch/df5f464b-be8d-46fb-ad81-2d4c2d1630e3/comments","type":"OrderedCollection","totalItems":0,"orderedItems":[]},"attributedTo":[{"type":"Group","id":"https://peertube.moe/video-channels/5224869f-aa63-4c83-ab3a-87c3a5ac440e"},{"type":"Person","id":"https://peertube.moe/accounts/7even"}],"to":["https://www.w3.org/ns/activitystreams#Public"],"cc":[],"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1",{"RsaSignature2017":"https://w3id.org/security#RsaSignature2017","Hashtag":"as:Hashtag","uuid":"http://schema.org/identifier","category":"http://schema.org/category","licence":"http://schema.org/license","sensitive":"as:sensitive","language":"http://schema.org/inLanguage","views":"http://schema.org/Number","size":"http://schema.org/Number","commentsEnabled":"http://schema.org/Boolean","support":"http://schema.org/Text"},{"likes":{"@id":"as:likes","@type":"@id"},"dislikes":{"@id":"as:dislikes","@type":"@id"},"shares":{"@id":"as:shares","@type":"@id"},"comments":{"@id":"as:comments","@type":"@id"}}]}
\ No newline at end of file
index 527c2e1f7f6ac6f03661f032fcc27f4dc03fb5ae..4ee2feb9572bceb32f6ec52b167a561536a6b369 100644 (file)
@@ -760,6 +760,22 @@ defmodule HTTPoisonMock do
      }}
   end
 
+  def get("https://peertube.moe/videos/watch/df5f464b-be8d-46fb-ad81-2d4c2d1630e3", _, _) do
+    {:ok,
+     %Response{
+       status_code: 200,
+       body: File.read!("test/fixtures/httpoison_mock/peertube.moe-vid.json")
+     }}
+  end
+
+  def get("https://peertube.moe/accounts/7even", _, _) do
+    {:ok,
+     %Response{
+       status_code: 200,
+       body: File.read!("test/fixtures/httpoison_mock/7even.json")
+     }}
+  end
+
   def get(url, body, headers) do
     {:error,
      "Not implemented the mock response for get #{inspect(url)}, #{inspect(body)}, #{
index 90c0bd7682158b4b4a27dca32027d84c99c46a47..1cf7d6bbcbc50bbc3303c40c8f9324052da4cb91 100644 (file)
@@ -506,6 +506,15 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
     end
   end
 
+  test "it can fetch peertube videos" do
+    {:ok, object} =
+      ActivityPub.fetch_object_from_id(
+        "https://peertube.moe/videos/watch/df5f464b-be8d-46fb-ad81-2d4c2d1630e3"
+      )
+
+    assert object
+  end
+
   def data_uri do
     File.read!("test/fixtures/avatar_data_uri")
   end