From cdb26ad8e5915e71a4c9bdda46a1006cd29eb63e Mon Sep 17 00:00:00 2001 From: jweg <jweg@informatik.uni-kiel.de> Date: Thu, 27 Jul 2017 16:35:47 +0200 Subject: [PATCH] work in progress: include backendPlugin && manage requests from multiple clients --- app.js | 50 +++++++++++++++++++++++++++++---------- backendFunctions.js | 51 ++++++++++++++++++++++++++++++++-------- clientFolder.js | 34 +++++++++++++++++++++++++++ downloadFiles.json | 3 ++- frontendFunctions.js | 40 ++++++++++++++++++++++++------- initializers/gitRepos.js | 4 ++-- views/download.hbs | 8 +++---- views/home.hbs | 5 +++- views/tooManyClients.hbs | 27 +++++++++++++++++++++ zipFunctions.js | 26 ++++++++++---------- 10 files changed, 197 insertions(+), 51 deletions(-) create mode 100644 clientFolder.js create mode 100644 views/tooManyClients.hbs diff --git a/app.js b/app.js index baff28b..c3c822e 100644 --- a/app.js +++ b/app.js @@ -17,6 +17,7 @@ const downloadFiles = require('./downloadFiles.json'); const downloadNames = Object.keys(downloadFiles); //load functions for frontend and backend build +const clientFolder = require('./clientFolder.js'); const backendFunctions = require('./backendFunctions.js'); const frontendFunctions = require('./frontendFunctions.js'); const zipFunctions = require('./zipFunctions.js'); @@ -32,12 +33,13 @@ app.use(bodyParser.json()); app.engine('.hbs', exphbs({extname: '.hbs'})); app.set('view engine', '.hbs'); - +let clientCounter = 0; + //TODO add spinner for telling user to wait until initialization is done //initGitRepos.initialize(downloadFiles); //routes app.get('/', function(req, res){ - + res.render('home', {downloadFiles: downloadNames}); }); @@ -55,10 +57,23 @@ app.set('view engine', '.hbs'); app.get('/download', function(req, res, next){ + let clientName; + const zip = new JSZip(); + zip.file("README.txt", "text for README"); //holds promises for backend and/or frontend for synchronizing const promiseArray = [] const checkedFiles = req.query.checkedFiles.split(','); + clientCounter= clientCounter + 1; + console.log('clientCounter after increment:', clientCounter); + if (clientCounter > 5){ + res.render('tooManyClients'); + }else{ + clientName = 'client_' + clientCounter; + clientFolder.makeClientFolder(clientName); + + } + backendChecked = checkedFiles.find(function(file){ @@ -67,7 +82,8 @@ app.set('view engine', '.hbs'); frontendChecked = checkedFiles.find(function(file){ return file === 'explorviz-ui-frontend'; }); -//the user is not allowed to check plugins without having checked frontend or backend core +//The user is not allowed to check plugins without having checked frontend or backend core. +//If he has not checked at least one of those, he will be redirected to the homepage. if(!(backendChecked || frontendChecked)){ res.render('home', {downloadFiles: downloadNames}); } @@ -77,10 +93,12 @@ if (backendChecked){ const fileName = backendChecked; function backendAll(){ - return backendFunctions.backendClean(fileName).then(function(){ - return backendFunctions.backendPull(fileName).then(function(){ - return backendFunctions.backendInstallAddons(checkedFiles,downloadFiles).then(function(){ - return backendFunctions.backendBuild(fileName) + return backendFunctions.prepareClientFolder(clientName,fileName).then(function(){ + return backendFunctions.backendClean(clientName, fileName).then(function(){ + return backendFunctions.backendPull(clientName, fileName).then(function(){ + return backendFunctions.backendInstallAddons(checkedFiles,downloadFiles,clientName).then(function(){ + return backendFunctions.backendBuild(clientName, fileName) + }) }) }) }).catch(function(error){ @@ -104,10 +122,12 @@ if (frontendChecked){ const downloadURL = downloadFiles[frontendChecked]; function frontendAll() { - return frontendFunctions.frontendClean(fileName).then(function(){ - return frontendFunctions.frontendPull(fileName).then(function(){ - return frontendFunctions.frontendInstallAddons(fileName, checkedFiles, downloadFiles).then(function(){ - return frontendFunctions.frontendBuild(fileName) + return frontendFunctions.prepareClientFolder(clientName,fileName).then(function(){ + return frontendFunctions.frontendClean(clientName,fileName).then(function(){ + return frontendFunctions.frontendPull(clientName,fileName).then(function(){ + return frontendFunctions.frontendInstallAddons(clientName,fileName, checkedFiles, downloadFiles).then(function(){ + return frontendFunctions.frontendBuild(clientName,fileName) + }) }) }) }).catch(function(error){ @@ -125,9 +145,10 @@ if (frontendChecked){ finalizeZip(); - +console.log('promiseArray:', promiseArray); function finalizeZip(){ - return zipFunctions.streamFilesToZip(promiseArray).then(function(zip){ + //Wo clientCounter runterzählen? + return zipFunctions.streamFilesToZip(promiseArray,zip, clientName).then(function(zip){ return createZip(zip) }).catch(function(error) {let response = 'There was an error during your build. ' + @@ -144,6 +165,9 @@ 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); + clientCounter = clientCounter - 1; + console.log('clientCounter in the end:', clientCounter); res.download('explorviz-builds.zip', function(error){ if(error){ let response = diff --git a/backendFunctions.js b/backendFunctions.js index 85a9e9a..9f3245f 100644 --- a/backendFunctions.js +++ b/backendFunctions.js @@ -1,12 +1,39 @@ -var express = require('express'); -var exec = require('child_process').exec; +const express = require('express'); +const exec = require('child_process').exec; -function backendClean(fileName){ + + + +function prepareClientFolder(clientName, fileName){ + return new Promise((resolve,reject)=>{ + + exec('cp -R ' + fileName + ' ' + clientName + '/',(error,stdout,stderr)=>{ + + if (error) { + reject(error); + return; + } + + console.log(stdout); + console.log(stderr); + + resolve(fileName); + + }) + }) + + +} + + + +function backendClean(clientName, fileName){ return new Promise((resolve,reject)=>{ - exec('cd explorviz-ui-backend/plugins/net/explorviz/ && rm -rf plugins/*', (error, stdout,stderr)=>{ + exec('cd ' + clientName + '/explorviz-ui-backend/plugins/net/explorviz/ && rm -rf plugins/*', (error, stdout,stderr)=>{ if (error) { + console.log('backendClean:', error); reject(error); return; } @@ -20,13 +47,14 @@ function backendClean(fileName){ }) } -function backendPull(fileName){ +function backendPull(clientName, fileName){ return new Promise((resolve, reject)=> { - exec('cd ' + fileName + ' git pull ', (error, stdout, stderr) => { + exec('cd ' + clientName + '/' + fileName + ' && git pull ', (error, stdout, stderr) => { if (error) { + console.log('backendPull:', error); reject(error); return; } @@ -41,7 +69,7 @@ function backendPull(fileName){ } -function backendInstallAddons(checkedFiles,downloadFiles){ +function backendInstallAddons(checkedFiles,downloadFiles,clientName){ return new Promise((resolve, reject)=>{ checkedPlugins = checkedFiles.filter(function(file){ @@ -51,9 +79,10 @@ function backendInstallAddons(checkedFiles,downloadFiles){ if(checkedPlugins.length !== 0 ){ checkedPlugins.forEach((pluginName) => { - exec('cd '+ pluginName + ' git pull ' + '&& rsync -av . ' + ' ../explorviz-ui-backend/plugins/net/explorviz/plugins/ ' + ' --exclude .git', (error, stdout, stderr) => { //'cd explorviz-ui-backend/plugins/net/explorviz/plugins/ ' + + exec('cd '+ pluginName + ' && git pull ' + ' && rsync -av . ' + ' ../' + clientName +'/explorviz-ui-backend/plugins/net/explorviz/plugins/ ' + ' --exclude .git', (error, stdout, stderr) => { //'cd explorviz-ui-backend/plugins/net/explorviz/plugins/ ' + if (error) { + console.log('backendInstallAddons:', error); reject(error); return; } @@ -74,11 +103,12 @@ function backendInstallAddons(checkedFiles,downloadFiles){ } -function backendBuild(fileName){ +function backendBuild(clientName, fileName){ return new Promise((resolve,reject)=>{ - exec('cd '+ fileName + ' && mvn compile war:war ', (error,stdout,stderr)=> { + exec('cd '+ clientName + '/' + fileName + ' && mvn compile war:war ', (error,stdout,stderr)=> { if (error) { + console.log('backendBuild:', error); reject(error); return; } @@ -96,6 +126,7 @@ function backendBuild(fileName){ } module.exports = { + prepareClientFolder, backendClean, backendPull, backendInstallAddons, diff --git a/clientFolder.js b/clientFolder.js new file mode 100644 index 0000000..b281a3d --- /dev/null +++ b/clientFolder.js @@ -0,0 +1,34 @@ +const express = require('express'); +const exec = require('child_process').exec; + +function makeClientFolder(clientName){ + exec('mkdir ' + clientName, (error, stdout,stderr)=>{ + + if (error) { + console.log('error in mkdir:', error); + } + + console.log(stdout); + console.log(stderr); + + }) +} + + +function removeClientFolder(clientName){ + exec('rm -rf ' + clientName, (error, stdout,stderr)=>{ + + if (error) { + console.log('error in rmdir:', error); + } + + console.log(stdout); + console.log(stderr); + + }) +} + +module.exports = { + makeClientFolder, + removeClientFolder +} \ No newline at end of file diff --git a/downloadFiles.json b/downloadFiles.json index 0de3dca..a21e3f9 100644 --- a/downloadFiles.json +++ b/downloadFiles.json @@ -1,5 +1,6 @@ { "explorviz-ui-frontend": "https://github.com/ExplorViz/explorviz-ui-frontend.git", - "explorviz-ui-backend": "https://github.com/ExplorViz/explorviz-ui-backend.git", +"explorviz-frontend-plugin-colorpicker":"https://github.com/ExplorViz/explorviz-frontend-plugin-colorpicker.git", "explorviz-frontend-plugin-example": "https://github.com/ExplorViz/explorviz-frontend-plugin-example.git", + "explorviz-ui-backend": "https://github.com/ExplorViz/explorviz-ui-backend.git", "explorviz-backend-plugin-example": "https://github.com/ExplorViz/explorviz-backend-plugin-example.git" } \ No newline at end of file diff --git a/frontendFunctions.js b/frontendFunctions.js index 0112c10..5b55a12 100644 --- a/frontendFunctions.js +++ b/frontendFunctions.js @@ -1,10 +1,33 @@ let express = require('express'); let exec = require('child_process').exec; - function frontendClean(fileName){ + + +function prepareClientFolder(clientName, fileName){ +return new Promise((resolve,reject)=>{ + +exec('cp -R ' + fileName + ' ' + clientName + '/',(error,stdout,stderr)=>{ + + if (error) { + reject(error); + return; + } + + console.log(stdout); + console.log(stderr); + + resolve(fileName); + +}) +}) + + +} + + function frontendClean(clientName, fileName){ return new Promise((resolve, reject) => { - exec('cd ' + fileName + ' && git checkout package.json && npm prune ', (error, stdout, stderr) => { + exec('cd ' + clientName + '/' + fileName + ' && git checkout package.json && npm prune ', (error, stdout, stderr) => { if (error) { reject(error) @@ -20,11 +43,11 @@ } - function frontendPull(fileName){ + function frontendPull(clientName, fileName){ return new Promise((resolve, reject) => { - exec('cd ' + fileName +' && git pull ', (error, stdout, stderr) => { + exec('cd ' + clientName + '/' + fileName +' && git pull ', (error, stdout, stderr) => { if (error) { reject(error) @@ -38,7 +61,7 @@ }) } - function frontendInstallAddons(fileName, checkedFiles, downloadFiles){ + function frontendInstallAddons(clientName, fileName, checkedFiles, downloadFiles){ return new Promise((resolve, reject) => { @@ -49,7 +72,7 @@ if(checkedPlugins.length !== 0 ){ checkedPlugins.forEach((pluginName) => { //TODO now addon is listed under dependencies-section in package.json - exec('cd ' + fileName + ' && ember install ' + downloadFiles[pluginName] + ' --save', (error, stdout, stderr) => { + exec('cd ' + clientName + '/' + fileName + ' && ember install ' + downloadFiles[pluginName] + ' --save', (error, stdout, stderr) => { if (error) { reject(error); @@ -72,11 +95,11 @@ }) } - function frontendBuild(fileName){ + function frontendBuild(clientName, fileName){ return new Promise((resolve,reject)=> { - exec('cd ' + fileName +' && ember build --environment=production', (error, stdout, stderr) => { + exec('cd ' + clientName + '/' + fileName + ' && ember build --environment=production', (error, stdout, stderr) => { if (error) { reject(error); @@ -96,6 +119,7 @@ } module.exports = { + prepareClientFolder, frontendClean, frontendPull, frontendInstallAddons, diff --git a/initializers/gitRepos.js b/initializers/gitRepos.js index cc0f89b..e8dd4c4 100644 --- a/initializers/gitRepos.js +++ b/initializers/gitRepos.js @@ -1,5 +1,5 @@ -var express = require('express'); -var exec = require('child_process').exec; +const express = require('express'); +const exec = require('child_process').exec; //Clone the git repos initially for performance. function initialize(downloadFiles){ diff --git a/views/download.hbs b/views/download.hbs index 55fdfd9..e1b7061 100644 --- a/views/download.hbs +++ b/views/download.hbs @@ -13,10 +13,10 @@ </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-3"></div> <div class="col-md-9"> - <h3>Choose which files to compile into your custom build of ExplorViz:</h3> <form action="/" method="post"> <div class ="form-group"> <div class="checkbox"> @@ -34,14 +34,14 @@ </div> <div class="row"> <div class="col-md-3"></div> - <div class="col-md-6"> - <iframe id ="downloadFrame" src="" onload="onDownloadFinished(this)"></iframe> + <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> + </script> --> {{#each checkedFiles as |file|}} {{/each}} <script> location.href="/download?checkedFiles={{checkedFiles}}" </script> diff --git a/views/home.hbs b/views/home.hbs index 75f82eb..8ff16ac 100644 --- a/views/home.hbs +++ b/views/home.hbs @@ -13,10 +13,13 @@ </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-3"></div> <div class="col-md-9"> - <h3>Choose which files to compile into your custom build of ExplorViz:</h3> <form action="/" method="post"> <div class ="form-group"> <div class="checkbox"> diff --git a/views/tooManyClients.hbs b/views/tooManyClients.hbs new file mode 100644 index 0000000..7d7b090 --- /dev/null +++ b/views/tooManyClients.hbs @@ -0,0 +1,27 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags --> + <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>Sorry, too many people.</h3></div> + </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/zipFunctions.js b/zipFunctions.js index ef68a05..afd8521 100644 --- a/zipFunctions.js +++ b/zipFunctions.js @@ -1,22 +1,20 @@ - var express = require('express'); - var fs = require('fs'); - var fsReaddir = require('fs-readdir'); - var JSZip = require('jszip'); + const express = require('express'); + const fs = require('fs'); + const fsReaddir = require('fs-readdir'); + const JSZip = require('jszip'); + + const clientFolder = require('./clientFolder.js'); + - const zip = new JSZip(); - zip.file("README.txt", "text for README"); - let finishedArray=[]; - - function streamFilesToZip(promiseArray){ - + function streamFilesToZip(promiseArray,zip, clientName){ + let finishedArray=[]; return new Promise((resolve,reject)=> { Promise.all(promiseArray).then(files => { files.forEach(file => { if (file.zipFileName === 'backend.war'){ - fs.readFileAsync = function(filePath){ return new Promise(function (resolve, reject) { fs.readFile(filePath, function(err, data) { @@ -38,9 +36,11 @@ } backendContent = fs.readFileAsync(file.path); backendContent.then(function(data){ - addBackendToZip(data).then(function(){ + addBackendToZip(data).then(function(){ finishedArray.push('backend finished'); if(finishedArray.length === promiseArray.length){ + finishedArray=[]; + clientFolder.removeClientFolder(clientName); resolve(zip); } @@ -61,6 +61,8 @@ }).on('finish', function(){ finishedArray.push('frontend finished'); if(finishedArray.length === promiseArray.length){ + finishedArray=[]; + clientFolder.removeClientFolder(clientName); resolve(zip); } -- GitLab