aboutsummaryrefslogblamecommitdiff
path: root/lib/cli/cli.ex
blob: 2fbf8c2417cfe3bd522f2ac4b0da3f5bde5ba7e9 (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
    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