Permalink
Browse files

add Album and Artist classes, cache the "get()" results

  • Loading branch information...
TooTallNate committed Jan 20, 2013
1 parent 22c99b0 commit 77a93abef9aa56f12e1e31d5731f1b1ef8c1ff80
Showing with 122 additions and 5 deletions.
  1. +55 −0 lib/album.js
  2. +55 −0 lib/artist.js
  3. +6 −4 lib/spotify.js
  4. +6 −1 lib/track.js
View
@@ -0,0 +1,55 @@
+
+/**
+ * Module dependencies.
+ */
+
+var util = require('./util');
+var Album = require('./schemas').metadata['spotify.metadata.proto.Album'];
+var debug = require('debug')('spotify-web:album');
+
+/**
+ * Module exports.
+ */
+
+exports = module.exports = Album;
+
+/**
+ * Album URI getter.
+ */
+
+Object.defineProperty(Album.prototype, 'uri', {
+ get: function () {
+ return util.gid2uri('album', this.gid);
+ },
+ enumerable: true,
+ configurable: true
+});
+
+/**
+ * Loads all the metadata for this Album instance. Useful for when you get an only
+ * partially filled Album instance from an Album instance for example.
+ *
+ * @param {Function} fn callback function
+ * @api public
+ */
+
+Album.prototype.get =
+Album.prototype.metadata = function (fn) {
+ if (this._loaded) {
+ // already been loaded...
+ debug('album already loaded');
+ return process.nextTick(fn.bind(null, null, this));
+ }
+ var spotify = this._spotify;
+ var self = this;
+ spotify.get(this.uri, function (err, album) {
+ if (err) return fn(err);
+ // extend this Album instance with the new one's properties
+ Object.keys(album).forEach(function (key) {
+ if (!self.hasOwnProperty(key)) {
+ self[key] = album[key];
+ }
+ });
+ fn(null, self);
+ });
+};
View
@@ -0,0 +1,55 @@
+
+/**
+ * Module dependencies.
+ */
+
+var util = require('./util');
+var Artist = require('./schemas').metadata['spotify.metadata.proto.Artist'];
+var debug = require('debug')('spotify-web:artist');
+
+/**
+ * Module exports.
+ */
+
+exports = module.exports = Artist;
+
+/**
+ * Artist URI getter.
+ */
+
+Object.defineProperty(Artist.prototype, 'uri', {
+ get: function () {
+ return util.gid2uri('artist', this.gid);
+ },
+ enumerable: true,
+ configurable: true
+});
+
+/**
+ * Loads all the metadata for this Artist instance. Useful for when you get an only
+ * partially filled Artist instance from an Album instance for example.
+ *
+ * @param {Function} fn callback function
+ * @api public
+ */
+
+Artist.prototype.get =
+Artist.prototype.metadata = function (fn) {
+ if (this._loaded) {
+ // already been loaded...
+ debug('artist already loaded');
+ return process.nextTick(fn.bind(null, null, this));
+ }
+ var spotify = this._spotify;
+ var self = this;
+ spotify.get(this.uri, function (err, artist) {
+ if (err) return fn(err);
+ // extend this Artist instance with the new one's properties
+ Object.keys(artist).forEach(function (key) {
+ if (!self.hasOwnProperty(key)) {
+ self[key] = artist[key];
+ }
+ });
+ fn(null, self);
+ });
+};
View
@@ -29,9 +29,8 @@ var MercuryMultiGetReply = mercury['spotify.mercury.proto.MercuryMultiGetReply']
var MercuryRequest = mercury['spotify.mercury.proto.MercuryRequest'];
var MercuryReply = mercury['spotify.mercury.proto.MercuryReply'];
-var metadata = schemas.metadata;
-var Artist = metadata['spotify.metadata.proto.Artist'];
-var Album = metadata['spotify.metadata.proto.Album'];
+var Artist = require('./artist');
+var Album = require('./album');
var Track = require('./track');
var Image = require('./image');
@@ -274,6 +273,7 @@ Spotify.prototype._onmessage = function (data) {
debug('WebSocket "message" event: %s', data);
var msg = JSON.parse(data);
if ('error' in msg) {
+ // { error: [ 14, 429, '' ], id: 273 }
console.error(msg);
throw new Error('TODO: implement!');
} else if ('message' in msg) {
@@ -456,7 +456,9 @@ Spotify.prototype.metadata = function (uris, fn) {
} else {
throw new Error('Unrecognised metadata type: ' + type);
}
- return self._parse(parser, new Buffer(body, 'base64'));
+ var item = self._parse(parser, new Buffer(body, 'base64'));
+ item._loaded = true;
+ return item;
}
};
View
@@ -39,9 +39,14 @@ Object.defineProperty(Track.prototype, 'uri', {
Track.prototype.get =
Track.prototype.metadata = function (fn) {
+ if (this._loaded) {
+ // already been loaded...
+ debug('track already loaded');
+ return process.nextTick(fn.bind(null, null, this));
+ }
var spotify = this._spotify;
var self = this;
- spotify.metadata(this.uri, function (err, track) {
+ spotify.get(this.uri, function (err, track) {
if (err) return fn(err);
// extend this Track instance with the new one's properties
Object.keys(track).forEach(function (key) {

0 comments on commit 77a93ab

Please sign in to comment.