diff --git a/src/app/channel/media/queue.js b/src/app/channel/media/queue.js index f74b0f0..0a5ebaa 100644 --- a/src/app/channel/media/queue.js +++ b/src/app/channel/media/queue.js @@ -131,7 +131,6 @@ class queue{ socket.on("lock", () => {this.toggleLock(socket)}); socket.on("goLive", (data) => {this.goLive(socket, data)}); socket.on("getStreamType", (data) => {this.getStreamType(socket)}); - socket.on("getArchive", (data) => {this.getArchive(socket, data)}); //If debug mode is enabled if(config.debug){ @@ -511,57 +510,6 @@ class queue{ } } - /** - * Returns current channel stream type upon request - * @param {Socket} socket - Socket we received the request from - * @param {Object} data - Event payload - */ - async getArchive(socket, data){ - try{ - //If we get an invalid start date - if(typeof data.startDate != "number" || data.startDate < 0){ - //Bitch, moan, an' complain! - loggerUtils.socketErrorHandler(socket, "Invalid Start Date!", "validation"); - //Yeetus-Deletus bitch - return; - } - - //If we get an invalid start date - if(typeof data.endDate != "number" || data.endDate < 0){ - //Bitch, moan, an' complain! - loggerUtils.socketErrorHandler(socket, "Invalid End Date!", "validation"); - //Yeetus-Deletus bitch - return; - } - - //If our startDate isn't before our endDate - if(data.startDate >= data.endDate){ - //Bitch, moan, an' complain! - loggerUtils.socketErrorHandler(socket, "Invalid Date Range!", "validation"); - //Yeetus-Deletus bitch - return; - } - - //Get the current channel from the database - const chanDB = await channelModel.findOne({name: socket.chan}); - - //If the user isn't allowed to read the schedule - if(!await chanDB.permCheck(socket.user, 'readSchedule')){ - //Fuckin ignore em' - return; - } - - //Create new date objects to represent range of data requested - const startDate = new Date(data.startDate); - const endDate = new Date(data.endDate); - - //Grab archives from given range, and send them back to the requesting socket - socket.emit("archive", {archive: await this.prepArchive(startDate, endDate)}); - }catch(err){ - return loggerUtils.socketExceptionHandler(socket, err); - } - } - async dumpQueue(socket, data){ //If we somehow got here while config.debug is disabled, or the user isn't allowed to preform server-side debugging if(!(config.debug && await permissionModel.permCheck(socket.user, "debug"))){ @@ -574,7 +522,7 @@ class queue{ //Pull the channel DB doc const chanDB = await channelModel.findOne({name:this.channel.name}); //Pull archived media by channel name - const archived = await this.queryArchive(); + const archived = await this.getArchive(); //Cook and emit a new object from all of the data socket.emit("dumpQueue", { @@ -1000,7 +948,7 @@ class queue{ //If broadcasting is enabled if(!noBroadcast){ //Broadcast the channel - this.broadcastQueue(); + this.broadcastQueue(chanDB); } }catch(err){ @@ -1290,7 +1238,7 @@ class queue{ await chanDB.save(); //Broadcast queue since we ended our media item early - this.broadcastQueue(); + this.broadcastQueue(chanDB); }catch(err){ loggerUtils.localExceptionHandler(err); } @@ -1436,7 +1384,7 @@ class queue{ } //broadcast queue using unsaved archive, run this before chanDB.save() for better responsiveness - this.broadcastQueue(); + this.broadcastQueue(chanDB); //Save our changes to the DB await chanDB.save(); @@ -1677,7 +1625,7 @@ class queue{ await this.scheduleMedia(newSched, null, chanDB); //Broadcast the queue now that everything is hunky dory - await this.broadcastQueue(); + await this.broadcastQueue(chanDB); }catch(err){ //Null out live remainder for the next stream this.liveRemainder = null; @@ -1851,49 +1799,71 @@ class queue{ /** * Broadcasts channel queue + * @param {Mongoose.Document} chanDB - Pass through Channel Document to save on DB Transactions */ - async broadcastQueue(){ + async broadcastQueue(chanDB){ //Broadcast queue to authenticated sockets within the channels room inside the protected 'queue-broadcast' namespace - this.server.queueBroadcastManager.namespace.in(this.channel.name).emit('queue',{queue: await this.prepQueue()}); + this.server.queueBroadcastManager.namespace.in(this.channel.name).emit('queue',{queue: await this.prepQueue(chanDB)}); } /** * Broadcasts channel queue to a single socket + * @param {Mongoose.Document} chanDB - Pass through Channel Document to save on DB Transactions * @param {Socket} socket - Socket to send queue to */ - async emitQueue(socket){ + async emitQueue(chanDB, socket){ //Broadcast queue to authenticated sockets within the channels room inside the protected 'queue-broadcast' namespace - socket.emit('queue',{queue: await this.prepQueue()}); - } - - /** - * Broadcasts channel queue to a single socket - * @param {Date} startDate - Start date to pull archives from - * @param {Date} endDate - Start date to pull archives from - * @param {Socket} socket - Socket to send queue to - */ - async emitArchive(startDate, endDate, socket){ - //Broadcast queue to authenticated sockets within the channels room inside the protected 'queue-broadcast' namespace - socket.emit('queue',{queue: await this.prepArchive(startDate, endDate)}); + socket.emit('queue',{queue: await this.prepQueue(chanDB)}); } /** * Prepares channel queue for network transmission + * @param {Mongoose.Document} chanDB - Pass through Channel Document to save on DB Transactions * @returns de-hydrated scehdule information */ - async prepQueue(){ + async prepQueue(chanDB){ 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 loggerUtils.exceptionSmith(`Unable to find channel document ${this.channel.name} while rehydrating queue!`, "queue"); + } + + //Create an empty array to hold our schedule + let schedule = []; + //Get todays epoch const yesterday = new Date(); //Make it yesterdays yesterday.setDate(yesterday.getDate() - 1); - //Prep archive from yesterday - const archive = await this.prepArchive(yesterday); + //Get archive since yesterday + const archive = await this.getArchive(yesterday); + + //Iterate through the channel archive backwards to save time + for(let mediaIndex = archive.length - 1; mediaIndex >= 0; mediaIndex--){ + //Grab the current media record + let media = archive[mediaIndex].rehydrate(); + + //If we're sending out the live remainder during a live stream + if(this.liveRemainder != null && media.uuid.toString() == this.liveRemainder.uuid.toString()){ + //Throw out the early end before sending it off, so it looks like it hasn't been cut off yet (smoke n mirrors :P) + media.earlyEnd = null; + } + + //Add it to the temporary schedule array as if it where part of the actual schedule map + schedule.unshift([media.startTime, media]); + } //Concatonate the actual schedule to the items we pulled out of the archive return it - return archive.concat(Array.from(this.schedule)); + return schedule.concat(Array.from(this.schedule)); //If we can't get shit from the database }catch(err){ //Complain @@ -1903,31 +1873,6 @@ class queue{ } } - async prepArchive(startDate, endDate = new Date()){ - //Define array to hold prepped archive objects - const preppedArchive = []; - - //Get archive since yesterday - const archive = await this.queryArchive(startDate, endDate); - - //Iterate through the channel archive backwards to save time - for(let mediaIndex = archive.length - 1; mediaIndex >= 0; mediaIndex--){ - //Grab the current media record - let media = archive[mediaIndex].rehydrate(); - - //If we're sending out the live remainder during a live stream - if(this.liveRemainder != null && media.uuid.toString() == this.liveRemainder.uuid.toString()){ - //Throw out the early end before sending it off, so it looks like it hasn't been cut off yet (smoke n mirrors :P) - media.earlyEnd = null; - } - - //Add it to the temporary preppd archive array as if it where part of the actual schedule map - preppedArchive.unshift([media.startTime, media]); - } - - return preppedArchive; - } - /** * Rehydrates media schedule from DB * @param {Mongoose.Document} chanDB - Pass through Channel Document to save on DB Transactions @@ -2001,7 +1946,7 @@ class queue{ //If we have a remainder from a livestream if(chanDB.media.liveRemainder){ - let archive = await this.queryArchive(); + let archive = await this.getArchive(); //Iterate backwards through channel archive @@ -2060,17 +2005,15 @@ class queue{ /** * Get Channel Archive - * @param {Date} startDate - Start of range to grab from - * @param {Date} endDate - End of range to grab from */ - async queryArchive(startDate, endDate = new Date()){ + async getArchive(startDate){ //If we provided a start date if(startDate != null){ //Return archived media after start date return await archivedMediaModel.find({ channel:this.channel._id, //Prevent mongoose from attempting to sanatize and invalidate our query object, plus I think we can trust an epoch that came from server-side :) - startTime: mongoose.trusted({$gt: startDate.getTime(), $lt: endDate.getTime()}) + startTime: mongoose.trusted({$gt: startDate.getTime()}) }); //Otherwise }else{ diff --git a/src/app/channel/media/queueBroadcastManager.js b/src/app/channel/media/queueBroadcastManager.js index f2ee20f..7f8e319 100644 --- a/src/app/channel/media/queueBroadcastManager.js +++ b/src/app/channel/media/queueBroadcastManager.js @@ -79,7 +79,7 @@ class queueBroadcastManager extends auxServer{ socket.join(socket.chan); //Send the queue down to our newly connected user - activeChannel.queue.emitQueue(socket); + activeChannel.queue.emitQueue(chanDB, socket); //Define listeners this.defineListeners(socket); diff --git a/www/js/channel/channel.js b/www/js/channel/channel.js index 13d2bda..6b5e535 100644 --- a/www/js/channel/channel.js +++ b/www/js/channel/channel.js @@ -126,10 +126,6 @@ class channel{ this.queueBroadcastSocket.on("queue", (data) => { this.queue = new Map(data.queue); }); - - this.socket.on("archive", (data) =>{ - this.sortQueue(data.archive); - }) } /** @@ -161,39 +157,6 @@ class channel{ this.streamType = data.streamType; } - /** - * Sorts queue, optionally adding new items along the way - * @param {object} queueData - Contains list of entries to add to the queue - */ - sortQueue(queueData){ - //Create array to temporary sort schedule within - const tempSched = []; - //Get current queue as entries - let entries = Array.from(this.queue.entries()); - - //Blow-out existing queue since we've already pulled out the data we need from it - this.queue = new Map(); - - - //If we have new queue data - if(queueData != null){ - //Concat passed queue data to beggining of entries pulled from queue map - entries = queueData.concat(entries); - } - - //For each media entry accounted for - for(let entry of entries){ - //Store entry item in array indexed to its start epoch in seconds - tempSched[Math.round(entry[0] / 1000)] = entry[1]; - } - - //Iterate through populated indices of tempSched to skip over empty indexes, just like in the server-side - for(let startTime of Object.keys(tempSched)){ - //Add each entry to the queue in order of start time - this.queue.set(tempSched[startTime].startTime, tempSched[startTime]); - } - } - /** * Processes and applies default config on any unset settings * @param {Boolean} force - Whether or not to forcefully reset already set settings diff --git a/www/js/channel/panels/queuePanel/queuePanel.js b/www/js/channel/panels/queuePanel/queuePanel.js index 50a9dee..5f49000 100644 --- a/www/js/channel/panels/queuePanel/queuePanel.js +++ b/www/js/channel/panels/queuePanel/queuePanel.js @@ -142,8 +142,7 @@ class queuePanel extends panelObj{ defineListeners(){ //Render queue when we receive a new copy of the queue data from the server //Render queue should be called within an arrow function so that it's called with default parameters, and not handed an event as a date - this.client.queueBroadcastSocket.on("queue", this.renderQueue.bind(this)); - this.client.socket.on("archive", this.renderQueue.bind(this)); + this.client.queueBroadcastSocket.on("queue", () => {this.renderQueue();}); this.client.socket.on("start", this.handleStart.bind(this)); this.client.socket.on("end", this.handleEnd.bind(this)); this.client.socket.on("lock", this.handleScheduleLock.bind(this)); @@ -492,20 +491,6 @@ class queuePanel extends panelObj{ //Re-render/hide the time marker this.renderTimeMarker(); - //If we're not looking at today - if(!utils.isSameDate(date, new Date())){ - //Clone given epoch twice - const dayBefore = new Date(date.getTime()); - const dayAfter = new Date(date.getTime()); - - //Make it a day before/after - dayBefore.setDate(dayBefore.getDate() - 1); - dayAfter.setDate(dayAfter.getDate() + 1); - - //Request the archives from that day - this.client.socket.emit("getArchive", {startDate: dayBefore.getTime(), endDate: dayAfter.getTime()}); - } - //If autoscroll is enabled if(this.autoscroll){ //Simulate a button click to un/re-light the button and trigger a scroll when the date is set to today