summaryrefslogtreecommitdiff
path: root/lib/lsg_irc
diff options
context:
space:
mode:
Diffstat (limited to 'lib/lsg_irc')
-rw-r--r--lib/lsg_irc/admin_handler.ex15
-rw-r--r--lib/lsg_irc/base_handler.ex2
-rw-r--r--lib/lsg_irc/calc_handler.ex38
-rw-r--r--lib/lsg_irc/calc_plugin.ex38
-rw-r--r--lib/lsg_irc/connection_handler.ex37
-rw-r--r--lib/lsg_irc/dice_handler.ex1
-rw-r--r--lib/lsg_irc/handler.ex24
-rw-r--r--lib/lsg_irc/kick_roulette_handler.ex2
-rw-r--r--lib/lsg_irc/last_fm_handler.ex8
-rw-r--r--lib/lsg_irc/login_handler.ex25
-rw-r--r--lib/lsg_irc/quatre_cent_vingt_plugin.ex105
-rw-r--r--lib/lsg_irc/txt_handler.ex14
-rw-r--r--lib/lsg_irc/user_track.ex150
-rw-r--r--lib/lsg_irc/user_track_handler.ex93
-rw-r--r--lib/lsg_irc/wikipedia_plugin.ex90
-rw-r--r--lib/lsg_irc/youtube_handler.ex2
16 files changed, 267 insertions, 377 deletions
diff --git a/lib/lsg_irc/admin_handler.ex b/lib/lsg_irc/admin_handler.ex
index 27d35c3..fab4dbc 100644
--- a/lib/lsg_irc/admin_handler.ex
+++ b/lib/lsg_irc/admin_handler.ex
@@ -14,18 +14,27 @@ defmodule LSG.IRC.AdminHandler do
def init([client]) do
ExIRC.Client.add_handler client, self
+ :ok = IRC.register("op")
{:ok, client}
end
- def handle_info({:received, "!op", sender, chan}, client) do
- if LSG.IRC.admin?(sender) do
+ def handle_info({:irc, :trigger, "op", m = %IRC.Message{trigger: %IRC.Trigger{type: :bang}, sender: sender}}, client) do
+ if IRC.admin?(sender) do
+ m.replyfun.({:mode, "+o"})
+ else
+ m.replyfun.({:kick, "non"})
+ end
+ {:noreply, client}
+ end
+
+ def handle_info({:joined, chan, sender}, client) do
+ if IRC.admin?(sender) do
ExIRC.Client.mode(client, chan, "+o", sender.nick)
end
{:noreply, client}
end
def handle_info(msg, client) do
- IO.inspect(msg)
{:noreply, client}
end
diff --git a/lib/lsg_irc/base_handler.ex b/lib/lsg_irc/base_handler.ex
index 9145936..35b2ade 100644
--- a/lib/lsg_irc/base_handler.ex
+++ b/lib/lsg_irc/base_handler.ex
@@ -1,7 +1,5 @@
defmodule LSG.IRC.BaseHandler do
- use LSG.IRC.Handler
-
def irc_doc, do: nil
def start_link(client) do
diff --git a/lib/lsg_irc/calc_handler.ex b/lib/lsg_irc/calc_handler.ex
deleted file mode 100644
index 0f74ac9..0000000
--- a/lib/lsg_irc/calc_handler.ex
+++ /dev/null
@@ -1,38 +0,0 @@
-defmodule LSG.IRC.CalcHandler do
- @moduledoc """
- # calc
-
- * **!calc `<expression>`**: évalue l'expression mathématique `<expression>`.
- """
-
- def irc_doc, do: @moduledoc
-
- def start_link(client) do
- GenServer.start_link(__MODULE__, [client])
- end
-
- def init([client]) do
- ExIRC.Client.add_handler client, self
- {:ok, client}
- end
-
- def handle_info({:received, "!calc "<>expr, %ExIRC.SenderInfo{nick: nick}, chan}, client) do
- IO.inspect "HAZ CALC " <>inspect(expr)
- result = try do
- case Abacus.eval(expr) do
- {:ok, result} -> result
- error -> inspect(error)
- end
- rescue
- error -> "#{error.message}"
- end
- ExIRC.Client.msg(client, :privmsg, chan, "#{nick}: #{expr} = #{result}")
- {:noreply, client}
- end
-
- def handle_info(msg, client) do
- {:noreply, client}
- end
-
-end
-
diff --git a/lib/lsg_irc/calc_plugin.ex b/lib/lsg_irc/calc_plugin.ex
new file mode 100644
index 0000000..6e4e30c
--- /dev/null
+++ b/lib/lsg_irc/calc_plugin.ex
@@ -0,0 +1,38 @@
+defmodule LSG.IRC.CalcPlugin do
+ @moduledoc """
+ # calc
+
+ * **!calc `<expression>`**: évalue l'expression mathématique `<expression>`.
+ """
+
+ def irc_doc, do: @moduledoc
+
+ def start_link() do
+ GenServer.start_link(__MODULE__, [])
+ end
+
+ def init(_) do
+ {:ok, _} = Registry.register(IRC.PubSub, "trigger:calc", [])
+ {:ok, nil}
+ end
+
+ def handle_info({:irc, :trigger, "calc", message = %IRC.Message{trigger: %IRC.Trigger{type: :bang, args: expr_list}}}, state) do
+ expr = Enum.join(expr_list, " ")
+ result = try do
+ case Abacus.eval(expr) do
+ {:ok, result} -> result
+ error -> inspect(error)
+ end
+ rescue
+ error -> "#{error.message}"
+ end
+ message.replyfun.("#{message.sender.nick}: #{expr} = #{result}")
+ {:noreply, state}
+ end
+
+ def handle_info(msg, state) do
+ {:noreply, state}
+ end
+
+end
+
diff --git a/lib/lsg_irc/connection_handler.ex b/lib/lsg_irc/connection_handler.ex
deleted file mode 100644
index 8d07e58..0000000
--- a/lib/lsg_irc/connection_handler.ex
+++ /dev/null
@@ -1,37 +0,0 @@
-defmodule LSG.IRC.ConnectionHandler do
- defmodule State do
- defstruct [:host, :port, :pass, :nick, :name, :user, :client]
- end
-
- def start_link(client) do
- irc = Application.get_env(:lsg, :irc)[:irc]
- host = irc[:host]
- port = irc[:port]
- nick = irc[:nick]
- user = irc[:user]
- name = irc[:name]
- GenServer.start_link(__MODULE__, [%State{client: client, host: host, port: port, nick: nick, user: user, name: name}])
- end
-
- def init([state]) do
- IO.puts inspect(state)
- ExIRC.Client.add_handler state.client, self
- ExIRC.Client.connect! state.client, state.host, state.port
- {:ok, state}
- end
-
- def handle_info({:connected, server, port}, state) do
- debug "Connected to #{server}:#{port}"
- ExIRC.Client.logon state.client, state.pass, state.nick, state.user, state.name
- {:noreply, state}
- end
-
- # Catch-all for messages you don't care about
- def handle_info(msg, state) do
- {:noreply, state}
- end
-
- defp debug(msg) do
- IO.puts IO.ANSI.yellow() <> msg <> IO.ANSI.reset()
- end
-end
diff --git a/lib/lsg_irc/dice_handler.ex b/lib/lsg_irc/dice_handler.ex
index b07b59b..7ff7b4d 100644
--- a/lib/lsg_irc/dice_handler.ex
+++ b/lib/lsg_irc/dice_handler.ex
@@ -22,6 +22,7 @@ defmodule LSG.IRC.DiceHandler do
def init([client]) do
ExIRC.Client.add_handler(client, self())
+ {:ok, _} = Registry.register(IRC.PubSub, "dice", [])
{:ok, %__MODULE__{client: client}}
end
diff --git a/lib/lsg_irc/handler.ex b/lib/lsg_irc/handler.ex
deleted file mode 100644
index 19c0945..0000000
--- a/lib/lsg_irc/handler.ex
+++ /dev/null
@@ -1,24 +0,0 @@
-defmodule LSG.IRC.Handler do
- defmacro __using__(_) do
- quote do
- alias LSG.IRC
- alias LSG.IRC.UserTrack
- alias ExIRC.Client
- require LSG.IRC.Handler
- import LSG.IRC.Handler
- end
- end
-
- def privmsg(client, {nil, %ExIRC.SenderInfo{nick: nick}}, message) do
- privmsg(client, nick, message)
- end
-
- def privmsg(client, {channel, _}, message) do
- privmsg(client, channel, message)
- end
-
- def privmsg(client, target, message) when is_binary(target) do
- ExIRC.Client.msg(client, :privmsg, target, message)
- end
-
-end
diff --git a/lib/lsg_irc/kick_roulette_handler.ex b/lib/lsg_irc/kick_roulette_handler.ex
index 3591b5e..ece1b95 100644
--- a/lib/lsg_irc/kick_roulette_handler.ex
+++ b/lib/lsg_irc/kick_roulette_handler.ex
@@ -18,7 +18,7 @@ defmodule LSG.IRC.KickRouletteHandler do
def handle_info({:received, "!kick", sender, chan}, client) do
if 5 == :crypto.rand_uniform(1, 6) do
spawn(fn() ->
- :timer.sleep(:crypto.rand_uniform(500, 15_000))
+ :timer.sleep(:crypto.rand_uniform(200, 10_000))
ExIRC.Client.kick(client, chan, sender.nick, "perdu")
end)
end
diff --git a/lib/lsg_irc/last_fm_handler.ex b/lib/lsg_irc/last_fm_handler.ex
index fe767b1..4eef24e 100644
--- a/lib/lsg_irc/last_fm_handler.ex
+++ b/lib/lsg_irc/last_fm_handler.ex
@@ -64,6 +64,14 @@ defmodule LSG.IRC.LastFmHandler do
{:noreply, state}
end
+ def terminate(_reason, state) do
+ if state.dets do
+ :dets.sync(state.dets)
+ :dets.close(state.dets)
+ end
+ :ok
+ end
+
defp irc_now_playing(nick_or_user, chan, state) do
nick_or_user = String.strip(nick_or_user)
username = case :dets.lookup(state.dets, String.downcase(nick_or_user)) do
diff --git a/lib/lsg_irc/login_handler.ex b/lib/lsg_irc/login_handler.ex
deleted file mode 100644
index f989b40..0000000
--- a/lib/lsg_irc/login_handler.ex
+++ /dev/null
@@ -1,25 +0,0 @@
-defmodule LSG.IRC.LoginHandler do
- def start_link(client) do
- GenServer.start_link(__MODULE__, [client])
- end
-
- def init([client]) do
- ExIRC.Client.add_handler client, self
- {:ok, {client, ["#lsg", "#lsgtest"]}}
- end
-
- def handle_info(:logged_in, state = {client, channels}) do
- debug "Logged in to server"
- channels |> Enum.map(&ExIRC.Client.join client, &1)
- {:noreply, state}
- end
-
- # Catch-all for messages you don't care about
- def handle_info(_msg, state) do
- {:noreply, state}
- end
-
- defp debug(msg) do
- IO.puts IO.ANSI.yellow() <> msg <> IO.ANSI.reset()
- end
-end
diff --git a/lib/lsg_irc/quatre_cent_vingt_plugin.ex b/lib/lsg_irc/quatre_cent_vingt_plugin.ex
new file mode 100644
index 0000000..579858e
--- /dev/null
+++ b/lib/lsg_irc/quatre_cent_vingt_plugin.ex
@@ -0,0 +1,105 @@
+defmodule LSG.IRC.QuatreCentVingtPlugin do
+ require Logger
+
+ @moduledoc """
+ # 420
+
+ * **!420**: recorde un nouveau 420.
+ * **!420 pseudo**: stats du pseudo.
+ """
+
+ @achievements %{
+ 1 => ["[le premier… il faut bien commencer un jour]"],
+ 10 => ["T'en es seulement à 10 ? ╭∩╮(Ο_Ο)╭∩╮"],
+ 42 => ["Bravo, et est-ce que autant de pétards t'on aidés à trouver la Réponse ? ٩(- ̮̮̃-̃)۶ [42]"],
+ 100 => ["°º¤ø,¸¸,ø¤º°`°º¤ø,¸,ø¤°º¤ø,¸¸,ø¤º°`°º¤ø,¸ 100 °º¤ø,¸¸,ø¤º°`°º¤ø,¸,ø¤°º¤ø,¸¸,ø¤º°`°º¤ø,¸"],
+ 115 => [" ۜ\(סּںסּَ` )/ۜ 115!!"]
+ }
+
+ @emojis [
+ "\\o/",
+ "~o~",
+ "~~o∞~~",
+ "*\\o/*",
+ "**\\o/**",
+ "*ô*",
+ ]
+
+ @coeffs Range.new(1, 10)
+
+ def irc_doc, do: @moduledoc
+
+ def start_link, do: GenServer.start_link(__MODULE__, [])
+
+ def init(_) do
+ for coeff <- @coeffs do
+ {:ok, _} = Registry.register(IRC.PubSub, "trigger:#{420*coeff}", [])
+ end
+ dets_filename = (LSG.data_path() <> "/" <> "420.dets") |> String.to_charlist
+ {:ok, dets} = :dets.open_file(dets_filename, [{:type,:bag}])
+ {:ok, dets}
+ end
+
+ for coeff <- @coeffs do
+ qvc = to_string(420 * coeff)
+ def handle_info({:irc, :trigger, unquote(qvc), m = %IRC.Message{trigger: %IRC.Trigger{args: [], type: :bang}}}, dets) do
+ {count, last} = get_statistics_for_nick(dets, m.sender.nick)
+ count = count + unquote(coeff)
+ text = achievement_text(count)
+ now = DateTime.to_unix(DateTime.utc_now())-1 # this is ugly
+ for i <- Range.new(1, unquote(coeff)) do
+ :ok = :dets.insert(dets, {String.downcase(m.sender.nick), now+i})
+ end
+ last_s = if last do
+ last_s = format_relative_timestamp(last)
+ " (le dernier était #{last_s})"
+ else
+ ""
+ end
+ m.replyfun.("#{m.sender.nick} 420 +#{unquote(coeff)} #{text}#{last_s}")
+ {:noreply, dets}
+ end
+ end
+
+ def handle_info({:irc, :trigger, "420", m = %IRC.Message{trigger: %IRC.Trigger{args: [nick], type: :bang}}}, dets) do
+ text = case get_statistics_for_nick(dets, nick) do
+ {0, _} -> "#{nick} n'a jamais !420 ... honte à lui."
+ {count, last} ->
+ last_s = format_relative_timestamp(last)
+ "#{nick} 420: total #{count}, le dernier #{last_s}"
+ end
+ m.replyfun.(text)
+ {:noreply, dets}
+ end
+
+ defp format_relative_timestamp(timestamp) do
+ alias Timex.Format.DateTime.Formatters
+ alias Timex.Timezone
+ date = timestamp
+ |> DateTime.from_unix!
+ |> 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
+
+ defp get_statistics_for_nick(dets, nick) do
+ qvc = :dets.lookup(dets, String.downcase(nick)) |> Enum.sort
+ count = Enum.reduce(qvc, 0, fn(_, acc) -> acc + 1 end)
+ {_, last} = List.last(qvc) || {nil, nil}
+ {count, last}
+ end
+
+ @achievements_keys Map.keys(@achievements)
+ defp achievement_text(count) when count in @achievements_keys do
+ Enum.random(Map.get(@achievements, count))
+ end
+
+ defp achievement_text(count) do
+ emoji = Enum.random(@emojis)
+ "#{emoji} [#{count}]"
+ end
+
+end
diff --git a/lib/lsg_irc/txt_handler.ex b/lib/lsg_irc/txt_handler.ex
index efe2b68..032c11c 100644
--- a/lib/lsg_irc/txt_handler.ex
+++ b/lib/lsg_irc/txt_handler.ex
@@ -1,5 +1,5 @@
defmodule LSG.IRC.TxtHandler do
- alias LSG.IRC.UserTrack
+ alias IRC.UserTrack
require Logger
@moduledoc """
@@ -213,6 +213,14 @@ defmodule LSG.IRC.TxtHandler do
{:noreply, state}
end
+ def terminate(_reason, state) do
+ if state.locks do
+ :dets.sync(state.locks)
+ :dets.close(state.locks)
+ end
+ :ok
+ end
+
# Load/Reloads text files from disk
defp load() do
triggers = Path.wildcard(directory() <> "/*.txt")
@@ -331,8 +339,8 @@ defmodule LSG.IRC.TxtHandler do
end
defp can_write?(state = %__MODULE__{rw: rw?, locks: locks}, channel, sender, trigger) do
- admin? = LSG.IRC.admin?(sender)
- operator? = LSG.IRC.UserTrack.operator?(channel, sender.nick)
+ admin? = IRC.admin?(sender)
+ operator? = IRC.UserTrack.operator?(channel, sender.nick)
locked? = case :dets.lookup(locks, trigger) do
[{trigger}] -> true
_ -> false
diff --git a/lib/lsg_irc/user_track.ex b/lib/lsg_irc/user_track.ex
deleted file mode 100644
index b67b9f6..0000000
--- a/lib/lsg_irc/user_track.ex
+++ /dev/null
@@ -1,150 +0,0 @@
-defmodule LSG.IRC.UserTrack do
- @moduledoc """
- User Track DB & Utilities
- """
-
- @ets LSG.IRC.UserTrack.Storage
- # {uuid, nick, nicks, privilege_map}
- # Privilege map:
- # %{"#channel" => [:operator, :voice]
- defmodule Storage do
-
- def delete(id) do
- op(fn(ets) -> :ets.delete(ets, id) end)
- end
-
- def insert(tuple) do
- op(fn(ets) -> :ets.insert(ets, tuple) end)
- end
-
- def op(fun) do
- GenServer.call(__MODULE__, {:op, fun})
- end
-
- def start_link do
- GenServer.start_link(__MODULE__, [], [name: __MODULE__])
- end
-
- def init([]) do
- ets = :ets.new(__MODULE__, [:set, :named_table, :protected, {:read_concurrency, true}])
- {:ok, ets}
- end
-
- def handle_call({:op, fun}, _from, ets) do
- returned = try do
- {:ok, fun.(ets)}
- rescue
- rescued -> {:error, rescued}
- catch
- rescued -> {:error, rescued}
- end
- {:reply, returned, ets}
- end
- end
-
- defmodule Id, do: use EntropyString
-
- defmodule User do
- defstruct [:id, :nick, :nicks, :username, :host, :realname, :privileges]
-
- def to_tuple(u = %__MODULE__{}) do
- {u.id || LSG.IRC.UserTrack.Id.large_id, u.nick, u.nicks || [], u.username, u.host, u.realname, u.privileges}
- end
-
- def from_tuple({id, nick, nicks, username, host, realname, privs}) do
- %__MODULE__{id: id, nick: nick, nicks: nicks, username: username, realname: realname, privileges: privs}
- end
- end
-
- def find_by_nick(nick) do
- case :ets.match(@ets, {:'$1', nick, :_, :_, :_, :_, :_}) do
- [[id]] -> lookup(id)
- _ -> nil
- end
- end
-
- def to_list, do: :ets.tab2list(@ets)
-
- def lookup(id) do
- case :ets.lookup(@ets, id) do
- [] -> nil
- [tuple] -> User.from_tuple(tuple)
- end
- end
-
- def operator?(channel, nick) do
- if user = find_by_nick(nick) do
- privs = Map.get(user.privileges, channel, [])
- Enum.member?(privs, :admin) || Enum.member?(privs, :operator)
- else
- false
- end
- end
-
- def joined(c, s), do: joined(c,s,[])
-
- def joined(channel, sender=%{nick: nick, user: uname, host: host}, privileges) do
- privileges = if LSG.IRC.admin?(sender) do
- privileges ++ [:admin]
- else privileges end
- user = if user = find_by_nick(nick) do
- %User{user | username: uname, host: host, privileges: Map.put(user.privileges || %{}, channel, privileges)}
- else
- %User{nick: nick, username: uname, host: host, privileges: %{channel => privileges}}
- end
-
- Storage.op(fn(ets) ->
- :ets.insert(ets, User.to_tuple(user))
- end)
- end
-
- def joined(channel, nick, privileges) do
- user = if user = find_by_nick(nick) do
- %User{user | privileges: Map.put(user.privileges, channel, privileges)}
- else
- %User{nick: nick, privileges: %{channel => privileges}}
- end
-
- Storage.op(fn(ets) ->
- :ets.insert(ets, User.to_tuple(user))
- end)
- end
-
- def renamed(old_nick, new_nick) do
- if user = find_by_nick(old_nick) do
- user = %User{user | nick: new_nick, nicks: [old_nick|user.nicks]}
- Storage.insert(User.to_tuple(user))
- end
- end
-
- def change_privileges(channel, nick, {add, remove}) do
- if user = find_by_nick(nick) do
- privs = Map.get(user.privileges, channel)
-
- privs = Enum.reduce(add, privs, fn(priv, acc) -> [priv|acc] end)
- privs = Enum.reduce(remove, privs, fn(priv, acc) -> List.delete(acc, priv) end)
-
- user = %User{user | privileges: Map.put(user.privileges, channel, privs)}
- Storage.insert(User.to_tuple(user))
- end
- end
-
- def parted(channel, nick) do
- if user = find_by_nick(nick) do
- privs = Map.delete(user.privileges, channel)
- if Enum.count(privs) > 0 do
- user = %User{user | privileges: privs}
- Storage.insert(User.to_tuple(user))
- else
- Storage.delete(user.id)
- end
- end
- end
-
- def quitted(sender) do
- if user = find_by_nick(sender.nick) do
- Storage.delete(user.id)
- end
- end
-
-end
diff --git a/lib/lsg_irc/user_track_handler.ex b/lib/lsg_irc/user_track_handler.ex
deleted file mode 100644
index d167af5..0000000
--- a/lib/lsg_irc/user_track_handler.ex
+++ /dev/null
@@ -1,93 +0,0 @@
-defmodule LSG.IRC.UserTrackHandler do
- @moduledoc """
- # User Track Handler
-
- This handlers keeps track of users presence and privileges.
-
- Planned API:
-
- UserTrackHandler.operator?(%ExIRC.Sender{nick: "href", …}, "#channel") :: boolean
-
- """
-
- def irc_doc, do: nil
-
- def start_link(client) do
- GenServer.start_link(__MODULE__, [client])
- end
-
- defstruct client: nil, ets: nil
-
- def init([client]) do
- ExIRC.Client.add_handler client, self
- {:ok, %__MODULE__{client: client}}
- end
-
- def handle_info({:joined, channel}, state) do
- ExIRC.Client.who(state.client, channel)
- {:noreply, state}
- end
-
- def handle_info({:who, channel, whos}, state) do
- Enum.map(whos, fn(who = %ExIRC.Who{nick: nick, operator?: operator}) ->
- priv = if operator, do: [:operator], else: []
- LSG.IRC.UserTrack.joined(channel, who, priv)
- end)
- {:noreply, state}
- end
-
- def handle_info({:quit, _reason, sender}, state) do
- LSG.IRC.UserTrack.quitted(sender)
- {:noreply, state}
- end
-
- def handle_info({:joined, channel, sender}, state) do
- LSG.IRC.UserTrack.joined(channel, sender, [])
- {:noreply, state}
- end
-
- def handle_info({:kicked, nick, _by, channel, _reason}, state) do
- parted(channel, nick)
- {:noreply, state}
- end
-
- def handle_info({:parted, channel, %ExIRC.SenderInfo{nick: nick}}, state) do
- parted(channel, nick)
- {:noreply, state}
- end
-
- def handle_info({:mode, [channel, mode, nick]}, state) do
- mode(channel, nick, mode)
- {:noreply, state}
- end
-
- def handle_info({:nick_changed, old_nick, new_nick}, state) do
- rename(old_nick, new_nick)
- {:noreply, state}
- end
-
- def handle_info(msg, state) do
- {:noreply, state}
- end
-
- defp parted(channel, nick) do
- LSG.IRC.UserTrack.parted(channel, nick)
- :ok
- end
-
- defp mode(channel, nick, "+o") do
- LSG.IRC.UserTrack.change_privileges(channel, nick, {[:operator], []})
- :ok
- end
-
- defp mode(channel, nick, "-o") do
- LSG.IRC.UserTrack.change_privileges(channel, nick, {[], [:operator]})
- :ok
- end
-
- defp rename(old, new) do
- LSG.IRC.UserTrack.renamed(old, new)
- :ok
- end
-
-end
diff --git a/lib/lsg_irc/wikipedia_plugin.ex b/lib/lsg_irc/wikipedia_plugin.ex
new file mode 100644
index 0000000..4ee95b1
--- /dev/null
+++ b/lib/lsg_irc/wikipedia_plugin.ex
@@ -0,0 +1,90 @@
+defmodule LSG.IRC.WikipediaPlugin do
+ require Logger
+
+ @moduledoc """
+ # wikipédia
+
+ * **!wp `<recherche>`**: retourne le premier résultat de la `<recherche>` Wikipedia
+ * **!wp**: un article Wikipédia au hasard
+ """
+
+ def irc_doc, do: @moduledoc
+
+ def start_link() do
+ GenServer.start_link(__MODULE__, [])
+ end
+
+ def init(_) do
+ {:ok, _} = Registry.register(IRC.PubSub, "trigger:wp", [])
+ {:ok, nil}
+ end
+
+ def handle_info({:irc, :trigger, "wp", message = %IRC.Message{trigger: %IRC.Trigger{args: []}}}, state) do
+ irc_random(message)
+ {:noreply, state}
+ end
+ def handle_info({:irc, :trigger, "wp", message = %IRC.Message{trigger: %IRC.Trigger{args: args}}}, state) do
+ irc_search(Enum.join(args, " "), message)
+ {:noreply, state}
+ end
+
+ def handle_info(info, state) do
+ {:noreply, state}
+ end
+
+ defp irc_search("", message), do: irc_random(message)
+ defp irc_search(query, message) do
+ params = %{
+ "action" => "query",
+ "list" => "search",
+ "srsearch" => String.strip(query),
+ "srlimit" => 1,
+ }
+ case query_wikipedia(params) do
+ {:ok, %{"query" => %{"search" => [item | _]}}} ->
+ title = item["title"]
+ url = "https://fr.wikipedia.org/wiki/" <> String.replace(title, " ", "_")
+ msg = "Wikipédia: #{title} — #{url}"
+ message.replyfun.(msg)
+ _ ->
+ nil
+ end
+ end
+
+ defp irc_random(message) do
+ params = %{
+ "action" => "query",
+ "generator" => "random",
+ "grnnamespace" => 0,
+ "prop" => "info"
+ }
+ case query_wikipedia(params) do
+ {:ok, %{"query" => %{"pages" => map = %{}}}} ->
+ [{_, item}] = Map.to_list(map)
+ title = item["title"]
+ url = "https://fr.wikipedia.org/wiki/" <> String.replace(title, " ", "_")
+ msg = "Wikipédia: #{title} — #{url}"
+ message.replyfun.(msg)
+ _ ->
+ nil
+ end
+ end
+
+ defp query_wikipedia(params) do
+ url = "https://fr.wikipedia.org/w/api.php"
+ params = params
+ |> Map.put("format", "json")
+ |> Map.put("utf8", "")
+
+ case HTTPoison.get(url, [], params: params) do
+ {:ok, %HTTPoison.Response{status_code: 200, body: body}} -> Jason.decode(body)
+ {:ok, %HTTPoison.Response{status_code: 400, body: body}} ->
+ Logger.error "Wikipedia HTTP 400: #{inspect body}"
+ {:error, "http 400"}
+ error ->
+ Logger.error "Wikipedia http error: #{inspect error}"
+ {:error, "http client error"}
+ end
+ end
+
+end
diff --git a/lib/lsg_irc/youtube_handler.ex b/lib/lsg_irc/youtube_handler.ex
index e7eadfc..51584a2 100644
--- a/lib/lsg_irc/youtube_handler.ex
+++ b/lib/lsg_irc/youtube_handler.ex
@@ -7,7 +7,7 @@ defmodule LSG.IRC.YouTubeHandler do
* **!yt `<recherche>`**, !youtube `<recherche>`: retourne le premier résultat de la `<recherche>` YouTube
"""
- defstruct client: nil, dets: nil
+ defstruct client: nil
def irc_doc, do: @moduledoc