summaryrefslogtreecommitdiff
path: root/lib/irc
diff options
context:
space:
mode:
authorhref <href@random.sh>2021-09-03 04:04:21 +0200
committerhref <href@random.sh>2021-09-03 04:04:21 +0200
commit5399fc818cf821c75f9f19fd00bf7905ba7fe7e3 (patch)
tree00408724f9778cc7323b1459782a762626d39b6a /lib/irc
parentassets.. (diff)
various fixes, web client wip, pubsub events
Diffstat (limited to 'lib/irc')
-rw-r--r--lib/irc/account.ex2
-rw-r--r--lib/irc/connection.ex38
-rw-r--r--lib/irc/puppet_connection.ex4
-rw-r--r--lib/irc/user_track.ex21
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