javascript - Uploading files using Skipper with Sails.js v0.10 - how to retrieve new file name -


i upgrading sails.js version 0.10 , need use skipper manage file uploads.

when upload file generate new name using uuid, , save in public/files/ folder (this change when i've got working it's testing right now)

i save original name, , uploaded name + path mongo database.

this quite straightforward under sails v0.9.x using skipper can't figure out how read new file name , path. (obviously if read name construct path though it's name need)

my controller looks this

var uuid = require('node-uuid'),     path = require('path'),     blobadapter = require('skipper-disk');  module.exports = {    upload: function(req, res) {      var receiver = blobadapter().receive({           dirname: sails.config.apppath + "/public/files/",           saveas: function(file) {             var filename = file.filename,                 newname = uuid.v4() + path.extname(filename);             return newname;           }         }),         results = [];      req.file('docs').upload(receiver, function (err, files) {       if (err) return res.servererror(err);       async.foreach(files, function(file, next) {         document.create({           name: file.filename,           size: file.size,           localname: // ***** how `saveas()` value uploaded file *****,           path: // *** , likewise how path ******         }).exec(function(err, savedfile){           if (err) {             next(err);           } else {             results.push({               id: savedfile.id,               url: '/files/' + savedfile.localname             });             next();           }         });       }, function(err){         if (err) {           sails.log.error('caught error', err);           return res.servererror({error: err});         } else {           return res.json({ files: results });         }       });     });   },    _config: {}  }; 

how do this?

i've worked out , thought i'd share solution benefit of others struggling similar issues.

the solution not use skipper-disk @ write own custom receiver. i've created sails service object.

so in file api/services/uploader.js

// uploader utilities , helper methods // designed relatively generic.  var fs = require('fs'),     writable = require('stream').writable;  exports.documentreceiverstream = function(options) {   var defaults = {     dirname: '/dev/null',     saveas: function(file){       return file.filename;     },     completed: function(file, done){       done();     }   };    // don't have access jquery here simplest way   // think of merge options.   opts = defaults;   if (options.dirname) opts.dirname = options.dirname;   if (options.saveas) opts.saveas = options.saveas;   if (options.completed) opts.completed = options.completed;    var documentreceiver = writable({objectmode: true});    // `_write` method invoked each time new file received   // readable stream (upstream) pumping filestreams   // receiver.  (filename === `file.filename`).   documentreceiver._write = function onfile(file, encoding, done) {     var newfilename = opts.saveas(file),         filesavepath = opts.dirname + newfilename,         outputs = fs.createwritestream(filesavepath, encoding);     file.pipe(outputs);      // garbage-collect bytes written file.     // (called when read or write error occurs)     function gc(err) {       sails.log.debug("garbage collecting file '" + file.filename + "' located @ '" + filesavepath + "'");        fs.unlink(filesavepath, function (gcerr) {         if (gcerr) {           return done([err].concat([gcerr]));         } else {           return done(err);         }       });     };      file.on('error', function (err) {       sails.log.error('read error on file ' + file.filename, '::', err);     });      outputs.on('error', function failedtowritefile (err) {       sails.log.error('failed write file', file.filename, 'with encoding', encoding, ': done =', done);       gc(err);     });      outputs.on('finish', function successfullywrotefile () {       sails.log.debug("file uploaded")       opts.completed({         name: file.filename,         size: file.size,         localname: newfilename,         path: filesavepath       }, done);     });   };    return documentreceiver; } 

and controller became (in api/controllers/documentcontroller.js)

var uuid = require('node-uuid'),     path = require('path');  module.exports = {    upload: function(req, res) {      var results = [],         streamoptions = {           dirname: sails.config.apppath + "/public/files/",           saveas: function(file) {             var filename = file.filename,                 newname = uuid.v4() + path.extname(filename);             return newname;           },           completed: function(filedata, next) {             document.create(filedata).exec(function(err, savedfile){               if (err) {                 next(err);               } else {                 results.push({                   id: savedfile.id,                   url: '/files/' + savedfile.localname                 });                 next();               }             });           }         };      req.file('docs').upload(uploader.documentreceiverstream(streamoptions),       function (err, files) {         if (err) return res.servererror(err);          res.json({           message: files.length + ' file(s) uploaded successfully!',           files: results         });       }     );   },    _config: {} }; 

i'm sure can improved further works me.


Comments

Popular posts from this blog

commonjs - How to write a typescript definition file for a node module that exports a function? -

openid - Okta: Failed to get authorization code through API call -

ios - Change Storyboard View using Seague -