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
Post a Comment