summaryrefslogtreecommitdiff
path: root/lib/lsg_irc
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
parentlink: post_* callbacks; html & pdftitle. (diff)
Commit all the changes that hasn't been committed + updates.
Diffstat (limited to 'lib/lsg_irc')
-rw-r--r--lib/lsg_irc/alcolog_plugin.ex358
-rw-r--r--lib/lsg_irc/alcoolog_announcer_plugin.ex57
-rw-r--r--lib/lsg_irc/base_plugin.ex12
-rw-r--r--lib/lsg_irc/bourosama_plugin.ex7
-rw-r--r--lib/lsg_irc/calc_plugin.ex5
-rw-r--r--lib/lsg_irc/coronavirus_plugin.ex14
-rw-r--r--lib/lsg_irc/correction_plugin.ex8
-rw-r--r--lib/lsg_irc/dice_plugin.ex4
-rw-r--r--lib/lsg_irc/finance_plugin.ex13
-rw-r--r--lib/lsg_irc/kick_roulette_plugin.ex4
-rw-r--r--lib/lsg_irc/last_fm_plugin.ex9
-rw-r--r--lib/lsg_irc/link_plugin.ex11
-rw-r--r--lib/lsg_irc/np_handler.ex4
-rw-r--r--lib/lsg_irc/outline_plugin.ex38
-rw-r--r--lib/lsg_irc/preums_plugin.ex80
-rw-r--r--lib/lsg_irc/quatre_cent_vingt_plugin.ex7
-rw-r--r--lib/lsg_irc/say_plugin.ex9
-rw-r--r--lib/lsg_irc/script_plugin.ex5
-rw-r--r--lib/lsg_irc/seen_plugin.ex7
-rw-r--r--lib/lsg_irc/sms_plugin.ex5
-rw-r--r--lib/lsg_irc/tell_plugin.ex93
-rw-r--r--lib/lsg_irc/txt_plugin.ex16
-rw-r--r--lib/lsg_irc/untappd_plugin.ex2
-rw-r--r--lib/lsg_irc/wikipedia_plugin.ex4
-rw-r--r--lib/lsg_irc/wolfram_alpha_plugin.ex4
-rw-r--r--lib/lsg_irc/youtube_plugin.ex5
26 files changed, 573 insertions, 208 deletions
diff --git a/lib/lsg_irc/alcolog_plugin.ex b/lib/lsg_irc/alcolog_plugin.ex
index 600dc1a..c758117 100644
--- a/lib/lsg_irc/alcolog_plugin.ex
+++ b/lib/lsg_irc/alcolog_plugin.ex
@@ -6,6 +6,7 @@ defmodule LSG.IRC.AlcoologPlugin do
* **!santai `<cl | (calc)>` `<degrés d'alcool> [annotation]`**: enregistre un nouveau verre de `montant` d'une boisson à `degrés d'alcool`.
* **!santai `<cl | (calc)>` `<beer name>`**: enregistre un nouveau verre de `cl` de la bière `beer name`, et checkin sur Untappd.com.
+ * **!moar `[cl]` : enregistre un verre équivalent au dernier !santai.
* **-santai**: annule la dernière entrée d'alcoolisme.
* **.alcoolisme**: état du channel en temps réel.
* **.alcoolisme `<semaine | Xj>`**: points par jour, sur X j.
@@ -139,7 +140,7 @@ defmodule LSG.IRC.AlcoologPlugin do
"attention... l'alcool permet de rendre l'eau potable",
"{{'QUOI ?' | bold}}",
"QUO{{'I' | rrepeat}}?",
- "{{'COMMENT ÇA DE L'EAU ?' | red}}",
+ "{{\"COMMENT ÇA DE L'EAU ?\" | red}}",
"resaisis toi et va ouvrir une bonne teille de rouge...",
"bwais tu veux pas un \"petit\" rhum plutôt ?"
]
@@ -163,16 +164,20 @@ defmodule LSG.IRC.AlcoologPlugin do
end
def init(_) do
- {:ok, _} = Registry.register(IRC.PubSub, "account", [])
- {:ok, _} = Registry.register(IRC.PubSub, "trigger:santai", [])
- {:ok, _} = Registry.register(IRC.PubSub, "trigger:santo", [])
- {:ok, _} = Registry.register(IRC.PubSub, "trigger:santeau", [])
- {:ok, _} = Registry.register(IRC.PubSub, "trigger:alcoolog", [])
- {:ok, _} = Registry.register(IRC.PubSub, "trigger:sobre", [])
- {:ok, _} = Registry.register(IRC.PubSub, "trigger:sobrepour", [])
- {:ok, _} = Registry.register(IRC.PubSub, "trigger:soif", [])
- {:ok, _} = Registry.register(IRC.PubSub, "trigger:alcoolisme", [])
- {:ok, _} = Registry.register(IRC.PubSub, "trigger:alcool", [])
+ regopts = [plugin: __MODULE__]
+ {:ok, _} = Registry.register(IRC.PubSub, "account", regopts)
+ {:ok, _} = Registry.register(IRC.PubSub, "trigger:santai", regopts)
+ {:ok, _} = Registry.register(IRC.PubSub, "trigger:moar", regopts)
+ {:ok, _} = Registry.register(IRC.PubSub, "trigger:again", regopts)
+ {:ok, _} = Registry.register(IRC.PubSub, "trigger:bis", regopts)
+ {:ok, _} = Registry.register(IRC.PubSub, "trigger:santo", regopts)
+ {:ok, _} = Registry.register(IRC.PubSub, "trigger:santeau", regopts)
+ {:ok, _} = Registry.register(IRC.PubSub, "trigger:alcoolog", regopts)
+ {:ok, _} = Registry.register(IRC.PubSub, "trigger:sobre", regopts)
+ {:ok, _} = Registry.register(IRC.PubSub, "trigger:sobrepour", regopts)
+ {:ok, _} = Registry.register(IRC.PubSub, "trigger:soif", regopts)
+ {:ok, _} = Registry.register(IRC.PubSub, "trigger:alcoolisme", regopts)
+ {:ok, _} = Registry.register(IRC.PubSub, "trigger:alcool", regopts)
dets_filename = (LSG.data_path() <> "/" <> "alcoolisme.dets") |> String.to_charlist
{:ok, dets} = :dets.open_file(dets_filename, [{:type,:bag}])
ets = :ets.new(__MODULE__.ETS, [:ordered_set, :named_table, :protected, {:read_concurrency, true}])
@@ -182,8 +187,25 @@ defmodule LSG.IRC.AlcoologPlugin do
traverse_fun = fn(obj, dets) ->
case obj do
+ object = {nick, date, volumes, active, cl, deg, name, comment, meta} ->
+ :ets.insert(ets, {{nick, date}, volumes, active, cl, deg, name, comment, meta})
+ dets
object = {nick, date, volumes, active, name, comment} ->
- :ets.insert(ets, {{nick, date}, volumes, active, name, comment})
+ IO.puts("Migrating object #{inspect object}")
+ {cl, deg} = with \
+ %{"cl" => cl, "deg" => deg} <- Regex.named_captures(~r/^(?<cl>\d+[.]\d+)cl\s+(?<deg>\d+[.]\d+)°$/, name),
+ {cl, _} <- Util.float_paparse(cl),
+ {deg, _} <- Util.float_paparse(deg)
+ do
+ {cl, deg}
+ else
+ _ -> {nil, nil}
+ end
+ new = {nick, date, volumes, active, cl, deg, name, comment, Map.new()}
+ :dets.delete_object(dets, obj)
+ :dets.insert(dets, new)
+
+ :ets.insert(ets, {{nick, date}, volumes, active, cl, deg, name, comment, Map.new()})
dets
_ ->
dets
@@ -206,40 +228,40 @@ defmodule LSG.IRC.AlcoologPlugin do
|> Timex.Timezone.convert("Europe/Paris")
apero = format_duration_from_now(%DateTime{now | hour: 18, minute: 0, second: 0}, false)
day_of_week = Date.day_of_week(now)
- txt = cond do
+ {txt, apero?} = cond do
now.hour >= 0 && now.hour < 6 ->
- ["apéro tardif ? Je dis OUI ! SANTAI !"]
+ {["apéro tardif ? Je dis OUI ! SANTAI !"], true}
now.hour >= 6 && now.hour < 12 ->
if day_of_week >= 6 do
- ["C'est quand même un peu tôt non ? Prochain apéro #{apero}"]
+ {["de l'alcool pour le petit dej ? le week-end, pas de problème !"], true}
else
- ["de l'alcool pour le petit dej ? le week-end, pas de problème !"]
+ {["C'est quand même un peu tôt non ? Prochain apéro #{apero}"], false}
end
now.hour >= 12 && (now.hour < 14) ->
- ["oui! c'est l'apéro de midi! (et apéro #{apero})",
+ {["oui! c'est l'apéro de midi! (et apéro #{apero})",
"tu peux attendre #{apero} ou y aller, il est midi !"
- ]
+ ], true}
now.hour == 17 ->
- [
+ {[
"ÇA APPROCHE !!! Apéro #{apero}",
"BIENTÔT !!! Apéro #{apero}",
"achetez vite les teilles, apéro dans #{apero}!",
"préparez les teilles, apéro dans #{apero}!"
- ]
+ ], false}
now.hour >= 14 && now.hour < 18 ->
weekend = if day_of_week >= 6 do
" ... ou maintenant en fait, c'est le week-end!"
else
""
end
- ["tiens bon! apéro #{apero}#{weekend}",
+ {["tiens bon! apéro #{apero}#{weekend}",
"courage... apéro dans #{apero}#{weekend}",
"pas encore :'( apéro dans #{apero}#{weekend}"
- ]
+ ], false}
true ->
- [
+ {[
"C'EST L'HEURE DE L'APÉRO !!! SANTAIIIIIIIIIIII !!!!"
- ]
+ ], true}
end
txt = txt
@@ -248,6 +270,11 @@ defmodule LSG.IRC.AlcoologPlugin do
m.replyfun.(txt)
+ stats = get_full_statistics(state, m.account.id)
+ if !apero? && stats.active > 0.1 do
+ m.replyfun.("(... ou continue en fait, je suis pas ta mère !)")
+ end
+
{:noreply, state}
end
@@ -344,15 +371,58 @@ defmodule LSG.IRC.AlcoologPlugin do
end
def handle_info({:irc, :trigger, "santai", m = %IRC.Message{trigger: %IRC.Trigger{args: [cl, deg | comment], type: :bang}}}, state) do
- comment = if comment == [] do
- nil
- else
- Enum.join(comment, " ")
+ santai(m, state, cl, deg, comment)
+ {:noreply, state}
+ end
+
+ @moar [
+ "{{message.sender.nick}}: la même donc ?",
+ "{{message.sender.nick}}: et voilà la petite sœur !"
+ ]
+
+ def handle_info({:irc, :trigger, "bis", m = %IRC.Message{trigger: %IRC.Trigger{args: args, type: :bang}}}, state) do
+ handle_info({:irc, :trigger, "moar", m}, state)
+ end
+ def handle_info({:irc, :trigger, "again", m = %IRC.Message{trigger: %IRC.Trigger{args: args, type: :bang}}}, state) do
+ handle_info({:irc, :trigger, "moar", m}, state)
+ end
+
+ def handle_info({:irc, :trigger, "moar", m = %IRC.Message{trigger: %IRC.Trigger{args: args, type: :bang}}}, state) do
+ case get_statistics_for_nick(state, m.account.id) do
+ {_, obj = {_, _date, _points, _active, cl, deg, _name, comment, _meta}} ->
+ cl = case args do
+ [cls] ->
+ case Util.float_paparse(cls) do
+ {cl, _} -> cl
+ _ -> cl
+ end
+ _ -> cl
+ end
+ moar = @moar |> Enum.shuffle() |> Enum.random() |> Tmpl.render(m) |> m.replyfun.()
+ santai(m, state, cl, deg, comment, auto_set: true)
+ {_, obj = {_, date, points, _last_active, type, descr}} ->
+ case Regex.named_captures(~r/^(?<cl>\d+[.]\d+)cl\s+(?<deg>\d+[.]\d+)°$/, type) do
+ nil -> m.replyfun.("suce")
+ u ->
+ moar = @moar |> Enum.shuffle() |> Enum.random() |> Tmpl.render(m) |> m.replyfun.()
+ santai(m, state, u["cl"], u["deg"], descr, auto_set: true)
+ end
+ _ -> nil
+ end
+ {:noreply, state}
+ end
+
+ defp santai(m, state, cl, deg, comment, options \\ []) do
+ comment = cond do
+ comment == [] -> nil
+ is_binary(comment) -> comment
+ comment == nil -> nil
+ true -> Enum.join(comment, " ")
end
{cl, cl_extra} = case {Util.float_paparse(cl), cl} do
{{cl, extra}, _} -> {cl, extra}
- {:error, "("<>_} ->
+ {:error, "("<>_} ->
try do
{:ok, result} = Abacus.eval(cl)
{result, nil}
@@ -363,7 +433,7 @@ defmodule LSG.IRC.AlcoologPlugin do
end
{deg, comment, auto_set, beer_id} = case Util.float_paparse(deg) do
- {deg, _} -> {deg, comment, false, nil}
+ {deg, _} -> {deg, comment, Keyword.get(options, :auto_set, false), nil}
:error ->
beername = if(comment, do: "#{deg} #{comment}", else: deg)
case Untappd.search_beer(beername, limit: 1) do
@@ -374,7 +444,6 @@ defmodule LSG.IRC.AlcoologPlugin do
end
end
-
cond do
cl == nil -> m.replyfun.(cl_extra)
deg == nil -> m.replyfun.(comment)
@@ -383,16 +452,20 @@ defmodule LSG.IRC.AlcoologPlugin do
cl < 0 || deg < 0 -> m.replyfun.(Tmpl.render(Enum.random(Enum.shuffle(Map.get(@bad_drinks, :negative))), m))
true ->
points = Alcool.units(cl, deg)
- now = DateTime.to_unix(DateTime.utc_now(), :millisecond)
+ now = m.at || DateTime.utc_now()
+ |> DateTime.to_unix(:millisecond)
user_meta = get_user_meta(state, m.account.id)
name = "#{cl}cl #{deg}°"
old_stats = get_full_statistics(state, m.account.id)
- :ok = :dets.insert(state.dets, {m.account.id, now, points, if(old_stats, do: old_stats.active, else: 0), name, comment})
- true = :ets.insert(state.ets, {{m.account.id, now}, points, if(old_stats, do: old_stats.active, else: 0),name, comment})
+ meta = %{}
+ meta = Map.put(meta, "timestamp", now)
+ meta = Map.put(meta, "weight", user_meta.weight)
+ meta = Map.put(meta, "sex", user_meta.sex)
+ :ok = :dets.insert(state.dets, {m.account.id, now, points, if(old_stats, do: old_stats.active, else: 0), cl, deg, name, comment, meta})
+ true = :ets.insert(state.ets, {{m.account.id, now}, points, if(old_stats, do: old_stats.active, else: 0),cl, deg, name, comment, meta})
sante = @santai |> Enum.map(fn(s) -> String.trim(String.upcase(s)) end) |> Enum.shuffle() |> Enum.random()
- meta = get_user_meta(state, m.account.id)
- k = if meta.sex, do: 0.7, else: 0.6
- weight = meta.weight
+ k = if user_meta.sex, do: 0.7, else: 0.6
+ weight = user_meta.weight
peak = Float.round((10*points||0.0)/(k*weight), 4)
stats = get_full_statistics(state, m.account.id)
sober_add = if old_stats && Map.get(old_stats || %{}, :sober_in) do
@@ -418,12 +491,24 @@ defmodule LSG.IRC.AlcoologPlugin do
""
end
+ since_str = if stats.since && stats.since_min > 180 do
+ "(depuis: #{stats.since_s}) "
+ else
+ ""
+ end
+
msg = fn(nick, extra) ->
- "#{sante} #{nick}#{extra}#{up} #{format_points(points)} @#{stats.active}g/l [+#{peak} g/l]"
- <> " (15m: #{stats.active15m}, 30m: #{stats.active30m}, 1h: #{stats.active1h}) (sobriété #{at} (dans #{stats.sober_in_s})#{sober_add}) !"
+ "#{sante} #{nick} #{extra}#{up} #{format_points(points)} @#{stats.active}g/l [+#{peak} g/l]"
+ <> " (15m: #{stats.active15m}, 30m: #{stats.active30m}, 1h: #{stats.active1h}) #{since_str}(sobriété #{at} (dans #{stats.sober_in_s})#{sober_add}) !"
<> " (aujourd'hui #{stats.daily_volumes} points - #{stats.daily_gl} g/l)"
end
+ meta = if beer_id do
+ Map.put(meta, "untappd:beer_id", beer_id)
+ else
+ meta
+ end
+
if beer_id do
spawn(fn() ->
case Untappd.maybe_checkin(m.account, beer_id) do
@@ -434,7 +519,7 @@ defmodule LSG.IRC.AlcoologPlugin do
|> Enum.filter(fn(b) -> b end)
|> Enum.intersperse(", ")
|> Enum.join("")
- badge = if(badges > 1, do: "badges", else: "badge")
+ badge = if(length(badges) > 1, do: "badges", else: "badge")
m.replyfun.("\\O/ Unlocked untappd #{badge}: #{badges_s}")
end
:ok
@@ -445,7 +530,15 @@ defmodule LSG.IRC.AlcoologPlugin do
end)
end
- local_extra = if auto_set, do: " #{comment} (#{deg}°)", else: ""
+ local_extra = if auto_set do
+ if comment do
+ " #{comment} (#{cl}cl @ #{deg}°)"
+ else
+ "#{cl}cl @ #{deg}°"
+ end
+ else
+ ""
+ end
m.replyfun.(msg.(m.sender.nick, local_extra))
notify = IRC.Membership.notify_channels(m.account) -- [{m.network,m.channel}]
for {net, chan} <- notify do
@@ -456,6 +549,7 @@ defmodule LSG.IRC.AlcoologPlugin do
end
miss = cond do
+ points <= 0.6 -> :blague
stats.active30m >= 2.9 && stats.active30m < 3 -> :miss3
stats.active30m >= 1.9 && stats.active30m < 2 -> :miss2
stats.active30m >= 0.9 && stats.active30m < 1 -> :miss1
@@ -471,6 +565,9 @@ defmodule LSG.IRC.AlcoologPlugin do
end
miss = case miss do
+ :blague -> [
+ "c'est une blague ?!"
+ ]
:miss025 -> [
"si peu ?"
]
@@ -518,7 +615,6 @@ defmodule LSG.IRC.AlcoologPlugin do
end
end
- {:noreply, state}
end
def handle_info({:irc, :trigger, "santai", m = %IRC.Message{trigger: %IRC.Trigger{args: _, type: :bang}}}, state) do
@@ -549,13 +645,26 @@ defmodule LSG.IRC.AlcoologPlugin do
|> Enum.sort_by(fn({_, status}) -> status.active end, &>/2)
end
+ @spec since() :: %{IRC.Account.id() => DateTime.t()}
+ @doc "Returns the last time the user was at 0 g/l"
+ def since() do
+ :ets.foldr(fn({{acct, timestamp}, _vol, current, _cl, _deg, _name, _comment, _m}, acc) ->
+ if !Map.get(acc, acct) && current == 0 do
+ date = DateTime.from_unix!(timestamp, :millisecond)
+ Map.put(acc, acct, date)
+ else
+ acc
+ end
+ end, %{}, __MODULE__.ETS)
+ end
+
def get_full_statistics(nick) do
get_full_statistics(data_state(), nick)
end
defp get_full_statistics(state, nick) do
case get_statistics_for_nick(state, nick) do
- {count, {_, last_at, last_points, last_active, last_type, last_descr}} ->
+ {count, {_, last_at, last_points, last_active, last_cl, last_deg, last_type, last_descr, _meta}} ->
{active, active_drinks} = current_alcohol_level(state, nick)
{_, m30} = alcohol_level_rising(state, nick)
{rising, m15} = alcohol_level_rising(state, nick, 15)
@@ -601,20 +710,30 @@ defmodule LSG.IRC.AlcoologPlugin do
nil
end
+ since = if active > 0 do
+ since()
+ |> Map.get(nick)
+ end
+
+ since_diff = if since, do: Timex.diff(DateTime.utc_now(), since, :minutes)
+ since_duration = if since, do: Timex.Duration.from_minutes(since_diff)
+ since_s = if since, do: Timex.Format.Duration.Formatter.lformat(since_duration, "fr", :humanized)
+
user_status = list
|> Enum.shuffle()
|> Enum.random()
{total_volumes, total_gl} = user_stats(state, nick)
- %{active: active, last_at: last_at, last_points: last_points, last_type: last_type, last_descr: last_descr,
+ %{active: active, last_at: last_at, last_cl: last_cl, last_deg: last_deg, last_points: last_points, last_type: last_type, last_descr: last_descr,
trend_symbol: trend,
active5m: m5, active15m: m15, active30m: m30, active1h: h1,
rising: rising,
active_drinks: active_drinks,
user_status: user_status,
daily_gl: total_gl, daily_volumes: total_volumes,
- sober_in: minutes_til_sober, sober_in_s: sober_in_s
+ sober_in: minutes_til_sober, sober_in_s: sober_in_s,
+ since: since, since_min: since_diff, since_s: since_s,
}
_ ->
nil
@@ -660,7 +779,7 @@ defmodule LSG.IRC.AlcoologPlugin do
if account do
user = IRC.UserTrack.find_by_account(m.network, account)
nick = if(user, do: user.nick, else: account.name)
- stats = get_full_statistics(state, nick)
+ stats = get_full_statistics(state, account.id)
if stats && stats.sober_in > 0 do
now = DateTime.utc_now()
sober = now |> DateTime.add(round(stats.sober_in*60), :second)
@@ -693,7 +812,12 @@ defmodule LSG.IRC.AlcoologPlugin do
else
status.trend_symbol
end
- "#{nick} #{status.user_status} #{trend_symbol} #{Float.round(status.active, 4)} g/l"
+ since_str = if status.since_min > 180 do
+ "depuis: #{status.since_s} | "
+ else
+ ""
+ end
+ "#{nick} #{status.user_status} #{trend_symbol} #{Float.round(status.active, 4)} g/l [#{since_str}sobre dans: #{status.sober_in_s}]"
end)
|> Enum.intersperse(", ")
|> Enum.join("")
@@ -732,54 +856,43 @@ defmodule LSG.IRC.AlcoologPlugin do
{:noreply, state}
end
- # TODO Fix with user/channel membership
- def handle_info({:irc, :trigger, "alcoolisme", m = %IRC.Message{trigger: %IRC.Trigger{args: ["semaine"], type: :bang}}}, state) do
- aday = 7*((24 * 60)*60)
- now = DateTime.utc_now()
- before = now
- |> DateTime.add(-aday, :second)
- |> DateTime.to_unix(:millisecond)
- over_time_stats(before, 7, m, state)
- end
-
- def handle_info({:irc, :trigger, "alcoolisme", m = %IRC.Message{trigger: %IRC.Trigger{args: ["30j"], type: :bang}}}, state) do
- aday = 31*((24 * 60)*60)
- now = DateTime.utc_now()
- before = now
- |> DateTime.add(-aday, :second)
- |> DateTime.to_unix(:millisecond)
- over_time_stats(before, 30, m, state)
+ def user_over_time(account, count) do
+ user_over_time(data_state(), account, count)
end
- def handle_info({:irc, :trigger, "alcoolisme", m = %IRC.Message{trigger: %IRC.Trigger{args: ["90j"], type: :bang}}}, state) do
- aday = 91*((24 * 60)*60)
- now = DateTime.utc_now()
- before = now
- |> DateTime.add(-aday, :second)
- |> DateTime.to_unix(:millisecond)
- over_time_stats(before, 90, m, state)
- end
-
- def handle_info({:irc, :trigger, "alcoolisme", m = %IRC.Message{trigger: %IRC.Trigger{args: ["180j"], type: :bang}}}, state) do
- aday = 180*((24 * 60)*60)
+ def user_over_time(state, account, count) do
+ delay = count*((24 * 60)*60)
now = DateTime.utc_now()
- before = now
- |> DateTime.add(-aday, :second)
+ before = DateTime.utc_now()
+ |> DateTime.shift_zone!("Europe/Paris", Tzdata.TimeZoneDatabase)
+ |> DateTime.add(-delay, :second, Tzdata.TimeZoneDatabase)
|> DateTime.to_unix(:millisecond)
- over_time_stats(before, 180, m, state)
- end
+ #[
+# {{{:"$1", :"$2"}, :_, :_, :_, :_, :_, :_, :_},
+# [{:andalso, {:==, :"$1", :"$1"}, {:<, :"$2", {:const, 3000}}}], [:lol]}
+ #]
+ match = [{{{:"$1", :"$2"}, :_, :_, :_, :_, :_, :_, :_},
+ [{:andalso, {:>, :"$2", {:const, before}}, {:==, :"$1", {:const, account.id}}}], [:"$_"]}
+ ]
+ :ets.select(state.ets, match)
+ |> Enum.reduce(Map.new, fn({{_, ts}, vol, _, _, _, _, _, _}, acc) ->
+ date = DateTime.from_unix!(ts, :millisecond)
+ |> DateTime.shift_zone!("Europe/Paris", Tzdata.TimeZoneDatabase)
+ date = if date.hour <= 8 do
+ DateTime.add(date, -(60*(60*(date.hour+1))), :second, Tzdata.TimeZoneDatabase)
+ else
+ date
+ end
+ |> DateTime.to_date()
- def handle_info({:irc, :trigger, "alcoolisme", m = %IRC.Message{trigger: %IRC.Trigger{args: ["365j"], type: :bang}}}, state) do
- aday = 365*((24 * 60)*60)
- now = DateTime.utc_now()
- before = now
- |> DateTime.add(-aday, :second)
- |> DateTime.to_unix(:millisecond)
- over_time_stats(before, 365, m, state)
+ Map.put(acc, date, Map.get(acc, date, 0) + vol)
+ end)
end
- defp user_over_time(state, account, count) do
+ def user_over_time_gl(account, count) do
+ state = data_state()
+ meta = get_user_meta(state, account.id)
delay = count*((24 * 60)*60)
now = DateTime.utc_now()
before = DateTime.utc_now()
@@ -787,14 +900,14 @@ defmodule LSG.IRC.AlcoologPlugin do
|> DateTime.add(-delay, :second, Tzdata.TimeZoneDatabase)
|> DateTime.to_unix(:millisecond)
#[
-# {{{:"$1", :"$2"}, :_, :_, :_, :_},
+# {{{:"$1", :"$2"}, :_, :_, :_, :_, :_, :_, :_},
# [{:andalso, {:==, :"$1", :"$1"}, {:<, :"$2", {:const, 3000}}}], [:lol]}
#]
- match = [{{{:"$1", :"$2"}, :_, :_, :_, :_},
+ match = [{{{:"$1", :"$2"}, :_, :_, :_, :_, :_, :_, :_},
[{:andalso, {:>, :"$2", {:const, before}}, {:==, :"$1", {:const, account.id}}}], [:"$_"]}
]
:ets.select(state.ets, match)
- |> Enum.reduce(Map.new, fn({{_, ts}, vol, _, _, _}, acc) ->
+ |> Enum.reduce(Map.new, fn({{_, ts}, vol, _, _, _, _, _, _}, acc) ->
date = DateTime.from_unix!(ts, :millisecond)
|> DateTime.shift_zone!("Europe/Paris", Tzdata.TimeZoneDatabase)
@@ -804,23 +917,28 @@ defmodule LSG.IRC.AlcoologPlugin do
date
end
|> DateTime.to_date()
+ weight = meta.weight
+ k = if meta.sex, do: 0.7, else: 0.6
+ gl = (10*vol)/(k*weight)
- Map.put(acc, date, Map.get(acc, date, 0) + vol)
+ Map.put(acc, date, Map.get(acc, date, 0) + gl)
end)
end
+
+
defp over_time_stats(before, j, m, state) do
- #match = :ets.fun2ms(fn(obj = {{^nick, date}, _, _, _, _}) when date > before -> obj end)
- match = [{{{:_, :"$1"}, :_, :_, :_, :_},
+ #match = :ets.fun2ms(fn(obj = {{^nick, date}, _, _, _, _, _, _, _}) when date > before -> obj end)
+ match = [{{{:_, :"$1"}, :_, :_, :_, :_, :_, :_, :_},
[{:>, :"$1", {:const, before}}], [:"$_"]}
]
# tuple ets: {{nick, date}, volumes, current, nom, commentaire}
members = IRC.Membership.members_or_friends(m.account, m.network, m.channel)
drinks = :ets.select(state.ets, match)
- |> Enum.filter(fn({{account, _}, _, _, _, _}) -> Enum.member?(members, account) end)
- |> Enum.sort_by(fn({{_, ts}, _, _, _, _}) -> ts end, &>/2)
+ |> Enum.filter(fn({{account, _}, _, _, _, _, _, _, _}) -> Enum.member?(members, account) end)
+ |> Enum.sort_by(fn({{_, ts}, _, _, _, _, _, _, _}) -> ts end, &>/2)
- top = Enum.reduce(drinks, %{}, fn({{nick, _}, vol, _, _, _}, acc) ->
+ top = Enum.reduce(drinks, %{}, fn({{nick, _}, vol, _, _, _, _, _, _}, acc) ->
all = Map.get(acc, nick, 0)
Map.put(acc, nick, all + vol)
end)
@@ -872,7 +990,7 @@ defmodule LSG.IRC.AlcoologPlugin do
meta = Map.merge(@default_user_meta, %{sex: h, weight: weight, loss_factor: factor})
put_user_meta(state, m.account.id, meta)
fat = ["t'as grossi...", "bientôt la tonne ?", "t'as encore abusé du fromage ?"]
- thin = ["en route vers l'anorexie ?", "t'as grossi...", "faut manger plus de fromage!"]
+ thin = ["en route vers l'anorexie ?", "t'as vomi...", "t'as grossi...", "faut manger plus de fromage!"]
msg = cond do
old_meta.weight < meta.weight -> Enum.random(Enum.shuffle(fat))
old_meta.weight == meta.weight -> "ok"
@@ -886,7 +1004,7 @@ defmodule LSG.IRC.AlcoologPlugin do
def handle_info({:irc, :trigger, "santai", m = %IRC.Message{trigger: %IRC.Trigger{args: args, type: :minus}}}, state) do
case get_statistics_for_nick(state, m.account.id) do
- {_, obj = {_, date, points, _last_active, type, descr}} ->
+ {_, obj = {_, date, points, _last_active, _cl, _deg, type, descr, _meta}} ->
:dets.delete_object(state.dets, obj)
:ets.delete(state.ets, {m.account.id, date})
m.replyfun.("supprimé: #{m.sender.nick} #{points} #{type} #{descr}")
@@ -903,6 +1021,7 @@ defmodule LSG.IRC.AlcoologPlugin do
end
end
+
def handle_info({:irc, :trigger, "alcoolisme", m = %IRC.Message{trigger: %IRC.Trigger{args: args, type: :bang}}}, state) do
{account, duration} = case args do
[nick | rest] -> {IRC.Account.find_always_by_nick(m.network, m.channel, nick), rest}
@@ -951,6 +1070,7 @@ defmodule LSG.IRC.AlcoologPlugin do
<> (if stats.active > 0 || stats.active15m > 0 || stats.active30m > 0 || stats.active1h > 0, do: ": #{trend_symbol} #{Float.round(stats.active, 4)}g/l ", else: "")
<> (if stats.active30m > 0 || stats.active1h > 0, do: "(15m: #{stats.active15m}, 30m: #{stats.active30m}, 1h: #{stats.active1h}) ", else: "")
<> (if stats.sober_in > 0, do: "— Sobre dans #{stats.sober_in_s} ", else: "")
+ <> (if stats.since && stats.since_min > 180, do: "— Paitai depuis #{stats.since_s} ", else: "")
<> "— Dernier verre: #{present_type(stats.last_type, stats.last_descr)} [#{Float.round(stats.last_points+0.0, 4)}] "
<> "#{format_duration_from_now(stats.last_at)} "
<> (if stats.daily_volumes > 0, do: "— Aujourd'hui: #{stats.daily_volumes} #{stats.daily_gl}g/l", else: "")
@@ -969,7 +1089,7 @@ defmodule LSG.IRC.AlcoologPlugin do
# Account merge
def handle_info({:account_change, old_id, new_id}, state) do
- spec = [{{:"$1", :_, :_, :_, :_, :_}, [{:==, :"$1", {:const, old_id}}], [:"$_"]}]
+ spec = [{{:"$1", :_, :_, :_, :_, :_, :_, :_, :_}, [{:==, :"$1", {:const, old_id}}], [:"$_"]}]
Util.ets_mutate_select_each(:dets, state.dets, spec, fn(table, obj) ->
Logger.debug("alcolog/account_change:: merging #{old_id} -> #{new_id}")
rename_object_owner(table, state.ets, obj, old_id, new_id)
@@ -991,11 +1111,11 @@ defmodule LSG.IRC.AlcoologPlugin do
end
end
- defp rename_object_owner(table, ets, object = {old_id, date, volume, current, name, comment}, old_id, new_id) do
+ defp rename_object_owner(table, ets, object = {old_id, date, volume, current, cl, deg, name, comment, meta}, old_id, new_id) do
:dets.delete_object(table, object)
:ets.delete(ets, {old_id, date})
- :dets.insert(table, {new_id, date, volume, current, name, comment})
- :ets.insert(ets, {{new_id, date}, volume, current, name, comment})
+ :dets.insert(table, {new_id, date, volume, current, cl, deg, name, comment, meta})
+ :ets.insert(ets, {{new_id, date}, volume, current, cl, deg, name, comment, meta})
end
# Account: move from nick to account id
@@ -1005,9 +1125,9 @@ defmodule LSG.IRC.AlcoologPlugin do
mapping = Enum.reduce(accounts, Map.new, fn({:account, _net, _chan, nick, account_id}, acc) ->
Map.put(acc, String.downcase(nick), account_id)
end)
- spec = [{{:"$1", :_, :_, :_, :_, :_}, [], [:"$_"]}]
+ spec = [{{:"$1", :_, :_, :_, :_, :_, :_, :_, :_}, [], [:"$_"]}]
Logger.debug("accounts:: mappings #{inspect mapping}")
- Util.ets_mutate_select_each(:dets, state.dets, spec, fn(table, obj = {nick, _date, _vol, _cur, _name, _comment}) ->
+ Util.ets_mutate_select_each(:dets, state.dets, spec, fn(table, obj = {nick, _date, _vol, _cur, _cl, _deg, _name, _comment, _meta}) ->
#Logger.debug("accounts:: item #{inspect(obj)}")
if new_id = Map.get(mapping, nick) do
Logger.debug("alcolog/accounts:: merging #{nick} -> #{new_id}")
@@ -1019,7 +1139,7 @@ defmodule LSG.IRC.AlcoologPlugin do
def handle_info({:account, _net, _chan, nick, account_id}, state) do
nick = String.downcase(nick)
- spec = [{{:"$1", :_, :_, :_, :_, :_}, [{:==, :"$1", {:const, nick}}], [:"$_"]}]
+ spec = [{{:"$1", :_, :_, :_, :_, :_, :_, :_, :_}, [{:==, :"$1", {:const, nick}}], [:"$_"]}]
Util.ets_mutate_select_each(:dets, state.dets, spec, fn(table, obj) ->
Logger.debug("alcoolog/account:: merging #{nick} -> #{account_id}")
rename_object_owner(table, state.ets, obj, nick, account_id)
@@ -1039,10 +1159,19 @@ defmodule LSG.IRC.AlcoologPlugin do
{:noreply, state}
end
+ def nick_history(account) do
+ spec = [
+ {{{:"$1", :_}, :_, :_, :_, :_, :_, :_, :_},
+ [{:==, :"$1", {:const, account.id}}],
+ [:"$_"]}
+ ]
+ :ets.select(data_state().ets, spec)
+ end
+
defp get_statistics_for_nick(state, account_id) do
qvc = :dets.lookup(state.dets, account_id)
- |> Enum.sort_by(fn({_, ts, _, _, _, _}) -> ts end, &</2)
- count = Enum.reduce(qvc, 0, fn({_nick, _ts, points, _active, _type, _descr}, acc) -> acc + (points||0) end)
+ |> Enum.sort_by(fn({_, ts, _, _, _, _, _, _, _}) -> ts end, &</2)
+ count = Enum.reduce(qvc, 0, fn({_nick, _ts, points, _active, _cl, _deg, _type, _descr, _meta}, acc) -> acc + (points||0) end)
last = List.last(qvc) || nil
{count, last}
end
@@ -1102,6 +1231,10 @@ defmodule LSG.IRC.AlcoologPlugin do
# stop folding when ?
#
+ def user_stats(account) do
+ user_stats(data_state(), account.id)
+ end
+
defp user_stats(state = %{ets: ets}, account_id) do
meta = get_user_meta(state, account_id)
aday = (10 * 60)*60
@@ -1111,7 +1244,7 @@ defmodule LSG.IRC.AlcoologPlugin do
|> DateTime.to_unix(:millisecond)
#match = :ets.fun2ms(fn(obj = {{^nick, date}, _, _, _, _}) when date > before -> obj end)
match = [
- {{{:"$1", :"$2"}, :_, :_, :_, :_},
+ {{{:"$1", :"$2"}, :_, :_, :_, :_, :_, :_, :_},
[
{:>, :"$2", {:const, before}},
{:"=:=", {:const, account_id}, :"$1"}
@@ -1120,7 +1253,7 @@ defmodule LSG.IRC.AlcoologPlugin do
# tuple ets: {{nick, date}, volumes, current, nom, commentaire}
drinks = :ets.select(ets, match)
# {date, single_peak}
- total_volume = Enum.reduce(drinks, 0.0, fn({{_, date}, volume, _, _, _}, acc) ->
+ total_volume = Enum.reduce(drinks, 0.0, fn({{_, date}, volume, _, _, _, _, _, _}, acc) ->
acc + volume
end)
k = if meta.sex, do: 0.7, else: 0.6
@@ -1155,7 +1288,7 @@ defmodule LSG.IRC.AlcoologPlugin do
|> DateTime.to_unix(:millisecond)
#match = :ets.fun2ms(fn(obj = {{^nick, date}, _, _, _, _}) when date > before -> obj end)
match = [
- {{{:"$1", :"$2"}, :_, :_, :_, :_},
+ {{{:"$1", :"$2"}, :_, :_, :_, :_, :_, :_, :_},
[
{:>, :"$2", {:const, before}},
{:"=:=", {:const, account_id}, :"$1"}
@@ -1163,9 +1296,9 @@ defmodule LSG.IRC.AlcoologPlugin do
]
# tuple ets: {{nick, date}, volumes, current, nom, commentaire}
drinks = :ets.select(ets, match)
- |> Enum.sort_by(fn({{_, date}, _, _, _, _}) -> date end, &</2)
+ |> Enum.sort_by(fn({{_, date}, _, _, _, _, _, _, _}) -> date end, &</2)
# {date, single_peak}
- {all, last_drink_at, gl, active_drinks} = Enum.reduce(drinks, {0.0, nil, [], 0}, fn({{_, date}, volume, _, _, _}, {all, last_at, acc, active_drinks}) ->
+ {all, last_drink_at, gl, active_drinks} = Enum.reduce(drinks, {0.0, nil, [], 0}, fn({{_, date}, volume, _, _, _, _, _, _}, {all, last_at, acc, active_drinks}) ->
k = if meta.sex, do: 0.7, else: 0.6
weight = meta.weight
peak = (10*volume)/(k*weight)
@@ -1249,4 +1382,3 @@ defmodule LSG.IRC.AlcoologPlugin do
end
end
-
diff --git a/lib/lsg_irc/alcoolog_announcer_plugin.ex b/lib/lsg_irc/alcoolog_announcer_plugin.ex
index 28973ca..3902d5f 100644
--- a/lib/lsg_irc/alcoolog_announcer_plugin.ex
+++ b/lib/lsg_irc/alcoolog_announcer_plugin.ex
@@ -24,7 +24,26 @@ defmodule LSG.IRC.AlcoologAnnouncerPlugin do
def irc_doc, do: nil
- def start_link(), do: GenServer.start_link(__MODULE__, [])
+ def start_link(), do: GenServer.start_link(__MODULE__, [], name: __MODULE__)
+
+ def log(account) do
+ dets_filename = (LSG.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", [])
@@ -32,21 +51,42 @@ defmodule LSG.IRC.AlcoologAnnouncerPlugin do
Process.send_after(self(), :stats, :timer.seconds(30))
dets_filename = (LSG.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 = LSG.IRC.SettingPlugin.declare("alcoolog.alerts", __MODULE__, true, :boolean)
#:ok = LSG.IRC.SettingPlugin.declare("alcoolog.aperoalert", __MODULE__, true, :boolean)
- {:ok, {stats, now(), dets}}
+ #
+ {: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}) do
+ def handle_info(:stats, {old_stats, old_now, dets, ets}) do
stats = get_stats()
now = now()
@@ -73,10 +113,13 @@ defmodule LSG.IRC.AlcoologAnnouncerPlugin 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, DateTime.utc_now(), new[:active]})
+ :dets.insert(dets, {acct, now, new[:active]})
+ :ets.insert(ets, {{acct, now}, new[:active]})
else
- :dets.insert(dets, {acct, DateTime.utc_now(), 0.0})
+ :dets.insert(dets, {acct, now, 0.0})
+ :ets.insert(ets, {{acct, now}, new[:active]})
end
event = cond do
@@ -206,7 +249,7 @@ defmodule LSG.IRC.AlcoologAnnouncerPlugin do
timer()
#IO.puts "tick stats ok"
- {:noreply, {stats,now,dets}}
+ {:noreply, {stats,now,dets,ets}}
end
def handle_info(_, state) do
diff --git a/lib/lsg_irc/base_plugin.ex b/lib/lsg_irc/base_plugin.ex
index 69b02e8..a95f45c 100644
--- a/lib/lsg_irc/base_plugin.ex
+++ b/lib/lsg_irc/base_plugin.ex
@@ -3,14 +3,15 @@ defmodule LSG.IRC.BasePlugin do
def irc_doc, do: nil
def start_link() do
- GenServer.start_link(__MODULE__, [])
+ GenServer.start_link(__MODULE__, [], name: __MODULE__)
end
def init([]) do
- {:ok, _} = Registry.register(IRC.PubSub, "trigger:version", [])
- {:ok, _} = Registry.register(IRC.PubSub, "trigger:help", [])
- {:ok, _} = Registry.register(IRC.PubSub, "trigger:liquidrender", [])
- {:ok, _} = Registry.register(IRC.PubSub, "trigger:plugin", [])
+ regopts = [plugin: __MODULE__]
+ {:ok, _} = Registry.register(IRC.PubSub, "trigger:version", regopts)
+ {:ok, _} = Registry.register(IRC.PubSub, "trigger:help", regopts)
+ {:ok, _} = Registry.register(IRC.PubSub, "trigger:liquidrender", regopts)
+ {:ok, _} = Registry.register(IRC.PubSub, "trigger:plugin", regopts)
{:ok, nil}
end
@@ -105,4 +106,3 @@ defmodule LSG.IRC.BasePlugin do
end
end
-
diff --git a/lib/lsg_irc/bourosama_plugin.ex b/lib/lsg_irc/bourosama_plugin.ex
index 7dde662..ba63d81 100644
--- a/lib/lsg_irc/bourosama_plugin.ex
+++ b/lib/lsg_irc/bourosama_plugin.ex
@@ -13,14 +13,15 @@ defmodule LSG.IRC.BoursoramaPlugin do
end
def start_link() do
- GenServer.start_link(__MODULE__, [])
+ GenServer.start_link(__MODULE__, [], name: __MODULE__)
end
@cac40_url "https://www.boursorama.com/bourse/actions/palmares/france/?france_filter%5Bmarket%5D=1rPCAC&france_filter%5Bsector%5D=&france_filter%5Bvariation%5D=50002&france_filter%5Bperiod%5D=1&france_filter%5Bfilter%5D="
def init(_) do
- {:ok, _} = Registry.register(IRC.PubSub, "trigger:cac40", [])
- {:ok, _} = Registry.register(IRC.PubSub, "trigger:caca40", [])
+ regopts = [plugin: __MODULE__]
+ {:ok, _} = Registry.register(IRC.PubSub, "trigger:cac40", regopts)
+ {:ok, _} = Registry.register(IRC.PubSub, "trigger:caca40", regopts)
{:ok, nil}
end
diff --git a/lib/lsg_irc/calc_plugin.ex b/lib/lsg_irc/calc_plugin.ex
index b8eee39..ca65675 100644
--- a/lib/lsg_irc/calc_plugin.ex
+++ b/lib/lsg_irc/calc_plugin.ex
@@ -8,11 +8,11 @@ defmodule LSG.IRC.CalcPlugin do
def irc_doc, do: @moduledoc
def start_link() do
- GenServer.start_link(__MODULE__, [])
+ GenServer.start_link(__MODULE__, [], name: __MODULE__)
end
def init(_) do
- {:ok, _} = Registry.register(IRC.PubSub, "trigger:calc", [])
+ {:ok, _} = Registry.register(IRC.PubSub, "trigger:calc", [plugin: __MODULE__])
{:ok, nil}
end
@@ -35,4 +35,3 @@ defmodule LSG.IRC.CalcPlugin do
end
end
-
diff --git a/lib/lsg_irc/coronavirus_plugin.ex b/lib/lsg_irc/coronavirus_plugin.ex
index 8038d14..b9a9e40 100644
--- a/lib/lsg_irc/coronavirus_plugin.ex
+++ b/lib/lsg_irc/coronavirus_plugin.ex
@@ -14,15 +14,22 @@ defmodule LSG.IRC.CoronavirusPlugin do
"""
def irc_doc, do: @moduledoc
- def start_link(), do: GenServer.start_link(__MODULE__, [])
+ def start_link() do
+ GenServer.start_link(__MODULE__, [], name: __MODULE__)
+ end
def init(_) do
- {:ok, _} = Registry.register(IRC.PubSub, "trigger:coronavirus", [])
+ {:ok, _} = Registry.register(IRC.PubSub, "trigger:coronavirus", [plugin: __MODULE__])
+ {:ok, nil, {:continue, :init}}
+ :ignore
+ end
+
+ def handle_continue(:init, _) do
date = Date.add(Date.utc_today(), -2)
{data, _} = fetch_data(%{}, date)
{data, next} = fetch_data(data)
:timer.send_after(next, :update)
- {:ok, %{data: data}}
+ {:noreply, %{data: data}}
end
def handle_info(:update, state) do
@@ -163,4 +170,3 @@ defmodule LSG.IRC.CoronavirusPlugin do
end
end
-
diff --git a/lib/lsg_irc/correction_plugin.ex b/lib/lsg_irc/correction_plugin.ex
index e7b2577..f370cf8 100644
--- a/lib/lsg_irc/correction_plugin.ex
+++ b/lib/lsg_irc/correction_plugin.ex
@@ -7,12 +7,12 @@ defmodule LSG.IRC.CorrectionPlugin do
def irc_doc, do: @moduledoc
def start_link() do
- GenServer.start_link(__MODULE__, [])
+ GenServer.start_link(__MODULE__, [], name: __MODULE__)
end
def init(_) do
- {:ok, _} = Registry.register(IRC.PubSub, "message", [])
- {:ok, _} = Registry.register(IRC.PubSub, "triggers", [])
+ {:ok, _} = Registry.register(IRC.PubSub, "message", [plugin: __MODULE__])
+ {:ok, _} = Registry.register(IRC.PubSub, "triggers", [plugin: __MODULE__])
{:ok, %{}}
end
@@ -25,7 +25,7 @@ defmodule LSG.IRC.CorrectionPlugin do
{:noreply, correction(m, state)}
end
- defp correction(m, state) do
+ def correction(m, state) do
history = Map.get(state, key(m), [])
if String.starts_with?(m.text, "s/") do
case String.split(m.text, "/") do
diff --git a/lib/lsg_irc/dice_plugin.ex b/lib/lsg_irc/dice_plugin.ex
index a507b8e..eafd88a 100644
--- a/lib/lsg_irc/dice_plugin.ex
+++ b/lib/lsg_irc/dice_plugin.ex
@@ -17,11 +17,11 @@ defmodule LSG.IRC.DicePlugin do
def irc_doc, do: @moduledoc
def start_link() do
- GenServer.start_link(__MODULE__, [])
+ GenServer.start_link(__MODULE__, [], name: __MODULE__)
end
def init([]) do
- {:ok, _} = Registry.register(IRC.PubSub, "trigger:dice", [])
+ {:ok, _} = Registry.register(IRC.PubSub, "trigger:dice", [plugin: __MODULE__])
{:ok, %__MODULE__{}}
end
diff --git a/lib/lsg_irc/finance_plugin.ex b/lib/lsg_irc/finance_plugin.ex
index 7266a5e..51ec3f6 100644
--- a/lib/lsg_irc/finance_plugin.ex
+++ b/lib/lsg_irc/finance_plugin.ex
@@ -23,8 +23,8 @@ defmodule LSG.IRC.FinancePlugin do
"""
- @currency_list "https://www.alphavantage.co/physical_currency_list/"
- @crypto_list "https://www.alphavantage.co/digital_currency_list/"
+ @currency_list "http://www.alphavantage.co/physical_currency_list/"
+ @crypto_list "http://www.alphavantage.co/digital_currency_list/"
HTTPoison.start()
load_currency = fn(url) ->
@@ -47,13 +47,14 @@ defmodule LSG.IRC.FinancePlugin do
def irc_doc, do: @moduledoc
def start_link() do
- GenServer.start_link(__MODULE__, [])
+ GenServer.start_link(__MODULE__, [], name: __MODULE__)
end
def init([]) do
- {:ok, _} = Registry.register(IRC.PubSub, "trigger:forex", [])
- {:ok, _} = Registry.register(IRC.PubSub, "trigger:currency", [])
- {:ok, _} = Registry.register(IRC.PubSub, "trigger:stocks", [])
+ regopts = [plugin: __MODULE__]
+ {:ok, _} = Registry.register(IRC.PubSub, "trigger:forex", regopts)
+ {:ok, _} = Registry.register(IRC.PubSub, "trigger:currency", regopts)
+ {:ok, _} = Registry.register(IRC.PubSub, "trigger:stocks", regopts)
{:ok, nil}
end
diff --git a/lib/lsg_irc/kick_roulette_plugin.ex b/lib/lsg_irc/kick_roulette_plugin.ex
index 83efcb0..f810a74 100644
--- a/lib/lsg_irc/kick_roulette_plugin.ex
+++ b/lib/lsg_irc/kick_roulette_plugin.ex
@@ -7,11 +7,11 @@ defmodule LSG.IRC.KickRoulettePlugin do
def irc_doc, do: @moduledoc
def start_link() do
- GenServer.start_link(__MODULE__, [])
+ GenServer.start_link(__MODULE__, [], name: __MODULE__)
end
def init([]) do
- {:ok, _} = Registry.register(IRC.PubSub, "trigger:kick", [])
+ {:ok, _} = Registry.register(IRC.PubSub, "trigger:kick", [plugin: __MODULE__])
{:ok, nil}
end
diff --git a/lib/lsg_irc/last_fm_plugin.ex b/lib/lsg_irc/last_fm_plugin.ex
index 067a44e..8497f2d 100644
--- a/lib/lsg_irc/last_fm_plugin.ex
+++ b/lib/lsg_irc/last_fm_plugin.ex
@@ -14,13 +14,14 @@ defmodule LSG.IRC.LastFmPlugin do
def irc_doc, do: @moduledoc
def start_link() do
- GenServer.start_link(__MODULE__, [])
+ GenServer.start_link(__MODULE__, [], name: __MODULE__)
end
def init([]) do
- {:ok, _} = Registry.register(IRC.PubSub, "account", [])
- {:ok, _} = Registry.register(IRC.PubSub, "trigger:lastfm", [])
- {:ok, _} = Registry.register(IRC.PubSub, "trigger:lastfmall", [])
+ regopts = [type: __MODULE__]
+ {:ok, _} = Registry.register(IRC.PubSub, "account", regopts)
+ {:ok, _} = Registry.register(IRC.PubSub, "trigger:lastfm", regopts)
+ {:ok, _} = Registry.register(IRC.PubSub, "trigger:lastfmall", regopts)
dets_filename = (LSG.data_path() <> "/" <> "lastfm.dets") |> String.to_charlist
{:ok, dets} = :dets.open_file(dets_filename, [])
{:ok, %__MODULE__{dets: dets}}
diff --git a/lib/lsg_irc/link_plugin.ex b/lib/lsg_irc/link_plugin.ex
index ea6df0c..ced80b2 100644
--- a/lib/lsg_irc/link_plugin.ex
+++ b/lib/lsg_irc/link_plugin.ex
@@ -52,8 +52,8 @@ defmodule LSG.IRC.LinkPlugin do
defstruct [:client]
def init([]) do
- {:ok, _} = Registry.register(IRC.PubSub, "message", [])
- #{:ok, _} = Registry.register(IRC.PubSub, "message:telegram", [])
+ {:ok, _} = Registry.register(IRC.PubSub, "message", [plugin: __MODULE__])
+ #{:ok, _} = Registry.register(IRC.PubSub, "message:telegram", [plugin: __MODULE__])
Logger.info("Link handler started")
{:ok, %__MODULE__{}}
end
@@ -159,7 +159,7 @@ defmodule LSG.IRC.LinkPlugin do
{length, _} = Integer.parse(length)
handlers = Keyword.get(Application.get_env(:lsg, __MODULE__, [handlers: []]), :handlers)
- handler = Enum.reduce_while(handlers, nil, fn({module, opts}, acc) ->
+ handler = Enum.reduce_while(handlers, false, fn({module, opts}, acc) ->
module = Module.concat([module])
try do
case module.post_match(url, content_type, headers, opts) do
@@ -225,8 +225,9 @@ defmodule LSG.IRC.LinkPlugin do
end
end
- defp get_body(_, len, client, _, _acc) do
+ defp get_body(_, len, client, h, _acc) do
:hackney.close(client)
+ IO.inspect(h)
{:ok, "Error: file over 30"}
end
@@ -243,6 +244,8 @@ defmodule LSG.IRC.LinkPlugin do
{:error, status, _headers} ->
text = Plug.Conn.Status.reason_phrase(status)
{:ok, acc, "Error: HTTP #{text} (#{status})"}
+ {:error, {:tls_alert, {:handshake_failure, err}}} ->
+ {:ok, acc, "TLS Error: #{to_string(err)}"}
{:error, reason} ->
{:ok, acc, "Error: #{to_string(reason)}"}
end
diff --git a/lib/lsg_irc/np_handler.ex b/lib/lsg_irc/np_handler.ex
index 5f724d4..1a52c75 100644
--- a/lib/lsg_irc/np_handler.ex
+++ b/lib/lsg_irc/np_handler.ex
@@ -8,12 +8,12 @@ defmodule LSG.IRC.NpHandler do
def short_irc_doc, do: "!np (en ce moment sur 115ans)"
def irc_doc, do: @moduledoc
def start_link(client) do
- GenServer.start_link(__MODULE__, [client])
+ GenServer.start_link(__MODULE__, [client], name: __MODULE__)
end
def init([client]) do
ExIRC.Client.add_handler client, self
- {:ok, _} = Registry.register(LSG.BroadcastRegistry, "icecast", [])
+ {:ok, _} = Registry.register(LSG.BroadcastRegistry, "icecast", [plugin: __MODULE__])
{:ok, client}
end
diff --git a/lib/lsg_irc/outline_plugin.ex b/lib/lsg_irc/outline_plugin.ex
index 7bfaac1..471448b 100644
--- a/lib/lsg_irc/outline_plugin.ex
+++ b/lib/lsg_irc/outline_plugin.ex
@@ -12,14 +12,15 @@ defmodule LSG.IRC.OutlinePlugin do
require Logger
def start_link() do
- GenServer.start_link(__MODULE__, [])
+ GenServer.start_link(__MODULE__, [], name: __MODULE__)
end
defstruct [:file, :hosts]
def init([]) do
- {:ok, _} = Registry.register(IRC.PubSub, "trigger:outline", [])
- {:ok, _} = Registry.register(IRC.PubSub, "message", [])
+ regopts = [plugin: __MODULE__]
+ {:ok, _} = Registry.register(IRC.PubSub, "trigger:outline", regopts)
+ {:ok, _} = Registry.register(IRC.PubSub, "message", regopts)
file = Path.join(LSG.data_path, "/outline.txt")
hosts = case File.read(file) do
{:error, :enoent} ->
@@ -51,7 +52,8 @@ defmodule LSG.IRC.OutlinePlugin do
uri = URI.parse(word)
if uri.scheme && uri.host do
if Enum.any?(state.hosts, fn(host) -> String.ends_with?(uri.host, host) end) do
- line = "-> https://outline.com/#{word}"
+ outline_url = outline(word)
+ line = "-> #{outline(word)}"
message.replyfun.(line)
end
end
@@ -69,4 +71,32 @@ defmodule LSG.IRC.OutlinePlugin do
File.write(file, string)
end
+ def outline(url) do
+ unexpanded = "https://outline.com/#{url}"
+ headers = [
+ {"User-Agent", "Mozilla/5.0 (X11; Linux x86_64; rv:77.0) Gecko/20100101 Firefox/77.0"},
+ {"Accept", "*/*"},
+ {"Accept-Language", "en-US,en;q=0.5"},
+ {"Origin", "https://outline.com"},
+ {"DNT", "1"},
+ {"Referer", unexpanded},
+ {"Pragma", "no-cache"},
+ {"Cache-Control", "no-cache"}
+ ]
+ params = %{"source_url" => url}
+ case HTTPoison.get("https://api.outline.com/v3/parse_article", headers, params: params) do
+ {:ok, %HTTPoison.Response{status_code: 200, body: json}} ->
+ body = Poison.decode!(json)
+ if Map.get(body, "success") do
+ code = get_in(body, ["data", "short_code"])
+ "https://outline.com/#{code}"
+ else
+ unexpanded
+ end
+ error ->
+ Logger.info("outline.com error: #{inspect error}")
+ unexpanded
+ end
+ end
+
end
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
diff --git a/lib/lsg_irc/quatre_cent_vingt_plugin.ex b/lib/lsg_irc/quatre_cent_vingt_plugin.ex
index db85d49..fff7e4f 100644
--- a/lib/lsg_irc/quatre_cent_vingt_plugin.ex
+++ b/lib/lsg_irc/quatre_cent_vingt_plugin.ex
@@ -30,16 +30,17 @@ defmodule LSG.IRC.QuatreCentVingtPlugin do
def irc_doc, do: @moduledoc
- def start_link, do: GenServer.start_link(__MODULE__, [])
+ def start_link, do: GenServer.start_link(__MODULE__, [], name: __MODULE__)
def init(_) do
for coeff <- @coeffs do
- {:ok, _} = Registry.register(IRC.PubSub, "trigger:#{420*coeff}", [])
+ {:ok, _} = Registry.register(IRC.PubSub, "trigger:#{420*coeff}", [plugin: __MODULE__])
end
- {:ok, _} = Registry.register(IRC.PubSub, "account", [])
+ {:ok, _} = Registry.register(IRC.PubSub, "account", [plugin: __MODULE__])
dets_filename = (LSG.data_path() <> "/420.dets") |> String.to_charlist
{:ok, dets} = :dets.open_file(dets_filename, [{:type,:bag},{:repair,:force}])
{:ok, dets}
+ :ignore
end
for coeff <- @coeffs do
diff --git a/lib/lsg_irc/say_plugin.ex b/lib/lsg_irc/say_plugin.ex
index 6a4f547..690d0a6 100644
--- a/lib/lsg_irc/say_plugin.ex
+++ b/lib/lsg_irc/say_plugin.ex
@@ -14,13 +14,14 @@ defmodule LSG.IRC.SayPlugin do
end
def start_link() do
- GenServer.start_link(__MODULE__, [])
+ GenServer.start_link(__MODULE__, [], name: __MODULE__)
end
def init([]) do
- {:ok, _} = Registry.register(IRC.PubSub, "trigger:say", [])
- {:ok, _} = Registry.register(IRC.PubSub, "trigger:asay", [])
- {:ok, _} = Registry.register(IRC.PubSub, "message:private", [])
+ regopts = [type: __MODULE__]
+ {:ok, _} = Registry.register(IRC.PubSub, "trigger:say", regopts)
+ {:ok, _} = Registry.register(IRC.PubSub, "trigger:asay", regopts)
+ {:ok, _} = Registry.register(IRC.PubSub, "message:private", regopts)
{:ok, nil}
end
diff --git a/lib/lsg_irc/script_plugin.ex b/lib/lsg_irc/script_plugin.ex
index 28ae2a7..bae6f3f 100644
--- a/lib/lsg_irc/script_plugin.ex
+++ b/lib/lsg_irc/script_plugin.ex
@@ -19,11 +19,11 @@ defmodule LSG.IRC.ScriptPlugin do
def irc_doc, do: @ircdoc
def start_link() do
- GenServer.start_link(__MODULE__, [])
+ GenServer.start_link(__MODULE__, [], name: __MODULE__)
end
def init([]) do
- {:ok, _} = Registry.register(IRC.PubSub, "trigger:script", [])
+ {:ok, _} = Registry.register(IRC.PubSub, "trigger:script", [plugin: __MODULE__])
dets_filename = (LSG.data_path() <> "/" <> "scripts.dets") |> String.to_charlist
{:ok, dets} = :dets.open_file(dets_filename, [])
{:ok, %{dets: dets}}
@@ -40,4 +40,3 @@ defmodule LSG.IRC.ScriptPlugin do
end
end
-
diff --git a/lib/lsg_irc/seen_plugin.ex b/lib/lsg_irc/seen_plugin.ex
index 8b2178f..f1a5473 100644
--- a/lib/lsg_irc/seen_plugin.ex
+++ b/lib/lsg_irc/seen_plugin.ex
@@ -7,12 +7,13 @@ defmodule LSG.IRC.SeenPlugin do
def irc_doc, do: @moduledoc
def start_link() do
- GenServer.start_link(__MODULE__, [])
+ GenServer.start_link(__MODULE__, [], name: __MODULE__)
end
def init([]) do
- {:ok, _} = Registry.register(IRC.PubSub, "triggers", [])
- {:ok, _} = Registry.register(IRC.PubSub, "message", [])
+ regopts = [plugin: __MODULE__]
+ {:ok, _} = Registry.register(IRC.PubSub, "triggers", regopts)
+ {:ok, _} = Registry.register(IRC.PubSub, "message", regopts)
dets_filename = (LSG.data_path() <> "/seen.dets") |> String.to_charlist()
{:ok, dets} = :dets.open_file(dets_filename, [])
{:ok, %{dets: dets}}
diff --git a/lib/lsg_irc/sms_plugin.ex b/lib/lsg_irc/sms_plugin.ex
index 60554fb..a37fb4e 100644
--- a/lib/lsg_irc/sms_plugin.ex
+++ b/lib/lsg_irc/sms_plugin.ex
@@ -54,7 +54,7 @@ defmodule LSG.IRC.SmsPlugin do
end
def start_link() do
- GenServer.start_link(__MODULE__, [])
+ GenServer.start_link(__MODULE__, [], name: __MODULE__)
end
def path() do
@@ -88,9 +88,10 @@ defmodule LSG.IRC.SmsPlugin do
end
def init([]) do
- {:ok, _} = Registry.register(IRC.PubSub, "trigger:sms", [])
+ {:ok, _} = Registry.register(IRC.PubSub, "trigger:sms", [plugin: __MODULE__])
:ok = register_ovh_callback()
{:ok, %{}}
+ :ignore
end
def handle_info({:irc, :trigger, "sms", m = %IRC.Message{trigger: %IRC.Trigger{type: :bang, args: [nick | text]}}}, state) do
diff --git a/lib/lsg_irc/tell_plugin.ex b/lib/lsg_irc/tell_plugin.ex
new file mode 100644
index 0000000..a683b43
--- /dev/null
+++ b/lib/lsg_irc/tell_plugin.ex
@@ -0,0 +1,93 @@
+defmodule LSG.IRC.TellPlugin do
+ use GenServer
+
+ @moduledoc """
+ # Tell
+
+ * **!tell `<nick>` `<message>`**: tell `message` to `nick` when they reconnect.
+ """
+
+ def irc_doc, do: @moduledoc
+ def start_link() do
+ GenServer.start_link(__MODULE__, [], name: __MODULE__)
+ end
+
+ def dets do
+ (LSG.data_path() <> "/tell.dets") |> String.to_charlist()
+ end
+
+ def init([]) do
+ regopts = [plugin: __MODULE__]
+ {:ok, _} = Registry.register(IRC.PubSub, "account", regopts)
+ {:ok, _} = Registry.register(IRC.PubSub, "trigger:tell", regopts)
+ {:ok, dets} = :dets.open_file(dets(), [type: :bag])
+ {:ok, %{dets: dets}}
+ end
+
+ def handle_info({:irc, :trigger, "tell", m = %IRC.Message{trigger: %IRC.Trigger{type: :bang, args: [nick_target | message]}}}, state) do
+ target = IRC.Account.find_always_by_nick(m.network, m.channel, nick_target)
+ message = Enum.join(message, " ")
+ with \
+ {:target, %IRC.Account{} = target} <- {:target, target},
+ {:same, false} <- {:same, target.id == m.account.id},
+ target_user = IRC.UserTrack.find_by_account(m.network, target),
+ target_nick = if(target_user, do: target_user.nick, else: target.name),
+ present? = if(target_user, do: Map.has_key?(target_user.last_active, m.channel)),
+ {:absent, true, _} <- {:absent, !present?, target_nick},
+ {:message, message} <- {:message, message}
+ do
+ obj = { {m.network, m.channel, target.id}, m.account.id, message, NaiveDateTime.utc_now()}
+ :dets.insert(state.dets, obj)
+ m.replyfun.("will tell to #{target_nick}")
+ else
+ {:same, _} -> m.replyfun.("are you so stupid that you need a bot to tell yourself things ?")
+ {:target, _} -> m.replyfun.("#{nick_target} unknown")
+ {:absent, _, nick} -> m.replyfun.("#{nick} is here, tell yourself!")
+ {:message, _} -> m.replyfun.("can't tell without a message")
+ end
+ {:noreply, state}
+ end
+
+ def handle_info({:account, network, channel, nick, account_id}, state) do
+ messages = :dets.lookup(state.dets, {network, channel, account_id})
+ if messages != [] do
+ strs = Enum.map(messages, fn({_, from, message, at}) ->
+ account = IRC.Account.get(from)
+ user = IRC.UserTrack.find_by_account(network, account)
+ fromnick = if user, do: user.nick, else: account.name
+ "#{nick}: <#{fromnick}> #{message}"
+ end)
+ Enum.each(strs, fn(s) -> IRC.Connection.broadcast_message(network, channel, s) end)
+ :dets.delete(state.dets, {network, channel, account_id})
+ end
+ {:noreply, state}
+ end
+
+ def handle_info({:account_change, old_id, new_id}, state) do
+ #:ets.fun2ms(fn({ {_net, _chan, target_id}, from_id, _, _} = obj) when (target_id == old_id) or (from_id == old_id) -> obj end)
+ spec = [{{{:"$1", :"$2", :"$3"}, :"$4", :_, :_}, [{:orelse, {:==, :"$3", {:const, old_id}}, {:==, :"$4", {:const, old_id}}}], [:"$_"]}]
+ Util.Util.ets_mutate_select_each(:dets, state.dets, spec, fn(table, obj) ->
+ case obj do
+ { {net, chan, ^old_id}, from_id, message, at } = obj ->
+ :dets.delete(obj)
+ :dets.insert(table, {{net, chan, new_id}, from_id, message, at})
+ {key, ^old_id, message, at} = obj ->
+ :dets.delete(table, obj)
+ :dets.insert(table, {key, new_id, message, at})
+ _ -> :ok
+ end
+ end)
+ {:noreply, state}
+ end
+
+
+ def handle_info(info, state) do
+ {:noreply, state}
+ end
+
+ def terminate(_, state) do
+ :dets.close(state.dets)
+ :ok
+ end
+
+end
diff --git a/lib/lsg_irc/txt_plugin.ex b/lib/lsg_irc/txt_plugin.ex
index f8c3a29..0f97bcc 100644
--- a/lib/lsg_irc/txt_plugin.ex
+++ b/lib/lsg_irc/txt_plugin.ex
@@ -33,7 +33,7 @@ defmodule LSG.IRC.TxtPlugin do
def irc_doc, do: @moduledoc
def start_link() do
- GenServer.start_link(__MODULE__, [])
+ GenServer.start_link(__MODULE__, [], name: __MODULE__)
end
defstruct triggers: %{}, rw: true, locks: nil, markov_handler: nil, markov: nil
@@ -43,7 +43,7 @@ defmodule LSG.IRC.TxtPlugin do
{:ok, locks} = :dets.open_file(dets_locks_filename, [])
markov_handler = Keyword.get(Application.get_env(:lsg, __MODULE__, []), :markov_handler, LSG.IRC.TxtPlugin.Markov.Native)
{:ok, markov} = markov_handler.start_link()
- {:ok, _} = Registry.register(IRC.PubSub, "triggers", [])
+ {:ok, _} = Registry.register(IRC.PubSub, "triggers", [plugin: __MODULE__])
{:ok, %__MODULE__{locks: locks, markov_handler: markov_handler, markov: markov, triggers: load()}}
end
@@ -147,13 +147,21 @@ defmodule LSG.IRC.TxtPlugin do
def handle_info({:irc, :trigger, "txt", msg = %{trigger: %{type: :bang, args: args}}}, state) do
grep = Enum.join(args, " ")
- result = with_stateful_results(msg, {:bang,"txt",grep}, fn() ->
+ |> String.downcase
+ |> :unicode.characters_to_nfd_binary()
+
+ result = with_stateful_results(msg, {:bang,"txt",msg.network,msg.channel,grep}, fn() ->
Enum.reduce(state.triggers, [], fn({trigger, data}, acc) ->
Enum.reduce(data, acc, fn({l, _}, acc) ->
[{trigger, l} | acc]
end)
end)
- |> Enum.filter(fn({_, line}) -> String.contains?(String.downcase(line), String.downcase(grep)) end)
+ |> Enum.filter(fn({_, line}) ->
+ line
+ |> String.downcase()
+ |> :unicode.characters_to_nfd_binary()
+ |> String.contains?(grep)
+ end)
|> Enum.shuffle()
end)
diff --git a/lib/lsg_irc/untappd_plugin.ex b/lib/lsg_irc/untappd_plugin.ex
index 02b22e3..69e4be6 100644
--- a/lib/lsg_irc/untappd_plugin.ex
+++ b/lib/lsg_irc/untappd_plugin.ex
@@ -18,7 +18,7 @@ defmodule LSG.IRC.UntappdPlugin do
end
def init(_) do
- {:ok, _} = Registry.register(IRC.PubSub, "trigger:beer", [])
+ {:ok, _} = Registry.register(IRC.PubSub, "trigger:beer", [plugin: __MODULE__])
{:ok, %{}}
end
diff --git a/lib/lsg_irc/wikipedia_plugin.ex b/lib/lsg_irc/wikipedia_plugin.ex
index 16e7c42..618eb66 100644
--- a/lib/lsg_irc/wikipedia_plugin.ex
+++ b/lib/lsg_irc/wikipedia_plugin.ex
@@ -11,11 +11,11 @@ defmodule LSG.IRC.WikipediaPlugin do
def irc_doc, do: @moduledoc
def start_link() do
- GenServer.start_link(__MODULE__, [])
+ GenServer.start_link(__MODULE__, [], name: __MODULE__)
end
def init(_) do
- {:ok, _} = Registry.register(IRC.PubSub, "trigger:wp", [])
+ {:ok, _} = Registry.register(IRC.PubSub, "trigger:wp", [plugin: __MODULE__])
{:ok, nil}
end
diff --git a/lib/lsg_irc/wolfram_alpha_plugin.ex b/lib/lsg_irc/wolfram_alpha_plugin.ex
index b34db56..c07f659 100644
--- a/lib/lsg_irc/wolfram_alpha_plugin.ex
+++ b/lib/lsg_irc/wolfram_alpha_plugin.ex
@@ -11,11 +11,11 @@ defmodule LSG.IRC.WolframAlphaPlugin do
def irc_doc, do: @moduledoc
def start_link() do
- GenServer.start_link(__MODULE__, [])
+ GenServer.start_link(__MODULE__, [], name: __MODULE__)
end
def init(_) do
- {:ok, _} = Registry.register(IRC.PubSub, "trigger:wa", [])
+ {:ok, _} = Registry.register(IRC.PubSub, "trigger:wa", [plugin: __MODULE__])
{:ok, nil}
end
diff --git a/lib/lsg_irc/youtube_plugin.ex b/lib/lsg_irc/youtube_plugin.ex
index e0781f0..49fc31c 100644
--- a/lib/lsg_irc/youtube_plugin.ex
+++ b/lib/lsg_irc/youtube_plugin.ex
@@ -12,12 +12,11 @@ defmodule LSG.IRC.YouTubePlugin do
def irc_doc, do: @moduledoc
def start_link() do
- GenServer.start_link(__MODULE__, [])
+ GenServer.start_link(__MODULE__, [], name: __MODULE__)
end
def init([]) do
- {:ok, _} = Registry.register(IRC.PubSub, "trigger:yt", [])
- {:ok, _} = Registry.register(IRC.PubSub, "trigger:youtube", [])
+ for t <- ["trigger:yt", "trigger:youtube"], do: {:ok, _} = Registry.register(IRC.PubSub, t, [plugin: __MODULE__])
{:ok, %__MODULE__{}}
end