summaryrefslogtreecommitdiff
path: root/lib/lsg_irc/preums_plugin.ex
diff options
context:
space:
mode:
authorhref <href@random.sh>2020-03-11 21:18:34 +0100
committerhref <href@random.sh>2020-03-11 21:18:34 +0100
commita28d24470ddeca6196219a1333c1ccac1319efef (patch)
tree4f29e3c8fb6afbb1f99d6b8737f844c95fca54df /lib/lsg_irc/preums_plugin.ex
parentup to 420*100 (diff)
welp
Diffstat (limited to 'lib/lsg_irc/preums_plugin.ex')
-rw-r--r--lib/lsg_irc/preums_plugin.ex108
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