defmodule ClacksWeb.OutboxController do use ClacksWeb, :controller alias Clacks.{Actor, Timeline} @context "https://www.w3.org/ns/activitystreams" plug :get_actor defp get_actor(%Plug.Conn{path_params: %{"username" => username}} = conn, _opts) do case Actor.get_by_nickname(username) do %Actor{local: true} = actor -> assign(conn, :actor, actor) _ -> conn |> put_status(404) |> json(%{error: "Not Found"}) end end def outbox(conn, %{} = params) do actor = conn.assigns[:actor] activities = Timeline.actor_timeline(actor, params, true) data = %{ "@context" => @context, "type" => "OrderedCollection", "id" => current_url(conn, %{}), "first" => outbox_page(conn, params, activities) } conn |> put_resp_header("content-type", "application/activity+json") |> json(data) end def outbox(conn, params) do actor = conn.assigns[:actor] activities = Timeline.actor_timeline(actor, params, true) data = outbox_page(conn, params, activities) |> Map.put("@context", @context) conn |> put_resp_header("content-type", "application/activity+json") |> json(data) end defp outbox_page(conn, pagination_params, activities) do next = case activities do [] -> # todo: is nil the right thing here? nil _ -> last_id = List.last(activities).id current_url(conn, %{max_id: last_id}) end %{ "type" => "OrderedColletionPage", "partOf" => current_url(conn, %{}), "id" => current_url(conn, pagination_params), "next" => next, "orderedItems" => Enum.map(activities, & &1.data) } end end