jmacura преди 4 години
родител
ревизия
3d7ceb4ad4
променени са 2 файла, в които са добавени 134 реда и са изтрити 170 реда
  1. 120 162
      index.js
  2. 14 8
      nuts-data.js

+ 120 - 162
index.js

@@ -38,176 +38,143 @@ app.get('/', (req, res) => {
 
 /* Makes refresh of the data loaded to the server objects.
    Must be called after the CSV data has changed */
-app.get('/refresh', (req, res, next) => {
-  nutsData.loadDatasets(_datasetsFilePath, function (ds) {
+app.get('/refresh', async (req, res, next) => {
+  try {
+    _datasets = await nutsData.loadDatasets(_datasetsFilePath)
     //console.log('Datasets loaded succesfully');
-    _datasets = ds;
-    nutsData.loadRuralData(_dataFilePath, _datasets, function (rd) {
-      //console.log('Rural data loaded succesfully');
-      _ruralData = rd;
-      res.send('Data refreshed');
-    });
-  });
+    _ruralData = await nutsData.loadRuralData(_dataFilePath, _datasets)
+    //console.log('Rural data loaded succesfully');
+  } catch (e) {
+    res.send(e.toString() || e)
+  }
+  res.send('Data refreshed')
 });
 
 /* Returns JSON array with the list of all the datasets */
-app.get('/datasets', (req, res, next) => {
-  if (_datasets) {
-    helpers.formatResponse(_datasets, req, res);
-  }
-  else {
-    nutsData.loadDatasets(_datasetsFilePath, function (ds) {
-      //console.log('Datasets loaded callback');
-      _datasets = ds;
-      helpers.formatResponse(_datasets, req, res);
-    });
+app.get('/datasets', async (req, res, next) => {
+  if (!_datasets) {
+    try {
+      _datasets = await nutsData.loadDatasets(_datasetsFilePath)
+    } catch (e) {
+      res.send(e.toString() || e)
+    }
   }
+  helpers.formatResponse(_datasets, req, res)
 });
 
 /* Returns JSON array with the list of all the datasets */
-app.get('/datasets/cz', (req, res, next) => {
+app.get('/datasets/cz', async (req, res, next) => {
   console.log('received datasets/cz GET request')
-  if (_datasetsCZ) {
-    helpers.formatResponse(_datasetsCZ, req, res);
-  }
-  else {
-    nutsData.loadDatasets(_datasetsCzFilePath, function (ds) {
-      //console.log('Datasets loaded callback');
-      _datasetsCZ = ds;
-      helpers.formatResponse(_datasetsCZ, req, res);
-    });
+  if (!_datasetsCZ) {
+    try {
+      _datasetsCZ = await nutsData.loadDatasets(_datasetsCzFilePath)
+    } catch (e) {
+      res.send(e.toString() || e)
+    }
   }
+  //console.log('Datasets loaded callback');
+  helpers.formatResponse(_datasetsCZ, req, res)
 });
 
 /* Returns attractivity data for the region with ID equal to the 'nuts' parameter */
-app.get('/scores/:nuts', (req, res, next) => {
-  if (_ruralData) {
-    returnRegionScores(req.params.nuts, req, res);
-  }
-  else {
-    if (_datasets) { // datasets must be loaded prior to data loading
-      nutsData.loadRuralData(_dataFilePath, _datasets, function (rd) {
-        _ruralData = rd;
-        returnRegionScores(req.params.nuts, req, res);
-      });
+app.get('/scores/:nuts', async (req, res, next) => {
+  if (!_datasets) { // datasets must be loaded prior to data loading
+    try {
+      _datasets = await nutsData.loadDatasets(_datasetsFilePath)
+    } catch (e) {
+      res.send(e.toString() || e)
     }
-    else {
-      nutsData.loadDatasets(_datasetsFilePath, function (ds) {
-        _datasets = ds;
-
-        nutsData.loadRuralData(_dataFilePath, _datasets, function (rd) {
-          _ruralData = rd;
-          returnRegionScores(req.params.nuts, req, res);
-        });
-      });
+  }
+  if (!_ruralData) {
+    try {
+      _ruralData = await nutsData.loadRuralData(_dataFilePath, _datasets)
+    } catch (e) {
+      res.send(e.toString() || e)
     }
   }
+  returnRegionScores(req.params.nuts, req, res)
 });
 
 /* Returns attractivity data for all the regions in source CSV data. */
-app.get('/scores', (req, res, next) => {
-  if (_ruralData)
-    helpers.formatResponse(_ruralData, req, res);
-  else {
-    if (_datasets) { // datasets must be loaded prior to data loading
-      nutsData.loadRuralData(_dataFilePath, _datasets, function (rd) {
-        _ruralData = rd;
-        helpers.formatResponse(_ruralData, req, res);
-      });
+app.get('/scores', async (req, res, next) => {
+  if (!_datasets) { // datasets must be loaded prior to data loading
+    try {
+      _datasets = await nutsData.loadDatasets(_datasetsFilePath)
+    } catch (e) {
+      res.send(e.toString() || e)
     }
-    else {
-      nutsData.loadDatasets(_datasetsFilePath, function (ds) {
-        _datasets = ds;
-
-        nutsData.loadRuralData(_dataFilePath, _datasets, function (rd) {
-          _ruralData = rd;
-          helpers.formatResponse(_ruralData, req, res);
-        });
-      });
+  }
+  if (!_ruralData) {
+    try {
+      _ruralData = await nutsData.loadRuralData(_dataFilePath, _datasets)
+    } catch (e) {
+      res.send(e.toString() || e)
     }
   }
+  helpers.formatResponse(_ruralData, req, res)
 });
 
 /* Computes and returns attractivity data for all the NUTS regions based on the
    incomming datasets and factor weights. */
-app.post('/scores', (req, res, next) => {
+app.post('/scores', async (req, res, next) => {
   //console.log("query: " + JSON.stringify(req.body.factors, null, 4));
-
-  if (_ruralData) {
-    returnAllScores(req, res);
-  }
-  else {
-    if (_datasets) { // datasets must be loaded prior to data loading
-      nutsData.loadRuralData(_dataFilePath, _datasets, function (rd) {
-        _ruralData = rd;
-        returnAllScores(req, res);
-      });
+  if (!_datasets) { // datasets must be loaded prior to data loading
+    try {
+      _datasets = await nutsData.loadDatasets(_datasetsFilePath)
+    } catch (e) {
+      res.send(e.toString() || e)
     }
-    else {
-      nutsData.loadDatasets(_datasetsFilePath, function (ds) {
-        _datasets = ds;
-
-        nutsData.loadRuralData(_dataFilePath, _datasets, function (rd) {
-          _ruralData = rd;
-          returnAllScores(req, res);
-        });
-      });
+  }
+  if (!_ruralData) {
+    try {
+      _ruralData = await nutsData.loadRuralData(_dataFilePath, _datasets)
+    } catch (e) {
+      res.send(e.toString() || e)
     }
   }
+  returnAllScores(req, res)
 });
 
 /* Returns attractivity data for all the regions in source CSV data. */
-app.get('/scores/cz', (req, res, next) => {
+app.get('/scores/cz', async (req, res, next) => {
   console.log('received scores/cz GET request')
-  if (_ruralDataCZ)
-    helpers.formatResponse(_ruralDataCZ, req, res);
-  else {
-    if (_datasetsCZ) { // datasets must be loaded prior to data loading
-      nutsData.loadRuralData(_dataCzFilePath, _datasetsCZ, function (rd) {
-        _ruralDataCZ = rd;
-        helpers.formatResponse(_ruralDataCZ, req, res);
-      });
+  if (!_datasetsCZ) { // datasets must be loaded prior to data loading
+    try {
+      _datasetsCZ = await nutsData.loadDatasets(_datasetsCzFilePath)
+    } catch (e) {
+      res.send(e.toString() || e)
     }
-    else {
-      nutsData.loadDatasets(_datasetsCzFilePath, function (ds) {
-        _datasetsCZ = ds;
-
-        nutsData.loadRuralData(_dataCzFilePath, _datasetsCZ, function (rd) {
-          _ruralDataCZ = rd;
-          helpers.formatResponse(_ruralDataCZ, req, res);
-        });
-      });
+  }
+  if (!_ruralDataCZ) {
+    try {
+      _ruralDataCZ = await nutsData.loadRuralData(_dataCzFilePath, _datasetsCZ)
+    } catch (e) {
+      res.send(e.toString() || e)
     }
   }
+  helpers.formatResponse(_ruralDataCZ, req, res)
 });
 
 /* Computes and returns attractivity data for all the NUTS regions based on the
    incomming datasets and factor weights. */
-app.post('/scores/cz', (req, res, next) => {
+app.post('/scores/cz', async (req, res, next) => {
   console.log('received scores/cz POST request')
   //console.log("query: " + JSON.stringify(req.body.factors, null, 4));
-
-  if (_ruralDataCZ) {
-    returnAllScoresCz(req, res);
-  }
-  else {
-    if (_datasetsCZ) { // datasets must be loaded prior to data loading
-      nutsData.loadRuralData(_dataCzFilePath, _datasetsCZ, function (rd) {
-        _ruralDataCZ = rd;
-        returnAllScoresCz(req, res);
-      });
+  if (!_datasetsCZ) { // datasets must be loaded prior to data loading
+    try {
+      _datasetsCZ = await nutsData.loadDatasets(_datasetsCzFilePath)
+    } catch (e) {
+      res.send(e.toString() || e)
     }
-    else {
-      nutsData.loadDatasets(_datasetsCzFilePath, function (ds) {
-        _datasetsCZ = ds;
-
-        nutsData.loadRuralData(_dataCzFilePath, _datasetsCZ, function (rd) {
-          _ruralDataCZ = rd;
-          returnAllScoresCz(req, res);
-        });
-      });
+  }
+  if (!_ruralDataCZ) {
+    try {
+      _ruralDataCZ = await nutsData.loadRuralData(_dataCzFilePath, _datasetsCZ)
+    } catch (e) {
+      res.send(e.toString() || e)
     }
   }
+    returnAllScoresCz(req, res)
 });
 
 /*
@@ -240,21 +207,21 @@ app.get('/runR/:version?', (req, res, next) => {
 */
 app.get(['/clusters', '/clusters/cz'], (req, res, next) => {
   const data = { response: '/clusters methods are only available under POST' }
-  helpers.formatResponse(data, req, res);
+  helpers.formatResponse(data, req, res)
 });
 
 /*
     Modifies input CSV file, calls R script, loads the resulting CSV file and returns it
 */
 app.post('/clusters', async (req, res, next) => {
-  try {
-    if (!_datasets) {
-      //TODO: promisify all functions to avoid callback hell and make this work properly
-      await nutsData.loadDatasets(_datasetsFilePath, function (ds) {
-        //console.log('Datasets loaded succesfully');
-        _datasets = ds;
-      })
+  if (!_datasets) { // datasets must be loaded prior to data loading
+    try {
+      _datasets = await nutsData.loadDatasets(_datasetsFilePath)
+    } catch (e) {
+      res.send(e.toString() || e)
     }
+  }
+  try {
     //console.log(req.body);
     const clusteringData = await nutsData.loadClusteringInput(
       _dataFilePath
@@ -266,9 +233,9 @@ app.post('/clusters', async (req, res, next) => {
       idString: 'NUTS_ID',
       outputFileName: _clusteringModifiedFilePath
     });
-    handleRCall(req, res, 'eu');
+    handleRCall(req, res, 'eu')
   } catch (error) { // Catch errors in async functions
-    next(error.toString());
+    next(error.toString())
   }
 });
 
@@ -276,14 +243,11 @@ app.post('/clusters', async (req, res, next) => {
     Modifies input CSV file, calls R script, loads the resulting CSV file and returns it
 */
 app.post('/clusters/cz', async (req, res, next) => {
+  if (!_datasetsCZ) {
+    _datasetsCZ = await nutsData.loadDatasets(_datasetsCzFilePath)
+    //console.log('Datasets loaded succesfully');
+  }
   try {
-    if (!_datasetsCZ) {
-      //TODO: promisify all functions to avoid callback hell and make this work properly
-      await nutsData.loadDatasets(_datasetsCzFilePath, function (ds) {
-        //console.log('Datasets loaded succesfully');
-        _datasetsCZ = ds;
-      })
-    }
     //console.log(req.body);
     const clusteringData = await nutsData.loadClusteringInput(
       _clusteringCzInputFilePath
@@ -295,35 +259,29 @@ app.post('/clusters/cz', async (req, res, next) => {
       params: req.body,
       idString: 'LAU2',
       outputFileName: _clusteringCzModifiedFilePath
-    });
+    })
     handleRCall(req, res, 'cz');
   } catch (error) { // Catch errors in async functions
     next(error.toString());
   }
 });
 
-app.get('/georeport/:nuts', (req, res, next) => {
-  if (_ruralData) {
-    renderPugReport(req.params.nuts, req, res);
-  }
-  else {
-    if (_datasets) { // datasets must be loaded prior to data loading
-      nutsData.loadRuralData(_dataFilePath, _datasets, function (rd) {
-        _ruralData = rd;
-        renderPugReport(req.params.nuts, req, res);
-      });
+app.get('/georeport/:nuts', async (req, res, next) => {
+  if (!_datasets) { // datasets must be loaded prior to data loading
+    try {
+      _datasets = await nutsData.loadDatasets(_datasetsFilePath)
+    } catch (e) {
+      res.send(e.toString() || e)
     }
-    else {
-      nutsData.loadDatasets(_datasetsFilePath, function (ds) {
-        _datasets = ds;
-
-        nutsData.loadRuralData(_dataFilePath, _datasets, function (rd) {
-          _ruralData = rd;
-          renderPugReport(req.params.nuts, req, res);
-        });
-      });
+  }
+  if (!_ruralData) {
+    try {
+      _ruralData = await nutsData.loadRuralData(_dataFilePath, _datasets)
+    } catch (e) {
+      res.send(e.toString() || e)
     }
   }
+  renderPugReport(req.params.nuts, req, res);
 });
 
 // start the service on the port xxxx
@@ -331,7 +289,7 @@ app.listen(3000, () => console.log('Rural attractivity WS listening on port 3000
 
 
 function renderPugReport(nuts, req, res) {
-  var found = false;
+  let found = false;
 
   _ruralData.forEach(region => {
     if (region.nuts == nuts) {

+ 14 - 8
nuts-data.js

@@ -3,12 +3,13 @@ const csv = require('csv-parse');
 const stringify = require('csv-stringify');
 
 /* Helper method to load the datasets from CSV and store it in server object */
-module.exports.loadDatasets = function(filePath, dataLoadedCallback) {
+module.exports.loadDatasets = async function(filePath) {
     //console.log('Datasets structure loading.');
-    var datasets = [];
+    let datasets = [];
 
     let columns = undefined;
 
+    return new Promise((resolve, reject) => {
     fs.createReadStream(filePath)
         .pipe(csv({ separator: ';' }))
         .on('data', (row) => {
@@ -26,18 +27,21 @@ module.exports.loadDatasets = function(filePath, dataLoadedCallback) {
         })
         .on('end', () => {
             //console.log('Datasets structure loaded.');
-            dataLoadedCallback(datasets);
-        });
+            resolve(datasets);
+        })
+        .on('error', reject);
+    })
 }
 
 /* Load all the attractivness data from CSV into a server object.
    The data don't need to be loaded for each request then. */
-module.exports.loadRuralData = function (filePath, datasets, dataLoadedCallback) {
+module.exports.loadRuralData = async function (filePath, datasets) {
     console.log('Reading rural data file processing started.');
-    var ruralData = [];
+    let ruralData = [];
 
     let columns = undefined;
 
+    return new Promise((resolve, reject) => {
     fs.createReadStream(filePath)
         .pipe(csv())
         .on('data', (row) => {
@@ -74,8 +78,10 @@ module.exports.loadRuralData = function (filePath, datasets, dataLoadedCallback)
         })
         .on('end', () => {
             //console.log('Rural data file processing finished.');
-            dataLoadedCallback(ruralData);
-        });
+            resolve(ruralData);
+        })
+        .on('error', reject);
+    })
 }
 
 /**