diff --git a/lib/index.js b/lib/index.js index be1706e..65126ef 100644 --- a/lib/index.js +++ b/lib/index.js @@ -209,6 +209,46 @@ MongoStorage = (function() { }); }; + 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.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; })(); @@ -382,6 +422,29 @@ MongoStorage.prototype.download.http = { 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 = 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": { 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..791d816 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: @@ -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