diff options
Diffstat (limited to 'lib/irc')
-rw-r--r-- | lib/irc/membership.ex | 129 | ||||
-rw-r--r-- | lib/irc/nola_irc.ex | 2 | ||||
-rw-r--r-- | lib/irc/user_track.ex | 8 |
3 files changed, 5 insertions, 134 deletions
diff --git a/lib/irc/membership.ex b/lib/irc/membership.ex deleted file mode 100644 index 25a0cfc..0000000 --- a/lib/irc/membership.ex +++ /dev/null @@ -1,129 +0,0 @@ -defmodule IRC.Membership do - @moduledoc """ - Memberships (users in channels) - """ - - # Key: {account, net, channel} - # Format: {key, last_seen} - - defp dets() do - to_charlist(Nola.data_path <> "/memberships.dets") - end - - def start_link() do - GenServer.start_link(__MODULE__, [], [name: __MODULE__]) - end - - def init(_) do - dets = :dets.open_file(dets(), []) - {:ok, dets} - end - - def of_account(%Nola.Account{id: id}) do - spec = [{{{:"$1", :"$2", :"$3"}, :_}, [{:==, :"$1", {:const, id}}], [{{:"$2", :"$3"}}]}] - :dets.select(dets(), spec) - end - - def merge_account(old_id, new_id) do - #iex(37)> :ets.fun2ms(fn({{old_id, _, _}, _}=obj) when old_id == "42" -> obj end) - spec = [{{{:"$1", :_, :_}, :_}, [{:==, :"$1", {:const, old_id}}], [:"$_"]}] - Util.ets_mutate_select_each(:dets, dets(), spec, fn(table, obj = {{_old, net, chan}, ts}) -> - :dets.delete_object(table, obj) - :dets.insert(table, {{new_id, net, chan}, ts}) - end) - end - - def touch(%Nola.Account{id: id}, network, channel) do - :dets.insert(dets(), {{id, network, channel}, NaiveDateTime.utc_now()}) - end - def touch(account_id, network, channel) do - if account = Nola.Account.get(account_id) do - touch(account, network, channel) - end - end - - def notify_channels(account, minutes \\ 30, last_active \\ true) do - not_before = NaiveDateTime.add(NaiveDateTime.utc_now(), (minutes*-60), :second) - spec = [{{{:"$1", :_, :_}, :_}, [{:==, :"$1", {:const, account.id}}], [:"$_"]}] - memberships = :dets.select(dets(), spec) - |> Enum.sort_by(fn({_, ts}) -> ts end, {:desc, NaiveDateTime}) - active_memberships = Enum.filter(memberships, fn({_, ts}) -> NaiveDateTime.compare(ts, not_before) == :gt end) - cond do - active_memberships == [] && last_active -> - case memberships do - [{{_, net, chan}, _}|_] -> [{net, chan}] - _ -> [] - end - active_memberships == [] -> - [] - true -> - Enum.map(active_memberships, fn({{_, net, chan}, _}) -> {net,chan} end) - end - end - - def members_or_friends(account, _network, nil) do - friends(account) - end - - def members_or_friends(_, network, channel) do - members(network, channel) - end - - def expanded_members_or_friends(account, network, channel) do - expand(network, members_or_friends(account, network, channel)) - end - - def expanded_members(network, channel) do - expand(network, members(network, channel)) - end - - def members(network, channel) do - #iex(19)> :ets.fun2ms(fn({{id, net, chan}, ts}) when net == network and chan == channel and ts > min_seen -> id end) - limit = 0 # NaiveDateTime.add(NaiveDateTime.utc_now, 30*((24*-60)*60), :second) - spec = [ - {{{:"$1", :"$2", :"$3"}, :"$4"}, - [ - {:andalso, - {:andalso, {:==, :"$2", {:const, network}}, {:==, :"$3", {:const, channel}}}, - {:>, :"$4", {:const, limit}}} - ], [:"$1"]} - ] - :dets.select(dets(), spec) - end - - def friends(account = %Nola.Account{id: id}) do - for({net, chan} <- of_account(account), do: members(net, chan)) - |> List.flatten() - |> Enum.uniq() - end - - def handle_info(_, dets) do - {:noreply, dets} - end - - def handle_cast(_, dets) do - {:noreply, dets} - end - - def handle_call(_, _, dets) do - {:noreply, dets} - end - - def terminate(_, dets) do - :dets.sync(dets) - :dets.close(dets) - end - - defp expand(network, list) do - for id <- list do - if account = Nola.Account.get(id) do - user = IRC.UserTrack.find_by_account(network, account) - nick = if(user, do: user.nick, else: account.name) - {account, user, nick} - end - end - |> Enum.filter(fn(x) -> x end) - end - - -end diff --git a/lib/irc/nola_irc.ex b/lib/irc/nola_irc.ex index 2d355d3..7e23f50 100644 --- a/lib/irc/nola_irc.ex +++ b/lib/irc/nola_irc.ex @@ -12,7 +12,7 @@ defmodule Nola.IRC do [ worker(Registry, [[keys: :duplicate, name: IRC.ConnectionPubSub]], id: :registr_irc_conn), - worker(IRC.Membership, []), + worker(Nola.Membership, []), worker(Nola.Account, []), worker(IRC.UserTrack.Storage, []), worker(Nola.Plugins.Account, []), diff --git a/lib/irc/user_track.ex b/lib/irc/user_track.ex index 3f144d5..56a319f 100644 --- a/lib/irc/user_track.ex +++ b/lib/irc/user_track.ex @@ -213,7 +213,7 @@ defmodule IRC.UserTrack do user = touch_struct(user, channel) if touch && user.account do - IRC.Membership.touch(user.account, sender.network, channel) + Nola.Membership.touch(user.account, sender.network, channel) end Storage.op(fn(ets) -> @@ -246,7 +246,7 @@ defmodule IRC.UserTrack do {%User{user | account: account.id}, account} end Storage.insert(User.to_tuple(user)) - if chan, do: IRC.Membership.touch(account, network, chan) + if chan, do: Nola.Membership.touch(account, network, chan) if !m.account do {:ok, %IRC.Message{m | account: account}} else @@ -287,7 +287,7 @@ defmodule IRC.UserTrack do def parted(network, channel, nick) do if user = find_by_nick(network, nick) do if user.account do - IRC.Membership.touch(user.account, network, channel) + Nola.Membership.touch(user.account, network, channel) end privs = Map.delete(user.privileges, channel) @@ -307,7 +307,7 @@ defmodule IRC.UserTrack 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) + Nola.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 |