summaryrefslogtreecommitdiff
path: root/lib/nola_plugins/alcoolog_announcer.ex
diff options
context:
space:
mode:
Diffstat (limited to 'lib/nola_plugins/alcoolog_announcer.ex')
-rw-r--r--lib/nola_plugins/alcoolog_announcer.ex269
1 files changed, 269 insertions, 0 deletions
diff --git a/lib/nola_plugins/alcoolog_announcer.ex b/lib/nola_plugins/alcoolog_announcer.ex
new file mode 100644
index 0000000..674f19b
--- /dev/null
+++ b/lib/nola_plugins/alcoolog_announcer.ex
@@ -0,0 +1,269 @@
+defmodule Nola.Plugins.AlcoologAnnouncer do
+ require Logger
+
+ @moduledoc """
+ Annonce changements d'alcoolog
+ """
+
+ @channel "#dmz"
+
+ @seconds 30
+
+ @apero [
+ "C'EST L'HEURE DE L'APÉRRROOOOOOOO !!",
+ "SAAAAANNNNNNNTTTTTTTTAAAAAAAAIIIIIIIIIIIIIIIIIIIIII",
+ "APÉRO ? APÉRO !",
+ {:timed, ["/!\\ à vos tires bouchons…", "… débouchez …", "… BUVEZ! SANTAIII!"]},
+ "/!\\ ALERTE APÉRO /!\\",
+ "CED !!! VASE DE ROUGE !",
+ "DIDI UN PETIT RICARD™??!",
+ "ALLEZ GUIGUI UNE PETITE BIERE ?",
+ {:timed, ["/!\\ à vos tires bouchons…", "… débouchez …", "… BUVEZ! SANTAIII!"]},
+ "APPPPAIIIRRREAAUUUUUUUUUUU"
+ ]
+
+ def irc_doc, do: nil
+
+ def start_link(), do: GenServer.start_link(__MODULE__, [], name: __MODULE__)
+
+ def log(account) do
+ dets_filename = (Nola.data_path() <> "/" <> "alcoologlog.dets") |> String.to_charlist
+ {:ok, dets} = :dets.open_file(dets_filename, [{:type,:bag}])
+ from = ~U[2020-08-23 19:41:40.524154Z]
+ to = ~U[2020-08-24 19:41:40.524154Z]
+ select = [
+ {{:"$1", :"$2", :_},
+ [
+ {:andalso,
+ {:andalso, {:==, :"$1", {:const, account.id}},
+ {:>, :"$2", {:const, DateTime.to_unix(from)}}},
+ {:<, :"$2", {:const, DateTime.to_unix(to)}}}
+ ], [:"$_"]}
+ ]
+ res = :dets.select(dets, select)
+ :dets.close(dets)
+ res
+ end
+
+ def init(_) do
+ {:ok, _} = Registry.register(IRC.PubSub, "account", [])
+ stats = get_stats()
+ Process.send_after(self(), :stats, :timer.seconds(30))
+ dets_filename = (Nola.data_path() <> "/" <> "alcoologlog.dets") |> String.to_charlist
+ {:ok, dets} = :dets.open_file(dets_filename, [{:type,:bag}])
+ ets = nil # :ets.new(__MODULE__.ETS, [:ordered_set, :named_table, :protected, {:read_concurrency, true}])
+ {:ok, {stats, now(), dets, ets}}#, {:continue, :traverse}}
+ end
+
+ def handle_continue(:traverse, state = {_, _, dets, ets}) do
+ traverse_fun = fn(obj, dets) ->
+ case obj do
+ {nick, %DateTime{} = dt, active} ->
+ :dets.delete_object(dets, obj)
+ :dets.insert(dets, {nick, DateTime.to_unix(dt), active})
+ IO.puts("ok #{inspect obj}")
+ dets
+ {nick, ts, value} ->
+ :ets.insert(ets, { {nick, ts}, value })
+ dets
+ end
+ end
+ :dets.foldl(traverse_fun, dets, dets)
+ :dets.sync(dets)
+ IO.puts("alcoolog announcer fixed")
+ {:noreply, state}
+ end
+
+ def alcohol_reached(old, new, level) do
+ (old.active < level && new.active >= level) && (new.active5m >= level)
+ end
+
+ def alcohol_below(old, new, level) do
+ (old.active > level && new.active <= level) && (new.active5m <= level)
+ end
+
+
+ def handle_info(:stats, {old_stats, old_now, dets, ets}) do
+ stats = get_stats()
+ now = now()
+
+ if old_now.hour < 18 && now.hour == 18 do
+ apero = Enum.shuffle(@apero)
+ |> Enum.random()
+
+ case apero do
+ {:timed, list} ->
+ spawn(fn() ->
+ for line <- list do
+ IRC.Connection.broadcast_message("evolu.net", "#dmz", line)
+ :timer.sleep(:timer.seconds(5))
+ end
+ end)
+ string ->
+ IRC.Connection.broadcast_message("evolu.net", "#dmz", string)
+ end
+
+ end
+
+ #IO.puts "newstats #{inspect stats}"
+ events = for {acct, old} <- old_stats do
+ new = Map.get(stats, acct, nil)
+ #IO.puts "#{acct}: #{inspect(old)} -> #{inspect(new)}"
+
+ now = DateTime.to_unix(DateTime.utc_now())
+ if new && new[:active] do
+ :dets.insert(dets, {acct, now, new[:active]})
+ :ets.insert(ets, {{acct, now}, new[:active]})
+ else
+ :dets.insert(dets, {acct, now, 0.0})
+ :ets.insert(ets, {{acct, now}, new[:active]})
+ end
+
+ event = cond do
+ old == nil -> nil
+ (old.active > 0) && (new == nil) -> :sober
+ new == nil -> nil
+ alcohol_reached(old, new, 0.5) -> :stopconduire
+ alcohol_reached(old, new, 1.0) -> :g1
+ alcohol_reached(old, new, 2.0) -> :g2
+ alcohol_reached(old, new, 3.0) -> :g3
+ alcohol_reached(old, new, 4.0) -> :g4
+ alcohol_reached(old, new, 5.0) -> :g5
+ alcohol_reached(old, new, 6.0) -> :g6
+ alcohol_reached(old, new, 7.0) -> :g7
+ alcohol_reached(old, new, 10.0) -> :g10
+ alcohol_reached(old, new, 13.74) -> :record
+ alcohol_below(old, new, 0.5) -> :conduire
+ alcohol_below(old, new, 1.0) -> :fini1g
+ alcohol_below(old, new, 2.0) -> :fini2g
+ alcohol_below(old, new, 3.0) -> :fini3g
+ alcohol_below(old, new, 4.0) -> :fini4g
+ (old.rising) && (!new.rising) -> :lowering
+ true -> nil
+ end
+ {acct, event}
+ end
+
+ for {acct, event} <- events do
+ message = case event do
+ :g1 -> [
+ "[vigicuite jaune] LE GRAMME! LE GRAMME O/",
+ "début de vigicuite jaune ! LE GRAMME ! \\O/",
+ "waiiiiiiii le grammmeee",
+ "bourraiiiiiiiiiiide 1 grammeeeeeeeeeee",
+ ]
+ :g2 -> [
+ "[vigicuite orange] \\o_YAY 2 GRAMMES ! _o/",
+ "PAITAIIIIIIIIII DEUX GRAMMEESSSSSSSSSSSSSSSSS",
+ "bourrrrrraiiiiiiiiiiiiiiiide 2 grammeeeeeeeeeees",
+ ]
+ :g3 -> [
+ "et un ! et deux ! et TROIS GRAMMEEESSSSSSS",
+ "[vigicuite rouge] _o/ BOURRAIIDDDEEEE 3 GRAMMESSSSSSSSS \\o/ \\o/"
+ ]
+ :g4 -> [
+ "[vigicuite écarlate] et un, et deux, et trois, ET QUATRES GRAMMEESSSSSSSSSSSSSSSSSSSssssss"
+ ]
+ :g5 -> "[vigicuite écarlate+] PUTAIN 5 GRAMMES !"
+ :g6 -> "[vigicuite écarlate++] 6 grammes ? Vous pouvez joindre Alcool info service au 0 980 980 930"
+ :g7 -> "[vigicuite c'est la merde] 7 grammes. Le SAMU, c'est le 15."
+ :g10 -> "BORDLE 10 GRAMMES"
+ :record -> "RECORD DU MONDE BATTU ! >13.74g/l !!"
+ :fini1g -> [
+ "fin d'alerte vigicuite jaune, passage en vert (<1g/l)",
+ "/!\\ alerte moins de 1g/l /!\\"
+ ]
+ :fini2g -> [
+ "t'as moins de 2 g/l, faut se reprendre là [vigicuite jaune]"
+ ]
+ :fini3g -> [
+ "fin d'alerte vigicuite rouge, passage en orange (<3g/l)"
+ ]
+ :fini4g -> [
+ "fin d'alerte vigicuite écarlate, passage en rouge (<4g/l)"
+ ]
+ :lowering -> [
+ "attention ça baisse!",
+ "tu vas quand même pas en rester là ?",
+ "IL FAUT CONTINUER À BOIRE !",
+ "t'abandonnes déjà ?",
+ "!santai ?",
+ "faut pas en rester là",
+ "il faut se resservir",
+ "coucou faut reboire",
+ "encore un petit verre ?",
+ "abwaaaaaaaaaaaaarrrrrrrrrrrrrr",
+ "taux d'alcoolémie en chute ! agissez avant qu'il soit trop tard!",
+ "ÇA BAISSE !!"
+ ]
+ :stopconduire -> [
+ "0.5g! bientot le gramme?",
+ "tu peux plus prendre la route... mais... tu peux prendre la route du gramme! !santai !",
+ "fini la conduite!",
+ "0.5! continues faut pas en rester là!",
+ "beau début, continues !",
+ "ça monte! 0.5g/l!"
+ ]
+ :conduire -> [
+ "tu peux conduire, ou recommencer à boire! niveau critique!",
+ "!santai ?",
+ "tu peux reprendre la route, ou reprendre la route du gramme..",
+ "attention, niveau critique!",
+ "il faut boire !!",
+ "trop de sang dans ton alcool, c'est mauvais pour la santé",
+ "faut pas en rester là !",
+ ]
+ :sober -> [
+ "sobre…",
+ "/!\\ alerte sobriété /!\\",
+ "... sobre?!?!",
+ "sobre :(",
+ "attention, t'es sobre :/",
+ "danger, alcoolémie à 0.0 !",
+ "sobre! c'était bien on recommence quand ?",
+ "sobre ? Faut recommencer...",
+ "T'es sobre. Ne te laisses pas abattre- ton caviste peut aider.",
+ "Vous êtes sobre ? Ceci n'est pas une fatalité - resservez vous vite !"
+ ]
+ _ -> nil
+ end
+ message = case message do
+ m when is_binary(m) -> m
+ m when is_list(m) -> m |> Enum.shuffle() |> Enum.random()
+ nil -> nil
+ end
+ if message do
+ #IO.puts("#{acct}: #{message}")
+ account = IRC.Account.get(acct)
+ for {net, chan} <- IRC.Membership.notify_channels(account) do
+ user = IRC.UserTrack.find_by_account(net, account)
+ nick = if(user, do: user.nick, else: account.name)
+ IRC.Connection.broadcast_message(net, chan, "#{nick}: #{message}")
+ end
+ end
+ end
+
+ timer()
+
+ #IO.puts "tick stats ok"
+ {:noreply, {stats,now,dets,ets}}
+ end
+
+ def handle_info(_, state) do
+ {:noreply, state}
+ end
+
+ defp now() do
+ DateTime.utc_now()
+ |> Timex.Timezone.convert("Europe/Paris")
+ end
+
+ defp get_stats() do
+ Enum.into(Nola.Plugins.Alcoolog.get_all_stats(), %{})
+ end
+
+ defp timer() do
+ Process.send_after(self(), :stats, :timer.seconds(@seconds))
+ end
+
+end