Toot
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
defmodule MobilizonWeb.ActivityPubController do
|
||||
use MobilizonWeb, :controller
|
||||
alias Mobilizon.{Actors, Actors.Actor, Events, Events.Event}
|
||||
alias Mobilizon.{Actors, Actors.Actor, Events}
|
||||
alias Mobilizon.Events.{Event, Comment}
|
||||
alias MobilizonWeb.ActivityPub.{ObjectView, ActorView}
|
||||
alias Mobilizon.Service.ActivityPub
|
||||
alias Mobilizon.Service.Federator
|
||||
@@ -9,16 +10,18 @@ defmodule MobilizonWeb.ActivityPubController do
|
||||
|
||||
action_fallback(:errors)
|
||||
|
||||
@activity_pub_headers [
|
||||
"application/activity+json",
|
||||
"application/activity+json, application/ld+json"
|
||||
]
|
||||
|
||||
def actor(conn, %{"name" => name}) do
|
||||
with %Actor{} = actor <- Actors.get_local_actor_by_name(name) do
|
||||
case get_req_header(conn, "accept") do
|
||||
["application/activity+json"] ->
|
||||
cond do
|
||||
conn |> get_req_header("accept") |> is_ap_header() ->
|
||||
conn |> render_ap_actor(actor)
|
||||
|
||||
["application/activity+json, application/ld+json"] ->
|
||||
conn |> render_ap_actor(actor)
|
||||
|
||||
_ ->
|
||||
true ->
|
||||
conn
|
||||
|> put_resp_content_type("text/html")
|
||||
|> send_file(200, "priv/static/index.html")
|
||||
@@ -28,6 +31,10 @@ defmodule MobilizonWeb.ActivityPubController do
|
||||
end
|
||||
end
|
||||
|
||||
defp is_ap_header(ap_headers) do
|
||||
length(@activity_pub_headers -- ap_headers) < 2
|
||||
end
|
||||
|
||||
defp render_ap_actor(conn, %Actor{} = actor) do
|
||||
conn
|
||||
|> put_resp_header("content-type", "application/activity+json")
|
||||
@@ -41,7 +48,21 @@ defmodule MobilizonWeb.ActivityPubController do
|
||||
|> put_resp_header("content-type", "application/activity+json")
|
||||
|> json(ObjectView.render("event.json", %{event: event}))
|
||||
else
|
||||
false ->
|
||||
_ ->
|
||||
{:error, :not_found}
|
||||
end
|
||||
end
|
||||
|
||||
def comment(conn, %{"uuid" => uuid}) do
|
||||
with %Comment{} = comment <- Events.get_comment_full_from_uuid(uuid) do
|
||||
# Comments are always public for now
|
||||
# TODO : Make comments maybe restricted
|
||||
# true <- comment.public do
|
||||
conn
|
||||
|> put_resp_header("content-type", "application/activity+json")
|
||||
|> json(ObjectView.render("comment.json", %{comment: comment}))
|
||||
else
|
||||
_ ->
|
||||
{:error, :not_found}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -14,7 +14,7 @@ defmodule MobilizonWeb.Router do
|
||||
end
|
||||
|
||||
pipeline :activity_pub do
|
||||
plug(:accepts, ["activity-json", "text/html"])
|
||||
plug(:accepts, ["activity-json", "html"])
|
||||
plug(MobilizonWeb.HTTPSignaturePlug)
|
||||
end
|
||||
|
||||
@@ -55,7 +55,7 @@ defmodule MobilizonWeb.Router do
|
||||
get("/@:name/following", ActivityPubController, :following)
|
||||
get("/@:name/followers", ActivityPubController, :followers)
|
||||
get("/events/:uuid", ActivityPubController, :event)
|
||||
get("/comments/:uuid", ActivityPubController, :event)
|
||||
get("/comments/:uuid", ActivityPubController, :comment)
|
||||
post("/@:name/inbox", ActivityPubController, :inbox)
|
||||
post("/inbox", ActivityPubController, :inbox)
|
||||
end
|
||||
|
||||
@@ -32,6 +32,8 @@ defmodule MobilizonWeb.ActivityPub.ActorView do
|
||||
"owner" => actor.url,
|
||||
"publicKeyPem" => public_key
|
||||
},
|
||||
# TODO : Make have actors have an uuid
|
||||
# "uuid" => actor.uuid
|
||||
"endpoints" => %{
|
||||
"sharedInbox" => actor.shared_inbox_url
|
||||
}
|
||||
@@ -135,6 +137,7 @@ defmodule MobilizonWeb.ActivityPub.ActorView do
|
||||
"Announce"
|
||||
end,
|
||||
"actor" => activity.actor,
|
||||
# Not sure if needed since this is used into outbox
|
||||
"published" => Timex.now(),
|
||||
"to" => ["https://www.w3.org/ns/activitystreams#Public"],
|
||||
"object" =>
|
||||
@@ -143,9 +146,10 @@ defmodule MobilizonWeb.ActivityPub.ActorView do
|
||||
render_one(activity.data, ObjectView, "event.json", as: :event)
|
||||
|
||||
:Comment ->
|
||||
render_one(activity.data, ObjectView, "note.json", as: :note)
|
||||
render_one(activity.data, ObjectView, "comment.json", as: :comment)
|
||||
end
|
||||
}
|
||||
|> Map.merge(Utils.make_json_ld_header())
|
||||
end
|
||||
|
||||
def collection(collection, iri, page, total \\ nil) do
|
||||
|
||||
@@ -2,20 +2,7 @@ defmodule MobilizonWeb.ActivityPub.ObjectView do
|
||||
use MobilizonWeb, :view
|
||||
alias MobilizonWeb.ActivityPub.ObjectView
|
||||
alias Mobilizon.Service.ActivityPub.Transmogrifier
|
||||
|
||||
@base %{
|
||||
"@context" => [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1",
|
||||
%{
|
||||
"manuallyApprovesFollowers" => "as:manuallyApprovesFollowers",
|
||||
"sensitive" => "as:sensitive",
|
||||
"Hashtag" => "as:Hashtag",
|
||||
"toot" => "http://joinmastodon.org/ns#",
|
||||
"Emoji" => "toot:Emoji"
|
||||
}
|
||||
]
|
||||
}
|
||||
alias Mobilizon.Service.ActivityPub.Utils
|
||||
|
||||
def render("event.json", %{event: event}) do
|
||||
event = %{
|
||||
@@ -24,29 +11,36 @@ defmodule MobilizonWeb.ActivityPub.ObjectView do
|
||||
"name" => event.title,
|
||||
"category" => render_one(event.category, ObjectView, "category.json", as: :category),
|
||||
"content" => event.description,
|
||||
"mediaType" => "text/markdown",
|
||||
"mediaType" => "text/html",
|
||||
"published" => Timex.format!(event.inserted_at, "{ISO:Extended}"),
|
||||
"updated" => Timex.format!(event.updated_at, "{ISO:Extended}")
|
||||
}
|
||||
|
||||
Map.merge(event, @base)
|
||||
Map.merge(event, Utils.make_json_ld_header())
|
||||
end
|
||||
|
||||
def render("note.json", %{note: note}) do
|
||||
event = %{
|
||||
def render("comment.json", %{comment: comment}) do
|
||||
comment = %{
|
||||
"actor" => comment.actor.url,
|
||||
"uuid" => comment.uuid,
|
||||
# The activity should have attributedTo, not the comment itself
|
||||
# "attributedTo" => comment.attributed_to,
|
||||
"type" => "Note",
|
||||
"id" => note.url,
|
||||
"content" => note.text,
|
||||
"mediaType" => "text/markdown",
|
||||
"published" => Timex.format!(note.inserted_at, "{ISO:Extended}"),
|
||||
"updated" => Timex.format!(note.updated_at, "{ISO:Extended}")
|
||||
"id" => comment.url,
|
||||
"content" => comment.text,
|
||||
"mediaType" => "text/html",
|
||||
"published" => Timex.format!(comment.inserted_at, "{ISO:Extended}"),
|
||||
"updated" => Timex.format!(comment.updated_at, "{ISO:Extended}")
|
||||
}
|
||||
|
||||
Map.merge(event, @base)
|
||||
Map.merge(comment, Utils.make_json_ld_header())
|
||||
end
|
||||
|
||||
def render("category.json", %{category: category}) do
|
||||
%{"title" => category.title}
|
||||
%{
|
||||
"identifier" => category.id,
|
||||
"name" => category.title
|
||||
}
|
||||
end
|
||||
|
||||
def render("category.json", %{category: nil}) do
|
||||
|
||||
Reference in New Issue
Block a user