Added module for providing subroutines for repetitive queries

This commit is contained in:
Alex Tavarez
2025-09-02 17:16:27 -04:00
parent abc6bbd4af
commit 819c38c110

View File

@@ -0,0 +1,173 @@
defmodule Sukaato.StandardQueries do
alias Sukaato.{Repo, User, Post}
alias SukaatoWeb.Marker
import Ecto.Changeset
import Ecto.Query
@rel_proj_root "../.."
@site_config_file Path.expand(@rel_proj_root <> "/site.toml", __DIR__)
@site_config Toml.decode_file(@site_config_file)
@admin_username elem(@site_config, 1)["site"]["username"]
@markdown_user_root Path.expand("../../lib/sukaato_web/controllers/page_md/users", __DIR__)
@tables %{
user: User,
post: Post
}
def add_entry(schema, type \\ :user) do
case type do
:user ->
entry = @tables.user.changeset(%User{}, schema)
result = Repo.insert(entry, on_conflict: {:replace_all_except, [:id, :slug, :inserted_at, :updated_at]})
result
end
end
def get_admin() do
query = from u in @tables.user, select: {u.username, u.perms}
results = Repo.all(query)
results = Enum.filter(results, fn r -> Enum.at(elem(r, 1), length(elem(r, 1)) - 1) == 15 end)
results = Enum.map(results, fn r -> elem(r, 0) end)
results
end
@doc """
Gets the GPG public keys of the given user.
"""
def get_pubkeys(username \\ @admin_username, gpg_id \\ "") do
query = from u in @tables.user, select: u.pub_keys, where: u.username == ^username
pubkeys = Repo.all(query)
if pubkeys != nil do
if length(pubkeys) > 0 do
if gpg_id != "" do
pubkeys = Enum.filter(pubkeys, fn k -> Map.has_key?(k, gpg_id) end)
if length(pubkeys) > 0 do
pubkeys = Enum.map(pubkeys, fn k -> {gpg_id, k[gpg_id]} end)
{:ok, pubkeys}
else
{:ok, [{gpg_id, pubkeys}]}
end
else
key_choices = Enum.map(pubkeys, fn k -> Enum.random(Map.keys(k)) end)
selection = Enum.zip([key_choices, pubkeys])
pubkeys = Enum.map(selection, fn s -> {elem(s, 0), elem(s, 1)[elem(s, 0)]} end)
{:ok, pubkeys}
end
else
{:ok, [{gpg_id, ""}]}
end
else
{:ok, [{gpg_id, ""}]}
end
# {:ok, {username, gpg_id, ""}}
end
@doc """
Gets and compiles a list of affiliate links or protocol addresses for the givn user.
"""
def get_inboxes(username \\ @admin_username, filter_protocols \\ [], method \\ :reject) do
query = from u in @tables.user, select: u.email, where: u.username == ^username
emails = Repo.all(query)
query = from u in @tables.user, select: u.affil, where: u.username == ^username
addresses = Repo.all(query)
# @TODO create a database changeset schema for this in 'lib/sukaato/vschemas.ex'
emails = Enum.map(emails, fn e -> %{"name" => "EMAIL", "address" => e, "protocol" => "mailto", "scheme_postfix" => ":", "icon_uri" => "", "icon_name" => "envelope-solid"} end)
if length(filter_protocols) > 0 do
filter = filter_protocols
addresses = if method == :reject, do: Enum.filter(addresses, fn a -> !Enum.member?(filter, a.protocol) end), else: Enum.filter(addresses, fn a -> Enum.member?(filter, a.protocol) end)
inboxes = [emails | addresses]
# inboxes = Enum.map(inboxes, fn i -> for {k, v} <- i, into: %{}, do: {String.to_atom(k), v} end)
{:ok, inboxes}
else
inboxes = [emails | addresses]
# inboxes = addresses
{:ok, inboxes}
end
end
def verify_login_token(token) when is_binary(token) do
token = String.split(token, ":", parts: 2)
username = Enum.at(token, 0)
query = from u in @tables.user, select: u.user_token, where: u.username == ^username
db_token = Repo.one(query)
if is_nil(db_token) do
false
else
match_token = Enum.at(token, 1)
match_token == db_token
end
end
def absorb_login_token(token) when is_binary(token) do
token = String.split(token, ":", parts: 2)
username = Enum.at(token, 0)
query = from u in @tables.user, where: u.username == ^username
result = Repo.one(query)
if is_nil(result) do
{:ok, result}
else
token = Enum.at(token, 1)
demand = change(result, user_token: token)
result = Repo.update(demand)
{:ok, result}
end
end
def dump_login_token(token) when is_binary(token) do
token = String.split(token, ":", parts: 2)
username = Enum.at(token, 0)
query = from u in @tables.user, where: u.username == ^username
result = Repo.one(query)
demand = if is_nil(result), do: result, else: change(result, user_token: nil)
result = if is_nil(demand), do: demand, else: Repo.update(demand)
result
end
defp synchronize_posts(for_user, path \\ "") do
user_posts = if path != "", do: Path.wildcard(path), else: Path.wildcard(@markdown_user_root <> "/" <> for_user <> "/posts/*.md")
if length(user_posts) > 0 do
# user_posts = if !is_list(user_posts), do: [user_posts], else: user_posts
user_posts = Enum.map(user_posts, fn p -> Path.basename(p) end)
user_posts = Enum.map(user_posts, fn p -> Marker.render_mark(p, :markdown_post, for_user) end)
user_posts = Enum.filter(user_posts, fn p -> elem(p, 0) == :ok end)
user_posts = Enum.map(user_posts, fn p -> Map.put(elem(p, 1), "content", elem(p, 2)) end)
user_posts = Enum.map(user_posts, fn p -> if Map.has_key?(p, "ledit"), do: Map.put(p, "ledit", Date.from_iso8601!(p["ledit"])), else: p end)
# user_posts = Enum.map(user_posts, fn p -> if Map.has_key?(p, "auth_id"), do: Map.put(p, "auth_id", elem(Integer.parse(p["auth_id"]), 0)), else: p end)
# user_posts = Enum.map(user_posts, fn p -> if Map.has_key?(p, "rev_id"), do: Map.put(p, "rev_id", elem(Integer.parse(p["auth_id"]), 0)), else: p end)
user_posts = Map.new(user_posts, fn {k, v} -> {String.to_atom(k), v} end)
# @TODO push user_posts to database
user_posts = Enum.map(user_posts, fn p -> @tables.post.changeset(%Post{}, p) end)
results = Repo.insert_all(@tables.post, user_posts, on_conflict: {:replace_all_except, [:id, :slug, :inserted_at, :updated_at]})
results
else
{:ok, user_posts}
end
end
def synchronize(sync_source \\ :storage, for_user \\ @admin_username) do
if is_atom(sync_source) do
case sync_source do
:storage ->
results = synchronize_posts(for_user)
results
end
end
if is_binary(sync_source) do
results = synchronize_posts(for_user, sync_source)
results
end
end
end