Browse Source

Refactored the `FileService.parseFromUrl` method to return the filepath instead of a stream, and updated the `routes/index.js` file to handle the new return value

node10
Onja 11 months ago
parent
commit
cd747af78a
  1. 31
      src/models/file.js
  2. 24
      src/routes/index.js
  3. 15
      src/services/file.js

31
src/models/file.js

@ -18,15 +18,6 @@ const { basedir } = require('../config/constants');
const dest = path.join(basedir, 'public/csv');
// Create a generateFilePath function witch returns a path with a filename and datetime
function generateFilePath(filename) {
return {
filepath: path.join(dest, `${filename}-${Date.now()}.csv`),
generatedpath: path.join(dest, `${filename}-generated-${Date.now()}.csv`),
};
}
// Create a class File that extends EventEmitter
class File {
@ -38,7 +29,14 @@ class File {
this.url = url;
}
// Create a generateFilePath function witch returns a path with a filename and datetime
generateFilePath(filename) {
const date = new Date();
return {
filepath: path.join(dest, `${filename}-${date.toISOString().split('T')[0]}.csv`),
generatedpath: path.join(dest, `${filename}-generated-${date.toISOString().split('T')[0]}.csv`),
};
}
/**
* Download a file from a url
@ -47,7 +45,7 @@ class File {
async download() {
const url = URL.parse(this.url);
this.filename = slugify(url.hostname, { lower: true });
const { filepath, generatedpath } = generateFilePath(this.filename);
const { filepath, generatedpath } = this.generateFilePath(this.filename);
this.filepath = filepath;
this.generatedpath = generatedpath;
@ -121,13 +119,14 @@ class File {
// create a parse method which read the file and return a stream
parse(columns) {
const stream = new PassThrough();
return new Promise((resolve, reject) => {
const fileStream = fs.createWriteStream(this.generatedpath);
// check if columns is valid
if (!columns || !columns.length) {
// return Promise.reject(new Error('Invalid columns'));
emitter.emit('parse.error', { url: this.url, filepath: this.filepath, error: 'Invalid columns' });
reject(new Error('Invalid columns'));
return false;
}
@ -163,14 +162,12 @@ class File {
// Emit a parse.start event with the url and filepath
emitter.emit('parse.start', { url: this.url, filepath: this.filepath, headers, result: result });
stream.write(result.join(';') + "\n");
fileStream.write(result.join(';') + "\n");
})
.on('data', (row) => {
// Emit a parse.data event with the url, filepath and data
let result = this.processRow(row, columnsIndex, columnsFiltered);
emitter.emit('parse.data', { url: this.url, filepath: this.filepath, data: row, result, index: count });
stream.write(result.join(';') + "\n");
fileStream.write(result.join(';') + "\n");
count++;
})
@ -179,16 +176,16 @@ class File {
emitter.emit('parse.error', { url: this.url, filepath: this.filepath, error: err.message });
fileStream.close();
reject(err);
fs.unlink(this.generatedpath, () => {});
})
.on('end', () => {
// Emit a parse.end event with the url and filepath
stream.end();
fileStream.close();
resolve(this.generatedpath);
emitter.emit('parse.end', { url: this.url, filepath: this.filepath, count: count - 1, generated: path.basename(this.generatedpath) });
});
return stream;
});
}
/**

24
src/routes/index.js

@ -105,7 +105,7 @@ router.get('/', async function(req, res, next) {
return res;
});
router.post('/', async function(req, res, next) {
router.post('/', function(req, res, next) {
// const url = 'https://bodacc-datadila.opendatasoft.com/api/explore/v2.1/catalog/datasets/annonces-commerciales/exports/csv?lang=fr&refine=publicationavis%3A%22A%22&refine=publicationavis_facette%3A%22Bodacc%20A%22&refine=familleavis_lib%3A%22Ventes%20et%20cessions%22&timezone=Asia%2FBaghdad&use_labels=true&delimiter=%3B';
// get url from form
@ -120,22 +120,16 @@ router.post('/', async function(req, res, next) {
return res.status(500).send('Invalid columns');
}
let stream = null;
try {
stream = await fileService.parseFromUrl(url, columns);
} catch (err) {
fileService.parseFromUrl(url, columns)
.then((filepath) => {
res.send({
success: true
})
})
.catch(err => {
console.error('routes [/] error', err.message);
}
if ( !stream ) {
return res.status(500).send('Invalid stream');
}
res.setHeader('Content-Disposition', 'attachment; filename="mon_fichier.csv"');
res.setHeader('Content-Type', 'text/csv; charset=utf-8');
stream.pipe(res);
// res.render('index', { title: 'Express' });
});
});
module.exports = router;

15
src/services/file.js

@ -29,14 +29,15 @@ class FileService {
const file = new File(url);
const filepath = await file.download();
const stream = file.parse(columns);
if ( !stream ) {
emitter.emit('parseFromUrl.error', { url, columns, error: 'Invalid stream' });
return Promise.reject(new Error('Invalid stream'));
}
return file.parse(columns)
.then((filepath) => {
emitter.emit('parseFromUrl.end', { url, columns, filepath });
return Promise.resolve(stream);
return filepath;
})
.catch((err) => {
emitter.emit('parseFromUrl.error', { url, columns, error: err.message });
return err;
});
}
/**

Loading…
Cancel
Save