diff options
author | Théophile Choutri <theophile@choutri.eu> | 2018-01-19 15:08:01 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-01-19 15:08:01 +0100 |
commit | 77f8aab44fe39b0bc8c8da3c5cd399bb79cead3d (patch) | |
tree | cc522f7997834352709fdc8cdade0893b32ac038 | |
parent | Fix namespaces and improve internal consistency (diff) |
Add WHO query (#78)
Support the WHO query
-rw-r--r-- | lib/exirc/client.ex | 58 | ||||
-rw-r--r-- | lib/exirc/commands.ex | 5 | ||||
-rw-r--r-- | lib/exirc/who.ex | 17 | ||||
-rw-r--r-- | lib/exirc/whois.ex | 2 |
4 files changed, 71 insertions, 11 deletions
diff --git a/lib/exirc/client.ex b/lib/exirc/client.ex index 4dd4d25..f84a1d2 100644 --- a/lib/exirc/client.ex +++ b/lib/exirc/client.ex @@ -34,7 +34,8 @@ defmodule ExIRC.Client do retries: 0, inet: :inet, owner: nil, - whois_buffers: %{} + whois_buffers: %{}, + who_buffers: %{} end ################# @@ -177,6 +178,13 @@ defmodule ExIRC.Client do GenServer.call(client, {:whois, user}, :infinity) end + @doc """ + Ask the server for the channel's users + """ + @spec who(client :: pid, channel :: binary) :: :ok | {:error, atom()} + def who(client, channel) do + GenServer.call(client, {:who, channel}, :infinity) + end @doc """ Change mode for a user or channel @@ -414,6 +422,11 @@ defmodule ExIRC.Client do {:reply, :ok, state} end + def handle_call({:who, channel}, _from, state) do + Transport.send(state, who!(channel)) + {:reply, :ok, state} + end + # Handles a call to change mode for a user or channel def handle_call({:mode, channel_or_nick, flags, args}, _from, state) do Transport.send(state, mode!(channel_or_nick, flags, args)) @@ -611,10 +624,7 @@ defmodule ExIRC.Client do ## WHOIS - - def handle_data(%ExIRC.Message{cmd: @rpl_whoisuser, args: [_sender, nickname, username, hostname, _, realname]}, state) do - user = %{nickname: nickname, username: username, hostname: hostname, realname: realname} {:noreply, %ClientState{state|whois_buffers: Map.put(state.whois_buffers, nickname, user)}} end @@ -632,14 +642,12 @@ defmodule ExIRC.Client do end def handle_data(%ExIRC.Message{cmd: @rpl_whoischannels, args: [_sender, nickname, channels]}, state) do - chans = String.split(channels, " ") {:noreply, %ClientState{state|whois_buffers: put_in(state.whois_buffers, [nickname, :channels], chans)}} end def handle_data(%ExIRC.Message{cmd: @rpl_whoisserver, args: [_sender, nickname, server_addr, server_name]}, state) do - new_buffer = state.whois_buffers |> put_in([nickname, :server_name], server_name) |> put_in([nickname, :server_address], server_addr) @@ -655,11 +663,10 @@ defmodule ExIRC.Client do end def handle_data(%ExIRC.Message{cmd: @rpl_whoissecure, args: [_sender, nickname, _message]}, state) do - {:noreply, %ClientState{state|whois_buffers: put_in(state.whois_buffers, [nickname, :tls?], true)}} + {:noreply, %ClientState{state|whois_buffers: put_in(state.whois_buffers, [nickname, :ssl?], true)}} end def handle_data(%ExIRC.Message{cmd: @rpl_whoisidle, args: [_sender, nickname, idling_time, signon_time, _message]}, state) do - new_buffer = state.whois_buffers |> put_in([nickname, :idling_time], idling_time) |> put_in([nickname, :signon_time], signon_time) @@ -668,13 +675,44 @@ defmodule ExIRC.Client do def handle_data(%ExIRC.Message{cmd: @rpl_endofwhois, args: [_sender, nickname, _message]}, state) do buffer = struct(ExIRC.Whois, state.whois_buffers[nickname]) - send_event {:whois, buffer}, state {:noreply, %ClientState{state|whois_buffers: Map.delete(state.whois_buffers, nickname)}} end - def handle_data(%ExIRC.Message{cmd: @rpl_notopic, args: [channel]}, state) do + ## WHO + + def handle_data(%ExIRC.Message{:cmd => "352", :args => [_, channel, user, host, server, nick, mode, hop_and_realn]}, state) do + [hop, name] = String.split(hop_and_realn, " ", parts: 2) + :binary.compile_pattern(["@", "&", "+"]) + admin? = String.contains?(mode, "&") + away? = String.contains?(mode, "G") + founder? = String.contains?(mode, "~") + half_operator? = String.contains?(mode, "%") + operator? = founder? || admin? || String.contains?(mode, "@") + server_operator? = String.contains?(mode, "*") + voiced? = String.contains?(mode, "+") + + nick = %{nick: nick, user: user, name: name, server: server, hops: hop, admin?: admin?, + away?: away?, founder?: founder?, half_operator?: half_operator?, + operator?: operator?, server_operator?: server_operator?, voiced?: voiced? + } + + buffer = Map.get(state.who_buffers, channel, []) + {:noreply, %ClientState{state | who_buffers: Map.put(state.who_buffers, channel, [nick|buffer])}} + end + + def handle_data(%ExIRC.Message{:cmd => "315", :args => [_, channel, _]}, state) do + buffer = state + |> Map.get(:who_buffers) + |> Map.get(channel) + |> Enum.map(fn user -> struct(ExIRC.Who, user) end) + + send_event {:who, channel, buffer}, state + {:noreply, %ClientState{state | who_buffers: Map.delete(state.who_buffers, channel)}} + end + + def handle_data(%ExIRC.Message{cmd: @rpl_notopic, args: [channel]}, state) do if state.debug? do debug "INITIAL TOPIC MSG" debug "1. NO TOPIC SET FOR #{channel}}" diff --git a/lib/exirc/commands.ex b/lib/exirc/commands.ex index c4833d5..7f7a130 100644 --- a/lib/exirc/commands.ex +++ b/lib/exirc/commands.ex @@ -208,6 +208,11 @@ defmodule ExIRC.Commands do def whois!(user), do: command! ['WHOIS ', user] @doc """ + Send a WHO request about a channel + """ + def who!(channel), do: command! ['WHO ', channel] + + @doc """ Send password to server """ def pass!(pwd), do: command! ['PASS ', pwd] diff --git a/lib/exirc/who.ex b/lib/exirc/who.ex new file mode 100644 index 0000000..583717f --- /dev/null +++ b/lib/exirc/who.ex @@ -0,0 +1,17 @@ +defmodule ExIRC.Who do + + defstruct [ + admin?: nil, + away?: nil, + founder?: nil, + half_operator?: nil, + hops: nil, + name: nil, + nickname: nil, + operator?: nil, + server: nil, + server_operator?: nil, + user: nil, + voiced?: nil + ] +end diff --git a/lib/exirc/whois.ex b/lib/exirc/whois.ex index 3970214..8b9d987 100644 --- a/lib/exirc/whois.ex +++ b/lib/exirc/whois.ex @@ -12,7 +12,7 @@ defmodule ExIRC.Whois do server_address: nil, server_name: nil, signon_time: 0, - tls?: false, + ssl?: false, username: nil, ] end |