From 8adc5c193ac992954aec57ee477920103bcbf43a Mon Sep 17 00:00:00 2001 From: Ajay Ramachandran Date: Wed, 17 Apr 2019 08:32:24 -0400 Subject: [PATCH 01/32] Added what match the maximum performance happened in. Resolves https://github.com/LakeEffectRobotics/LakeEffectScoutingApp/issues/285. --- summarizer.js | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/summarizer.js b/summarizer.js index 42b5008..48e0945 100644 --- a/summarizer.js +++ b/summarizer.js @@ -382,7 +382,27 @@ function getActionSummary(currentRobotNumber, labels, robots, searchTerm) { //it will find the minimum misses in the matches where they scored the most (the best performance) let missMinItems = getMinItems(maxMissItems); - fullSummary += searchTerm + " Max " + hitMaxItems[0][0] + " : " + missMinItems[0] + "
"; + //get match number index to show what match this happened in + let matchNumColumn = getColumnIndex(labels, "match"); + + //string of what match numbers this max happened in + let matchNumbersOfMaximums = ""; + for (let i = 0; i < hitMaxItems.length; i++) { + matchNumbersOfMaximums += robots[matchNumColumn].data[hitMaxItems[i][1]][matchNumColumn]; + + if (i != hitMaxItems.length - 1) { + //if it is not the last index + matchNumbersOfMaximums += ", "; + } + } + + if (hitMaxItems[0][0] === "0") { + //there is no maximum, so it doesn't matter + //it would just list every match + matchNumbersOfMaximums = "N/A"; + } + + fullSummary += searchTerm + " Max " + hitMaxItems[0][0] + " : " + missMinItems[0] + " in match " + matchNumbersOfMaximums + "
"; //return resulted summary return fullSummary; From daf8a0698fe32a1c72a0e8dfcf8ad96ffdff8f73 Mon Sep 17 00:00:00 2001 From: Ajay Ramachandran Date: Fri, 19 Apr 2019 15:51:01 -0400 Subject: [PATCH 02/32] Added ability to get striaght to the raw data when clicking on the summarized data. The correct raw data is pulled up and the window automatically scrolls down to the custom data section. --- index.html | 4 ++- index.js | 91 +++++++++++++++++++++++++++++++++++++-------------- summarizer.js | 2 ++ 3 files changed, 72 insertions(+), 25 deletions(-) diff --git a/index.html b/index.html index a67e798..62e9d3d 100644 --- a/index.html +++ b/index.html @@ -50,7 +50,9 @@

Pre-match Info (click to hide/show)

-

Custom Info (click to hide/show)

+ +

Custom Info (click to hide/show)

