|
@@ -5,15 +5,18 @@ const async = require('async'),
|
|
config = require('config'),
|
|
config = require('config'),
|
|
_ = require('underscore')._;
|
|
_ = require('underscore')._;
|
|
|
|
|
|
-const io = require('../io');
|
|
|
|
-const db = require('../db');
|
|
|
|
-const cache = require('../cache');
|
|
|
|
-const notifications = require('../notifications');
|
|
|
|
-const utils = require('../utils');
|
|
|
|
-const logger = require('../logger');
|
|
|
|
-const stations = require('../stations');
|
|
|
|
-const songs = require('../songs');
|
|
|
|
const hooks = require('./hooks');
|
|
const hooks = require('./hooks');
|
|
|
|
+
|
|
|
|
+const moduleManager = require("../../index");
|
|
|
|
+
|
|
|
|
+const db = moduleManager.modules["db"];
|
|
|
|
+const cache = moduleManager.modules["cache"];
|
|
|
|
+const notifications = moduleManager.modules["notifications"];
|
|
|
|
+const utils = moduleManager.modules["utils"];
|
|
|
|
+const logger = moduleManager.modules["logger"];
|
|
|
|
+const stations = moduleManager.modules["stations"];
|
|
|
|
+const songs = moduleManager.modules["songs"];
|
|
|
|
+
|
|
let userList = {};
|
|
let userList = {};
|
|
let usersPerStation = {};
|
|
let usersPerStation = {};
|
|
let usersPerStationCount = {};
|
|
let usersPerStationCount = {};
|
|
@@ -29,39 +32,40 @@ setInterval(() => {
|
|
usersPerStationCount = {};
|
|
usersPerStationCount = {};
|
|
|
|
|
|
async.each(Object.keys(userList), function(socketId, next) {
|
|
async.each(Object.keys(userList), function(socketId, next) {
|
|
- let socket = utils.socketFromSession(socketId);
|
|
|
|
- let stationId = userList[socketId];
|
|
|
|
- if (!socket || Object.keys(socket.rooms).indexOf(`station.${stationId}`) === -1) {
|
|
|
|
- if (stationsCountUpdated.indexOf(stationId) === -1) stationsCountUpdated.push(stationId);
|
|
|
|
- if (stationsUpdated.indexOf(stationId) === -1) stationsUpdated.push(stationId);
|
|
|
|
- delete userList[socketId];
|
|
|
|
- return next();
|
|
|
|
- }
|
|
|
|
- if (!usersPerStationCount[stationId]) usersPerStationCount[stationId] = 0;
|
|
|
|
- usersPerStationCount[stationId]++;
|
|
|
|
- if (!usersPerStation[stationId]) usersPerStation[stationId] = [];
|
|
|
|
-
|
|
|
|
- async.waterfall([
|
|
|
|
- (next) => {
|
|
|
|
- if (!socket.session || !socket.session.sessionId) return next('No session found.');
|
|
|
|
- cache.hget('sessions', socket.session.sessionId, next);
|
|
|
|
- },
|
|
|
|
-
|
|
|
|
- (session, next) => {
|
|
|
|
- if (!session) return next('Session not found.');
|
|
|
|
- db.models.user.findOne({_id: session.userId}, next);
|
|
|
|
- },
|
|
|
|
-
|
|
|
|
- (user, next) => {
|
|
|
|
- if (!user) return next('User not found.');
|
|
|
|
- if (usersPerStation[stationId].indexOf(user.username) !== -1) return next('User already in the list.');
|
|
|
|
- next(null, user.username);
|
|
|
|
- }
|
|
|
|
- ], (err, username) => {
|
|
|
|
- if (!err) {
|
|
|
|
- usersPerStation[stationId].push(username);
|
|
|
|
|
|
+ utils.socketFromSession(socketId).then((socket) => {
|
|
|
|
+ let stationId = userList[socketId];
|
|
|
|
+ if (!socket || Object.keys(socket.rooms).indexOf(`station.${stationId}`) === -1) {
|
|
|
|
+ if (stationsCountUpdated.indexOf(stationId) === -1) stationsCountUpdated.push(stationId);
|
|
|
|
+ if (stationsUpdated.indexOf(stationId) === -1) stationsUpdated.push(stationId);
|
|
|
|
+ delete userList[socketId];
|
|
|
|
+ return next();
|
|
}
|
|
}
|
|
- next();
|
|
|
|
|
|
+ if (!usersPerStationCount[stationId]) usersPerStationCount[stationId] = 0;
|
|
|
|
+ usersPerStationCount[stationId]++;
|
|
|
|
+ if (!usersPerStation[stationId]) usersPerStation[stationId] = [];
|
|
|
|
+
|
|
|
|
+ async.waterfall([
|
|
|
|
+ (next) => {
|
|
|
|
+ if (!socket.session || !socket.session.sessionId) return next('No session found.');
|
|
|
|
+ cache.hget('sessions', socket.session.sessionId, next);
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ (session, next) => {
|
|
|
|
+ if (!session) return next('Session not found.');
|
|
|
|
+ db.models.user.findOne({_id: session.userId}, next);
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ (user, next) => {
|
|
|
|
+ if (!user) return next('User not found.');
|
|
|
|
+ if (usersPerStation[stationId].indexOf(user.username) !== -1) return next('User already in the list.');
|
|
|
|
+ next(null, user.username);
|
|
|
|
+ }
|
|
|
|
+ ], (err, username) => {
|
|
|
|
+ if (!err) {
|
|
|
|
+ usersPerStation[stationId].push(username);
|
|
|
|
+ }
|
|
|
|
+ next();
|
|
|
|
+ });
|
|
});
|
|
});
|
|
//TODO Code to show users
|
|
//TODO Code to show users
|
|
}, (err) => {
|
|
}, (err) => {
|
|
@@ -78,12 +82,12 @@ setInterval(() => {
|
|
}
|
|
}
|
|
|
|
|
|
stationsCountUpdated.forEach((stationId) => {
|
|
stationsCountUpdated.forEach((stationId) => {
|
|
- console.log("Updating count of ", stationId);
|
|
|
|
|
|
+ //logger.info("UPDATE_STATION_USER_COUNT", `Updating user count of ${stationId}.`);
|
|
cache.pub('station.updateUserCount', stationId);
|
|
cache.pub('station.updateUserCount', stationId);
|
|
});
|
|
});
|
|
|
|
|
|
stationsUpdated.forEach((stationId) => {
|
|
stationsUpdated.forEach((stationId) => {
|
|
- console.log("Updating ", stationId);
|
|
|
|
|
|
+ //logger.info("UPDATE_STATION_USER_LIST", `Updating user list of ${stationId}.`);
|
|
cache.pub('station.updateUsers', stationId);
|
|
cache.pub('station.updateUsers', stationId);
|
|
});
|
|
});
|
|
|
|
|
|
@@ -99,10 +103,10 @@ cache.sub('station.updateUsers', stationId => {
|
|
cache.sub('station.updateUserCount', stationId => {
|
|
cache.sub('station.updateUserCount', stationId => {
|
|
let count = usersPerStationCount[stationId] || 0;
|
|
let count = usersPerStationCount[stationId] || 0;
|
|
utils.emitToRoom(`station.${stationId}`, "event:userCount.updated", count);
|
|
utils.emitToRoom(`station.${stationId}`, "event:userCount.updated", count);
|
|
- stations.getStation(stationId, (err, station) => {
|
|
|
|
|
|
+ stations.getStation(stationId, async (err, station) => {
|
|
if (station.privacy === 'public') utils.emitToRoom('home', "event:userCount.updated", stationId, count);
|
|
if (station.privacy === 'public') utils.emitToRoom('home', "event:userCount.updated", stationId, count);
|
|
else {
|
|
else {
|
|
- let sockets = utils.getRoomSockets('home');
|
|
|
|
|
|
+ let sockets = await utils.getRoomSockets('home');
|
|
for (let socketId in sockets) {
|
|
for (let socketId in sockets) {
|
|
let socket = sockets[socketId];
|
|
let socket = sockets[socketId];
|
|
let session = sockets[socketId].session;
|
|
let session = sockets[socketId].session;
|
|
@@ -121,6 +125,10 @@ cache.sub('station.updateUserCount', stationId => {
|
|
})
|
|
})
|
|
});
|
|
});
|
|
|
|
|
|
|
|
+cache.sub('station.queueLockToggled', data => {
|
|
|
|
+ utils.emitToRoom(`station.${data.stationId}`, "event:queueLockToggled", data.locked)
|
|
|
|
+});
|
|
|
|
+
|
|
cache.sub('station.updatePartyMode', data => {
|
|
cache.sub('station.updatePartyMode', data => {
|
|
utils.emitToRoom(`station.${data.stationId}`, "event:partyMode.updated", data.partyMode);
|
|
utils.emitToRoom(`station.${data.stationId}`, "event:partyMode.updated", data.partyMode);
|
|
});
|
|
});
|
|
@@ -130,7 +138,9 @@ cache.sub('privatePlaylist.selected', data => {
|
|
});
|
|
});
|
|
|
|
|
|
cache.sub('station.pause', stationId => {
|
|
cache.sub('station.pause', stationId => {
|
|
- utils.emitToRoom(`station.${stationId}`, "event:stations.pause");
|
|
|
|
|
|
+ stations.getStation(stationId, (err, station) => {
|
|
|
|
+ utils.emitToRoom(`station.${stationId}`, "event:stations.pause", { pausedAt: station.pausedAt });
|
|
|
|
+ });
|
|
});
|
|
});
|
|
|
|
|
|
cache.sub('station.resume', stationId => {
|
|
cache.sub('station.resume', stationId => {
|
|
@@ -150,18 +160,19 @@ cache.sub('station.voteSkipSong', stationId => {
|
|
});
|
|
});
|
|
|
|
|
|
cache.sub('station.remove', stationId => {
|
|
cache.sub('station.remove', stationId => {
|
|
|
|
+ utils.emitToRoom(`station.${stationId}`, 'event:stations.remove');
|
|
utils.emitToRoom('admin.stations', 'event:admin.station.removed', stationId);
|
|
utils.emitToRoom('admin.stations', 'event:admin.station.removed', stationId);
|
|
});
|
|
});
|
|
|
|
|
|
cache.sub('station.create', stationId => {
|
|
cache.sub('station.create', stationId => {
|
|
- stations.initializeStation(stationId, (err, station) => {
|
|
|
|
|
|
+ stations.initializeStation(stationId, async (err, station) => {
|
|
station.userCount = usersPerStationCount[stationId] || 0;
|
|
station.userCount = usersPerStationCount[stationId] || 0;
|
|
if (err) console.error(err);
|
|
if (err) console.error(err);
|
|
utils.emitToRoom('admin.stations', 'event:admin.station.added', station);
|
|
utils.emitToRoom('admin.stations', 'event:admin.station.added', station);
|
|
// TODO If community, check if on whitelist
|
|
// TODO If community, check if on whitelist
|
|
if (station.privacy === 'public') utils.emitToRoom('home', "event:stations.created", station);
|
|
if (station.privacy === 'public') utils.emitToRoom('home', "event:stations.created", station);
|
|
else {
|
|
else {
|
|
- let sockets = utils.getRoomSockets('home');
|
|
|
|
|
|
+ let sockets = await utils.getRoomSockets('home');
|
|
for (let socketId in sockets) {
|
|
for (let socketId in sockets) {
|
|
let socket = sockets[socketId];
|
|
let socket = sockets[socketId];
|
|
let session = sockets[socketId].session;
|
|
let session = sockets[socketId].session;
|
|
@@ -234,13 +245,13 @@ module.exports = {
|
|
next(null, resultStations);
|
|
next(null, resultStations);
|
|
});
|
|
});
|
|
}
|
|
}
|
|
- ], (err, stations) => {
|
|
|
|
|
|
+ ], async (err, stations) => {
|
|
if (err) {
|
|
if (err) {
|
|
- err = utils.getError(err);
|
|
|
|
|
|
+ err = await utils.getError(err);
|
|
logger.error("STATIONS_INDEX", `Indexing stations failed. "${err}"`);
|
|
logger.error("STATIONS_INDEX", `Indexing stations failed. "${err}"`);
|
|
return cb({'status': 'failure', 'message': err});
|
|
return cb({'status': 'failure', 'message': err});
|
|
}
|
|
}
|
|
- logger.success("STATIONS_INDEX", `Indexing stations successful.`);
|
|
|
|
|
|
+ logger.success("STATIONS_INDEX", `Indexing stations successful.`, false);
|
|
return cb({'status': 'success', 'stations': stations});
|
|
return cb({'status': 'success', 'stations': stations});
|
|
});
|
|
});
|
|
},
|
|
},
|
|
@@ -262,13 +273,13 @@ module.exports = {
|
|
if (!station) return next('Station not found.');
|
|
if (!station) return next('Station not found.');
|
|
next(null, station);
|
|
next(null, station);
|
|
}
|
|
}
|
|
- ], (err, station) => {
|
|
|
|
|
|
+ ], async (err, station) => {
|
|
if (err) {
|
|
if (err) {
|
|
- err = utils.getError(err);
|
|
|
|
|
|
+ err = await utils.getError(err);
|
|
logger.error("STATIONS_FIND_BY_NAME", `Finding station "${stationName}" failed. "${err}"`);
|
|
logger.error("STATIONS_FIND_BY_NAME", `Finding station "${stationName}" failed. "${err}"`);
|
|
return cb({'status': 'failure', 'message': err});
|
|
return cb({'status': 'failure', 'message': err});
|
|
}
|
|
}
|
|
- logger.success("STATIONS_FIND_BY_NAME", `Found station "${stationName}" successfully.`);
|
|
|
|
|
|
+ logger.success("STATIONS_FIND_BY_NAME", `Found station "${stationName}" successfully.`, false);
|
|
cb({status: 'success', data: station});
|
|
cb({status: 'success', data: station});
|
|
});
|
|
});
|
|
},
|
|
},
|
|
@@ -288,26 +299,27 @@ module.exports = {
|
|
|
|
|
|
(station, next) => {
|
|
(station, next) => {
|
|
if (!station) return next('Station not found.');
|
|
if (!station) return next('Station not found.');
|
|
- if (station.type !== 'official') return next('This is not an official station.');
|
|
|
|
- next();
|
|
|
|
|
|
+ else if (station.type !== 'official') return next('This is not an official station.');
|
|
|
|
+ else next();
|
|
},
|
|
},
|
|
|
|
|
|
(next) => {
|
|
(next) => {
|
|
- cache.hget("officialPlaylists", stationId, next);
|
|
|
|
|
|
+ cache.hget('officialPlaylists', stationId, next);
|
|
},
|
|
},
|
|
|
|
|
|
(playlist, next) => {
|
|
(playlist, next) => {
|
|
if (!playlist) return next('Playlist not found.');
|
|
if (!playlist) return next('Playlist not found.');
|
|
next(null, playlist);
|
|
next(null, playlist);
|
|
}
|
|
}
|
|
- ], (err, playlist) => {
|
|
|
|
|
|
+ ], async (err, playlist) => {
|
|
if (err) {
|
|
if (err) {
|
|
- err = utils.getError(err);
|
|
|
|
|
|
+ err = await utils.getError(err);
|
|
logger.error("STATIONS_GET_PLAYLIST", `Getting playlist for station "${stationId}" failed. "${err}"`);
|
|
logger.error("STATIONS_GET_PLAYLIST", `Getting playlist for station "${stationId}" failed. "${err}"`);
|
|
- return cb({'status': 'failure', 'message': err});
|
|
|
|
|
|
+ return cb({ status: 'failure', message: err });
|
|
|
|
+ } else {
|
|
|
|
+ logger.success("STATIONS_GET_PLAYLIST", `Got playlist for station "${stationId}" successfully.`, false);
|
|
|
|
+ cb({ status: 'success', data: playlist.songs });
|
|
}
|
|
}
|
|
- logger.success("STATIONS_GET_PLAYLIST", `Got playlist for station "${stationId}" successfully.`);
|
|
|
|
- cb({status: 'success', data: playlist.songs})
|
|
|
|
});
|
|
});
|
|
},
|
|
},
|
|
|
|
|
|
@@ -345,9 +357,9 @@ module.exports = {
|
|
if (station.owner === session.userId) return next(true);
|
|
if (station.owner === session.userId) return next(true);
|
|
next('An error occurred while joining the station.');
|
|
next('An error occurred while joining the station.');
|
|
}
|
|
}
|
|
- ], (err) => {
|
|
|
|
|
|
+ ], async (err) => {
|
|
if (err === true) return next(null, station);
|
|
if (err === true) return next(null, station);
|
|
- next(utils.getError(err));
|
|
|
|
|
|
+ next(await utils.getError(err));
|
|
});
|
|
});
|
|
},
|
|
},
|
|
|
|
|
|
@@ -360,9 +372,11 @@ module.exports = {
|
|
startedAt: station.startedAt,
|
|
startedAt: station.startedAt,
|
|
paused: station.paused,
|
|
paused: station.paused,
|
|
timePaused: station.timePaused,
|
|
timePaused: station.timePaused,
|
|
|
|
+ pausedAt: station.pausedAt,
|
|
description: station.description,
|
|
description: station.description,
|
|
displayName: station.displayName,
|
|
displayName: station.displayName,
|
|
privacy: station.privacy,
|
|
privacy: station.privacy,
|
|
|
|
+ locked: station.locked,
|
|
partyMode: station.partyMode,
|
|
partyMode: station.partyMode,
|
|
owner: station.owner,
|
|
owner: station.owner,
|
|
privatePlaylist: station.privatePlaylist
|
|
privatePlaylist: station.privatePlaylist
|
|
@@ -377,7 +391,7 @@ module.exports = {
|
|
if (!data.currentSong || !data.currentSong.title) return next(null, data);
|
|
if (!data.currentSong || !data.currentSong.title) return next(null, data);
|
|
utils.socketJoinSongRoom(session.socketId, `song.${data.currentSong.songId}`);
|
|
utils.socketJoinSongRoom(session.socketId, `song.${data.currentSong.songId}`);
|
|
data.currentSong.skipVotes = data.currentSong.skipVotes.length;
|
|
data.currentSong.skipVotes = data.currentSong.skipVotes.length;
|
|
- songs.getSong(data.currentSong.songId, (err, song) => {
|
|
|
|
|
|
+ songs.getSongFromId(data.currentSong.songId, (err, song) => {
|
|
if (!err && song) {
|
|
if (!err && song) {
|
|
data.currentSong.likes = song.likes;
|
|
data.currentSong.likes = song.likes;
|
|
data.currentSong.dislikes = song.dislikes;
|
|
data.currentSong.dislikes = song.dislikes;
|
|
@@ -388,9 +402,9 @@ module.exports = {
|
|
next(null, data);
|
|
next(null, data);
|
|
});
|
|
});
|
|
}
|
|
}
|
|
- ], (err, data) => {
|
|
|
|
|
|
+ ], async (err, data) => {
|
|
if (err) {
|
|
if (err) {
|
|
- err = utils.getError(err);
|
|
|
|
|
|
+ err = await utils.getError(err);
|
|
logger.error("STATIONS_JOIN", `Joining station "${stationName}" failed. "${err}"`);
|
|
logger.error("STATIONS_JOIN", `Joining station "${stationName}" failed. "${err}"`);
|
|
return cb({'status': 'failure', 'message': err});
|
|
return cb({'status': 'failure', 'message': err});
|
|
}
|
|
}
|
|
@@ -399,6 +413,39 @@ module.exports = {
|
|
});
|
|
});
|
|
},
|
|
},
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * Toggles if a station is locked
|
|
|
|
+ *
|
|
|
|
+ * @param session
|
|
|
|
+ * @param stationId - the station id
|
|
|
|
+ * @param cb
|
|
|
|
+ */
|
|
|
|
+ toggleLock: hooks.ownerRequired((session, stationId, cb) => {
|
|
|
|
+ async.waterfall([
|
|
|
|
+ (next) => {
|
|
|
|
+ stations.getStation(stationId, next);
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ (station, next) => {
|
|
|
|
+ db.models.station.updateOne({ _id: stationId }, { $set: { locked: !station.locked} }, next);
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ (res, next) => {
|
|
|
|
+ stations.updateStation(stationId, next);
|
|
|
|
+ }
|
|
|
|
+ ], async (err, station) => {
|
|
|
|
+ if (err) {
|
|
|
|
+ err = await utils.getError(err);
|
|
|
|
+ logger.error("STATIONS_UPDATE_LOCKED_STATUS", `Toggling the queue lock for station "${stationId}" failed. "${err}"`);
|
|
|
|
+ return cb({ status: 'failure', message: err });
|
|
|
|
+ } else {
|
|
|
|
+ logger.success("STATIONS_UPDATE_LOCKED_STATUS", `Toggled the queue lock for station "${stationId}" successfully to "${station.locked}".`);
|
|
|
|
+ cache.pub('station.queueLockToggled', {stationId, locked: station.locked});
|
|
|
|
+ return cb({ status: 'success', data: station.locked });
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ }),
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* Votes to skip a station
|
|
* Votes to skip a station
|
|
*
|
|
*
|
|
@@ -415,13 +462,20 @@ module.exports = {
|
|
|
|
|
|
(station, next) => {
|
|
(station, next) => {
|
|
if (!station) return next('Station not found.');
|
|
if (!station) return next('Station not found.');
|
|
|
|
+ utils.canUserBeInStation(station, userId, (canBe) => {
|
|
|
|
+ if (canBe) return next(null, station);
|
|
|
|
+ return next('Insufficient permissions.');
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ (station, next) => {
|
|
if (!station.currentSong) return next('There is currently no song to skip.');
|
|
if (!station.currentSong) return next('There is currently no song to skip.');
|
|
if (station.currentSong.skipVotes.indexOf(userId) !== -1) return next('You have already voted to skip this song.');
|
|
if (station.currentSong.skipVotes.indexOf(userId) !== -1) return next('You have already voted to skip this song.');
|
|
next(null, station);
|
|
next(null, station);
|
|
},
|
|
},
|
|
|
|
|
|
(station, next) => {
|
|
(station, next) => {
|
|
- db.models.station.update({_id: stationId}, {$push: {"currentSong.skipVotes": userId}}, next)
|
|
|
|
|
|
+ db.models.station.updateOne({_id: stationId}, {$push: {"currentSong.skipVotes": userId}}, next)
|
|
},
|
|
},
|
|
|
|
|
|
(res, next) => {
|
|
(res, next) => {
|
|
@@ -432,9 +486,9 @@ module.exports = {
|
|
if (!station) return next('Station not found.');
|
|
if (!station) return next('Station not found.');
|
|
next(null, station);
|
|
next(null, station);
|
|
}
|
|
}
|
|
- ], (err, station) => {
|
|
|
|
|
|
+ ], async (err, station) => {
|
|
if (err) {
|
|
if (err) {
|
|
- err = utils.getError(err);
|
|
|
|
|
|
+ err = await utils.getError(err);
|
|
logger.error("STATIONS_VOTE_SKIP", `Vote skipping station "${stationId}" failed. "${err}"`);
|
|
logger.error("STATIONS_VOTE_SKIP", `Vote skipping station "${stationId}" failed. "${err}"`);
|
|
return cb({'status': 'failure', 'message': err});
|
|
return cb({'status': 'failure', 'message': err});
|
|
}
|
|
}
|
|
@@ -462,9 +516,9 @@ module.exports = {
|
|
if (!station) return next('Station not found.');
|
|
if (!station) return next('Station not found.');
|
|
next();
|
|
next();
|
|
}
|
|
}
|
|
- ], (err) => {
|
|
|
|
|
|
+ ], async (err) => {
|
|
if (err) {
|
|
if (err) {
|
|
- err = utils.getError(err);
|
|
|
|
|
|
+ err = await utils.getError(err);
|
|
logger.error("STATIONS_FORCE_SKIP", `Force skipping station "${stationId}" failed. "${err}"`);
|
|
logger.error("STATIONS_FORCE_SKIP", `Force skipping station "${stationId}" failed. "${err}"`);
|
|
return cb({'status': 'failure', 'message': err});
|
|
return cb({'status': 'failure', 'message': err});
|
|
}
|
|
}
|
|
@@ -492,14 +546,10 @@ module.exports = {
|
|
(station, next) => {
|
|
(station, next) => {
|
|
if (!station) return next('Station not found.');
|
|
if (!station) return next('Station not found.');
|
|
next();
|
|
next();
|
|
- },
|
|
|
|
-
|
|
|
|
- (next) => {
|
|
|
|
- cache.client.hincrby('station.userCounts', stationId, -1, next);
|
|
|
|
}
|
|
}
|
|
- ], (err, userCount) => {
|
|
|
|
|
|
+ ], async (err, userCount) => {
|
|
if (err) {
|
|
if (err) {
|
|
- err = utils.getError(err);
|
|
|
|
|
|
+ err = await utils.getError(err);
|
|
logger.error("STATIONS_LEAVE", `Leaving station "${stationId}" failed. "${err}"`);
|
|
logger.error("STATIONS_LEAVE", `Leaving station "${stationId}" failed. "${err}"`);
|
|
return cb({'status': 'failure', 'message': err});
|
|
return cb({'status': 'failure', 'message': err});
|
|
}
|
|
}
|
|
@@ -521,15 +571,15 @@ module.exports = {
|
|
updateName: hooks.ownerRequired((session, stationId, newName, cb) => {
|
|
updateName: hooks.ownerRequired((session, stationId, newName, cb) => {
|
|
async.waterfall([
|
|
async.waterfall([
|
|
(next) => {
|
|
(next) => {
|
|
- db.models.station.update({_id: stationId}, {$set: {name: newName}}, next);
|
|
|
|
|
|
+ db.models.station.updateOne({_id: stationId}, {$set: {name: newName}}, {runValidators: true}, next);
|
|
},
|
|
},
|
|
|
|
|
|
(res, next) => {
|
|
(res, next) => {
|
|
stations.updateStation(stationId, next);
|
|
stations.updateStation(stationId, next);
|
|
}
|
|
}
|
|
- ], (err) => {
|
|
|
|
|
|
+ ], async (err) => {
|
|
if (err) {
|
|
if (err) {
|
|
- err = utils.getError(err);
|
|
|
|
|
|
+ err = await utils.getError(err);
|
|
logger.error("STATIONS_UPDATE_DISPLAY_NAME", `Updating station "${stationId}" displayName to "${newName}" failed. "${err}"`);
|
|
logger.error("STATIONS_UPDATE_DISPLAY_NAME", `Updating station "${stationId}" displayName to "${newName}" failed. "${err}"`);
|
|
return cb({'status': 'failure', 'message': err});
|
|
return cb({'status': 'failure', 'message': err});
|
|
}
|
|
}
|
|
@@ -549,15 +599,15 @@ module.exports = {
|
|
updateDisplayName: hooks.ownerRequired((session, stationId, newDisplayName, cb) => {
|
|
updateDisplayName: hooks.ownerRequired((session, stationId, newDisplayName, cb) => {
|
|
async.waterfall([
|
|
async.waterfall([
|
|
(next) => {
|
|
(next) => {
|
|
- db.models.station.update({_id: stationId}, {$set: {displayName: newDisplayName}}, next);
|
|
|
|
|
|
+ db.models.station.updateOne({_id: stationId}, {$set: {displayName: newDisplayName}}, {runValidators: true}, next);
|
|
},
|
|
},
|
|
|
|
|
|
(res, next) => {
|
|
(res, next) => {
|
|
stations.updateStation(stationId, next);
|
|
stations.updateStation(stationId, next);
|
|
}
|
|
}
|
|
- ], (err) => {
|
|
|
|
|
|
+ ], async (err) => {
|
|
if (err) {
|
|
if (err) {
|
|
- err = utils.getError(err);
|
|
|
|
|
|
+ err = await utils.getError(err);
|
|
logger.error("STATIONS_UPDATE_DISPLAY_NAME", `Updating station "${stationId}" displayName to "${newDisplayName}" failed. "${err}"`);
|
|
logger.error("STATIONS_UPDATE_DISPLAY_NAME", `Updating station "${stationId}" displayName to "${newDisplayName}" failed. "${err}"`);
|
|
return cb({'status': 'failure', 'message': err});
|
|
return cb({'status': 'failure', 'message': err});
|
|
}
|
|
}
|
|
@@ -577,15 +627,15 @@ module.exports = {
|
|
updateDescription: hooks.ownerRequired((session, stationId, newDescription, cb) => {
|
|
updateDescription: hooks.ownerRequired((session, stationId, newDescription, cb) => {
|
|
async.waterfall([
|
|
async.waterfall([
|
|
(next) => {
|
|
(next) => {
|
|
- db.models.station.update({_id: stationId}, {$set: {description: newDescription}}, next);
|
|
|
|
|
|
+ db.models.station.updateOne({_id: stationId}, {$set: {description: newDescription}}, {runValidators: true}, next);
|
|
},
|
|
},
|
|
|
|
|
|
(res, next) => {
|
|
(res, next) => {
|
|
stations.updateStation(stationId, next);
|
|
stations.updateStation(stationId, next);
|
|
}
|
|
}
|
|
- ], (err) => {
|
|
|
|
|
|
+ ], async (err) => {
|
|
if (err) {
|
|
if (err) {
|
|
- err = utils.getError(err);
|
|
|
|
|
|
+ err = await utils.getError(err);
|
|
logger.error("STATIONS_UPDATE_DESCRIPTION", `Updating station "${stationId}" description to "${newDescription}" failed. "${err}"`);
|
|
logger.error("STATIONS_UPDATE_DESCRIPTION", `Updating station "${stationId}" description to "${newDescription}" failed. "${err}"`);
|
|
return cb({'status': 'failure', 'message': err});
|
|
return cb({'status': 'failure', 'message': err});
|
|
}
|
|
}
|
|
@@ -605,15 +655,15 @@ module.exports = {
|
|
updatePrivacy: hooks.ownerRequired((session, stationId, newPrivacy, cb) => {
|
|
updatePrivacy: hooks.ownerRequired((session, stationId, newPrivacy, cb) => {
|
|
async.waterfall([
|
|
async.waterfall([
|
|
(next) => {
|
|
(next) => {
|
|
- db.models.station.update({_id: stationId}, {$set: {privacy: newPrivacy}}, next);
|
|
|
|
|
|
+ db.models.station.updateOne({_id: stationId}, {$set: {privacy: newPrivacy}}, {runValidators: true}, next);
|
|
},
|
|
},
|
|
|
|
|
|
(res, next) => {
|
|
(res, next) => {
|
|
stations.updateStation(stationId, next);
|
|
stations.updateStation(stationId, next);
|
|
}
|
|
}
|
|
- ], (err) => {
|
|
|
|
|
|
+ ], async (err) => {
|
|
if (err) {
|
|
if (err) {
|
|
- err = utils.getError(err);
|
|
|
|
|
|
+ err = await utils.getError(err);
|
|
logger.error("STATIONS_UPDATE_PRIVACY", `Updating station "${stationId}" privacy to "${newPrivacy}" failed. "${err}"`);
|
|
logger.error("STATIONS_UPDATE_PRIVACY", `Updating station "${stationId}" privacy to "${newPrivacy}" failed. "${err}"`);
|
|
return cb({'status': 'failure', 'message': err});
|
|
return cb({'status': 'failure', 'message': err});
|
|
}
|
|
}
|
|
@@ -622,6 +672,62 @@ module.exports = {
|
|
});
|
|
});
|
|
}),
|
|
}),
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * Updates a station's genres
|
|
|
|
+ *
|
|
|
|
+ * @param session
|
|
|
|
+ * @param stationId - the station id
|
|
|
|
+ * @param newGenres - the new station genres
|
|
|
|
+ * @param cb
|
|
|
|
+ */
|
|
|
|
+ updateGenres: hooks.ownerRequired((session, stationId, newGenres, cb) => {
|
|
|
|
+ async.waterfall([
|
|
|
|
+ (next) => {
|
|
|
|
+ db.models.station.updateOne({_id: stationId}, {$set: {genres: newGenres}}, {runValidators: true}, next);
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ (res, next) => {
|
|
|
|
+ stations.updateStation(stationId, next);
|
|
|
|
+ }
|
|
|
|
+ ], async (err) => {
|
|
|
|
+ if (err) {
|
|
|
|
+ err = await utils.getError(err);
|
|
|
|
+ logger.error("STATIONS_UPDATE_GENRES", `Updating station "${stationId}" genres to "${newGenres}" failed. "${err}"`);
|
|
|
|
+ return cb({'status': 'failure', 'message': err});
|
|
|
|
+ }
|
|
|
|
+ logger.success("STATIONS_UPDATE_GENRES", `Updated station "${stationId}" genres to "${newGenres}" successfully.`);
|
|
|
|
+ return cb({'status': 'success', 'message': 'Successfully updated the genres.'});
|
|
|
|
+ });
|
|
|
|
+ }),
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Updates a station's blacklisted genres
|
|
|
|
+ *
|
|
|
|
+ * @param session
|
|
|
|
+ * @param stationId - the station id
|
|
|
|
+ * @param newBlacklistedGenres - the new station blacklisted genres
|
|
|
|
+ * @param cb
|
|
|
|
+ */
|
|
|
|
+ updateBlacklistedGenres: hooks.ownerRequired((session, stationId, newBlacklistedGenres, cb) => {
|
|
|
|
+ async.waterfall([
|
|
|
|
+ (next) => {
|
|
|
|
+ db.models.station.updateOne({_id: stationId}, {$set: {blacklistedGenres: newBlacklistedGenres}}, {runValidators: true}, next);
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ (res, next) => {
|
|
|
|
+ stations.updateStation(stationId, next);
|
|
|
|
+ }
|
|
|
|
+ ], async (err) => {
|
|
|
|
+ if (err) {
|
|
|
|
+ err = await utils.getError(err);
|
|
|
|
+ logger.error("STATIONS_UPDATE_BLACKLISTED_GENRES", `Updating station "${stationId}" blacklisted genres to "${newBlacklistedGenres}" failed. "${err}"`);
|
|
|
|
+ return cb({'status': 'failure', 'message': err});
|
|
|
|
+ }
|
|
|
|
+ logger.success("STATIONS_UPDATE_BLACKLISTED_GENRES", `Updated station "${stationId}" blacklisted genres to "${newBlacklistedGenres}" successfully.`);
|
|
|
|
+ return cb({'status': 'success', 'message': 'Successfully updated the blacklisted genres.'});
|
|
|
|
+ });
|
|
|
|
+ }),
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* Updates a station's party mode
|
|
* Updates a station's party mode
|
|
*
|
|
*
|
|
@@ -639,15 +745,15 @@ module.exports = {
|
|
(station, next) => {
|
|
(station, next) => {
|
|
if (!station) return next('Station not found.');
|
|
if (!station) return next('Station not found.');
|
|
if (station.partyMode === newPartyMode) return next('The party mode was already ' + ((newPartyMode) ? 'enabled.' : 'disabled.'));
|
|
if (station.partyMode === newPartyMode) return next('The party mode was already ' + ((newPartyMode) ? 'enabled.' : 'disabled.'));
|
|
- db.models.station.update({_id: stationId}, {$set: {partyMode: newPartyMode}}, next);
|
|
|
|
|
|
+ db.models.station.updateOne({_id: stationId}, {$set: {partyMode: newPartyMode}}, {runValidators: true}, next);
|
|
},
|
|
},
|
|
|
|
|
|
(res, next) => {
|
|
(res, next) => {
|
|
stations.updateStation(stationId, next);
|
|
stations.updateStation(stationId, next);
|
|
}
|
|
}
|
|
- ], (err) => {
|
|
|
|
|
|
+ ], async (err) => {
|
|
if (err) {
|
|
if (err) {
|
|
- err = utils.getError(err);
|
|
|
|
|
|
+ err = await utils.getError(err);
|
|
logger.error("STATIONS_UPDATE_PARTY_MODE", `Updating station "${stationId}" party mode to "${newPartyMode}" failed. "${err}"`);
|
|
logger.error("STATIONS_UPDATE_PARTY_MODE", `Updating station "${stationId}" party mode to "${newPartyMode}" failed. "${err}"`);
|
|
return cb({'status': 'failure', 'message': err});
|
|
return cb({'status': 'failure', 'message': err});
|
|
}
|
|
}
|
|
@@ -674,15 +780,15 @@ module.exports = {
|
|
(station, next) => {
|
|
(station, next) => {
|
|
if (!station) return next('Station not found.');
|
|
if (!station) return next('Station not found.');
|
|
if (station.paused) return next('That station was already paused.');
|
|
if (station.paused) return next('That station was already paused.');
|
|
- db.models.station.update({_id: stationId}, {$set: {paused: true, pausedAt: Date.now()}}, next);
|
|
|
|
|
|
+ db.models.station.updateOne({_id: stationId}, {$set: {paused: true, pausedAt: Date.now()}}, next);
|
|
},
|
|
},
|
|
|
|
|
|
(res, next) => {
|
|
(res, next) => {
|
|
stations.updateStation(stationId, next);
|
|
stations.updateStation(stationId, next);
|
|
}
|
|
}
|
|
- ], (err) => {
|
|
|
|
|
|
+ ], async (err) => {
|
|
if (err) {
|
|
if (err) {
|
|
- err = utils.getError(err);
|
|
|
|
|
|
+ err = await utils.getError(err);
|
|
logger.error("STATIONS_PAUSE", `Pausing station "${stationId}" failed. "${err}"`);
|
|
logger.error("STATIONS_PAUSE", `Pausing station "${stationId}" failed. "${err}"`);
|
|
return cb({'status': 'failure', 'message': err});
|
|
return cb({'status': 'failure', 'message': err});
|
|
}
|
|
}
|
|
@@ -710,15 +816,15 @@ module.exports = {
|
|
if (!station) return next('Station not found.');
|
|
if (!station) return next('Station not found.');
|
|
if (!station.paused) return next('That station is not paused.');
|
|
if (!station.paused) return next('That station is not paused.');
|
|
station.timePaused += (Date.now() - station.pausedAt);
|
|
station.timePaused += (Date.now() - station.pausedAt);
|
|
- db.models.station.update({_id: stationId}, {$set: {paused: false}, $inc: {timePaused: Date.now() - station.pausedAt}}, next);
|
|
|
|
|
|
+ db.models.station.updateOne({_id: stationId}, {$set: {paused: false}, $inc: {timePaused: Date.now() - station.pausedAt}}, next);
|
|
},
|
|
},
|
|
|
|
|
|
- (next) => {
|
|
|
|
|
|
+ (res, next) => {
|
|
stations.updateStation(stationId, next);
|
|
stations.updateStation(stationId, next);
|
|
}
|
|
}
|
|
- ], (err) => {
|
|
|
|
|
|
+ ], async (err) => {
|
|
if (err) {
|
|
if (err) {
|
|
- err = utils.getError(err);
|
|
|
|
|
|
+ err = await utils.getError(err);
|
|
logger.error("STATIONS_RESUME", `Resuming station "${stationId}" failed. "${err}"`);
|
|
logger.error("STATIONS_RESUME", `Resuming station "${stationId}" failed. "${err}"`);
|
|
return cb({'status': 'failure', 'message': err});
|
|
return cb({'status': 'failure', 'message': err});
|
|
}
|
|
}
|
|
@@ -738,15 +844,15 @@ module.exports = {
|
|
remove: hooks.ownerRequired((session, stationId, cb) => {
|
|
remove: hooks.ownerRequired((session, stationId, cb) => {
|
|
async.waterfall([
|
|
async.waterfall([
|
|
(next) => {
|
|
(next) => {
|
|
- db.models.station.remove({ _id: stationId }, err => next(err));
|
|
|
|
|
|
+ db.models.station.deleteOne({ _id: stationId }, err => next(err));
|
|
},
|
|
},
|
|
|
|
|
|
(next) => {
|
|
(next) => {
|
|
cache.hdel('stations', stationId, err => next(err));
|
|
cache.hdel('stations', stationId, err => next(err));
|
|
}
|
|
}
|
|
- ], (err) => {
|
|
|
|
|
|
+ ], async (err) => {
|
|
if (err) {
|
|
if (err) {
|
|
- err = utils.getError(err);
|
|
|
|
|
|
+ err = await utils.getError(err);
|
|
logger.error("STATIONS_REMOVE", `Removing station "${stationId}" failed. "${err}"`);
|
|
logger.error("STATIONS_REMOVE", `Removing station "${stationId}" failed. "${err}"`);
|
|
return cb({ 'status': 'failure', 'message': err });
|
|
return cb({ 'status': 'failure', 'message': err });
|
|
}
|
|
}
|
|
@@ -765,7 +871,6 @@ module.exports = {
|
|
* @param userId
|
|
* @param userId
|
|
*/
|
|
*/
|
|
create: hooks.loginRequired((session, data, cb, userId) => {
|
|
create: hooks.loginRequired((session, data, cb, userId) => {
|
|
- console.log(data);
|
|
|
|
data.name = data.name.toLowerCase();
|
|
data.name = data.name.toLowerCase();
|
|
let blacklist = ["country", "edm", "musare", "hip-hop", "rap", "top-hits", "todays-hits", "old-school", "christmas", "about", "support", "staff", "help", "news", "terms", "privacy", "profile", "c", "community", "tos", "login", "register", "p", "official", "o", "trap", "faq", "team", "donate", "buy", "shop", "forums", "explore", "settings", "admin", "auth", "reset_password"];
|
|
let blacklist = ["country", "edm", "musare", "hip-hop", "rap", "top-hits", "todays-hits", "old-school", "christmas", "about", "support", "staff", "help", "news", "terms", "privacy", "profile", "c", "community", "tos", "login", "register", "p", "official", "o", "trap", "faq", "team", "donate", "buy", "shop", "forums", "explore", "settings", "admin", "auth", "reset_password"];
|
|
async.waterfall([
|
|
async.waterfall([
|
|
@@ -812,10 +917,9 @@ module.exports = {
|
|
}, next);
|
|
}, next);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- ], (err, station) => {
|
|
|
|
|
|
+ ], async (err, station) => {
|
|
if (err) {
|
|
if (err) {
|
|
- console.log(err);
|
|
|
|
- err = utils.getError(err);
|
|
|
|
|
|
+ err = await utils.getError(err);
|
|
logger.error("STATIONS_CREATE", `Creating station failed. "${err}"`);
|
|
logger.error("STATIONS_CREATE", `Creating station failed. "${err}"`);
|
|
return cb({'status': 'failure', 'message': err});
|
|
return cb({'status': 'failure', 'message': err});
|
|
}
|
|
}
|
|
@@ -842,7 +946,25 @@ module.exports = {
|
|
|
|
|
|
(station, next) => {
|
|
(station, next) => {
|
|
if (!station) return next('Station not found.');
|
|
if (!station) return next('Station not found.');
|
|
|
|
+ if (station.locked) {
|
|
|
|
+ db.models.user.findOne({ _id: userId }, (err, user) => {
|
|
|
|
+ if (user.role !== 'admin' && station.owner !== userId) return next('Only owners and admins can add songs to a locked queue.');
|
|
|
|
+ else return next(null, station);
|
|
|
|
+ });
|
|
|
|
+ } else {
|
|
|
|
+ return next(null, station);
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ (station, next) => {
|
|
if (station.type !== 'community') return next('That station is not a community station.');
|
|
if (station.type !== 'community') return next('That station is not a community station.');
|
|
|
|
+ utils.canUserBeInStation(station, userId, (canBe) => {
|
|
|
|
+ if (canBe) return next(null, station);
|
|
|
|
+ return next('Insufficient permissions.');
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ (station, next) => {
|
|
if (station.currentSong && station.currentSong.songId === songId) return next('That song is currently playing.');
|
|
if (station.currentSong && station.currentSong.songId === songId) return next('That song is currently playing.');
|
|
async.each(station.queue, (queueSong, next) => {
|
|
async.each(station.queue, (queueSong, next) => {
|
|
if (queueSong.songId === songId) return next('That song is already in the queue.');
|
|
if (queueSong.songId === songId) return next('That song is already in the queue.');
|
|
@@ -854,8 +976,7 @@ module.exports = {
|
|
|
|
|
|
(station, next) => {
|
|
(station, next) => {
|
|
songs.getSong(songId, (err, song) => {
|
|
songs.getSong(songId, (err, song) => {
|
|
- if (!err && song) return next(null, song);
|
|
|
|
- console.log(53, songId);
|
|
|
|
|
|
+ if (!err && song) return next(null, song, station);
|
|
utils.getSongFromYouTube(songId, (song) => {
|
|
utils.getSongFromYouTube(songId, (song) => {
|
|
song.artists = [];
|
|
song.artists = [];
|
|
song.skipDuration = 0;
|
|
song.skipDuration = 0;
|
|
@@ -863,22 +984,66 @@ module.exports = {
|
|
song.dislikes = -1;
|
|
song.dislikes = -1;
|
|
song.thumbnail = "empty";
|
|
song.thumbnail = "empty";
|
|
song.explicit = false;
|
|
song.explicit = false;
|
|
- next(null, song);
|
|
|
|
|
|
+ next(null, song, station);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
},
|
|
},
|
|
|
|
|
|
- (song, next) => {
|
|
|
|
|
|
+ (song, station, next) => {
|
|
|
|
+ let queue = station.queue;
|
|
song.requestedBy = userId;
|
|
song.requestedBy = userId;
|
|
- db.models.station.update({_id: stationId}, {$push: {queue: song}}, next);
|
|
|
|
|
|
+ queue.push(song);
|
|
|
|
+
|
|
|
|
+ let totalDuration = 0;
|
|
|
|
+ queue.forEach((song) => {
|
|
|
|
+ totalDuration += song.duration;
|
|
|
|
+ });
|
|
|
|
+ if (totalDuration >= 3600 * 3) return next('The max length of the queue is 3 hours.');
|
|
|
|
+ next(null, song, station);
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ (song, station, next) => {
|
|
|
|
+ let queue = station.queue;
|
|
|
|
+ if (queue.length === 0) return next(null, song, station);
|
|
|
|
+ let totalDuration = 0;
|
|
|
|
+ const userId = queue[queue.length - 1].requestedBy;
|
|
|
|
+ station.queue.forEach((song) => {
|
|
|
|
+ if (userId === song.requestedBy) {
|
|
|
|
+ totalDuration += song.duration;
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ if(totalDuration >= 900) return next('The max length of songs per user is 15 minutes.');
|
|
|
|
+ next(null, song, station);
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ (song, station, next) => {
|
|
|
|
+ let queue = station.queue;
|
|
|
|
+ if (queue.length === 0) return next(null, song);
|
|
|
|
+ let totalSongs = 0;
|
|
|
|
+ const userId = queue[queue.length - 1].requestedBy;
|
|
|
|
+ queue.forEach((song) => {
|
|
|
|
+ if (userId === song.requestedBy) {
|
|
|
|
+ totalSongs++;
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ if (totalSongs <= 2) return next(null, song);
|
|
|
|
+ if (totalSongs > 3) return next('The max amount of songs per user is 3, and only 2 in a row is allowed.');
|
|
|
|
+ if (queue[queue.length - 2].requestedBy !== userId || queue[queue.length - 3] !== userId) return next('The max amount of songs per user is 3, and only 2 in a row is allowed.');
|
|
|
|
+ next(null, song);
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ (song, next) => {
|
|
|
|
+ db.models.station.updateOne({_id: stationId}, {$push: {queue: song}}, {runValidators: true}, next);
|
|
},
|
|
},
|
|
|
|
|
|
(res, next) => {
|
|
(res, next) => {
|
|
stations.updateStation(stationId, next);
|
|
stations.updateStation(stationId, next);
|
|
}
|
|
}
|
|
- ], (err, station) => {
|
|
|
|
|
|
+ ], async (err, station) => {
|
|
if (err) {
|
|
if (err) {
|
|
- err = utils.getError(err);
|
|
|
|
|
|
+ err = await utils.getError(err);
|
|
logger.error("STATIONS_ADD_SONG_TO_QUEUE", `Adding song "${songId}" to station "${stationId}" queue failed. "${err}"`);
|
|
logger.error("STATIONS_ADD_SONG_TO_QUEUE", `Adding song "${songId}" to station "${stationId}" queue failed. "${err}"`);
|
|
return cb({'status': 'failure', 'message': err});
|
|
return cb({'status': 'failure', 'message': err});
|
|
}
|
|
}
|
|
@@ -917,15 +1082,15 @@ module.exports = {
|
|
},
|
|
},
|
|
|
|
|
|
(next) => {
|
|
(next) => {
|
|
- db.models.update({_id: stationId}, {$pull: {queue: {songId: songId}}}, next);
|
|
|
|
|
|
+ db.models.station.updateOne({_id: stationId}, {$pull: {queue: {songId: songId}}}, next);
|
|
},
|
|
},
|
|
|
|
|
|
- (next) => {
|
|
|
|
|
|
+ (res, next) => {
|
|
stations.updateStation(stationId, next);
|
|
stations.updateStation(stationId, next);
|
|
}
|
|
}
|
|
- ], (err, station) => {
|
|
|
|
|
|
+ ], async (err, station) => {
|
|
if (err) {
|
|
if (err) {
|
|
- err = utils.getError(err);
|
|
|
|
|
|
+ err = await utils.getError(err);
|
|
logger.error("STATIONS_REMOVE_SONG_TO_QUEUE", `Removing song "${songId}" from station "${stationId}" queue failed. "${err}"`);
|
|
logger.error("STATIONS_REMOVE_SONG_TO_QUEUE", `Removing song "${songId}" from station "${stationId}" queue failed. "${err}"`);
|
|
return cb({'status': 'failure', 'message': err});
|
|
return cb({'status': 'failure', 'message': err});
|
|
}
|
|
}
|
|
@@ -942,7 +1107,7 @@ module.exports = {
|
|
* @param stationId - the station id
|
|
* @param stationId - the station id
|
|
* @param cb
|
|
* @param cb
|
|
*/
|
|
*/
|
|
- getQueue: hooks.adminRequired((session, stationId, cb) => {
|
|
|
|
|
|
+ getQueue: (session, stationId, cb) => {
|
|
async.waterfall([
|
|
async.waterfall([
|
|
(next) => {
|
|
(next) => {
|
|
stations.getStation(stationId, next);
|
|
stations.getStation(stationId, next);
|
|
@@ -952,17 +1117,24 @@ module.exports = {
|
|
if (!station) return next('Station not found.');
|
|
if (!station) return next('Station not found.');
|
|
if (station.type !== 'community') return next('Station is not a community station.');
|
|
if (station.type !== 'community') return next('Station is not a community station.');
|
|
next(null, station);
|
|
next(null, station);
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ (station, next) => {
|
|
|
|
+ utils.canUserBeInStation(station, session.userId, (canBe) => {
|
|
|
|
+ if (canBe) return next(null, station);
|
|
|
|
+ return next('Insufficient permissions.');
|
|
|
|
+ });
|
|
}
|
|
}
|
|
- ], (err, station) => {
|
|
|
|
|
|
+ ], async (err, station) => {
|
|
if (err) {
|
|
if (err) {
|
|
- err = utils.getError(err);
|
|
|
|
|
|
+ err = await utils.getError(err);
|
|
logger.error("STATIONS_GET_QUEUE", `Getting queue for station "${stationId}" failed. "${err}"`);
|
|
logger.error("STATIONS_GET_QUEUE", `Getting queue for station "${stationId}" failed. "${err}"`);
|
|
return cb({'status': 'failure', 'message': err});
|
|
return cb({'status': 'failure', 'message': err});
|
|
}
|
|
}
|
|
logger.success("STATIONS_GET_QUEUE", `Got queue for station "${stationId}" successfully.`);
|
|
logger.success("STATIONS_GET_QUEUE", `Got queue for station "${stationId}" successfully.`);
|
|
return cb({'status': 'success', 'message': 'Successfully got queue.', queue: station.queue});
|
|
return cb({'status': 'success', 'message': 'Successfully got queue.', queue: station.queue});
|
|
});
|
|
});
|
|
- }),
|
|
|
|
|
|
+ },
|
|
|
|
|
|
/**
|
|
/**
|
|
* Selects a private playlist for a station
|
|
* Selects a private playlist for a station
|
|
@@ -989,22 +1161,97 @@ module.exports = {
|
|
(playlist, next) => {
|
|
(playlist, next) => {
|
|
if (!playlist) return next('Playlist not found.');
|
|
if (!playlist) return next('Playlist not found.');
|
|
let currentSongIndex = (playlist.songs.length > 0) ? playlist.songs.length - 1 : 0;
|
|
let currentSongIndex = (playlist.songs.length > 0) ? playlist.songs.length - 1 : 0;
|
|
- db.models.station.update({_id: stationId}, {$set: {privatePlaylist: playlistId, currentSongIndex: currentSongIndex}}, next);
|
|
|
|
|
|
+ db.models.station.updateOne({_id: stationId}, {$set: {privatePlaylist: playlistId, currentSongIndex: currentSongIndex}}, {runValidators: true}, next);
|
|
},
|
|
},
|
|
|
|
|
|
(res, next) => {
|
|
(res, next) => {
|
|
stations.updateStation(stationId, next);
|
|
stations.updateStation(stationId, next);
|
|
}
|
|
}
|
|
- ], (err, station) => {
|
|
|
|
|
|
+ ], async (err, station) => {
|
|
if (err) {
|
|
if (err) {
|
|
- err = utils.getError(err);
|
|
|
|
|
|
+ err = await utils.getError(err);
|
|
logger.error("STATIONS_SELECT_PRIVATE_PLAYLIST", `Selecting private playlist "${playlistId}" for station "${stationId}" failed. "${err}"`);
|
|
logger.error("STATIONS_SELECT_PRIVATE_PLAYLIST", `Selecting private playlist "${playlistId}" for station "${stationId}" failed. "${err}"`);
|
|
return cb({'status': 'failure', 'message': err});
|
|
return cb({'status': 'failure', 'message': err});
|
|
}
|
|
}
|
|
logger.success("STATIONS_SELECT_PRIVATE_PLAYLIST", `Selected private playlist "${playlistId}" for station "${stationId}" successfully.`);
|
|
logger.success("STATIONS_SELECT_PRIVATE_PLAYLIST", `Selected private playlist "${playlistId}" for station "${stationId}" successfully.`);
|
|
|
|
+ notifications.unschedule(`stations.nextSong?id${stationId}`);
|
|
if (!station.partyMode) stations.skipStation(stationId)();
|
|
if (!station.partyMode) stations.skipStation(stationId)();
|
|
cache.pub('privatePlaylist.selected', {playlistId, stationId});
|
|
cache.pub('privatePlaylist.selected', {playlistId, stationId});
|
|
return cb({'status': 'success', 'message': 'Successfully selected playlist.'});
|
|
return cb({'status': 'success', 'message': 'Successfully selected playlist.'});
|
|
});
|
|
});
|
|
}),
|
|
}),
|
|
|
|
+
|
|
|
|
+ favoriteStation: hooks.loginRequired((session, stationId, cb, userId) => {
|
|
|
|
+ async.waterfall([
|
|
|
|
+ (next) => {
|
|
|
|
+ stations.getStation(stationId, next);
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ (station, next) => {
|
|
|
|
+ if (!station) return next('Station not found.');
|
|
|
|
+ async.waterfall([
|
|
|
|
+ (next) => {
|
|
|
|
+ if (station.privacy !== 'private') return next(true);
|
|
|
|
+ if (!session.userId) return next("You're not allowed to favorite this station.");
|
|
|
|
+ next();
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ (next) => {
|
|
|
|
+ db.models.user.findOne({ _id: userId }, next);
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ (user, next) => {
|
|
|
|
+ if (!user) return next("You're not allowed to favorite this station.");
|
|
|
|
+ if (user.role === 'admin') return next(true);
|
|
|
|
+ if (station.type === 'official') return next("You're not allowed to favorite this station.");
|
|
|
|
+ if (station.owner === session.userId) return next(true);
|
|
|
|
+ next("You're not allowed to favorite this station.");
|
|
|
|
+ }
|
|
|
|
+ ], (err) => {
|
|
|
|
+ if (err === true) return next(null);
|
|
|
|
+ next(utils.getError(err));
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ (next) => {
|
|
|
|
+ db.models.user.updateOne({ _id: userId }, { $addToSet: { favoriteStations: stationId } }, next);
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ (res, next) => {
|
|
|
|
+ if (res.nModified === 0) return next("The station was already favorited.");
|
|
|
|
+ next();
|
|
|
|
+ }
|
|
|
|
+ ], async (err) => {
|
|
|
|
+ if (err) {
|
|
|
|
+ err = await utils.getError(err);
|
|
|
|
+ logger.error("FAVORITE_STATION", `Favoriting station "${stationId}" failed. "${err}"`);
|
|
|
|
+ return cb({'status': 'failure', 'message': err});
|
|
|
|
+ }
|
|
|
|
+ logger.success("FAVORITE_STATION", `Favorited station "${stationId}" successfully.`);
|
|
|
|
+ cache.pub('user.favoritedStation', { userId, stationId });
|
|
|
|
+ return cb({'status': 'success', 'message': 'Succesfully favorited station.'});
|
|
|
|
+ });
|
|
|
|
+ }),
|
|
|
|
+
|
|
|
|
+ unfavoriteStation: hooks.loginRequired((session, stationId, cb, userId) => {
|
|
|
|
+ async.waterfall([
|
|
|
|
+ (next) => {
|
|
|
|
+ db.models.user.updateOne({ _id: userId }, { $pull: { favoriteStations: stationId } }, next);
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ (res, next) => {
|
|
|
|
+ if (res.nModified === 0) return next("The station wasn't favorited.");
|
|
|
|
+ next();
|
|
|
|
+ }
|
|
|
|
+ ], async (err) => {
|
|
|
|
+ if (err) {
|
|
|
|
+ err = await utils.getError(err);
|
|
|
|
+ logger.error("UNFAVORITE_STATION", `Unfavoriting station "${stationId}" failed. "${err}"`);
|
|
|
|
+ return cb({'status': 'failure', 'message': err});
|
|
|
|
+ }
|
|
|
|
+ logger.success("UNFAVORITE_STATION", `Unfavorited station "${stationId}" successfully.`);
|
|
|
|
+ cache.pub('user.unfavoritedStation', { userId, stationId });
|
|
|
|
+ return cb({'status': 'success', 'message': 'Succesfully unfavorited station.'});
|
|
|
|
+ });
|
|
|
|
+ }),
|
|
};
|
|
};
|