diff options
author | href <href@random.sh> | 2020-03-11 21:18:34 +0100 |
---|---|---|
committer | href <href@random.sh> | 2020-03-11 21:18:34 +0100 |
commit | a28d24470ddeca6196219a1333c1ccac1319efef (patch) | |
tree | 4f29e3c8fb6afbb1f99d6b8737f844c95fca54df /lib/lsg_irc/preums_plugin.ex | |
parent | up to 420*100 (diff) |
welp
Diffstat (limited to '')
-rw-r--r-- | lib/lsg_irc/preums_plugin.ex | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/lib/lsg_irc/preums_plugin.ex b/lib/lsg_irc/preums_plugin.ex new file mode 100644 index 0000000..98cd539 --- /dev/null +++ b/lib/lsg_irc/preums_plugin.ex @@ -0,0 +1,108 @@ +defmodule LSG.IRC.PreumsPlugin do + @moduledoc """ + # preums !!! + + * `!preums`: affiche le preums du jour + * `.preums`: stats des preums + """ + + @perfects [~r/preum(s|)/i] + + # dets {{chan, day = {yyyy, mm, dd}}, nick, now, perfect?, text} + + def irc_doc, do: @moduledoc + def start_link() do + GenServer.start_link(__MODULE__, []) + end + + def init([]) do + {:ok, _} = Registry.register(IRC.PubSub, "message", []) + {:ok, _} = Registry.register(IRC.PubSub, "triggers", []) + dets_filename = (LSG.data_path() <> "/preums.dets") |> String.to_charlist() + {:ok, dets} = :dets.open_file(dets_filename, []) + {:ok, %{dets: dets}} + end + + # Latest + def handle_info({:irc, :trigger, "preums", m = %IRC.Message{channel: channel, trigger: %IRC.Trigger{type: :bang}}}, state) do + state = handle_preums(m, state) + tz = timezone(channel) + {:ok, now} = DateTime.now(tz, Tzdata.TimeZoneDatabase) + date = {now.year, now.month, now.day} + key = {channel, date} + chan_cache = Map.get(state, channel, %{}) + item = if i = Map.get(chan_cache, date) do + i + else + case :dets.lookup(state.dets, key) do + [item = {^key, _nick, _now, _perfect, _text}] -> item + _ -> nil + end + end + + if item do + {_, nick, date, _perfect, text} = item + h = "#{date.hour}:#{date.minute}:#{date.second}" + m.replyfun.("preums: #{nick} à #{h}: “#{text}”") + end + {:noreply, state} + end + + # Stats + def handle_info({:irc, :trigger, "preums", m = %IRC.Message{channel: channel, trigger: %IRC.Trigger{type: :dot}}}, state) do + state = handle_preums(m, state) + {:noreply, state} + end + + # Help + def handle_info({:irc, :trigger, "preums", m = %IRC.Message{channel: channel, trigger: %IRC.Trigger{type: :query}}}, state) do + state = handle_preums(m, state) + {:noreply, state} + end + + # Trigger fallback + def handle_info({:irc, :trigger, _, m = %IRC.Message{}}, state) do + state = handle_preums(m, state) + {:noreply, state} + end + + # Message fallback + def handle_info({:irc, :text, m = %IRC.Message{}}, state) do + {:noreply, handle_preums(m, state)} + end + + defp timezone(channel) do + env = Application.get_env(:lsg, LSG.IRC.PreumsPlugin, []) + channels = Keyword.get(env, :channels, %{}) + channel_settings = Map.get(channels, channel, []) + default = Keyword.get(env, :default_tz, "Europe/Paris") + Keyword.get(channel_settings, :tz, default) || default + end + + defp handle_preums(m = %IRC.Message{channel: channel, text: text, sender: sender}, state) do + tz = timezone(channel) + {:ok, now} = DateTime.now(tz, Tzdata.TimeZoneDatabase) + date = {now.year, now.month, now.day} + key = {channel, date} + chan_cache = Map.get(state, channel, %{}) + unless i = Map.get(chan_cache, date) do + case :dets.lookup(state.dets, key) do + [item = {^key, _nick, _now, _perfect, _text}] -> + # Preums lost, but wasn't cached + state = Map.put(state, channel, %{date => item}) + state + _ -> + # Preums won! + perfect? = Enum.any?(@perfects, fn(perfect) -> Regex.match?(perfect, text) end) + item = {key, sender.nick, now, perfect?, text} + :dets.insert(state.dets, item) + :dets.sync(state.dets) + state = Map.put(state, channel, %{date => item}) + state + end + else + state + end + end + +end |