From 895e588c534785229366141ce0ef998cd8fbc207 Mon Sep 17 00:00:00 2001 From: Sachin Date: Tue, 2 Feb 2016 12:02:30 +0530 Subject: [PATCH 1/3] Added download by id and support to send upload stream in req.filedata --- lib/index.js | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++- package.json | 2 +- 2 files changed, 76 insertions(+), 2 deletions(-) diff --git a/lib/index.js b/lib/index.js index be1706e..f6b8639 100644 --- a/lib/index.js +++ b/lib/index.js @@ -131,7 +131,15 @@ MongoStorage = (function() { return callback(null, res); })["catch"](callback); }); - return req.pipe(busboy); + //return req.pipe(busboy); + + // There may be a requirement to read the req stream before calling this function. e.g. to do virus scanning in temporary location. + // The file stream can again be attached to req.filedata and passed to this function in that case. + if (req.filedata) { + return req.filedata.pipe(busboy); + }else { + return req.pipe(busboy); + } }; MongoStorage.prototype.uploadFile = function(container, file, options, callback) { @@ -208,6 +216,46 @@ MongoStorage = (function() { return read.pipe(res); }); }; + + MongoStorage.prototype.getFileById = function(container, fileId, callback) { + return this.db.collection('fs.files').findOne({ + 'metadata.mongo-storage': true, + 'metadata.container': container, + '_id': new ObjectID(fileId) + }, function(err, file) { + if (err) { + return callback(err); + } + if (!file) { + err = new Error('File not found'); + err.status = 404; + return callback(err); + } + return callback(null, file); + }); + }; + MongoStorage.prototype.downloadFileById = function(container, fileId, res, callback) { + console.log("inside custom method"); + var self; + if (callback == null) { + callback = (function() {}); + } + self = this; + return this.getFileById(container, fileId, function(err, file) { + var gfs, read; + if (err) { + return callback(err); + } + gfs = Grid(self.db, mongodb); + read = gfs.createReadStream({ + _id: file._id + }); + res.set('Content-Disposition', "attachment; filename=\"" + file.filename + "\""); + res.set('Content-Type', file.metadata.mimetype); + res.set('Content-Length', file.length); + return read.pipe(res); + }); + }; return MongoStorage; @@ -377,11 +425,37 @@ MongoStorage.prototype.download.accepts = [ } ]; + + MongoStorage.prototype.download.http = { verb: 'get', path: '/:container/download/:file' }; +//New API endpoint to download file by id +MongoStorage.prototype.downloadFileById.shared = true; + +MongoStorage.prototype.downloadFileById.accepts = [ + { + arg: 'container', + type: 'string' + }, { + arg: 'fileId', + type: 'string' + }, { + arg: 'res', + type: 'object', + http: { + source: 'res' + } + } +]; + +MongoStorage.prototype.downloadFileById.http = { + verb: 'get', + path: '/:container/downloadFile/:fileId' +}; + exports.initialize = function(dataSource, callback) { var connector, k, m, method, opt, ref, settings; settings = dataSource.settings || {}; diff --git a/package.json b/package.json index 2ea1146..2fc4b6b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "loopback-component-storage-mongo", - "version": "1.0.2", + "version": "1.0.3", "description": "", "main": "lib/index.js", "scripts": { From 772aefde62d54e13be6b64c586e053df8f0609e1 Mon Sep 17 00:00:00 2001 From: Sachin Date: Tue, 2 Feb 2016 23:05:03 +0530 Subject: [PATCH 2/3] Updated coffee scripts --- lib/index.js | 95 +++++++++++++++++++------------------------ source/index.coffee | 35 ++++++++++++++++ test/connector.coffee | 17 +++++++- 3 files changed, 93 insertions(+), 54 deletions(-) diff --git a/lib/index.js b/lib/index.js index f6b8639..65126ef 100644 --- a/lib/index.js +++ b/lib/index.js @@ -131,15 +131,7 @@ MongoStorage = (function() { return callback(null, res); })["catch"](callback); }); - //return req.pipe(busboy); - - // There may be a requirement to read the req stream before calling this function. e.g. to do virus scanning in temporary location. - // The file stream can again be attached to req.filedata and passed to this function in that case. - if (req.filedata) { - return req.filedata.pipe(busboy); - }else { - return req.pipe(busboy); - } + return req.pipe(busboy); }; MongoStorage.prototype.uploadFile = function(container, file, options, callback) { @@ -216,46 +208,46 @@ MongoStorage = (function() { return read.pipe(res); }); }; - + MongoStorage.prototype.getFileById = function(container, fileId, callback) { - return this.db.collection('fs.files').findOne({ - 'metadata.mongo-storage': true, - 'metadata.container': container, - '_id': new ObjectID(fileId) - }, function(err, file) { - if (err) { - return callback(err); - } - if (!file) { - err = new Error('File not found'); - err.status = 404; - return callback(err); - } - return callback(null, file); - }); - }; - MongoStorage.prototype.downloadFileById = function(container, fileId, res, callback) { - console.log("inside custom method"); - var self; - if (callback == null) { - callback = (function() {}); - } - self = this; - return this.getFileById(container, fileId, function(err, file) { - var gfs, read; - if (err) { - return callback(err); - } - gfs = Grid(self.db, mongodb); - read = gfs.createReadStream({ - _id: file._id - }); - res.set('Content-Disposition', "attachment; filename=\"" + file.filename + "\""); - res.set('Content-Type', file.metadata.mimetype); - res.set('Content-Length', file.length); - return read.pipe(res); - }); - }; + return this.db.collection('fs.files').findOne({ + 'metadata.mongo-storage': true, + 'metadata.container': container, + '_id': new ObjectID(fileId) + }, function(err, file) { + if (err) { + return callback(err); + } + if (!file) { + err = new Error('File not found'); + err.status = 404; + return callback(err); + } + return callback(null, file); + }); + }; + + MongoStorage.prototype.downloadById = function(container, fileId, res, callback) { + var self; + if (callback == null) { + callback = (function() {}); + } + self = this; + return this.getFileById(container, fileId, function(err, file) { + var gfs, read; + if (err) { + return callback(err); + } + gfs = Grid(self.db, mongodb); + read = gfs.createReadStream({ + _id: file._id + }); + res.set('Content-Disposition', "attachment; filename=\"" + file.filename + "\""); + res.set('Content-Type', file.metadata.mimetype); + res.set('Content-Length', file.length); + return read.pipe(res); + }); + }; return MongoStorage; @@ -425,14 +417,11 @@ MongoStorage.prototype.download.accepts = [ } ]; - - MongoStorage.prototype.download.http = { verb: 'get', path: '/:container/download/:file' }; -//New API endpoint to download file by id MongoStorage.prototype.downloadFileById.shared = true; MongoStorage.prototype.downloadFileById.accepts = [ @@ -440,7 +429,7 @@ MongoStorage.prototype.downloadFileById.accepts = [ arg: 'container', type: 'string' }, { - arg: 'fileId', + arg: 'id', type: 'string' }, { arg: 'res', @@ -453,7 +442,7 @@ MongoStorage.prototype.downloadFileById.accepts = [ MongoStorage.prototype.downloadFileById.http = { verb: 'get', - path: '/:container/downloadFile/:fileId' + path: '/:container/downloadById/:id' }; exports.initialize = function(dataSource, callback) { diff --git a/source/index.coffee b/source/index.coffee index cc8fb80..f853c65 100644 --- a/source/index.coffee +++ b/source/index.coffee @@ -147,6 +147,33 @@ class MongoStorage res.set 'Content-Length', file.length read.pipe res + + getFileById: (container, fileId, callback) -> + @db.collection 'fs.files' + .findOne + 'metadata.mongo-storage': true + 'metadata.container': container + '_id': new ObjectID(fileId) + , (err, file) -> + return callback err if err + if not file + err = new Error 'File not found' + err.status = 404 + return callback err + callback null, file + + downloadById: (container, fileId, res, callback = (-> return)) -> + self = @ + @getFileById container, fileId, (err, file) -> + return callback err if err + gfs = Grid self.db, mongodb + read = gfs.createReadStream + _id: file._id + res.set 'Content-Disposition', "attachment; filename=\"#{file.filename}\"" + res.set 'Content-Type', file.metadata.mimetype + res.set 'Content-Length', file.length + read.pipe res + MongoStorage.modelName = 'storage' MongoStorage.prototype.getContainers.shared = true @@ -204,6 +231,14 @@ MongoStorage.prototype.download.accepts = [ ] MongoStorage.prototype.download.http = {verb: 'get', path: '/:container/download/:file'} +MongoStorage.prototype.downloadFileById.shared = true +MongoStorage.prototype.downloadFileById.accepts = [ + {arg: 'container', type: 'string'} + {arg: 'id', type: 'string'} + {arg: 'res', type: 'object', http: {source: 'res'}} +] +MongoStorage.prototype.downloadFileById.http = {verb: 'get', path: '/:container/downloadById/:id'} + exports.initialize = (dataSource, callback) -> settings = dataSource.settings or {} connector = new MongoStorage settings diff --git a/test/connector.coffee b/test/connector.coffee index 838b7e7..f4509b5 100644 --- a/test/connector.coffee +++ b/test/connector.coffee @@ -11,6 +11,7 @@ request = require 'supertest' insertTestFile = (ds, done) -> options = + id: '123456789' filename: 'item.png' mode: 'w' metadata: @@ -51,7 +52,7 @@ describe 'mongo gridfs connector', -> it 'should create the url', -> expect(datasource.settings.url).to.exist - expect(datasource.settings.url).to.eql "mongodb://127.0.0.1:27017/test" + expect(datasource.settings.url).to.eql "mongodb://127.0.0.1:8017/test" it 'should be connected', -> expect(datasource.connected).to.eql true @@ -175,3 +176,17 @@ describe 'mongo gridfs connector', -> expect(res.status).to.equal 200 done() + describe 'downloadById', -> + + before (done) -> + ds.connector.db.collection('fs.files').remove {}, done + + before (done) -> + insertTestFile ds, done + + it 'should return the file', (done) -> + request 'http://127.0.0.1:5000' + .get '/my-model/my-cats/downloadById/1234567891' + .end (err, res) -> + expect(res.status).to.equal 200 + done() \ No newline at end of file From 2d76126c3070475f9793b946475c15de759e1289 Mon Sep 17 00:00:00 2001 From: Sachin Date: Tue, 2 Feb 2016 23:14:48 +0530 Subject: [PATCH 3/3] Corrected mongodb port. --- test/connector.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/connector.coffee b/test/connector.coffee index f4509b5..791d816 100644 --- a/test/connector.coffee +++ b/test/connector.coffee @@ -52,7 +52,7 @@ describe 'mongo gridfs connector', -> it 'should create the url', -> expect(datasource.settings.url).to.exist - expect(datasource.settings.url).to.eql "mongodb://127.0.0.1:8017/test" + expect(datasource.settings.url).to.eql "mongodb://127.0.0.1:27017/test" it 'should be connected', -> expect(datasource.connected).to.eql true