API Docs for: 0.9.0
Show:

File: lib/storageAdapter/fileStorageAdapter.js

// Copyright 2014, Yahoo! Inc.
// Copyrights licensed under the Mit License. See the accompanying LICENSE file for terms.

var path = require('path');
var fs = require('fs');

var Promise = require('promise');
var PNGImage = require('pngjs-image');

var StorageAdapter = require('./storageAdapter');


/**
 * File storage adapter
 *
 * @class FileStorageAdapter
 * @extends StorageAdapter
 * @constructor
 * @param {Object} options
 * @param {String} options.path
 * @param {String} options.approvedFolderName
 * @param {String} options.buildFolderName
 * @param {String} options.highlightFolderName
 *
 * @property {string} _path
 * @property {string} _approvedFolderName
 * @property {string} _buildFolderName
 * @property {string} _highlightFolderName
 */
var FileStorageAdapter = StorageAdapter.extend(

	/** @lends FileStorageAdapter.prototype */
	{
		/**
		 * Initializes the source-adapter
		 *
		 * @method initialize
		 */
		initialize: function () {
			this.__super();

			this._path = this._options.path;

			this._approvedFolderName = this._options.approvedFolderName || 'approved';
			this._buildFolderName = this._options.buildFolderName || 'build';
			this._highlightFolderName = this._options.highlightFolderName || 'highlight';

			this.setPromise(this.getPromise().then(function () {
				this._prepareFolder();
			}.bind(this)).then(null, function (err) {
				console.log(err.stack);
			}));
		},


		/**
		 * Prepares the output folder
		 *
		 * @method _prepareFolder
		 * @private
		 */
		_prepareFolder: function () {
			if (!fs.existsSync(this._getApprovedPath())) {
				fs.mkdirSync(this._getApprovedPath());
			}
			if (!fs.existsSync(this._getBuildPath())) {
				fs.mkdirSync(this._getBuildPath());
			}
			if (!fs.existsSync(this._getHighlightPath())) {
				fs.mkdirSync(this._getHighlightPath());
			}
		},

		/**
		 * Reads an image and returns a promise
		 *
		 * @method _readImage
		 * @param {string} path
		 * @return {Promise} With {PNGImage} Image
		 * @private
		 */
		_readImage: function (path) {

			return new Promise(function (resolve, reject) {
				var image = PNGImage.readImage(path, function (err) {
					if (err) {
						reject(err);
					} else {
						resolve(image);
					}
				});
			});
		},

		/**
		 * Writes an image and returns a promise
		 *
		 * @method _writeImage
		 * @param {string} path
		 * @param {PNGImage} image
		 * @return {Promise}
		 * @private
		 */
		_writeImage: function (path, image) {

			return new Promise(function (resolve, reject) {
				image.writeImage(path, function (err) {
					if (err) {
						reject(err);
					} else {
						resolve();
					}
				});
			});
		},

		/**
		 * Reads a directory an returns all files found in the folder
		 *
		 * @method _readDir
		 * @param {string} path
		 * @returns {string[]}
		 * @private
		 */
		_readDir: function (path) {
			return fs.readdirSync(path);
		},

		/**
		 * Reads a directory and filters for png files, removing the extensions
		 *
		 * @method _readDirAndFilter
		 * @param {string} path
		 * @returns {string[]}
		 * @private
		 */
		_readDirAndFilter: function (path) {
			var files = this._readDir(path);
			return files.filter(this._pngFilter).map(function (filename) {
				return filename.substr(0, filename.length - 4);
			});
		},

		/**
		 * List filter for png extensions
		 *
		 * @method _pngFilter
		 * @param {string} filename
		 * @return {boolean}
		 * @private
		 */
		_pngFilter: function (filename) {
			return (filename.substr(-4).toLowerCase() === '.png');
		},


		/**
		 * Gets the processing path
		 *
		 * @method _getPath
		 * @return {string}
		 * @private
		 */
		_getPath: function () {
			return this._path;
		},


		/**
		 * Gets the approved path
		 *
		 * @method _getApprovedPath
		 * @return {string}
		 * @private
		 */
		_getApprovedPath: function () {
			return path.join(this._getPath(), this._approvedFolderName);
		},

		/**
		 * Gets the build path
		 *
		 * @method _getBuildPath
		 * @return {string}
		 * @private
		 */
		_getBuildPath: function () {
			return path.join(this._getPath(), this._buildFolderName);
		},

		/**
		 * Gets the highlight path
		 *
		 * @method _getHighlightPath
		 * @return {string}
		 * @private
		 */
		_getHighlightPath: function () {
			return path.join(this._getPath(), this._highlightFolderName);
		},


		/**
		 * Gets a list of currently approve screen names
		 *
		 * @method getCurrentApprovedScreenNames
		 * @return {Promise} With {string[]} List of approved screen names
		 */
		getCurrentApprovedScreenNames: function () {
			return this.getPromise().then(function () {
				return this._readDirAndFilter(this._getApprovedPath());
			}.bind(this));
		},

		/**
		 * Gets a specific currently approved screen
		 *
		 * @method getCurrentApprovedScreen
		 * @param {string} name Name of approved screen
		 * @return {Promise} With {PNGImage} Approved screen
		 */
		getCurrentApprovedScreen: function (name) {
			return this.getPromise().then(function () {
				return this._readImage(path.join(this._getApprovedPath(), name + '.png'));
			}.bind(this));
		},

		/**
		 * Archives a specific currently approved screen
		 *
		 * @method archiveCurrentApprovedScreen
		 * @param {string} name Name of approved screen
		 * @param {PNGImage} image Screen to archive
		 * @return {Promise}
		 */
		archiveCurrentApprovedScreen: function (name, image) {
			// Do nothing
			return Promise.resolve();
		},


		/**
		 * Gets a list of approve screen names
		 *
		 * @method getApprovedScreenNames
		 * @return {Promise} With {string[]} List of approved screen names
		 */
		getApprovedScreenNames: function () {
			return this.getPromise().then(function () {
				return [];
			});
		},

		/**
		 * Gets a specific approved screen
		 *
		 * @method getApprovedScreen
		 * @param {string} name Name of approved screen
		 * @return {Promise} With {PNGImage} Approved screen
		 */
		getApprovedScreen: function (name) {
			return this.getPromise().then(function () {
				return undefined;
			});
		},

		/**
		 * Archives a specific approved screen
		 *
		 * @method archiveApprovedScreen
		 * @param {string} name Name of approved screen
		 * @param {PNGImage} image Screen to archive
		 * @return {Promise}
		 */
		archiveApprovedScreen: function (name, image) {
			// Do nothing
			return Promise.resolve();
		},


		/**
		 * Gets a list of build screen names
		 *
		 * @method getBuildScreenNames
		 * @return {string[]} List of build screen names
		 * @return {Promise} With {string[]} List of build screen names
		 */
		getBuildScreenNames: function () {
			return this.getPromise().then(function () {
				return this._readDirAndFilter(this._getBuildPath());
			}.bind(this));
		},

		/**
		 * Gets a specific build screen
		 *
		 * @method getBuildScreen
		 * @param {string} name Name of build screen
		 * @return {Promise} With {PNGImage}
		 */
		getBuildScreen: function (name) {
			return this.getPromise().then(function () {
				return this._readImage(path.join(this._getBuildPath(), name + '.png'));
			}.bind(this));
		},

		/**
		 * Archives a specific build screen
		 *
		 * @method archiveBuildScreen
		 * @param {string} name Name of build screen
		 * @param {PNGImage} image Screen to archive
		 * @return {Promise}
		 */
		archiveBuildScreen: function (name, image) {
			// Do nothing
			return Promise.resolve();
		},


		/**
		 * Gets a list of highlight screen names
		 *
		 * @method getHighlightScreenNames
		 * @return {string[]} List of highlight screen names
		 * @return {Promise} With {string[]} List of highlight screen names
		 */
		getHighlightScreenNames: function () {
			return this.getPromise().then(function () {
				return this._readDirAndFilter(this._getHighlightPath());
			}.bind(this));
		},

		/**
		 * Gets a specific highlight screen
		 *
		 * @method getHighlightScreen
		 * @param {string} name Name of highlight screen
		 * @return {Promise} With {PNGImage}
		 */
		getHighlightScreen: function (name) {
			return this.getPromise().then(function () {
				return this._readImage(path.join(this._getHighlightPath(), name + '.png'));
			}.bind(this));
		},

		/**
		 * Archives a specific highlight screen
		 *
		 * @method archiveHighlightScreen
		 * @param {string} name Name of highlight screen
		 * @param {PNGImage} image Screen to archive
		 * @return {Promise}
		 */
		archiveHighlightScreen: function (name, image) {
			return this.getPromise().then(function () {
				return this._writeImage(path.join(this._getHighlightPath(), name + '.png'), image);
			}.bind(this));
		}
	},

	{
		/**
		 * Type of class
		 *
		 * @property TYPE
		 * @type string
		 */
		TYPE: 'FileStorageAdapter'
	});

module.exports = FileStorageAdapter;