diff options
Diffstat (limited to 'lib/irc/membership.ex')
-rw-r--r-- | lib/irc/membership.ex | 129 |
1 files changed, 0 insertions, 129 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 |