aboutsummaryrefslogblamecommitdiff
path: root/shard/lib/cli/cli.ex
blob: bf3a5555fdb1fb8aa09935beef846968c7c9db06 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
                 



                                                       
              



                                                                 



                  

                     



                                      
                                                                           



                                          




                                                                 

                                           
              


                                                
                


       











                                                                                                 
                                                          

                                                       
                                    


       
                                       
                                     
 

                                                                 




                        
                                       








                                                                                       

     
                                               

                                                                     



                                                                                               
                                                 




                                        

     
                                             
                                    
       

     
                                   
                             
       

     
defmodule SCLI do
  @moduledoc """
  Small command line interface for the chat application
  """

  def run() do
    for {_chid, _manifest, chpid} <- Shard.Manager.list_shards do
      GenServer.cast(chpid, {:subscribe, self()})
    end

    run(nil)
  end

  defp run(pid) do
    handle_messages()

    nick = Shard.Identity.get_nickname
    prompt = case pid do
      nil -> "(no channel) #{nick}: "
      _ -> 
        %SApp.Chat.Manifest{channel: 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} <- Shard.Manager.list_shards do
      %SApp.Chat.Manifest{channel: chan} = manifest
      IO.puts "##{chan}"
    end
    pid
  end

  defp handle_command(pid, ["hist"]) do
    if pid == nil do
      IO.puts "Not currently on a channel!"
    else
      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
  end

  defp handle_command(_pid, ["join", qchan]) do
    list = for {_chid, manifest, chpid} <- Shard.Manager.list_shards,
               %SApp.Chat.Manifest{channel: 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