diff options
author | href <href@random.sh> | 2021-09-03 04:04:21 +0200 |
---|---|---|
committer | href <href@random.sh> | 2021-09-03 04:04:21 +0200 |
commit | 5399fc818cf821c75f9f19fd00bf7905ba7fe7e3 (patch) | |
tree | 00408724f9778cc7323b1459782a762626d39b6a /lib/irc | |
parent | assets.. (diff) |
various fixes, web client wip, pubsub events
Diffstat (limited to 'lib/irc')
-rw-r--r-- | lib/irc/account.ex | 2 | ||||
-rw-r--r-- | lib/irc/connection.ex | 38 | ||||
-rw-r--r-- | lib/irc/puppet_connection.ex | 4 | ||||
-rw-r--r-- | lib/irc/user_track.ex | 21 |
4 files changed, 52 insertions, 13 deletions
diff --git a/lib/irc/account.ex b/lib/irc/account.ex index 0aa8638..c835d55 100644 --- a/lib/irc/account.ex +++ b/lib/irc/account.ex @@ -268,7 +268,7 @@ defmodule IRC.Account do def irc_doc, do: @moduledoc def start_link(), do: GenServer.start_link(__MODULE__, [], name: __MODULE__) def init(_) do - {:ok, _} = Registry.register(IRC.PubSub, "message:private", []) + {:ok, _} = Registry.register(IRC.PubSub, "messages:private", []) {:ok, nil} end diff --git a/lib/irc/connection.ex b/lib/irc/connection.ex index e856114..eff5930 100644 --- a/lib/irc/connection.ex +++ b/lib/irc/connection.ex @@ -165,6 +165,10 @@ defmodule IRC.Connection do end end + def update_connection(connection) do + :dets.insert(dets(), to_tuple(connection)) + end + def start_link(conn) do GenServer.start_link(__MODULE__, [conn], name: {:global, conn.id}) end @@ -275,12 +279,12 @@ defmodule IRC.Connection do def handle_info({:received, text, sender, chan}, state) do reply_fun = fn(text) -> irc_reply(state, {chan, sender}, text) end account = IRC.Account.lookup(sender) - message = %IRC.Message{text: text, network: network(state), account: account, sender: sender, channel: chan, replyfun: reply_fun, trigger: extract_trigger(text)} + message = %IRC.Message{at: NaiveDateTime.utc_now(), text: text, network: network(state), account: account, sender: sender, channel: chan, replyfun: reply_fun, trigger: extract_trigger(text)} message = case IRC.UserTrack.messaged(message) do :ok -> message {:ok, message} -> message end - publish(message, ["message:#{chan}", "#{message.network}/#{chan}:message"]) + publish(message, ["#{message.network}/#{chan}:messages"]) {:noreply, state} end @@ -293,7 +297,7 @@ defmodule IRC.Connection do :ok -> message {:ok, message} -> message end - publish(message, ["message:private"]) + publish(message, ["messages:private", "#{message.network}/#{account.id}:messages"]) {:noreply, state} end @@ -336,8 +340,8 @@ defmodule IRC.Connection do {:noreply, state} end - def handle_info({:quit, _reason, sender}, state) do - IRC.UserTrack.quitted(sender) + def handle_info({:quit, reason, sender}, state) do + IRC.UserTrack.quitted(sender, reason) {:noreply, state} end @@ -378,18 +382,32 @@ defmodule IRC.Connection do def publish(pub), do: publish(pub, []) def publish(m = %IRC.Message{trigger: nil}, keys) do - dispatch(["message"] ++ keys, {:irc, :text, m}) + dispatch(["messages"] ++ keys, {:irc, :text, m}) end def publish(m = %IRC.Message{trigger: t = %IRC.Trigger{trigger: trigger}}, keys) do dispatch(["triggers", "#{m.network}/#{m.channel}:triggers", "trigger:"<>trigger], {:irc, :trigger, trigger, m}) end + def publish_event(net, event = %{type: _}) when is_binary(net) do + event = event + |> Map.put(:at, NaiveDateTime.utc_now()) + |> Map.put(:network, net) + dispatch("#{net}:events", {:irc, :event, event}) + end + def publish_event({net, chan}, event = %{type: type}) do + event = event + |> Map.put(:at, NaiveDateTime.utc_now()) + |> Map.put(:network, net) + |> Map.put(:channel, chan) + dispatch("#{net}/#{chan}:events", {:irc, :event, event}) + end + def dispatch(keys, content, sub \\ IRC.PubSub) def dispatch(key, content, sub) when is_binary(key), do: dispatch([key], content, sub) def dispatch(keys, content, sub) when is_list(keys) do - IO.puts "dispatching to #{inspect({sub,keys})} --> #{inspect content}" + Logger.debug("dispatch #{inspect keys} = #{inspect content}") for key <- keys do spawn(fn() -> Registry.dispatch(sub, key, fn h -> for {pid, _} <- h, do: send(pid, content) @@ -419,13 +437,15 @@ defmodule IRC.Connection do # irc_reply(ExIRC.Client pid, {channel or nick, ExIRC.Sender}, binary | replies # replies :: {:kick, reason} | {:kick, nick, reason} | {:mode, mode, nick} - defp irc_reply(%{client: client, network: network}, {target, _}, text) when is_binary(text) or is_list(text) do + defp irc_reply(state = %{client: client, network: network}, {target, _}, text) when is_binary(text) or is_list(text) do lines = IRC.splitlong(text) |> Enum.map(fn(x) -> if(is_list(x), do: x, else: String.split(x, "\n")) end) |> List.flatten() - for line <- lines do + outputs = for line <- lines do ExIRC.Client.msg(client, :privmsg, target, line) + {:irc, :out, %IRC.Message{network: network, channel: target, text: line, sender: %ExIRC.SenderInfo{nick: state.conn.nick}, at: NaiveDateTime.utc_now()}} end + for f <- outputs, do: dispatch(["irc:outputs", "#{network}/#{target}:outputs"], f) case :global.whereis_name({LSG.TelegramRoom, network, target}) do pid when is_pid(pid) -> send(pid, {:raw, text}) _ -> :ok diff --git a/lib/irc/puppet_connection.ex b/lib/irc/puppet_connection.ex index 68f1425..8c9b218 100644 --- a/lib/irc/puppet_connection.ex +++ b/lib/irc/puppet_connection.ex @@ -52,6 +52,10 @@ defmodule IRC.PuppetConnection do GenServer.cast(pid, {:send_message, channel, text}) end + def start(account = %IRC.Account{}, connection = %IRC.Connection{}) do + IRC.PuppetConnection.Supervisor.start_child(account, connection) + end + def start_link(account_id, connection_id) do GenServer.start_link(__MODULE__, [account_id, connection_id], name: name(account_id, connection_id)) end diff --git a/lib/irc/user_track.ex b/lib/irc/user_track.ex index 5e1c3a3..4b1ee67 100644 --- a/lib/irc/user_track.ex +++ b/lib/irc/user_track.ex @@ -183,7 +183,7 @@ defmodule IRC.UserTrack do user = if user = find_by_nick(sender.network, nick) do %User{user | username: uname, host: host, privileges: Map.put(user.privileges || %{}, channel, privileges)} else - user = %User{network: sender.network, nick: nick, username: uname, host: host, privileges: %{channel => privileges}} + user = %User{id: IRC.UserTrack.Id.large_id, network: sender.network, nick: nick, username: uname, host: host, privileges: %{channel => privileges}} account = IRC.Account.lookup(user).id user = %User{user | account: account} @@ -197,6 +197,8 @@ defmodule IRC.UserTrack do Storage.op(fn(ets) -> :ets.insert(ets, User.to_tuple(user)) end) + + IRC.Connection.publish_event({sender.network, channel}, %{type: :join, user_id: user.id, account_id: user.account}) end #def joined(network, channel, nick, privileges) do @@ -235,6 +237,8 @@ defmodule IRC.UserTrack do account = IRC.Account.lookup(user, false) || old_account user = %User{user | nick: new_nick, account: account.id, nicks: [old_nick|user.nicks]} Storage.insert(User.to_tuple(user)) + channels = for {channel, _} <- user.privileges, do: channel + IRC.Connection.publish_event(network, %{type: :nick, user_id: user.id, account_id: account.id, nick: new_nick, old_nick: old_nick}) end end @@ -247,9 +251,11 @@ defmodule IRC.UserTrack do user = %User{user | privileges: Map.put(user.privileges, channel, privs)} Storage.insert(User.to_tuple(user)) + IRC.Connection.publish_event({network, channel}, %{type: :privileges, user_id: user.id, account_id: user.account, added: add, removed: remove}) end end + # XXX: Reason def parted(channel, %{network: network, nick: nick}) do parted(network, channel, nick) end @@ -265,16 +271,21 @@ defmodule IRC.UserTrack do if Enum.count(privs) > 0 do user = %User{user | privileges: privs} Storage.insert(User.to_tuple(user)) + IRC.Connection.publish_event({network, channel}, %{type: :part, user_id: user.id, account_id: user.account, reason: nil}) else + IRC.Connection.publish_event(network, %{type: :quit, user_id: user.id, account_id: user.account, reason: "Left all known channels"}) Storage.delete(user.id) end end end - def quitted(sender) do + def quitted(sender, reason) do if user = find_by_nick(sender.network, sender.nick) do if user.account do - for({channel, _} <- user.privileges, do: IRC.Membership.touch(user.account, sender.network, channel)) + for {channel, _} <- user.privileges do + IRC.Membership.touch(user.account, sender.network, channel) + end + IRC.Connection.publish_event(sender.network, %{type: :quit, user_id: user.id, account_id: user.account, reason: reason}) end Storage.delete(user.id) end @@ -288,4 +299,8 @@ defmodule IRC.UserTrack do %User{user | last_active: last_active} end + defp userchans(%{privileges: privileges}) do + for({chan, _} <- privileges, do: chan) + end + end |