diff --git a/src/app/channel/media/queue.js b/src/app/channel/media/queue.js index 75399fd..d6610f7 100644 --- a/src/app/channel/media/queue.js +++ b/src/app/channel/media/queue.js @@ -263,6 +263,9 @@ module.exports = class{ return now; } } + + //If we fell through, just return input + return start; } refreshNextTimer(volatile = false){ @@ -522,95 +525,111 @@ module.exports = class{ https://community.appsmith.com/content/blog/dark-side-foreach-why-you-should-think-twice-using-it */ - let mediaObj = media[0]; - - //If someone is trying to schedule something that starts and ends in the past - if((mediaObj.getEndTime() < new Date().getTime()) && !force){ - //If an originating socket was provided for this request - if(socket != null){ - //Yell at the user for being an asshole - loggerUtils.socketErrorHandler(socket, "You cannot alter the past!", "queue"); + for(let mediaObj of media){ + //If someone is trying to schedule something that starts and ends in the past + if((mediaObj.getEndTime() < new Date().getTime()) && !force){ + //If an originating socket was provided for this request + if(socket != null){ + //Yell at the user for being an asshole + loggerUtils.socketErrorHandler(socket, "You cannot alter the past!", "queue"); + } + return false; } - return false; - } - //If the item has already started - if((mediaObj.startTime < new Date().getTime()) && !force){ - //Set time stamp to existing timestamp plus the difference between the orginal start-date and now - const calculatedTimeStamp = mediaObj.startTimeStamp + ((new Date().getTime() - mediaObj.startTime) / 1000) + //If the item has already started + if((mediaObj.startTime < new Date().getTime()) && !force){ + //Set time stamp to existing timestamp plus the difference between the orginal start-date and now + const calculatedTimeStamp = mediaObj.startTimeStamp + ((new Date().getTime() - mediaObj.startTime) / 1000) - //If the calculated time stamp is more than negligible, and therefore not simply caused by serverside processing time - if(calculatedTimeStamp > 5){ - //Set the media timestamp - mediaObj.startTimeStamp = calculatedTimeStamp; + //If the calculated time stamp is more than negligible, and therefore not simply caused by serverside processing time + if(calculatedTimeStamp > 5){ + //Set the media timestamp + mediaObj.startTimeStamp = calculatedTimeStamp; - //Start the item now - mediaObj.startTime = new Date().getTime(); + //Start the item now + mediaObj.startTime = new Date().getTime(); + } + } + + //If there's already something queued right now + if(this.getItemAtEpoch(mediaObj.startTime) != null || this.getItemAtEpoch(mediaObj.getEndTime())){ + //If an originating socket was provided for this request + if(socket != null){ + //Yell at the user for being an asshole + loggerUtils.socketErrorHandler(socket, "This time slot has already been taken in the queue!", "queue"); + } + //Ignore it + return false; + } + + //Create an empty temp array to sparsley populate with our schedule + const tempSchedule = []; + //Create new map to replace our current schedule map + const newSchedule = new Map(); + + //For every item that's already been scheduled + for(let item of this.schedule){ + //add it to the slot corresponding to it's start epoch in seconds + tempSchedule[Math.round(item[0] / 1000)] = item[1]; + } + + //Inject the media object into the slot corresponding to it's epoch in the temp schedule array + tempSchedule[Math.round(mediaObj.startTime / 1000)] = mediaObj; + + //For every populated key in our array + for(let startTime of Object.keys(tempSchedule)){ + //Add item to replacement schedule map + newSchedule.set(tempSchedule[startTime].startTime, tempSchedule[startTime]); + } + + //Replace the existing schedule map with our new one + this.schedule = newSchedule; + + //Broadcast the channel queue + this.broadcastQueue(); + + //Refresh the next timer to ensure whatever comes on next is right + this.refreshNextTimer(startVolatile); + + //If media has more than a minute before starting and DB transactions are enabled + if(mediaObj.startTime - new Date().getTime() > 1000 && !volatile){ + //fuck you yoda you fucking nerd + try{ + //If we didn't get handed a freebie + if(chanDB == null){ + //Go out and get it done ourselves + chanDB = await channelModel.findOne({name:this.channel.name}); + } + + //If we couldn't find the channel + if(chanDB == null){ + //FUCK + throw new Error(`Unable to find channel document ${this.channel.name} while saving item to queue!`); + } + + //Add media to the persistant schedule + chanDB.media.scheduled.push(mediaObj); + + //If something fucked up + }catch(err){ + //If this was originated by someone + if(socket != null){ + //Bitch at them + loggerUtils.socketExceptionHandler(socket, err); + //If not + }else{ + //Bitch to the console + loggerUtils.localExceptionHandler(err); + } + } } } - //If there's already something queued right now - if(this.getItemAtEpoch(mediaObj.startTime) != null || this.getItemAtEpoch(mediaObj.getEndTime())){ - //If an originating socket was provided for this request - if(socket != null){ - //Yell at the user for being an asshole - loggerUtils.socketErrorHandler(socket, "This time slot has already been taken in the queue!", "queue"); - } - //Ignore it - return false; - } - - //Create an empty temp array to sparsley populate with our schedule - const tempSchedule = []; - //Create new map to replace our current schedule map - const newSchedule = new Map(); - - //For every item that's already been scheduled - for(let item of this.schedule){ - //add it to the slot corresponding to it's start epoch in seconds - tempSchedule[Math.round(item[0] / 1000)] = item[1]; - } - - //Inject the media object into the slot corresponding to it's epoch in the temp schedule array - tempSchedule[Math.round(mediaObj.startTime / 1000)] = mediaObj; - - //For every populated key in our array - for(let startTime of Object.keys(tempSchedule)){ - //Add item to replacement schedule map - newSchedule.set(tempSchedule[startTime].startTime, tempSchedule[startTime]); - } - - //Replace the existing schedule map with our new one - this.schedule = newSchedule; - - //Broadcast the channel queue - this.broadcastQueue(); - - //Refresh the next timer to ensure whatever comes on next is right - this.refreshNextTimer(startVolatile); - - //If media has more than a minute before starting and DB transactions are enabled - if(mediaObj.startTime - new Date().getTime() > 1000 && !volatile){ - //fuck you yoda you fucking nerd + //If we fucked with the DB during the main loop + if(chanDB == null && !volatile){ try{ - //If we didn't get handed a freebie - if(chanDB == null){ - //Go out and get it done ourselves - chanDB = await channelModel.findOne({name:this.channel.name}); - } - - //If we couldn't find the channel - if(chanDB == null){ - //FUCK - throw new Error(`Unable to find channel document ${this.channel.name} while saving item to queue!`); - } - - //Add media to the persistant schedule - chanDB.media.scheduled.push(mediaObj); - //Save the database chanDB.save(); - //If something fucked up }catch(err){ //If this was originated by someone @@ -625,8 +644,8 @@ module.exports = class{ } } - //return media object for use - return mediaObj; + //return true to let everyone know this shit worked + return true; } async start(mediaObj, timestamp = mediaObj.startTimeStamp, volatile = false){ @@ -964,7 +983,6 @@ module.exports = class{ //Add record to new schedule newSched.push(record); - //Re-Schedule it in RAM await this.scheduleMedia([mediaObj], null, chanDB, true, true, false); }else{