2024-09-05 00:45:14 +02:00
|
|
|
defmodule Mse25.Directus do
|
2024-10-07 23:44:22 +02:00
|
|
|
@moduledoc """
|
|
|
|
|
Simple Directus client, utilizing Req to do CRUD
|
|
|
|
|
operations.
|
|
|
|
|
|
|
|
|
|
Currently, this client only read data, and supports
|
|
|
|
|
various ways of filtering data.
|
|
|
|
|
|
|
|
|
|
It is by no means generic, since fieldsets are not
|
|
|
|
|
agnostic. It may however be used as a base to create
|
|
|
|
|
a more generic client implementation in Elixir.
|
|
|
|
|
|
|
|
|
|
Directus documentation:
|
|
|
|
|
https://docs.directus.io/
|
|
|
|
|
"""
|
|
|
|
|
|
2024-10-03 14:38:56 +02:00
|
|
|
@draft_filter "filter[status][_eq]=published"
|
|
|
|
|
|
2024-09-05 00:45:14 +02:00
|
|
|
def get_article(slug) do
|
|
|
|
|
get_item(:articles, slug)
|
|
|
|
|
end
|
|
|
|
|
|
2024-10-01 16:44:34 +02:00
|
|
|
def get_articles!(options \\ []) do
|
2024-09-05 00:45:14 +02:00
|
|
|
params =
|
|
|
|
|
[
|
|
|
|
|
"sort=-pubDate",
|
2024-09-06 22:41:12 +02:00
|
|
|
"fields=" <>
|
|
|
|
|
Enum.join(
|
|
|
|
|
[
|
|
|
|
|
"slug",
|
|
|
|
|
"title",
|
|
|
|
|
"date_updated",
|
2024-10-07 23:44:22 +02:00
|
|
|
"pubDate",
|
|
|
|
|
"contents"
|
2024-09-06 22:41:12 +02:00
|
|
|
],
|
|
|
|
|
","
|
|
|
|
|
)
|
2024-09-05 00:45:14 +02:00
|
|
|
]
|
2024-10-04 13:09:50 +02:00
|
|
|
|> annual?(:articles, options)
|
2024-10-01 16:44:34 +02:00
|
|
|
|> query_params_string(options, :articles)
|
2024-09-05 00:45:14 +02:00
|
|
|
|
|
|
|
|
get("/articles?" <> params)
|
|
|
|
|
end
|
|
|
|
|
|
2025-02-11 13:15:58 +01:00
|
|
|
def get_note(slug) do
|
|
|
|
|
get_item(:notes, slug)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def get_notes!(options \\ []) do
|
|
|
|
|
params =
|
|
|
|
|
[
|
|
|
|
|
"fields=" <>
|
|
|
|
|
Enum.join(
|
|
|
|
|
[
|
|
|
|
|
"id",
|
|
|
|
|
"contents",
|
|
|
|
|
"images",
|
|
|
|
|
"date_created",
|
|
|
|
|
"location"
|
|
|
|
|
],
|
|
|
|
|
","
|
|
|
|
|
)
|
|
|
|
|
]
|
|
|
|
|
|> annual?(:notes, options)
|
|
|
|
|
|> query_params_string(options, :notes)
|
|
|
|
|
|
|
|
|
|
get("/notes?" <> params)
|
|
|
|
|
end
|
|
|
|
|
|
2024-10-03 22:52:40 +02:00
|
|
|
def get_album(externalId) do
|
2024-10-16 15:40:53 +02:00
|
|
|
case get_item(
|
|
|
|
|
:albums,
|
|
|
|
|
externalId,
|
|
|
|
|
[
|
|
|
|
|
"*",
|
|
|
|
|
"songs.title",
|
|
|
|
|
"songs.artist.name"
|
|
|
|
|
]
|
|
|
|
|
|> Enum.join(",")
|
|
|
|
|
) do
|
|
|
|
|
{:ok,
|
|
|
|
|
data = %{
|
|
|
|
|
"album" => album,
|
|
|
|
|
"year" => year,
|
|
|
|
|
"songs" => [%{"artist" => %{"name" => artist}} | _]
|
|
|
|
|
}} ->
|
|
|
|
|
{:ok,
|
|
|
|
|
data
|
|
|
|
|
|> Map.put("artist", artist)
|
|
|
|
|
|> Map.put("summary", "#{artist} - #{album} (#{to_string(year)})")}
|
|
|
|
|
|
|
|
|
|
not_found ->
|
|
|
|
|
not_found
|
|
|
|
|
end
|
2024-09-05 00:45:14 +02:00
|
|
|
end
|
|
|
|
|
|
2024-10-03 09:55:44 +02:00
|
|
|
def get_albums!(options \\ []) do
|
|
|
|
|
params =
|
|
|
|
|
[
|
|
|
|
|
"sort=-purchased_at",
|
|
|
|
|
"fields=" <>
|
|
|
|
|
Enum.join(
|
|
|
|
|
[
|
2024-10-04 13:15:27 +02:00
|
|
|
"*",
|
2024-10-03 09:55:44 +02:00
|
|
|
"songs.title",
|
|
|
|
|
"songs.artist.name"
|
|
|
|
|
],
|
|
|
|
|
","
|
|
|
|
|
)
|
|
|
|
|
]
|
2024-10-04 13:15:27 +02:00
|
|
|
|> annual?(:albums, options)
|
2024-10-03 09:55:44 +02:00
|
|
|
|> query_params_string(options, :brutal_legends)
|
|
|
|
|
|
|
|
|
|
get("/albums?" <> params)
|
2024-10-07 23:44:22 +02:00
|
|
|
|> Enum.map(
|
|
|
|
|
fn m = %{
|
|
|
|
|
"album" => album,
|
|
|
|
|
"year" => year,
|
|
|
|
|
"songs" => [%{"artist" => %{"name" => artist}} | _],
|
|
|
|
|
"purchased_at" => purchased_at
|
|
|
|
|
} ->
|
|
|
|
|
m
|
|
|
|
|
|> Map.put("artist", artist)
|
|
|
|
|
|> Map.put(
|
|
|
|
|
"purchase_year",
|
|
|
|
|
String.slice(purchased_at, 0..3)
|
|
|
|
|
)
|
|
|
|
|
|> Map.put("summary", "#{artist} - #{album} (#{to_string(year)})")
|
|
|
|
|
end
|
|
|
|
|
)
|
2024-10-03 09:55:44 +02:00
|
|
|
end
|
|
|
|
|
|
2024-10-03 22:52:40 +02:00
|
|
|
def get_event(slug) do
|
2024-10-03 09:55:44 +02:00
|
|
|
get_item(
|
2024-10-03 22:52:40 +02:00
|
|
|
:events,
|
|
|
|
|
slug,
|
2024-10-03 09:55:44 +02:00
|
|
|
[
|
2024-10-03 22:52:40 +02:00
|
|
|
"*",
|
|
|
|
|
"location.*",
|
|
|
|
|
"poster",
|
|
|
|
|
"bands.artists_id.name",
|
|
|
|
|
"mia.artists_id.name"
|
2024-10-03 09:55:44 +02:00
|
|
|
]
|
|
|
|
|
|> Enum.join(",")
|
|
|
|
|
)
|
|
|
|
|
end
|
|
|
|
|
|
2024-10-01 16:44:34 +02:00
|
|
|
def get_events!(options \\ []) do
|
2024-10-03 09:55:44 +02:00
|
|
|
[sorting, filter] =
|
|
|
|
|
case options[:upcoming] do
|
|
|
|
|
true -> ["started_at", "1"]
|
|
|
|
|
_ -> ["-started_at", "0"]
|
|
|
|
|
end
|
|
|
|
|
|
2024-09-05 00:45:14 +02:00
|
|
|
params =
|
|
|
|
|
[
|
2024-10-03 09:55:44 +02:00
|
|
|
"sort=" <> sorting,
|
|
|
|
|
"filter[upcoming][_eq]=" <> filter,
|
2024-09-06 22:41:12 +02:00
|
|
|
"fields=" <>
|
|
|
|
|
Enum.join(
|
|
|
|
|
[
|
2024-10-16 15:40:53 +02:00
|
|
|
"id",
|
2024-09-06 22:41:12 +02:00
|
|
|
"title",
|
|
|
|
|
"lead",
|
2024-10-01 16:44:34 +02:00
|
|
|
"slug",
|
2024-10-03 22:52:40 +02:00
|
|
|
"poster",
|
|
|
|
|
"category",
|
2024-10-04 13:09:50 +02:00
|
|
|
"started_at",
|
|
|
|
|
"ended_at",
|
2024-10-07 23:44:22 +02:00
|
|
|
"contents",
|
2024-10-16 15:40:53 +02:00
|
|
|
"date_created",
|
2024-09-06 22:41:12 +02:00
|
|
|
"bands.artists_id.name",
|
2024-10-07 14:32:15 +02:00
|
|
|
"mia.artists_id.name",
|
|
|
|
|
"location.*"
|
2024-09-06 22:41:12 +02:00
|
|
|
],
|
|
|
|
|
","
|
|
|
|
|
)
|
2024-09-05 00:45:14 +02:00
|
|
|
]
|
2024-10-04 13:09:50 +02:00
|
|
|
|> annual?(:events, options)
|
2024-10-01 16:44:34 +02:00
|
|
|
|> query_params_string(options, :events)
|
2024-09-05 00:45:14 +02:00
|
|
|
|
|
|
|
|
get("/events?" <> params)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def get_link(slug) do
|
|
|
|
|
get_item(:links, slug)
|
|
|
|
|
end
|
|
|
|
|
|
2024-10-01 16:44:34 +02:00
|
|
|
def get_links!(options \\ []) do
|
2024-09-05 00:45:14 +02:00
|
|
|
params =
|
|
|
|
|
[
|
|
|
|
|
"sort=-pubDate",
|
2024-09-06 22:41:12 +02:00
|
|
|
"fields=" <>
|
|
|
|
|
Enum.join(
|
|
|
|
|
[
|
|
|
|
|
"slug",
|
|
|
|
|
"title",
|
|
|
|
|
"date_updated",
|
|
|
|
|
"pubDate",
|
|
|
|
|
"h1",
|
|
|
|
|
"source",
|
|
|
|
|
"contents"
|
|
|
|
|
],
|
|
|
|
|
","
|
|
|
|
|
)
|
2024-09-05 00:45:14 +02:00
|
|
|
]
|
2024-10-04 13:09:50 +02:00
|
|
|
|> annual?(:links, options)
|
2024-10-01 16:44:34 +02:00
|
|
|
|> query_params_string(options, :links)
|
2024-09-05 00:45:14 +02:00
|
|
|
|
|
|
|
|
get("/links?" <> params)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def get_page(slug) do
|
|
|
|
|
get_item(:pages, slug)
|
|
|
|
|
end
|
|
|
|
|
|
2024-10-03 09:55:44 +02:00
|
|
|
defp get_item(collection, externalId_or_slug, fields \\ "*")
|
|
|
|
|
|
|
|
|
|
defp get_item(:albums, externalId, fields) do
|
|
|
|
|
case get("/albums?fields=" <> fields <> "&filter[externalId][_eq]=" <> externalId) do
|
|
|
|
|
[] -> {:not_found, externalId}
|
|
|
|
|
[item | _] -> {:ok, item}
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2025-02-11 13:15:58 +01:00
|
|
|
defp get_item(:notes, externalId, fields) do
|
|
|
|
|
case get("/notes?fields=" <> fields <> "&filter[id][_eq]=" <> externalId) do
|
|
|
|
|
[] -> {:not_found, externalId}
|
|
|
|
|
[item | _] -> {:ok, item}
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2024-10-03 09:55:44 +02:00
|
|
|
defp get_item(collection, slug, fields) do
|
2024-09-05 00:45:14 +02:00
|
|
|
case get(
|
|
|
|
|
"/" <> to_string(collection) <> "?fields=" <> fields <> "&filter[slug][_eq]=" <> slug
|
|
|
|
|
) do
|
|
|
|
|
[] -> {:not_found, slug}
|
|
|
|
|
[item | _] -> {:ok, item}
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
defp get(resource) do
|
|
|
|
|
[base_url: base_url, token: token] = Application.fetch_env!(:mse25, :directus)
|
|
|
|
|
req = Req.new(base_url: base_url <> "/items")
|
|
|
|
|
|
2024-10-03 14:38:56 +02:00
|
|
|
resource =
|
|
|
|
|
case String.contains?(resource, "?") do
|
|
|
|
|
true -> resource <> "&" <> @draft_filter
|
|
|
|
|
false -> resource <> "?" <> @draft_filter
|
|
|
|
|
end
|
|
|
|
|
|
2024-09-06 22:41:12 +02:00
|
|
|
case Req.get!(req, url: resource, auth: {:bearer, token})
|
|
|
|
|
|> payload do
|
|
|
|
|
{:ok, payload} -> payload
|
|
|
|
|
{:forbidden, message} -> message
|
|
|
|
|
end
|
2024-09-05 00:45:14 +02:00
|
|
|
end
|
|
|
|
|
|
2024-09-06 22:41:12 +02:00
|
|
|
defp payload(%Req.Response{status: 200, body: %{"data" => payload}}), do: {:ok, payload}
|
|
|
|
|
|
|
|
|
|
defp payload(%Req.Response{status: 401}), do: {:forbidden, "Invalid Directus credentials"}
|
2024-09-05 00:45:14 +02:00
|
|
|
|
2024-10-01 16:44:34 +02:00
|
|
|
defp query_params_string(params, options, _),
|
2024-09-05 00:45:14 +02:00
|
|
|
do:
|
|
|
|
|
params
|
|
|
|
|
|> limit?(options)
|
|
|
|
|
|> page?(options)
|
2024-10-03 15:31:19 +02:00
|
|
|
|> query?(options)
|
2024-09-05 00:45:14 +02:00
|
|
|
|> Enum.join("&")
|
|
|
|
|
|
|
|
|
|
defp limit?(params, opts) do
|
|
|
|
|
case opts[:limit] do
|
|
|
|
|
nil -> params
|
|
|
|
|
lmt = _ -> ["limit=" <> to_string(lmt) | params]
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
defp page?(params, opts) do
|
|
|
|
|
case opts[:page] do
|
|
|
|
|
nil -> params
|
2024-10-01 16:44:34 +02:00
|
|
|
pg -> ["page=" <> to_string(pg) | params]
|
|
|
|
|
end
|
|
|
|
|
end
|
2024-10-03 15:31:19 +02:00
|
|
|
|
|
|
|
|
defp query?(params, opts) do
|
|
|
|
|
case opts[:query] do
|
|
|
|
|
nil -> params
|
|
|
|
|
"" -> params
|
2024-10-03 22:52:40 +02:00
|
|
|
pg -> ["filter[title][_icontains]=" <> String.replace(to_string(pg), " ", "%20") | params]
|
2024-10-03 15:31:19 +02:00
|
|
|
end
|
|
|
|
|
end
|
2024-10-04 13:09:50 +02:00
|
|
|
|
|
|
|
|
defp annual?(params, type, opts) do
|
|
|
|
|
case opts[:year] do
|
|
|
|
|
nil ->
|
|
|
|
|
params
|
|
|
|
|
|
|
|
|
|
year ->
|
|
|
|
|
year_filter(type, year, params)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
defp year_filter(:albums, year, params),
|
|
|
|
|
do: [
|
|
|
|
|
"filter[purchased_at][_gte]=" <> to_string(year) <> "-01-01",
|
|
|
|
|
"filter[purchased_at][_lte]=" <> to_string(year) <> "-12-31"
|
|
|
|
|
| params
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
defp year_filter(:articles, year, params),
|
|
|
|
|
do: [
|
|
|
|
|
"filter[pubDate][_gte]=" <> to_string(year) <> "-01-01",
|
|
|
|
|
"filter[pubDate][_lte]=" <> to_string(year) <> "-12-31"
|
|
|
|
|
| params
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
defp year_filter(:events, year, params),
|
|
|
|
|
do: [
|
|
|
|
|
"filter[started_at][_gte]=" <> to_string(year) <> "-01-01",
|
|
|
|
|
"filter[ended_at][_lte]=" <> to_string(year) <> "-12-31"
|
|
|
|
|
| params
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
defp year_filter(:links, year, params),
|
|
|
|
|
do: [
|
|
|
|
|
"filter[pubDate][_gte]=" <> to_string(year) <> "-01-01",
|
|
|
|
|
"filter[pubDate][_lte]=" <> to_string(year) <> "-12-31"
|
|
|
|
|
| params
|
|
|
|
|
]
|
2024-09-05 00:45:14 +02:00
|
|
|
end
|