Skip to content

Commit

Permalink
support resumableThreshold & using simple vs resumable
Browse files Browse the repository at this point in the history
  • Loading branch information
stephenplusplus committed Nov 20, 2014
1 parent c4c6488 commit 7e1dde8
Show file tree
Hide file tree
Showing 7 changed files with 712 additions and 424 deletions.
114 changes: 73 additions & 41 deletions lib/storage/bucket.js
Original file line number Diff line number Diff line change
Expand Up @@ -228,13 +228,16 @@ Bucket.prototype.setMetadata = function(metadata, callback) {
*
* @param {string} localPath - The fully qualified path to the file you wish to
* upload to your bucket.
* @param {string=|module:storage/file=} destination - The place to save your
* file. If given a string, the file will be uploaded to the bucket using
* the string as a filename. When given a File object, your local file will
* be uploaded to the File object's bucket and under the File object's name.
* Lastly, when this argument is omitted, the file is uploaded to your
* @param {object=} options - Configuration options.
* @param {string=|module:storage/file=} options.destination - The place to save
* your file. If given a string, the file will be uploaded to the bucket
* using the string as a filename. When given a File object, your local file
* will be uploaded to the File object's bucket and under the File object's
* name. Lastly, when this argument is omitted, the file is uploaded to your
* bucket using the name of the local file.
* @param {object=} metadata - Metadata to set for your file.
* @param {object=} options.metadata - Metadata to set for your file.
* @param {boolean=} options.resumable - Whether to use a resumable upload or
* simple upload.
* @param {function} callback - The callback function.
*
* @example
Expand All @@ -251,8 +254,19 @@ Bucket.prototype.setMetadata = function(metadata, callback) {
* //-
* // It's not always that easy. You will likely want to specify the filename
* // used when your new file lands in your bucket.
* //
* // You may also need to set metadata, or customize other options, like if you
* // want the security of a resumable upload.
* //-
* bucket.upload('/local/path/image.png', 'new-image.png', function(err, file) {
* var options = {
* destination: 'new-image.png',
* resumable: true,
* metadata: {
* event: 'Fall trip to the zoo'
* }
* };
*
* bucket.upload('/local/path/image.png', options, function(err, file) {
* // Your bucket now contains:
* // - "new-image.png" (with the contents of `/local/path/image.png')
*
Expand All @@ -263,45 +277,37 @@ Bucket.prototype.setMetadata = function(metadata, callback) {
* // You may also re-use a File object, {module:storage/file}, that references
* // the file you wish to create or overwrite.
* //-
* var file = bucket.file('existing-file.png');
* bucket.upload('/local/path/image.png', file, function(err, newFile) {
* var options = {
* destination: bucket.file('existing-file.png'),
* resumable: false
* };
*
* bucket.upload('/local/path/image.png', options, function(err, newFile) {
* // Your bucket now contains:
* // - "existing-file.png" (with the contents of `/local/path/image.png')
*
* // Note:
* // The `newFile` parameter is equal to `file`.
* });
*/
Bucket.prototype.upload = function(localPath, destination, metadata, callback) {
var name;
var newFile;
switch (arguments.length) {
case 4:
break;
case 3:
callback = metadata;
if (util.is(destination, 'object')) {
metadata = destination;
} else {
metadata = {};
}
/* falls through */
default:
callback = callback || destination;
name = path.basename(localPath);
break;
}
metadata = metadata || {};
callback = callback || util.noop;
if (util.is(destination, 'string')) {
name = destination;
Bucket.prototype.upload = function(localPath, options, callback) {
if (util.is(options, 'function')) {
callback = options;
options = {};
}
if (destination instanceof File) {
name = destination.name;
newFile = destination;

var newFile;
if (options.destination instanceof File) {
newFile = options.destination;
} else if (util.is(options.destination, 'string')) {
// Use the string as the name of the file.
newFile = this.file(options.destination);
} else {
// Resort to using the name of the incoming file.
newFile = this.file(path.basename(localPath));
}
newFile = newFile || this.file(name);

var metadata = options.metadata || {};
var contentType = mime.lookup(localPath);
if (contentType && !metadata.contentType) {
metadata.contentType = contentType;
Expand All @@ -312,12 +318,38 @@ Bucket.prototype.upload = function(localPath, destination, metadata, callback) {
metadata.contentType += '; charset=' + charset;
}

fs.createReadStream(localPath)
.pipe(newFile.createWriteStream(metadata))
.on('error', callback)
.on('complete', function() {
callback(null, newFile);
var resumable;
if (util.is(options.resumable, 'boolean')) {
resumable = options.resumable;
upload();
} else {
// Determine if the upload should be resumable based on if it meets the
// resumableThreshold.
var resumableThreshold = this.storage.resumableThreshold;

fs.stat(localPath, function(err, fd) {
if (err) {
callback(err);
return;
}

resumable = fd.size > resumableThreshold;

upload();
});
}

function upload() {
fs.createReadStream(localPath)
.pipe(newFile.createWriteStream({
resumable: resumable,
metadata: metadata
}))
.on('error', callback)
.on('complete', function() {
callback(null, newFile);
});
}
};

/**
Expand Down
Loading

0 comments on commit 7e1dde8

Please sign in to comment.