Basic peertube support.
This commit is contained in:
parent
847cb15626
commit
333389607f
|
@ -7,17 +7,25 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|
|||
alias Pleroma.Activity
|
||||
alias Pleroma.Repo
|
||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||
alias Pleroma.Web.ActivityPub.Utils
|
||||
|
||||
import Ecto.Query
|
||||
|
||||
require Logger
|
||||
|
||||
def get_actor(%{"actor" => actor}) when is_binary(actor), do: actor
|
||||
def get_actor(%{"actor" => actor_list}) do
|
||||
Enum.find(actor_list, fn(%{"type" => type}) -> type == "Person" end)
|
||||
|> Map.get("id")
|
||||
end
|
||||
|
||||
@doc """
|
||||
Modifies an incoming AP object (mastodon format) to our internal format.
|
||||
"""
|
||||
def fix_object(object) do
|
||||
attributedTo = object["attributedTo"]
|
||||
object
|
||||
|> Map.put("actor", object["attributedTo"])
|
||||
|> Map.put("actor", get_actor(%{"actor" => attributedTo}))
|
||||
|> fix_attachments
|
||||
|> fix_context
|
||||
|> fix_in_reply_to
|
||||
|
@ -42,8 +50,10 @@ 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
|
||||
|
@ -173,6 +183,33 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|
|||
end
|
||||
end
|
||||
|
||||
def handle_incoming(%{"type" => "Create", "object" => %{"type" => "Video"} = object} = data) do
|
||||
actor = get_actor(data)
|
||||
data = Map.put(data, "actor", actor)
|
||||
with nil <- Activity.get_create_activity_by_object_ap_id(object["id"]),
|
||||
%User{} = user <- User.get_or_fetch_by_ap_id(data["actor"]) do
|
||||
|
||||
object = fix_object(data["object"])
|
||||
|
||||
params = %{
|
||||
to: data["to"],
|
||||
object: object,
|
||||
actor: user,
|
||||
context: object["conversation"],
|
||||
local: false,
|
||||
published: data["published"],
|
||||
additional: Map.take(data, [
|
||||
"cc",
|
||||
"id"
|
||||
])
|
||||
}
|
||||
|
||||
ActivityPub.create(params)
|
||||
else
|
||||
%Activity{} = activity -> {:ok, activity}
|
||||
_e -> :error
|
||||
end
|
||||
end
|
||||
# TODO
|
||||
# Accept
|
||||
# Undo
|
||||
|
|
|
@ -88,7 +88,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do
|
|||
@doc """
|
||||
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 ["Note"] do
|
||||
def insert_full_object(%{"object" => %{"type" => type} = object_data}) when is_map(object_data) and type in ["Note", "Video"] do
|
||||
with {:ok, _} <- Object.create(object_data) do
|
||||
:ok
|
||||
end
|
||||
|
@ -150,13 +150,15 @@ 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
|
||||
|
@ -207,7 +209,8 @@ 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
|
||||
|
|
|
@ -117,6 +117,7 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do
|
|||
}
|
||||
end
|
||||
|
||||
# Handles "Note" and "Video"
|
||||
def to_map(%Activity{data: %{"object" => %{"content" => content} = object}} = activity, %{user: user} = opts) do
|
||||
created_at = object["published"] |> Utils.date_to_asctime
|
||||
like_count = object["like_count"] || 0
|
||||
|
@ -147,6 +148,14 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do
|
|||
|
||||
html = 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"],
|
||||
|
@ -158,7 +167,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,
|
||||
|
|
|
@ -6,7 +6,7 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ObjectRepresenter do
|
|||
data = object.data
|
||||
%{
|
||||
url: url["href"] |> Pleroma.Web.MediaProxy.url(),
|
||||
mimetype: url["mediaType"],
|
||||
mimetype: url["mediaType"] || url["mimeType"],
|
||||
id: data["uuid"],
|
||||
oembed: false
|
||||
}
|
||||
|
@ -15,7 +15,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
|
||||
}
|
||||
|
|
|
@ -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}
|
File diff suppressed because one or more lines are too long
|
@ -456,6 +456,20 @@ 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)}, #{inspect(headers)}"}
|
||||
end
|
||||
|
|
|
@ -353,6 +353,12 @@ 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
|
||||
|
|
Loading…
Reference in New Issue