From 2aa46493fa99db48ccc08414c7e5c94a864787ca Mon Sep 17 00:00:00 2001 From: "David Humphrey (:humph) david.humphrey@senecacollege.ca" Date: Tue, 25 Mar 2014 11:47:08 -0400 Subject: [PATCH] Add sh.wget() for downloading files into the fs, with tests and docs --- README.md | 25 +++++++++++++ src/shell/shell.js | 40 +++++++++++++++++++++ tests/spec/shell/wget.spec.js | 66 +++++++++++++++++++++++++++++++++++ tests/test-file.txt | 1 + tests/test-manifest.js | 1 + 5 files changed, 133 insertions(+) create mode 100644 tests/spec/shell/wget.spec.js create mode 100644 tests/test-file.txt diff --git a/README.md b/README.md index 88f9aae..20027dd 100644 --- a/README.md +++ b/README.md @@ -1133,6 +1133,7 @@ var sh = fs.Shell(); * [sh.rm(path, [options], callback)](#rm) * [sh.tempDir(callback)](#tempDir) * [sh.mkdirp(path, callback)](#mkdirp) +* [sh.wget(path, [options], callback)](#wget) #### sh.cd(path, callback) @@ -1338,3 +1339,27 @@ sh.mkdirp('/test/mkdirp', function(err) { // the root '/' now contains a directory 'test' containing the directory 'mkdirp' }); ``` + +#### sh.wget(url, [options], callback) + +Downloads the file at `url` and saves it to the filesystem. +The file is saved to a file named with the current date/time +unless the `options.filename` is present, in which case that +filename is used instead. The callback receives `(error, path)`, +where `path` is the full path to the downloaded file. + +Example: + +```javascript +// Download the file at /files/file.json +sh.wget('/files/file.json', function(err, path) { + if(err) throw err; + // /file-134134513 is now saved to the fs +}); + +// Download the file at /files/file.json, specifying a filename +sh.wget('/files/file.json', {filename: 'file.json'}, function(err, path) { + if(err) throw err; + // /file.json is now saved to the fs +}); +``` diff --git a/src/shell/shell.js b/src/shell/shell.js index d82e074..e5d392a 100644 --- a/src/shell/shell.js +++ b/src/shell/shell.js @@ -421,6 +421,46 @@ define(function(require) { _mkdirp(path, callback); }; + /** + * Downloads the file at `url` and saves it to the filesystem. + * The file is saved to a file named with the current date/time + * unless the `options.filename` is present, in which case that + * filename is used instead. The callback receives (error, path). + */ + Shell.prototype.wget = function(url, options, callback) { + var fs = this.fs; + if(typeof options === 'function') { + callback = options; + options = {}; + } + options = options || {}; + callback = callback || function(){}; + + if(!url) { + callback(new Errors.EINVAL('missing url argument')); + return; + } + + var path = options.filename || ('file-' + Date.now()); + path = Path.resolve(fs.cwd, path); + + var request = new XMLHttpRequest(); + request.addEventListener("load", function() { + var data = new Uint8Array(request.response); + fs.writeFile(path, data, function(err) { + if(err) { + callback(err); + } else { + callback(null, path); + } + }); + }, false); + request.addEventListener("error", function(err) { callback(err); }, false); + request.open("GET", url); + request.responseType = "arraybuffer"; + request.send(); + }; + return Shell; }); diff --git a/tests/spec/shell/wget.spec.js b/tests/spec/shell/wget.spec.js new file mode 100644 index 0000000..3a4b587 --- /dev/null +++ b/tests/spec/shell/wget.spec.js @@ -0,0 +1,66 @@ +define(["Filer", "util"], function(Filer, util) { + + describe('FileSystemShell.wget', function() { + beforeEach(util.setup); + afterEach(util.cleanup); + + it('should be a function', function() { + var shell = util.shell(); + expect(shell.wget).to.be.a('function'); + }); + + it('should fail when url argument is absent', function(done) { + var fs = util.fs(); + var shell = fs.Shell(); + + shell.wget(null, function(err, data) { + expect(err).to.exist; + expect(data).not.to.exist; + done(); + }); + }); + + it('should download the contents of a file from a url to default filename', function(done) { + var fs = util.fs(); + var shell = fs.Shell(); + var url = "test-file.txt"; + var contents = "This is a test file used in some of the tests.\n"; + + shell.wget(url, function(err, path) { + if(err) throw err; + + // The filename should be something like /file-13424512341 + expect(path).to.match(/^\/file\-\d+$/); + + fs.readFile(path, 'utf8', function(err, data) { + if(err) throw err; + + expect(data).to.equal(contents); + done(); + }); + }); + }); + + it('should download the contents of a file from a url to specified filename', function(done) { + var fs = util.fs(); + var shell = fs.Shell(); + var url = "test-file.txt"; + var contents = "This is a test file used in some of the tests.\n"; + + shell.wget(url, { filename: 'test-file.txt' }, function(err, path) { + if(err) throw err; + + // The filename should be something like /file-13424512341 + expect(path).to.equal('/test-file.txt'); + + fs.readFile(path, 'utf8', function(err, data) { + if(err) throw err; + + expect(data).to.equal(contents); + done(); + }); + }); + }); + + }); +}); diff --git a/tests/test-file.txt b/tests/test-file.txt new file mode 100644 index 0000000..a5c0182 --- /dev/null +++ b/tests/test-file.txt @@ -0,0 +1 @@ +This is a test file used in some of the tests. diff --git a/tests/test-manifest.js b/tests/test-manifest.js index 1e5a908..aa63b50 100644 --- a/tests/test-manifest.js +++ b/tests/test-manifest.js @@ -57,6 +57,7 @@ define([ "spec/shell/rm.spec", "spec/shell/env.spec", "spec/shell/mkdirp.spec", + "spec/shell/wget.spec", // Ported node.js tests (filenames match names in https://github.com/joyent/node/tree/master/test) "spec/node-js/simple/test-fs-mkdir",