Implement downloadDir for flat-file format
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
exports = module.exports = {
|
||||
upload: upload,
|
||||
download: download,
|
||||
downloadDir: downloadDir,
|
||||
copy: copy,
|
||||
|
||||
remove: remove,
|
||||
@@ -21,6 +22,8 @@ var assert = require('assert'),
|
||||
AWS = require('aws-sdk'),
|
||||
BackupsError = require('../backups.js').BackupsError,
|
||||
debug = require('debug')('box:storage/s3'),
|
||||
fs = require('fs'),
|
||||
mkdirp = require('mkdirp'),
|
||||
PassThrough = require('stream').PassThrough,
|
||||
path = require('path'),
|
||||
S3BlockReadStream = require('s3-block-read-stream');
|
||||
@@ -123,6 +126,54 @@ function download(apiConfig, backupFilePath, callback) {
|
||||
});
|
||||
}
|
||||
|
||||
function downloadDir(apiConfig, backupFilePath, destDir, callback) {
|
||||
assert.strictEqual(typeof apiConfig, 'object');
|
||||
assert.strictEqual(typeof backupFilePath, 'string');
|
||||
assert.strictEqual(typeof destDir, 'string');
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
|
||||
getBackupCredentials(apiConfig, function (error, credentials) {
|
||||
if (error) return callback(error);
|
||||
|
||||
var s3 = new AWS.S3(credentials);
|
||||
var listParams = {
|
||||
Bucket: apiConfig.bucket,
|
||||
Prefix: backupFilePath
|
||||
};
|
||||
|
||||
async.forever(function listAndDownload(foreverCallback) {
|
||||
s3.listObjectsV2(listParams, function (error, listData) {
|
||||
if (error) {
|
||||
debug('remove: Failed to list %s. Not fatal.', error);
|
||||
return foreverCallback(error);
|
||||
}
|
||||
|
||||
async.eachLimit(listData.Contents, 10, function downloadFile(content, iteratorCallback) {
|
||||
var relativePath = path.relative(backupFilePath, content.Key);
|
||||
mkdirp(path.dirname(path.join(destDir, relativePath)), function (error) {
|
||||
if (error) return iteratorCallback(new BackupsError(BackupsError.EXTERNAL_ERROR, error.message));
|
||||
|
||||
var destStream = fs.createWriteStream(path.join(destDir, relativePath));
|
||||
destStream.on('error', function (error) {
|
||||
return iteratorCallback(new BackupsError(BackupsError.EXTERNAL_ERROR, error.message));
|
||||
});
|
||||
download(apiConfig, content.Key, destStream, iteratorCallback);
|
||||
});
|
||||
}, function doneCopying(error) {
|
||||
if (error) return foreverCallback(error);
|
||||
|
||||
if (listData.IsTruncated) return foreverCallback();
|
||||
|
||||
foreverCallback(new Error('Done'));
|
||||
});
|
||||
});
|
||||
}, function (error) {
|
||||
if (error.message === 'Done') return callback();
|
||||
callback(error);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function copy(apiConfig, oldFilePath, newFilePath, callback) {
|
||||
assert.strictEqual(typeof apiConfig, 'object');
|
||||
assert.strictEqual(typeof oldFilePath, 'string');
|
||||
@@ -188,7 +239,7 @@ function remove(apiConfig, pathPrefix, callback) {
|
||||
|
||||
listParams.Marker = listData.Contents[listData.Contents.length - 1].Key; // NextMarker is returned only with delimiter
|
||||
|
||||
if (deleteData.IsTruncated) return iteratorCallback();
|
||||
if (listData.IsTruncated) return iteratorCallback();
|
||||
|
||||
iteratorCallback(new Error('Done'));
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user