add source query support

This commit is contained in:
Inhji 2023-06-11 22:22:17 +02:00
parent 7112d92c14
commit 627c758acd
5 changed files with 103 additions and 32 deletions

View file

@ -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

View file

@ -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.

View file

@ -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

View file

@ -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

View file

@ -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