Finished up with backend for user playlists
This commit is contained in:
parent
aefc2dc1bd
commit
ed78bc7dfc
|
|
@ -37,18 +37,140 @@ module.exports = class{
|
||||||
socket.on("getChannelPlaylists", () => {this.getChannelPlaylists(socket)});
|
socket.on("getChannelPlaylists", () => {this.getChannelPlaylists(socket)});
|
||||||
socket.on("createChannelPlaylist", (data) => {this.createChannelPlaylist(socket, data)});
|
socket.on("createChannelPlaylist", (data) => {this.createChannelPlaylist(socket, data)});
|
||||||
socket.on("deleteChannelPlaylist", (data) => {this.deleteChannelPlaylist(socket, data)});
|
socket.on("deleteChannelPlaylist", (data) => {this.deleteChannelPlaylist(socket, data)});
|
||||||
socket.on("deleteChannelPlaylistMedia", (data) => {this.deleteChannelPlaylistMedia(socket, data)});
|
|
||||||
socket.on("addToChannelPlaylist", (data) => {this.addToChannelPlaylist(socket, data)});
|
socket.on("addToChannelPlaylist", (data) => {this.addToChannelPlaylist(socket, data)});
|
||||||
socket.on("queueChannelPlaylist", (data) => {this.queueChannelPlaylist(socket, data)});
|
socket.on("queueChannelPlaylist", (data) => {this.queueChannelPlaylist(socket, data)});
|
||||||
socket.on("queueRandomFromChannelPlaylist", (data) => {this.queueRandomFromChannelPlaylist(socket, data)});
|
|
||||||
socket.on("queueFromChannelPlaylist", (data) => {this.queueFromChannelPlaylist(socket, data)});
|
socket.on("queueFromChannelPlaylist", (data) => {this.queueFromChannelPlaylist(socket, data)});
|
||||||
|
socket.on("queueRandomFromChannelPlaylist", (data) => {this.queueRandomFromChannelPlaylist(socket, data)});
|
||||||
socket.on("renameChannelPlaylist", (data) => {this.renameChannelPlaylist(socket, data)});
|
socket.on("renameChannelPlaylist", (data) => {this.renameChannelPlaylist(socket, data)});
|
||||||
socket.on("changeDefaultTitlesChannelPlaylist", (data) => {this.changeDefaultTitlesChannelPlaylist(socket, data)});
|
socket.on("changeDefaultTitlesChannelPlaylist", (data) => {this.changeDefaultTitlesChannelPlaylist(socket, data)});
|
||||||
|
socket.on("deleteChannelPlaylistMedia", (data) => {this.deleteChannelPlaylistMedia(socket, data)});
|
||||||
|
|
||||||
//User Playlist Listeners
|
//User Playlist Listeners
|
||||||
socket.on("getUserPlaylists", () => {this.getUserPlaylists(socket)});
|
socket.on("getUserPlaylists", () => {this.getUserPlaylists(socket)});
|
||||||
socket.on("createUserPlaylist", (data) => {this.createUserPlaylist(socket, data)});
|
socket.on("createUserPlaylist", (data) => {this.createUserPlaylist(socket, data)});
|
||||||
socket.on("deleteUserPlaylist", (data) => {this.deleteUserPlaylist(socket, data)});
|
socket.on("deleteUserPlaylist", (data) => {this.deleteUserPlaylist(socket, data)});
|
||||||
|
socket.on("addToUserPlaylist", (data) => {this.addToUserPlaylist(socket, data)});
|
||||||
|
socket.on("queueUserPlaylist", (data) => {this.queueUserPlaylist(socket, data)});
|
||||||
|
socket.on("queueFromUserPlaylist", (data) => {this.queueFromUserPlaylist(socket, data)});
|
||||||
|
socket.on("queueRandomFromUserPlaylist", (data) => {this.queueRandomFromUserPlaylist(socket, data)});
|
||||||
|
socket.on("renameUserPlaylist", (data) => {this.renameUserPlaylist(socket, data)});
|
||||||
|
socket.on("changeDefaultTitlesUserPlaylist", (data) => {this.changeDefaultTitlesUserPlaylist(socket, data)});
|
||||||
|
socket.on("deleteUserPlaylistMedia", (data) => {this.deleteUserPlaylistMedia(socket, data)});
|
||||||
|
}
|
||||||
|
|
||||||
|
//Validation/Sanatization functions
|
||||||
|
createPlaylistValidator(socket, data){
|
||||||
|
//Create empty array to hold titles
|
||||||
|
const safeTitles = [];
|
||||||
|
|
||||||
|
//If the title is too long
|
||||||
|
if(typeof data.playlist != 'string' || !validator.isLength(data.playlist, {min: 1, max:30})){
|
||||||
|
//Bitch, moan, complain...
|
||||||
|
loggerUtils.socketErrorHandler(socket, "Invalid Playlist Name!", "validation");
|
||||||
|
//and ignore it!
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(data.defaultTitles != null){
|
||||||
|
//For each default title passed by the data
|
||||||
|
for(let title of data.defaultTitles){
|
||||||
|
//If the title isn't too long
|
||||||
|
if(typeof title != 'string' || validator.isLength(title, {min:1, max:30})){
|
||||||
|
//Add it to the safe title list
|
||||||
|
safeTitles.push(validator.escape(validator.trim(title)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Escape/trim the playlist name
|
||||||
|
return {
|
||||||
|
playlist: validator.escape(validator.trim(data.playlist)),
|
||||||
|
defaultTitles: safeTitles
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async addToPlaylistValidator(socket, url){
|
||||||
|
//If we where given a bad URL
|
||||||
|
if(typeof url != 'string' || !validator.isURL(url)){
|
||||||
|
//Attempt to fix the situation by encoding it
|
||||||
|
url = encodeURI(url);
|
||||||
|
|
||||||
|
//If it's still bad
|
||||||
|
if(typeof url != 'string' || !validator.isURL(url)){
|
||||||
|
//Bitch, moan, complain...
|
||||||
|
loggerUtils.socketErrorHandler(socket, "Bad URL!", "validation");
|
||||||
|
//and ignore it!
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Pull media metadata
|
||||||
|
const mediaList = await yanker.yankMedia(url);
|
||||||
|
|
||||||
|
//If we didn't get any media
|
||||||
|
if(mediaList.length == 0 || mediaList == null){
|
||||||
|
//Bitch, moan, complain...
|
||||||
|
loggerUtils.socketErrorHandler(socket, "No media found!", "queue");
|
||||||
|
//and ignore it!
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mediaList;
|
||||||
|
}
|
||||||
|
|
||||||
|
queueFromChannelPlaylistValidator(socket, data){
|
||||||
|
//Validate UUID
|
||||||
|
if(typeof data.uuid != 'string' || !validator.isUUID(data.uuid)){
|
||||||
|
//Bitch, moan, complain...
|
||||||
|
loggerUtils.socketErrorHandler(socket, `'${data.uuid}' is not a valid UUID!`, "validation");
|
||||||
|
//and ignore it!
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//The UUID is only validated, not processed so we just return the new time :P
|
||||||
|
return this.channel.queue.getStart(data.start)
|
||||||
|
}
|
||||||
|
|
||||||
|
renameChannelPlaylistValidator(socket, data){
|
||||||
|
//If the title is too long
|
||||||
|
if(typeof data.name != 'string' || !validator.isLength(data.name, {min: 1, max:30})){
|
||||||
|
//Bitch, moan, complain...
|
||||||
|
loggerUtils.socketErrorHandler(socket, "Invalid playlist name!", "validation");
|
||||||
|
//and ignore it!
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Escape/trim the playlist name
|
||||||
|
return validator.escape(validator.trim(data.name));
|
||||||
|
}
|
||||||
|
|
||||||
|
changeDefaultTitlesValidator(data){
|
||||||
|
//Create empty array to hold titles
|
||||||
|
const safeTitles = [];
|
||||||
|
|
||||||
|
//For each default title passed by the data
|
||||||
|
for(let title of data.defaultTitles){
|
||||||
|
//If the title isn't too long or too short
|
||||||
|
if(typeof title != 'string' || validator.isLength(title, {min: 1, max:30})){
|
||||||
|
//Add it to the safe title list
|
||||||
|
safeTitles.push(validator.escape(validator.trim(title)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//return safe titles
|
||||||
|
return safeTitles;
|
||||||
|
}
|
||||||
|
|
||||||
|
deletePlaylistMediaValidator(socket, data){
|
||||||
|
//If we don't have a valid UUID
|
||||||
|
if(typeof data.uuid != 'string' || !validator.isUUID(data.uuid)){
|
||||||
|
//Bitch, moan, complain...
|
||||||
|
loggerUtils.socketErrorHandler(socket, `'${data.uuid}' is not a valid UUID!`, "validation");
|
||||||
|
//and ignore it!
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return data.uuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Get playlist functions
|
//Get playlist functions
|
||||||
|
|
@ -83,38 +205,17 @@ module.exports = class{
|
||||||
}
|
}
|
||||||
|
|
||||||
//Create playlist functions
|
//Create playlist functions
|
||||||
createPlaylistValidator(socket, data){
|
|
||||||
//Create empty array to hold titles
|
|
||||||
const safeTitles = [];
|
|
||||||
|
|
||||||
//If the title is too long
|
|
||||||
if(!validator.isLength(data.playlist, {min: 1, max:30})){
|
|
||||||
//Bitch, moan, complain...
|
|
||||||
loggerUtils.socketErrorHandler(socket, "Playlist name too long!", "validation");
|
|
||||||
//and ignore it!
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(data.defaultTitles != null){
|
|
||||||
//For each default title passed by the data
|
|
||||||
for(let title of data.defaultTitles){
|
|
||||||
//If the title isn't too long
|
|
||||||
if(validator.isLength(title, {min:1, max:30})){
|
|
||||||
//Add it to the safe title list
|
|
||||||
safeTitles.push(validator.escape(validator.trim(title)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Escape/trim the playlist name
|
|
||||||
return {
|
|
||||||
playlist: validator.escape(validator.trim(data.playlist)),
|
|
||||||
defaultTitles: safeTitles
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async createChannelPlaylist(socket, data, chanDB){
|
async createChannelPlaylist(socket, data, chanDB){
|
||||||
try{
|
try{
|
||||||
|
//Validate Data
|
||||||
|
const validData = this.createPlaylistValidator(socket, data);
|
||||||
|
|
||||||
|
//If we got bad data
|
||||||
|
if(validData == null){
|
||||||
|
//Do nothing
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//if we wherent handed a channel document
|
//if we wherent handed a channel document
|
||||||
if(chanDB == null){
|
if(chanDB == null){
|
||||||
//Pull it based on channel name
|
//Pull it based on channel name
|
||||||
|
|
@ -122,15 +223,6 @@ module.exports = class{
|
||||||
}
|
}
|
||||||
|
|
||||||
if(await chanDB.permCheck(socket.user, 'editChannelPlaylists')){
|
if(await chanDB.permCheck(socket.user, 'editChannelPlaylists')){
|
||||||
//Validate Data
|
|
||||||
const validData = this.createPlaylistValidator(socket, data);
|
|
||||||
|
|
||||||
//If we got bad data
|
|
||||||
if(validData == null){
|
|
||||||
//Do nothing
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//If the channel already exists
|
//If the channel already exists
|
||||||
if(chanDB.getPlaylistByName(validData.playlist) != null){
|
if(chanDB.getPlaylistByName(validData.playlist) != null){
|
||||||
//Bitch, moan, complain...
|
//Bitch, moan, complain...
|
||||||
|
|
@ -158,12 +250,6 @@ module.exports = class{
|
||||||
|
|
||||||
async createUserPlaylist(socket, data, userDB){
|
async createUserPlaylist(socket, data, userDB){
|
||||||
try{
|
try{
|
||||||
//if we wherent handed a user document
|
|
||||||
if(userDB == null){
|
|
||||||
//Find the user in the Database
|
|
||||||
userDB = await userModel.findOne({user: socket.request.session.user.user});
|
|
||||||
}
|
|
||||||
|
|
||||||
//Validate Data
|
//Validate Data
|
||||||
const validData = this.createPlaylistValidator(socket, data);
|
const validData = this.createPlaylistValidator(socket, data);
|
||||||
|
|
||||||
|
|
@ -173,6 +259,12 @@ module.exports = class{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//if we wherent handed a user document
|
||||||
|
if(userDB == null){
|
||||||
|
//Find the user in the Database
|
||||||
|
userDB = await userModel.findOne({user: socket.request.session.user.user});
|
||||||
|
}
|
||||||
|
|
||||||
//If the channel already exists
|
//If the channel already exists
|
||||||
if(userDB.getPlaylistByName(validData.playlist) != null){
|
if(userDB.getPlaylistByName(validData.playlist) != null){
|
||||||
//Bitch, moan, complain...
|
//Bitch, moan, complain...
|
||||||
|
|
@ -262,35 +354,19 @@ module.exports = class{
|
||||||
}
|
}
|
||||||
|
|
||||||
if(await chanDB.permCheck(socket.user, 'editChannelPlaylists')){
|
if(await chanDB.permCheck(socket.user, 'editChannelPlaylists')){
|
||||||
let url = data.url
|
//Normally I put validators before the DB call
|
||||||
|
//But this reqs a server-side fetch, so I'll do the perm check first :P
|
||||||
|
//Validate URL and pull media
|
||||||
|
const mediaList = await this.addToPlaylistValidator(socket, data.url);
|
||||||
|
|
||||||
//If we where given a bad URL
|
//If we encountered an error during validation
|
||||||
if(!validator.isURL(url)){
|
if(mediaList == null){
|
||||||
//Attempt to fix the situation by encoding it
|
//Fuck off and die
|
||||||
url = encodeURI(url);
|
return;
|
||||||
|
|
||||||
//If it's still bad
|
|
||||||
if(!validator.isURL(url)){
|
|
||||||
//Bitch, moan, complain...
|
|
||||||
loggerUtils.socketErrorHandler(socket, "Bad URL!", "validation");
|
|
||||||
//and ignore it!
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Pull media metadata
|
|
||||||
let mediaList = await yanker.yankMedia(url);
|
|
||||||
|
|
||||||
//If we didn't get any media
|
|
||||||
if(mediaList.length == 0 || mediaList == null){
|
|
||||||
//Bitch, moan, complain...
|
|
||||||
loggerUtils.socketErrorHandler(socket, "No media found!", "queue");
|
|
||||||
//and ignore it!
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Find the playlist
|
//Find the playlist
|
||||||
let playlist = chanDB.getPlaylistByName(data.playlist);
|
const playlist = chanDB.getPlaylistByName(data.playlist);
|
||||||
|
|
||||||
//If we didn't find a real playlist
|
//If we didn't find a real playlist
|
||||||
if(playlist == null){
|
if(playlist == null){
|
||||||
|
|
@ -314,6 +390,47 @@ module.exports = class{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async addToUserPlaylist(socket, data, userDB){
|
||||||
|
try{
|
||||||
|
//Validate URL and pull media
|
||||||
|
const mediaList = await this.addToPlaylistValidator(socket, data.url);
|
||||||
|
|
||||||
|
//If we encountered an error during validation
|
||||||
|
if(mediaList == null){
|
||||||
|
//Fuck off and die
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if we wherent handed a user document
|
||||||
|
if(userDB == null){
|
||||||
|
//Find the user in the Database
|
||||||
|
userDB = await userModel.findOne({user: socket.request.session.user.user});
|
||||||
|
}
|
||||||
|
|
||||||
|
//Find the playlist
|
||||||
|
const playlist = userDB.getPlaylistByName(data.playlist);
|
||||||
|
|
||||||
|
//If we didn't find a real playlist
|
||||||
|
if(playlist == null){
|
||||||
|
//Bitch, moan, complain...
|
||||||
|
loggerUtils.socketErrorHandler(socket, "Playlist not found!", "validation");
|
||||||
|
//and ignore it!
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//delete media from playlist
|
||||||
|
userDB.playlists[playlist.listIndex].addMedia(mediaList);
|
||||||
|
|
||||||
|
//save the channel document
|
||||||
|
await userDB.save();
|
||||||
|
|
||||||
|
//Return playlists from channel doc
|
||||||
|
this.getUserPlaylists(socket, userDB);
|
||||||
|
}catch(err){
|
||||||
|
return loggerUtils.socketExceptionHandler(socket, err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//Queuing Functions
|
//Queuing Functions
|
||||||
async queueChannelPlaylist(socket, data, chanDB){
|
async queueChannelPlaylist(socket, data, chanDB){
|
||||||
try{
|
try{
|
||||||
|
|
@ -348,7 +465,60 @@ module.exports = class{
|
||||||
let mediaObj = item.rehydrate();
|
let mediaObj = item.rehydrate();
|
||||||
|
|
||||||
//Set media title from default titles
|
//Set media title from default titles
|
||||||
mediaObj.title = playlist.pickDefaultTitle();
|
mediaObj.title = playlist.pickDefaultTitle(mediaObj.title);
|
||||||
|
|
||||||
|
//Push rehydrated item on to the mediaList
|
||||||
|
mediaList.push(mediaObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Convert array of standard media objects to queued media objects, and push to schedule
|
||||||
|
this.channel.queue.scheduleMedia(queuedMedia.fromMediaArray(mediaList, start), socket, chanDB);
|
||||||
|
}
|
||||||
|
}catch(err){
|
||||||
|
return loggerUtils.socketExceptionHandler(socket, err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async queueUserPlaylist(socket, data, userDB, chanDB){
|
||||||
|
try{
|
||||||
|
//if we wherent handed a user document
|
||||||
|
if(userDB == null){
|
||||||
|
//Find the user in the Database
|
||||||
|
userDB = await userModel.findOne({user: socket.request.session.user.user});
|
||||||
|
}
|
||||||
|
|
||||||
|
//if we wherent handed a channel document
|
||||||
|
if(chanDB == null){
|
||||||
|
//Pull it based on channel name
|
||||||
|
chanDB = await channelModel.findOne({name: this.channel.name});
|
||||||
|
}
|
||||||
|
|
||||||
|
//Permcheck to make sure the user can fuck w/ the queue
|
||||||
|
if((!this.channel.queue.locked && await chanDB.permCheck(socket.user, 'scheduleMedia')) || await chanDB.permCheck(socket.user, 'scheduleAdmin')){
|
||||||
|
//Pull a valid start time from input, or make one up if we can't
|
||||||
|
let start = this.channel.queue.getStart(data.start);
|
||||||
|
|
||||||
|
//Grab playlist from the DB
|
||||||
|
let playlist = userDB.getPlaylistByName(data.playlist);
|
||||||
|
|
||||||
|
//If we didn't find a real playlist
|
||||||
|
if(playlist == null){
|
||||||
|
//Bitch, moan, complain...
|
||||||
|
loggerUtils.socketErrorHandler(socket, "Playlist not found!", "validation");
|
||||||
|
//and ignore it!
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Create an empty array to hold our media list
|
||||||
|
const mediaList = [];
|
||||||
|
|
||||||
|
//Iterate through playlist media
|
||||||
|
for(let item of playlist.media){
|
||||||
|
//Rehydrate a full phat media object from the flat DB entry
|
||||||
|
let mediaObj = item.rehydrate();
|
||||||
|
|
||||||
|
//Set media title from default titles
|
||||||
|
mediaObj.title = playlist.pickDefaultTitle(mediaObj.title);
|
||||||
|
|
||||||
//Push rehydrated item on to the mediaList
|
//Push rehydrated item on to the mediaList
|
||||||
mediaList.push(mediaObj);
|
mediaList.push(mediaObj);
|
||||||
|
|
@ -364,6 +534,15 @@ module.exports = class{
|
||||||
|
|
||||||
async queueFromChannelPlaylist(socket, data, chanDB){
|
async queueFromChannelPlaylist(socket, data, chanDB){
|
||||||
try{
|
try{
|
||||||
|
//Validate data
|
||||||
|
const start = this.queueFromChannelPlaylistValidator(socket, data);
|
||||||
|
|
||||||
|
//If we had a validation issue
|
||||||
|
if(start == null){
|
||||||
|
//Fuck off and die
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//if we wherent handed a channel document
|
//if we wherent handed a channel document
|
||||||
if(chanDB == null){
|
if(chanDB == null){
|
||||||
//Pull it based on channel name
|
//Pull it based on channel name
|
||||||
|
|
@ -372,9 +551,6 @@ module.exports = class{
|
||||||
|
|
||||||
//Permcheck the user
|
//Permcheck the user
|
||||||
if((!this.channel.queue.locked && await chanDB.permCheck(socket.user, 'scheduleMedia')) || await chanDB.permCheck(socket.user, 'scheduleAdmin')){
|
if((!this.channel.queue.locked && await chanDB.permCheck(socket.user, 'scheduleMedia')) || await chanDB.permCheck(socket.user, 'scheduleAdmin')){
|
||||||
//Pull a valid start time from input, or make one up if we can't
|
|
||||||
let start = this.channel.queue.getStart(data.start);
|
|
||||||
|
|
||||||
//Grab playlist
|
//Grab playlist
|
||||||
const playlist = chanDB.getPlaylistByName(data.playlist);
|
const playlist = chanDB.getPlaylistByName(data.playlist);
|
||||||
|
|
||||||
|
|
@ -384,26 +560,67 @@ module.exports = class{
|
||||||
loggerUtils.socketErrorHandler(socket, "Playlist not found!", "validation");
|
loggerUtils.socketErrorHandler(socket, "Playlist not found!", "validation");
|
||||||
//and ignore it!
|
//and ignore it!
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//If we don't have a valid UUID
|
|
||||||
if(!validator.isUUID(data.uuid)){
|
|
||||||
//Bitch, moan, complain...
|
|
||||||
loggerUtils.socketErrorHandler(socket, `'${data.uuid}' is not a valid UUID!`, "validation");
|
|
||||||
//and ignore it!
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Pull and rehydrate media from playlist
|
//Pull and rehydrate media from playlist
|
||||||
const media = playlist.findMediaByUUID(data.uuid).rehydrate();
|
const media = playlist.findMediaByUUID(data.uuid).rehydrate();
|
||||||
|
|
||||||
//Set title from default titles
|
//Set title from default titles
|
||||||
media.title = playlist.pickDefaultTitle();
|
media.title = playlist.pickDefaultTitle(media.title);
|
||||||
|
|
||||||
//Queue found media
|
//Queue found media
|
||||||
this.channel.queue.scheduleMedia(queuedMedia.fromMediaArray([media], start), socket, chanDB);
|
this.channel.queue.scheduleMedia(queuedMedia.fromMediaArray([media], start), socket, chanDB);
|
||||||
}
|
}
|
||||||
|
}catch(err){
|
||||||
|
return loggerUtils.socketExceptionHandler(socket, err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async queueFromUserPlaylist(socket, data, userDB, chanDB){
|
||||||
|
try{
|
||||||
|
//Validate data
|
||||||
|
const start = this.queueFromChannelPlaylistValidator(socket, data);
|
||||||
|
|
||||||
|
//If we had a validation issue
|
||||||
|
if(start == null){
|
||||||
|
//Fuck off and die
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if we wherent handed a user document
|
||||||
|
if(userDB == null){
|
||||||
|
//Find the user in the Database
|
||||||
|
userDB = await userModel.findOne({user: socket.request.session.user.user});
|
||||||
|
}
|
||||||
|
|
||||||
|
//if we wherent handed a channel document
|
||||||
|
if(chanDB == null){
|
||||||
|
//Pull it based on channel name
|
||||||
|
chanDB = await channelModel.findOne({name: this.channel.name});
|
||||||
|
}
|
||||||
|
|
||||||
|
//Permcheck the user
|
||||||
|
if((!this.channel.queue.locked && await chanDB.permCheck(socket.user, 'scheduleMedia')) || await chanDB.permCheck(socket.user, 'scheduleAdmin')){
|
||||||
|
//Grab playlist
|
||||||
|
const playlist = userDB.getPlaylistByName(data.playlist);
|
||||||
|
|
||||||
|
//If we didn't find a real playlist
|
||||||
|
if(playlist == null){
|
||||||
|
//Bitch, moan, complain...
|
||||||
|
loggerUtils.socketErrorHandler(socket, "Playlist not found!", "validation");
|
||||||
|
//and ignore it!
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Pull and rehydrate media from playlist
|
||||||
|
const media = playlist.findMediaByUUID(data.uuid).rehydrate();
|
||||||
|
|
||||||
|
//Set title from default titles
|
||||||
|
media.title = playlist.pickDefaultTitle(media.title);
|
||||||
|
|
||||||
|
//Queue found media
|
||||||
|
this.channel.queue.scheduleMedia(queuedMedia.fromMediaArray([media], start), socket, chanDB);
|
||||||
|
}
|
||||||
}catch(err){
|
}catch(err){
|
||||||
return loggerUtils.socketExceptionHandler(socket, err);
|
return loggerUtils.socketExceptionHandler(socket, err);
|
||||||
}
|
}
|
||||||
|
|
@ -440,19 +657,17 @@ module.exports = class{
|
||||||
const foundMedia = playlist.media[foundID].rehydrate();
|
const foundMedia = playlist.media[foundID].rehydrate();
|
||||||
|
|
||||||
//Set title from default titles
|
//Set title from default titles
|
||||||
foundMedia.title = playlist.pickDefaultTitle();
|
foundMedia.title = playlist.pickDefaultTitle(foundMedia.title);
|
||||||
|
|
||||||
//Queue found media
|
//Queue found media
|
||||||
this.channel.queue.scheduleMedia(queuedMedia.fromMediaArray([foundMedia], start), socket, chanDB);
|
this.channel.queue.scheduleMedia(queuedMedia.fromMediaArray([foundMedia], start), socket, chanDB);
|
||||||
}
|
}
|
||||||
|
|
||||||
}catch(err){
|
}catch(err){
|
||||||
return loggerUtils.socketExceptionHandler(socket, err);
|
return loggerUtils.socketExceptionHandler(socket, err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Rename Channel Playlist
|
async queueRandomFromUserPlaylist(socket, data, userDB, chanDB){
|
||||||
async renameChannelPlaylist(socket, data, chanDB){
|
|
||||||
try{
|
try{
|
||||||
//if we wherent handed a channel document
|
//if we wherent handed a channel document
|
||||||
if(chanDB == null){
|
if(chanDB == null){
|
||||||
|
|
@ -460,19 +675,65 @@ module.exports = class{
|
||||||
chanDB = await channelModel.findOne({name: this.channel.name});
|
chanDB = await channelModel.findOne({name: this.channel.name});
|
||||||
}
|
}
|
||||||
|
|
||||||
if(await chanDB.permCheck(socket.user, 'editChannelPlaylists')){
|
//if we wherent handed a user document
|
||||||
//If the title is too long
|
if(userDB == null){
|
||||||
if(!validator.isLength(data.name, {max:30})){
|
//Find the user in the Database
|
||||||
|
userDB = await userModel.findOne({user: socket.request.session.user.user});
|
||||||
|
}
|
||||||
|
|
||||||
|
//Permcheck the user
|
||||||
|
if((!this.channel.queue.locked && await chanDB.permCheck(socket.user, 'scheduleMedia')) || await chanDB.permCheck(socket.user, 'scheduleAdmin')){
|
||||||
|
//Pull a valid start time from input, or make one up if we can't
|
||||||
|
let start = this.channel.queue.getStart(data.start);
|
||||||
|
|
||||||
|
//Grab playlist
|
||||||
|
const playlist = userDB.getPlaylistByName(data.playlist);
|
||||||
|
|
||||||
|
//If we didn't find a real playlist
|
||||||
|
if(playlist == null){
|
||||||
//Bitch, moan, complain...
|
//Bitch, moan, complain...
|
||||||
loggerUtils.socketErrorHandler(socket, "Playlist name too long!", "validation");
|
loggerUtils.socketErrorHandler(socket, "Playlist not found!", "validation");
|
||||||
//and ignore it!
|
//and ignore it!
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Escape/trim the playlist name
|
//Pick a random video ID based on the playlist's length
|
||||||
const name = validator.escape(validator.trim(data.name));
|
const foundID = Math.round(Math.random() * (playlist.media.length - 1));
|
||||||
|
|
||||||
//If the channel already exists
|
//Pull and rehydrate media from playlist
|
||||||
|
const foundMedia = playlist.media[foundID].rehydrate();
|
||||||
|
|
||||||
|
//Set title from default titles
|
||||||
|
foundMedia.title = playlist.pickDefaultTitle(foundMedia.title);
|
||||||
|
|
||||||
|
//Queue found media
|
||||||
|
this.channel.queue.scheduleMedia(queuedMedia.fromMediaArray([foundMedia], start), socket, chanDB);
|
||||||
|
}
|
||||||
|
}catch(err){
|
||||||
|
return loggerUtils.socketExceptionHandler(socket, err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Rename playlist functions
|
||||||
|
async renameChannelPlaylist(socket, data, chanDB){
|
||||||
|
try{
|
||||||
|
//Validate and Sanatize name
|
||||||
|
const name = this.renameChannelPlaylistValidator(socket, data);
|
||||||
|
|
||||||
|
//If validation fucked up
|
||||||
|
if(name == null){
|
||||||
|
//STOP
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if we wherent handed a channel document
|
||||||
|
if(chanDB == null){
|
||||||
|
//Pull it based on channel name
|
||||||
|
chanDB = await channelModel.findOne({name: this.channel.name});
|
||||||
|
}
|
||||||
|
|
||||||
|
if(await chanDB.permCheck(socket.user, 'editChannelPlaylists')){
|
||||||
|
//If the new name already exists
|
||||||
if(chanDB.getPlaylistByName(name) != null){
|
if(chanDB.getPlaylistByName(name) != null){
|
||||||
//Bitch, moan, complain...
|
//Bitch, moan, complain...
|
||||||
loggerUtils.socketErrorHandler(socket, `Playlist named '${name}' already exists!`, "validation");
|
loggerUtils.socketErrorHandler(socket, `Playlist named '${name}' already exists!`, "validation");
|
||||||
|
|
@ -505,7 +766,56 @@ module.exports = class{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Change Default Title Functions
|
async renameUserPlaylist(socket, data, userDB){
|
||||||
|
try{
|
||||||
|
//Validate and Sanatize name
|
||||||
|
const name = this.renameChannelPlaylistValidator(socket, data);
|
||||||
|
|
||||||
|
//If validation fucked up
|
||||||
|
if(name == null){
|
||||||
|
//STOP
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if we wherent handed a user document
|
||||||
|
if(userDB == null){
|
||||||
|
//Find the user in the Database
|
||||||
|
userDB = await userModel.findOne({user: socket.request.session.user.user});
|
||||||
|
}
|
||||||
|
|
||||||
|
//If the new name already exists
|
||||||
|
if(userDB.getPlaylistByName(name) != null){
|
||||||
|
//Bitch, moan, complain...
|
||||||
|
loggerUtils.socketErrorHandler(socket, `Playlist named '${name}' already exists!`, "validation");
|
||||||
|
//and ignore it!
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Find playlist
|
||||||
|
let playlist = userDB.getPlaylistByName(data.playlist);
|
||||||
|
|
||||||
|
//If we didn't find a real playlist
|
||||||
|
if(playlist == null){
|
||||||
|
//Bitch, moan, complain...
|
||||||
|
loggerUtils.socketErrorHandler(socket, "Playlist not found!", "validation");
|
||||||
|
//and ignore it!
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Change playlist name
|
||||||
|
userDB.playlists[playlist.listIndex].name = name;
|
||||||
|
|
||||||
|
//Save channel document
|
||||||
|
await userDB.save();
|
||||||
|
|
||||||
|
//Return playlists from channel doc
|
||||||
|
this.getUserPlaylists(socket, userDB);
|
||||||
|
}catch(err){
|
||||||
|
return loggerUtils.socketExceptionHandler(socket, err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Change default title list functions
|
||||||
async changeDefaultTitlesChannelPlaylist(socket, data, chanDB){
|
async changeDefaultTitlesChannelPlaylist(socket, data, chanDB){
|
||||||
try{
|
try{
|
||||||
//if we wherent handed a channel document
|
//if we wherent handed a channel document
|
||||||
|
|
@ -526,20 +836,8 @@ module.exports = class{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Create empty array to hold titles
|
//Keep valid default titles
|
||||||
const safeTitles = [];
|
chanDB.media.playlists[playlist.listIndex].defaultTitles = this.changeDefaultTitlesValidator(data);
|
||||||
|
|
||||||
//For each default title passed by the data
|
|
||||||
for(let title of data.defaultTitles){
|
|
||||||
//If the title isn't too long or too short
|
|
||||||
if(validator.isLength(title, {min: 1, max:30})){
|
|
||||||
//Add it to the safe title list
|
|
||||||
safeTitles.push(validator.escape(validator.trim(title)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Change playlist name
|
|
||||||
chanDB.media.playlists[playlist.listIndex].defaultTitles = safeTitles;
|
|
||||||
|
|
||||||
//Save channel document
|
//Save channel document
|
||||||
await chanDB.save();
|
await chanDB.save();
|
||||||
|
|
@ -552,9 +850,51 @@ module.exports = class{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Delete Playlist Functions
|
async changeDefaultTitlesUserPlaylist(socket, data, userDB){
|
||||||
|
try{
|
||||||
|
//if we wherent handed a user document
|
||||||
|
if(userDB == null){
|
||||||
|
//Find the user in the Database
|
||||||
|
userDB = await userModel.findOne({user: socket.request.session.user.user});
|
||||||
|
}
|
||||||
|
|
||||||
|
//Find playlist
|
||||||
|
let playlist = userDB.getPlaylistByName(data.playlist);
|
||||||
|
|
||||||
|
//If we didn't find a real playlist
|
||||||
|
if(playlist == null){
|
||||||
|
//Bitch, moan, complain...
|
||||||
|
loggerUtils.socketErrorHandler(socket, "Playlist not found!", "validation");
|
||||||
|
//and ignore it!
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Keep valid de.mediafault titles
|
||||||
|
userDB.playlists[playlist.listIndex].defaultTitles = this.changeDefaultTitlesValidator(data);
|
||||||
|
|
||||||
|
//Save user document
|
||||||
|
await userDB.save();
|
||||||
|
|
||||||
|
//Return playlists from user doc
|
||||||
|
this.getUserPlaylists(socket, userDB);
|
||||||
|
}catch(err){
|
||||||
|
return loggerUtils.socketExceptionHandler(socket, err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Delete playlist media functions
|
||||||
async deleteChannelPlaylistMedia(socket, data, chanDB){
|
async deleteChannelPlaylistMedia(socket, data, chanDB){
|
||||||
try{
|
try{
|
||||||
|
//Validate UUID
|
||||||
|
const uuid = this.deletePlaylistMediaValidator(socket, data);
|
||||||
|
|
||||||
|
//If we failed validation
|
||||||
|
if(uuid == null){
|
||||||
|
//fuck off
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//if we wherent handed a channel document
|
//if we wherent handed a channel document
|
||||||
if(chanDB == null){
|
if(chanDB == null){
|
||||||
//Pull it based on channel name
|
//Pull it based on channel name
|
||||||
|
|
@ -562,14 +902,6 @@ module.exports = class{
|
||||||
}
|
}
|
||||||
|
|
||||||
if(await chanDB.permCheck(socket.user, 'editChannelPlaylists')){
|
if(await chanDB.permCheck(socket.user, 'editChannelPlaylists')){
|
||||||
//If we don't have a valid UUID
|
|
||||||
if(!validator.isUUID(data.uuid)){
|
|
||||||
//Bitch, moan, complain...
|
|
||||||
loggerUtils.socketErrorHandler(socket, `'${data.uuid}' is not a valid UUID!`, "validation");
|
|
||||||
//and ignore it!
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Find the playlist
|
//Find the playlist
|
||||||
let playlist = chanDB.getPlaylistByName(data.playlist);
|
let playlist = chanDB.getPlaylistByName(data.playlist);
|
||||||
|
|
||||||
|
|
@ -594,4 +926,45 @@ module.exports = class{
|
||||||
return loggerUtils.socketExceptionHandler(socket, err);
|
return loggerUtils.socketExceptionHandler(socket, err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async deleteUserPlaylistMedia(socket, data, userDB){
|
||||||
|
try{
|
||||||
|
//Validate UUID
|
||||||
|
const uuid = this.deletePlaylistMediaValidator(socket, data);
|
||||||
|
|
||||||
|
//If we failed validation
|
||||||
|
if(uuid == null){
|
||||||
|
//fuck off
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if we wherent handed a user document
|
||||||
|
if(userDB == null){
|
||||||
|
//Find the user in the Database
|
||||||
|
userDB = await userModel.findOne({user: socket.request.session.user.user});
|
||||||
|
}
|
||||||
|
|
||||||
|
//Find the playlist
|
||||||
|
let playlist = userDB.getPlaylistByName(data.playlist);
|
||||||
|
|
||||||
|
//If we didn't find a real playlist
|
||||||
|
if(playlist == null){
|
||||||
|
//Bitch, moan, complain...
|
||||||
|
loggerUtils.socketErrorHandler(socket, "Playlist not found!", "validation");
|
||||||
|
//and ignore it!
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//delete media from playlist
|
||||||
|
userDB.playlists[playlist.listIndex].deleteMedia(data.uuid);
|
||||||
|
|
||||||
|
//save the user document
|
||||||
|
await userDB.save();
|
||||||
|
|
||||||
|
//Return playlists from user doc
|
||||||
|
this.getUserPlaylists(socket, userDB);
|
||||||
|
}catch(err){
|
||||||
|
return loggerUtils.socketExceptionHandler(socket, err);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -91,9 +91,19 @@ playlistSchema.methods.deleteMedia = function(uuid){
|
||||||
this.media = keptMedia;
|
this.media = keptMedia;
|
||||||
}
|
}
|
||||||
|
|
||||||
playlistSchema.methods.pickDefaultTitle = function(){
|
playlistSchema.methods.pickDefaultTitle = function(title){
|
||||||
//Grab a random default title and return it
|
//If we don't have default titles in this playlist
|
||||||
return this.defaultTitles[Math.floor(Math.random() * this.defaultTitles.length)];
|
if(this.defaultTitles.length <= 0){
|
||||||
|
//If we wheren't handed an original title
|
||||||
|
if(title == null || title == ''){
|
||||||
|
return 'Unnamed Media'
|
||||||
|
}else{
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
//Grab a random default title and return it
|
||||||
|
return this.defaultTitles[Math.floor(Math.random() * this.defaultTitles.length)];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = playlistSchema;
|
module.exports = playlistSchema;
|
||||||
Loading…
Reference in a new issue