API Docs for: 0.8.0
Show:

File: include/service/media/mongo_media_provider.js

/*
    Copyright (C) 2016  PencilBlue, LLC

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
'use strict';

//dependencies
var MongoDB   = require('mongodb');
var GridStore = MongoDB.GridStore;
var util      = require('../../util.js');

module.exports = function MongoMediaProviderModule(pb) {

    /**
     * A media provider that uses Mongo's GridFS as the method of storage.
     * @class MongoMediaProvider
     * @constructor
     * @param {Object} context
     * @param {String} context.site
     */
    function MongoMediaProvider(/*context*/) {}

    /**
     * Retrieves the item in GridFS as a stream.
     * @method getStream
     * @param {String} mediaPath The path/key to the media.  Typically this is a
     * path such as: /media/2014/9/540a3ff0e30ddfb9e60000be-1409957872680.jpg
     * @param {Object} [options] Options for interacting with S3
     * @param {String} [options.bucket] The S3 bucket to interact with
     * @param {Function} cb A callback that provides two parameters: An Error, if
     * occurred and a ReadableStream that contains the media content.
     */
    MongoMediaProvider.prototype.getStream = function(mediaPath, cb) {

        pb.dbm.getDb(pb.config.db.name, function(err, db) {
            if (util.isError(err)) {
                return cb(err);
            }

            var gs  = new GridStore(db, mediaPath, 'r');
            gs.open(function(err, gs) {
                if (util.isError(err)) {
                    return cb(err);
                }

                cb(null, gs.stream(true));
            });
        });
    };

    /**
     * Retrieves the content from GridFS as a String or Buffer.
     * @method get
     * @param {String} mediaPath The path/key to the media.  Typically this is a
     * path such as: /media/2014/9/540a3ff0e30ddfb9e60000be-1409957872680.jpg
     * @param {Function} cb A callback that provides two parameters: An Error, if
     * occurred and an entity that contains the media content.
     */
    MongoMediaProvider.prototype.get = function(mediaPath, cb) {

        pb.dbm.getDb(pb.config.db.name, function(err, db) {
            if (util.isError(err)) {
                return cb(err);
            }

            var gs  = new GridStore(db, mediaPath, 'r');
            gs.open(function(err, gs) {
                if (util.isError(err)) {
                    return cb(err);
                }

                gs.read(function(err, data) {
                    if (util.isError(err)) {
                        return cb(err);
                    }

                    gs.close(function(err) {
                        cb(err, data);
                    });
                });
            });
        });
    };

    /**
     * Sets media content into GridFS based on the specified media path and
     * options.  The stream provided must be a ReadableStream.
     * @method setStream
     * @param {ReadableStream} stream The content stream
     * @param {String} mediaPath The path/key to the media.  Typically this is a
     * path such as: /media/2014/9/540a3ff0e30ddfb9e60000be-1409957872680.jpg
     * @param {Function} cb A callback that provides two parameters: An Error, if
     * occurred and the success of the operation.
     */
    MongoMediaProvider.prototype.setStream = function(stream, mediaPath, cb) {
        var self = this;

        var buffers = [];
        stream.on('data', function(buffer) {
            buffers.push(buffer);
        });
        stream.on('end', function() {

            var buffer = Buffer.concat(buffers);
            self.set(buffer, mediaPath, cb);
        });
        stream.on('error', function(err) {
            cb(err);
        });
    };

    /**
     * Sets media content into GridFS based on the specified media path and
     * options.  The data must be in the form of a String or Buffer.
     * @method setStream
     * @param {String|Buffer} fileDataStrOrBuffOrStream The content to persist
     * @param {String} mediaPath The path/key to the media.  Typically this is a
     * path such as: /media/2014/9/540a3ff0e30ddfb9e60000be-1409957872680.jpg
     * @param {Function} cb A callback that provides two parameters: An Error, if
     * occurred and the success of the operation.
     */
    MongoMediaProvider.prototype.set = function(fileDataStrOrBuff, mediaPath, cb) {

        var opt = {
            content_type: "application/octet-stream",
            metadata:{
                provider: "MongoMediaProvider",
                mediaPath: mediaPath
            }
        };

        pb.dbm.getDb(pb.config.db.name, function(err, db) {
            if (util.isError(err)) {
                return cb(err);
            }

            var gs  = new GridStore(db, mediaPath, 'w', opt);
            gs.open(function(err, gs) {
                gs.write(fileDataStrOrBuff, true, cb);
            });
        });
    };

    /**
     * Not Implemented
     * @method createWriteStream
     * @param {String} mediaPath The path/key to the media.  Typically this is a
     * path such as: /media/2014/9/540a3ff0e30ddfb9e60000be-1409957872680.jpg
     * @param {Function} cb A callback that provides two parameters: An Error, if
     * occurred and a WriteableStream.
     */
    MongoMediaProvider.prototype.createWriteStream = function(mediaPath, cb) {
        throw new Error('Not implemented');
    };

    /**
     * Checks to see if the file actually exists in GridFS
     * @method exists
     * @param {String} mediaPath The path/key to the media.  Typically this is a
     * path such as: /media/2014/9/540a3ff0e30ddfb9e60000be-1409957872680.jpg
     * @param {Function} cb A callback that provides two parameters: An Error, if
     * occurred and a Boolean.
     */
    MongoMediaProvider.prototype.exists = function(mediaPath, cb) {

        pb.dbm.getDb(pb.config.db.name, function(err, db) {
            if (util.isError(err)) {
                return cb(err);
            }

            GridStore.exist(db, mediaPath, cb);
        });
    };

    /**
     * Deletes a file from the GridFS
     * @method delete
     * @param {String} mediaPath The path/key to the media.  Typically this is a
     * path such as: /media/2014/9/540a3ff0e30ddfb9e60000be-1409957872680.jpg
     * @param {Function} cb A callback that provides two parameters: An Error, if
     * occurred and the success of the operation.
     */
    MongoMediaProvider.prototype.delete = function(mediaPath, cb) {

        pb.dbm.getDb(pb.config.db.name, function(err, db) {
            if (util.isError(err)) {
                return cb(err);
            }

            GridStore.unlink(db, mediaPath, cb);
        });
    };

    /**
     * Retrieve the stats on the file
     * @method stat
     * @param {String} mediaPath The path/key to the media.  Typically this is a
     * path such as: /media/2014/9/540a3ff0e30ddfb9e60000be-1409957872680.jpg
     * @param {Function} cb A callback that provides two parameters: An Error, if
     * occurred and an object that contains the file stats
     */
    MongoMediaProvider.prototype.stat = function(mediaPath, cb) {

        pb.dbm.getDb(pb.config.db.name, function(err, db) {
            if (util.isError(err)) {
                return cb(err);
            }

            var gs  = new GridStore(db, mediaPath, 'r');
            gs.open(function(err, gs) {
                if (util.isError(err)) {
                    return cb(err);
                }

                var stat = {
                    length: gs.length,
                    contentType: gs.contentType,
                    uploadDate: gs.uploadDate,
                    metadata: gs.metadata,
                    chunkSize: gs.chunkSize
                };
                gs.close(function(err) {
                    cb(err, stat);
                });
            });
        });
    };

    //exports
    return MongoMediaProvider;
};