diff options
Diffstat (limited to 'shard/lib/cli/cli.ex')
-rw-r--r-- | shard/lib/cli/cli.ex | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/shard/lib/cli/cli.ex b/shard/lib/cli/cli.ex new file mode 100644 index 0000000..2fbf8c2 --- /dev/null +++ b/shard/lib/cli/cli.ex @@ -0,0 +1,98 @@ +defmodule SCLI do + @moduledoc """ + Small command line interface for the chat application + """ + + def run() do + run(nil) + end + + defp run(pid) do + handle_messages() + + nick = Shard.Identity.get_nickname + prompt = case pid do + nil -> "(no channel) #{nick}: " + _ -> + {:chat, chan} = GenServer.call(pid, :manifest) + "##{chan} #{nick}: " + end + + str = prompt |> IO.gets |> String.trim + cond do + str == "/quit" -> + nil + String.slice(str, 0..0) == "/" -> + command = str |> String.slice(1..-1) |> String.split(" ") + pid2 = handle_command(pid, command) + run(pid2) + true -> + if str != "" do + GenServer.cast(pid, {:chat_send, str}) + end + run(pid) + end + end + + defp handle_messages() do + receive do + {:chat_recv, chan, {ts, nick, msg}} -> + IO.puts "#{ts |> DateTime.from_unix! |> DateTime.to_iso8601} ##{chan} <#{nick}> #{msg}" + handle_messages() + {:chat_send, _, _} -> + # do nothing + handle_messages() + after 10 -> nil + end + end + + defp handle_command(pid, ["connect", ipstr, portstr]) do + {:ok, ip} = :inet.parse_address (to_charlist ipstr) + {port, _} = Integer.parse portstr + Shard.Manager.add_peer(ip, port) + pid + end + + defp handle_command(pid, ["list"]) do + IO.puts "List of known channels:" + + for {_chid, manifest, _chpid} <- :ets.tab2list(:shard_db) do + {:chat, chan} = manifest + IO.puts "##{chan}" + end + pid + end + + defp handle_command(pid, ["hist"]) do + GenServer.call(pid, {:read_history, nil, 25}) + |> Enum.each(fn {{ts, nick, msg}, true} -> + IO.puts "#{ts |> DateTime.from_unix! |> DateTime.to_iso8601} <#{nick}> #{msg}" + end) + pid + end + + defp handle_command(_pid, ["join", qchan]) do + list = for {_chid, manifest, chpid} <- :ets.tab2list(:shard_db), + {:chat, chan} = manifest, + do: {chan, chpid} + case List.keyfind(list, qchan, 0) do + nil -> + {:ok, pid} = DynamicSupervisor.start_child(Shard.DynamicSupervisor, {SApp.Chat, qchan}) + GenServer.cast(pid, {:subscribe, self()}) + pid + {_, pid} -> + IO.puts "Switching to ##{qchan}" + pid + end + end + + defp handle_command(pid, ["nick", nick]) do + Shard.Identity.set_nickname nick + pid + end + + defp handle_command(pid, _cmd) do + IO.puts "Invalid command" + pid + end +end |