Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Multifile download

  • Loading branch information...
commit 74607d1eeab8d630fa2a286347c5e11de1a98090 1 parent cd97653
@indutny indutny authored
Showing with 95 additions and 8 deletions.
  1. +62 −7 lib/cloudfiles/core.js
  2. +33 −1 lib/cloudfiles/utils.js
View
69 lib/cloudfiles/core.js
@@ -148,15 +148,70 @@ Cloudfiles.prototype.destroyContainer = function (container, callback) {
});
};
-Cloudfiles.prototype.getFiles = function (container, callback) {
+Cloudfiles.prototype.getFiles = function (container, download, callback) {
var self = this;
+
+ // Download is optional argument
+ // And can be only: true, false, [array of files]
+
+ // Also download can be omitted: (...).getFiles(container, callback);
+ // In this case second argument will be a function
+ if (typeof download === 'function' && !(download instanceof RegExp)) {
+ callback = download;
+ download = false;
+ }
+
utils.rackspace(this.storageUrl(container, true), this, callback, function (body) {
- var results = [], files = JSON.parse(body);
- files.forEach(function (file) {
- file.container = container;
- results.push(new (cloudfiles.StorageObject)(self, file));
- });
- callback(null, results);
+ var files = JSON.parse(body);
+
+ // If download == false or wasn't defined
+ if (!download) {
+ var results = files.map(function (file) {
+ file.container = container;
+ return new (cloudfiles.StorageObject)(self, file);
+ });
+ callback(null, results);
+ return;
+ }
+
+ var batch;
+
+ if (download instanceof RegExp || download == true) {
+ // If download == true
+ // Download all files
+ if (download !== true) {
+ files = files.filter(function (file) {
+ return download.test(file);
+ });
+ }
+
+ // Create a batch
+ batch = files.map(function (file) {
+ return function(callback) {
+ self.getFile(container, file, callback);
+ }
+ });
+ } else if (Array.isArray(download)) {
+ // Go through all files that we've asked to download
+ batch = download.map(function(file) {
+ var exists = files.indexOf(file);
+
+ // If file exists - get it
+ // If not report about error
+ return exists ?
+ function (callback) {
+ self.getFile(container, file, callback);
+ } :
+ function (callback) {
+ callback(Error('File : ' + file + ' doesn\'t exists'));
+ };
+ });
+ } else {
+ callback(Error('"download" argument can be only boolean, array or regexp'));
+ }
+
+ // Run batch
+ utils.runBatch(batch, callback);
});
};
View
34 lib/cloudfiles/utils.js
@@ -199,4 +199,36 @@ utils.rackspaceCurl = function (options, callback, success) {
callback(ex);
}
});
-};
+};
+
+// Runs a array of functions with callback argument
+// And calls finish at the end of execution
+utils.runBatch = function(fns, finish) {
+ var finished = 0,
+ total = fns.length,
+ errors = [],
+ results = [];
+
+ fns.forEach(function(fn, i) {
+ var once = false;
+
+ function next(err, value) {
+ // Can be called only one time
+ if (once) return;
+ once = true;
+
+ // If have error - push them into errors
+ if (err) {
+ errors[i] = err;
+ } else {
+ results[i] = value;
+ }
+
+ if (++finished === total) finish(errors.length ? errors : null, results);
+ }
+
+ var value = fn(next);
+ // If function returns value - it won't be working in async mode
+ if (value !== undefined) next(null, value);
+ });
+};
Please sign in to comment.
Something went wrong with that request. Please try again.