|
|
'use strict';
|
|
|
|
|
|
var MediaModel = require('./models/mediaModel.js'),
|
|
|
PlayModel = require('./models/playModel.js');
|
|
|
|
|
|
var DubAPIError = require('./errors/error.js'),
|
|
|
DubAPIRequestError = require('./errors/requestError.js');
|
|
|
|
|
|
var endpoints = require('./data/endpoints.js'),
|
|
|
events = require('./data/events.js'),
|
|
|
utils = require('./utils.js');
|
|
|
|
|
|
var mediaCache = {};
|
|
|
|
|
|
function ActionHandler(dubAPI, auth) {
|
|
|
this.doLogin = doLogin.bind(dubAPI, auth);
|
|
|
this.clearPlay = clearPlay.bind(dubAPI);
|
|
|
this.updatePlay = updatePlay.bind(dubAPI);
|
|
|
this.updateQueue = updateQueue.bind(dubAPI);
|
|
|
this.updateQueueDebounce = utils.debounce(this.updateQueue, 5000);
|
|
|
}
|
|
|
|
|
|
function doLogin(auth, callback) {
|
|
|
var that = this;
|
|
|
|
|
|
this._.reqHandler.send({method: 'POST', url: endpoints.authDubtrack, form: auth}, function(code, body) {
|
|
|
if ([200, 400].indexOf(code) === -1) {
|
|
|
return callback(new DubAPIRequestError(code, that._.reqHandler.endpoint(endpoints.authDubtrack)));
|
|
|
} else if (code === 400) {
|
|
|
return callback(new DubAPIError('Authentication Failed: ' + body.data.details.message));
|
|
|
}
|
|
|
|
|
|
callback(undefined);
|
|
|
});
|
|
|
}
|
|
|
|
|
|
function clearPlay() {
|
|
|
clearTimeout(this._.room.playTimeout);
|
|
|
|
|
|
var message = {type: events.roomPlaylistUpdate};
|
|
|
|
|
|
if (this._.room.play) {
|
|
|
message.lastPlay = {
|
|
|
id: this._.room.play.id,
|
|
|
media: utils.clone(this._.room.play.media),
|
|
|
user: utils.clone(this._.room.users.findWhere({id: this._.room.play.user})),
|
|
|
score: this._.room.play.getScore()
|
|
|
};
|
|
|
}
|
|
|
|
|
|
this._.room.play = undefined;
|
|
|
this._.room.users.set({dub: undefined});
|
|
|
|
|
|
this.emit('*', message);
|
|
|
this.emit(events.roomPlaylistUpdate, message);
|
|
|
}
|
|
|
|
|
|
function updatePlay() {
|
|
|
var that = this;
|
|
|
|
|
|
clearTimeout(that._.room.playTimeout);
|
|
|
|
|
|
that._.reqHandler.queue({method: 'GET', url: endpoints.roomPlaylistActive}, function(code, body) {
|
|
|
if ([200, 404].indexOf(code) === -1) {
|
|
|
that.emit('error', new DubAPIRequestError(code, that._.reqHandler.endpoint(endpoints.roomPlaylistActive)));
|
|
|
return;
|
|
|
} else if (code === 404) {
|
|
|
that._.actHandler.clearPlay();
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (body.data.song === undefined) {
|
|
|
|
|
|
|
|
|
that._.room.playTimeout = setTimeout(that._.actHandler.updatePlay, 30000);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
var message = {type: events.roomPlaylistUpdate},
|
|
|
newPlay = new PlayModel(body.data.song),
|
|
|
curPlay = that._.room.play;
|
|
|
|
|
|
if (curPlay && newPlay.id === curPlay.id) {
|
|
|
if (Date.now() - newPlay.played > newPlay.songLength) that._.actHandler.clearPlay();
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
|
|
|
if (body.data.songInfo != null) {
|
|
|
newPlay.media = new MediaModel(body.data.songInfo);
|
|
|
|
|
|
if (newPlay.media.type === undefined || newPlay.media.fkid === undefined) {
|
|
|
newPlay.media = undefined;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
message.raw = body.data;
|
|
|
|
|
|
if (that._.room.play) {
|
|
|
message.lastPlay = {
|
|
|
id: curPlay.id,
|
|
|
media: utils.clone(curPlay.media),
|
|
|
user: utils.clone(that._.room.users.findWhere({id: curPlay.user})),
|
|
|
score: curPlay.getScore()
|
|
|
};
|
|
|
}
|
|
|
|
|
|
message.id = newPlay.id;
|
|
|
message.media = utils.clone(newPlay.media);
|
|
|
message.user = utils.clone(that._.room.users.findWhere({id: newPlay.user}));
|
|
|
|
|
|
that._.reqHandler.queue({method: 'GET', url: endpoints.roomPlaylistActiveDubs}, function(code, body) {
|
|
|
that._.room.play = newPlay;
|
|
|
that._.room.playTimeout = setTimeout(that._.actHandler.updatePlay, newPlay.getTimeRemaining() + 15000);
|
|
|
|
|
|
that._.room.users.set({dub: undefined});
|
|
|
|
|
|
if (code === 200) {
|
|
|
body.data.currentSong = new PlayModel(body.data.currentSong);
|
|
|
|
|
|
if (newPlay.id === body.data.currentSong.id) {
|
|
|
newPlay.updubs = body.data.currentSong.updubs;
|
|
|
newPlay.downdubs = body.data.currentSong.downdubs;
|
|
|
newPlay.grabs = body.data.currentSong.grabs;
|
|
|
|
|
|
body.data.upDubs.forEach(function(dub) {
|
|
|
newPlay.dubs[dub.userid] = 'updub';
|
|
|
|
|
|
var user = that._.room.users.findWhere({id: dub.userid});
|
|
|
if (user) user.set({dub: 'updub'});
|
|
|
});
|
|
|
|
|
|
body.data.downDubs.forEach(function(dub) {
|
|
|
newPlay.dubs[dub.userid] = 'downdub';
|
|
|
|
|
|
var user = that._.room.users.findWhere({id: dub.userid});
|
|
|
if (user) user.set({dub: 'downdub'});
|
|
|
});
|
|
|
}
|
|
|
} else {
|
|
|
that.emit('error', new DubAPIRequestError(code, that._.reqHandler.endpoint(endpoints.roomPlaylistActiveDubs)));
|
|
|
}
|
|
|
|
|
|
that.emit('*', message);
|
|
|
that.emit(events.roomPlaylistUpdate, message);
|
|
|
});
|
|
|
});
|
|
|
}
|
|
|
|
|
|
function updateQueue() {
|
|
|
var that = this;
|
|
|
|
|
|
that._.reqHandler.queue({method: 'GET', url: endpoints.roomPlaylistDetails}, function(code, body) {
|
|
|
if (code !== 200) {
|
|
|
that.emit('error', new DubAPIRequestError(code, that._.reqHandler.endpoint(endpoints.roomPlaylistDetails)));
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
var promises = body.data.reduce(function(promises, queueItem) {
|
|
|
if (queueItem === null) return promises;
|
|
|
|
|
|
if (mediaCache[queueItem.songid]) {
|
|
|
mediaCache[queueItem.songid].ts = Date.now();
|
|
|
return promises;
|
|
|
}
|
|
|
|
|
|
promises.push(new Promise(function(resolve, reject) {
|
|
|
that._.reqHandler.send({method: 'GET', url: endpoints.song.replace('%SONGID%', queueItem.songid)}, function(code, body) {
|
|
|
if (code !== 200) {
|
|
|
that.emit('error', new DubAPIRequestError(code, that._.reqHandler.endpoint(endpoints.song.replace('%SONGID%', queueItem.songid))));
|
|
|
|
|
|
|
|
|
return resolve();
|
|
|
}
|
|
|
|
|
|
mediaCache[queueItem.songid] = {media: new MediaModel(body.data), ts: Date.now()};
|
|
|
|
|
|
return resolve();
|
|
|
});
|
|
|
}));
|
|
|
|
|
|
return promises;
|
|
|
}, []);
|
|
|
|
|
|
Promise.all(promises).then(function() {
|
|
|
var message = {type: events.roomPlaylistQueueUpdate};
|
|
|
|
|
|
that._.room.queue.clear();
|
|
|
|
|
|
body.data.forEach(function(queueItem) {
|
|
|
|
|
|
if (queueItem === null) return;
|
|
|
|
|
|
queueItem = {
|
|
|
id: queueItem._id,
|
|
|
uid: queueItem._user._id,
|
|
|
media: mediaCache[queueItem.songid] ? mediaCache[queueItem.songid].media : undefined,
|
|
|
get user() {return that._.room.users.findWhere({id: this.uid});}
|
|
|
};
|
|
|
|
|
|
that._.room.queue.add(queueItem);
|
|
|
});
|
|
|
|
|
|
message.raw = body.data;
|
|
|
message.queue = utils.clone(that._.room.queue, {deep: true});
|
|
|
|
|
|
that.emit('*', message);
|
|
|
that.emit(events.roomPlaylistQueueUpdate, message);
|
|
|
});
|
|
|
|
|
|
setImmediate(function() {
|
|
|
for (var key in mediaCache) {
|
|
|
if (mediaCache.hasOwnProperty(key) && Date.now() - mediaCache[key].ts > 900000) delete mediaCache[key];
|
|
|
}
|
|
|
});
|
|
|
});
|
|
|
}
|
|
|
|
|
|
module.exports = ActionHandler;
|
|
|
|