Preparatory work
This commit is contained in:
parent
a22ba724df
commit
386a331956
9 changed files with 217 additions and 1 deletions
|
|
@ -5,11 +5,14 @@ defmodule BirdyChat.Application do
|
|||
|
||||
use Application
|
||||
|
||||
@env Mix.env
|
||||
|
||||
@impl true
|
||||
def start(_type, _args) do
|
||||
children = [
|
||||
BirdyChatWeb.Telemetry,
|
||||
BirdyChat.Repo,
|
||||
{BirdyChat.Identity, env: @env},
|
||||
{DNSCluster, query: Application.get_env(:birdy_chat, :dns_cluster_query) || :ignore},
|
||||
{Phoenix.PubSub, name: BirdyChat.PubSub},
|
||||
# Start a worker by calling: BirdyChat.Worker.start_link(arg)
|
||||
|
|
|
|||
56
lib/birdy_chat/identity.ex
Normal file
56
lib/birdy_chat/identity.ex
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
defmodule BirdyChat.Identity do
|
||||
use Agent
|
||||
|
||||
defstruct [:identity, :peers, :mode]
|
||||
|
||||
def start_link(opts) do
|
||||
name = opts[:name] || __MODULE__
|
||||
input = opts[:input]
|
||||
|
||||
Agent.start_link(fn -> initialise(input) end, name: name)
|
||||
end
|
||||
|
||||
def mode(pid \\ __MODULE__) do
|
||||
Agent.get(pid, & &1.mode)
|
||||
end
|
||||
|
||||
def identity(pid \\ __MODULE__) do
|
||||
Agent.get(pid, & &1.identity)
|
||||
end
|
||||
|
||||
def peers(pid \\ __MODULE__) do
|
||||
Agent.get(pid, & &1.peers)
|
||||
end
|
||||
|
||||
def parse_identity(value) do
|
||||
case Integer.parse(value) do
|
||||
{_number, ""} -> value
|
||||
_ -> raise "Identity must be a string that can be converted to Integer, got: >>#{value}<<."
|
||||
end
|
||||
end
|
||||
|
||||
def parse_peers(peers) do
|
||||
values = String.split(peers, ";")
|
||||
|
||||
for value <- values,
|
||||
[identity, address] = String.split(value, "::"), into: %{} do
|
||||
{identity, address}
|
||||
end
|
||||
end
|
||||
|
||||
def initialise(%{peers: peers, identity: identity}) do
|
||||
peers = parse_peers(peers)
|
||||
identity = parse_identity(identity)
|
||||
|
||||
%__MODULE__{identity: identity, peers: peers, mode: :connected}
|
||||
end
|
||||
|
||||
def initialise(nil) do
|
||||
identity = System.get_env("BIRDY_CHAT_IDENTITY")
|
||||
peers = System.get_env("BIRDY_CHAT_PEERS")
|
||||
|
||||
case {identity, peers} do
|
||||
{nil, nil} -> %__MODULE__{identity: "test", peers: [], mode: :singleton}
|
||||
end
|
||||
end
|
||||
end
|
||||
46
lib/birdy_chat/message.ex
Normal file
46
lib/birdy_chat/message.ex
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
defmodule BirdyChat.Message do
|
||||
use Ecto.Schema
|
||||
|
||||
embedded_schema do
|
||||
field :from, :string
|
||||
field :to, :string
|
||||
field :message, :string
|
||||
end
|
||||
|
||||
def validate(params) do
|
||||
changeset =
|
||||
%__MODULE__{}
|
||||
|> Ecto.Changeset.cast(params, [:from, :to, :message])
|
||||
|> Ecto.Changeset.validate_required([:from, :to, :message])
|
||||
|
||||
if changeset.valid? do
|
||||
{:ok, changeset}
|
||||
else
|
||||
{:error, changeset}
|
||||
end
|
||||
end
|
||||
|
||||
def write(%{to: to, from: from, message: message} = msg) do
|
||||
message_to_write = "#{from}: #{message}\n"
|
||||
:ok = create_messages_folder!(Application.app_dir(:birdy_chat, ["priv", "messages"]))
|
||||
path = Application.app_dir(:birdy_chat, ["priv", "messages", "#{to}.txt"])
|
||||
result = File.write!(path, message_to_write, [:append])
|
||||
{:ok, msg}
|
||||
end
|
||||
|
||||
def create_messages_folder!(path) do
|
||||
case File.mkdir(path) do
|
||||
:ok ->
|
||||
:ok
|
||||
|
||||
{:error, :eexist} ->
|
||||
:ok
|
||||
|
||||
{:error, reason} ->
|
||||
raise File.Error,
|
||||
reason: reason,
|
||||
action: "make directory",
|
||||
path: IO.chardata_to_string(path)
|
||||
end
|
||||
end
|
||||
end
|
||||
20
lib/birdy_chat_web/api/messages/controller.ex
Normal file
20
lib/birdy_chat_web/api/messages/controller.ex
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
defmodule BirdyChatWeb.Api.Messages.Controller do
|
||||
use BirdyChatWeb, :controller
|
||||
|
||||
def create(conn, params) do
|
||||
case BirdyChat.Message.validate(params) do
|
||||
{:ok, changeset} ->
|
||||
case BirdyChat.Message.write(changeset.changes) do
|
||||
{:ok, msg} ->
|
||||
conn
|
||||
|> put_status(:created)
|
||||
|> render(:create, message: msg)
|
||||
end
|
||||
|
||||
{:error, changeset} ->
|
||||
conn
|
||||
|> put_status(:unprocessable_entity)
|
||||
|> render(:error, changeset: changeset)
|
||||
end
|
||||
end
|
||||
end
|
||||
14
lib/birdy_chat_web/api/messages/json.ex
Normal file
14
lib/birdy_chat_web/api/messages/json.ex
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
defmodule BirdyChatWeb.Api.Messages.JSON do
|
||||
def render("create.json", %{message: message}) do
|
||||
message
|
||||
end
|
||||
|
||||
def render("error.json", %{changeset: changeset}) do
|
||||
errors = Ecto.Changeset.traverse_errors(changeset, &get_error/1)
|
||||
%{errors: errors}
|
||||
end
|
||||
|
||||
def get_error({msg, opts}) do
|
||||
Gettext.dgettext(BirdyChatWeb.Gettext, "errors", msg, opts)
|
||||
end
|
||||
end
|
||||
|
|
@ -20,6 +20,12 @@ defmodule BirdyChatWeb.Router do
|
|||
get "/", PageController, :home
|
||||
end
|
||||
|
||||
scope "/api", BirdyChatWeb.Api do
|
||||
pipe_through [:api]
|
||||
|
||||
post "/messages", Messages.Controller, :create
|
||||
end
|
||||
|
||||
# Other scopes may use custom stacks.
|
||||
# scope "/api", BirdyChatWeb do
|
||||
# pipe_through :api
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue