diff options
Diffstat (limited to 'lib/nola_plugins/last_fm.ex')
-rw-r--r-- | lib/nola_plugins/last_fm.ex | 187 |
1 files changed, 0 insertions, 187 deletions
diff --git a/lib/nola_plugins/last_fm.ex b/lib/nola_plugins/last_fm.ex deleted file mode 100644 index 1a9b7dd..0000000 --- a/lib/nola_plugins/last_fm.ex +++ /dev/null @@ -1,187 +0,0 @@ -defmodule Nola.Plugins.LastFm do - require Logger - - @moduledoc """ - # last.fm - - * **!lastfm|np `[nick|username]`** - * **.lastfm|np** - * **+lastfm, -lastfm `<username last.fm>; ?lastfm`** Configurer un nom d'utilisateur last.fm - """ - - @single_trigger ~w(lastfm np) - @pubsub_topics ~w(trigger:lastfm trigger:np) - - defstruct dets: nil - - def irc_doc, do: @moduledoc - - def start_link() do - GenServer.start_link(__MODULE__, [], name: __MODULE__) - end - - def init([]) do - regopts = [type: __MODULE__] - for t <- @pubsub_topics, do: {:ok, _} = Registry.register(IRC.PubSub, t, type: __MODULE__) - dets_filename = (Nola.data_path() <> "/" <> "lastfm.dets") |> String.to_charlist - {:ok, dets} = :dets.open_file(dets_filename, []) - {:ok, %__MODULE__{dets: dets}} - end - - def handle_info({:irc, :trigger, "lastfm", message = %{trigger: %{type: :plus, args: [username]}}}, state) do - username = String.strip(username) - :ok = :dets.insert(state.dets, {message.account.id, username}) - message.replyfun.("#{message.sender.nick}: nom d'utilisateur last.fm configuré: \"#{username}\".") - {:noreply, state} - end - - def handle_info({:irc, :trigger, "lastfm", message = %{trigger: %{type: :minus, args: []}}}, state) do - text = case :dets.lookup(state.dets, message.account.id) do - [{_nick, _username}] -> - :dets.delete(state.dets, message.account.id) - message.replyfun.("#{message.sender.nick}: nom d'utilisateur last.fm enlevé.") - _ -> nil - end - {:noreply, state} - end - - def handle_info({:irc, :trigger, "lastfm", message = %{trigger: %{type: :query, args: []}}}, state) do - text = case :dets.lookup(state.dets, message.account.id) do - [{_nick, username}] -> - message.replyfun.("#{message.sender.nick}: #{username}.") - _ -> nil - end - {:noreply, state} - end - - def handle_info({:irc, :trigger, _, message = %{trigger: %{type: :bang, args: []}}}, state) do - irc_now_playing(message.account.id, message, state) - {:noreply, state} - end - - def handle_info({:irc, :trigger, _, message = %{trigger: %{type: :bang, args: [nick_or_user]}}}, state) do - irc_now_playing(nick_or_user, message, state) - {:noreply, state} - end - - def handle_info({:irc, :trigger, _, message = %{trigger: %{type: :dot}}}, state) do - members = IRC.Membership.members(message.network, message.channel) - foldfun = fn({nick, user}, acc) -> [{nick,user}|acc] end - usernames = :dets.foldl(foldfun, [], state.dets) - |> Enum.uniq() - |> Enum.filter(fn({acct,_}) -> Enum.member?(members, acct) end) - |> Enum.map(fn({_, u}) -> u end) - for u <- usernames, do: irc_now_playing(u, message, state) - {:noreply, state} - end - - def handle_info(info, state) 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, message, state) do - nick_or_user = String.strip(nick_or_user) - - id_or_user = if account = IRC.Account.get(nick_or_user) || IRC.Account.find_always_by_nick(message.network, message.channel, nick_or_user) do - account.id - else - nick_or_user - end - - username = case :dets.lookup(state.dets, id_or_user) do - [{_, username}] -> username - _ -> id_or_user - end - - case now_playing(username) do - {:error, text} when is_binary(text) -> - message.replyfun.(text) - {:ok, map} when is_map(map) -> - track = fetch_track(username, map) - text = format_now_playing(map, track) - user = if account = IRC.Account.get(id_or_user) do - user = IRC.UserTrack.find_by_account(message.network, account) - if(user, do: user.nick, else: account.name) - else - username - end - if user && text do - message.replyfun.("#{user} #{text}") - else - message.replyfun.("#{username}: pas de résultat") - end - other -> - message.replyfun.("erreur :(") - end - end - - defp now_playing(user) do - api = Application.get_env(:nola, :lastfm)[:api_key] - url = "http://ws.audioscrobbler.com/2.0/?method=user.getrecenttracks&format=json&limit=1&extended=1" <> "&api_key=" <> api <> "&user="<> user - case HTTPoison.get(url) do - {:ok, %HTTPoison.Response{status_code: 200, body: body}} -> Jason.decode(body) - {:ok, %HTTPoison.Response{status_code: 404}} -> {:error, "last.fm: utilisateur \"#{user}\" inexistant"} - {:ok, %HTTPoison.Response{status_code: code}} -> {:error, "last.fm: erreur #{to_string(code)}"} - error -> - Logger.error "Lastfm http error: #{inspect error}" - :error - end - end - defp fetch_track(user, %{"recenttracks" => %{"track" => [ t = %{"name" => name, "artist" => %{"name" => artist}} | _]}}) do - api = Application.get_env(:nola, :lastfm)[:api_key] - url = "http://ws.audioscrobbler.com/2.0/?method=track.getInfo&format=json" <> "&api_key=" <> api <> "&username="<> user <> "&artist="<>URI.encode(artist)<>"&track="<>URI.encode(name) - case HTTPoison.get(url) do - {:ok, %HTTPoison.Response{status_code: 200, body: body}} -> - case Jason.decode(body) do - {:ok, body} -> body["track"] || %{} - _ -> %{} - end - error -> - Logger.error "Lastfm http error: #{inspect error}" - :error - end - end - - defp format_now_playing(%{"recenttracks" => %{"track" => [track = %{"@attr" => %{"nowplaying" => "true"}} | _]}}, et) do - format_track(true, track, et) - end - - defp format_now_playing(%{"recenttracks" => %{"track" => [track | _]}}, et) do - format_track(false, track, et) - end - - defp format_now_playing(%{"error" => err, "message" => message}, _) do - "last.fm error #{err}: #{message}" - end - - defp format_now_playing(miss) do - nil - end - - defp format_track(np, track, extended) do - artist = track["artist"]["name"] - album = if track["album"]["#text"], do: " (" <> track["album"]["#text"] <> ")", else: "" - name = track["name"] <> album - action = if np, do: "écoute ", else: "a écouté" - love = if track["loved"] != "0", do: "❤️" - count = if x = extended["userplaycount"], do: "x#{x} #{love}" - tags = (get_in(extended, ["toptags", "tag"]) || []) - |> Enum.map(fn(tag) -> tag["name"] end) - |> Enum.filter(& &1) - |> Enum.join(", ") - - [action, artist, name, count, tags, track["url"]] - |> Enum.filter(& &1) - |> Enum.map(&String.trim(&1)) - |> Enum.join(" - ") - end - -end |