Skip to content

Instantly share code, notes, and snippets.

@romainhuet
Created November 28, 2012 15:17
Show Gist options
  • Save romainhuet/4161906 to your computer and use it in GitHub Desktop.
Save romainhuet/4161906 to your computer and use it in GitHub Desktop.
SoundCloud Module for Jolicloud as presented at Node Dublin (refactoring in progress for the coming Jolicloud Open Platform)
/**
* Jolicloud SoundCloud Module
*/
var _ = require('underscore'),
Item = require('jolicloud-module').Item,
SoundCloud = require('./soundcloud');
// Create a Jolicloud item from a SoundCloud track.
function mapTrack(track) {
// Initialize Jolicloud Item.
var item = new Item({
kind : 'music',
url : track.permalink_url,
source : track.permalink_url,
id : track.id,
name : track.title,
description : track.description,
date : new Date(track.created_at)
});
// Item images.
var thumbnail = track.artwork_url || track.user.avatar_url || '';
item.set('images', {
thumbnail : thumbnail,
preview : thumbnail.replace('-large', '-t300x300'),
original : thumbnail.replace('-large', '-t500x500')
});
// Item author.
item.set('author', {
name : track.user.username,
url : track.user.permalink_url,
picture : track.user.avatar_url
});
// Embeded representation of the item.
var embedUrl = track.secret_uri ? track.secret_uri + '&secret_url=true': track.uri;
embedUrl += '&auto_play=true&show_artwork=true&color=4DC3DD';
item.set('embed', '<iframe width="100%" height="166" scrolling="no" frameborder="no" '+
'src="http://w.soundcloud.com/player/?url=' + encodeURIComponent(embedUrl) + '"></iframe>');
return item;
}
/**
* Browse SoundCloud contents.
*/
exports.browse = function(id, options, callback) {
var soundcloud = new SoundCloud(options);
if (!id || id === '/') {
// Main structure.
var response = [
new Item({
id : 'stream',
name : 'Stream',
kind : 'folder',
'default': true
}),
new Item({
id : 'tracks',
name : 'My Tracks',
kind : 'folder'
}),
new Item({
id : 'favorites',
name : 'Favorites',
kind : 'folder'
})
];
callback(null, response);
} else if (id === 'stream') {
// User's incoming tracks from people he follows.
soundcloud.getIncoming({ offset: options.next }, function(err, activities, paginationNext) {
if (err) return callback(err);
var items = _.map(activities, mapTrack);
callback(null, items, paginationNext);
});
} else if (id === 'tracks') {
// User's tracks.
soundcloud.getTracks({ offset: options.next }, function(err, tracks, paginationNext) {
if (err) return callback(err);
var items = _.map(tracks, mapTrack);
callback(null, items, paginationNext);
});
} else if (id === 'favorites') {
// Favorite tracks.
soundcloud.getFavorites({ offset: options.next }, function(err, tracks, paginationNext) {
if (err) return callback(err);
var items = _.map(tracks, mapTrack);
callback(null, items, paginationNext);
});
} else {
callback('No match on path.');
}
};
/**
* Link SoundCloud to Jolicloud.
*/
exports.link = function(options, callback) {
var userConvertor = function(soundcloudUser, cb) {
cb(null, {
id: soundcloudUser.id,
handle: soundcloudUser.username
});
};
var authorizeUrlParams = {
scope: 'non-expiring'
};
var soundcloud = new SoundCloud(options);
soundcloud.consumer.link(authorizeUrlParams, userConvertor, options, callback);
};
{
"name": "jolicloud-soundcloud",
"version": "0.0.1",
"description": "Jolicloud SoundCloud Module",
"author": "Jolicloud",
"homepage": "http://www.jolicloud.com/",
"engines": {
"node": ">=0.6.0"
},
"directories": {
"lib": "lib"
},
"dependencies": {
"jolicloud-module": ">=0.1.0",
"underscore": ">=1.2.0"
},
"main": "lib/jolicloud-soundcloud.js"
}
/**
* SoundCloud API Client.
*/
var OAuth2 = require('jolicloud-module').OAuth2;
/**
* SoundCloud API Client.
*/
function SoundCloud(config) {
if (!(this instanceof SoundCloud)) return new SoundCloud(config);
// Configure OAuth 2 consumer.
this.consumer = new OAuth2(config, // Client & user credentials
'https://soundcloud.com/connect', // Authorize URL
'https://api.soundcloud.com/oauth2/token'); // Access token URL
// SoundCloud specifics.
this.consumer.setAccessTokenName('oauth_token');
}
module.exports = SoundCloud;
SoundCloud.prototype.getSelf = function(options, callback) {
this.request('/me.json', {}, callback);
};
/**
* Get the user's tracks.
*/
SoundCloud.prototype.getTracks = function(options, callback) {
this.request('/me/tracks.json?&limit=&offset=', options, callback);
};
/**
* Get the favorited tracks.
*/
SoundCloud.prototype.getFavorites = function(options, callback) {
this.request('/me/favorites.json?order=favorited_at&limit=&offset=', options, callback);
};
/**
* Get the incoming tracks (activities).
*/
SoundCloud.prototype.getIncoming = function(options, callback) {
this.request('/me/activities/tracks/affiliated.json?&limit=&cursor=', options, callback, true);
};
/**
* Get the tracks at a resource URL. Handles pagination.
*/
SoundCloud.prototype.request = function(resource, options, callback) {
options = options || {};
// Pagination
var offset = options.offset || 0;
var cursor = options.offset || '';
var limit = options.limit || 20;
// Final request URL.
var url = 'https://api.soundcloud.com' + resource.replace('&limit=', '&limit=' + limit).replace('&offset=', '&offset=' + offset).replace('&cursor=', '&cursor=' + cursor);
this.consumer.get(url, function(error, result, response) {
var data;
var newOffset;
if (!error) {
try {
data = JSON.parse(result);
if (data.collection) {
// It's an activity feed.
newOffset = data.next_href && (data.collection.length < limit ? null : data.next_href.replace(/^.*[?&]cursor=([^&]*).*$/, '$1'));
data = data.collection;
} else if (data instanceof Array) {
// It's an array of tracks.
newOffset = data.length < limit ? null : parseInt(offset, 10) + parseInt(limit, 10);
}
} catch (e) {
error = e.message;
}
}
callback(error, data, newOffset);
});
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment