defmodule Nola.IRC.OutlinePlugin do @moduledoc """ # outline auto-link Envoie un lien vers Outline quand un lien est envoyé. * **!outline ``** crée un lien outline pour ``. * **+outline ``** active outline pour ``. * **-outline ``** désactive outline pour ``. """ def short_irc_doc, do: false def irc_doc, do: @moduledoc require Logger def start_link() do GenServer.start_link(__MODULE__, [], name: __MODULE__) end defstruct [:file, :hosts] def init([]) do regopts = [plugin: __MODULE__] {:ok, _} = Registry.register(IRC.PubSub, "trigger:outline", regopts) {:ok, _} = Registry.register(IRC.PubSub, "messages", regopts) file = Path.join(Nola.data_path, "/outline.txt") hosts = case File.read(file) do {:error, :enoent} -> [] {:ok, lines} -> String.split(lines, "\n", trim: true) end {:ok, %__MODULE__{file: file, hosts: hosts}} end def handle_info({:irc, :trigger, "outline", message = %IRC.Message{trigger: %IRC.Trigger{type: :plus, args: [host]}}}, state) do state = %{state | hosts: [host | state.hosts]} save(state) message.replyfun.("ok") {:noreply, state} end def handle_info({:irc, :trigger, "outline", message = %IRC.Message{trigger: %IRC.Trigger{type: :minus, args: [host]}}}, state) do state = %{state | hosts: List.delete(state.hosts, host)} save(state) message.replyfun.("ok") {:noreply, state} end def handle_info({:irc, :trigger, "outline", message = %IRC.Message{trigger: %IRC.Trigger{type: :bang, args: [url]}}}, state) do line = "-> #{outline(url)}" message.replyfun.(line) end def handle_info({:irc, :text, message = %IRC.Message{text: text}}, state) do String.split(text) |> Enum.map(fn(word) -> if String.starts_with?(word, "http://") || String.starts_with?(word, "https://") 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 outline_url = outline(word) line = "-> #{outline_url}" message.replyfun.(line) end end end end) {:noreply, state} end def handle_info(msg, state) do {:noreply, state} end def save(state = %{file: file, hosts: hosts}) do string = Enum.join(hosts, "\n") 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