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