Source: index.js

/**
 * SongKick module
 * @module songkick-wrapper
 * @author Suhail Abood
 */
var request = require('request');
var urls = require('./songkick/urls');
var q = require('q');
/**
 * Creates a new SongKick instance
 * @constructor
 * @name SongKick
 * @param {string} KEY the SongKick API key 
 */
var SongKick = function(KEY){
	this.key = KEY;
};

function proxy(fn,ctx){
	var c = ctx || this;
	return function(){
		fn.apply(c,arguments);
	};
}

var sendRequest = function(url){
	var def = q.defer();
	request({url:url,json:true},function(err,response,body){
	
		if (!err && response.statusCode == 200){
			def.resolve(body);
			return;
		}
		def.reject('Network error has occured');
	});
	return def.promise;
}

function scs(e){
	if (e && e.resultsPage && e.resultsPage.results){
		return e.resultsPage;
	}
	return {};
}

function err(e){
	return e;
}

function functor(fn){
	var def = q.defer();
	if (fn){
		fn(def);
	}
	return def.promise;
}

SongKick.prototype = {
	/**
	 * Retrieves the detials of an event given its SongKick id. 
	 * @param {Number} id SongKick id of the event
	 * @param {String} [dataType] this can be either "json" or "xml" defaults to "json"
	 * @return {Promise} a promise which will be resolved or rejected depending on the result of the request. 
	 */
	getEventDetails:function(id,dataType){
		return sendRequest(urls.eventDetails(this.key,id,dataType))
			.then(scs,err);
	},
	/**
	 * Retrieves the upcoming events of an artist given his/her SongKick id. 
	 * @param {Number} id SongKick id of the artist
	 * @param {String} [dataType] can be either "json" or "xml" defaults to "json"
	 * @param {String} [createdAfter] a date to filter the results, this must be in this format "YYYY-MM-DDTHH:mm:iiZ" defaults to undefined
	 * @param {Number} [page] which page of the results to fetch, defaults to 0. 
	 * @param {String} [order] the order in which the results should be sorted this can be either "asc" or "desc". 
	 * @return {Promise} a promise which will be resolved or rejected depending on the result of the request. 
	 */
	getArtistUpcomingEvents:function(id,dataType,createdAfter,page,order){
		return sendRequest(urls.artistUpcoming(this.key,id,dataType,createdAfter,page,order))
			.then(scs,err);
	},
	/**
	 * Retrieves the upcoming events of an artist given his/her MusicBrainz id. 
	 * @param {Number} id MusicBrainz id of the artist
	 * @param {String} [dataType] can be either "json" or "xml" defaults to "json"
	 * @param {String} [createdAfter] a date to filter the results, this must be in this format "YYYY-MM-DDTHH:mm:iiZ" defaults to undefined
	 * @param {Number} [page] which page of the results to fetch, defaults to 0. 
	 * @param {String} [order] the order in which the results should be sorted this can be either "asc" or "desc". 
	 * @return {Promise} a promise which will be resolved or rejected depending on the result of the request. 
	 */
	getArtistUpcomingEventsUsingMusicBrainz:function(id,dataType,createdAfter,page,order){
		return sendRequest(urls.artistUpcomingMusicBrainz(this.key,id,dataType,createdAfter,page,order))
			.then(scs,err);
	},
	/**
	 * Retrieves a venue's upcoming events of given the venue's id. 
	 * @param {Number} id SongKick id of the venue
	 * @param {String} [dataType] can be either "json" or "xml" defaults to "json"
	 * @param {String} [createdAfter] a date to filter the results, this must be in this format "YYYY-MM-DDTHH:mm:iiZ" defaults to undefined
	 * @param {Number} [page] which page of the results to fetch, defaults to 0. 
	 * @param {String} [order] the order in which the results should be sorted this can be either "asc" or "desc". 
	 * @return {Promise} a promise which will be resolved or rejected depending on the result of the request. 
	 */
	getVenueUpcomingEvents:function(id,dataType,createdAfter,page,order){
		return sendRequest(urls.venueUpcoming(this.key,id,dataType,createdAfter,page,order))
			.then(scs,err);
	},
	/**
	 * Retrieves a metro area's upcoming events of given the merto area's id. 
	 * @param {Number} id SongKick id of the metro area
	 * @param {String} [dataType] can be either "json" or "xml" defaults to "json"
	 * @param {String} [createdAfter] a date to filter the results, this must be in this format "YYYY-MM-DDTHH:mm:iiZ" defaults to undefined
	 * @param {Number} [page] which page of the results to fetch, defaults to 0. 
	 * @param {String} [order] the order in which the results should be sorted this can be either "asc" or "desc". 
	 * @return {Promise} a promise which will be resolved or rejected depending on the result of the request. 
	 */
	getMetroAreaUpcomingEvents:function(id,dataType,createdAfter,page,order){
		return sendRequest(urls.metroAreaUpcoming(this.key,id,dataType,createdAfter,page,order))
			.then(scs,err);
	},
	/**
	 * Retrieves a user's upcoming events of given the user's id. 
	 * @param {Number} username SongKick username of the user
	 * @param {String} filter the data filter to use this can be either "attendance" or "tracked_artist"
	 * @param {String} [dataType] can be either "json" or "xml" defaults to "json"
	 * @param {String} [createdAfter] a date to filter the results, this must be in this format "YYYY-MM-DDTHH:mm:iiZ" defaults to undefined
	 * @param {Number} [page] which page of the results to fetch, defaults to 0. 
	 * @param {String} [order] the order in which the results should be sorted this can be either "asc" or "desc". 
	 * @return {Promise} a promise which will be resolved or rejected depending on the result of the request. 
	 */
	getUserUpcomingEvents:function(username,filter,dataType,createdAfter,page,order){
		return sendRequest(urls.userUpcoming(this.key,username,filter,dataType,createdAfter,page,order))
			.then(scs,err);
	},
	/**
	 * Retrieves a user's upcoming events attendance of a user. 
	 * @param {Number} username SongKick username of the user
	 * @param {String} [dataType] can be either "json" or "xml" defaults to "json"
	 * @param {String} [createdAfter] a date to filter the results, this must be in this format "YYYY-MM-DDTHH:mm:iiZ" defaults to undefined
	 * @param {Number} [page] which page of the results to fetch, defaults to 0. 
	 * @param {String} [order] the order in which the results should be sorted this can be either "asc" or "desc". 
	 * @return {Promise} a promise which will be resolved or rejected depending on the result of the request. 
	 */
	getUserUpcomingEventsAttendance:function(username,dataType,createdAfter,page,order){
		return sendRequest(urls.userUpcomingAttendance(this.key,username,dataType,createdAfter,page,order))
			.then(scs,err);
	},
	/**
	 * Retrieves a user's upcoming events of tracked artists of a user. 
	 * @param {Number} username SongKick username of the user
	 * @param {String} [dataType] can be either "json" or "xml" defaults to "json"
	 * @param {String} [createdAfter] a date to filter the results, this must be in this format "YYYY-MM-DDTHH:mm:iiZ" defaults to undefined
	 * @param {Number} [page] which page of the results to fetch, defaults to 0. 
	 * @param {String} [order] the order in which the results should be sorted this can be either "asc" or "desc". 
	 * @return {Promise} a promise which will be resolved or rejected depending on the result of the request. 
	 */
	getUserUpcomingTrackedArtist:function(username,dataType,createdAfter,page,order){
		return sendRequest(urls.userUpcomingTrackedArtist(this.key,username,dataType,createdAfter,page,order))
			.then(scs,err);
	},
	/**
	 * Retrieves a user's past events of tracked artists of a user. 
	 * @param {Number} username SongKick username of the user
	 * @param {String} [dataType] can be either "json" or "xml" defaults to "json"
	 * @param {String} [createdAfter] a date to filter the results, this must be in this format "YYYY-MM-DDTHH:mm:iiZ" defaults to undefined
	 * @param {Number} [page] which page of the results to fetch, defaults to 0. 
	 * @param {String} [order] the order in which the results should be sorted this can be either "asc" or "desc". 
	 * @return {Promise} a promise which will be resolved or rejected depending on the result of the request. 
	 */
	getUserPastEvents:function(username,dataType,page,order){
		return sendRequest(urls.userPastEvents(this.key,username,dataType,page,order))
			.then(scs,err);
	},
	/**
	 * Retrieves a user's events of tracked artists of a user. 
	 * @param {Number} username SongKick username of the user
	 * @param {String} [dataType] can be either "json" or "xml" defaults to "json"
	 * @param {String} [createdAfter] a date to filter the results, this must be in this format "YYYY-MM-DDTHH:mm:iiZ" defaults to undefined
	 * @param {Number} [page] which page of the results to fetch, defaults to 0. 
	 * @param {String} [order] the order in which the results should be sorted this can be either "asc" or "desc". 
	 * @return {Promise} a promise which will be resolved or rejected depending on the result of the request. 
	 */
	getUserEvents:function(username,dataType,createdAfter,page,order){
		return sendRequest(urls.userEvents(this.key,username,dataType,createdAfter,page,order))
			.then(scs,err);
	},
	/**
	 * Retrieves an artist's past events given the artist's id. 
	 * @param {Number} id SongKick id of the artist
	 * @param {String} [dataType] can be either "json" or "xml" defaults to "json"
	 * @param {String} [createdAfter] a date to filter the results, this must be in this format "YYYY-MM-DDTHH:mm:iiZ" defaults to undefined
	 * @param {Number} [page] which page of the results to fetch, defaults to 0. 
	 * @param {String} [order] the order in which the results should be sorted this can be either "asc" or "desc". 
	 * @return {Promise} a promise which will be resolved or rejected depending on the result of the request. 
	 */
	getArtistPastEvents:function(id,dataType,page,order){
		return sendRequest(urls.artistPastEvents(this.key,id,dataType,page,order))
			.then(scs,err);
	},
	/**
	 * Retrieves an artist's past events given the artist's MusicBrainz id. 
	 * @param {Number} id MusicBrainz id of the artist
	 * @param {String} [dataType] can be either "json" or "xml" defaults to "json"
	 * @param {String} [createdAfter] a date to filter the results, this must be in this format "YYYY-MM-DDTHH:mm:iiZ" defaults to undefined
	 * @param {Number} [page] which page of the results to fetch, defaults to 0. 
	 * @param {String} [order] the order in which the results should be sorted this can be either "asc" or "desc". 
	 * @return {Promise} a promise which will be resolved or rejected depending on the result of the request. 
	 */
	getArtistPastEventsUsingMusicBrainz:function(id,dataType,page,order){
		return sendRequest(urls.artistPastEventsMusicBrainz(this.key,id,dataType,page,order))
			.then(scs,err);	
	},
	/**
	 * Retrieves the details of a given venue given its id. 
	 * @param {Number} id SongKick id of the venue
	 * @param {String} [dataType] can be either "json" or "xml" defaults to "json"
	 * @param {String} [createdAfter] a date to filter the results, this must be in this format "YYYY-MM-DDTHH:mm:iiZ" defaults to undefined
	 * @param {Number} [page] which page of the results to fetch, defaults to 0. 
	 * @param {String} [order] the order in which the results should be sorted this can be either "asc" or "desc". 
	 * @return {Promise} a promise which will be resolved or rejected depending on the result of the request. 
	 */
	getVenueDetails:function(id,dataType){
		return sendRequest(urls.venueDetails(this.key,id,dataType))
			.then(scs,err);
	},
	/**
	 * Retrieves an event's set list given the venue's id. 
	 * @param {Number} id SongKick id of the venue
	 * @param {String} [dataType] can be either "json" or "xml" defaults to "json"
	 * @param {String} [createdAfter] a date to filter the results, this must be in this format "YYYY-MM-DDTHH:mm:iiZ" defaults to undefined
	 * @param {Number} [page] which page of the results to fetch, defaults to 0. 
	 * @param {String} [order] the order in which the results should be sorted this can be either "asc" or "desc". 
	 * @return {Promise} a promise which will be resolved or rejected depending on the result of the request. 
	 */
	getEventsSetList:function(id,dataType,page,order){
		return sendRequest(urls.eventSetList(this.key,id,dataType,page,order))
			.then(scs,err);
	},
	/**
	 * Retrieves a list of similar artists given an artist id. 
	 * @param {Number} id SongKick id of the artist
	 * @param {String} [dataType] can be either "json" or "xml" defaults to "json"
	 * @param {String} [createdAfter] a date to filter the results, this must be in this format "YYYY-MM-DDTHH:mm:iiZ" defaults to undefined
	 * @param {Number} [page] which page of the results to fetch, defaults to 0. 
	 * @param {String} [order] the order in which the results should be sorted this can be either "asc" or "desc". 
	 * @return {Promise} a promise which will be resolved or rejected depending on the result of the request. 
	 */
	getSimilarArtists:function(id,dataType){
		return sendRequest(urls.similarArtists(this.key,id,dataType))
			.then(scs,err);
	},

};

module.exports = {
	/**
	 * Factory method to create new SongKick instances
	 * @name module:songkick-wrapper.create
	 * @function
	 * @memberOf module:songkick-wrapper
	 * @param {string} key the SongKick API key 
	 * @return {SongKick} new {@link SongKick|SongKick} instance
	 */
	create:function(key){
		return new SongKick(key);
	},
	/**
	 * Access the mock plugin of the module 
	 * @name module:songkick-wrapper.mock
	 */
	mock:{
		/**
		 * @name module:songkick-wrapper.mock.setRequestFn
		 * @memberof module:songkick-wrapper.
		 * @instance
		 */
		setRequestFn:function(fn){
			sendRequest = fn;
		}
	}
};