summaryrefslogblamecommitdiff
path: root/lib/lsg_irc/radio_france_plugin.ex
blob: 34935ca8e01ff4633c98d23babe15889d5c19ea7 (plain) (tree)




































































































































                                                                                                                                                   
defmodule LSG.IRC.RadioFrancePlugin do
  require Logger

  def irc_doc() do
    """
    # radio france

    Qu'est ce qu'on écoute sur radio france ?

    * **!radiofrance `[station]`, !rf `[station]`**
    * **!fip, !inter, !info, !bleu, !culture, !musique, !fip `[sous-station]`, !bleu `[région]`**
    """
  end

  def start_link() do
    GenServer.start_link(__MODULE__, [], name: __MODULE__)
  end

  @trigger "radiofrance"
  @shortcuts ~w(fip inter info bleu culture musique)

  def init(_) do
    regopts = [plugin: __MODULE__]
    {:ok, _} = Registry.register(IRC.PubSub, "trigger:radiofrance", regopts)
    {:ok, _} = Registry.register(IRC.PubSub, "trigger:rf", regopts)
    for s <- @shortcuts do
      {:ok, _} = Registry.register(IRC.PubSub, "trigger:#{s}", regopts)
    end
    {:ok, nil}
  end

  def handle_info({:irc, :trigger, "rf", m = %IRC.Message{trigger: %IRC.Trigger{type: :bang}}}, state) do
    handle_info({:irc, :trigger, "radiofrance", m}, state)
  end

  def handle_info({:irc, :trigger, @trigger, m = %IRC.Message{trigger: %IRC.Trigger{type: :bang, args: []}}}, state) do
    m.replyfun.("radiofrance: précisez la station!")
    {:noreply, state}
  end

  def handle_info({:irc, :trigger, @trigger, m = %IRC.Message{trigger: %IRC.Trigger{type: :bang, args: args}}}, state) do
    now(args_to_station(args), m)
    {:noreply, state}
  end

  def handle_info({:irc, :trigger, trigger, m = %IRC.Message{trigger: %IRC.Trigger{type: :bang, args: args}}}, state) when trigger in @shortcuts do
    now(args_to_station([trigger | args]), m)
    {:noreply, state}
  end

  defp args_to_station(args) do
    args
    |> Enum.map(&unalias/1)
    |> Enum.map(&String.downcase/1)
    |> Enum.join("_")
  end

  def handle_info(info, state) do
    Logger.debug("unhandled info: #{inspect info}")
    {:noreply, state}
  end

  defp now(station, m) when is_binary(station) do
    case HTTPoison.get(np_url(station), [], []) do
      {:ok, %HTTPoison.Response{status_code: 200, body: body}} ->
        json = Poison.decode!(body)
        song? = !!get_in(json, ["now", "song"])
        station = reformat_station_name(get_in(json, ["now", "stationName"]))
        now_title = get_in(json, ["now", "firstLine", "title"])
        now_subtitle = get_in(json, ["now", "secondLine", "title"])        
        next_title = get_in(json, ["next", "firstLine", "title"])
        next_subtitle = get_in(json, ["next", "secondLine", "title"])
        next_song? = !!get_in(json, ["next", "song"])
        next_at = get_in(json, ["next", "startTime"])

        now = format_title(song?, now_title, now_subtitle)
        prefix = if song?, do: "🎶", else: "🎤"
        m.replyfun.("#{prefix} #{station}: #{now}")
        
        next = format_title(song?, next_title, next_subtitle)
        if next do
          next_prefix = if next_at do
            next_date = DateTime.from_unix!(next_at)
            in_seconds = DateTime.diff(next_date, DateTime.utc_now())
            in_minutes = ceil(in_seconds / 60)
            if in_minutes >= 5 do
              if next_song?, do: "#{in_minutes}m 🔜", else: "dans #{in_minutes} minutes:"
            else
              if next_song?, do: "🔜", else: "suivi de:"
            end
          else
            if next_song?, do: "🔜", else: "à suivre:"
          end
          m.replyfun.("#{next_prefix} #{next}")
        end

      {:error, %HTTPoison.Response{status_code: 404}} ->
        m.replyfun.("radiofrance: la radio \"#{station}\" n'existe pas")

      {:error, %HTTPoison.Response{status_code: code}} ->
        m.replyfun.("radiofrance: erreur http #{code}")

      _ ->
        m.replyfun.("radiofrance: ça n'a pas marché, rip")
    end
  end

  defp np_url(station), do: "https://www.radiofrance.fr/api/v2.0/stations/#{station}/live"

  defp unalias("inter"), do: "franceinter"
  defp unalias("info"), do: "franceinfo"
  defp unalias("bleu"), do: "francebleu"
  defp unalias("culture"), do: "franceculture"
  defp unalias("musique"), do: "francemusique"
  defp unalias(station), do: station

  defp format_title(_, nil, nil) do
    nil
  end
  defp format_title(true, title, artist) do
    [artist, title] |> Enum.filter(& &1) |> Enum.join(" - ")
  end
  defp format_title(false, show, section) do
    [show, section] |> Enum.filter(& &1) |> Enum.join(": ")
  end

  defp reformat_station_name(station) do
    station
    |> String.replace("france", "france ")
    |> String.replace("_", " ")
  end

end