diff --git a/src/models/File.js b/src/models/File.js index 83febe4..730b018 100644 --- a/src/models/File.js +++ b/src/models/File.js @@ -7,7 +7,6 @@ const https = require('https'); const exec = util.promisify(require('child_process').exec); const EventEmitter = require('events'); -const csv = require('csv-parser'); const slugify = require('slugify'); const dest = path.join(appRoot, 'public/csv'); @@ -22,7 +21,10 @@ function generateFilePath(filename) { // Create a class File that extends EventEmitter class File extends EventEmitter { - // Create a constructor that takes a url as a parameter + /** + * Create a new File instance + * @param {string} url + */ constructor(url) { super(); this.url = url; @@ -30,7 +32,10 @@ class File extends EventEmitter { - // Create a download method that downloads the file from the url + /** + * Download a file from a url + * @returns {Promise} filepath + */ async download() { const url = URL.parse(this.url); this.filename = slugify(url.hostname, { lower: true }); @@ -46,13 +51,41 @@ class File extends EventEmitter { file.on('error', (err) => { fs.unlink(filepath, () => { // Emit a download.error event with the error - this.emit('download.error', { url: this.url, filepath: this.filepath, error: err, type: 'file' }); + this.emit('download.error', { url: this.url, filepath: this.filepath, error: err.message, type: 'file' }); }); }); return new Promise((resolve, reject) => { request .get(url.href, (response) => { + // Check if response is valid + if (response.statusCode !== 200) { + // Emit a download.error event with the error + this.emit('download.error', { url: this.url, filepath: this.filepath, error: response.statusMessage, type: 'response' }); + return reject(response.statusMessage); + } + + // Get the content length and parse it to an integer + const contentLength = parseInt(response.headers['content-length'], 10); + + const step = Math.floor(contentLength / 100); + let stepLimit = step; + // Create a variable to hold the downloaded size + let downloaded = 0; + + // Handle response data + response.on('data', (chunk) => { + // Add the size of the chunk to the downloaded variable + downloaded += chunk.length; + + // Check if the downloaded size is bigger than the step limit + if (downloaded > stepLimit) { + // Emit a download.progress event with the url, filepath and downloaded size + this.emit('download.progress', { url: this.url, filepath: this.filepath, percentage: Math.floor((downloaded / contentLength) * 100) }); + stepLimit += step; + } + }); + response.pipe(file); file.on('finish', () => { @@ -66,10 +99,12 @@ class File extends EventEmitter { .on('error', (err) => { fs.unlink(filepath, () => { // Emit a download.error event with the error - this.emit('download.error', { url: this.url, filepath: this.filepath, error: err, type: 'request' }); + this.emit('download.error', { url: this.url, filepath: this.filepath, error: err.message, type: 'request' }); reject(err.message); }); }); }); } -} \ No newline at end of file +} + +module.exports = File; \ No newline at end of file