defmodule Spotify.Personalization do
@moduledoc """
Endpoints for retrieving information about the user’s listening habits
Some endpoints return collections. Spotify wraps the collection in a paging object,
this API does the same. A single piece of data will not be wrapped.
There are two functions for each endpoint, one that actually makes the request,
and one that provides the endpoint:
Spotify.Playist.create_playlist(conn, "foo", "bar") # makes the POST request.
Spotify.Playist.create_playlist_url("foo", "bar") # provides the url for the request.
https://developer.spotify.com/web-api/web-api-personalization-endpoints/
"""
import Spotify.Helpers
use Spotify.Responder
alias Spotify.{
Client,
Paging
}
defstruct ~w[
items
next
previous
total
limit
href
]a
@doc """
Get the current user’s top artists based on calculated affinity.
[Spotify Documentation](https://developer.spotify.com/web-api/get-users-top-artists-and-tracks/)
**Method**: `GET`
**Optional Params**: `limit`, `offset`, `time_range`
Spotify.Personalization.top_artists(conn)
{ :ok, artists: [%Spotify.Artist{..}...], paging: %Paging{next:...} }
"""
def top_artists(conn, params \\ []) do
url = top_artists_url(params)
conn |> Client.get(url) |> handle_response
end
@doc """
Get the current user’s top artists based on calculated affinity.
iex> Spotify.Personalization.top_artists_url(limit: 5, time_range: "medium_term")
"https://api.spotify.com/v1/me/top/artists?limit=5&time_range=medium_term"
"""
def top_artists_url(params \\ []) do
url() <> "artists" <> query_string(params)
end
@doc """
Get the current user’s top tracks based on calculated affinity.
[Spotify Documentation](https://developer.spotify.com/web-api/get-users-top-artists-and-tracks/)
**Method**: `GET`
**Optional Params**: `limit`, `offset`, `time_range`
Spotify.Personalization.top_tracks(conn)
{ :ok, tracks: [%Spotify.Tracks{..}...], paging: %Paging{next:...} }
"""
def top_tracks(conn, params \\ []) do
url = top_tracks_url(params)
conn |> Client.get(url) |> handle_response
end
@doc """
Get the current user’s top tracks based on calculated affinity.
iex> Spotify.Personalization.top_tracks_url
"https://api.spotify.com/v1/me/top/tracks"
"""
def top_tracks_url(params \\ []) do
url() <> "tracks" <> query_string(params)
end
@doc """
Base URL
"""
def url do
"https://api.spotify.com/v1/me/top/"
end
@doc """
Implements the hook expected by the Responder behaviour
"""
def build_response(body) do
items =
Enum.map(body["items"], fn item ->
case item["type"] do
"artist" -> build_artist_struct(item)
"track" -> build_track_struct(item)
end
end)
paging = to_struct(Paging, body)
Map.put(paging, :items, items)
end
@doc false
def build_artist_struct(artist) do
to_struct(Spotify.Artist, artist)
end
@doc false
def build_track_struct(track) do
to_struct(Spotify.Track, track)
end
end