diff --git a/app.js b/app.js index c334e546d90a77730ba4a347ff28adaa186fae23..d4f33c9b8fecb485b32d553066f6930734689f68 100644 --- a/app.js +++ b/app.js @@ -2,7 +2,6 @@ const express = require('express'); const bodyParser = require('body-parser'); const exec = require('child_process').exec; -const execSync = require('child_process').execSync; const fs = require('fs'); const path = require('path'); const fsReaddir = require('fs-readdir'); @@ -33,41 +32,40 @@ app.use(bodyParser.json()); app.engine('.hbs', exphbs({extname: '.hbs'})); app.set('view engine', '.hbs'); +//clientCounter holds the number of clients that wants to download files let clientCounter = 0; //TODO add spinner for telling user to wait until initialization is done - //initGitRepos.initialize(downloadFiles); - //routes + initGitRepos.initialize(downloadFiles); + //This route shows the homepage. app.get('/', function(req, res){ - res.render('home', {downloadFiles: downloadNames}); }); +//This route takes the checkedFiles the user selected on the homepage, shows the download page on which the actual download is triggered. +app.post('/', function(req, res, next){ + const checkedFiles = Object.keys(req.body); - app.post('/', function(req, res, next){ - const checkedFiles = Object.keys(req.body); - - if(typeof checkedFiles !== 'undefined' && checkedFiles.length > 0){ - clientCounter= clientCounter + 1; - console.log('clientCounter after increment:', clientCounter); - res.render('download', {checkedFiles: checkedFiles, downloadFiles: downloadNames}); - } - else { - res.render('home', {downloadFiles: downloadNames}); - } - }); + if(typeof checkedFiles !== 'undefined' && checkedFiles.length > 0){ + clientCounter= clientCounter + 1; + res.render('download', {checkedFiles: checkedFiles, downloadFiles: downloadNames}); + } + else { + res.render('home', {downloadFiles: downloadNames}); + } +}); - app.get('/download', function(req, res, next){ - const checkedFiles = req.query.checkedFiles.split(','); - let clientName; - const zip = new JSZip(); - zip.file("README.txt", "text for README"); +//This route gets the files the user checked for downloading, builds the custom build and delivers the zip file as a download. +app.get('/download', function(req, res, next){ + const checkedFiles = req.query.checkedFiles.split(','); + let clientName; + const zip = new JSZip(); + zip.file("README.txt", "text for README"); //holds promises for backend and/or frontend for synchronizing const promiseArray = [] - - + //TODO handle multiple clients if (clientCounter > 5){ res.render('tooManyClients'); }else{ @@ -76,8 +74,6 @@ let clientCounter = 0; } - - backendChecked = checkedFiles.find(function(file){ return file === 'explorviz-ui-backend'; }); @@ -149,7 +145,6 @@ finalizeZip(); console.log('promiseArray:', promiseArray); function finalizeZip(){ - //Wo clientCounter runterzählen? return zipFunctions.streamFilesToZip(promiseArray,zip, clientName).then(function(zip){ return createZip(zip) }).catch(function(error) {let response = @@ -167,9 +162,8 @@ function createZip(zip){ console.log('error in createZip:', error); }).on('finish', function () { console.log('explorviz-builds.zip written.'); - console.log('clientCounter in createZip before decrement: ', clientCounter); + //client finishes everything except getting the download clientCounter = clientCounter - 1; - console.log('clientCounter in the end:', clientCounter); res.download('explorviz-builds.zip', function(error){ if(error){ let response = @@ -191,5 +185,5 @@ function createZip(zip){ - app.listen(3000); - console.log("Downloader started on port 3000."); +app.listen(3000); +console.log("Downloader started on port 3000."); diff --git a/backendFunctions.js b/backendFunctions.js index 4cc6c31d9dedc5cb98625ef2e92f6b3d59dab03d..a39b8235792ba8d5958e6cfd1fd052c2716c344a 100644 --- a/backendFunctions.js +++ b/backendFunctions.js @@ -1,27 +1,28 @@ const express = require('express'); const exec = require('child_process').exec; +//These functions handle everything regarding the backend of ExplorViz except adding it to the zip. Each will return a Promise. - function prepareClientFolder(clientName, fileName){ - return new Promise((resolve,reject)=>{ +function prepareClientFolder(clientName, fileName){ + return new Promise((resolve,reject)=>{ - exec('cp -R ' + fileName + ' ' + clientName + '/',(error,stdout,stderr)=>{ + exec('cp -R ' + fileName + ' ' + clientName + '/',(error,stdout,stderr)=>{ - if (error) { - reject(error); - return; - } + if (error) { + reject(error); + return; + } - console.log(stdout); - console.log(stderr); + console.log(stdout); + console.log(stderr); - resolve(fileName); + resolve(fileName); - }) - }) + }) + }) - } +} //remove addons from former builds @@ -32,7 +33,6 @@ function backendClean(clientName, fileName){ exec('rm -rf plugins/*',{cwd:path}, (error, stdout,stderr)=>{ if (error) { - console.log('backendClean:', error); reject(error); return; } @@ -54,7 +54,6 @@ function backendPull(clientName, fileName){ exec('git pull ',{cwd:path} ,(error, stdout, stderr) => { if (error) { - console.log('backendPull:', error); reject(error); return; } @@ -72,7 +71,7 @@ function backendPull(clientName, fileName){ function backendInstallAddons(checkedFiles,downloadFiles,clientName){ return new Promise((resolve, reject)=>{ - + let pluginsFinished=0; checkedPlugins = checkedFiles.filter(function(file){ return /\bexplorviz-backend-plugin-\w*/.exec(file); @@ -86,7 +85,6 @@ function backendInstallAddons(checkedFiles,downloadFiles,clientName){ exec('git pull ' + ' && rsync -av . ' + ' ../' + clientName +'/explorviz-ui-backend/plugins/net/explorviz/plugins/ ' + ' --exclude .git',{cwd:path}, (error, stdout, stderr) => { //'cd explorviz-ui-backend/plugins/net/explorviz/plugins/ ' + if (error) { - console.log('backendInstallAddons:', error); reject(error); return; } @@ -94,8 +92,12 @@ function backendInstallAddons(checkedFiles,downloadFiles,clientName){ console.log(stdout); console.log(stderr); - resolve(); + pluginsFinished = pluginsFinished +1; + if (checkedPlugins.length == pluginsFinished){ + resolve(); + } + }); }) @@ -118,7 +120,6 @@ function backendBuild(checkedFiles, clientName, fileName){ if (error) { - console.log('backendBuild:', error); reject(error); return; } diff --git a/clientFolder.js b/clientFolder.js index 6307f0043429945a5ec1efa90c0aa319ebf59128..439183e2f8c2ffa03967be1c353dcbeab09c5187 100644 --- a/clientFolder.js +++ b/clientFolder.js @@ -1,11 +1,13 @@ const express = require('express'); const exec = require('child_process').exec; +//functions for creating and removing the client specific working directory "client_x/" + function makeClientFolder(clientName){ exec('mkdir ' + clientName, (error, stdout,stderr)=>{ if (error) { - console.log('error in mkdir:', error); + return(error); } console.log(stdout); @@ -19,7 +21,7 @@ function removeClientFolder(clientName){ exec('rm -rf ' + clientName + '/', (error, stdout,stderr)=>{ if (error) { - console.log('error in rmdir:', error); + return(error); } console.log(stdout); diff --git a/frontendFunctions.js b/frontendFunctions.js index 2de7d85f8f9a181dc6b5a242cbca53557bd53b83..a0ddab922c92742a2b3a722f0c496f153fe51913 100644 --- a/frontendFunctions.js +++ b/frontendFunctions.js @@ -1,27 +1,28 @@ const express = require('express'); const exec = require('child_process').exec; +//These functions handle everything regarding the frontend of ExplorViz except adding it to the zip. Each function returns a Promise. - function prepareClientFolder(clientName, fileName){ - return new Promise((resolve,reject)=>{ +function prepareClientFolder(clientName, fileName){ + return new Promise((resolve,reject)=>{ - exec('cp -R ' + fileName + '/ ' + clientName + '/',(error,stdout,stderr)=>{ + exec('cp -R ' + fileName + '/ ' + clientName + '/',(error,stdout,stderr)=>{ - if (error) { - reject(error); - return; - } + if (error) { + reject(error); + return; + } - console.log(stdout); - console.log(stderr); + console.log(stdout); + console.log(stderr); - resolve(fileName); + resolve(fileName); - }) - }) + }) + }) - } +} //remove addons from former builds function frontendClean(clientName, fileName){ @@ -89,13 +90,9 @@ function frontendInstallAddons(clientName, fileName, checkedFiles, downloadFiles console.log(stderr); pluginsFinished = pluginsFinished +1; - - console.log('checkedPlugins.length: ',checkedPlugins.length); - console.log('pluginsFinished: ', pluginsFinished); - if (checkedPlugins.length == pluginsFinished){ + if (checkedPlugins.length == pluginsFinished){ resolve(); - } }); @@ -104,7 +101,7 @@ function frontendInstallAddons(clientName, fileName, checkedFiles, downloadFiles } else { - //If no plugins were checked by the user, the downloader skips this step by resolving immediately. + //If no plugins were checked by the user, the downloader skips the installation step by resolving immediately. resolve(); } diff --git a/initializers/gitRepos.js b/initializers/gitRepos.js index e8dd4c41330697be6229951c4289aa8bb4a9c453..6141d1b025c683f9824a3a21d6ed7130d175e8ee 100644 --- a/initializers/gitRepos.js +++ b/initializers/gitRepos.js @@ -1,7 +1,8 @@ const express = require('express'); const exec = require('child_process').exec; - //Clone the git repos initially for performance. + //These functions clone the git repos of the explorviz-ui-backend, explorviz-ui-frontend and plugins for the backend once the server is started. + //The Urls for downloading are taken from the downloadFiles.json file. function initialize(downloadFiles){ return initBackend(downloadFiles).then(function(downloadFiles){ return initBackendPlugins(downloadFiles).then(function(downloadFiles){ @@ -33,7 +34,8 @@ const exec = require('child_process').exec; function initBackendPlugins(downloadFiles){ downloadNames = Object.keys(downloadFiles); - + let pluginsFinished=0; + const backendPlugins = downloadNames.filter(function(file){ return /\bexplorviz-backend-plugin-\w*/.exec(file); }); @@ -51,9 +53,11 @@ const exec = require('child_process').exec; console.log(stdout); console.log(stderr); + pluginsFinished = pluginsFinished +1; - resolve(downloadFiles); - + if (backendPlugins.length == pluginsFinished){ + resolve(downloadFiles); + } }); }) @@ -62,9 +66,6 @@ const exec = require('child_process').exec; } }) - - - } function initFrontend(downloadFiles){ diff --git a/views/download.hbs b/views/download.hbs index e1b7061d7766ecba7f553125804497a683b709d0..9c0f3b4759680ebf90066a055a92efddccfd4422 100644 --- a/views/download.hbs +++ b/views/download.hbs @@ -8,12 +8,15 @@ <title>Download</title> <!-- Bootstrap --> - <!--<link href="../node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">--> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> </head> <body> <div class ="container"> - <div class="row"><div class="col-md-2"></div> <div class="col-md-10"><h3>Choose which files to compile into your custom build of ExplorViz:</h3></div></div> + <div class="row"> + <div class="col-md-2"></div> + <div class="col-md-10"><h3>Choose which files to compile into your custom build of ExplorViz:</h3> + </div> + </div> <div class="row"> <div class="col-md-3"></div> <div class="col-md-9"> @@ -32,27 +35,21 @@ </form> </div> </div> - <div class="row"> + <div class="row"> <div class="col-md-3"></div> - <div class="col-md-6">Please do not close the window, while your download is being prepared. -<!-- <iframe id ="downloadFrame" src="" onload="onDownloadFinished(this)"></iframe> - <script type="text/javascript"> - document.getElementById('downloadFrame').onload= function() { - //"Your download will start automatically." - // Hier newDownload anzeigen und checkedFiles übergeben?! - }; - </script> --> -{{#each checkedFiles as |file|}} - {{/each}} - <script> location.href="/download?checkedFiles={{checkedFiles}}" </script> + <div class="col-md-6">Please do not close the window while your download is being prepared. <br> + You have chosen: + <ul class="list-group"> + {{#each checkedFiles as |file|}} + <li class="list-group-item">{{file}}</li> + {{/each}} + </ul> + <script> location.href="/download?checkedFiles={{checkedFiles}}" </script> </div> - </div> <!-- jQuery (necessary for Bootstrap's JavaScript plugins) --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> - <!-- Include all compiled plugins (below), or include individual files as needed --> - <!-- <script src="../node_modules/bootstrap/dist/js/bootstrap.min.js"></script>--> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script> </body> </html> \ No newline at end of file diff --git a/views/home.hbs b/views/home.hbs index 8ff16ac3869375a56bcf500a3573fcba0989fd30..b2e46e59c6b49b7de0bd4115991b988b96a9ce46 100644 --- a/views/home.hbs +++ b/views/home.hbs @@ -8,7 +8,6 @@ <title>Download</title> <!-- Bootstrap --> - <!--<link href="../node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">--> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> </head> <body> @@ -35,12 +34,8 @@ </form> </div> </div> - - <!-- jQuery (necessary for Bootstrap's JavaScript plugins) --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> - <!-- Include all compiled plugins (below), or include individual files as needed --> - <!-- <script src="../node_modules/bootstrap/dist/js/bootstrap.min.js"></script>--> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script> </body> </html> \ No newline at end of file diff --git a/views/tooManyClients.hbs b/views/tooManyClients.hbs index 7d7b0900dbc44c844dcb1263b51e1654e4633211..eda4b5b857b7efb4baae6f3093bbfb82dfd4b7ea 100644 --- a/views/tooManyClients.hbs +++ b/views/tooManyClients.hbs @@ -8,7 +8,6 @@ <title>Download</title> <!-- Bootstrap --> - <!--<link href="../node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">--> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> </head> <body> @@ -21,7 +20,6 @@ <!-- jQuery (necessary for Bootstrap's JavaScript plugins) --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> <!-- Include all compiled plugins (below), or include individual files as needed --> - <!-- <script src="../node_modules/bootstrap/dist/js/bootstrap.min.js"></script>--> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script> </body> </html> \ No newline at end of file diff --git a/zipFunctions.js b/zipFunctions.js index 99ca9ea3136be06784088ae39e6feb990c3ab28f..59f98fefc62d535dc31fd7089e5ad60c1451e541 100644 --- a/zipFunctions.js +++ b/zipFunctions.js @@ -5,7 +5,8 @@ const JSZip = require('jszip'); const clientFolder = require('./clientFolder.js'); - +//streamFilesToZip waits for frontend and/or backend to be build and streams the built project(s) to one zip. +//In the end it removes the working directory (client_x/). function streamFilesToZip(promiseArray,zip, clientName){ let finishedArray=[]; @@ -50,6 +51,7 @@ const clientFolder = require('./clientFolder.js'); } if(file.zipFileName === 'frontend'){ + //TODO do not write client_x folder in zip, but we need it in file.path in order to find the folder that should be copied. const frontendStream = fsReaddir(file.path) .on('error', function(err) { console.log('error:', err);