diff options
Diffstat (limited to '')
-rw-r--r-- | lib/lsg_irc/alcolog_plugin.ex | 200 |
1 files changed, 200 insertions, 0 deletions
diff --git a/lib/lsg_irc/alcolog_plugin.ex b/lib/lsg_irc/alcolog_plugin.ex new file mode 100644 index 0000000..b5392a3 --- /dev/null +++ b/lib/lsg_irc/alcolog_plugin.ex @@ -0,0 +1,200 @@ +defmodule LSG.IRC.AlcologPlugin do + require Logger + + @moduledoc """ + # alcoolisme _(v2)_ + + * **`!santai <montant> <degrés d'alcool> [annotation]`** enregistre un nouveau verre de `montant` d'une boisson à `degrés d'alcool`. + + * **!`<trigger>` `[coeff]` `[annotation]`** enregistre de l'alcoolisme. + * **!alcoolisme `[pseudo]`** affiche les points d'alcoolisme. + + Triggers/Coeffs: + + * bière: (coeffs: 25, 50/+, 75/++, 100/+++, ++++) + * pinard: (coeffs: +, ++, +++, ++++) + * shot/fort/whisky/rhum/..: (coeffs: +, ++, +++, ++++) + * eau (-1) + + Annotation: champ libre! + + """ + + @triggers %{ + "apero" => + %{ + triggers: ["apero", "apéro", "apairo", "santai"], + default_coeff: "25", + coeffs: %{ + "+" => 2, + "++" => 3, + "+++" => 4, + "++++" => 5, + } + }, + "bière" => + %{ + triggers: ["beer", "bière", "biere", "biaire"], + default_coeff: "25", + coeffs: %{ + "25" => 1, + "50" => 2, + "75" => 3, + "100" => 4, + "+" => 2, + "++" => 3, + "+++" => 4, + "++++" => 5, + } + }, + "pinard" => %{ + triggers: ["pinard", "vin", "rouge", "blanc", "rosé", "rose"], + annotations: ["rouge", "blanc", "rosé", "rose"], + default_coeff: "", + coeffs: %{ + "" => 1, + "+" => 2, + "++" => 3, + "+++" => 4, + "++++" => 5, + "vase" => 6, + } + }, + "fort" => %{ + triggers: ["shot", "royaume", "whisky", "rhum", "armagnac", "dijo"], + default_coeff: "", + coeffs: %{ + "" => 3, + "+" => 5, + "++" => 7, + "+++" => 9, + "++++" => 11 + } + }, + "eau" => %{ + triggers: ["eau"], + default_coeff: "1", + coeffs: %{ + "1" => -2, + "+" => -3, + "++" => -4, + "+++" => -6, + "++++" => -8 + } + } + } + + @santai ["SANTÉ", "SANTÉ", "SANTAIIII", "SANTAIIIIIIIIII", "SANTAI", "A LA TIENNE"] + + def irc_doc, do: @moduledoc + + def start_link(), do: GenServer.start_link(__MODULE__, []) + + def init(_) do + {:ok, _} = Registry.register(IRC.PubSub, "trigger:alcoolisme", []) + for {_, config} <- @triggers do + for trigger <- config.triggers do + {:ok, _} = Registry.register(IRC.PubSub, "trigger:#{trigger}", []) + for coeff when byte_size(coeff) > 0 <- Map.keys(config.coeffs) do + {:ok, _} = Registry.register(IRC.PubSub, "trigger:#{trigger}#{coeff}", []) + end + end + end + dets_filename = (LSG.data_path() <> "/" <> "alcoolisme.dets") |> String.to_charlist + {:ok, dets} = :dets.open_file(dets_filename, [{:type,:bag}]) + {:ok, dets} + end + + for {name, config} <- @triggers do + coeffs = Map.get(config, "coeffs") + default_coeff_value = Map.get(config.coeffs, config.default_coeff) + + + IO.puts "at triggers #{inspect config}" + # Handle each trigger + for trigger <- config.triggers do + + # … with a known coeff … + for {coef, value} when byte_size(coef) > 0 <- config.coeffs do + def handle_info({:irc, :trigger, unquote(trigger), m = %IRC.Message{trigger: %IRC.Trigger{args: [unquote(coef)<>_ | args], type: :bang}}}, dets) do + handle_bang(unquote(name), unquote(value), m, args, dets) + {:noreply, dets} + end + def handle_info({:irc, :trigger, unquote(trigger)<>unquote(coef), m = %IRC.Message{trigger: %IRC.Trigger{args: args, type: :bang}}}, dets) do + handle_bang(unquote(name), unquote(value), m, args, dets) + {:noreply, dets} + end + end + + # … or without + def handle_info({:irc, :trigger, unquote(trigger), m = %IRC.Message{trigger: %IRC.Trigger{args: args, type: :bang}}}, dets) do + handle_bang(unquote(name), unquote(default_coeff_value), m, args, dets) + {:noreply, dets} + end + + end + + end + + def handle_info({:irc, :trigger, "alcoolisme", m = %IRC.Message{trigger: %IRC.Trigger{args: args, type: :bang}}}, dets) do + nick = case args do + [nick] -> nick + [] -> m.sender.nick + end + case get_statistics_for_nick(dets, nick) do + {count, {_, last_at, last_points, last_type, last_descr}} -> + m.replyfun.("#{nick} a #{count} points d'alcoolisme. Dernier verre: #{present_type(last_type, + last_descr)} [#{last_points}] #{format_relative_timestamp(last_at)}") + _ -> + m.replyfun.("honteux mais #{nick} n'a pas l'air alcoolique du tout. /kick") + end + {:noreply, dets} + end + + defp handle_bang(name, points, message, args, dets) do + description = case args do + [] -> nil + [something] -> something + something when is_list(something) -> Enum.join(something, " ") + _ -> nil + end + now = DateTime.to_unix(DateTime.utc_now(), :milliseconds) + :ok = :dets.insert(dets, {String.downcase(message.sender.nick), now, points, name, description}) + {count, {_, last_at, last_points, last_type, last_descr}} = get_statistics_for_nick(dets, message.sender.nick) + sante = @santai |> Enum.shuffle() |> Enum.random() + message.replyfun.("#{sante} #{message.sender.nick} #{format_points(points)}! (total #{count} points)") + end + + defp get_statistics_for_nick(dets, nick) do + qvc = :dets.lookup(dets, String.downcase(nick)) + IO.puts inspect(qvc) + count = Enum.reduce(qvc, 0, fn({_nick, _ts, points, _type, _descr}, acc) -> acc + points end) + last = List.last(qvc) || nil + {count, last} + end + + def present_type(type, descr) when descr in [nil, ""], do: "#{type}" + def present_type(type, description), do: "#{type} (#{description})" + + def format_points(int) when int > 0 do + "+#{Integer.to_string(int)}" + end + def format_points(int) when int < 0 do + Integer.to_string(int) + end + def format_points(0), do: "0" + + defp format_relative_timestamp(timestamp) do + alias Timex.Format.DateTime.Formatters + alias Timex.Timezone + date = timestamp + |> DateTime.from_unix!(:milliseconds) + |> Timezone.convert("Europe/Paris") + + {:ok, relative} = Formatters.Relative.relative_to(date, Timex.now("Europe/Paris"), "{relative}", "fr") + {:ok, detail} = Formatters.Default.lformat(date, " ({h24}:{m})", "fr") + + relative <> detail + end +end + |