From c081d9c4ffcf5b5f24c2ff43ea8510f4c3a29437 Mon Sep 17 00:00:00 2001 From: rainbow napkin Date: Thu, 15 Oct 2026 20:33:27 -0400 Subject: [PATCH] Updated queue.js to allow clients to search archive by title or URL --- src/app/channel/media/queue.js | 155 ++++++++++++++++++++++++--------- 1 file changed, 112 insertions(+), 43 deletions(-) diff --git a/src/app/channel/media/queue.js b/src/app/channel/media/queue.js index f74b0f0..b6871f2 100644 --- a/src/app/channel/media/queue.js +++ b/src/app/channel/media/queue.js @@ -518,30 +518,7 @@ class queue{ */ 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}); @@ -551,12 +528,86 @@ class queue{ return; } - //Create new date objects to represent range of data requested - const startDate = new Date(data.startDate); - const endDate = new Date(data.endDate); + let startDate = undefined; + let endDate = undefined; + let title = undefined; + let url = undefined - //Grab archives from given range, and send them back to the requesting socket - socket.emit("archive", {archive: await this.prepArchive(startDate, endDate)}); + //If we where supplied with a start date + if(data.startDate != null){ + //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; + } + + + //Store validated start date as new date object + startDate = new Date(data.startDate); + } + + if(data.endDate != null){ + //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 != null && data.startDate >= data.endDate){ + //Bitch, moan, an' complain! + loggerUtils.socketErrorHandler(socket, "Invalid Date Range!", "validation"); + //Yeetus-Deletus bitch + return; + } + + //Store validated endDate as new date object + endDate = new Date(data.endDate); + } + + + //If we have a valid title + if(data.title != null && data.title != ''){ + //If the title is too long + if(!validator.isLength(data.title, {max:30})){ + //Bitch, moan, complain... + loggerUtils.socketErrorHandler(socket, "Title too long!", "validation"); + //and ignore it! + return; + } + + //Sanatize, trim, and keep the title + title = validator.escape(validator.trim(data.title)); + } + + //If we were given a URL + if(data.url != null && data.url != ''){ + //Set URL + url = data.url; + + //If we were given a bad URL + if(!validator.isURL(url,{require_valid_protocol: true})){ + //Attempt to fix the situation by encoding it + url = encodeURI(url); + + //If it's still bad + if(!validator.isURL(url,{require_valid_protocol: true})){ + //Bitch, moan, complain... + loggerUtils.socketErrorHandler(socket, "Bad URL!", "validation"); + //and ignore it! + return; + } + } + } + + + + //Grab archives from given range, and send them back to the requesting socket, providing result as search result if search was requested + socket.emit(data.search ? "archiveSearch" : "archive", {archive: await this.prepArchive(startDate, endDate, title, url)}); }catch(err){ return loggerUtils.socketExceptionHandler(socket, err); } @@ -1903,12 +1954,20 @@ class queue{ } } - async prepArchive(startDate, endDate = new Date()){ + /** + * Preps archive for network transmission to clients + * @param {Date} startDate - Start date to pass to archive query + * @param {Date} endDate - end date to pass to archive query + * @param {String} title - title to search through archive for + * @param {String} url - URL to pass to archive query + * @returns Array of archived media objects prepped for network transmission. + */ + async prepArchive(startDate, endDate = new Date(), title, url){ //Define array to hold prepped archive objects const preppedArchive = []; //Get archive since yesterday - const archive = await this.queryArchive(startDate, endDate); + const archive = await this.queryArchive(startDate, endDate, url); //Iterate through the channel archive backwards to save time for(let mediaIndex = archive.length - 1; mediaIndex >= 0; mediaIndex--){ @@ -1921,8 +1980,11 @@ class queue{ 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]); + //If requested title is unspecified or was found in the in the media's title + if((title == null || title == '') || media.title.includes(title)){ + //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; @@ -2062,21 +2124,28 @@ class queue{ * Get Channel Archive * @param {Date} startDate - Start of range to grab from * @param {Date} endDate - End of range to grab from + * @param {String} url - URL to search for */ - async queryArchive(startDate, endDate = new Date()){ + async queryArchive(startDate, endDate = new Date(), url){ + //Define object to contain our DB query + const dbQuery = { + channel: this.channel._id + }; + //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()}) - }); - //Otherwise - }else{ - //return all archived media - return await archivedMediaModel.find({channel:this.channel._id}); + //Specify start/end datetime, this one needs to be unsantized for it to werk, I figure its taking in numbers returned by a server-side function, this is fine + dbQuery.startTime = mongoose.trusted({$gt: startDate.getTime(), $lt: endDate.getTime()}); } + + //Do I really need to re-type this shit for the url? + if(url != null && url != ''){ + //Search for exact URL matches + dbQuery.url = {$eq: url}; + } + + //return archived media based on resulting query + return await archivedMediaModel.find(dbQuery); } }