diff --git a/package.json b/package.json index 93f3159..bc0fed9 100644 --- a/package.json +++ b/package.json @@ -36,9 +36,16 @@ "commander": "^2.8.1", "debug": "^2.2.0", "faye": "^1.1.2", + "http-status": "^1.3.2", + "humanize-duration": "^3.21.0", "inquirer": "^0.11.1", "jsonfile": "^2.2.1", + "mkdirp": "^0.5.1", + "pretty-bytes": "^5.3.0", + "request": "^2.88.0", + "request-progress": "^3.0.0", "shelljs": "^0.7.0", + "single-line-log": "^1.1.2", "swagger-client": "^2.1.9" }, "devDependencies": { diff --git a/src/downloader.js b/src/downloader.js index e0d157d..74d58a6 100644 --- a/src/downloader.js +++ b/src/downloader.js @@ -5,21 +5,21 @@ */ // Dependencies -const { exec, spawn } = require('child_process'); +const fs = require('fs'), + request = require('request'), + progress = require('request-progress'), + mkdirp = require('mkdirp'), + path = require('path'), + logSingleLine = require('single-line-log').stdout, + debug = require('debug')('openframe:downloader'), + status = require('http-status'), + prettyBytes = require('pretty-bytes'), + humanizeDuration = require('humanize-duration'); -var debug = require('debug')('openframe:downloader'), - artworkDir = '/tmp'; - -// unused at present -function _mkdirp(dir) { - var mkdir = 'mkdir -p ' + dir; - exec(mkdir, function(err) { - if (err) { - throw err; - } - }); -} +const artworkDir = '/tmp'; +let artworkRequest, finished = false + /** * Download a file using HTTP get. * @@ -27,31 +27,65 @@ function _mkdirp(dir) { * @param {String} file_output_name */ function downloadFile(file_url, file_output_name) { - debug('downloading %s', file_url); - return new Promise(function(resolve, reject) { - var file_name = file_output_name, - file_path = artworkDir + '/' + file_name; - - const curl = spawn('curl', ['-L', '-o', file_path, file_url]); - - curl.stdout.on('data', (data) => { - debug(`stdout: ${data}`); - }); - - curl.stderr.on('data', (data) => { - debug(`stderr: ${data}`); - }); - - curl.on('close', (code) => { - debug(`child process exited with code ${code}`); - if (code !== 0) { - reject('Download failed'); - } else { - resolve(file_path); - } - }); + debug('downloading %s', file_url); + + return new Promise(function(resolve, reject) { + var file_name = file_output_name, + file_path = artworkDir + '/' + file_name; + + mkdirp(artworkDir, function (err) { + if (err) { + console.log('Couldn\'t create artwork directory.') + console.error(err) + } }); + // debug('finished',finished) + if (artworkRequest && !finished) artworkRequest.abort() + finished = false + artworkRequest = request({ + url: file_url, + headers: { + 'User-Agent': 'request' + } + }) + + progress(artworkRequest, { + throttle : 500 + }) + .on('response', function(response) { + // console.log(response.statusCode) + // console.log(response.headers['content-type']) + if (!(/^2/.test('' + response.statusCode))) { // Status Codes other than 2xx + console.log("The artwork is not available.") + console.log("Server responded with this status code:", response.statusCode, status[response.statusCode]); + reject() + } + }) + .on('error', function(err) { + console.log("Error downloading artwork") + console.error(err) + reject() + }) + .on('abort', function() { + debug("Aborted downloading artwork") + reject() + }) + .on('progress', function (state) { + if (debug.enabled) logSingleLine((state.percent*100).toFixed(2) + '% of ' + prettyBytes(state.size.total)+ ' – ' + humanizeDuration(state.time.remaining * 1000, { round: true }) + ' remaining – ' + (state.speed != null ? prettyBytes(state.speed) : '?') + '/s') + }) + .pipe(fs.createWriteStream(file_path).on("error", function(err) { + console.log("Error saving artwork") + console.log(err) + reject() + })) + .on('finish', function() { + debug('Artwork downloaded') + finished = true + + return resolve(file_path); + }); + }); } exports.downloadFile = downloadFile;