diff options
Diffstat (limited to '')
-rw-r--r-- | lib/lsg_irc/preums_plugin.ex | 80 |
1 files changed, 63 insertions, 17 deletions
diff --git a/lib/lsg_irc/preums_plugin.ex b/lib/lsg_irc/preums_plugin.ex index 1f9a76b..7bb2c78 100644 --- a/lib/lsg_irc/preums_plugin.ex +++ b/lib/lsg_irc/preums_plugin.ex @@ -6,6 +6,35 @@ defmodule LSG.IRC.PreumsPlugin do * `.preums`: stats des preums """ + # WIP Scores + # L'idée c'est de donner un score pour mettre un peu de challenge en pénalisant les preums faciles. + # + # Un preums ne vaut pas 1 point, mais plutôt 0.10 ou 0.05, et on arrondi au plus proche. C'est un jeu sur le long + # terme. Un gros bonus pourrait apporter beaucoup de points. + # + # Il faudrait ces données: + # - moyenne des preums + # - activité récente du channel et par nb actifs d'utilisateurs + # (aggréger memberships+usertrack last_active ?) + # (faire des stats d'activité habituelle (un peu a la pisg) ?) + # - preums consécutifs + # + # Malus: + # - est proche de la moyenne en faible activité + # - trop consécutif de l'utilisateur sauf si activité + # + # Bonus: + # - plus le preums est éloigné de la moyenne + # - après 18h double + # - plus l'activité est élévée, exponentiel selon la moyenne + # - derns entre 4 et 6 (pourrait être adapté selon les stats d'activité) + # + # WIP Badges: + # - derns + # - streaks + # - faciles + # - ? + require Logger @perfects [~r/preum(s|)/i] @@ -17,9 +46,9 @@ defmodule LSG.IRC.PreumsPlugin do end def all(dets, channel) do - fun = fn({{chan, date}, nick, time, perfect, text}, acc) -> + fun = fn({{chan, date}, account_id, time, perfect, text}, acc) -> if channel == chan do - [%{date: date, nick: nick, time: time, perfect: perfect, text: text} | acc] + [%{date: date, account_id: account_id, time: time, perfect: perfect, text: text} | acc] else acc end @@ -27,22 +56,28 @@ defmodule LSG.IRC.PreumsPlugin do :dets.foldl(fun, [], dets) end - def topnicks(dets, channel) do - fun = fn(x = {{chan, date}, nick, _time, _perfect, _text}, acc) -> + def topnicks(dets, channel, options \\ []) do + sort_elem = case Keyword.get(options, :sort_by, :score) do + :score -> 1 + :count -> 0 + end + + fun = fn(x = {{chan, date}, account_id, time, perfect, text}, acc) -> if (channel == nil and chan) or (channel == chan) do - count = Map.get(acc, nick, 0) - Map.put(acc, nick, count + 1) + {count, points} = Map.get(acc, account_id, {0, 0}) + score = score(chan, account_id, time, perfect, text) + Map.put(acc, account_id, {count + 1, points + score}) else acc end end :dets.foldl(fun, %{}, dets) - |> Enum.sort_by(fn({nick, count}) -> count end, &>=/2) + |> Enum.sort_by(fn({_account_id, value}) -> elem(value, sort_elem) end, &>=/2) end def irc_doc, do: @moduledoc def start_link() do - GenServer.start_link(__MODULE__, []) + GenServer.start_link(__MODULE__, [], name: __MODULE__) end def dets do @@ -50,9 +85,10 @@ defmodule LSG.IRC.PreumsPlugin do end def init([]) do - {:ok, _} = Registry.register(IRC.PubSub, "account", []) - {:ok, _} = Registry.register(IRC.PubSub, "message", []) - {:ok, _} = Registry.register(IRC.PubSub, "triggers", []) + regopts = [plugin: __MODULE__] + {:ok, _} = Registry.register(IRC.PubSub, "account", regopts) + {:ok, _} = Registry.register(IRC.PubSub, "message", regopts) + {:ok, _} = Registry.register(IRC.PubSub, "triggers", regopts) {:ok, dets} = :dets.open_file(dets(), [{:repair, :force}]) Util.ets_mutate_select_each(:dets, dets, [{:"$1", [], [:"$1"]}], fn(table, obj) -> {key, nick, now, perfect, text} = obj @@ -98,14 +134,17 @@ defmodule LSG.IRC.PreumsPlugin do i else case :dets.lookup(state.dets, key) do - [item = {^key, _nick, _now, _perfect, _text}] -> item + [item = {^key, _account_id, _now, _perfect, _text}] -> item _ -> nil end end if item do - {_, nick, date, _perfect, text} = item + {_, account_id, date, _perfect, text} = item h = "#{date.hour}:#{date.minute}:#{date.second}" + account = IRC.Account.get(account_id) + user = IRC.UserTrack.find_by_account(m.network, account) + nick = if(user, do: user.nick, else: account.name) m.replyfun.("preums: #{nick} à #{h}: “#{text}”") end {:noreply, state} @@ -115,11 +154,13 @@ defmodule LSG.IRC.PreumsPlugin do def handle_info({:irc, :trigger, "preums", m = %IRC.Message{trigger: %IRC.Trigger{type: :dot}}}, state) do channel = {m.network, m.channel} state = handle_preums(m, state) - top = topnicks(state.dets, channel) - |> Enum.map(fn({nick, count}) -> - "#{nick} (#{count})" + top = topnicks(state.dets, channel, sort_by: :score) + |> Enum.map(fn({account_id, {count, score}}) -> + account = IRC.Account.get(account_id) + user = IRC.UserTrack.find_by_account(m.network, account) + nick = if(user, do: user.nick, else: account.name) + "#{nick}: #{score} (#{count})" end) - |> Enum.filter(fn(x) -> x end) |> Enum.intersperse(", ") |> Enum.join("") msg = unless top == "" do @@ -227,4 +268,9 @@ defmodule LSG.IRC.PreumsPlugin do end end + def score(_chan, _account, _time, _perfect, _text) do + 1 + end + + end |