diff options
Diffstat (limited to 'lib/lsg_irc')
-rw-r--r-- | lib/lsg_irc/admin_handler.ex | 15 | ||||
-rw-r--r-- | lib/lsg_irc/base_handler.ex | 2 | ||||
-rw-r--r-- | lib/lsg_irc/calc_handler.ex | 38 | ||||
-rw-r--r-- | lib/lsg_irc/calc_plugin.ex | 38 | ||||
-rw-r--r-- | lib/lsg_irc/connection_handler.ex | 37 | ||||
-rw-r--r-- | lib/lsg_irc/dice_handler.ex | 1 | ||||
-rw-r--r-- | lib/lsg_irc/handler.ex | 24 | ||||
-rw-r--r-- | lib/lsg_irc/kick_roulette_handler.ex | 2 | ||||
-rw-r--r-- | lib/lsg_irc/last_fm_handler.ex | 8 | ||||
-rw-r--r-- | lib/lsg_irc/login_handler.ex | 25 | ||||
-rw-r--r-- | lib/lsg_irc/quatre_cent_vingt_plugin.ex | 105 | ||||
-rw-r--r-- | lib/lsg_irc/txt_handler.ex | 14 | ||||
-rw-r--r-- | lib/lsg_irc/user_track.ex | 150 | ||||
-rw-r--r-- | lib/lsg_irc/user_track_handler.ex | 93 | ||||
-rw-r--r-- | lib/lsg_irc/wikipedia_plugin.ex | 90 | ||||
-rw-r--r-- | lib/lsg_irc/youtube_handler.ex | 2 |
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 |