summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJordan Bracco <href@random.sh>2023-03-05 10:12:03 +0100
committerJordan Bracco <href@random.sh>2023-03-05 10:12:03 +0100
commita76fb9e738d8ce2d49311ac70a3613a0c2669dc2 (patch)
treec8e65119510aa267c5d9e9f785ceb71c597a08bc
parentcouch: fixes (diff)
connection: ignore snoonet channels on join
-rw-r--r--lib/irc/connection.ex97
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