diff --git a/lib/chiya/channels/channel.ex b/lib/chiya/channels/channel.ex index 15d2e1f..b2f4d9d 100644 --- a/lib/chiya/channels/channel.ex +++ b/lib/chiya/channels/channel.ex @@ -3,7 +3,7 @@ defmodule Chiya.Channels.Channel do import Ecto.Changeset alias Chiya.Channels.ChannelSlug - @derive {Jason.Encoder, only: [:id, :name, :content, :slug, :visibility]} + @derive {Jason.Encoder, only: [:name]} schema "channels" do field :content, :string field :name, :string diff --git a/lib/chiya/notes.ex b/lib/chiya/notes.ex index f066cf1..414cb2a 100644 --- a/lib/chiya/notes.ex +++ b/lib/chiya/notes.ex @@ -104,7 +104,11 @@ defmodule Chiya.Notes do ** (Ecto.NoResultsError) """ - def get_note_preloaded!(id), do: Repo.get!(Note, id) |> preload_note() + def get_note_preloaded!(id), + do: + Note + |> Repo.get!(id) + |> preload_note() @doc """ Gets a single note by its slug and preloads it. @@ -120,7 +124,11 @@ defmodule Chiya.Notes do ** (Ecto.NoResultsError) """ - def get_note_by_slug_preloaded!(slug), do: Repo.get_by!(Note, slug: slug) |> preload_note() + def get_note_by_slug_preloaded!(slug), + do: + Note + |> Repo.get_by!(slug: slug) + |> preload_note() @doc """ Gets a single note by its slug and preloads it. @@ -136,7 +144,25 @@ defmodule Chiya.Notes do nil """ - def get_note_by_slug_preloaded(slug), do: Repo.get_by(Note, slug: slug) |> preload_note() + def get_note_by_slug_preloaded(slug), + do: + Note + |> Repo.get_by(slug: slug) + |> preload_note() + + def get_public_note_by_slug_preloaded(slug), + do: + Note + |> where([n], not is_nil(n.published_at)) + |> Repo.get_by(slug: slug) + |> preload_note() + + def get_public_note_by_slug_preloaded!(slug), + do: + Note + |> where([n], not is_nil(n.published_at)) + |> Repo.get_by!(slug: slug) + |> preload_note() @doc """ Creates a note. diff --git a/lib/chiya/notes/note.ex b/lib/chiya/notes/note.ex index eb9a8d9..83f7049 100644 --- a/lib/chiya/notes/note.ex +++ b/lib/chiya/notes/note.ex @@ -9,8 +9,9 @@ defmodule Chiya.Notes.Note do statics: ChiyaWeb.static_paths() @reserved_slugs ~w(user admin dev api) + @note_url_regex ~r/\/note\/([a-z0-9-]+)/ - @derive {Jason.Encoder, only: [:id, :name, :content, :slug, :channels]} + @derive {Jason.Encoder, only: [:id, :name, :content, :slug, :channels, :tags]} schema "notes" do field :content, :string @@ -50,9 +51,19 @@ defmodule Chiya.Notes.Note do timestamps() end + def note_path(note) do + ~p"/note/#{note.slug}" + end + def note_url(note) do - URI.merge(ChiyaWeb.Endpoint.url(), ~p"/note/#{note.slug}") - |> to_string() + Phoenix.VerifiedRoutes.url(~p"/note/#{note.slug}") + end + + def note_slug(note_url) do + case Regex.run(@note_url_regex, note_url) do + nil -> {:error, nil} + [_full, slug] -> {:ok, slug} + end end @doc false diff --git a/lib/chiya/tags/tag.ex b/lib/chiya/tags/tag.ex index 90952a8..35a9c72 100644 --- a/lib/chiya/tags/tag.ex +++ b/lib/chiya/tags/tag.ex @@ -6,6 +6,7 @@ defmodule Chiya.Tags.Tag do import Ecto.Changeset alias Chiya.Tags.TagSlug + @derive {Jason.Encoder, only: [:name]} schema "tags" do field :name, :string field :slug, TagSlug.Type diff --git a/lib/chiya_web/indie/micropub_handler.ex b/lib/chiya_web/indie/micropub_handler.ex index c0d4a19..cdbd8e8 100644 --- a/lib/chiya_web/indie/micropub_handler.ex +++ b/lib/chiya_web/indie/micropub_handler.ex @@ -5,6 +5,15 @@ defmodule ChiyaWeb.Indie.MicropubHandler do alias ChiyaWeb.Indie.Properties, as: Props alias ChiyaWeb.Indie.Token + @default_properties [ + "name", + "content", + "published_at", + "slug", + "channels", + "tags" + ] + @impl true def handle_create(type, properties, access_token) do Logger.info("Handle create") @@ -41,37 +50,59 @@ defmodule ChiyaWeb.Indie.MicropubHandler do {:error, :insufficient_scope} end - @impl true - def handle_source_query(_url, _filter_properties, _access_token) do - {:error, :insufficient_scope} - end - @impl true def handle_media(_files, _access_token) do {:error, :insufficient_scope} end @impl true - def handle_config_query(_access_token) do - channels = Chiya.Channels.list_channels() + def handle_source_query(url, filter_properties, access_token) do + filter_properties = + if Enum.empty?(filter_properties), + do: @default_properties, + else: filter_properties - {:ok, - %{ - "destination" => [], - "post-types" => [ + with :ok <- verify_token(access_token), + {:ok, slug} <- Chiya.Notes.Note.note_slug(url), + note <- Chiya.Notes.get_public_note_by_slug_preloaded!(slug) do + filtered_note = + Map.filter(note, fn {key, _val} -> + Enum.member?(filter_properties, to_string(key)) + end) + + {:ok, filtered_note} + else + _ -> {:error, :insufficient_scope} + end + end + + @impl true + def handle_config_query(access_token) do + case verify_token(access_token) do + :ok -> + channels = Chiya.Channels.list_channels() + + {:ok, %{ - "type" => "note", - "name" => "Note" - } - ], - "channels" => - Enum.map(channels, fn c -> - %{ - "uid" => c.slug, - "name" => c.name - } - end) - }} + "destination" => [], + "post-types" => [ + %{ + "type" => "note", + "name" => "Note" + } + ], + "channels" => + Enum.map(channels, fn c -> + %{ + "uid" => c.slug, + "name" => c.name + } + end) + }} + + _ -> + {:error, :insufficient_scope} + end end @impl true @@ -85,10 +116,12 @@ defmodule ChiyaWeb.Indie.MicropubHandler do @impl true def handle_category_query(access_token) do case verify_token(access_token) do - :ok -> + :ok -> tags = Enum.map(Chiya.Tags.list_tags(), fn t -> t.name end) {:ok, %{"categories" => tags}} - _ -> {:error, :insufficient_scope} + + _ -> + {:error, :insufficient_scope} end end