TODOs / QUESTIONS / NOTEs:
- Include the revision somewhere in the Playlist change events
- Consider whether it's better to fire off multiple events (ie. one per item) or just one with an array (ie. one per revision)
- Work out how to best expose each class to the user, as most (if not all) of them will require a reference back to the Spotify object to communicate with the server
- Work out how items returned from metadata e.g. Artists and Albums for a Track, Tracks for a Playlist or RadioStation, get converted into their relevant objects.
- Work out if it is feasble to no longer inherit/extend from the protobuf-generated classes, especially if all the logic is self contained within each relevant class (ie. get rid of logic from spotify.get() and spotify.playlist() and either remove them completely or make them into helper/backwards-compat stubs that forward it to the class to do). Ideally, this should separate the logic out so that the only thing that the Spotify class is really concerned about is communication and login.
- Also, if we are moving the logic for parsing protobufs to the track class, etc. then we probably don't need the tag function (or at least not in its current form) as each class will interact directly with the sendCommand / sendProtobufRequest api.
- Decide if the current login logic is better or if it is advantageous to decouple authentication from connection.
- Make sure the API calls allow
fn(err, result)
style callbacks so we can get rid of all the exception throwing (or at least keep it to a minimum) - Work out how to do multi-get requests. Some sort of parent collection object? But then how would that work or how would users use it in a nice way.
- Look at which callbacks should be optional, and which shouldn't, and document them correctly. Any functions without side-effects (e.g. getting metadata) should require a callback.
- Should we separate Hermes/Mercury communication into a separate object/file? What advantage would this have?
- Could the Schemas object be simplified by developing for protobufjs first and doing wrapping around protobuf? (Performance metrics probably required)
- Work out where new features fit in the scheme of things, e.g. Inbox, Notifications, Messages, Users, Social Sharing, Suggested followers, Discover, Browse, Recently Played Artists, Last.fm scrobbling, Top lists (albums, tracks, etc.)
Helper function, creates new Spotify instance and performs spotify.login
function(command, args) {}
Emitted when there is a Spotify "message" from the server to the client.
By default, this is internally tied to spotify._onmessagecommand to automatically handle "do_work" and other messages.
Creates the connection to the Spotify Web websocket server and logs in using
the given Spotify username
and password
credentials.
Creates the connection to the Spotify Web websocket server and logs in using an anonymous identity.
Creates the connection to the Spotify Web websocket server and logs in using the given Facebook App OAuth token and corresponding user ID.
Sends the "connect" command.
Should be called once the WebSocket connection is established.
Closes the WebSocket connection of present. This effectively ends your Spotify Web "session" (and derefs from the event-loop, so your program can exit).
Retrieves the object for one or more track, album, artist or playlist spotify uris. If multiple uris are specified then an array of objects will be returned.
(Internally calls Track.get / Album.get / Artist.get / Playlist.get depending on the uri type)
Backwards compatibility / helper function. Creates a playlist object for the uri, requests
(QUESTION: Should this be removed ?)
(QUESTION: Should this be removed ?)
(QUESTION: If rootlist is removed, should it be replaced by some helper function to help get the rootlist? Or should that be under the playlist class as a static method)
Executes a "search" against the Spotify music library. Note that the response is an XML data String, so you must parse it yourself.
Creates a new Playlist instance with the specified uri, or in the case of multiple uris, creates an array of new Playlist instances.
Create a new Playlist
function(modifications) { }
Fired when any part of the Playlist changes on the server
When a listener is attached to this event, a subscription is automatically created
Playlist type, determined from its' uri
One of 'playlist', 'rootlist', 'publishedrootlist', 'starred'
Return the spotify uri of the Playlist
Retrieve the playlist attributes
function(new_attributes, old_attributes) { }
Fired when the attributes of the Playlist changes on the server
Retrieve the playlist contents
function(item, index) { }
Fired for each new item added
function(item, newIndex, oldIndex) { }
Fired for each new item moved
function(item) { }
Fired for each new item removed
function(item, new_attributes, old_attributes) { }
Fired for each new item modified
Fired on any of the four above events
Add an item to the playlist
Remove an item from a playlist
Modifies the attributes of the Playlist
Deletes the Playlist represented by the Playlist instance.
Subscribe to modification notifications from the server
Required for any of the events to work correctly
When the object detects a new listener on any of the events it will automatically subscribe to notifications
Unsubscribe from modification notifications from the server
When the object detects all listeners have been removed and subscribe was not called manually, then unsubscribe will be called automatically.
Get the current revision from the server
Get the differences between the latest revision and the revision specified.
Publishes / Follows a Playlist
This is a helper function that adds the current playlist to the user's publishedrootlist
Unpublishes / Unfollows a Playlist
This is a helper function that removes the current playlist to the user's publishedrootlist
Returns the Playlist Item at the offset
Returns the instance of the Playlist to which the PlaylistContents instance belongs to
function(newIndex, oldIndex) { }
Fired when the item is moved within the Playlist
function(new_attributes, old_attributes) { }
Fired when the item's attributes are modified
function() { }
Fired when the item is removed from the Playlist
Fired on any of the four above events
Returns the instance of the PlaylistContents to which the PlaylistItem instance belongs to
Returns the revision of the parent PlaylistContents instance
function(new_attributes, old_attributes) { }
Fired when the attributes of the item changes on the server
Retrieve the object specified by the URI.
For example, in the typical case a Playlist will contain track URIs, and therefore this function will return a Track instance
Creates a new Track instance with the specified uri, or in the case of multiple uris, creates an array of new Track instances.
Instances will only contain a URI and will not have metadata populated.
Equivalent to Track.get(uri)
???
Converts the internal GID to the Track URI
Converts the internal GID to the Track Hex ID
Gets the audio URL for the given Track object.
Format can be one of 'MP3_96' (30 second preview) or 'MP3_160' (default).
Transport can be one of 'http' (default) or 'rtmp'.
Returns the metadata for the Track to the specified callback.
If refresh is specified and truthy, then a new request will be made for the data regardless if the metadata has already been loaded.
Retrieve suggested similar tracks to the given track URI
Checks if the given Track object is "available" for playback, taking account for the allowed/forbidden countries, the user's current country, the user's account type (free/paid), etc.
Checks if the given "track" is "available". If yes, returns the "track"
untouched. If no, then the "alternative" tracks array on the "track" instance
is searched until one of them is "available", and then returns that "track".
If none of the alternative tracks are "available", returns null
.
Begins playing the track
Callback signature: function(err, stream) { }
If callback is not specified return a PassThrough stream, listeners should listen for the error event on it as well.
(QUESTION: Should we add a 'start'/'success'/'play' event to the PassThrough stream as well so the stream can be piped once we know it is valid? Or just tell people to use the callback-API?)
Begins playing the track preview
Callback signature: function(err, stream) { }
(These are for if a client really needs to do it manually, I'm hoping these events can be automatically sent according to AudioStream, even if it's not entirely correct as we don't know the stream source.)
Access the underlying response object
The format of the stream (e.g. MP3 160k or MP3 96k)
Pauses the stream and sends the track paused event
Pauses the stream and sends the track play event
Stops the stream and sends the track end event
Creates a new Album instance with the specified uri, or in the case of multiple uris, creates an array of new Album instances.
Note that this function doesn't actually trigger a request to the server, and just creates an empty instance. Use track.get() to actually request data.
Returns the metadata for the Album
Creates a new Artist instance with the specified uri, or in the case of multiple uris, creates an array of new Artist instances.
Note that this function doesn't actually trigger a request to the server, and just creates an empty instance. Use track.get() to actually request data.
Returns the metadata for the Artist
Returns a RadioStation instance for the specified URI (Station ID)
Creates a new RadioStation given the Seed URIs and attributes