diff --git a/lib/nulla/activitypub.ex b/lib/nulla/activitypub.ex index 66a439a..2be7a2e 100644 --- a/lib/nulla/activitypub.ex +++ b/lib/nulla/activitypub.ex @@ -85,47 +85,58 @@ defmodule Nulla.ActivityPub do ) end - @spec note(String.t(), Nulla.Models.User.t(), Nulla.Models.Note.t()) :: Jason.OrderedObject.t() - def note(domain, user, note) do + @spec note(String.t(), Nulla.Models.Note.t()) :: Jason.OrderedObject.t() + def note(domain, note) do + attachment = + case note.media_attachments do + [] -> [] + attachments -> + [ + attachment: + Enum.map(attachments, fn att -> + Jason.OrderedObject.new( + type: "Document", + mediaType: att.mime_type, + url: "https://#{domain}/files/#{att.file}" + ) + end) + ] + end + Jason.OrderedObject.new( "@context": [ "https://www.w3.org/ns/activitystreams", Jason.OrderedObject.new(sensitive: "as:sensitive") ], - id: "https://#{domain}/@#{user.username}/#{note.id}", + id: "https://#{domain}/@#{note.user.username}/#{note.id}", type: "Note", summary: nil, inReplyTo: nil, published: note.inserted_at, - url: "https://#{domain}/@#{user.username}/#{note.id}", - attributedTo: "https://#{domain}/@#{user.username}", + url: "https://#{domain}/@#{note.user.username}/#{note.id}", + attributedTo: "https://#{domain}/@#{note.user.username}", to: [ "https://www.w3.org/ns/activitystreams#Public" ], cc: [ - "https://#{domain}/@#{user.username}/followers" + "https://#{domain}/@#{note.user.username}/followers" ], sensetive: false, content: note.content, contentMap: Jason.OrderedObject.new("#{note.language}": note.content), - attachment: [ - Jason.OrderedObject.new( - type: "Document", - mediaType: "#{note.media_attachment.mime_type}", - url: "https://#{domain}/files/#{note.media_attachment.file}" - ) - ] + attachment: attachment ) end - def activity(domain, action) do + @spec activity(String.t(), Nulla.Models.Activity.t()) :: Jason.OrderedObject.t() + def activity(domain, activity) do Jason.OrderedObject.new( "@context": "https://www.w3.org/ns/activitystreams", - id: "https://#{domain}/activities/#{action.id}", - type: action.type, - actor: action.actor, - object: action.object, - to: action.to + id: "https://#{domain}/activities/#{activity.id}", + type: activity.type, + actor: activity.actor, + object: activity.object, + to: activity.to ) end end diff --git a/lib/nulla/models/note.ex b/lib/nulla/models/note.ex index 965e642..57a07e6 100644 --- a/lib/nulla/models/note.ex +++ b/lib/nulla/models/note.ex @@ -29,5 +29,7 @@ defmodule Nulla.Models.Note do |> validate_required([:content, :visibility, :sensitive, :language, :in_reply_to, :user_id]) end + def get_note!(id), do: Repo.get!(Note, id) + def get_all_notes!(user_id), do: Repo.all(from n in Note, where: n.user_id == ^user_id) end diff --git a/lib/nulla_web/controllers/note_controller.ex b/lib/nulla_web/controllers/note_controller.ex index 814a1dd..ae4516a 100644 --- a/lib/nulla_web/controllers/note_controller.ex +++ b/lib/nulla_web/controllers/note_controller.ex @@ -1,8 +1,9 @@ defmodule NullaWeb.NoteController do use NullaWeb, :controller - - alias Nulla.Notes + alias Nulla.Repo alias Nulla.Models.Note + alias Nulla.Models.InstanceSettings + alias Nulla.ActivityPub def index(conn, _params) do notes = Notes.list_notes() @@ -26,11 +27,33 @@ defmodule NullaWeb.NoteController do end end - def show(conn, %{"id" => id}) do - note = Notes.get_note!(id) - render(conn, :show, note: note) + def show(conn, %{"username" => username, "note_id" => note_id}) do + accept = List.first(get_req_header(conn, "accept")) + instance_settings = InstanceSettings.get_instance_settings!() + domain = instance_settings.domain + note = Note.get_note!(note_id) |> Repo.preload([:user, :media_attachments]) + + if username != note.user.username do + conn + |> put_status(:not_found) + |> json(%{error: "Note not found"}) + |> halt() + end + + if accept in ["application/activity+json", "application/ld+json"] do + conn + |> put_resp_content_type("application/activity+json") + |> json(ActivityPub.note(domain, note)) + else + render(conn, :show, domain: domain, note: note, layout: false) + end end + #def show(conn, %{"id" => id}) do + # note = Notes.get_note!(id) + # render(conn, :show, note: note) + #end + def edit(conn, %{"id" => id}) do note = Notes.get_note!(id) changeset = Notes.change_note(note) diff --git a/lib/nulla_web/router.ex b/lib/nulla_web/router.ex index 5af267b..783534f 100644 --- a/lib/nulla_web/router.ex +++ b/lib/nulla_web/router.ex @@ -22,7 +22,7 @@ defmodule NullaWeb.Router do pipe_through :browser get "/@:username", UserController, :show - resources "/users", UserController + get "/@:username/:note_id", NoteController, :show end # Other scopes may use custom stacks.