+
diff --git a/index.js b/index.js index 8c4b951..2b00b0a 100644 --- a/index.js +++ b/index.js @@ -13,10 +13,10 @@ var currentRobotNumber = null; function init() { //start with the prematch summary hidden - toggleBox("preMatchSummaryContainer"); + disableBox("preMatchSummaryContainer"); //start with the custom summary hidden - toggleBox("customSummaryContainer"); + disableBox("customSummaryContainer"); //get the labels electron.ipcRenderer.send("getLabels"); @@ -78,8 +78,10 @@ electron.ipcRenderer.on("showLabels", function (event, result) { }); electron.ipcRenderer.on("showDataForLabel", function (event, label, result) { - openCustomDataLabels.push(label); - openCustomDataPoints.push(result); + if (!openCustomDataLabels.includes(label) && !openCustomDataPoints.includes(result)) { + openCustomDataLabels.push(label); + openCustomDataPoints.push(result); + } showCustomSummary(); }); @@ -140,7 +142,7 @@ function showLabels(labels) { for (let i = 0; i < labels.length; i++) { //make each item be in a clickable div - labelsString += "
"; + labelsString += "
"; labelsString += labels[i] + "
"; } @@ -150,13 +152,21 @@ function showLabels(labels) { function toggleBox(id) { if (document.getElementById(id).style.display === "none") { //enable it - document.getElementById(id).removeAttribute("style"); + enableBox(id); } else { //disable it - document.getElementById(id).style.display = "none"; + disableBox(id); } } +function enableBox(id) { + document.getElementById(id).removeAttribute("style"); +} + +function disableBox(id) { + document.getElementById(id).style.display = "none"; +} + function inputKeyPress(event) { //check if an enter is pressed if (event.key === "Enter") { @@ -164,6 +174,21 @@ function inputKeyPress(event) { } } +//when an extra summary info is clicked, bring the user down to the custom summary +function extraSummaryClick(labelName) { + //open up custom summary if it is not opened + enableBox("customSummaryContainer"); + + //blank it out first to make sure the page gets scrolled down + window.location.hash = ""; + //move to that section + window.location.hash = "customLabel"; + + //for hit and miss + selectCustomSummaryLabel(labelName + " Hit"); + selectCustomSummaryLabel(labelName + " Miss"); +} + //for the custom summary searching functionality function customSearchKeyUp(event) { //event can be ignored, and instead what's in the box can be used @@ -190,34 +215,52 @@ function customSearchKeyUp(event) { showLabels(searchedLabels); } +//calls the other label clicked function +//takes just an index instead of the label itself +function labelClickedByIndex(index) { + labelClicked(searchLabels[index]); +} + //for the labels in the custom summary view //allows the user to view the raw data, but only the ones they select -function labelClicked(index) { +function labelClicked(label) { if (currentRobotNumber === null) { //no robot yet return; } - if (document.getElementById(searchLabels[index]).style.backgroundColor === "black") { - //it is already selected, deselect it - document.getElementById(searchLabels[index]).style.backgroundColor = "white"; - document.getElementById(searchLabels[index]).style.color = "black"; + if (document.getElementById(label).style.backgroundColor === "black") { + deselectCustomSummaryLabel(label); + } else { + selectCustomSummaryLabel(label); + } +} - //remove this from the custom data view - let customDataIndex = getLabelIndex(searchLabels[index]); +//deselcts the label in the custom summary +//thois is used when searching through the raw data +function deselectCustomSummaryLabel(label) { + //it is already selected, deselect it + document.getElementById(label).style.backgroundColor = "white"; + document.getElementById(label).style.color = "black"; - openCustomDataLabels.splice(customDataIndex, 1); - openCustomDataPoints.splice(customDataIndex, 1); + //remove this from the custom data view + let customDataIndex = getLabelIndex(label); - //update the view - showCustomSummary(); - } else { - document.getElementById(searchLabels[index]).style.backgroundColor = "black"; - document.getElementById(searchLabels[index]).style.color = "white"; + openCustomDataLabels.splice(customDataIndex, 1); + openCustomDataPoints.splice(customDataIndex, 1); - //get the data for this label - electron.ipcRenderer.send("getDataForLabel", currentRobotNumber, searchLabels[index]); - } + //update the view + showCustomSummary(); +} + +//deselcts the label in the custom summary +//thois is used when searching through the raw data +function selectCustomSummaryLabel(label) { + document.getElementById(label).style.backgroundColor = "black"; + document.getElementById(label).style.color = "white"; + + //get the data for this label + electron.ipcRenderer.send("getDataForLabel", currentRobotNumber, label); } function getLabelIndex(labels, search) { diff --git a/summarizer.js b/summarizer.js index 48e0945..b9021ab 100644 --- a/summarizer.js +++ b/summarizer.js @@ -322,7 +322,9 @@ function getComplexActionSummary(currentRobotNumber, labels, robots, searchTerm) for (let i = 0; i < extras.length; i++ ) { let extraSearchTerm = searchTerm.replace("Full", extras[i]); + extraSummary += ""; extraSummary += getActionSummary(currentRobotNumber, labels, robots, extraSearchTerm); + extraSummary += ""; } let fullSummary = ""; From fe75397ee57820bd52b97d5c8e7efb1648daa460 Mon Sep 17 00:00:00 2001 From: Ajay Ramachandran Date: Sat, 20 Apr 2019 22:13:03 -0400 Subject: [PATCH 03/32] Added ability to get what position a robot is in for averages of statistics. Says top x per category. Only works for averages for now. --- index.html | 4 +- main.js | 7 ++- summarizer.js | 118 ++++++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 105 insertions(+), 24 deletions(-) diff --git a/index.html b/index.html index 62e9d3d..a67e798 100644 --- a/index.html +++ b/index.html @@ -50,9 +50,7 @@

Pre-match Info (click to hide/show)

- -

Custom Info (click to hide/show)

-
+

Custom Info (click to hide/show)

diff --git a/main.js b/main.js index 880fb75..c7dc115 100644 --- a/main.js +++ b/main.js @@ -55,7 +55,6 @@ function loadData() { //parse through the data if (labels === null) { labels = data.split("\n")[0].split(","); - global.labels = labels; } let robot = new Robot(); @@ -105,9 +104,6 @@ function loadData() { robots.push(robot); }); } - - //send this variable over to the client side - global.robots = robots; }); } @@ -153,6 +149,9 @@ ipcMain.on('getLastUpdated', function (event, args) { ipcMain.on('getLabels', function (event, args) { event.sender.send("showLabels", labels); + + console.log("as") + summarizer.generateStats(labels, robots); }); //gets data under a specific label diff --git a/summarizer.js b/summarizer.js index b9021ab..d4d08c4 100644 --- a/summarizer.js +++ b/summarizer.js @@ -6,7 +6,8 @@ module.exports = { getAutoSummary: getAutoSummary, getPreMatchSummary: getPreMatchSummary, getCommentsSummary: getCommentsSummary, - getDataForLabel: getDataForLabel + getDataForLabel: getDataForLabel, + generateStats: generateStats } //the specifics that can be added to the searches (used by getActionSummary) @@ -15,24 +16,25 @@ const rocketHatchExtras = ['Far', 'Close', 'Level 1', 'Level 2', 'Level 3']; //cargo has no far and close, only levels on the rocket const rocketCargoExtras = ['Level 1', 'Level 2', 'Level 3']; -function getOverallData(currentRobotNumber, labels, robots) { - let fullSummary = ""; - - fullSummary += getComplexActionSummary(currentRobotNumber, labels, robots, "TeleOp Full Rocket Cargo"); - - fullSummary += "
"; +//what labels have a complex action summary +var actionSummaryLabels = []; +actionSummaryLabels.push("TeleOp Full Rocket Cargo"); +actionSummaryLabels.push("TeleOp Full Cargo Ship Cargo"); +actionSummaryLabels.push("TeleOp Full Rocket Hatch"); +actionSummaryLabels.push("TeleOp Full Cargo Ship Hatch"); - fullSummary += getComplexActionSummary(currentRobotNumber, labels, robots, "TeleOp Full Cargo Ship Cargo"); +//ordered list of every robot number +//this will contain a sorted list for each stat +var sortedRobotsByStat = []; - fullSummary += "
"; - - fullSummary += getComplexActionSummary(currentRobotNumber, labels, robots, "TeleOp Full Rocket Hatch"); - - fullSummary += "
"; +function getOverallData(currentRobotNumber, labels, robots) { + let fullSummary = ""; - fullSummary += getComplexActionSummary(currentRobotNumber, labels, robots, "TeleOp Full Cargo Ship Hatch"); + for (let i = 0; i < actionSummaryLabels.length; i++) { + fullSummary += getComplexActionSummary(currentRobotNumber, labels, robots, i); - fullSummary += "
"; + fullSummary += "
"; + } let deathRateItems = getColumnItems(currentRobotNumber, labels, robots, "died"); fullSummary += "Death Rate: " + getRateOfItems(deathRateItems) + " | " + getParsedAverageItem(deathRateItems) + "%"; @@ -197,6 +199,82 @@ function getDataForLabel(currentRobotNumber, labels, robots, searchTerm) { return getColumnRawItems(currentRobotNumber, labels, robots, searchTerm); } +//will generate the placement statistics for each robot +//Ex. sorted list of top hatch robots, sorted list of top cargo bots +//by average +function generateStats(labels, robots) { + //the list of statistics to look at + let statistics = []; + for (let i = 0; i < actionSummaryLabels.length; i++) { + statistics.push(actionSummaryLabels[i] + " Hit"); + } + + for (let i = 0; i < statistics.length; i++) { + let columnIndex = getColumnIndex(labels, statistics[i]); + + let sortedRobots = []; + let robotsLeft = Array.from(robots); + while (robotsLeft.length > 0) { + //robots performing the best this round + let bestRobots = []; + let highestPerformance = -1; + + for (let robotNumber = 0; robotNumber < robotsLeft.length; robotNumber++) { + let dataPoints = []; + for (let dataPoint = 1; dataPoint < robotsLeft[robotNumber].data.length; dataPoint++) { + //not just an empty line + if (robotsLeft[robotNumber].data[dataPoint].length > 1) { + dataPoints.push(robotsLeft[robotNumber].data[dataPoint][columnIndex]); + } + } + let performance = getAverageItem(dataPoints); + let robotIndex = robots.indexOf(robotsLeft[robotNumber]); + + //if it's more, set it to be this robot + //if it's the same, add this robot to the list (it's a tie) + if (performance > highestPerformance) { + bestRobots = [robotIndex]; + highestPerformance = performance; + } else if (performance === highestPerformance) { + bestRobots.push(robotIndex); + } + } + + //these are the best robots, add them to the list together as they are tied + sortedRobots.push(bestRobots); + + //remove these robots from robots left + for (let q = 0; q < bestRobots.length; q++) { + robotsLeft.splice(robotsLeft.indexOf(robots[bestRobots[q]]), 1); + } + } + sortedRobotsByStat[i] = sortedRobots; + } +} + +function getPositionInSortedList(robots, sortedRobotsByStat, robotNumber, statIndex) { + let position = 0; + + //find robot index from robot number + let robotIndex = 0; + for (let i = 0; i < robots.length; i++) { + if (robots[i].robotNumber === robotNumber) { + robotIndex = i; + } + } + + for (let i = 0; i < sortedRobotsByStat[statIndex].length; i++) { + if (!sortedRobotsByStat[statIndex][i].includes(robotIndex)) { + position += sortedRobotsByStat[statIndex][i].length; + } else { + //the robot has been found + break; + } + } + + return position; +} + //find the amount of times a certain string has been saved in a column in a percentage //Ex. number of successful level 2 climb //only if the first search term AND the second are true (in the current column and the next column) @@ -304,9 +382,15 @@ function getColumnItems(currentRobotNumber, labels, robots, searchTerm) { //uses getActionSummary to get a simple action summary along with more complicated //summary details when clicked //returns a string -function getComplexActionSummary(currentRobotNumber, labels, robots, searchTerm) { +function getComplexActionSummary(currentRobotNumber, labels, robots, searchTermIndex) { + let searchTerm = actionSummaryLabels[searchTermIndex]; + let mainSummary = getActionSummary(currentRobotNumber, labels, robots, searchTerm); + //add on if they are top in something + let standing = getPositionInSortedList(robots, sortedRobotsByStat, currentRobotNumber, searchTermIndex); + mainSummary += " Top " + standing; + //load the more detailed summary, and put it in a hidden box let extraSummary = ""; let extras = []; @@ -412,7 +496,7 @@ function getActionSummary(currentRobotNumber, labels, robots, searchTerm) { function getColumnIndex(labels, search) { for (let i = 0; i < labels.length; i++) { - if (labels[i].toLowerCase().includes(search)) { + if (labels[i].toLowerCase().includes(search.toLowerCase())) { return i; } } From d18149a0ce7714f28b7435757a2502d891e84c2e Mon Sep 17 00:00:00 2001 From: Ajay Ramachandran Date: Sat, 20 Apr 2019 23:08:19 -0400 Subject: [PATCH 04/32] Added the top # indicator for all items (extra details as well). Now the top # location and calculation is more improved. --- index.html | 2 +- main.js | 3 +-- summarizer.js | 73 +++++++++++++++++++++++++++++++++++++-------------- 3 files changed, 55 insertions(+), 23 deletions(-) diff --git a/index.html b/index.html index a67e798..ddd9af2 100644 --- a/index.html +++ b/index.html @@ -22,7 +22,7 @@

Overall (click to hide/show)

- +

diff --git a/main.js b/main.js index c7dc115..c99ab77 100644 --- a/main.js +++ b/main.js @@ -150,8 +150,7 @@ ipcMain.on('getLastUpdated', function (event, args) { ipcMain.on('getLabels', function (event, args) { event.sender.send("showLabels", labels); - console.log("as") - summarizer.generateStats(labels, robots); + summarizer.generateAllStats(labels, robots); }); //gets data under a specific label diff --git a/summarizer.js b/summarizer.js index d4d08c4..a63ca42 100644 --- a/summarizer.js +++ b/summarizer.js @@ -7,7 +7,7 @@ module.exports = { getPreMatchSummary: getPreMatchSummary, getCommentsSummary: getCommentsSummary, getDataForLabel: getDataForLabel, - generateStats: generateStats + generateAllStats: generateAllStats } //the specifics that can be added to the searches (used by getActionSummary) @@ -23,9 +23,35 @@ actionSummaryLabels.push("TeleOp Full Cargo Ship Cargo"); actionSummaryLabels.push("TeleOp Full Rocket Hatch"); actionSummaryLabels.push("TeleOp Full Cargo Ship Hatch"); +//pre generate all of the extra action labels +var extraActionSummaryLabels = []; +for (let i = 0; i < actionSummaryLabels.length; i++) { + let extras = []; + if (actionSummaryLabels[i].includes("Cargo Ship")) { + extras = cargoShipExtras; + } else if (actionSummaryLabels[i].includes("Rocket") && actionSummaryLabels[i].includes("Hatch")) { + extras = rocketHatchExtras; + } else if (actionSummaryLabels[i].includes("Rocket") && actionSummaryLabels[i].includes("Cargo")) { + extras = rocketCargoExtras; + } + + //add all these to a list, then add the list to the larger one + let currentExtraActionSummaryLabels = []; + + //go through the extra terms and get the extra summaries if any + for (let s = 0; s < extras.length; s++ ) { + currentExtraActionSummaryLabels.push(actionSummaryLabels[i].replace("Full", extras[s])); + } + + //done, add it to the full list + extraActionSummaryLabels.push(currentExtraActionSummaryLabels); +} + //ordered list of every robot number //this will contain a sorted list for each stat var sortedRobotsByStat = []; +//same list but for extra data +var extraSortedRobotsByStat = []; function getOverallData(currentRobotNumber, labels, robots) { let fullSummary = ""; @@ -199,10 +225,23 @@ function getDataForLabel(currentRobotNumber, labels, robots, searchTerm) { return getColumnRawItems(currentRobotNumber, labels, robots, searchTerm); } +//calls the generateStats for normal data and extra data +function generateAllStats(labels, robots) { + generateStats(labels, robots, actionSummaryLabels, sortedRobotsByStat); + + //each section of extra data is another array inside the main array + for (let i = 0; i < extraActionSummaryLabels.length; i++) { + let sortedRobots = []; + generateStats(labels, robots, extraActionSummaryLabels[i], sortedRobots); + + extraSortedRobotsByStat.push(sortedRobots); + } +} + //will generate the placement statistics for each robot //Ex. sorted list of top hatch robots, sorted list of top cargo bots //by average -function generateStats(labels, robots) { +function generateStats(labels, robots, actionSummaryLabels, sortedRobotsByStat) { //the list of statistics to look at let statistics = []; for (let i = 0; i < actionSummaryLabels.length; i++) { @@ -385,29 +424,17 @@ function getColumnItems(currentRobotNumber, labels, robots, searchTerm) { function getComplexActionSummary(currentRobotNumber, labels, robots, searchTermIndex) { let searchTerm = actionSummaryLabels[searchTermIndex]; - let mainSummary = getActionSummary(currentRobotNumber, labels, robots, searchTerm); - - //add on if they are top in something - let standing = getPositionInSortedList(robots, sortedRobotsByStat, currentRobotNumber, searchTermIndex); - mainSummary += " Top " + standing; + let mainSummary = getActionSummary(currentRobotNumber, labels, robots, actionSummaryLabels, sortedRobotsByStat, searchTermIndex); //load the more detailed summary, and put it in a hidden box let extraSummary = ""; - let extras = []; - if (searchTerm.includes("Cargo Ship")) { - extras = cargoShipExtras; - } else if (searchTerm.includes("Rocket") && searchTerm.includes("Hatch")) { - extras = rocketHatchExtras; - } else if (searchTerm.includes("Rocket") && searchTerm.includes("Cargo")) { - extras = rocketCargoExtras; - } //go through the extra terms and get the extra summaries if any - for (let i = 0; i < extras.length; i++ ) { - let extraSearchTerm = searchTerm.replace("Full", extras[i]); + for (let i = 0; i < extraActionSummaryLabels[searchTermIndex].length; i++ ) { + let extraSearchTerm = extraActionSummaryLabels[searchTermIndex][i]; extraSummary += ""; - extraSummary += getActionSummary(currentRobotNumber, labels, robots, extraSearchTerm); + extraSummary += getActionSummary(currentRobotNumber, labels, robots, extraActionSummaryLabels[searchTermIndex], extraSortedRobotsByStat[searchTermIndex], i); extraSummary += ""; } @@ -428,7 +455,9 @@ function getComplexActionSummary(currentRobotNumber, labels, robots, searchTermI //returns a summary message for this action //used to batch find the different action's stats -function getActionSummary(currentRobotNumber, labels, robots, searchTerm) { +function getActionSummary(currentRobotNumber, labels, robots, actionSummaryLabels, sortedRobotsByStat, searchTermIndex) { + let searchTerm = actionSummaryLabels[searchTermIndex]; + let fullSummary = ""; //miss and hit to include the successes and failures @@ -455,7 +484,11 @@ function getActionSummary(currentRobotNumber, labels, robots, searchTerm) { let hitAverage = getAverageItem(hitItems); let missAverage = getAverageItem(missItems); - fullSummary += searchTerm + " Average " + hitAverage.toFixed(2) + " : " + missAverage.toFixed(2) + "
"; + fullSummary += searchTerm + " Average " + hitAverage.toFixed(2) + " : " + missAverage.toFixed(2); + + //add on if they are top in something + let standing = getPositionInSortedList(robots, sortedRobotsByStat, currentRobotNumber, searchTermIndex); + fullSummary += " | Top " + standing + "
"; //find max let hitMaxItems = getMaxItems(hitItems); From 7c4df57fcc8ee61fb248232d589c942175fd5ef9 Mon Sep 17 00:00:00 2001 From: Ajay Ramachandran Date: Sat, 20 Apr 2019 23:08:45 -0400 Subject: [PATCH 05/32] Fixed maximum performance in match indicator being off by one match. --- summarizer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/summarizer.js b/summarizer.js index a63ca42..b141503 100644 --- a/summarizer.js +++ b/summarizer.js @@ -507,7 +507,7 @@ function getActionSummary(currentRobotNumber, labels, robots, actionSummaryLabel //string of what match numbers this max happened in let matchNumbersOfMaximums = ""; for (let i = 0; i < hitMaxItems.length; i++) { - matchNumbersOfMaximums += robots[matchNumColumn].data[hitMaxItems[i][1]][matchNumColumn]; + matchNumbersOfMaximums += robots[matchNumColumn].data[hitMaxItems[i][1] + 1][matchNumColumn]; if (i != hitMaxItems.length - 1) { //if it is not the last index From 047d7b7cde68ad0d4d3320d5b484cca53d6df2de Mon Sep 17 00:00:00 2001 From: Ajay Ramachandran Date: Tue, 23 Apr 2019 11:07:04 -0400 Subject: [PATCH 06/32] Added a top # indicator for maximum performance as well. Tells you the placement of all teams for their maximum performance. --- index.html | 2 +- summarizer.js | 51 +++++++++++++++++++++++++++++++++++---------------- 2 files changed, 36 insertions(+), 17 deletions(-) diff --git a/index.html b/index.html index ddd9af2..cc30600 100644 --- a/index.html +++ b/index.html @@ -22,7 +22,7 @@

Overall (click to hide/show)

- +

diff --git a/summarizer.js b/summarizer.js index b141503..2771bf0 100644 --- a/summarizer.js +++ b/summarizer.js @@ -49,9 +49,13 @@ for (let i = 0; i < actionSummaryLabels.length; i++) { //ordered list of every robot number //this will contain a sorted list for each stat -var sortedRobotsByStat = []; +var averageSortedRobotsByStat = []; //same list but for extra data -var extraSortedRobotsByStat = []; +var extraAverageSortedRobotsByStat = []; +//for maximums +var maxSortedRobotsByStat = []; +//same list but for extra data +var extraMaxSortedRobotsByStat = []; function getOverallData(currentRobotNumber, labels, robots) { let fullSummary = ""; @@ -227,21 +231,26 @@ function getDataForLabel(currentRobotNumber, labels, robots, searchTerm) { //calls the generateStats for normal data and extra data function generateAllStats(labels, robots) { - generateStats(labels, robots, actionSummaryLabels, sortedRobotsByStat); + generateStats(labels, robots, actionSummaryLabels, averageSortedRobotsByStat, true); + generateStats(labels, robots, actionSummaryLabels, maxSortedRobotsByStat, false); //each section of extra data is another array inside the main array for (let i = 0; i < extraActionSummaryLabels.length; i++) { - let sortedRobots = []; - generateStats(labels, robots, extraActionSummaryLabels[i], sortedRobots); + let averageSortedRobots = []; + let maxSortedRobots = []; + + generateStats(labels, robots, extraActionSummaryLabels[i], averageSortedRobots, true); + generateStats(labels, robots, extraActionSummaryLabels[i], maxSortedRobots, false); - extraSortedRobotsByStat.push(sortedRobots); + extraAverageSortedRobotsByStat.push(averageSortedRobots); + extraMaxSortedRobotsByStat.push(maxSortedRobots); } } //will generate the placement statistics for each robot //Ex. sorted list of top hatch robots, sorted list of top cargo bots -//by average -function generateStats(labels, robots, actionSummaryLabels, sortedRobotsByStat) { +//sortByAverage: true if sorting by average, false if sorting by max +function generateStats(labels, robots, actionSummaryLabels, sortedRobotsByStat, sortByAverage) { //the list of statistics to look at let statistics = []; for (let i = 0; i < actionSummaryLabels.length; i++) { @@ -266,7 +275,13 @@ function generateStats(labels, robots, actionSummaryLabels, sortedRobotsByStat) dataPoints.push(robotsLeft[robotNumber].data[dataPoint][columnIndex]); } } - let performance = getAverageItem(dataPoints); + let performance = 0; + if (sortByAverage) { + performance = getAverageItem(dataPoints); + } else { + //sort by max otherwise + performance = getMaxItems(dataPoints)[0][0]; + } let robotIndex = robots.indexOf(robotsLeft[robotNumber]); //if it's more, set it to be this robot @@ -424,7 +439,7 @@ function getColumnItems(currentRobotNumber, labels, robots, searchTerm) { function getComplexActionSummary(currentRobotNumber, labels, robots, searchTermIndex) { let searchTerm = actionSummaryLabels[searchTermIndex]; - let mainSummary = getActionSummary(currentRobotNumber, labels, robots, actionSummaryLabels, sortedRobotsByStat, searchTermIndex); + let mainSummary = getActionSummary(currentRobotNumber, labels, robots, actionSummaryLabels, averageSortedRobotsByStat, maxSortedRobotsByStat, searchTermIndex); //load the more detailed summary, and put it in a hidden box let extraSummary = ""; @@ -434,7 +449,7 @@ function getComplexActionSummary(currentRobotNumber, labels, robots, searchTermI let extraSearchTerm = extraActionSummaryLabels[searchTermIndex][i]; extraSummary += ""; - extraSummary += getActionSummary(currentRobotNumber, labels, robots, extraActionSummaryLabels[searchTermIndex], extraSortedRobotsByStat[searchTermIndex], i); + extraSummary += getActionSummary(currentRobotNumber, labels, robots, extraActionSummaryLabels[searchTermIndex], extraAverageSortedRobotsByStat[searchTermIndex], extraMaxSortedRobotsByStat[searchTermIndex], i); extraSummary += ""; } @@ -455,7 +470,7 @@ function getComplexActionSummary(currentRobotNumber, labels, robots, searchTermI //returns a summary message for this action //used to batch find the different action's stats -function getActionSummary(currentRobotNumber, labels, robots, actionSummaryLabels, sortedRobotsByStat, searchTermIndex) { +function getActionSummary(currentRobotNumber, labels, robots, actionSummaryLabels, averageSortedRobotsByStat, maxSortedRobotsByStat, searchTermIndex) { let searchTerm = actionSummaryLabels[searchTermIndex]; let fullSummary = ""; @@ -486,9 +501,9 @@ function getActionSummary(currentRobotNumber, labels, robots, actionSummaryLabel fullSummary += searchTerm + " Average " + hitAverage.toFixed(2) + " : " + missAverage.toFixed(2); - //add on if they are top in something - let standing = getPositionInSortedList(robots, sortedRobotsByStat, currentRobotNumber, searchTermIndex); - fullSummary += " | Top " + standing + "
"; + //add on if they are top for average + let averageStanding = getPositionInSortedList(robots, averageSortedRobotsByStat, currentRobotNumber, searchTermIndex); + fullSummary += " | Top " + averageStanding + "
"; //find max let hitMaxItems = getMaxItems(hitItems); @@ -521,7 +536,11 @@ function getActionSummary(currentRobotNumber, labels, robots, actionSummaryLabel matchNumbersOfMaximums = "N/A"; } - fullSummary += searchTerm + " Max " + hitMaxItems[0][0] + " : " + missMinItems[0] + " in match " + matchNumbersOfMaximums + "
"; + fullSummary += searchTerm + " Max " + hitMaxItems[0][0] + " : " + missMinItems[0] + " in match " + matchNumbersOfMaximums; + + //add on if they are top for max + let maxStanding = getPositionInSortedList(robots, maxSortedRobotsByStat, currentRobotNumber, searchTermIndex); + fullSummary += " | Top " + maxStanding + "
"; //return resulted summary return fullSummary; From 3df6b72493f06e51d0abe2d8685f3491d1b81873 Mon Sep 17 00:00:00 2001 From: Ajay Ramachandran Date: Wed, 24 Apr 2019 16:44:09 -0400 Subject: [PATCH 07/32] Created the first server version of the reader. This version runs on a server and passes the data over https calls. --- .gitignore | 4 +- index.js | 148 ++++++--- package-lock.json | 764 ++++++++++++++++++++++------------------------ package.json | 4 +- server.js | 176 +++++++++++ 5 files changed, 655 insertions(+), 441 deletions(-) create mode 100644 server.js diff --git a/.gitignore b/.gitignore index 3508822..cdf38e0 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,6 @@ dist data photos -build \ No newline at end of file +build + +certificates \ No newline at end of file diff --git a/index.js b/index.js index 2b00b0a..853809e 100644 --- a/index.js +++ b/index.js @@ -1,6 +1,12 @@ /*jshint esversion: 6 */ -var electron = require("electron"); +var serverBased = false; + +try { + var electron = require("electron"); +} catch(err) { + serverBased = true; +} var labels = []; //the labels shown from this search @@ -19,7 +25,11 @@ function init() { disableBox("customSummaryContainer"); //get the labels - electron.ipcRenderer.send("getLabels"); + if (serverBased) { + httpGetAsync("getLabels", prepareLabelsJson); + } else { + electron.ipcRenderer.send("getLabels"); + } } function loadData() { @@ -33,11 +43,19 @@ function loadData() { document.getElementById("commentsSummary").innerHTML = "Loading..."; //start the processing - electron.ipcRenderer.send("createOverallSummary", currentRobotNumber); - electron.ipcRenderer.send("createAutoSummary", currentRobotNumber); - electron.ipcRenderer.send("createPreMatchSummary", currentRobotNumber); - electron.ipcRenderer.send("createCommentsSummary", currentRobotNumber); - electron.ipcRenderer.send("getLastUpdated"); + if (serverBased) { + httpGetAsync("/createOverallSummary?robotNumber=" + currentRobotNumber, showOverallSummary); + httpGetAsync("/createAutoSummary?robotNumber=" + currentRobotNumber, showAutoSummary); + httpGetAsync("/createPreMatchSummary?robotNumber=" + currentRobotNumber, showPreMatchSummary); + httpGetAsync("/createCommentsSummary?robotNumber=" + currentRobotNumber, showCommentsSummary); + httpGetAsync("getLastUpdated", showLastUpdatedJson); + } else { + electron.ipcRenderer.send("createOverallSummary", currentRobotNumber); + electron.ipcRenderer.send("createAutoSummary", currentRobotNumber); + electron.ipcRenderer.send("createPreMatchSummary", currentRobotNumber); + electron.ipcRenderer.send("createCommentsSummary", currentRobotNumber); + electron.ipcRenderer.send("getLastUpdated"); + } //show robot photo document.getElementById("robot").src = "photos/" + currentRobotNumber + ".JPG"; @@ -46,27 +64,47 @@ function loadData() { reloadCustomSummary(); } -electron.ipcRenderer.on("showOverallSummary", function (event, result) { +//all the callback methods +function showOverallSummary(result) { document.getElementById("overallSummary").innerHTML = result; -}); - -electron.ipcRenderer.on("showAutoSummary", function (event, result) { +} +function showAutoSummary(result) { document.getElementById("autoSummary").innerHTML = result; -}); - -electron.ipcRenderer.on("showPreMatchSummary", function (event, result) { +} +function showPreMatchSummary(result) { document.getElementById("preMatchSummary").innerHTML = result; -}); - -electron.ipcRenderer.on("showCommentsSummary", function (event, result) { +} +function showCommentsSummary(result) { document.getElementById("commentsSummary").innerHTML = result; -}); - -electron.ipcRenderer.on("showLastUpdated", function (event, result) { +} +function showLastUpdatedJson(result) { + showLastUpdated(JSON.parse(result).lastUpdated); +} +function showLastUpdated(result) { document.getElementById("lastUpdated").innerHTML = "Last Updated Match " + result; -}); +} + +//calls other method with more requirements +function showDataForLabelJson(jsonResult) { + let json = JSON.parse(jsonResult); + + showDataForLabel(json.label, json.result); +} + +function showDataForLabel(label, result) { + if (!openCustomDataLabels.includes(label) && !openCustomDataPoints.includes(result)) { + openCustomDataLabels.push(label); + openCustomDataPoints.push(result); + } + + showCustomSummary(); +} -electron.ipcRenderer.on("showLabels", function (event, result) { +function prepareLabelsJson(result) { + prepareLabels(JSON.parse(result)); +} + +function prepareLabels(result) { labels = Array.from(result); //remove unneeded labels @@ -75,16 +113,37 @@ electron.ipcRenderer.on("showLabels", function (event, result) { labels.splice(labels.length - 2, 1); showLabels(labels); -}); +} -electron.ipcRenderer.on("showDataForLabel", function (event, label, result) { - if (!openCustomDataLabels.includes(label) && !openCustomDataPoints.includes(result)) { - openCustomDataLabels.push(label); - openCustomDataPoints.push(result); - } +if (!serverBased) { + electron.ipcRenderer.on("showOverallSummary", function (event, result) { + showOverallSummary(result); + }); + + electron.ipcRenderer.on("showAutoSummary", function (event, result) { + showAutoSummary(result); + }); + + electron.ipcRenderer.on("showPreMatchSummary", function (event, result) { + showPreMatchSummary(result); + }); + + electron.ipcRenderer.on("showCommentsSummary", function (event, result) { + showCommentsSummary(result); + }); + + electron.ipcRenderer.on("showLastUpdated", function (event, result) { + showLastUpdated(result); + }); - showCustomSummary(); -}); + electron.ipcRenderer.on("showDataForLabel", function (event, label, result) { + showDataForLabel(label, result); + }); + + electron.ipcRenderer.on("showLabels", function (event, result) { + prepareLabels(result); + }); +} //go through the custom summary and get new data from the server function reloadCustomSummary() { @@ -100,7 +159,11 @@ function reloadCustomSummary() { //call to get the new data for (let i = 0; i < customLabels.length; i++) { - electron.ipcRenderer.send("getDataForLabel", currentRobotNumber, customLabels[i]); + if (serverBased) { + httpGetAsync("getDataForLabel?robotNumber=" + currentRobotNumber + "&searchTerm=" + customLabels[i], showDataForLabelJson); + } else { + electron.ipcRenderer.send("getDataForLabel", currentRobotNumber, customLabels[i]); + } } } @@ -120,11 +183,11 @@ function showCustomSummary() { if (openCustomDataPoints.length > 0) { for (let i = 0; i < openCustomDataPoints[0].length; i++) { summary += ""; - + for (let s = 0; s < openCustomDataPoints.length; s++) { summary += "" + openCustomDataPoints[s][i] + ""; } - + summary += ""; } } @@ -203,7 +266,7 @@ function customSearchKeyUp(event) { //this will include all the labels that are part of this search let searchedLabels = []; - + //search for the lables to add to searchedLabels for (let i = 0; i < labels.length; i++) { if (labels[i].toLowerCase().includes(searchTerm.toLowerCase())) { @@ -260,7 +323,11 @@ function selectCustomSummaryLabel(label) { document.getElementById(label).style.color = "white"; //get the data for this label - electron.ipcRenderer.send("getDataForLabel", currentRobotNumber, label); + if (serverBased) { + httpGetAsync("getDataForLabel?robotNumber=" + currentRobotNumber + "&searchTerm=" + label, showDataForLabelJson); + } else { + electron.ipcRenderer.send("getDataForLabel", currentRobotNumber, label); + } } function getLabelIndex(labels, search) { @@ -271,4 +338,15 @@ function getLabelIndex(labels, search) { } return -1; +} + +function httpGetAsync(url, callback) { + var xmlHttp = new XMLHttpRequest(); + xmlHttp.onreadystatechange = function () { + if (xmlHttp.readyState == 4 && xmlHttp.status == 200) { + callback(xmlHttp.responseText); + } + } + xmlHttp.open("GET", url, true); + xmlHttp.send(null); } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index a13f76f..f6a8fc5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,15 @@ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" }, + "accepts": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", + "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", + "requires": { + "mime-types": "~2.1.18", + "negotiator": "0.6.1" + } + }, "ajv": { "version": "6.10.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", @@ -35,27 +44,10 @@ "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=" }, - "asar": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/asar/-/asar-1.0.0.tgz", - "integrity": "sha512-MBiDU5cDr9UWuY2F0zq2fZlnyRq1aOPmJGMas22Qa14K1odpRXL3xkMHPN3uw2hAK5mD89Q+/KidOUtpi4V0Cg==", - "requires": { - "chromium-pickle-js": "^0.2.0", - "commander": "^2.19.0", - "cuint": "^0.2.2", - "glob": "^7.1.3", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "pify": "^4.0.1", - "tmp-promise": "^1.0.5" - }, - "dependencies": { - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" - } - } + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" }, "asn1": { "version": "0.2.4", @@ -75,11 +67,6 @@ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" }, - "author-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/author-regex/-/author-regex-1.0.0.tgz", - "integrity": "sha1-0IiFvmubv5Q5/gh8dihyRfCoFFA=" - }, "aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", @@ -95,11 +82,6 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, - "base64-js": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", - "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==" - }, "bcrypt-pbkdf": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", @@ -108,10 +90,37 @@ "tweetnacl": "^0.14.3" } }, - "bluebird": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.3.tgz", - "integrity": "sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw==" + "body-parser": { + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz", + "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=", + "requires": { + "bytes": "3.0.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "~1.6.3", + "iconv-lite": "0.4.23", + "on-finished": "~2.3.0", + "qs": "6.5.2", + "raw-body": "2.3.3", + "type-is": "~1.6.16" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } }, "brace-expansion": { "version": "1.1.11", @@ -122,25 +131,6 @@ "concat-map": "0.0.1" } }, - "buffer-alloc": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", - "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", - "requires": { - "buffer-alloc-unsafe": "^1.1.0", - "buffer-fill": "^1.0.0" - } - }, - "buffer-alloc-unsafe": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", - "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==" - }, - "buffer-fill": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", - "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=" - }, "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", @@ -151,6 +141,11 @@ "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=" }, + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" + }, "camelcase": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", @@ -170,11 +165,6 @@ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" }, - "chromium-pickle-js": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz", - "integrity": "sha1-BKEGZywYsIWrd02YPfo+oTjyIgU=" - }, "code-point-at": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", @@ -188,16 +178,6 @@ "delayed-stream": "~1.0.0" } }, - "commander": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", - "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==" - }, - "compare-version": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/compare-version/-/compare-version-0.1.2.tgz", - "integrity": "sha1-AWLsLZNR9d3VmpICy6k1NmpyUIA=" - }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -243,16 +223,31 @@ } } }, + "content-disposition": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", + "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=" + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, + "cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, - "cuint": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/cuint/-/cuint-0.2.2.tgz", - "integrity": "sha1-QICG1AlVDCYxFVYZ6fp7ytw7mRs=" - }, "currently-unhandled": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", @@ -292,6 +287,16 @@ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, "ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", @@ -301,6 +306,11 @@ "safer-buffer": "^2.1.0" } }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, "electron": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/electron/-/electron-4.1.0.tgz", @@ -327,46 +337,74 @@ "sumchecker": "^2.0.2" } }, - "electron-notarize": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/electron-notarize/-/electron-notarize-0.0.5.tgz", - "integrity": "sha512-YzrqZ6RDQ7Wt2RWlxzRoQUuxnTeXrfp7laH7XKcmQqrZ6GaAr50DMPvFMpqDKdrZSHSbcgZgB7ktIQbjvITmCQ==", + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + }, + "env-paths": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-1.0.0.tgz", + "integrity": "sha1-QWgTO0K7BcOKNbGuQ5fIKYqzaeA=" + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "requires": { - "debug": "^4.1.0", - "fs-extra": "^7.0.0" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } + "is-arrayish": "^0.2.1" } }, - "electron-osx-sign": { - "version": "0.4.11", - "resolved": "https://registry.npmjs.org/electron-osx-sign/-/electron-osx-sign-0.4.11.tgz", - "integrity": "sha512-VVd40nrnVqymvFrY9ZkOYgHJOvexHHYTR3di/SN+mjJ0OWhR1I8BRVj3U+Yamw6hnkZZNKZp52rqL5EFAAPFkQ==", - "requires": { - "bluebird": "^3.5.0", - "compare-version": "^0.1.2", - "debug": "^2.6.8", - "isbinaryfile": "^3.0.2", - "minimist": "^1.2.0", - "plist": "^3.0.1" + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=" + }, + "express": { + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/express/-/express-4.16.4.tgz", + "integrity": "sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg==", + "requires": { + "accepts": "~1.3.5", + "array-flatten": "1.1.1", + "body-parser": "1.18.3", + "content-disposition": "0.5.2", + "content-type": "~1.0.4", + "cookie": "0.3.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.1.1", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.4", + "qs": "6.5.2", + "range-parser": "~1.2.0", + "safe-buffer": "5.1.2", + "send": "0.16.2", + "serve-static": "1.13.2", + "setprototypeof": "1.1.0", + "statuses": "~1.4.0", + "type-is": "~1.6.16", + "utils-merge": "1.0.1", + "vary": "~1.1.2" }, "dependencies": { "debug": { @@ -384,73 +422,6 @@ } } }, - "electron-packager": { - "version": "13.1.1", - "resolved": "https://registry.npmjs.org/electron-packager/-/electron-packager-13.1.1.tgz", - "integrity": "sha512-3Drgcw8OEOP3Psw/PprloAFJSkSUSQgjUq3AmWffJGB3Kj5WXmZl6A3GOUs8aT7bP/8GWg4oYqSiCSnA5PQkdQ==", - "requires": { - "asar": "^1.0.0", - "debug": "^4.0.1", - "electron-download": "^4.1.1", - "electron-notarize": "^0.0.5", - "electron-osx-sign": "^0.4.11", - "extract-zip": "^1.0.3", - "fs-extra": "^7.0.0", - "galactus": "^0.2.1", - "get-package-info": "^1.0.0", - "parse-author": "^2.0.0", - "pify": "^4.0.0", - "plist": "^3.0.0", - "rcedit": "^1.0.0", - "resolve": "^1.1.6", - "sanitize-filename": "^1.6.0", - "semver": "^5.3.0", - "yargs-parser": "^13.0.0" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" - } - } - }, - "env-paths": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-1.0.0.tgz", - "integrity": "sha1-QWgTO0K7BcOKNbGuQ5fIKYqzaeA=" - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=" - }, "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -505,6 +476,35 @@ "pend": "~1.2.0" } }, + "finalhandler": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", + "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "statuses": "~1.4.0", + "unpipe": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, "find-up": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", @@ -524,15 +524,6 @@ } } }, - "flora-colossus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/flora-colossus/-/flora-colossus-1.0.0.tgz", - "integrity": "sha1-VHKcNh7ezuAU3UQWeeGjfB13OkU=", - "requires": { - "debug": "^3.1.0", - "fs-extra": "^4.0.0" - } - }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -548,6 +539,16 @@ "mime-types": "^2.1.12" } }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, "fs-extra": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", @@ -563,93 +564,6 @@ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, - "galactus": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/galactus/-/galactus-0.2.1.tgz", - "integrity": "sha1-y+0tIKQMH1Z5o1kI4rlBVzPnjbk=", - "requires": { - "debug": "^3.1.0", - "flora-colossus": "^1.0.0", - "fs-extra": "^4.0.0" - } - }, - "get-package-info": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-package-info/-/get-package-info-1.0.0.tgz", - "integrity": "sha1-ZDJ5ZWPigRPNlHTbvQAFKYWkmZw=", - "requires": { - "bluebird": "^3.1.1", - "debug": "^2.2.0", - "lodash.get": "^4.0.0", - "read-pkg-up": "^2.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "requires": { - "locate-path": "^2.0.0" - } - }, - "load-json-file": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "strip-bom": "^3.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "path-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", - "requires": { - "pify": "^2.0.0" - } - }, - "read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", - "requires": { - "load-json-file": "^2.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^2.0.0" - } - }, - "read-pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^2.0.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" - } - } - }, "get-stdin": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", @@ -700,6 +614,17 @@ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==" }, + "http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + }, "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -710,6 +635,14 @@ "sshpk": "^1.7.0" } }, + "iconv-lite": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", + "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, "indent-string": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", @@ -737,6 +670,11 @@ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" }, + "ipaddr.js": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", + "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==" + }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -773,14 +711,6 @@ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" }, - "isbinaryfile": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-3.0.3.tgz", - "integrity": "sha512-8cJBL5tTd2OS0dM4jz07wQd5g0dCCqIhUxPIGtZfa5L6hWlvV5MHTITy/DBAsF+Oe2LS1X3krBUhNwaGUWpWxw==", - "requires": { - "buffer-alloc": "^1.2.0" - } - }, "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", @@ -874,20 +804,6 @@ "strip-bom": "^2.0.0" } }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=" - }, "loud-rejection": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", @@ -902,6 +818,11 @@ "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=" }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, "meow": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", @@ -919,6 +840,21 @@ "trim-newlines": "^1.0.0" } }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "mime": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", + "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==" + }, "mime-db": { "version": "1.38.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.38.0.tgz", @@ -965,6 +901,11 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" }, + "negotiator": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", + "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" + }, "nopt": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", @@ -1034,6 +975,14 @@ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=" }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -1061,35 +1010,6 @@ "os-tmpdir": "^1.0.0" } }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=" - }, - "parse-author": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/parse-author/-/parse-author-2.0.0.tgz", - "integrity": "sha1-00YL8d3Q367tQtp1QkLmX7aEqB8=", - "requires": { - "author-regex": "^1.0.0" - } - }, "parse-json": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", @@ -1098,6 +1018,11 @@ "error-ex": "^1.2.0" } }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + }, "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", @@ -1113,6 +1038,11 @@ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, "path-type": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", @@ -1151,16 +1081,6 @@ "pinkie": "^2.0.0" } }, - "plist": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/plist/-/plist-3.0.1.tgz", - "integrity": "sha512-GpgvHHocGRyQm74b6FWEZZVRroHKE1I0/BTjAmySaohK+cUn+hZpbqXkc3KWgW3gQYkqcQej35FohcT0FRlkRQ==", - "requires": { - "base64-js": "^1.2.3", - "xmlbuilder": "^9.0.7", - "xmldom": "0.1.x" - } - }, "pretty-bytes": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-1.0.4.tgz", @@ -1184,6 +1104,15 @@ "through2": "~0.2.3" } }, + "proxy-addr": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", + "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==", + "requires": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.0" + } + }, "psl": { "version": "1.1.31", "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz", @@ -1199,6 +1128,22 @@ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" }, + "range-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", + "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=" + }, + "raw-body": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", + "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", + "requires": { + "bytes": "3.0.0", + "http-errors": "1.6.3", + "iconv-lite": "0.4.23", + "unpipe": "1.0.0" + } + }, "rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", @@ -1210,11 +1155,6 @@ "strip-json-comments": "~2.0.1" } }, - "rcedit": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/rcedit/-/rcedit-1.1.1.tgz", - "integrity": "sha512-6NjOhOpkvbc/gpMEfk2hpXuWyHfbLFN8as5jx3jf4bhELvouRoYvc8d/W3NVVPwEBF1ICfbpwp1oRm8OJ2WDWw==" - }, "read-pkg": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", @@ -1307,19 +1247,62 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, - "sanitize-filename": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.1.tgz", - "integrity": "sha1-YS2hyWRz+gLczaktzVtKsWSmdyo=", - "requires": { - "truncate-utf8-bytes": "^1.0.0" - } - }, "semver": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==" }, + "send": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", + "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.6.2", + "mime": "1.4.1", + "ms": "2.0.0", + "on-finished": "~2.3.0", + "range-parser": "~1.2.0", + "statuses": "~1.4.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "serve-static": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", + "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.2", + "send": "0.16.2" + } + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + }, "signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", @@ -1382,6 +1365,11 @@ "tweetnacl": "~0.14.0" } }, + "statuses": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" + }, "string-width": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", @@ -1463,23 +1451,6 @@ "xtend": "~2.1.1" } }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "requires": { - "os-tmpdir": "~1.0.2" - } - }, - "tmp-promise": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-1.0.5.tgz", - "integrity": "sha512-hOabTz9Tp49wCozFwuJe5ISrOqkECm6kzw66XTP23DuzNU7QS/KiZq5LC9Y7QSy8f1rPSLy4bKaViP0OwGI1cA==", - "requires": { - "bluebird": "^3.5.0", - "tmp": "0.0.33" - } - }, "tough-cookie": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", @@ -1501,14 +1472,6 @@ "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=" }, - "truncate-utf8-bytes": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", - "integrity": "sha1-QFkjkJWS1W94pYGENLC3hInKXys=", - "requires": { - "utf8-byte-length": "^1.0.1" - } - }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -1522,6 +1485,15 @@ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" }, + "type-is": { + "version": "1.6.16", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", + "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.18" + } + }, "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", @@ -1532,6 +1504,11 @@ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, "uri-js": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", @@ -1540,16 +1517,16 @@ "punycode": "^2.1.0" } }, - "utf8-byte-length": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz", - "integrity": "sha1-9F8VDExm7uloGGUFq5P8u4rWv2E=" - }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, "uuid": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", @@ -1564,6 +1541,11 @@ "spdx-expression-parse": "^3.0.0" } }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + }, "verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", @@ -1579,16 +1561,6 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, - "xmlbuilder": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", - "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=" - }, - "xmldom": { - "version": "0.1.27", - "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz", - "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=" - }, "xtend": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz", @@ -1597,22 +1569,6 @@ "object-keys": "~0.4.0" } }, - "yargs-parser": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.0.0.tgz", - "integrity": "sha512-w2LXjoL8oRdRQN+hOyppuXs+V/fVAYtpcrRxZuF7Kt/Oc+Jr2uAcVntaUTNT6w5ihoWfFDpNY8CPx1QskxZ/pw==", - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, - "dependencies": { - "camelcase": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.2.0.tgz", - "integrity": "sha512-IXFsBS2pC+X0j0N/GE7Dm7j3bsEBp+oTpb7F50dwEVX7rf3IgwO9XatnegTsDtniKCUtEJH4fSU6Asw7uoVLfQ==" - } - } - }, "yauzl": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz", diff --git a/package.json b/package.json index fa44dc8..9f5bbd8 100644 --- a/package.json +++ b/package.json @@ -5,12 +5,14 @@ "main": "main.js", "scripts": { "test": "test", - "start": "electron ." + "start": "electron .", + "server": "npm run server.js" }, "author": "Ajay Ramachandran", "license": "MIT", "dependencies": { "electron": "^4.1.0", + "express": "^4.16.4", "jslint": "^0.12.1" } } diff --git a/server.js b/server.js new file mode 100644 index 0000000..1686432 --- /dev/null +++ b/server.js @@ -0,0 +1,176 @@ +/*jshint esversion: 6 */ + +const fs = require("fs"); +const summarizer = require("./summarizer"); + +var express = require('express'); +var https = require('https'); +var http = require('http'); + +//https://stackoverflow.com/a/14272874/1985387 +var options = { + key: fs.readFileSync('./certificates/private.key'), + cert: fs.readFileSync('./certificates/certificate.crt') +}; + +// Create a service (the app object is just a callback). +var app = express(); + +// Create an HTTP service. +http.createServer(app).listen(80); +// Create an HTTPS service identical to the HTTP service. +https.createServer(options, app).listen(443); + +//add the public files +app.get('/', function (req, res) { + return res.sendFile("index.html", { root: __dirname }); +}); + +app.get('/styles.css', function (req, res) { + return res.sendFile("styles.css", { root: __dirname }); +}); + +app.get('/index.js', function (req, res) { + return res.sendFile("index.js", { root: __dirname }); +}); + +//publish photos +app.use('/photos', express.static(__dirname + '/photos')); + +//list that holds all the data for the robots +var robots = []; +//the labels at the top of each file, only pulled once +var labels = null; + +//last match updated on +var lastUpdated = -1; + +//setup replace all function https://stackoverflow.com/a/38015918/1985387 +String.prototype.replaceAll = function(search, replace) { + if (replace === undefined) { + return this.toString(); + } + return this.split(search).join(replace); +} + +function loadData() { + fs.readdir('./data', function (err, items) { + if (err) throw err; + + //iterate through all files + for (let i = 0; i < items.length; i++) { + fs.readFile('./data/' + items[i], "utf8", function (error, data) { + if (error) throw error; + if (data === "") { + //file is empty + return; + } + + //parse through the data + if (labels === null) { + labels = data.split("\n")[0].split(","); + } + + let robot = new Robot(); + robot.robotNumber = items[i].replace(".csv", ""); + + let lines = data.split("\n"); + + let robotData = []; + + for (let s = 0; s < lines.length; s++) { + robotData.push(lines[s].split(",")); + + //find match number + if (s > 0) { + //update last updated to be the latest match number scouted + if (parseInt(lines[s].split(",")[0]) > lastUpdated) { + lastUpdated = parseInt(lines[s].split(",")[0]); + } + } + } + + //sort robotData by match number + //start it with the labels, they should always be at the top + let robotDataSorted = [robotData[0]]; + + //start at 1 to ignore labels at the top of the csv file + for (let s = 1; s < robotData.length; s++) { + for (let q = 1; q < robotData.length; q++) { + //skip over if already dealt with + if (robotDataSorted.includes(robotData[q])) continue; + + if (robotDataSorted.length == s) { + //start it with a default number + robotDataSorted.push([-1]); + } + + if (robotDataSorted[s][0] === -1 || parseInt(robotData[q][0]) < parseInt(robotDataSorted[s][0])) { + //this one is the lower one, it should be here (sorting from lowest to highest) + robotDataSorted[s] = robotData[q]; + } + } + } + + robot.data = robotDataSorted; + + //add to the full list of robots + robots.push(robot); + }); + } + }); + +} +loadData(); + +//creates the robot preview data that will be sent to the client +//calls back with the data +app.get('/createOverallSummary', function (req, res) { + summarizer.generateAllStats(labels, robots); + + let result = summarizer.getOverallData(req.query.robotNumber, labels, robots); + + res.send(result); +}); +app.get('/createAutoSummary', function (req, res) { + let result = summarizer.getAutoSummary(req.query.robotNumber, labels, robots); + + res.send(result); +}); +app.get('/createPreMatchSummary', function (req, res) { + let result = summarizer.getPreMatchSummary(req.query.robotNumber, labels, robots); + + res.send(result); +}); +app.get('/createCommentsSummary', function (req, res) { + let result = summarizer.getCommentsSummary(req.query.robotNumber, labels, robots); + + res.send(result); +}); +app.get('/getLastUpdated', function (req, res) { + res.send({lastUpdated}).end(); +}); + +app.get('/getLabels', function (req, res) { + res.send(labels); + + summarizer.generateAllStats(labels, robots); +}); + +//gets data under a specific label +app.get('/getDataForLabel', function (req, res) { + let data = summarizer.getDataForLabel(req.query.robotNumber, labels, robots, req.query.searchTerm.toLowerCase()); + + res.send({ + label: req.query.searchTerm, + result: data + }); +}); + +//Classes +class Robot { + constructor(robotNumber, data) { + this.robotNumber = robotNumber; + this.data = data; + } +} \ No newline at end of file From d53f51377c4035d9db92e7003b152f9ba4e9548e Mon Sep 17 00:00:00 2001 From: Ajay Ramachandran Date: Wed, 24 Apr 2019 21:57:33 -0400 Subject: [PATCH 08/32] Added basic scouting data uploading system to the server --- index.html | 8 ++++++++ package-lock.json | 5 +++++ package.json | 1 + server.js | 15 +++++++++++++++ 4 files changed, 29 insertions(+) diff --git a/index.html b/index.html index cc30600..18d2d6b 100644 --- a/index.html +++ b/index.html @@ -11,6 +11,14 @@ + + Upload Scouting Data +
+ + +
+
+ diff --git a/package-lock.json b/package-lock.json index f6a8fc5..9a1f313 100644 --- a/package-lock.json +++ b/package-lock.json @@ -539,6 +539,11 @@ "mime-types": "^2.1.12" } }, + "formidable": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.1.tgz", + "integrity": "sha512-Fs9VRguL0gqGHkXS5GQiMCr1VhZBxz0JnJs4JmMp/2jL18Fmbzvv7vOFRU+U8TBkHEE/CX1qDXzJplVULgsLeg==" + }, "forwarded": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", diff --git a/package.json b/package.json index 9f5bbd8..ba83728 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "dependencies": { "electron": "^4.1.0", "express": "^4.16.4", + "formidable": "^1.2.1", "jslint": "^0.12.1" } } diff --git a/server.js b/server.js index 1686432..b7eee60 100644 --- a/server.js +++ b/server.js @@ -7,6 +7,8 @@ var express = require('express'); var https = require('https'); var http = require('http'); +var formidable = require('formidable'); + //https://stackoverflow.com/a/14272874/1985387 var options = { key: fs.readFileSync('./certificates/private.key'), @@ -37,6 +39,19 @@ app.get('/index.js', function (req, res) { //publish photos app.use('/photos', express.static(__dirname + '/photos')); +//data uploader +app.post('/', function (req, res){ + var form = new formidable.IncomingForm(); + + form.parse(req); + + form.on('fileBegin', function (name, file){ + file.path = __dirname + '/data/' + file.name; + }); + + return res.sendFile("index.html", { root: __dirname }); +}); + //list that holds all the data for the robots var robots = []; //the labels at the top of each file, only pulled once From d544c5d0b900450fe4fff1b17eaa2709368ec876 Mon Sep 17 00:00:00 2001 From: Ajay Ramachandran Date: Wed, 24 Apr 2019 23:31:33 -0400 Subject: [PATCH 09/32] Made uploading require a password and only allow .csv files --- index.html | 5 ++++- server.js | 30 ++++++++++++++++++++++++++---- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/index.html b/index.html index 18d2d6b..bc4dceb 100644 --- a/index.html +++ b/index.html @@ -12,10 +12,13 @@ - Upload Scouting Data + Upload Scouting Data: +
+ Password: +
diff --git a/server.js b/server.js index b7eee60..b8b8325 100644 --- a/server.js +++ b/server.js @@ -43,13 +43,35 @@ app.use('/photos', express.static(__dirname + '/photos')); app.post('/', function (req, res){ var form = new formidable.IncomingForm(); - form.parse(req); + let files = []; + let field; - form.on('fileBegin', function (name, file){ - file.path = __dirname + '/data/' + file.name; + form.on('field', function(fieldName, value) { + if (fieldName == "password") { + field = value; + } }); - return res.sendFile("index.html", { root: __dirname }); + form.on('file', function(field, file) { + files.push(file); + }); + + form.on('end', function() { + for (let i = 0; i < files.length; i++) { + console.log(files[i].name + " " + files[i].name.endsWith(".csv")) + if (field == "2809cyber" && files[i].name.endsWith(".csv")) { + fs.copyFile(files[i].path, __dirname + '/data/' + files[i].name, function(err) { + if (err) { + console.error(err); + } + }); + } + } + + res.redirect('/'); + }); + + form.parse(req); }); //list that holds all the data for the robots From fd05962e1358d7f75b03c9c174cc8e0f0e1f6897 Mon Sep 17 00:00:00 2001 From: Ajay Ramachandran Date: Wed, 24 Apr 2019 23:46:08 -0400 Subject: [PATCH 10/32] Moved upload to another page --- failed.html | 3 +++ index.html | 11 ----------- server.js | 28 +++++++++++++++++++++++++--- success.html | 3 +++ upload.html | 18 ++++++++++++++++++ 5 files changed, 49 insertions(+), 14 deletions(-) create mode 100644 failed.html create mode 100644 success.html create mode 100644 upload.html diff --git a/failed.html b/failed.html new file mode 100644 index 0000000..f3338e9 --- /dev/null +++ b/failed.html @@ -0,0 +1,3 @@ +

Upload Failed!

+ +Back \ No newline at end of file diff --git a/index.html b/index.html index bc4dceb..cc30600 100644 --- a/index.html +++ b/index.html @@ -11,17 +11,6 @@ - - Upload Scouting Data: - -
- - - Password: - -
-
- diff --git a/server.js b/server.js index b8b8325..e5f500a 100644 --- a/server.js +++ b/server.js @@ -28,6 +28,22 @@ app.get('/', function (req, res) { return res.sendFile("index.html", { root: __dirname }); }); +//upload page +app.get('/upload', function (req, res) { + return res.sendFile("upload.html", { root: __dirname }); +}); +app.get('/u', function (req, res) { + return res.sendFile("upload.html", { root: __dirname }); +}); + +//success and failed +app.get('/success', function (req, res) { + return res.sendFile("success.html", { root: __dirname }); +}); +app.get('/failed', function (req, res) { + return res.sendFile("failed.html", { root: __dirname }); +}); + app.get('/styles.css', function (req, res) { return res.sendFile("styles.css", { root: __dirname }); }); @@ -40,7 +56,7 @@ app.get('/index.js', function (req, res) { app.use('/photos', express.static(__dirname + '/photos')); //data uploader -app.post('/', function (req, res){ +app.post('/upload', function (req, res){ var form = new formidable.IncomingForm(); let files = []; @@ -57,18 +73,24 @@ app.post('/', function (req, res){ }); form.on('end', function() { + let success = false; for (let i = 0; i < files.length; i++) { - console.log(files[i].name + " " + files[i].name.endsWith(".csv")) if (field == "2809cyber" && files[i].name.endsWith(".csv")) { fs.copyFile(files[i].path, __dirname + '/data/' + files[i].name, function(err) { if (err) { console.error(err); } }); + + success = true; } } - res.redirect('/'); + if (success) { + res.redirect("success"); + } else { + res.redirect("failed"); + } }); form.parse(req); diff --git a/success.html b/success.html new file mode 100644 index 0000000..0f59b39 --- /dev/null +++ b/success.html @@ -0,0 +1,3 @@ +

Upload Success!

+ +Back \ No newline at end of file diff --git a/upload.html b/upload.html new file mode 100644 index 0000000..3eb5dec --- /dev/null +++ b/upload.html @@ -0,0 +1,18 @@ + + + + + + + + Upload Scouting Data: + +
+ + + Password: + +
+
+ + \ No newline at end of file From 15f59951ada94137afcf1817738854f0196b234d Mon Sep 17 00:00:00 2001 From: Ajay Ramachandran Date: Thu, 25 Apr 2019 07:01:24 -0400 Subject: [PATCH 11/32] Added a multi view page --- multiview.html | 32 ++++++++++++++++++++++++++++++++ server.js | 23 +++++++++++++++++++---- styles.css | 6 ++++++ upload.html | 13 ++++++++++++- 4 files changed, 69 insertions(+), 5 deletions(-) create mode 100644 multiview.html diff --git a/multiview.html b/multiview.html new file mode 100644 index 0000000..4482dd7 --- /dev/null +++ b/multiview.html @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + +
+ + + +
+ \ No newline at end of file diff --git a/server.js b/server.js index e5f500a..05245c1 100644 --- a/server.js +++ b/server.js @@ -36,6 +36,14 @@ app.get('/u', function (req, res) { return res.sendFile("upload.html", { root: __dirname }); }); +//multiview page +app.get('/multiview', function (req, res) { + return res.sendFile("multiview.html", { root: __dirname }); +}); +app.get('/m', function (req, res) { + return res.sendFile("multiview.html", { root: __dirname }); +}); + //success and failed app.get('/success', function (req, res) { return res.sendFile("success.html", { root: __dirname }); @@ -56,7 +64,14 @@ app.get('/index.js', function (req, res) { app.use('/photos', express.static(__dirname + '/photos')); //data uploader -app.post('/upload', function (req, res){ +app.post('/data', function (req, res){ + upload(req, res, ".csv", "/data/"); +}); +app.post('/photos', function (req, res){ + upload(req, res, ".JPG", "/photos/"); +}); + +function upload(req, res, fileType, folder) { var form = new formidable.IncomingForm(); let files = []; @@ -75,8 +90,8 @@ app.post('/upload', function (req, res){ form.on('end', function() { let success = false; for (let i = 0; i < files.length; i++) { - if (field == "2809cyber" && files[i].name.endsWith(".csv")) { - fs.copyFile(files[i].path, __dirname + '/data/' + files[i].name, function(err) { + if (field == "2809cyber" && files[i].name.endsWith(fileType)) { + fs.copyFile(files[i].path, __dirname + folder + files[i].name, function(err) { if (err) { console.error(err); } @@ -94,7 +109,7 @@ app.post('/upload', function (req, res){ }); form.parse(req); -}); +} //list that holds all the data for the robots var robots = []; diff --git a/styles.css b/styles.css index 7bb4127..6cf6bae 100644 --- a/styles.css +++ b/styles.css @@ -29,4 +29,10 @@ .column { flex: content; +} + +.robotView { + width: 100%; + height: 100%; + margin: 0px; } \ No newline at end of file diff --git a/upload.html b/upload.html index 3eb5dec..863fdb5 100644 --- a/upload.html +++ b/upload.html @@ -7,7 +7,18 @@ Upload Scouting Data: -
+ + + + Password: + +
+ +
+ + Upload Robot Photos (ends in JPG): + +
Password: From 3995b71b7acac667f3dc05f4ceec0b26d7f531dd Mon Sep 17 00:00:00 2001 From: Ajay Ramachandran Date: Thu, 25 Apr 2019 07:09:19 -0400 Subject: [PATCH 12/32] Added multi robot view on the main page --- index.html | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/index.html b/index.html index cc30600..2dca856 100644 --- a/index.html +++ b/index.html @@ -11,6 +11,10 @@ + + + + From 5aa6dbacc723c0161b81619c9266f8118ab41649 Mon Sep 17 00:00:00 2001 From: Ajay Ramachandran Date: Thu, 25 Apr 2019 07:09:53 -0400 Subject: [PATCH 13/32] Closed form tags properly. --- upload.html | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/upload.html b/upload.html index 863fdb5..8b652fa 100644 --- a/upload.html +++ b/upload.html @@ -8,10 +8,10 @@ Upload Scouting Data:
- - + + Password: - +

@@ -19,10 +19,10 @@ Upload Robot Photos (ends in JPG):
- - + + Password: - +
From 524b79c8457274bd626fc89f82582b71fdffb4fa Mon Sep 17 00:00:00 2001 From: Ajay Ramachandran Date: Thu, 25 Apr 2019 08:49:01 -0400 Subject: [PATCH 14/32] Published the data to the web --- server.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server.js b/server.js index 05245c1..4cb8313 100644 --- a/server.js +++ b/server.js @@ -62,6 +62,8 @@ app.get('/index.js', function (req, res) { //publish photos app.use('/photos', express.static(__dirname + '/photos')); +//publish data +app.use('/photos', express.static(__dirname + '/data')); //data uploader app.post('/data', function (req, res){ From 7a0f2c9f6264428cc2a07a9c650486d8d6030df7 Mon Sep 17 00:00:00 2001 From: Ajay Ramachandran Date: Thu, 25 Apr 2019 08:58:45 -0400 Subject: [PATCH 15/32] Added get data files endpoint --- server.js | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/server.js b/server.js index 4cb8313..69287c4 100644 --- a/server.js +++ b/server.js @@ -233,14 +233,17 @@ app.get('/getLabels', function (req, res) { summarizer.generateAllStats(labels, robots); }); +app.get('/getLabels', function (req, res) { + res.send(labels); + + summarizer.generateAllStats(labels, robots); +}); + //gets data under a specific label -app.get('/getDataForLabel', function (req, res) { - let data = summarizer.getDataForLabel(req.query.robotNumber, labels, robots, req.query.searchTerm.toLowerCase()); +app.get('/getDataFiles', function (req, res) { + let files = fs.readdirSync(testFolder); - res.send({ - label: req.query.searchTerm, - result: data - }); + res.send(files); }); //Classes From 8bbc415f1f47ee13846b7f6217275fcadd773a14 Mon Sep 17 00:00:00 2001 From: Ajay Ramachandran Date: Thu, 25 Apr 2019 09:01:58 -0400 Subject: [PATCH 16/32] Fixed folder not being specified --- server.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server.js b/server.js index 69287c4..a135f93 100644 --- a/server.js +++ b/server.js @@ -241,7 +241,7 @@ app.get('/getLabels', function (req, res) { //gets data under a specific label app.get('/getDataFiles', function (req, res) { - let files = fs.readdirSync(testFolder); + let files = fs.readdirSync("./data"); res.send(files); }); From ec0c91199b70eacc1c3954301ef14f948c2f81aa Mon Sep 17 00:00:00 2001 From: Ajay Ramachandran Date: Thu, 25 Apr 2019 09:20:52 -0400 Subject: [PATCH 17/32] Made the desktop app be able to pull periodically from the server --- index.html | 2 ++ index.js | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/index.html b/index.html index 2dca856..1bb53e7 100644 --- a/index.html +++ b/index.html @@ -11,6 +11,8 @@ + +
diff --git a/index.js b/index.js index 853809e..b30e25f 100644 --- a/index.js +++ b/index.js @@ -4,6 +4,8 @@ var serverBased = false; try { var electron = require("electron"); + var fs = require("fs"); + var http = require("http"); } catch(err) { serverBased = true; } @@ -28,6 +30,7 @@ function init() { if (serverBased) { httpGetAsync("getLabels", prepareLabelsJson); } else { + document.getElementById("downloadData").style.display = "inline"; electron.ipcRenderer.send("getLabels"); } } @@ -64,6 +67,21 @@ function loadData() { reloadCustomSummary(); } +function downloadData() { + httpGetAsync("https://scout.ajay.app/getDataFiles", downloadDataResponse); +} + +function downloadDataResponse(result) { + let files = JSON.parse(result); + + for (let i = 0; i < files.length; i++) { + let file = fs.createWriteStream("./data/" + files[i]); + let request = http.get("http://scout.ajay.app/data/" + files[i], function(response) { + response.pipe(file); + }); + } +} + //all the callback methods function showOverallSummary(result) { document.getElementById("overallSummary").innerHTML = result; From 2b68987464e557312fe6e8880a737a2f3e9b60d2 Mon Sep 17 00:00:00 2001 From: Ajay Ramachandran Date: Thu, 25 Apr 2019 09:21:17 -0400 Subject: [PATCH 18/32] Made data publish on the right endpoint --- server.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server.js b/server.js index a135f93..5dc6ede 100644 --- a/server.js +++ b/server.js @@ -63,7 +63,7 @@ app.get('/index.js', function (req, res) { //publish photos app.use('/photos', express.static(__dirname + '/photos')); //publish data -app.use('/photos', express.static(__dirname + '/data')); +app.use('/data', express.static(__dirname + '/data')); //data uploader app.post('/data', function (req, res){ From 1236e951992fac011e663840ffa969c55fa38b6a Mon Sep 17 00:00:00 2001 From: Ajay Ramachandran Date: Thu, 25 Apr 2019 10:34:10 -0400 Subject: [PATCH 19/32] Added endpoint to get list of photos --- server.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/server.js b/server.js index 5dc6ede..06bb827 100644 --- a/server.js +++ b/server.js @@ -239,12 +239,18 @@ app.get('/getLabels', function (req, res) { summarizer.generateAllStats(labels, robots); }); -//gets data under a specific label +//gets what data files are available app.get('/getDataFiles', function (req, res) { let files = fs.readdirSync("./data"); res.send(files); }); +//gets what photos are available +app.get('/getPhotoFiles', function (req, res) { + let files = fs.readdirSync("./photos"); + + res.send(files); +}); //Classes class Robot { From 5157bb3822e188d7242614c4f4e45328cb654a36 Mon Sep 17 00:00:00 2001 From: Ajay Ramachandran Date: Thu, 25 Apr 2019 12:41:54 -0400 Subject: [PATCH 20/32] Added a try catch --- server.js | 77 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 41 insertions(+), 36 deletions(-) diff --git a/server.js b/server.js index 06bb827..16c1cf7 100644 --- a/server.js +++ b/server.js @@ -74,43 +74,48 @@ app.post('/photos', function (req, res){ }); function upload(req, res, fileType, folder) { - var form = new formidable.IncomingForm(); - - let files = []; - let field; - - form.on('field', function(fieldName, value) { - if (fieldName == "password") { - field = value; - } - }); - - form.on('file', function(field, file) { - files.push(file); - }); - - form.on('end', function() { - let success = false; - for (let i = 0; i < files.length; i++) { - if (field == "2809cyber" && files[i].name.endsWith(fileType)) { - fs.copyFile(files[i].path, __dirname + folder + files[i].name, function(err) { - if (err) { - console.error(err); - } - }); - - success = true; + try { + var form = new formidable.IncomingForm(); + + let files = []; + let field; + + form.on('field', function(fieldName, value) { + if (fieldName == "password") { + field = value; } - } - - if (success) { - res.redirect("success"); - } else { - res.redirect("failed"); - } - }); - - form.parse(req); + }); + + form.on('file', function(field, file) { + files.push(file); + }); + + form.on('end', function() { + let success = false; + for (let i = 0; i < files.length; i++) { + if (field == "2809cyber" && files[i].name.endsWith(fileType)) { + fs.copyFile(files[i].path, __dirname + folder + files[i].name, function(err) { + if (err) { + console.error(err); + } + }); + + success = true; + } + } + + if (success) { + res.redirect("success"); + } else { + res.redirect("failed"); + } + }); + + form.parse(req); + } catch(err) { + console.log(err); + res.redirect("failed"); + } } //list that holds all the data for the robots From 8d6ba2e5eef2f0566890db7f967de43591d0b619 Mon Sep 17 00:00:00 2001 From: Ajay Ramachandran Date: Thu, 25 Apr 2019 12:59:55 -0400 Subject: [PATCH 21/32] Added back accidentally removed getDataForLabel. --- server.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/server.js b/server.js index 16c1cf7..8807478 100644 --- a/server.js +++ b/server.js @@ -244,6 +244,15 @@ app.get('/getLabels', function (req, res) { summarizer.generateAllStats(labels, robots); }); +app.get('/getDataForLabel', function (req, res) { + let data = summarizer.getDataForLabel(req.query.robotNumber, labels, robots, req.query.searchTerm.toLowerCase()); + + res.send({ + label: req.query.searchTerm, + result: data + }); +} + //gets what data files are available app.get('/getDataFiles', function (req, res) { let files = fs.readdirSync("./data"); From b4a27123ff8a04cde4e263a0a48117238cd70eda Mon Sep 17 00:00:00 2001 From: Ajay Ramachandran Date: Thu, 25 Apr 2019 13:00:56 -0400 Subject: [PATCH 22/32] Added missing semi colon --- server.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server.js b/server.js index 8807478..a8f3ec7 100644 --- a/server.js +++ b/server.js @@ -251,7 +251,7 @@ app.get('/getDataForLabel', function (req, res) { label: req.query.searchTerm, result: data }); -} +}); //gets what data files are available app.get('/getDataFiles', function (req, res) { From c155829fb27763cf31a5db023421522626b93edf Mon Sep 17 00:00:00 2001 From: Ajay Ramachandran Date: Thu, 25 Apr 2019 23:01:51 -0400 Subject: [PATCH 23/32] Made the data reload when data is uploaded --- server.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/server.js b/server.js index a8f3ec7..1ce617f 100644 --- a/server.js +++ b/server.js @@ -98,6 +98,11 @@ function upload(req, res, fileType, folder) { if (err) { console.error(err); } + + if (folder == "/data/") { + //then reload the data + loadData(); + } }); success = true; @@ -135,6 +140,9 @@ String.prototype.replaceAll = function(search, replace) { } function loadData() { + labels = null; + data = []; + fs.readdir('./data', function (err, items) { if (err) throw err; From 34aa8b46e87bea606d1f09b5fd7fb10ad3076b2c Mon Sep 17 00:00:00 2001 From: Ajay Ramachandran Date: Thu, 25 Apr 2019 23:18:16 -0400 Subject: [PATCH 24/32] Increase file size limit --- server.js | 1 + 1 file changed, 1 insertion(+) diff --git a/server.js b/server.js index 1ce617f..8d7b626 100644 --- a/server.js +++ b/server.js @@ -76,6 +76,7 @@ app.post('/photos', function (req, res){ function upload(req, res, fileType, folder) { try { var form = new formidable.IncomingForm(); + form.maxFileSize = 100 * 1024 * 1024 * 1024; let files = []; let field; From 752e00794ac717d02a57b209a5ec710f2947c10c Mon Sep 17 00:00:00 2001 From: Ajay Ramachandran Date: Fri, 26 Apr 2019 08:33:03 -0400 Subject: [PATCH 25/32] Made the window title contain the robot number --- index.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/index.js b/index.js index b30e25f..b546a10 100644 --- a/index.js +++ b/index.js @@ -39,6 +39,8 @@ function loadData() { //show a quick summary of all the data for this robot currentRobotNumber = document.getElementById("robotNumber").value; + document.title = currentRobotNumber + " - Scouting Reader"; + //set loading indicators document.getElementById("overallSummary").innerHTML = "Loading..."; document.getElementById("autoSummary").innerHTML = "Loading..."; From 2a05ae8fecd4adc4b3de794e2b2777f9b7bf8e30 Mon Sep 17 00:00:00 2001 From: Ajay Ramachandran Date: Fri, 26 Apr 2019 09:02:14 -0400 Subject: [PATCH 26/32] Raised file size limit --- server.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server.js b/server.js index 8d7b626..fc0dd6d 100644 --- a/server.js +++ b/server.js @@ -76,7 +76,7 @@ app.post('/photos', function (req, res){ function upload(req, res, fileType, folder) { try { var form = new formidable.IncomingForm(); - form.maxFileSize = 100 * 1024 * 1024 * 1024; + form.maxFileSize = 1000 * 1024 * 1024 * 1024; let files = []; let field; From 691d87ef265b74508bb6cd8d2a30558be1d243fd Mon Sep 17 00:00:00 2001 From: Ajay Ramachandran Date: Fri, 26 Apr 2019 10:40:01 -0400 Subject: [PATCH 27/32] Made the upload success and fail screen bring you back to the upload page --- failed.html | 2 +- success.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/failed.html b/failed.html index f3338e9..024c855 100644 --- a/failed.html +++ b/failed.html @@ -1,3 +1,3 @@

Upload Failed!

-Back \ No newline at end of file +

Back

\ No newline at end of file diff --git a/success.html b/success.html index 0f59b39..8a1e092 100644 --- a/success.html +++ b/success.html @@ -1,3 +1,3 @@

Upload Success!

-Back \ No newline at end of file +

Back

\ No newline at end of file From a171a9255280ec2214e3d6feb10fa7c30982ea26 Mon Sep 17 00:00:00 2001 From: Ajay Ramachandran Date: Fri, 26 Apr 2019 12:06:40 -0400 Subject: [PATCH 28/32] Added more try catches --- server.js | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/server.js b/server.js index fc0dd6d..1292c49 100644 --- a/server.js +++ b/server.js @@ -95,18 +95,23 @@ function upload(req, res, fileType, folder) { let success = false; for (let i = 0; i < files.length; i++) { if (field == "2809cyber" && files[i].name.endsWith(fileType)) { - fs.copyFile(files[i].path, __dirname + folder + files[i].name, function(err) { - if (err) { - console.error(err); - } - - if (folder == "/data/") { - //then reload the data - loadData(); - } - }); + try { + fs.copyFile(files[i].path, __dirname + folder + files[i].name, function(err) { + if (err) { + console.error(err); + } + + if (folder == "/data/") { + //then reload the data + loadData(); + } + }); - success = true; + success = true; + } catch (err) { + console.log(err); + success = false; + } } } From aaa2a13ce67b5530a64f21bc65f9f6a100e2ca78 Mon Sep 17 00:00:00 2001 From: Ajay Ramachandran Date: Fri, 26 Apr 2019 12:09:49 -0400 Subject: [PATCH 29/32] Made an error during reading not crash the whole program. --- server.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/server.js b/server.js index 1292c49..16bad4f 100644 --- a/server.js +++ b/server.js @@ -155,7 +155,10 @@ function loadData() { //iterate through all files for (let i = 0; i < items.length; i++) { fs.readFile('./data/' + items[i], "utf8", function (error, data) { - if (error) throw error; + if (error) { + console.log(error); + return; + } if (data === "") { //file is empty return; From c8a19021a1d86f7dcd687bfe129ef0ec944c3d12 Mon Sep 17 00:00:00 2001 From: Ajay Ramachandran Date: Fri, 26 Apr 2019 12:23:57 -0400 Subject: [PATCH 30/32] Adde timeout to reload data after upload --- server.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server.js b/server.js index 16bad4f..a52a1bc 100644 --- a/server.js +++ b/server.js @@ -101,9 +101,9 @@ function upload(req, res, fileType, folder) { console.error(err); } - if (folder == "/data/") { + if (folder == "/data/" && i == files.length - 1) { //then reload the data - loadData(); + setTimeout(loadData, 3000); } }); From 1e0527a2f4d6979e5592d6b1a68b298152805fb0 Mon Sep 17 00:00:00 2001 From: Ajay Ramachandran Date: Fri, 26 Apr 2019 12:29:04 -0400 Subject: [PATCH 31/32] Fixed load data not resetting the right thing --- server.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server.js b/server.js index a52a1bc..3d9d93b 100644 --- a/server.js +++ b/server.js @@ -147,7 +147,7 @@ String.prototype.replaceAll = function(search, replace) { function loadData() { labels = null; - data = []; + robots = []; fs.readdir('./data', function (err, items) { if (err) throw err; From 19fae05171fac89846251aa7738908f32759a3e1 Mon Sep 17 00:00:00 2001 From: Ajay Ramachandran Date: Wed, 1 May 2019 08:04:48 -0400 Subject: [PATCH 32/32] Made password load from config file instead of being hardcoded --- server.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server.js b/server.js index 3d9d93b..7dde10a 100644 --- a/server.js +++ b/server.js @@ -15,6 +15,8 @@ var options = { cert: fs.readFileSync('./certificates/certificate.crt') }; +var loadedPassword = fs.readFileSync('./certificates/password.txt'); + // Create a service (the app object is just a callback). var app = express(); @@ -94,7 +96,7 @@ function upload(req, res, fileType, folder) { form.on('end', function() { let success = false; for (let i = 0; i < files.length; i++) { - if (field == "2809cyber" && files[i].name.endsWith(fileType)) { + if (field == loadedPassword && files[i].name.endsWith(fileType)) { try { fs.copyFile(files[i].path, __dirname + folder + files[i].name, function(err) { if (err) {