203 lines
4.8 KiB
Elixir
203 lines
4.8 KiB
Elixir
defmodule Ferne.BlockDb do
|
|
@moduledoc """
|
|
Keeps a list of blocks and various handy functions to access info about them.
|
|
"""
|
|
alias Ferne.Repo
|
|
alias Ferne.{Event, Block}
|
|
import Ecto.Query
|
|
|
|
@blocks %{
|
|
"custom_fields" => Ferne.BlockDb.CustomFields,
|
|
"discord_login" => Ferne.BlockDb.DiscordLogin,
|
|
"ffxiv_roles" => Ferne.BlockDb.FFXIVRoles,
|
|
"parties" => Ferne.BlockDb.Parties,
|
|
"titles" => Ferne.BlockDb.Titles
|
|
}
|
|
|
|
## Single Block Queries
|
|
|
|
def block_description(block) do
|
|
@blocks[block].description()
|
|
end
|
|
|
|
def block_id(block) do
|
|
@blocks[block].id()
|
|
end
|
|
|
|
def block_name(block) do
|
|
@blocks[block].name()
|
|
end
|
|
|
|
def block_has_settings?(block) do
|
|
@blocks[block].has_settings()
|
|
end
|
|
|
|
def block_has_special_section?(block) do
|
|
@blocks[block].has_special_section()
|
|
end
|
|
|
|
def block_extends_signup_page?(block) do
|
|
@blocks[block].extends_signup_page()
|
|
end
|
|
|
|
def block_interact_with_attendee?(block) do
|
|
@blocks[block].interacts_with_attendee()
|
|
end
|
|
|
|
def block_special_section_icon(block) do
|
|
@blocks[block].special_section_icon()
|
|
end
|
|
|
|
def block_special_section_name(block) do
|
|
@blocks[block].special_section_name()
|
|
end
|
|
|
|
def has_block?(blocks, id) do
|
|
blocks
|
|
|> Enum.map(& &1.identifier)
|
|
|> Enum.member?(id)
|
|
end
|
|
|
|
def has_block_with_special_section?(blocks) do
|
|
blocks
|
|
|> Enum.map(& &1.identifier)
|
|
|> Enum.any?(&block_has_special_section?/1)
|
|
end
|
|
|
|
def block_has_data?(blocks, id) do
|
|
block = Enum.find(blocks, &(&1.identifier == id))
|
|
|
|
block.data["data"] && !Enum.empty?(block.data["data"])
|
|
end
|
|
|
|
def block_data_or_default(block, key, default) do
|
|
if block.data && block.data["data"] do
|
|
block.data["data"][key] || default
|
|
else
|
|
default
|
|
end
|
|
end
|
|
|
|
def find_block(blocks, id) do
|
|
Enum.find(blocks, &(&1.identifier == id))
|
|
end
|
|
|
|
## Controller Queries
|
|
@doc """
|
|
Handles a GET request for a block setting page
|
|
"""
|
|
def block_controller_get(conn, block, event) do
|
|
if block_has_settings?(block) do
|
|
@blocks[block].controller_get(conn, event)
|
|
end
|
|
end
|
|
|
|
@doc """
|
|
Handles a POST request for a block setting page.
|
|
"""
|
|
def block_controller_post(conn, block, event, params) do
|
|
if block_has_settings?(block) do
|
|
@blocks[block].controller_post(conn, event, params)
|
|
end
|
|
end
|
|
|
|
@doc """
|
|
Handles a GET request for a block special page.
|
|
"""
|
|
def block_controller_special_get(conn, block, event) do
|
|
if block_has_special_section?(block) do
|
|
@blocks[block].controller_special_get(conn, event)
|
|
end
|
|
end
|
|
|
|
@doc """
|
|
Handles a POST request for a block special page.
|
|
"""
|
|
def block_controller_special_post(conn, block, event, params) do
|
|
if block_has_special_section?(block) do
|
|
@blocks[block].controller_special_post(conn, event, params)
|
|
end
|
|
end
|
|
|
|
## Insertion Queries
|
|
@doc """
|
|
Insert a block.
|
|
"""
|
|
def create_block(attrs, event) do
|
|
%Block{}
|
|
|> Block.change_block(attrs)
|
|
|> Ecto.Changeset.change(event_id: event.id)
|
|
|> Repo.insert()
|
|
end
|
|
|
|
## Modification Queries
|
|
@doc """
|
|
Delete a block.
|
|
"""
|
|
def delete_block(block) do
|
|
Repo.delete(block)
|
|
end
|
|
|
|
## Event-based Queries
|
|
@doc """
|
|
Gets a single, specified block for an event.
|
|
"""
|
|
def get_block_for_event(id, event) do
|
|
query =
|
|
from b in Block,
|
|
where: b.identifier == ^id and b.event_id == ^event.id
|
|
|
|
Repo.one(query)
|
|
end
|
|
|
|
@doc """
|
|
Get blocks that are in use for an event.
|
|
"""
|
|
def get_blocks_for_event(event) do
|
|
query =
|
|
from e in Event,
|
|
where: e.id == ^event.id,
|
|
join: b in Block,
|
|
on: b.event_id == e.id,
|
|
select: b
|
|
|
|
Repo.all(query)
|
|
end
|
|
|
|
@doc """
|
|
Get blocks that are not used for an event. Uses a list of used
|
|
blocks to avoid a query, since it's supposed to be used with the prior
|
|
function.
|
|
"""
|
|
def get_unused_blocks_for_event(used_blocks) do
|
|
ids = used_blocks |> Enum.map(& &1.identifier)
|
|
|
|
Block.valid_ids()
|
|
|> Enum.reject(&Enum.member?(ids, &1))
|
|
end
|
|
|
|
## Display Queries
|
|
@doc """
|
|
Gets a list of all enabled block metadata. This returns a list of "headers" to be matched with
|
|
what's in an attendees `custom_data` field.
|
|
"""
|
|
def get_metadata_for_event(event) do
|
|
[]
|
|
|> get_metadata_for_block(event, "custom_fields")
|
|
|> get_metadata_for_block(event, "discord_login")
|
|
|> get_metadata_for_block(event, "ffxiv_roles")
|
|
|> get_metadata_for_block(event, "parties")
|
|
|> get_metadata_for_block(event, "titles")
|
|
|> Enum.concat()
|
|
end
|
|
|
|
def get_metadata_for_block(meta, event, block_id) do
|
|
if event.blocks && Enum.map(event.blocks, & &1.identifier) |> Enum.member?(block_id) do
|
|
data = Enum.find(event.blocks, &(&1.identifier == block_id)).data["data"]
|
|
[@blocks[block_id].get_metadata!(data) | meta]
|
|
else
|
|
meta
|
|
end
|
|
end
|
|
end
|