summaryrefslogtreecommitdiff
path: root/lib/nola_plugins/last_fm.ex
diff options
context:
space:
mode:
Diffstat (limited to 'lib/nola_plugins/last_fm.ex')
-rw-r--r--lib/nola_plugins/last_fm.ex187
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