summaryrefslogtreecommitdiff
path: root/lib/lsg_irc/preums_plugin.ex
diff options
context:
space:
mode:
authorhref <href@random.sh>2021-09-01 10:30:18 +0200
committerhref <href@random.sh>2021-09-01 10:30:18 +0200
commit75687711f35355bc30e4829439384aab28fcac6d (patch)
tree8f3256f472893c39720a684d390e890a152f7303 /lib/lsg_irc/preums_plugin.ex
parentlink: post_* callbacks; html & pdftitle. (diff)
Commit all the changes that hasn't been committed + updates.
Diffstat (limited to 'lib/lsg_irc/preums_plugin.ex')
-rw-r--r--lib/lsg_irc/preums_plugin.ex80
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