diff options
author | Jordan Bracco <href@random.sh> | 2023-03-05 10:12:03 +0100 |
---|---|---|
committer | Jordan Bracco <href@random.sh> | 2023-03-05 10:12:03 +0100 |
commit | a76fb9e738d8ce2d49311ac70a3613a0c2669dc2 (patch) | |
tree | c8e65119510aa267c5d9e9f785ceb71c597a08bc | |
parent | couch: fixes (diff) |
connection: ignore snoonet channels on join
-rw-r--r-- | lib/irc/connection.ex | 97 |
1 files changed, 66 insertions, 31 deletions
diff --git a/lib/irc/connection.ex b/lib/irc/connection.ex index 7a0ca9d..62d52d8 100644 --- a/lib/irc/connection.ex +++ b/lib/irc/connection.ex @@ -189,7 +189,11 @@ defmodule Nola.Irc.Connection do Logger.metadata(conn: conn.id) backoff = :backoff.init(@min_backoff, @max_backoff) |> :backoff.type(:jitter) - {:ok, %{client: nil, backoff: backoff, conn: conn, connected_server: nil, connected_port: nil, network: conn.network}, {:continue, :connect}} + {:ok, %{client: nil, + ignore_channel_for_a_while: conn.network == "snoonet", + backoff: backoff, + channels: Map.new, + conn: conn, connected_server: nil, connected_port: nil, network: conn.network}, {:continue, :connect}} end @triggers %{ @@ -234,7 +238,7 @@ defmodule Nola.Irc.Connection do {delay, backoff} = :backoff.fail(state.backoff) Logger.info("#{inspect(self())} Disconnected -- reconnecting in #{inspect delay}ms") Process.send_after(self(), :connect, delay) - {:noreply, %{state | backoff: backoff}} + {:noreply, %{state | channels: Map.new, backoff: backoff}} end def handle_info(:connect, state) do @@ -245,13 +249,13 @@ defmodule Nola.Irc.Connection do irc_reply(state, {channel, nil}, line) {:noreply, state} end - +<<>> # Connection successful def handle_info({:connected, server, port}, state) do Logger.info("#{inspect(self())} Connected to #{inspect(server)}:#{port} #{inspect state}") {_, backoff} = :backoff.succeed(state.backoff) ExIRC.Client.logon(state.client, state.conn.pass || "", state.conn.nick, state.conn.user, state.conn.name) - {:noreply, %{state | backoff: backoff, connected_server: server, connected_port: port}} + {:noreply, %{state | channels: Map.new, backoff: backoff, connected_server: server, connected_port: port}} end # Logon successful @@ -274,34 +278,39 @@ defmodule Nola.Irc.Connection do # Been kicked def handle_info({:kicked, _sender, chan, _reason}, state) do ExIRC.Client.join(state.client, chan) - {:noreply, state} + {:noreply, %{state | channels: Map.delete(state.channels, chan)}} end # Received something in a channel def handle_info({:received, text, sender, chan}, state) do - user = if user = Nola.UserTrack.find_by_nick(state.network, sender.nick) do - user - else - Logger.error("Could not lookup user for message: #{inspect {state.network, chan, sender.nick}}") - user = Nola.UserTrack.joined(chan, sender, []) - ExIRC.Client.who(state.client, chan) # Rewho everything in case of need ? We shouldn't not know that user.. - user - end - if !user do - ExIRC.Client.who(state.client, chan) # Rewho everything in case of need ? We shouldn't not know that user.. - Logger.error("Could not lookup user nor create it for message: #{inspect {state.network, chan, sender.nick}}") + channel_state = Map.get(state.channels, chan, Map.new) + if state.ignore_channel_for_a_while && DateTime.diff(DateTime.utc_now(), Map.get(channel_state, :joined)) < 30 do + :ignore_channel else - if !Map.get(user.options, :puppet) do - reply_fun = fn(text) -> irc_reply(state, {chan, sender}, text) end - account = Nola.Account.lookup(sender) - message = %Nola.Message{id: FlakeId.get(), transport: :irc, at: NaiveDateTime.utc_now(), text: text, network: state.network, - account: account, sender: sender, channel: chan, replyfun: reply_fun, - trigger: extract_trigger(text)} - message = case Nola.UserTrack.messaged(message) do - :ok -> message - {:ok, message} -> message + user = if user = Nola.UserTrack.find_by_nick(state.network, sender.nick) do + user + else + Logger.error("Could not lookup user for message: #{inspect {state.network, chan, sender.nick}}") + user = Nola.UserTrack.joined(chan, sender, []) + ExIRC.Client.who(state.client, chan) # Rewho everything in case of need ? We shouldn't not know that user.. + user + end + if !user do + ExIRC.Client.who(state.client, chan) # Rewho everything in case of need ? We shouldn't not know that user.. + Logger.error("Could not lookup user nor create it for message: #{inspect {state.network, chan, sender.nick}}") + else + if !Map.get(user.options, :puppet) do + reply_fun = fn(text) -> irc_reply(state, {chan, sender}, text) end + account = Nola.Account.lookup(sender) + message = %Nola.Message{id: FlakeId.get(), transport: :irc, at: NaiveDateTime.utc_now(), text: text, network: state.network, + account: account, sender: sender, channel: chan, replyfun: reply_fun, + trigger: extract_trigger(text)} + message = case Nola.UserTrack.messaged(message) do + :ok -> message + {:ok, message} -> message + end + publish(message, ["#{message.network}/#{chan}:messages"]) end - publish(message, ["#{message.network}/#{chan}:messages"]) end end {:noreply, state} @@ -341,8 +350,9 @@ defmodule Nola.Irc.Connection do ## -- UserTrack def handle_info({:joined, channel}, state) do + channels = Map.put(state.channels, channel, %{joined: DateTime.utc_now}) ExIRC.Client.who(state.client, channel) - {:noreply, state} + {:noreply, %{state | channels: channels}} end def handle_info({:who, channel, whos}, state) do @@ -427,11 +437,36 @@ defmodule Nola.Irc.Connection do def dispatch(key, content, sub) when is_binary(key), do: dispatch([key], content, sub) def dispatch(keys, content, sub) when is_list(keys) do - Logger.debug("dispatch #{inspect keys} = #{inspect content}") + should_dispatch_data = should_dispatch_data(content) for key <- keys do - spawn(fn() -> Registry.dispatch(sub, key, fn h -> - for {pid, _} <- h, do: send(pid, content) - end) end) + spawn(fn() -> + Registry.dispatch(sub, key, fn h -> + for {pid, reg} <- h, do: if(should_dispatch?(key, should_dispatch_data, reg), do: send(pid, content)) + end) + end) + end + end + + defp should_dispatch_data({:irc, :trigger, _, msg}) do + should_dispatch_data(msg) + end + defp should_dispatch_data({:irc, :text, msg}) do + should_dispatch_data(msg) + end + defp should_dispatch_data(%Nola.Message{network: network, channel: channel}) do + Application.get_env(:nola, :channel_pubsub_plugin_ignore_list, %{}) + |> Map.get("#{network}/#{channel}", []) + end + defp should_dispatch_data(_) do + [] + end + + def should_dispatch?(_, [], _), do: true + def should_dispatch?(_, data, reg) do + if plugin = Keyword.get(reg, :plugin) do + !Enum.member?(data, plugin) + else + true end end |