Skip to content

Commit 7e1dde8

Browse files
support resumableThreshold & using simple vs resumable
1 parent c4c6488 commit 7e1dde8

File tree

7 files changed

+712
-424
lines changed

7 files changed

+712
-424
lines changed

lib/storage/bucket.js

+73-41
Original file line numberDiff line numberDiff line change
@@ -228,13 +228,16 @@ Bucket.prototype.setMetadata = function(metadata, callback) {
228228
*
229229
* @param {string} localPath - The fully qualified path to the file you wish to
230230
* upload to your bucket.
231-
* @param {string=|module:storage/file=} destination - The place to save your
232-
* file. If given a string, the file will be uploaded to the bucket using
233-
* the string as a filename. When given a File object, your local file will
234-
* be uploaded to the File object's bucket and under the File object's name.
235-
* Lastly, when this argument is omitted, the file is uploaded to your
231+
* @param {object=} options - Configuration options.
232+
* @param {string=|module:storage/file=} options.destination - The place to save
233+
* your file. If given a string, the file will be uploaded to the bucket
234+
* using the string as a filename. When given a File object, your local file
235+
* will be uploaded to the File object's bucket and under the File object's
236+
* name. Lastly, when this argument is omitted, the file is uploaded to your
236237
* bucket using the name of the local file.
237-
* @param {object=} metadata - Metadata to set for your file.
238+
* @param {object=} options.metadata - Metadata to set for your file.
239+
* @param {boolean=} options.resumable - Whether to use a resumable upload or
240+
* simple upload.
238241
* @param {function} callback - The callback function.
239242
*
240243
* @example
@@ -251,8 +254,19 @@ Bucket.prototype.setMetadata = function(metadata, callback) {
251254
* //-
252255
* // It's not always that easy. You will likely want to specify the filename
253256
* // used when your new file lands in your bucket.
257+
* //
258+
* // You may also need to set metadata, or customize other options, like if you
259+
* // want the security of a resumable upload.
254260
* //-
255-
* bucket.upload('/local/path/image.png', 'new-image.png', function(err, file) {
261+
* var options = {
262+
* destination: 'new-image.png',
263+
* resumable: true,
264+
* metadata: {
265+
* event: 'Fall trip to the zoo'
266+
* }
267+
* };
268+
*
269+
* bucket.upload('/local/path/image.png', options, function(err, file) {
256270
* // Your bucket now contains:
257271
* // - "new-image.png" (with the contents of `/local/path/image.png')
258272
*
@@ -263,45 +277,37 @@ Bucket.prototype.setMetadata = function(metadata, callback) {
263277
* // You may also re-use a File object, {module:storage/file}, that references
264278
* // the file you wish to create or overwrite.
265279
* //-
266-
* var file = bucket.file('existing-file.png');
267-
* bucket.upload('/local/path/image.png', file, function(err, newFile) {
280+
* var options = {
281+
* destination: bucket.file('existing-file.png'),
282+
* resumable: false
283+
* };
284+
*
285+
* bucket.upload('/local/path/image.png', options, function(err, newFile) {
268286
* // Your bucket now contains:
269287
* // - "existing-file.png" (with the contents of `/local/path/image.png')
270288
*
271289
* // Note:
272290
* // The `newFile` parameter is equal to `file`.
273291
* });
274292
*/
275-
Bucket.prototype.upload = function(localPath, destination, metadata, callback) {
276-
var name;
277-
var newFile;
278-
switch (arguments.length) {
279-
case 4:
280-
break;
281-
case 3:
282-
callback = metadata;
283-
if (util.is(destination, 'object')) {
284-
metadata = destination;
285-
} else {
286-
metadata = {};
287-
}
288-
/* falls through */
289-
default:
290-
callback = callback || destination;
291-
name = path.basename(localPath);
292-
break;
293-
}
294-
metadata = metadata || {};
295-
callback = callback || util.noop;
296-
if (util.is(destination, 'string')) {
297-
name = destination;
293+
Bucket.prototype.upload = function(localPath, options, callback) {
294+
if (util.is(options, 'function')) {
295+
callback = options;
296+
options = {};
298297
}
299-
if (destination instanceof File) {
300-
name = destination.name;
301-
newFile = destination;
298+
299+
var newFile;
300+
if (options.destination instanceof File) {
301+
newFile = options.destination;
302+
} else if (util.is(options.destination, 'string')) {
303+
// Use the string as the name of the file.
304+
newFile = this.file(options.destination);
305+
} else {
306+
// Resort to using the name of the incoming file.
307+
newFile = this.file(path.basename(localPath));
302308
}
303-
newFile = newFile || this.file(name);
304309

310+
var metadata = options.metadata || {};
305311
var contentType = mime.lookup(localPath);
306312
if (contentType && !metadata.contentType) {
307313
metadata.contentType = contentType;
@@ -312,12 +318,38 @@ Bucket.prototype.upload = function(localPath, destination, metadata, callback) {
312318
metadata.contentType += '; charset=' + charset;
313319
}
314320

315-
fs.createReadStream(localPath)
316-
.pipe(newFile.createWriteStream(metadata))
317-
.on('error', callback)
318-
.on('complete', function() {
319-
callback(null, newFile);
321+
var resumable;
322+
if (util.is(options.resumable, 'boolean')) {
323+
resumable = options.resumable;
324+
upload();
325+
} else {
326+
// Determine if the upload should be resumable based on if it meets the
327+
// resumableThreshold.
328+
var resumableThreshold = this.storage.resumableThreshold;
329+
330+
fs.stat(localPath, function(err, fd) {
331+
if (err) {
332+
callback(err);
333+
return;
334+
}
335+
336+
resumable = fd.size > resumableThreshold;
337+
338+
upload();
320339
});
340+
}
341+
342+
function upload() {
343+
fs.createReadStream(localPath)
344+
.pipe(newFile.createWriteStream({
345+
resumable: resumable,
346+
metadata: metadata
347+
}))
348+
.on('error', callback)
349+
.on('complete', function() {
350+
callback(null, newFile);
351+
});
352+
}
321353
};
322354

323355
/**

0 commit comments

Comments
 (0)