From a4fd0858575918acc2ea5de1e03742b01256c0c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9ophile=20Choutri?= Date: Sat, 9 Dec 2017 00:13:23 +0100 Subject: testing this, now --- lib/exirc/channels.ex | 10 ++++---- lib/exirc/client.ex | 69 +++++++++++++++++++++++++++++++++++++++++++++------ lib/exirc/commands.ex | 23 +++++++++++++++++ lib/exirc/logger.ex | 6 ++--- lib/exirc/utils.ex | 14 +++++------ 5 files changed, 100 insertions(+), 22 deletions(-) (limited to 'lib') diff --git a/lib/exirc/channels.ex b/lib/exirc/channels.ex index b108de9..f274ef1 100644 --- a/lib/exirc/channels.ex +++ b/lib/exirc/channels.ex @@ -72,7 +72,7 @@ defmodule ExIrc.Channels do Update the type of a tracked channel when it changes """ def set_type(channel_tree, channel_name, channel_type) when is_binary(channel_type) do - set_type(channel_tree, channel_name, String.to_char_list(channel_type)) + set_type(channel_tree, channel_name, String.to_charlist(channel_type)) end def set_type(channel_tree, channel_name, channel_type) do name = downcase(channel_name) @@ -104,7 +104,7 @@ defmodule ExIrc.Channels do Add multiple users to a tracked channel (used primarily in conjunction with the NAMES command) """ def users_join(channel_tree, channel_name, nicks) do - pnicks = strip_rank(nicks) + pnicks = trim_rank(nicks) manipfn = fn(channel_nicks) -> :lists.usort(channel_nicks ++ pnicks) end users_manip(channel_tree, channel_name, manipfn) end @@ -113,13 +113,13 @@ defmodule ExIrc.Channels do Remove a user from a tracked channel when they leave """ def user_part(channel_tree, channel_name, nick) do - pnick = strip_rank([nick]) + pnick = trim_rank([nick]) manipfn = fn(channel_nicks) -> :lists.usort(channel_nicks -- pnick) end users_manip(channel_tree, channel_name, manipfn) end def user_quit(channel_tree, nick) do - pnick = strip_rank([nick]) + pnick = trim_rank([nick]) manipfn = fn(channel_nicks) -> :lists.usort(channel_nicks -- pnick) end foldl = fn(channel_name, new_channel_tree) -> name = downcase(channel_name) @@ -217,7 +217,7 @@ defmodule ExIrc.Channels do end end - defp strip_rank(nicks) do + defp trim_rank(nicks) do nicks |> Enum.map(fn(n) -> case n do << "@", nick :: binary >> -> nick << "+", nick :: binary >> -> nick diff --git a/lib/exirc/client.ex b/lib/exirc/client.ex index 9d6905b..36cb87d 100644 --- a/lib/exirc/client.ex +++ b/lib/exirc/client.ex @@ -33,7 +33,8 @@ defmodule ExIrc.Client do debug?: false, retries: 0, inet: :inet, - owner: nil + owner: nil, + whois_buffers: %{} end ################# @@ -167,6 +168,13 @@ defmodule ExIrc.Client do def names(client, channel) do GenServer.call(client, {:names, channel}, :infinity) end + + @spec whois(client :: pid, user :: binary) :: :ok | {:error, atom()} + def whois(client, user) do + GenServer.call(client, {:whois, user}, :infinity) + end + + @doc """ Change mode for a user or channel """ @@ -330,7 +338,7 @@ defmodule ExIrc.Client do # Set SSL mode state = %{state | ssl?: ssl} # Open a new connection - case Transport.connect(state, String.to_char_list(server), port, [:list, {:packet, :line}, {:keepalive, true}] ++ options) do + case Transport.connect(state, String.to_charlist(server), port, [:list, {:packet, :line}, {:keepalive, true}] ++ options) do {:ok, socket} -> send_event {:connected, server, port}, state {:reply, :ok, %{state | connected?: true, server: server, port: port, socket: socket}} @@ -397,6 +405,12 @@ defmodule ExIrc.Client do Transport.send(state, names!(channel)) {:reply, :ok, state} end + + def handle_call({:whois, user}, _from, state) do + Transport.send(state, whois!(user)) + {: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)) @@ -551,7 +565,7 @@ defmodule ExIrc.Client do end # Called when the client enters a channel def handle_data(%IrcMessage{nick: nick, cmd: "JOIN"} = msg, %ClientState{nick: nick} = state) do - channel = msg.args |> List.first |> String.strip + channel = msg.args |> List.first |> String.trim if state.debug?, do: debug "JOINED A CHANNEL #{channel}" channels = Channels.join(state.channels, channel) new_state = %{state | channels: channels} @@ -561,7 +575,7 @@ defmodule ExIrc.Client do # Called when another user joins a channel the client is in def handle_data(%IrcMessage{nick: user_nick, cmd: "JOIN", host: host, user: user} = msg, state) do sender = %SenderInfo{nick: user_nick, host: host, user: user} - channel = msg.args |> List.first |> String.strip + channel = msg.args |> List.first |> String.trim if state.debug?, do: debug "ANOTHER USER JOINED A CHANNEL: #{channel} - #{user_nick}" channels = Channels.user_join(state.channels, channel, user_nick) new_state = %{state | channels: channels} @@ -589,6 +603,47 @@ defmodule ExIrc.Client do send_event {:topic_changed, channel, topic}, new_state {:noreply, new_state} end + + + ## WHOIS + + def handle_data(%IrcMessage{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 + + def handle_data(%IrcMessage{cmd: @rpl_whoischannels, args: [_sender, nickname, channels]}, state) do + {:noreply, %ClientState{state|whois_buffers: Map.merge(state.whois_buffers[nickname], %{channels: channels})}} + end + + def handle_data(%IrcMessage{cmd: @rpl_whoisserver, args: [_sender, nickname, server_addr, server_name]}, state) do + {:noreply, %ClientState{state|whois_buffers: Map.merge(state.whois_buffers[nickname], %{server: %{name: server_name, address: server_addr}})}} + end + + def handle_data(%IrcMessage{cmd: @rpl_whoisoperator, args: [_sender, nickname, _msg]}, state) do + {:noreply, %ClientState{state|whois_buffers: Map.merge(state.whois_buffers[nickname], %{is_ircop?: true})}} + end + + def handle_data(%IrcMessage{cmd: @rpl_whoisaccount, args: [_sender, nickname, account_name]}, state) do + {:noreply, %ClientState{state|whois_buffers: Map.merge(state.whois_buffers[nickname], %{account_name: account_name})}} + end + + def handle_data(%IrcMessage{cmd: @rpl_whoissecure, args: [_sender, nickname, "is using a secure connection"]}, state) do + {:noreply, %ClientState{state|whois_buffers: Map.merge(state.whois_buffers[nickname], %{use_tls?: true})}} + end + + def handle_data(%IrcMessage{cmd: @rpl_whoisidle, args: [_sender, nickname, idling_time, signon_time, "seconds idle, signon time"]}, state) do + {:noreply, %ClientState{state|whois_buffers: Map.merge(state.whois_buffers[nickname], %{idling_time: idling_time, signon_time: signon_time})}} + end + + def handle_data(%IrcMessage{cmd: @rpl_endofwhois, args: [_sender, nickname, "End of /WHOIS list."]}, state) do + buffer = state.whois_buffers[nickname] + send_event {:whois, buffer}, state + {:noreply, %ClientState{state|whois_buffers: Map.delete(state.whois_buffers, nickname)}} + end + + + def handle_data(%IrcMessage{cmd: @rpl_notopic, args: [channel]}, state) do if state.debug? do debug "INITIAL TOPIC MSG" @@ -645,7 +700,7 @@ defmodule ExIrc.Client do end # Called when we leave a channel def handle_data(%IrcMessage{cmd: "PART", nick: nick} = msg, %ClientState{nick: nick} = state) do - channel = msg.args |> List.first |> String.strip + channel = msg.args |> List.first |> String.trim if state.debug?, do: debug "WE LEFT A CHANNEL: #{channel}" channels = Channels.part(state.channels, channel) new_state = %{state | channels: channels} @@ -655,7 +710,7 @@ defmodule ExIrc.Client do # Called when someone else in our channel leaves def handle_data(%IrcMessage{cmd: "PART", nick: from, host: host, user: user} = msg, state) do sender = %SenderInfo{nick: from, host: host, user: user} - channel = msg.args |> List.first |> String.strip + channel = msg.args |> List.first |> String.trim if state.debug?, do: debug "#{from} LEFT A CHANNEL: #{channel}" channels = Channels.user_part(state.channels, channel, from) new_state = %{state | channels: channels} @@ -729,7 +784,7 @@ defmodule ExIrc.Client do {:noreply, state} end # Called when a NOTICE is received by the client. - def handle_data(%IrcMessage{nick: from, cmd: "NOTICE", args: [target, message], host: host, user: user} = _msg, state) do + def handle_data(%IrcMessage{nick: from, cmd: "NOTICE", args: [_target, message], host: host, user: user} = _msg, state) do sender = %SenderInfo{nick: from, host: host, user: user} diff --git a/lib/exirc/commands.ex b/lib/exirc/commands.ex index 9f52b75..60cd779 100644 --- a/lib/exirc/commands.ex +++ b/lib/exirc/commands.ex @@ -49,6 +49,14 @@ defmodule Irc.Commands do #one of two replies is sent. If the topic is set, RPL_TOPIC is sent back else #RPL_NOTOPIC. #""" + @rpl_whoiregnick "307" + @rpl_whoisuser "311" + @rpl_whoisserver "312" + @rpl_whoisoperator "313" + @rpl_whoisidle "317" + @rpl_endofwhois "318" + @rpl_whoischannels "319" + @rpl_whoisaccount "330" @rpl_notopic "331" @rpl_topic "332" #@doc """ @@ -77,6 +85,8 @@ defmodule Irc.Commands do @rpl_motd "372" @rpl_motdstart "375" @rpl_endofmotd "376" + @rpl_whoishost "378" + @rpl_whoismodes "379" ################ # Error Codes @@ -150,6 +160,8 @@ defmodule Irc.Commands do #""" @err_restricted "484" + @rpl_whoissecure "671" + ############### # Code groups ############### @@ -158,6 +170,12 @@ defmodule Irc.Commands do @err_nickname_in_use, @err_nick_collision, @err_unavail_resource, @err_need_more_params, @err_already_registered, @err_restricted ] + + @whois_rpls [ @rpl_whoisuser, @rpl_whoishost, + @rpl_whoishost, @rpl_whoisserver, + @rpl_whoismodes, @rpl_whoisidle, + @rpl_endofwhois + ] end end @@ -182,6 +200,11 @@ defmodule Irc.Commands do # IRC Commands + @doc """ + Send a WHOIS request about a user + """ + def whois!(user), do: command! ['WHOIS', user] + @doc """ Send password to server """ diff --git a/lib/exirc/logger.ex b/lib/exirc/logger.ex index 6055221..65ae980 100644 --- a/lib/exirc/logger.ex +++ b/lib/exirc/logger.ex @@ -8,7 +8,7 @@ defmodule ExIrc.Logger do """ @spec info(binary) :: :ok def info(msg) do - :error_logger.info_report String.to_char_list(msg) + :error_logger.info_report String.to_charlist(msg) end @doc """ @@ -16,7 +16,7 @@ defmodule ExIrc.Logger do """ @spec warning(binary) :: :ok def warning(msg) do - :error_logger.warning_report String.to_char_list("#{IO.ANSI.yellow()}#{msg}#{IO.ANSI.reset()}") + :error_logger.warning_report String.to_charlist("#{IO.ANSI.yellow()}#{msg}#{IO.ANSI.reset()}") end @doc """ @@ -24,6 +24,6 @@ defmodule ExIrc.Logger do """ @spec error(binary) :: :ok def error(msg) do - :error_logger.error_report String.to_char_list("#{IO.ANSI.red()}#{msg}#{IO.ANSI.reset()}") + :error_logger.error_report String.to_charlist("#{IO.ANSI.red()}#{msg}#{IO.ANSI.reset()}") end end \ No newline at end of file diff --git a/lib/exirc/utils.ex b/lib/exirc/utils.ex index 46cba11..d79b326 100644 --- a/lib/exirc/utils.ex +++ b/lib/exirc/utils.ex @@ -13,7 +13,7 @@ defmodule ExIrc.Utils do message = ExIrc.Utils.parse data assert "irc.example.org" = message.server """ - @spec parse(raw_data :: char_list) :: IrcMessage.t + @spec parse(raw_data :: charlist) :: IrcMessage.t def parse(raw_data) do data = :string.substr(raw_data, 1, length(raw_data)) case data do @@ -137,7 +137,7 @@ defmodule ExIrc.Utils do end defp isup_param("PREFIX=" <> user_prefixes, state) do prefixes = Regex.run(~r/\((.*)\)(.*)/, user_prefixes, capture: :all_but_first) - |> Enum.map(&String.to_char_list/1) + |> Enum.map(&String.to_charlist/1) |> List.zip %{state | user_prefixes: prefixes} end @@ -167,15 +167,15 @@ defmodule ExIrc.Utils do ' ', :lists.nth(m, @months_of_year), ' ', - :io_lib.format("~2..0s", [Integer.to_char_list(d)]), + :io_lib.format("~2..0s", [Integer.to_charlist(d)]), ' ', - :io_lib.format("~2..0s", [Integer.to_char_list(h)]), + :io_lib.format("~2..0s", [Integer.to_charlist(h)]), ':', - :io_lib.format("~2..0s", [Integer.to_char_list(n)]), + :io_lib.format("~2..0s", [Integer.to_charlist(n)]), ':', - :io_lib.format("~2..0s", [Integer.to_char_list(s)]), + :io_lib.format("~2..0s", [Integer.to_charlist(s)]), ' ', - Integer.to_char_list(y)] |> List.flatten |> List.to_string + Integer.to_charlist(y)] |> List.flatten |> List.to_string end defp trim_crlf(charlist) do -- cgit v1.2.3 From 1acc2b64941082398d5b2c25cfffefd056716ce2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9ophile=20Choutri?= Date: Sat, 9 Dec 2017 15:26:53 +0100 Subject: implement WHOIS feature and a struct for data integrity --- lib/exirc/client.ex | 34 ++++++++++++++++++++++++---------- lib/exirc/commands.ex | 6 ++++-- lib/exirc/whois.ex | 18 ++++++++++++++++++ 3 files changed, 46 insertions(+), 12 deletions(-) create mode 100644 lib/exirc/whois.ex (limited to 'lib') diff --git a/lib/exirc/client.ex b/lib/exirc/client.ex index 36cb87d..bf6e4fc 100644 --- a/lib/exirc/client.ex +++ b/lib/exirc/client.ex @@ -607,43 +607,57 @@ defmodule ExIrc.Client do ## WHOIS + def handle_data(%IrcMessage{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 + def handle_data(%IrcMessage{cmd: @rpl_whoiscertfp, args: [_sender, nickname, "has client certificate fingerprint "<> fingerprint]}, state) do + {:noreply, %ClientState{state|whois_buffers: put_in(state.whois_buffers, [nickname, :certfp], fingerprint)}} + end + + def handle_data(%IrcMessage{cmd: @rpl_whoisregnick, args: [_sender, nickname, _message]}, state) do + {:noreply, %ClientState{state|whois_buffers: put_in(state.whois_buffers, [nickname, :registered_nick?], true)}} + end + + def handle_data(%IrcMessage{cmd: @rpl_whoishelpop, args: [_sender, nickname, "is available for help."]}, state) do + {:noreply, %ClientState{state|whois_buffers: put_in(state.whois_buffers, [nickname, :helpop?], true)}} + end + def handle_data(%IrcMessage{cmd: @rpl_whoischannels, args: [_sender, nickname, channels]}, state) do - {:noreply, %ClientState{state|whois_buffers: Map.merge(state.whois_buffers[nickname], %{channels: channels})}} + chans = String.split(channels, " ") + {:noreply, %ClientState{state|whois_buffers: put_in(state.whois_buffers, [nickname, :channels], chans)}} end def handle_data(%IrcMessage{cmd: @rpl_whoisserver, args: [_sender, nickname, server_addr, server_name]}, state) do - {:noreply, %ClientState{state|whois_buffers: Map.merge(state.whois_buffers[nickname], %{server: %{name: server_name, address: server_addr}})}} + new_buffer = state.whois_buffers |> put_in([nickname, :server_name], server_name) |> put_in([nickname, :server_address], server_addr) + {:noreply, %ClientState{state|whois_buffers: new_buffer}} end def handle_data(%IrcMessage{cmd: @rpl_whoisoperator, args: [_sender, nickname, _msg]}, state) do - {:noreply, %ClientState{state|whois_buffers: Map.merge(state.whois_buffers[nickname], %{is_ircop?: true})}} + {:noreply, %ClientState{state|whois_buffers: put_in(state.whois_buffers, [nickname, :ircop?], true)}} end - def handle_data(%IrcMessage{cmd: @rpl_whoisaccount, args: [_sender, nickname, account_name]}, state) do - {:noreply, %ClientState{state|whois_buffers: Map.merge(state.whois_buffers[nickname], %{account_name: account_name})}} + def handle_data(%IrcMessage{cmd: @rpl_whoisaccount, args: [_sender, nickname, account_name, "is logged in as"]}, state) do + {:noreply, %ClientState{state|whois_buffers: put_in(state.whois_buffers, [nickname, :account_name], account_name)}} end def handle_data(%IrcMessage{cmd: @rpl_whoissecure, args: [_sender, nickname, "is using a secure connection"]}, state) do - {:noreply, %ClientState{state|whois_buffers: Map.merge(state.whois_buffers[nickname], %{use_tls?: true})}} + {:noreply, %ClientState{state|whois_buffers: put_in(state.whois_buffers, [nickname, :tls?], true)}} end def handle_data(%IrcMessage{cmd: @rpl_whoisidle, args: [_sender, nickname, idling_time, signon_time, "seconds idle, signon time"]}, state) do - {:noreply, %ClientState{state|whois_buffers: Map.merge(state.whois_buffers[nickname], %{idling_time: idling_time, signon_time: signon_time})}} + new_buffer = state.whois_buffers |> put_in([nickname, :idling_time], idling_time) |> put_in([nickname, :signon_time], signon_time) + {:noreply, %ClientState{state|whois_buffers: new_buffer}} end def handle_data(%IrcMessage{cmd: @rpl_endofwhois, args: [_sender, nickname, "End of /WHOIS list."]}, state) do - buffer = state.whois_buffers[nickname] + buffer = struct(Irc.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(%IrcMessage{cmd: @rpl_notopic, args: [channel]}, state) do if state.debug? do debug "INITIAL TOPIC MSG" diff --git a/lib/exirc/commands.ex b/lib/exirc/commands.ex index 60cd779..0d959c0 100644 --- a/lib/exirc/commands.ex +++ b/lib/exirc/commands.ex @@ -49,7 +49,9 @@ defmodule Irc.Commands do #one of two replies is sent. If the topic is set, RPL_TOPIC is sent back else #RPL_NOTOPIC. #""" - @rpl_whoiregnick "307" + @rpl_whoiscertfp "276" + @rpl_whoisregnick "307" + @rpl_whoishelpop "310" @rpl_whoisuser "311" @rpl_whoisserver "312" @rpl_whoisoperator "313" @@ -203,7 +205,7 @@ defmodule Irc.Commands do @doc """ Send a WHOIS request about a user """ - def whois!(user), do: command! ['WHOIS', user] + def whois!(user), do: command! ['WHOIS ', user] @doc """ Send password to server diff --git a/lib/exirc/whois.ex b/lib/exirc/whois.ex new file mode 100644 index 0000000..fb14e63 --- /dev/null +++ b/lib/exirc/whois.ex @@ -0,0 +1,18 @@ +defmodule Irc.Whois do + defstruct [account_name: nil, + channels: [], + helpop?: false, + hostname: nil, + idling_time: 0, + ircop?: false, + nickname: nil, + realname: nil, + registered_nick?: false, + server_address: nil, + server_name: nil, + signon_time: 0, + tls?: false, + username: nil, + ] +end + -- cgit v1.2.3 From 868244e9591482804c1e1e1421139c76fbdc6a4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9ophile=20Choutri?= Date: Mon, 11 Dec 2017 21:58:22 +0100 Subject: Avoid matching on text, and reformat the pipelines --- lib/exirc/client.ex | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'lib') diff --git a/lib/exirc/client.ex b/lib/exirc/client.ex index bf6e4fc..0dcf9a9 100644 --- a/lib/exirc/client.ex +++ b/lib/exirc/client.ex @@ -169,6 +169,9 @@ defmodule ExIrc.Client do GenServer.call(client, {:names, channel}, :infinity) end + @doc """ + Ask the server for the user's informations. + """ @spec whois(client :: pid, user :: binary) :: :ok | {:error, atom()} def whois(client, user) do GenServer.call(client, {:whois, user}, :infinity) @@ -621,7 +624,7 @@ defmodule ExIrc.Client do {:noreply, %ClientState{state|whois_buffers: put_in(state.whois_buffers, [nickname, :registered_nick?], true)}} end - def handle_data(%IrcMessage{cmd: @rpl_whoishelpop, args: [_sender, nickname, "is available for help."]}, state) do + def handle_data(%IrcMessage{cmd: @rpl_whoishelpop, args: [_sender, nickname, _message]}, state) do {:noreply, %ClientState{state|whois_buffers: put_in(state.whois_buffers, [nickname, :helpop?], true)}} end @@ -631,28 +634,32 @@ defmodule ExIrc.Client do end def handle_data(%IrcMessage{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) + new_buffer = state.whois_buffers + |> put_in([nickname, :server_name], server_name) + |> put_in([nickname, :server_address], server_addr) {:noreply, %ClientState{state|whois_buffers: new_buffer}} end - def handle_data(%IrcMessage{cmd: @rpl_whoisoperator, args: [_sender, nickname, _msg]}, state) do + def handle_data(%IrcMessage{cmd: @rpl_whoisoperator, args: [_sender, nickname, _message]}, state) do {:noreply, %ClientState{state|whois_buffers: put_in(state.whois_buffers, [nickname, :ircop?], true)}} end - def handle_data(%IrcMessage{cmd: @rpl_whoisaccount, args: [_sender, nickname, account_name, "is logged in as"]}, state) do + def handle_data(%IrcMessage{cmd: @rpl_whoisaccount, args: [_sender, nickname, account_name, _message]}, state) do {:noreply, %ClientState{state|whois_buffers: put_in(state.whois_buffers, [nickname, :account_name], account_name)}} end - def handle_data(%IrcMessage{cmd: @rpl_whoissecure, args: [_sender, nickname, "is using a secure connection"]}, state) do + def handle_data(%IrcMessage{cmd: @rpl_whoissecure, args: [_sender, nickname, _message]}, state) do {:noreply, %ClientState{state|whois_buffers: put_in(state.whois_buffers, [nickname, :tls?], true)}} end - def handle_data(%IrcMessage{cmd: @rpl_whoisidle, args: [_sender, nickname, idling_time, signon_time, "seconds idle, signon time"]}, state) do - new_buffer = state.whois_buffers |> put_in([nickname, :idling_time], idling_time) |> put_in([nickname, :signon_time], signon_time) + def handle_data(%IrcMessage{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) {:noreply, %ClientState{state|whois_buffers: new_buffer}} end - def handle_data(%IrcMessage{cmd: @rpl_endofwhois, args: [_sender, nickname, "End of /WHOIS list."]}, state) do + def handle_data(%IrcMessage{cmd: @rpl_endofwhois, args: [_sender, nickname, _message]}, state) do buffer = struct(Irc.Whois, state.whois_buffers[nickname]) send_event {:whois, buffer}, state {:noreply, %ClientState{state|whois_buffers: Map.delete(state.whois_buffers, nickname)}} -- cgit v1.2.3