analytics / lib /plausible_web /controllers /api /internal /annotations_controller.ex
Leon4gr45's picture
Upload folder using huggingface_hub (part 2)
8da2481 verified
Raw
History Blame Contribute Delete
4.76 kB
defmodule PlausibleWeb.Api.Internal.AnnotationsController do
@moduledoc """
Internal API controller for annotations.
"""
use Plausible
use PlausibleWeb, :controller
use PlausibleWeb.Plugs.ErrorHandler
alias Plausible.Annotations
alias Plausible.ChangesetHelpers
alias Plausible.Stats.{ApiQueryParser, QueryPeriod}
alias PlausibleWeb.Api.Helpers, as: H
def index(conn, params) do
user = conn.assigns[:current_user]
site = conn.assigns.site
site_role = conn.assigns.site_role
with {:ok, input_date_range} <- parse_input_date_range(params),
{:ok, relative_date} <- parse_relative_date(params) do
now = DateTime.utc_now(:second)
range_in_site_tz =
QueryPeriod.build_range_for_site(input_date_range, site, relative_date, now)
case Annotations.get_all_for_site(site, site_role, user, range_in_site_tz) do
{:ok, result} ->
json(conn, result)
{:error, :not_enough_permissions} ->
json(conn, "Not enough permissions to get annotations")
end
else
{:error, message} -> H.bad_request(conn, message)
end
end
defp parse_input_date_range(%{
"date_range_start" => start,
"date_range_end" => end_
})
when is_binary(start) and is_binary(end_) do
case ApiQueryParser.parse_input_date_range([start, end_]) do
{:ok, parsed} -> {:ok, parsed}
{:error, %{message: message}} -> {:error, message}
end
end
defp parse_input_date_range(%{"date_range" => "realtime"}), do: {:ok, :realtime}
defp parse_input_date_range(%{"date_range" => "realtime_30m"}), do: {:ok, :realtime_30m}
defp parse_input_date_range(%{"date_range" => date_range}) do
case ApiQueryParser.parse_input_date_range(date_range) do
{:ok, parsed} -> {:ok, parsed}
{:error, %{message: message}} -> {:error, message}
end
end
defp parse_input_date_range(_), do: {:error, "Required 'date_range' parameter missing"}
defp parse_relative_date(%{"relative_date" => date}) when is_binary(date) do
case Date.from_iso8601(date) do
{:ok, date} -> {:ok, date}
_ -> {:error, "Failed to convert '#{date}' to date"}
end
end
defp parse_relative_date(_), do: {:ok, nil}
def create(conn, params) do
user = conn.assigns[:current_user]
site = conn.assigns.site
site_role = conn.assigns.site_role
case Annotations.insert_one(user, site, site_role, params) do
{:error, :not_enough_permissions} ->
H.not_enough_permissions(conn, "Not enough permissions to create annotation")
{:error, :annotations_limit_reached} ->
H.not_enough_permissions(conn, "Annotations limit reached")
{:error, {:invalid_annotation, errors}} when is_list(errors) ->
conn
|> put_status(400)
|> json(%{
error: ChangesetHelpers.serialize_first_error(errors)
})
{:ok, annotation} ->
json(conn, annotation)
end
end
def update(conn, params) do
user = conn.assigns[:current_user]
site = conn.assigns.site
site_role = conn.assigns.site_role
annotation_id = normalize_annotation_id_param(params["annotation_id"])
case Annotations.update_one(user, site, site_role, annotation_id, params) do
{:error, :not_enough_permissions} ->
H.not_enough_permissions(conn, "Not enough permissions to edit annotation")
{:error, :annotation_not_found} ->
annotation_not_found(conn, params["annotation_id"])
{:error, {:invalid_annotation, errors}} when is_list(errors) ->
conn
|> put_status(400)
|> json(%{
error: ChangesetHelpers.serialize_first_error(errors)
})
{:ok, annotation} ->
json(conn, annotation)
end
end
def delete(conn, params) do
user = conn.assigns[:current_user]
site = conn.assigns.site
site_role = conn.assigns.site_role
annotation_id = normalize_annotation_id_param(params["annotation_id"])
case Annotations.delete_one(user, site, site_role, annotation_id) do
{:error, :not_enough_permissions} ->
H.not_enough_permissions(conn, "Not enough permissions to delete annotation")
{:error, :annotation_not_found} ->
annotation_not_found(conn, params["annotation_id"])
{:ok, annotation} ->
json(conn, annotation)
end
end
@spec normalize_annotation_id_param(any()) :: nil | pos_integer()
defp normalize_annotation_id_param(input) do
case Integer.parse(input) do
{int_value, ""} when int_value > 0 -> int_value
_ -> nil
end
end
defp annotation_not_found(%Plug.Conn{} = conn, annotation_id_param) do
H.not_found(conn, "Annotation not found with ID #{inspect(annotation_id_param)}")
end
end