diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a56a7ef --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules + diff --git a/README b/README index d1158b7..2cad7df 100644 --- a/README +++ b/README @@ -1,3 +1,15 @@ A Collaborative Rdio Jukebox -twtbox.com \ No newline at end of file +twtbox.com + +##Installation + +heroku create +heroku addons:add redistogo:nano +heroku config:add REDISTOGO_URL=redis://redistogo:password@redistogo.com:8000/ +heroku config:add HEROKU_URL=http://appname.herokuapp.com +heroku config:add RDIO_API_KEY=xxx +heroku config:add RDIO_API_SECRET=xxx +heroku config:add SESSION_SECRET=random_secret_string +git push heroku master +heroku open \ No newline at end of file diff --git a/app.js b/app.js index 8456db2..da20a1f 100644 --- a/app.js +++ b/app.js @@ -1,38 +1,48 @@ +// Description: +// None +// +// Configuration: +// REDISTOGO_URL +// HEROKU_URL +// RDIO_API_KEY +// RDIO_API_SECRET +// SESSION_SECRET +// + var express = require('express'); var sys = require('sys'); var io = require('socket.io'); var mixpanel = require('mixpanel'); var _ = require('underscore'); -var RedisStore = require('./my-connect-redis'); +var RedisStore = require('connect-redis')(express); var app = module.exports = express.createServer(express.logger()); -var domain, mp_client, redisHost, redisPort, redisPass; -app.configure('development', function(){ - redisHost = "filefish.redistogo.com"; - redisPort = 9734; - redisPass = ""; // TODO: add the redis config. Removed for security - domain = "http://localhost:3000"; +var domain, mp_client, hostname, rclient; + +var Redis = require('redis'); +var Url = require('url'); + +app.configure(function(){ + info = Url.parse(process.env.REDISTOGO_URL || 'redis://localhost:6379'); + rclient = Redis.createClient(info.port, info.hostname); + if(info.auth) { + rclient.auth(info.auth.split(":")[1]); + } + domain = process.env.HEROKU_URL || "http://localhost:3000"; + hostname = Url.parse(domain).hostname; +}); + +app.configure('development', function(){ mp_client = new mixpanel.Client("8c587841d6590b8d46ca00197d8339a0"); app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); }); app.configure('production', function(){ - redisHost = "carp.redistogo.com"; - redisPort = 9069; - redisPass = ""; // TODO: add the redis config. Removed for security - domain = "http://twtbox.com"; mp_client = new mixpanel.Client("f5b01baad731fa1f37a2fd7be9a1de44"); app.use(express.errorHandler()); }); -var redis = require('redis'); -var rclient = redis.createClient(redisPort, redisHost); -var dbAuth = function() { rclient.auth(redisPass); } -rclient.addListener('connected', dbAuth); -rclient.addListener('reconnected', dbAuth); -dbAuth(); - app.configure(function(){ app.set('views', __dirname + '/views'); app.set('view engine', 'jade'); @@ -40,7 +50,7 @@ app.configure(function(){ app.use(express.methodOverride()); app.use(express.compiler({ src: __dirname + '/public', enable: ['less'] })); app.use(express.cookieParser()); - app.use(express.session({ store: new RedisStore({port: redisPort, host: redisHost, password: redisPass}), secret: '' })); // TODO: Add secret, removed for security + app.use(express.session({ store: new RedisStore({client: rclient}), secret: process.env.SESSION_SECRET })); app.use(app.router); app.use(express.static(__dirname + '/public')); }); @@ -52,7 +62,7 @@ app.dynamicHelpers({ var socket = io.listen(app); var OAuth = require('./oauth').OAuth; var oa = new OAuth("http://api.rdio.com/oauth/request_token", "http://api.rdio.com/oauth/access_token", - "", "", // TODO: Add the rdio oauth tokens. Removed for security + process.env.RDIO_API_KEY, process.env.RDIO_API_SECRET, "1.0", domain + "/callback", "HMAC-SHA1"); var rdioEndpoint = "http://api.rdio.com/1/"; @@ -148,7 +158,7 @@ app.get("/topsongs.json", adminRequired, function(req, res, next) { // admin view of room app.get('/r/:room', adminRequired, function(req, res, next) { oa.post(rdioEndpoint, req.session.oauth_access_token, req.session.oauth_access_token_secret, - { "method" : "getPlaybackToken", "domain" : "twtbox.com" }, function (error, data) { + { "method" : "getPlaybackToken", "domain" : hostname }, function (error, data) { var playbackToken = domain == "http://localhost:3000" ? "GAlNi78J_____zlyYWs5ZG02N2pkaHlhcWsyOWJtYjkyN2xvY2FsaG9zdEbwl7EHvbylWSWFWYMZwfc=" : JSON.parse(data)["result"]; var renderRoom = function(res, song, offset, playbackToken, domain) { diff --git a/my-connect-redis.js b/my-connect-redis.js deleted file mode 100644 index 8e3217b..0000000 --- a/my-connect-redis.js +++ /dev/null @@ -1,120 +0,0 @@ - -/*! - * Connect - Redis - * Copyright(c) 2010 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var Store = require('connect').session.Store - , redis = require('redis'); - -/** - * One day in seconds. - */ - -var oneDay = 86400; - -/** - * Initialize RedisStore with the given `options`. - * - * @param {Object} options - * @api public - */ - -var RedisStore = module.exports = function RedisStore(options) { - options = options || {}; - Store.call(this, options); - - this.client = redis.createClient(options.port, options.host); - var dbAuth = function(client) { client.auth(options.password); } - this.client.addListener('connected', dbAuth); - this.client.addListener('reconnected', dbAuth); - dbAuth(this.client); - -}; - -/** - * Inherit from `Store`. - */ - -RedisStore.prototype.__proto__ = Store.prototype; - -/** - * Attempt to fetch session by the given `sid`. - * - * @param {String} sid - * @param {Function} fn - * @api public - */ - -RedisStore.prototype.get = function(sid, fn){ - this.client.get(sid, function(err, data){ - try { - if (!data) return fn(); - fn(null, JSON.parse(data.toString())); - } catch (err) { - fn(err); - } - }); -}; - -/** - * Commit the given `sess` object associated with the given `sid`. - * - * @param {String} sid - * @param {Session} sess - * @param {Function} fn - * @api public - */ - -RedisStore.prototype.set = function(sid, sess, fn){ - try { - var maxAge = sess.cookie.maxAge - , ttl = 'number' == typeof maxAge - ? maxAge / 1000 | 0 - : oneDay - , sess = JSON.stringify(sess); - this.client.setex(sid, ttl, sess, function(){ - fn && fn.apply(this, arguments); - }); - } catch (err) { - fn && fn(err); - } -}; - -/** - * Destroy the session associated with the given `sid`. - * - * @param {String} sid - * @api public - */ - -RedisStore.prototype.destroy = function(sid, fn){ - this.client.del(sid, fn); -}; - -/** - * Fetch number of sessions. - * - * @param {Function} fn - * @api public - */ - -RedisStore.prototype.length = function(fn){ - this.client.dbsize(fn); -}; - -/** - * Clear all sessions. - * - * @param {Function} fn - * @api public - */ - -RedisStore.prototype.clear = function(fn){ - this.client.flushdb(fn); -}; \ No newline at end of file diff --git a/package.json b/package.json index 3b0bb94..108084b 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "redis":"0.5.7", "socket.io":"0.9.0", "mixpanel":"0.0.3", - "underscore":"1.1.6" + "underscore":"1.1.6", + "connect-redis":"1.4.0" } }