summaryrefslogtreecommitdiff
path: root/lib/plugins/wikipedia.ex
blob: 0bcbee7517bda3a798bff827a7b192a4adbce584 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
defmodule Nola.Plugins.Wikipedia 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__, [], name: __MODULE__)
  end

  def init(_) do
    {:ok, _} = Registry.register(Nola.PubSub, "trigger:wp", plugin: __MODULE__)
    {:ok, nil}
  end

  def handle_info(
        {:irc, :trigger, _,
         message = %Nola.Message{trigger: %Nola.Trigger{type: :bang, args: []}}},
        state
      ) do
    irc_random(message)
    {:noreply, state}
  end

  def handle_info(
        {:irc, :trigger, _,
         message = %Nola.Message{trigger: %Nola.Trigger{type: :bang, 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