<commit_before>/**
 * icu-converter
 * https://github.com/alex-dow/icu-converter
 *
 * Copyright (c) 2015 Alex Dowgailenko
 * Licensed under the MIT License
 * https://github.com/alex-dow/icu-converter/blob/master/LICENSE
 */

'use strict';

var _ = require('lodash');
var path = require('path');
var mkdirp = require('mkdirp');
var fs = require('fs');

function processString(str) {
  str = str.replace(/\n/g, '\\\n');
  str = str.replace(/\r/g, '\\\r');
  return str;
}

function processArray(arr, key) {

  var newArr = [];

  arr.forEach(function(obj, idx) {
    var propObj = {};
    var propKey = key + '.' + idx;
    if (_.isString(obj)) {
      propObj[propKey] = processString(obj);
    } else {
      // FIXME Better solutiosn to handling complex types in arrays?
      propObj[propKey] = JSON.stringify(obj);
    }

    newArr.push(propObj);
  });

  return newArr;

}

function flatten(obj, parentKey, processedObject) {

  for (var property in obj) {
    if (obj.hasOwnProperty(property)) {
      if (_.isObject(obj[property]) && !_.isArray(obj[property]) && !_.isString(obj[property])) {
        flatten(obj[property], parentKey + '.' + property, processedObject);

      } else if (_.isString(obj[property])) {

        var propObj = {};
        propObj[parentKey + '.' + property] = processString(obj[property]);
        processedObject.push(propObj);

      } else if (_.isArray(obj[property])) {
        var arr = processArray(obj[property], parentKey + '.' + property);
        processedObject.push.apply(processedObject, arr);

      } else {
        console.log('unsupported data type, dude that blows. I don"t even know how we go there?');
      }
    }
  }
}

function processObject(obj) {

  var processedObject = [];

  for (var k in obj) {
    if (obj.hasOwnProperty(k)) {
      flatten(obj[k], k, processedObject);
    }
  }

  return processedObject;
}

var Writer = function(obj, inputFile, outputDir, argOptions) {

  var defaultOptions = {};

  var options = _.defaults({}, argOptions, defaultOptions);

  var inputFileName = path.basename(inputFile);
  var fileExtension = path.extname(inputFileName);

  var outputFileName = inputFileName.replace(fileExtension, '.properties');
  var outputFile = outputDir + '/' + outputFileName;

  mkdirp(outputDir);

  var properties = processObject(obj);

  var propertiesFile = "";
  properties.forEach(function(prop) {
    var key = _.keys(prop).pop();
    var value = prop[key];

    propertiesFile += key + "=" + value + "\n";
  });

  console.log("Writing to " + outputFile);
  fs.writeFileSync(outputFile, propertiesFile);

};

module.exports = Writer;
<commit_msg>Store options to object instance<commit_after>/**
 * icu-converter
 * https://github.com/alex-dow/icu-converter
 *
 * Copyright (c) 2015 Alex Dowgailenko
 * Licensed under the MIT License
 * https://github.com/alex-dow/icu-converter/blob/master/LICENSE
 */

'use strict';

var _ = require('lodash');
var path = require('path');
var mkdirp = require('mkdirp');
var fs = require('fs');

function processString(str) {
  str = str.replace(/\n/g, '\\\n');
  str = str.replace(/\r/g, '\\\r');
  return str;
}

function processArray(arr, key) {

  var newArr = [];

  arr.forEach(function(obj, idx) {
    var propObj = {};
    var propKey = key + '.' + idx;
    if (_.isString(obj)) {
      propObj[propKey] = processString(obj);
    } else {
      // FIXME Better solutiosn to handling complex types in arrays?
      propObj[propKey] = JSON.stringify(obj);
    }

    newArr.push(propObj);
  });

  return newArr;

}

function flatten(obj, parentKey, processedObject) {

  for (var property in obj) {
    if (obj.hasOwnProperty(property)) {
      if (_.isObject(obj[property]) && !_.isArray(obj[property]) && !_.isString(obj[property])) {
        flatten(obj[property], parentKey + '.' + property, processedObject);

      } else if (_.isString(obj[property])) {

        var propObj = {};
        propObj[parentKey + '.' + property] = processString(obj[property]);
        processedObject.push(propObj);

      } else if (_.isArray(obj[property])) {
        var arr = processArray(obj[property], parentKey + '.' + property);
        processedObject.push.apply(processedObject, arr);

      } else {
        console.log('unsupported data type, dude that blows. I don"t even know how we go there?');
      }
    }
  }
}

function processObject(obj) {

  var processedObject = [];

  for (var k in obj) {
    if (obj.hasOwnProperty(k)) {
      flatten(obj[k], k, processedObject);
    }
  }

  return processedObject;
}

var Writer = function(obj, inputFile, outputDir, argOptions) {

  var defaultOptions = {};

  this.options = _.defaults({}, argOptions, defaultOptions);

  var inputFileName = path.basename(inputFile);
  var fileExtension = path.extname(inputFileName);

  var outputFileName = inputFileName.replace(fileExtension, '.properties');
  var outputFile = outputDir + '/' + outputFileName;

  mkdirp(outputDir);

  var properties = processObject(obj);

  var propertiesFile = "";
  properties.forEach(function(prop) {
    var key = _.keys(prop).pop();
    var value = prop[key];

    propertiesFile += key + "=" + value + "\n";
  });

  console.log("Writing to " + outputFile);
  fs.writeFileSync(outputFile, propertiesFile);

};

module.exports = Writer;
<|endoftext|>


<commit_before>/**
 *	ES6 Promise polyfill
 *	See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
 */

var PromisePolyfill;

function isThenable(value) {
	return value && typeof value.then === 'function';
}

if ( typeof Promise !== 'undefined' ) {

	// If we have the real one then use it
	PromisePolyfill = Promise;
	console.warn('Promise polyfill is no longer required');

} else {

	PromisePolyfill = function(handler) {

		if ( typeof handler !== 'function'  ) {
			throw new TypeError('You must pass a resolver function as the first argument to the promise constructor');
		}

		Object.defineProperties( this, {

			_promiseResolveActions: {
				value: [],
				writable: false
			},

			_promiseRejectActions: {
				value: [],
				writable: false
			}

		} );

		var that = this;

		function resolve(value) {

			if ( that._promiseStatus === 'unresolved' ) {

				if ( isThenable(value) ) {
					that._promiseStatus = 'indeterminate';
					value.then(runResolutionActions,runRejectionActions);
				} else {
					runResolutionActions(value);
				}
			}

		}

		function runResolutionActions(value) {
			that._promiseStatus = 'has-resolution';
			that._promiseResult = value;
			process.nextTick( function() {
				for ( var i = 0, j = that._promiseResolveActions.length; i < j; ++i ) {
					that._promiseResolveActions[i](value);
				}
			} );
		}

		function reject(value) {
			if ( that._promiseStatus === 'unresolved' ) {
				runRejectionActions(value);
			}
		}

		function runRejectionActions(value) {
			that._promiseStatus = 'has-rejection';
			that._promiseResult = value;
			process.nextTick( function runRejected() {
				for ( var i = 0, j = that._promiseRejectActions.length; i < j; ++i ) {
					that._promiseRejectActions[i](value);
				}
			} );
		}

		try {
			handler( resolve, reject );
		} catch(e) {
			reject(e);
		}
	};

	PromisePolyfill.prototype.then = function( onFulfilled, onRejected ) {

		var resolveProxy, rejectProxy;
		var promise = new PromisePolyfill( function( resolve, reject ) {

			resolveProxy = function(value) {

				if ( typeof onFulfilled !== 'function' ) {
					resolve(value);
					return;
				}

				try {
					value = onFulfilled(value);
					//console.log(value);
				} catch(e) {
					reject(e);
					return;
				}

				//console.log( 'then value', value);

				if ( isThenable(value) ) {
					value.then(resolve,reject);
				} else {
					resolve(value);
				}

			};

			rejectProxy = function(value) {

				if ( typeof onRejected !== 'function' ) {
					reject(value);
					return;
				}

				try {
					value = onRejected(value);
				} catch(e) {
					reject(e);
					return;
				}

				if ( isThenable(value) ) {
					PromisePolyfill.resolve(value).then(resolve,reject);
				} else {
					resolve(value);
				}

			};

		} );

		if ( this._promiseStatus === 'has-resolution' ) {
			process.nextTick( resolveProxy.bind( null, this._promiseResult) );
		} else if ( this._promiseStatus !== 'has-rejection' ) {
			this._promiseResolveActions.push(resolveProxy);
		}

		if ( this._promiseStatus === 'has-rejection' ) {
			process.nextTick( rejectProxy.bind( null, this._promiseResult) );
		} else if (  this._promiseStatus !== 'has-resolution' ) {
			this._promiseRejectActions.push(rejectProxy);
		}

		return promise;

	};

	PromisePolyfill.prototype.catch = function(onRejected) {
		return this.then( undefined, onRejected );
	};

	Object.defineProperties( PromisePolyfill.prototype, {

		_promiseStatus: {
			value: 'unresolved',
			writable: true
		},

		_promiseResult: {
			writable: true
		}

	} );

	PromisePolyfill.resolve = function(value) {

		if ( value && value.constructor === PromisePolyfill ) {
			return value;
		}

		if ( isThenable(value) ) {
			return new PromisePolyfill( function(resolve,reject) {
				value.then(resolve,reject);
			} );
		}

		return new PromisePolyfill( function(resolve) {
			resolve(value);
		} );

	};

	PromisePolyfill.reject = function(reason) {

		return new PromisePolyfill( function(resolve,reject) {
			reject(reason);
		} );

	};

	PromisePolyfill.all = function(iterable) {
		if ( !arguments.length ) {
			throw new TypeError('Not enough arguments to Promise.all.');
		}

		if ( !iterable || typeof iterable !== 'object' ) {
			throw new TypeError("Argument 1 of Promise.all can't be converted to a sequence.");
		}

		var resolveProxy, rejectProxy;
		var resolvedCountdown = iterable.length || 0;
		var results = [];
		var done = Array(resolvedCountdown);
		promise = new PromisePolyfill( function( resolve, reject ) {
			resolveProxy = function( index, value ) {

				if ( index >= 0 && !done[index] ) {
					done[index] = true;
					results[index] = value;
					--resolvedCountdown;
				}

				if ( resolvedCountdown === 0 ) {
					resolve(results);
				}

			};
			rejectProxy = function(value) {
				reject(value);
			};
		} );

		if ( resolvedCountdown === 0 ) {
			resolveProxy();
		}

		for ( var i = 0, j = iterable.length || 0; i<j; ++i ) {
			PromisePolyfill.resolve( iterable[i] ).then(
				resolveProxy.bind( null, i ),
				rejectProxy
			);
		}

		return promise;

	};

	PromisePolyfill.race = function(iterable) {
		if ( !arguments.length ) {
			throw new TypeError('Not enough arguments to Promise.race.');
		}

		if ( !iterable || typeof iterable !== 'object' ) {
			throw new TypeError("Argument 1 of Promise.race can't be converted to a sequence.");
		}

		var resolveProxy, rejectProxy;
		var promise = new PromisePolyfill( function( resolve, reject ) {
			resolveProxy = function(value) {
				resolve(value);
			};
			rejectProxy = function(value) {
				reject(value);
			};
		} );

		for ( var i = 0, j = iterable.length || 0; i<j; ++i ) {
			PromisePolyfill.resolve( iterable[i] ).then(
				resolveProxy,
				rejectProxy
			);
		}

		return promise;
	};

}

module.exports = PromisePolyfill;<commit_msg>Tidied<commit_after>/**
 *	ES6 Promise polyfill
 *	See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
 */

var PromisePolyfill;

function isThenable(value) {
	return value && typeof value.then === 'function';
}

if ( typeof Promise !== 'undefined' ) {

	// If we have the real one then use it	- although it would be best to check before require
	PromisePolyfill = Promise;
	console.warn('Promise polyfill is no longer required');

} else {

	PromisePolyfill = function(handler) {

		if ( typeof handler !== 'function'  ) {
			throw new TypeError('You must pass a resolver function as the first argument to the promise constructor');
		}

		Object.defineProperties( this, {

			_promiseResolveActions: {
				value: [],
				writable: false
			},

			_promiseRejectActions: {
				value: [],
				writable: false
			}

		} );

		var that = this;

		function resolve(value) {

			if ( that._promiseStatus === 'unresolved' ) {

				if ( isThenable(value) ) {
					that._promiseStatus = 'indeterminate';
					value.then(runResolutionActions,runRejectionActions);
				} else {
					runResolutionActions(value);
				}
			}

		}

		function runResolutionActions(value) {
			that._promiseStatus = 'has-resolution';
			that._promiseResult = value;
			process.nextTick( function() {
				for ( var i = 0, j = that._promiseResolveActions.length; i < j; ++i ) {
					that._promiseResolveActions[i](value);
				}
			} );
		}

		function reject(value) {
			if ( that._promiseStatus === 'unresolved' ) {
				runRejectionActions(value);
			}
		}

		function runRejectionActions(value) {
			that._promiseStatus = 'has-rejection';
			that._promiseResult = value;
			process.nextTick( function runRejected() {
				for ( var i = 0, j = that._promiseRejectActions.length; i < j; ++i ) {
					that._promiseRejectActions[i](value);
				}
			} );
		}

		try {
			handler( resolve, reject );
		} catch(e) {
			reject(e);
		}
	};

	PromisePolyfill.prototype.then = function( onFulfilled, onRejected ) {

		var resolveProxy, rejectProxy;
		var promise = new PromisePolyfill( function( resolve, reject ) {

			resolveProxy = function(value) {

				if ( typeof onFulfilled !== 'function' ) {
					resolve(value);
					return;
				}

				try {
					value = onFulfilled(value);
				} catch(e) {
					reject(e);
					return;
				}

				if ( isThenable(value) ) {
					value.then(resolve,reject);
				} else {
					resolve(value);
				}

			};

			rejectProxy = function(value) {

				if ( typeof onRejected !== 'function' ) {
					reject(value);
					return;
				}

				try {
					value = onRejected(value);
				} catch(e) {
					reject(e);
					return;
				}

				if ( isThenable(value) ) {
					PromisePolyfill.resolve(value).then(resolve,reject);
				} else {
					resolve(value);
				}

			};

		} );

		if ( this._promiseStatus === 'has-resolution' ) {
			process.nextTick( resolveProxy.bind( null, this._promiseResult) );
		} else if ( this._promiseStatus !== 'has-rejection' ) {
			this._promiseResolveActions.push(resolveProxy);
		}

		if ( this._promiseStatus === 'has-rejection' ) {
			process.nextTick( rejectProxy.bind( null, this._promiseResult) );
		} else if (  this._promiseStatus !== 'has-resolution' ) {
			this._promiseRejectActions.push(rejectProxy);
		}

		return promise;

	};

	PromisePolyfill.prototype.catch = function(onRejected) {
		return this.then( undefined, onRejected );
	};

	Object.defineProperties( PromisePolyfill.prototype, {

		/**
		 *	unresolved - not yet resolved
		 *	indeterminate - following a thenable.  Still accepting handlers, but not a new resolution
		 *	has-resolution
		 *	has-rejection
		 */
		_promiseStatus: {
			value: 'unresolved',
			writable: true
		},

		_promiseResult: {
			writable: true
		}

	} );

	PromisePolyfill.resolve = function(value) {

		if ( value && value.constructor === PromisePolyfill ) {
			return value;
		}

		if ( isThenable(value) ) {
			return new PromisePolyfill( function(resolve,reject) {
				value.then(resolve,reject);
			} );
		}

		return new PromisePolyfill( function(resolve) {
			resolve(value);
		} );

	};

	PromisePolyfill.reject = function(reason) {

		return new PromisePolyfill( function(resolve,reject) {
			reject(reason);
		} );

	};

	PromisePolyfill.all = function(iterable) {
		if ( !arguments.length ) {
			throw new TypeError('Not enough arguments to Promise.all.');
		}

		// It's not clear what the definition of a sequence is.  Anything that is an object seems to be acceptable.
		if ( !iterable || typeof iterable !== 'object' ) {
			throw new TypeError("Argument 1 of Promise.all can't be converted to a sequence.");
		}

		var resolveProxy, rejectProxy;
		var resolvedCountdown = iterable.length || 0;
		var results = [];
		var done = Array(resolvedCountdown);
		promise = new PromisePolyfill( function( resolve, reject ) {
			resolveProxy = function( index, value ) {

				if ( index >= 0 && !done[index] ) {
					done[index] = true;
					results[index] = value;
					--resolvedCountdown;
				}

				if ( resolvedCountdown === 0 ) {
					resolve(results);
				}

			};
			rejectProxy = function(value) {
				reject(value);
			};
		} );

		if ( resolvedCountdown === 0 ) {
			resolveProxy();
		}

		// It is has a length property iterate
		for ( var i = 0, j = iterable.length || 0; i<j; ++i ) {
			PromisePolyfill.resolve( iterable[i] ).then(
				resolveProxy.bind( null, i ),
				rejectProxy
			);
		}

		return promise;

	};

	PromisePolyfill.race = function(iterable) {
		if ( !arguments.length ) {
			throw new TypeError('Not enough arguments to Promise.race.');
		}

		if ( !iterable || typeof iterable !== 'object' ) {
			throw new TypeError("Argument 1 of Promise.race can't be converted to a sequence.");
		}

		var resolveProxy, rejectProxy;
		var promise = new PromisePolyfill( function( resolve, reject ) {
			resolveProxy = function(value) {
				resolve(value);
			};
			rejectProxy = function(value) {
				reject(value);
			};
		} );

		for ( var i = 0, j = iterable.length || 0; i<j; ++i ) {
			PromisePolyfill.resolve( iterable[i] ).then(
				resolveProxy,
				rejectProxy
			);
		}

		return promise;
	};

}

module.exports = PromisePolyfill;<|endoftext|>


<commit_before>// Set up dependencies
const express = require('express');
const favicon = require('serve-favicon');
const moment = require('moment');
moment().format();

// App configuration
const path = require('path');
const dir = path.resolve(__dirname, '..');
let app = express();
app.set('view engine', 'pug');
app.use(favicon(dir + '/public/favicon.ico'));
app.use('/public', express.static(dir + '/public/'));
app.use('/semantic', express.static(dir + '/node_modules/semantic-ui-css/'));
app.use('/jquery', express.static(dir + '/node_modules/jquery/dist/'));
app.use('/moment', express.static(dir + '/node_modules/moment/min/'));
app.use('/assets', express.static(dir + '/assets/'));
app.use(function(req, res, next) {
    let pathStr = req.path;
    if (req.path.length != 1 && req.path.substr(-1) == '/') {
        pathStr = req.path.substring(0, req.path.length - 1);
    }
    res.locals = { path: pathStr };
    next();
});

// App locals
app.locals.title = 'Upsilon Pi Epsilon';
app.locals.moment = moment;
app.locals.path = path;
app.locals.properCase = (str) => str.charAt(0).toUpperCase() + str.substring(1);

// Define navigation
app.locals.navigation = [{
    title: 'Home',
    url: '/'
}, {
    title: 'About',
    url: '/about'
}, {
    title: 'News',
    url: '/news'
}, {
    title: 'Tutoring',
    url: '/tutoring'
}, {
    title: 'Photos',
    url: '/photos'
}, {
    title: 'Contact Us',
    url: '/contact'
}];

// Define EBoard members
app.locals.eboard = [{
    position: 'President',
    name: 'Aiden Cullo'
}, {
     position: 'Vice President',
     name: 'Zachary Halpern'
}, {
     position: 'Secretary',
     name: 'Melanie Chen'
}, {
     position: 'Treasurer',
     name: 'Julie Kunnumpurath'
}, {
     position: 'Tutoring Coordinator',
     name: 'Johnathon Van Atta'
}, {
     position: 'Webmaster',
     name: 'Juliana Algava'
}, {
     position: 'Events Coordinator',
     name: 'Josiah Bailey'
}];

// Routes
require(dir + '/routes/general')(app);

// Resolve to error page if route not found
app.use(function(req, res) {
    res.render('error', {
        error: true
    });
});

if (process.env.COMPILE) {
    const async = require('async');
    const fs = require('fs-extra');
    const pug = require('pug');

    for (let i = 0; i < app.locals.navigation.length; i++) {
        if (app.locals.navigation[i].url === '/') {
            app.locals.navigation[i].url = 'index.html';
        } else {
            app.locals.navigation[i].url += '.html';
            app.locals.navigation[i].url = app.locals.navigation[i].url
                .substr(1);
        }
    }

    let tasks = [];

    let createDir = function(dir) {
        return function(callback) {
            fs.ensureDir(dir, callback);
        };
    };

    let writeFile = function(src, dst) {
        return function(callback) {
            let html = pug.renderFile(src, app.locals);
            html = html.replace(/href="\/(\w+)"/, 'href="$1.html"');
            fs.writeFile(dst, html, function(err) {
                if(err) {
                    console.log(err);
                    return callback(err);
                }

                console.log('✔ Saved to ' + dst);
                return callback(null, true);
            });
        }
    };

    let copy = function(src, dst) {
        return function(callback) {
            fs.copy(src, dst, function(err) {
                if (err) return callback(err);
                console.log('✔ Copied ' + src + ' to ' + dst);
                callback(null, true);
            });
        };
    };

    let getPhotos = function(folder) {
        return function(callback) {
            fs.readdir('static/assets/img/photos/' + folder,
                function(error, data) {
                    if (error) return callback(error);

                    let photos = [];
                    for (var i = 0; i < data.length; i++) {
                        if (path.extname(data[i]) === '.jpg') {
                            photos.push(data[i]);
                        }
                    }
                    app.locals[folder] = photos;
                    return callback(null, photos);
            });
        }
    };

    tasks.push(createDir('static'));
    tasks.push(createDir('static/jquery'));
    tasks.push(createDir('static/moment'));
    tasks.push(createDir('static/semantic'));

    tasks.push(copy('assets', 'static/assets'));
    tasks.push(copy('node_modules/jquery/dist/jquery.min.js',
        'static/jquery/jquery.min.js'));
    tasks.push(copy('node_modules/moment/min/moment.min.js',
        'static/moment/moment.min.js'));
    tasks.push(copy('node_modules/semantic-ui-css/semantic.min.css',
        'static/semantic/semantic.min.css'));
    tasks.push(copy('node_modules/semantic-ui-css/semantic.min.js',
        'static/semantic/semantic.min.js'));
    tasks.push(copy('node_modules/semantic-ui-css/themes',
        'static/semantic/themes'));
    tasks.push(copy('public/', 'static/public'));

    tasks.push(getPhotos('spring17'));
    tasks.push(getPhotos('spring16'));
    tasks.push(writeFile('views/photos.pug', 'static/photos.html'));

    tasks.push(writeFile('views/index.pug', 'static/index.html'));
    tasks.push(writeFile('views/about.pug', 'static/about.html'));
    tasks.push(writeFile('views/news.pug', 'static/news.html'));
    tasks.push(writeFile('views/tutoring.pug', 'static/tutoring.html'));
    tasks.push(writeFile('views/contact.pug', 'static/contact.html'));

    async.series(tasks, function(err, results) {
        if (err) {
            console.log('\nError generating static site');
            process.exit(1);
        }

        console.log('\nGenerated static site successfully');
        process.exit(0);
    });
} else {
    const port = process.env.PORT || 3000;
    app.listen(port, function() {
        console.log(`Running on localhost:${port}`);
    });
}
<commit_msg>Rename site<commit_after>// Set up dependencies
const express = require('express');
const favicon = require('serve-favicon');
const moment = require('moment');
moment().format();

// App configuration
const path = require('path');
const dir = path.resolve(__dirname, '..');
let app = express();
app.set('view engine', 'pug');
app.use(favicon(dir + '/public/favicon.ico'));
app.use('/public', express.static(dir + '/public/'));
app.use('/semantic', express.static(dir + '/node_modules/semantic-ui-css/'));
app.use('/jquery', express.static(dir + '/node_modules/jquery/dist/'));
app.use('/moment', express.static(dir + '/node_modules/moment/min/'));
app.use('/assets', express.static(dir + '/assets/'));
app.use(function(req, res, next) {
    let pathStr = req.path;
    if (req.path.length != 1 && req.path.substr(-1) == '/') {
        pathStr = req.path.substring(0, req.path.length - 1);
    }
    res.locals = { path: pathStr };
    next();
});

// App locals
app.locals.title = 'UPE Iota Chapter';
app.locals.moment = moment;
app.locals.path = path;
app.locals.properCase = (str) => str.charAt(0).toUpperCase() + str.substring(1);

// Define navigation
app.locals.navigation = [{
    title: 'Home',
    url: '/'
}, {
    title: 'About',
    url: '/about'
}, {
    title: 'News',
    url: '/news'
}, {
    title: 'Tutoring',
    url: '/tutoring'
}, {
    title: 'Photos',
    url: '/photos'
}, {
    title: 'Contact Us',
    url: '/contact'
}];

// Define EBoard members
app.locals.eboard = [{
    position: 'President',
    name: 'Aiden Cullo'
}, {
     position: 'Vice President',
     name: 'Zachary Halpern'
}, {
     position: 'Secretary',
     name: 'Melanie Chen'
}, {
     position: 'Treasurer',
     name: 'Julie Kunnumpurath'
}, {
     position: 'Tutoring Coordinator',
     name: 'Johnathon Van Atta'
}, {
     position: 'Webmaster',
     name: 'Juliana Algava'
}, {
     position: 'Events Coordinator',
     name: 'Josiah Bailey'
}];

// Routes
require(dir + '/routes/general')(app);

// Resolve to error page if route not found
app.use(function(req, res) {
    res.render('error', {
        error: true
    });
});

if (process.env.COMPILE) {
    const async = require('async');
    const fs = require('fs-extra');
    const pug = require('pug');

    for (let i = 0; i < app.locals.navigation.length; i++) {
        if (app.locals.navigation[i].url === '/') {
            app.locals.navigation[i].url = 'index.html';
        } else {
            app.locals.navigation[i].url += '.html';
            app.locals.navigation[i].url = app.locals.navigation[i].url
                .substr(1);
        }
    }

    let tasks = [];

    let createDir = function(dir) {
        return function(callback) {
            fs.ensureDir(dir, callback);
        };
    };

    let writeFile = function(src, dst) {
        return function(callback) {
            let html = pug.renderFile(src, app.locals);
            html = html.replace(/href="\/(\w+)"/, 'href="$1.html"');
            fs.writeFile(dst, html, function(err) {
                if(err) {
                    console.log(err);
                    return callback(err);
                }

                console.log('✔ Saved to ' + dst);
                return callback(null, true);
            });
        }
    };

    let copy = function(src, dst) {
        return function(callback) {
            fs.copy(src, dst, function(err) {
                if (err) return callback(err);
                console.log('✔ Copied ' + src + ' to ' + dst);
                callback(null, true);
            });
        };
    };

    let getPhotos = function(folder) {
        return function(callback) {
            fs.readdir('static/assets/img/photos/' + folder,
                function(error, data) {
                    if (error) return callback(error);

                    let photos = [];
                    for (var i = 0; i < data.length; i++) {
                        if (path.extname(data[i]) === '.jpg') {
                            photos.push(data[i]);
                        }
                    }
                    app.locals[folder] = photos;
                    return callback(null, photos);
            });
        }
    };

    tasks.push(createDir('static'));
    tasks.push(createDir('static/jquery'));
    tasks.push(createDir('static/moment'));
    tasks.push(createDir('static/semantic'));

    tasks.push(copy('assets', 'static/assets'));
    tasks.push(copy('node_modules/jquery/dist/jquery.min.js',
        'static/jquery/jquery.min.js'));
    tasks.push(copy('node_modules/moment/min/moment.min.js',
        'static/moment/moment.min.js'));
    tasks.push(copy('node_modules/semantic-ui-css/semantic.min.css',
        'static/semantic/semantic.min.css'));
    tasks.push(copy('node_modules/semantic-ui-css/semantic.min.js',
        'static/semantic/semantic.min.js'));
    tasks.push(copy('node_modules/semantic-ui-css/themes',
        'static/semantic/themes'));
    tasks.push(copy('public/', 'static/public'));

    tasks.push(getPhotos('spring17'));
    tasks.push(getPhotos('spring16'));
    tasks.push(writeFile('views/photos.pug', 'static/photos.html'));

    tasks.push(writeFile('views/index.pug', 'static/index.html'));
    tasks.push(writeFile('views/about.pug', 'static/about.html'));
    tasks.push(writeFile('views/news.pug', 'static/news.html'));
    tasks.push(writeFile('views/tutoring.pug', 'static/tutoring.html'));
    tasks.push(writeFile('views/contact.pug', 'static/contact.html'));

    async.series(tasks, function(err, results) {
        if (err) {
            console.log('\nError generating static site');
            process.exit(1);
        }

        console.log('\nGenerated static site successfully');
        process.exit(0);
    });
} else {
    const port = process.env.PORT || 3000;
    app.listen(port, function() {
        console.log(`Running on localhost:${port}`);
    });
}
<|endoftext|>


<commit_before>var EOL = require('os').EOL;

module.exports = {
  name: 'ember-cli-mocha',

  normalizeEntityName: function() {
    // this prevents an error when the entityName is
    // not specified (since that doesn't actually matter
    // to us
  },

  afterInstall: function() {
    var addonContext = this;

    return this.addBowerPackagesToProject([
      { name: 'mocha',                 source: 'mocha',                 target: '~2.2.4' },
      { name: 'chai',                  source: 'chai',                  target: '~2.3.0' },
      { name: 'ember-mocha-adapter',   source: 'ember-mocha-adapter',   target: '~0.3.1' },
      { name: 'ember-cli-test-loader', source: 'ember-cli-test-loader', target: '0.2.2'  }
    ]).then(function() {
      if ('removePackageFromProject' in addonContext) {
        return addonContext.removePackagesFromProject([
          { name: 'ember-cli-qunit' },
          { name: 'ember-qunit-notifications' }
        ]);
      }
    });
  }
};
<commit_msg>Revert "Merge pull request #97 from ballPointPenguin/test-loader"<commit_after>var EOL = require('os').EOL;

module.exports = {
  name: 'ember-cli-mocha',

  normalizeEntityName: function() {
    // this prevents an error when the entityName is
    // not specified (since that doesn't actually matter
    // to us
  },

  afterInstall: function() {
    var addonContext = this;

    return this.addBowerPackagesToProject([
      { name: 'mocha',                 source: 'mocha',                 target: '~2.2.4' },
      { name: 'chai',                  source: 'chai',                  target: '~2.3.0' },
      { name: 'ember-mocha-adapter',   source: 'ember-mocha-adapter',   target: '~0.3.1' },
      { name: 'ember-cli-test-loader', source: 'ember-cli-test-loader', target: '0.2.2'  }
    ]).then(function() {
      if ('removePackageFromProject' in addonContext) {
        return addonContext.removePackageFromProject('ember-cli-qunit');
      }
    });
  }
};
<|endoftext|>


<commit_before>'use strict';

/*!
 * Module dependencies.
 */

var slice = function (arr, start, end) { return Array.prototype.slice.call(arr, start, end) };
var EventEmitter = require('events').EventEmitter;

/**
 * compat with node 0.10
 */

var next = process.nextTick;

/**
 * Promise constructor.
 *
 * _NOTE: The success and failure event names can be overridden by setting `Promise.SUCCESS` and `Promise.FAILURE` respectively._
 *
 * @param {Function} back a function that accepts `fn(err, ...){}` as signature
 * @inherits NodeJS EventEmitter http://nodejs.org/api/events.html#events_class_events_eventemitter
 * @event `reject`: Emits when the promise is rejected (event name may be overridden)
 * @event `fulfill`: Emits when the promise is fulfilled (event name may be overridden)
 * @api public
 */

function Promise (back) {
  EventEmitter.call(this);

  this.emitted = {};
  this.ended = false;
  if ('function' == typeof back)
    this.onResolve(back);
}

/*!
 * event names
 */

Promise.SUCCESS = 'fulfill';
Promise.FAILURE = 'reject';

/*!
 * Inherits from EventEmitter.
 */

Promise.prototype.__proto__ = EventEmitter.prototype;

/**
 * Adds `listener` to the `event`.
 *
 * If `event` is either the success or failure event and the event has already been emitted, the`listener` is called immediately and passed the results of the original emitted event.
 *
 * @param {String} event
 * @param {Function} callback
 * @return {Promise} this
 * @api public
 */

Promise.prototype.on = function (event, callback) {
  if (this.emitted[event])
    callback.apply(this, this.emitted[event]);
  else
    EventEmitter.prototype.on.call(this, event, callback);

  return this;
}

/**
 * Keeps track of emitted events to run them on `on`.
 *
 * @api private
 */

Promise.prototype.emit = function (event) {
  // ensures a promise can't be fulfill() or reject() more than once
  var success = this.constructor.SUCCESS;
  var failure = this.constructor.FAILURE;

  if (event == success || event == failure) {
    if (this.emitted[success] || this.emitted[failure]) {
      return this;
    }
    this.emitted[event] = slice(arguments, 1);
  }

  return EventEmitter.prototype.emit.apply(this, arguments);
}

/**
 * Fulfills this promise with passed arguments.
 *
 * If this promise has already been fulfilled or rejected, no action is taken.
 *
 * @api public
 */

Promise.prototype.fulfill = function () {
  var args = slice(arguments);
  return this.emit.apply(this, [this.constructor.SUCCESS].concat(args));
}

/**
 * Rejects this promise with `reason`.
 *
 * If this promise has already been fulfilled or rejected, no action is taken.
 *
 * @api public
 * @param {Object|String} reason
 * @return {Promise} this
 */

Promise.prototype.reject = function (reason) {
  return this.emit(this.constructor.FAILURE, reason);
}

/**
 * Resolves this promise to a rejected state if `err` is passed or
 * fulfilled state if no `err` is passed.
 *
 * @param {Error} [err] error or null
 * @param {Object} [val] value to fulfill the promise with
 * @api public
 */

Promise.prototype.resolve = function (err, val) {
  if (err) return this.reject(err);
  return this.fulfill(val);
}

/**
 * Adds a listener to the SUCCESS event.
 *
 * @return {Promise} this
 * @api public
 */

Promise.prototype.onFulfill = function (fn) {
  if (!fn || !fn.call || !fn.apply) return this;
  return this.on(this.constructor.SUCCESS, fn);
}

/**
 * Adds a listener to the FAILURE event.
 *
 * @return {Promise} this
 * @api public
 */

Promise.prototype.onReject = function (fn) {
  if (!fn || !fn.call || !fn.apply) return this;
  return this.on(this.constructor.FAILURE, fn);
}

/**
 * Adds a single function as a listener to both SUCCESS and FAILURE.
 *
 * It will be executed with traditional node.js argument position:
 * function (err, args...) {}
 *
 * @param {Function} fn
 * @return {Promise} this
 */

Promise.prototype.onResolve = function (fn) {
  if (!fn || !fn.call || !fn.apply) return this;
  this.on(this.constructor.FAILURE, function (err) {
    fn.apply(this, [err]);
  });

  this.on(this.constructor.SUCCESS, function(){
    var args = slice(arguments);
    fn.apply(this, [null].concat(args));
  });

  return this;
}

/**
 * Creates a new promise and returns it. If `onFulfill` or
 * `onReject` are passed, they are added as SUCCESS/ERROR callbacks
 * to this promise after the next tick.
 *
 * Conforms to [promises/A+](https://github.com/promises-aplus/promises-spec) specification. Read for more detail how to use this method.
 *
 * ####Example:
 *
 *     var p = new Promise;
 *     p.then(function (arg) {
 *       return arg + 1;
 *     }).then(function (arg) {
 *       throw new Error(arg + ' is an error!');
 *     }).then(null, function (err) {
 *       assert.ok(err instanceof Error);
 *       assert.equal('2 is an error', err.message);
 *     });
 *     p.complete(1);
 *
 * @see promises-A+ https://github.com/promises-aplus/promises-spec
 * @param {Function} onFulFill
 * @param {Function} onReject
 * @return {Promise} newPromise
 */

Promise.prototype.then = function (onFulfill, onReject) {
  var self = this
    , retPromise = new Promise;

  if ('function' == typeof onReject) {
    self.onReject(handler(retPromise, onReject));
  } else {
    self.onReject(retPromise.reject.bind(retPromise));
  }
  if ('function' == typeof onFulfill) {
    self.onFulfill(handler(retPromise, onFulfill));
  } else {
    self.onFulfill(retPromise.fulfill.bind(retPromise));
  }

  return retPromise;
}

function handler (retPromise, fn) {
  return function handle () {
    var args = arguments;
    next(function () {
      var x;

      try {
        x = fn.apply(undefined, args);
      } catch (err) {
        return retPromise.reject(err);
      }

      resolve(retPromise, x);
    });
  }
}

function resolve (promise, x) {
  var then;
  var type;
  var done;
  var reject_;
  var resolve_;

  type = typeof x;
  if ('undefined' == type) {
    return promise.fulfill(x);
  }

  if (promise === x) {
    return promise.reject(new TypeError("promise and x are the same"));
  }

  if (null != x) {

    if ('object' == type || 'function' == type) {
      try {
        then = x.then;
      } catch (err) {
        if (promise.ended) throw err;
        return promise.reject(err);
      }

      if ('function' == typeof then) {
        try {
          resolve_ = resolve.bind(this, promise);
          reject_ = promise.reject.bind(promise);
          done = false;
          return then.call(
              x
            , function fulfill () {
                if (done) return;
                done = true;
                return resolve_.apply(this, arguments);
              }
            , function reject () {
                if (done) return;
                done = true;
                return reject_.apply(this, arguments);
              })
        } catch (err) {
          if (done) return;
          done = true;
          if (promise.ended) throw err;
          return promise.reject(err);
        }
      }
    }
  }

  promise.fulfill(x);
}

/**
 * Signifies that this promise was the last in a chain of `then()s`: if a handler passed to the call to `then` which produced this promise throws, the exception will go uncaught.
 *
 * ####Example:
 *
 *     var p = new Promise;
 *     p.then(function(){ throw new Error('shucks') });
 *     setTimeout(function () {
 *       p.fulfill();
 *       // error was caught and swallowed by the promise returned from
 *       // p.then(). we either have to always register handlers on
 *       // the returned promises or we can do the following...
 *     }, 10);
 *
 *     // this time we use .end() which prevents catching thrown errors
 *     var p = new Promise;
 *     var p2 = p.then(function(){ throw new Error('shucks') }).end(); // <--
 *     setTimeout(function () {
 *       p.fulfill(); // throws "shucks"
 *     }, 10);
 *
 * @api public
 */

Promise.prototype.end = function () {
  this.ended = true;
}

/*!
 * Module exports.
 */

module.exports = Promise;
<commit_msg>short circuit<commit_after>'use strict';

/*!
 * Module dependencies.
 */

var slice = function (arr, start, end) { return Array.prototype.slice.call(arr, start, end) };
var EventEmitter = require('events').EventEmitter;

/**
 * compat with node 0.10
 */

var next = process.nextTick;

/**
 * Promise constructor.
 *
 * _NOTE: The success and failure event names can be overridden by setting `Promise.SUCCESS` and `Promise.FAILURE` respectively._
 *
 * @param {Function} back a function that accepts `fn(err, ...){}` as signature
 * @inherits NodeJS EventEmitter http://nodejs.org/api/events.html#events_class_events_eventemitter
 * @event `reject`: Emits when the promise is rejected (event name may be overridden)
 * @event `fulfill`: Emits when the promise is fulfilled (event name may be overridden)
 * @api public
 */

function Promise (back) {
  EventEmitter.call(this);

  this.emitted = {};
  this.ended = false;
  if ('function' == typeof back)
    this.onResolve(back);
}

/*!
 * event names
 */

Promise.SUCCESS = 'fulfill';
Promise.FAILURE = 'reject';

/*!
 * Inherits from EventEmitter.
 */

Promise.prototype.__proto__ = EventEmitter.prototype;

/**
 * Adds `listener` to the `event`.
 *
 * If `event` is either the success or failure event and the event has already been emitted, the`listener` is called immediately and passed the results of the original emitted event.
 *
 * @param {String} event
 * @param {Function} callback
 * @return {Promise} this
 * @api public
 */

Promise.prototype.on = function (event, callback) {
  if (this.emitted[event])
    callback.apply(this, this.emitted[event]);
  else
    EventEmitter.prototype.on.call(this, event, callback);

  return this;
}

/**
 * Keeps track of emitted events to run them on `on`.
 *
 * @api private
 */

Promise.prototype.emit = function (event) {
  // ensures a promise can't be fulfill() or reject() more than once
  var success = this.constructor.SUCCESS;
  var failure = this.constructor.FAILURE;

  if (event == success || event == failure) {
    if (this.emitted[success] || this.emitted[failure]) {
      return this;
    }
    this.emitted[event] = slice(arguments, 1);
  }

  return EventEmitter.prototype.emit.apply(this, arguments);
}

/**
 * Fulfills this promise with passed arguments.
 *
 * If this promise has already been fulfilled or rejected, no action is taken.
 *
 * @api public
 */

Promise.prototype.fulfill = function () {
  var args = slice(arguments);
  return this.emit.apply(this, [this.constructor.SUCCESS].concat(args));
}

/**
 * Rejects this promise with `reason`.
 *
 * If this promise has already been fulfilled or rejected, no action is taken.
 *
 * @api public
 * @param {Object|String} reason
 * @return {Promise} this
 */

Promise.prototype.reject = function (reason) {
  return this.emit(this.constructor.FAILURE, reason);
}

/**
 * Resolves this promise to a rejected state if `err` is passed or
 * fulfilled state if no `err` is passed.
 *
 * @param {Error} [err] error or null
 * @param {Object} [val] value to fulfill the promise with
 * @api public
 */

Promise.prototype.resolve = function (err, val) {
  if (err) return this.reject(err);
  return this.fulfill(val);
}

/**
 * Adds a listener to the SUCCESS event.
 *
 * @return {Promise} this
 * @api public
 */

Promise.prototype.onFulfill = function (fn) {
  if (!fn || !fn.call || !fn.apply) return this;
  if (!this.listeners(this.constructor.SUCCESS).length) {
    this.fulfill = fn;
  } else {
    this.fulfill = Promise.prototype.fulfill;
  }
  return this.on(this.constructor.SUCCESS, fn);
}

/**
 * Adds a listener to the FAILURE event.
 *
 * @return {Promise} this
 * @api public
 */

Promise.prototype.onReject = function (fn) {
  if (!fn || !fn.call || !fn.apply) return this;
  if (!this.listeners(this.constructor.FAILURE).length) {
    this.reject = fn;
  } else {
    this.reject = Promise.prototype.reject;
  }
  return this.on(this.constructor.FAILURE, fn);
}

/**
 * Adds a single function as a listener to both SUCCESS and FAILURE.
 *
 * It will be executed with traditional node.js argument position:
 * function (err, args...) {}
 *
 * @param {Function} fn
 * @return {Promise} this
 */

Promise.prototype.onResolve = function (fn) {
  if (!fn || !fn.call || !fn.apply) return this;
  if (!this.listeners(this.constructor.FAILURE).length && !this.listeners(this.constructor.SUCCESS).length) {
    this.fulfill = function () {var args = [].slice.call(arguments); args.unshift(null); fn.apply(this, args)};
    this.reject = fn;
  } else {
    this.fulfill = Promise.prototype.fulfill;
    this.reject = Promise.prototype.reject;
  }

  this.on(this.constructor.FAILURE, function (err) {
    fn.apply(this, [err]);
  });

  this.on(this.constructor.SUCCESS, function(){
    var args = slice(arguments);
    fn.apply(this, [null].concat(args));
  });

  return this;
}

/**
 * Creates a new promise and returns it. If `onFulfill` or
 * `onReject` are passed, they are added as SUCCESS/ERROR callbacks
 * to this promise after the next tick.
 *
 * Conforms to [promises/A+](https://github.com/promises-aplus/promises-spec) specification. Read for more detail how to use this method.
 *
 * ####Example:
 *
 *     var p = new Promise;
 *     p.then(function (arg) {
 *       return arg + 1;
 *     }).then(function (arg) {
 *       throw new Error(arg + ' is an error!');
 *     }).then(null, function (err) {
 *       assert.ok(err instanceof Error);
 *       assert.equal('2 is an error', err.message);
 *     });
 *     p.complete(1);
 *
 * @see promises-A+ https://github.com/promises-aplus/promises-spec
 * @param {Function} onFulFill
 * @param {Function} onReject
 * @return {Promise} newPromise
 */

Promise.prototype.then = function (onFulfill, onReject) {
  var self = this
    , retPromise = new Promise;

  if ('function' == typeof onReject) {
    self.onReject(handler(retPromise, onReject));
  } else {
    self.onReject(retPromise.reject.bind(retPromise));
  }
  if ('function' == typeof onFulfill) {
    self.onFulfill(handler(retPromise, onFulfill));
  } else {
    self.onFulfill(retPromise.fulfill.bind(retPromise));
  }

  return retPromise;
}

function handler (retPromise, fn) {
  return function handle () {
    var args = arguments;
    next(function () {
      var x;

      try {
        x = fn.apply(undefined, args);
      } catch (err) {
        return retPromise.reject(err);
      }

      resolve(retPromise, x);
    });
  }
}

function resolve (promise, x) {
  var then;
  var type;
  var done;
  var reject_;
  var resolve_;

  type = typeof x;
  if ('undefined' == type) {
    return promise.fulfill(x);
  }

  if (promise === x) {
    return promise.reject(new TypeError("promise and x are the same"));
  }

  if (null != x) {

    if ('object' == type || 'function' == type) {
      try {
        then = x.then;
      } catch (err) {
        if (promise.ended) throw err;
        return promise.reject(err);
      }

      if ('function' == typeof then) {
        try {
          resolve_ = resolve.bind(this, promise);
          reject_ = promise.reject.bind(promise);
          done = false;
          return then.call(
              x
            , function fulfill () {
                if (done) return;
                done = true;
                return resolve_.apply(this, arguments);
              }
            , function reject () {
                if (done) return;
                done = true;
                return reject_.apply(this, arguments);
              })
        } catch (err) {
          if (done) return;
          done = true;
          if (promise.ended) throw err;
          return promise.reject(err);
        }
      }
    }
  }

  promise.fulfill(x);
}

/**
 * Signifies that this promise was the last in a chain of `then()s`: if a handler passed to the call to `then` which produced this promise throws, the exception will go uncaught.
 *
 * ####Example:
 *
 *     var p = new Promise;
 *     p.then(function(){ throw new Error('shucks') });
 *     setTimeout(function () {
 *       p.fulfill();
 *       // error was caught and swallowed by the promise returned from
 *       // p.then(). we either have to always register handlers on
 *       // the returned promises or we can do the following...
 *     }, 10);
 *
 *     // this time we use .end() which prevents catching thrown errors
 *     var p = new Promise;
 *     var p2 = p.then(function(){ throw new Error('shucks') }).end(); // <--
 *     setTimeout(function () {
 *       p.fulfill(); // throws "shucks"
 *     }, 10);
 *
 * @api public
 */

Promise.prototype.end = function () {
  this.ended = true;
}

/*!
 * Module exports.
 */

module.exports = Promise;
<|endoftext|>


<commit_before>import {default as React, Component} from 'react';
import {default as ReactDOM} from 'react-dom';
import {default as update} from 'react-addons-update';
import {default as Dropzone} from 'react-dropzone';
import {default as request} from 'superagent';
import {Breadcrumb, BreadcrumbItem, Table, Glyphicon, Input, Row, Col, Grid, Navbar, Nav, NavDropdown, MenuItem} from 'react-bootstrap';
import {default as FontAwesome} from 'react-fontawesome';
import {default as _} from 'underscore';

require('babel-polyfill');

class StegaView extends Component {

  constructor(props) {
    super(props);
    this.state = {
      // populate directory with event from socket.io
      directory: {}, //{photoset: {photoname: id}}
      scrollY: 0
    }
  }

  componentWillMount() {
    this.socket = io();
    this.socket.on('directory', (directory) => {
      this.setState({directory});
    });
    window.addEventListener('scroll', () => {this.setState({scrollY: window.pageYOffset});});
    // this.socket.on('hello', () => {
    //   this.socket.emit('hello');
    //   console.log('hello');
    // });
    // this.socket.emit('hello');
    // keep in mind that this doesn't work. Only server-side receives the "connection" event.
    // this.socket.on('connection', () => {
    //   this.socket.emit('hello');
    //   console.log('hello');
    // });
  }

  render() {
    return(

        <NavMain {...this.state}/>
        <Grid>
          <Row>
          <Col xs={6} sm={8} md={9}><DirectoryBreadCrumb /></Col>
          <Col xs={6} sm={4} md={3}><DirectorySearchBar /></Col>
          </Row>
          <DirectoryTable {...this.state} />
        </Grid>

    );
  }
}

class NavMain extends Component {

  constructor(props) {
    super(props);
  }

  render() {
    var style = {float: 'left', margin: '7px 10px'};
    var content =
    <Navbar fluid>
      <Grid>
        <Navbar.Header>
          <Navbar.Brand>StegaStore</Navbar.Brand>
        </Navbar.Header>

          <NavDropdown title="Account">
            <MenuItem>Settings</MenuItem>
            <MenuItem>Logout</MenuItem>
          </NavDropdown>

      </Grid>
    </Navbar>;
    if(this.props.scrollY > 50) {
      content =
      <Navbar fixedTop fluid>
        <Grid>
          <Navbar.Collapse>
            <Navbar.Header>
              <Navbar.Brand>StegaStore</Navbar.Brand>
            </Navbar.Header>
            <Navbar.Form pullRight>
              <DirectorySearchBar />
            </Navbar.Form>
          </Navbar.Collapse>
        </Grid>
      </Navbar>;
    }
    return content;
  }
}

class DirectoryTable extends Component {
  //Clicking on file should download
  constructor(props) {
    super(props);
    this.state = {
      curDir: ''
    }
  }

  render() {
    var rows = _.uniq(Object.keys(this.props.directory)
      .filter((file) => {return file.indexOf(this.state.curDir) === 0;}) //only current directory
      .map((file) => {return file.split('/')[0];})) //for nested files, show only top-most parent folder
    .map((file) => {
      var glyph = <Glyphicon glyph='file' />;

      //check if folder
      if(this.props.directory[this.state.curDir + file] === undefined) {
        glyph = <Glyphicon glyph='folder-close' />;
      } else {
        //take off .png from the end
        file = file.split('.').slice(0,-1).join('.');

        switch(file.split('.').slice(-1)[0]) {
          case 'jpg':
          case 'png':
          case 'jpeg':
          case 'gif':
            glyph = <Glyphicon glyph='picture' />;
            break;
          case 'pdf':
            glyph = <FontAwesome className='fa fa-file-pdf-o' name='rootfile'/>;
            break;
          //add more cases here...
        }
      }
      return (

          {glyph}
          {file}
          Today

      );
    });

    return(

            <Glyphicon glyph="star" />
            Name
            Modified

          {rows}

    );
  }
}

class DirectoryBreadCrumb extends Component {
  //Clicking on home should go back to home
  constructor(props) {
    super(props);
  }

  render() {
    return (
      <Breadcrumb>
        <BreadcrumbItem href='#'>
          Home
        </BreadcrumbItem>
        <BreadcrumbItem active>
          Folder
        </BreadcrumbItem>
      </Breadcrumb>
    );
  }
}

class DirectorySearchBar extends Component {
  //Search through directory react-ively
  constructor(props) {
    super(props);
  }

  render() {
    return(
      <Input
        type="text"
        placeholder="Search"
        addonAfter={<Glyphicon glyph="search" />}
      />
    );
  }
}

class DropzoneArea extends Component {

  constructor(props) {
    super(props);
    this.state = {
      files: [],
      percent: 0
    };
  }

  onDragEnter(event) {
    console.log(event);
  }

  onDrop(files, callback){
    if(files.some((file) => {return file.size > 195*1024*1024;})) {
      //alert the user that one of their files exceeds capacity
      console.log(`At least one of your files exceeds file size maximum`);
      return;
    }
    var req = request.post('/api/upload').on('progress', (e) => {
      console.log(`${e.percent} uploaded`);
      this.setState({percent: parseInt(e.percent)});
    });
    files.forEach( (file) => {
      console.log(file);
      req.attach(file.name, file, file.name);
    });
    req.end( (res) => {
      console.log(res);
      // if(res.ok) {
      //   console.log('Success in uploading files', res);
      // } else {
      //   console.log('Error', res);
      }
    )
    this.setState({files: this.state.files.concat(files.map((file) => {return file.name;}))});
  }

  render() {
    return (

        <Dropzone onDrop={this.onDrop.bind(this)} onDragEnter={this.onDragEnter}>

Try dropping some files here, or click to select files to upload.

        </Dropzone>
        <FileList files={this.state.files} percent={this.state.percent}/>

    );
  }
}

class FileList extends Component {
  constructor(props) {
    super(props);
  }

  render() {
    return(

Uploaded files:

Progress: {this.props.percent}%

          {this.props.files.map((file) => {return
{file}
;})}

    );
  }
}

ReactDOM.render(
  <StegaView/>,
  document.getElementById('example')
);
<commit_msg>can go down directories<commit_after>import {default as React, Component} from 'react';
import {default as ReactDOM} from 'react-dom';
import {default as update} from 'react-addons-update';
import {default as Dropzone} from 'react-dropzone';
import {default as request} from 'superagent';
import {Breadcrumb, BreadcrumbItem, Table, Glyphicon, Input, Row, Col, Grid, Navbar, Nav, NavDropdown, MenuItem} from 'react-bootstrap';
import {default as FontAwesome} from 'react-fontawesome';
import {default as _} from 'underscore';

require('babel-polyfill');

class StegaView extends Component {

  constructor(props) {
    super(props);
    this.state = {
      // populate directory with event from socket.io
      directory: {}, //{photoset: {photoname: id}}
      scrollY: 0
    }
  }

  componentWillMount() {
    this.socket = io();
    this.socket.on('directory', (directory) => {
      this.setState({directory});
    });
    window.addEventListener('scroll', () => {this.setState({scrollY: window.pageYOffset});});
    // this.socket.on('hello', () => {
    //   this.socket.emit('hello');
    //   console.log('hello');
    // });
    // this.socket.emit('hello');
    // keep in mind that this doesn't work. Only server-side receives the "connection" event.
    // this.socket.on('connection', () => {
    //   this.socket.emit('hello');
    //   console.log('hello');
    // });
  }

  render() {
    return(

        <NavMain {...this.state}/>
        <Grid>
          <Row>
          <Col xs={6} sm={8} md={9}><DirectoryBreadCrumb /></Col>
          <Col xs={6} sm={4} md={3}><DirectorySearchBar /></Col>
          </Row>
          <DirectoryTable {...this.state} />
        </Grid>

    );
  }
}

class NavMain extends Component {

  constructor(props) {
    super(props);
  }

  render() {
    var style = {float: 'left', margin: '7px 10px'};
    var content =
    <Navbar fluid>
      <Grid>
        <Navbar.Header>
          <Navbar.Brand>StegaStore</Navbar.Brand>
        </Navbar.Header>

          <NavDropdown title="Account">
            <MenuItem>Settings</MenuItem>
            <MenuItem>Logout</MenuItem>
          </NavDropdown>

      </Grid>
    </Navbar>;
    if(this.props.scrollY > 50) {
      content =
      <Navbar fixedTop fluid>
        <Grid>
          <Navbar.Collapse>
            <Navbar.Header>
              <Navbar.Brand>StegaStore</Navbar.Brand>
            </Navbar.Header>
            <Navbar.Form pullRight>
              <DirectorySearchBar />
            </Navbar.Form>
          </Navbar.Collapse>
        </Grid>
      </Navbar>;
    }
    return content;
  }
}

class DirectoryTable extends Component {
  //Clicking on file should download
  //Clicking on folder should go into folder
  constructor(props) {
    super(props);
    this.state = {
      curDir: ''
    }
  }

  changeDir(folder) {
    this.setState({
      curDir: this.state.curDir+folder+'/'
    });
    console.log(this.state.curDir);
  }

  render() {
    var rows = _.uniq(Object.keys(this.props.directory)
      .filter((file) => {return file.indexOf(this.state.curDir) === 0;}) //only current directory
      .map((file) => {return file.substring(this.state.curDir.length);}) //remove directory prefix
      .map((file) => {return file.split('/')[0];})) //for nested files, show only top-most parent folder
    .map((file) => {
      var glyph = <Glyphicon glyph='file' />;

      //check if folder
      if(this.props.directory[this.state.curDir + file] === undefined) {
        glyph = <Glyphicon glyph='folder-close' />;
        file = {file};

        // function updateDir(folder) {
        //   this.setState({})
        // }
      } else {
        //take off .png from the end
        file = file.split('.').slice(0,-1).join('.');

        switch(file.split('.').slice(-1)[0]) {
          case 'jpg':
          case 'png':
          case 'jpeg':
          case 'gif':
            glyph = <Glyphicon glyph='picture' />;
            break;
          case 'pdf':
            glyph = <FontAwesome className='fa fa-file-pdf-o' name='rootfile'/>;
            break;
          //add more cases here...
        }
      }
      return (

          {glyph}
          {file}
          Today

      );
    });

    return(

            <Glyphicon glyph="star" />
            Name
            Modified

          {rows}

    );
  }
}

class DirectoryBreadCrumb extends Component {
  //Clicking on home should go back to home
  constructor(props) {
    super(props);
  }

  render() {
    return (
      <Breadcrumb>
        <BreadcrumbItem href='#'>
          Home
        </BreadcrumbItem>
        <BreadcrumbItem active>
          Folder
        </BreadcrumbItem>
      </Breadcrumb>
    );
  }
}

class DirectorySearchBar extends Component {
  //Search through directory react-ively
  constructor(props) {
    super(props);
  }

  render() {
    return(
      <Input
        type="text"
        placeholder="Search"
        addonAfter={<Glyphicon glyph="search" />}
      />
    );
  }
}

class DropzoneArea extends Component {

  constructor(props) {
    super(props);
    this.state = {
      files: [],
      percent: 0
    };
  }

  onDragEnter(event) {
    console.log(event);
  }

  onDrop(files, callback){
    if(files.some((file) => {return file.size > 195*1024*1024;})) {
      //alert the user that one of their files exceeds capacity
      console.log(`At least one of your files exceeds file size maximum`);
      return;
    }
    var req = request.post('/api/upload').on('progress', (e) => {
      console.log(`${e.percent} uploaded`);
      this.setState({percent: parseInt(e.percent)});
    });
    files.forEach( (file) => {
      console.log(file);
      req.attach(file.name, file, file.name);
    });
    req.end( (res) => {
      console.log(res);
      // if(res.ok) {
      //   console.log('Success in uploading files', res);
      // } else {
      //   console.log('Error', res);
      }
    )
    this.setState({files: this.state.files.concat(files.map((file) => {return file.name;}))});
  }

  render() {
    return (

        <Dropzone onDrop={this.onDrop.bind(this)} onDragEnter={this.onDragEnter}>

Try dropping some files here, or click to select files to upload.

        </Dropzone>
        <FileList files={this.state.files} percent={this.state.percent}/>

    );
  }
}

class FileList extends Component {
  constructor(props) {
    super(props);
  }

  render() {
    return(

Uploaded files:

Progress: {this.props.percent}%

          {this.props.files.map((file) => {return
{file}
;})}

    );
  }
}

ReactDOM.render(
  <StegaView/>,
  document.getElementById('example')
);
<|endoftext|>


<commit_before>/** A diagram
 * @constructor
 */
hui.ui.Diagram = function(options) {
	this.options = options;
	this.name = options.name;
	this.nodes = [];
	this.lines = [];
	this.element = hui.get(options.element);
	hui.ui.extend(this);
	this._init();
}

hui.ui.Diagram.create = function(options) {
	options = hui.override({width:400,height:500},options);

	options.element = hui.build('div',{'class':'hui_diagram'});

	return new hui.ui.Diagram(options);
}

hui.ui.Diagram.prototype = {
	_init : function() {
		this.background = hui.ui.Drawing.create({
			width: this.options.width,
			height: this.options.height
		});
		this.element.appendChild(this.background.element);
	},

	addBox : function(options) {
		options.container = this;
		var box = hui.ui.Diagram.Box.create(options);
		this.add(box);
	},
	add : function(widget) {
		var e = widget.element;
		this.element.appendChild(e);
		e.style.left = (Math.random()*(this.options.width - e.clientWidth))+'px';
		e.style.top = (Math.random()*(this.options.height - e.clientHeight))+'px';
		this.nodes.push(widget);
	},
	addLine : function(options) {
		var from = this.getNode(options.from),
			to = this.getNode(options.to),
			fromCenter = this._getCenter(from),
			toCenter = this._getCenter(to);

		var line = this.background.addLine({ from: fromCenter, to: toCenter, color: '#999' });
		this.lines.push({ from: options.from, to: options.to, node: line });
	},
	_getCenter : function(widget) {
		var e = widget.element;
		return {
			x : Math.round(parseInt(e.style.left)+e.clientWidth/2),
			y : Math.round(parseInt(e.style.top)+e.clientHeight/2)
		};
	},
	getNode : function(id) {
		for (var i=0; i < this.nodes.length; i++) {
			if (this.nodes[i].id == id) {
				return this.nodes[i];
			}
		};
		return null;
	},
	__nodeMoved : function(widget) {
		var center = this._getCenter(widget);
		for (var i=0; i < this.lines.length; i++) {
			var line = this.lines[i];
			if (line.from==widget.id) {
				line.node.setFrom(center);
			}
			else if (line.to==widget.id) {
				line.node.setTo(center);
			}
		};
	}
}

/** A box in a diagram
 * @constructor
 */
hui.ui.Diagram.Box = function(options) {
	this.options = options;
	this.id = options.id;
	this.name = options.name;
	this.element = hui.get(options.element);
	hui.ui.extend(this);
	this._addBehavior();
}

hui.ui.Diagram.Box.create = function(options) {
	var html = '
'+options.title+'
';
	html+='
';
	for (var i=0; i < options.properties.length; i++) {
		var p = options.properties[i];
		html+='
'+p.label+'	'+p.value+'
';
	};
	html+='
';
	options.element = hui.build('div',{'class':'hui_diagram_box',html:html});
	return new hui.ui.Diagram.Box(options);
}

hui.ui.Diagram.Box.prototype = {
	_addBehavior : function() {
		hui.drag.register({
			element : this.element,
			onBeforeMove : this._onBeforeMove.bind(this) ,
 			onMove : this._onMove.bind(this),
			onAfterMove : this._onAfterMove.bind(this)
		});
	},

	_onBeforeMove : function(e) {
		e = hui.event(e);
		this.element.style.zIndex = hui.ui.nextPanelIndex();
		var pos = hui.position.get(this.element);
		this.dragState = {left: e.getLeft() - pos.left,top:e.getTop()-pos.top};
		this.element.style.right = 'auto';
		hui.cls.add(this.element,'hui_diagram_box_dragging');
	},
	_onMove : function(e) {
		var top = (e.getTop()-this.dragState.top);
		var left = (e.getLeft()-this.dragState.left);
		this.element.style.top = Math.max(top,0)+'px';
		this.element.style.left = Math.max(left,0)+'px';
		this.options.container.__nodeMoved(this);
	},
	_onAfterMove : function() {
		hui.cls.remove(this.element,'hui_diagram_box_dragging');
		//hui.ui.callDescendants(this,'$$parentMoved');
	}
}<commit_msg>Improved diagram dragging<commit_after>/** A diagram
 * @constructor
 */
hui.ui.Diagram = function(options) {
	this.options = options;
	this.name = options.name;
	this.nodes = [];
	this.lines = [];
	this.element = hui.get(options.element);
	hui.ui.extend(this);
	this._init();
}

hui.ui.Diagram.create = function(options) {
	options = hui.override({width:400,height:500},options);

	options.element = hui.build('div',{'class':'hui_diagram'});

	return new hui.ui.Diagram(options);
}

hui.ui.Diagram.prototype = {
	_init : function() {
		this.background = hui.ui.Drawing.create({
			width: this.options.width,
			height: this.options.height
		});
		this.element.appendChild(this.background.element);
	},

	addBox : function(options) {
		options.container = this;
		var box = hui.ui.Diagram.Box.create(options);
		this.add(box);
	},
	add : function(widget) {
		var e = widget.element;
		this.element.appendChild(e);
		e.style.left = (Math.random()*(this.options.width - e.clientWidth))+'px';
		e.style.top = (Math.random()*(this.options.height - e.clientHeight))+'px';
		this.nodes.push(widget);
	},
	addLine : function(options) {
		var from = this.getNode(options.from),
			to = this.getNode(options.to),
			fromCenter = this._getCenter(from),
			toCenter = this._getCenter(to);

		var line = this.background.addLine({ from: fromCenter, to: toCenter, color: '#999' });
		this.lines.push({ from: options.from, to: options.to, node: line });
	},
	_getCenter : function(widget) {
		var e = widget.element;
		return {
			x : Math.round(parseInt(e.style.left)+e.clientWidth/2),
			y : Math.round(parseInt(e.style.top)+e.clientHeight/2)
		};
	},
	getNode : function(id) {
		for (var i=0; i < this.nodes.length; i++) {
			if (this.nodes[i].id == id) {
				return this.nodes[i];
			}
		};
		return null;
	},
	__nodeMoved : function(widget) {
		var center = this._getCenter(widget);
		for (var i=0; i < this.lines.length; i++) {
			var line = this.lines[i];
			if (line.from==widget.id) {
				line.node.setFrom(center);
			}
			else if (line.to==widget.id) {
				line.node.setTo(center);
			}
		};
	}
}

/** A box in a diagram
 * @constructor
 */
hui.ui.Diagram.Box = function(options) {
	this.options = options;
	this.id = options.id;
	this.name = options.name;
	this.element = hui.get(options.element);
	hui.ui.extend(this);
	this._addBehavior();
}

hui.ui.Diagram.Box.create = function(options) {
	var html = '
'+options.title+'
';
	html+='
';
	for (var i=0; i < options.properties.length; i++) {
		var p = options.properties[i];
		html+='
'+p.label+'	'+p.value+'
';
	};
	html+='
';
	options.element = hui.build('div',{'class':'hui_diagram_box',html:html});
	return new hui.ui.Diagram.Box(options);
}

hui.ui.Diagram.Box.prototype = {
	_addBehavior : function() {
		hui.drag.register({
			element : this.element,
			onStart : this._onDragStart.bind(this),
			onBeforeMove : this._onBeforeMove.bind(this) ,
 			onMove : this._onMove.bind(this),
			onEnd : this._onDragEnd.bind(this)
		});
	},
	_onDragStart : function() {
		hui.cls.add(this.element,'hui_diagram_box_dragging');
	},
	_onBeforeMove : function(e) {
		e = hui.event(e);
		this.element.style.zIndex = hui.ui.nextPanelIndex();
		var pos = hui.position.get(this.element);
		var container = hui.position.get(this.options.container.element);
		this.dragState = {left: e.getLeft() - pos.left + container.left,top:e.getTop()-pos.top + container.top};
		this.element.style.right = 'auto';
	},
	_onMove : function(e) {
		var top = (e.getTop()-this.dragState.top);
		var left = (e.getLeft()-this.dragState.left);
		this.element.style.top = Math.max(top,0)+'px';
		this.element.style.left = Math.max(left,0)+'px';
		this.options.container.__nodeMoved(this);
	},
	_onDragEnd : function() {
		hui.cls.remove(this.element,'hui_diagram_box_dragging');
		//hui.ui.callDescendants(this,'$$parentMoved');
	}
}<|endoftext|>


<commit_before>var chalk = require('chalk');
var appendFileSync = require('fs').appendFileSync;

var green = chalk.green;
var white = chalk.white;

var DEPLOY = 'ember deploy';
var NEW_LINE = '\n';
var MESSAGE = NEW_LINE + green('Success! Now deploy your app: ') + white(DEPLOY) + NEW_LINE;
var GITIGNORE = '.gitignore';
var PAGEFRONT_CONFIG = '.pagefrontrc';

module.exports = {
  normalizeEntityName: function() {},

  beforeInstall: function() {
    return this.addPackageToProject('ember-cli-deploy', '0.5.0-beta.1');
  },

  afterInstall: function() {
    appendFileSync(GITIGNORE, NEW_LINE + PAGEFRONT_CONFIG);
    this.ui.writeLine(MESSAGE);
  },

  locals: function(options) {
    var args = options.args;

    return {
      app: args[1],
      key: args[2]
    };
  }
}
<commit_msg>pass app and key as named options to default blueprint<commit_after>var chalk = require('chalk');
var appendFileSync = require('fs').appendFileSync;

var green = chalk.green;
var white = chalk.white;

var DEPLOY = 'ember deploy';
var NEW_LINE = '\n';
var MESSAGE = NEW_LINE + green('Success! Now deploy your app: ') + white(DEPLOY) + NEW_LINE;
var GITIGNORE = '.gitignore';
var PAGEFRONT_CONFIG = '.pagefrontrc';

module.exports = {
  normalizeEntityName: function() {},

  beforeInstall: function() {
    return this.addPackageToProject('ember-cli-deploy', '0.5.0-beta.1');
  },

  afterInstall: function() {
    appendFileSync(GITIGNORE, NEW_LINE + PAGEFRONT_CONFIG);
    this.ui.writeLine(MESSAGE);
  },

  locals: function(options) {
    return {
      app: options.app,
      key: options.key
    };
  }
}
<|endoftext|>


<commit_before>/**
 * Copyright 2011-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"). You
 * may not use this file except in compliance with the License. A copy of
 * the License is located at
 *
 *     http://aws.amazon.com/apache2.0/
 *
 * or in the "license" file accompanying this file. This file is
 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
 * ANY KIND, either express or implied. See the License for the specific
 * language governing permissions and limitations under the License.
 */

var AWS = require('./core');
var inherit = AWS.util.inherit;

/**
 * == Asynchronous Promise Objects
 *
 * All requests made through the SDK are asynchronous and use an
 * event-based promise callback interface. Each service method
 * that kicks off a request returns an +AWS.AWSRequest+ promise
 * object that you can use to register callbacks.
 *
 * For example, the following service method returns the request
 * object as "request", which can be used to register callbacks:
 *
 *   // request is an AWS.AWSRequest object
 *   var request = ec2.client.describeInstances();
 *
 *   // register callbacks on request to retrieve response data
 *   request.done(function(response) {
 *     console.log(resp.data);
 *   });
 *
 * == Multiple Callbacks and Chaining
 *
 * You can register multiple callbacks on any request object. The
 * callbacks can be registered for different events, or all for the
 * same event. In addition, you can chain callback registration, for
 * example:
 *
 *   request.
 *     done(function(response) {
 *       console.log("Success!");
 *     }).
 *     fail(function(response) {
 *       console.log("Error!");
 *     }).
 *     always(function(response) {
 *       console.log("Always!");
 *     });
 *
 * The above example will print either "Success! Always!", or "Error! Always!",
 * depending on whether the request succeeded or not.
 *
 * == Binding Custom Context Data on a Callback
 *
 * By default, the +this+ context of a callback function registered on an
 * event will be the {AWS.AWSResponse} object returned from the service.
 * In some cases, it may be necessary to pass extra custom context to these
 * functions; in these cases, you can bind a custom value to be used as the
 * +this+ context object when the callbacks are executed. To do so, pass
 * the +bind+ option to the asynchronous registration method:
 *
 *   var myContext = new Object();
 *   request.always(function(response) {
 *     console.log(this === myContext);
 *   }, {bind: myContext});
 *
 * The above callback will print +true+ when the callback function is executed.
 *
 * @see AWS.AWSResponse
 */
AWS.AWSRequest = inherit({
  /**
   * @api private
   */
  constructor: function AWSRequest(awsResponse) {
    this.state = null;
    this.awsResponse = awsResponse;
    this.callbacks = { data: [], done: [], fail: [], always: [] };

    AWS.util.each.call(this, this.callbacks, function (name) {
      this.addConfigCallback(name);
    });
  },

  /**
   * This event is used to stream response data from the
   * service packet-by-packet. This event is mostly used for large responses,
   * when it is inefficient (or impossible) to load the entire response into
   * memory.
   *
   * === Example: Registering a +data+ callback
   *
   *   s3.client.getObject({Bucket: b, Key: k}).data(function(resp) {
   *     console.log(resp.data);
   *   });
   *
   * Prints:
   *
   *   <Buffer 50 4b 03 04 0a 00 00 00 ...>
   *   <Buffer 2c 70 96 ac 92 2e ca e7 ...>
   *   ...
   *
   * @note If you register a +data+ callback,
   *   +response.data+ will not contain serialized output
   *   for the entire request. Instead, it will be your responsibility
   *   to stream the output and de-serialize the result on your own.
   * @callback callback function(response)
   *   @param response [AWS.AWSResponse] the response object containing the
   *     current packet in the +data+ property.
   * @option options bind [Object] (response object) an object to bind
   *   the callback function to. Defaults to the response object.
   * @return [AWS.AWSRequest] The same object, for chaining.
   */
  data: function data(callback, options) {
    if (this.awsResponse.data !== null) {
      this.call(callback, options);
    }
    this.callbacks.data.push([callback, options]);
    return this;
  },

  /**
   * This event registers a callback to be called when a successful response
   * from the server is returned. The response contains a
   * {AWS.AWSResponse.data data} field with the serialized response data
   * from the service.
   *
   * === Example: Registering a +done+ callback
   *
   *   s3.client.listBuckets().done(function(response) {
   *     console.log(response.data);
   *   });
   *
   * Prints:
   *
   *   { Owner: { ID: '...', DisplayName: '...' },
   *     Buckets:
   *      [ { Name: 'someBucketName', CreationDate: someCreationDate },
   *        { Name: 'otherBucketName', CreationDate: otherCreationDate } ],
   *     RequestId: '...' }
   *
   * @option options bind [Object] (response object) an object to bind
   *   the callback function to. Defaults to the response object.
   * @callback callback function(response)
   *   @param response [AWS.AWSResponse] the response object containing the
   *     de-serialized response contents in the +data+ property.
   *   @note The +response.error+ property will be +null+ when this callback
   *     is called.
   * @return [AWS.AWSRequest] The same object, for chaining.
   */
  done: function done(callback, options) {
    if (this.state === 'done') {
      this.call(callback, options);
    } else if (this.state === null) {
      this.callbacks.done.push([callback, options]);
    }
    return this;
  },

  /**
   * This event registers a callback to be called when a failure response
   * from the server is returned, or if a networking error occurs.
   * The response contains a {AWS.AWSResponse.error data} field with the
   * error data from the service.
   *
   * === Example: Registering a +fail+ callback
   *
   *   s3.config.credentials.accessKeyId = 'invalid';
   *   s3.client.listBuckets().fail(function(response) {
   *     console.log(response.error);
   *   });
   *
   * Prints:
   *
   *   { code: 'Forbidden', message: 403 }
   *
   * @option options bind [Object] (response object) an object to bind
   *   the callback function to. Defaults to the response object.
   * @callback callback function(response)
   *   @param response [AWS.AWSResponse] the response object containing the
   *     service error details in the +error+ property.
   *   @note The +response.data+ property will be +null+ when this callback
   *     is called.
   * @return [AWS.AWSRequest] The same object, for chaining.
   */
  fail: function fail(callback, options) {
    if (this.state === 'fail') {
      this.call(callback, options);
    } else if (this.state === null) {
      this.callbacks.fail.push([callback, options]);
    }
    return this;
  },

  /**
   * This event registers a callback to be called in any final state of a
   * request, i.e., both {done} and {fail}. Use this callback to handle any
   * request cleanup that must be executed regardless of the success state.
   *
   * Note that if you do intend to use response data inside of this callback,
   * you must check for the presence of +response.data+ or +response.error+
   * before attempting to access either property. For example:
   *
   *   request.always(function(response) {
   *     if (response.error) {
   *       // an error occurred, handle it
   *     } else {
   *       // we can use response.data here
   *     }
   *   });
   *
   * @option options bind [Object] (response object) an object to bind
   *   the callback function to. Defaults to the response object.
   * @callback callback function(response)
   *   @param response [AWS.AWSResponse] the response object containing the
   *     de-serialized response contents in the +data+ property or the
   *     error information in the +error+ property, depending on the result.
   * @return [AWS.AWSRequest] The same object, for chaining.
   */
  always: function always(callback, options) {
    if (this.state) {
      this.call(callback, options);
    } else {
      this.callbacks.always.push([callback, options]);
    }
    return this;
  },

  /**
   * @api private
   */
  notifyData: function notifyData(data) {
    this.awsResponse.data = data;
    this.notify('data', this.callbacks.data);
  },

  /**
   * @api private
   */
  notifyDone: function notifyDone(data) {
    this.awsResponse.data = data;
    this.notify('done', this.callbacks.done.concat(this.callbacks.always));
  },

  /**
   * @api private
   */
  notifyFail: function notifyFail(error) {
    this.awsResponse.error = error;
    this.notify('fail', this.callbacks.fail.concat(this.callbacks.always));
  },

  /**
   * @api private
   */
  notify: function notify(state, callbacks) {
    AWS.util.arrayEach.call(this, callbacks, function iterator(cb) {
      this.call(cb[0], cb[1]);
    });
    this.state = state;
  },

  /**
   * @api private
   */
  call: function call(callback, options) {
    var binding = this.awsResponse;
    if (options && options.bind) {
      binding = options.bind;
    }
    callback.call(binding, this.awsResponse);
  },

  /**
   * @api private
   */
  addConfigCallback: function addConfigCallback(cbMethod, configName) {
    if (!this.awsResponse.client) return;

    if (configName === undefined) {
      configName = 'on' + cbMethod.charAt(0).toUpperCase() + cbMethod.slice(1);
    }

    var callbacks = this.awsResponse.client.config[configName];
    if (!(callbacks instanceof Array) && callbacks !== undefined) {
      callbacks = [callbacks];
    }

    AWS.util.arrayEach.call(this, callbacks, function (callback) {
      if (callback instanceof Function) {
        this[cbMethod].call(this, callback);
      }
    });
  }

});

/**
 * This class encapsulates the the response information
 * from a service request operation sent through {AWS.AWSRequest}.
 * The response object has two main properties for getting information
 * back from a request:
 *
 * == The +data+ property
 *
 * The +response.data+ property contains the serialized object data
 * retrieved from the service request. For instance, for an
 * Amazon DynamoDB +listTables+ method call, the response data might
 * look like:
 *
 *   > resp.data
 *   { TableNames:
 *      [ 'table1', 'table2', ... ] }
 *
 * The +data+ property can be null if an error occurs (see below).
 *
 * == The +error+ property
 *
 * In the event of a service error (or transfer error), the
 * +response.error+ property will be filled with the given
 * error data in the form:
 *
 *   { code: 'SHORT_UNIQUE_ERROR_CODE',
 *     message: 'Some human readable error message' }
 *
 * In the case of an error, the +data+ property will be +null+.
 * Note that if you handle events that can be in a failure state,
 * you should always check whether +response.error+ is set
 * before attempting to access the +response.data+ property.
 *
 * @!attribute data
 *   @readonly
 *   @group Data Properties
 *   @note Inside of a {AWS.AWSRequest.data} event, this
 *     property contains a single raw packet instead of the
 *     full de-serialized service response.
 *   @return [Object] the de-serialized response data
 *     from the service.
 *
 * @!attribute error
 *   An structure containing information about a service
 *   or networking error.
 *   @readonly
 *   @group Data Properties
 *   @note This attribute is only filled if a service or
 *     networking error occurs.
 *   @return [Object]
 *     * code [String] a unique short code representing the
 *       error that was emitted.
 *     * message [String] a longer human readable error message
 *     * retryable [Boolean] whether the error message is
 *       retryable.
 *
 * @!attribute client
 *   @readonly
 *   @group Operation Properties
 *   @return [AWS.Client] The low-level service client object
 *     that initiated the request.
 *
 * @!attribute method
 *   @readonly
 *   @group Operation Properties
 *   @return [String] the name of the operation executed on
 *     the service.
 *
 * @!attribute params
 *   @readonly
 *   @group Operation Properties
 *   @return [Object] the parameters sent in the request to
 *     the service.
 *
 * @!attribute retryCount
 *   @readonly
 *   @group Operation Properties
 *   @return [Integer] the number of retries that have were
 *     attempted before the request was completed.
 *
 * @!attribute httpRequest
 *   @readonly
 *   @group HTTP Properties
 *   @return [AWS.HttpRequest] the raw HTTP request object
 *     containing request headers and body information
 *     sent by the client.
 *
 * @!attribute httpResponse
 *   @readonly
 *   @group HTTP Properties
 *   @return [AWS.HttpResponse] the raw HTTP response object
 *     containing the response headers and body information
 *     from the server.
 *
 * @see AWS.AWSRequest
 */
AWS.AWSResponse = inherit({

  /**
   * @api private
   */
  constructor: function AWSResponse(options) {

    // the request "context"
    this.client = options.client;
    this.method = options.method;
    this.params = options.params;

    this.data = null;
    this.error = null;
    this.retryCount = 0;

    this.httpRequest = null;
    this.httpResponse = null;

  }

});
<commit_msg>Update error code example documentation in AWSRequest.fail<commit_after>/**
 * Copyright 2011-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"). You
 * may not use this file except in compliance with the License. A copy of
 * the License is located at
 *
 *     http://aws.amazon.com/apache2.0/
 *
 * or in the "license" file accompanying this file. This file is
 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
 * ANY KIND, either express or implied. See the License for the specific
 * language governing permissions and limitations under the License.
 */

var AWS = require('./core');
var inherit = AWS.util.inherit;

/**
 * == Asynchronous Promise Objects
 *
 * All requests made through the SDK are asynchronous and use an
 * event-based promise callback interface. Each service method
 * that kicks off a request returns an +AWS.AWSRequest+ promise
 * object that you can use to register callbacks.
 *
 * For example, the following service method returns the request
 * object as "request", which can be used to register callbacks:
 *
 *   // request is an AWS.AWSRequest object
 *   var request = ec2.client.describeInstances();
 *
 *   // register callbacks on request to retrieve response data
 *   request.done(function(response) {
 *     console.log(resp.data);
 *   });
 *
 * == Multiple Callbacks and Chaining
 *
 * You can register multiple callbacks on any request object. The
 * callbacks can be registered for different events, or all for the
 * same event. In addition, you can chain callback registration, for
 * example:
 *
 *   request.
 *     done(function(response) {
 *       console.log("Success!");
 *     }).
 *     fail(function(response) {
 *       console.log("Error!");
 *     }).
 *     always(function(response) {
 *       console.log("Always!");
 *     });
 *
 * The above example will print either "Success! Always!", or "Error! Always!",
 * depending on whether the request succeeded or not.
 *
 * == Binding Custom Context Data on a Callback
 *
 * By default, the +this+ context of a callback function registered on an
 * event will be the {AWS.AWSResponse} object returned from the service.
 * In some cases, it may be necessary to pass extra custom context to these
 * functions; in these cases, you can bind a custom value to be used as the
 * +this+ context object when the callbacks are executed. To do so, pass
 * the +bind+ option to the asynchronous registration method:
 *
 *   var myContext = new Object();
 *   request.always(function(response) {
 *     console.log(this === myContext);
 *   }, {bind: myContext});
 *
 * The above callback will print +true+ when the callback function is executed.
 *
 * @see AWS.AWSResponse
 */
AWS.AWSRequest = inherit({
  /**
   * @api private
   */
  constructor: function AWSRequest(awsResponse) {
    this.state = null;
    this.awsResponse = awsResponse;
    this.callbacks = { data: [], done: [], fail: [], always: [] };

    AWS.util.each.call(this, this.callbacks, function (name) {
      this.addConfigCallback(name);
    });
  },

  /**
   * This event is used to stream response data from the
   * service packet-by-packet. This event is mostly used for large responses,
   * when it is inefficient (or impossible) to load the entire response into
   * memory.
   *
   * === Example: Registering a +data+ callback
   *
   *   s3.client.getObject({Bucket: b, Key: k}).data(function(resp) {
   *     console.log(resp.data);
   *   });
   *
   * Prints:
   *
   *   <Buffer 50 4b 03 04 0a 00 00 00 ...>
   *   <Buffer 2c 70 96 ac 92 2e ca e7 ...>
   *   ...
   *
   * @note If you register a +data+ callback,
   *   +response.data+ will not contain serialized output
   *   for the entire request. Instead, it will be your responsibility
   *   to stream the output and de-serialize the result on your own.
   * @callback callback function(response)
   *   @param response [AWS.AWSResponse] the response object containing the
   *     current packet in the +data+ property.
   * @option options bind [Object] (response object) an object to bind
   *   the callback function to. Defaults to the response object.
   * @return [AWS.AWSRequest] The same object, for chaining.
   */
  data: function data(callback, options) {
    if (this.awsResponse.data !== null) {
      this.call(callback, options);
    }
    this.callbacks.data.push([callback, options]);
    return this;
  },

  /**
   * This event registers a callback to be called when a successful response
   * from the server is returned. The response contains a
   * {AWS.AWSResponse.data data} field with the serialized response data
   * from the service.
   *
   * === Example: Registering a +done+ callback
   *
   *   s3.client.listBuckets().done(function(response) {
   *     console.log(response.data);
   *   });
   *
   * Prints:
   *
   *   { Owner: { ID: '...', DisplayName: '...' },
   *     Buckets:
   *      [ { Name: 'someBucketName', CreationDate: someCreationDate },
   *        { Name: 'otherBucketName', CreationDate: otherCreationDate } ],
   *     RequestId: '...' }
   *
   * @option options bind [Object] (response object) an object to bind
   *   the callback function to. Defaults to the response object.
   * @callback callback function(response)
   *   @param response [AWS.AWSResponse] the response object containing the
   *     de-serialized response contents in the +data+ property.
   *   @note The +response.error+ property will be +null+ when this callback
   *     is called.
   * @return [AWS.AWSRequest] The same object, for chaining.
   */
  done: function done(callback, options) {
    if (this.state === 'done') {
      this.call(callback, options);
    } else if (this.state === null) {
      this.callbacks.done.push([callback, options]);
    }
    return this;
  },

  /**
   * This event registers a callback to be called when a failure response
   * from the server is returned, or if a networking error occurs.
   * The response contains a {AWS.AWSResponse.error data} field with the
   * error data from the service.
   *
   * === Example: Registering a +fail+ callback
   *
   *   s3.config.credentials.accessKeyId = 'invalid';
   *   s3.client.listBuckets().fail(function(response) {
   *     console.log(response.error);
   *   });
   *
   * Prints:
   *
   *   { code: 'Forbidden', message: null }
   *
   * @option options bind [Object] (response object) an object to bind
   *   the callback function to. Defaults to the response object.
   * @callback callback function(response)
   *   @param response [AWS.AWSResponse] the response object containing the
   *     service error details in the +error+ property.
   *   @note The +response.data+ property will be +null+ when this callback
   *     is called.
   * @return [AWS.AWSRequest] The same object, for chaining.
   */
  fail: function fail(callback, options) {
    if (this.state === 'fail') {
      this.call(callback, options);
    } else if (this.state === null) {
      this.callbacks.fail.push([callback, options]);
    }
    return this;
  },

  /**
   * This event registers a callback to be called in any final state of a
   * request, i.e., both {done} and {fail}. Use this callback to handle any
   * request cleanup that must be executed regardless of the success state.
   *
   * Note that if you do intend to use response data inside of this callback,
   * you must check for the presence of +response.data+ or +response.error+
   * before attempting to access either property. For example:
   *
   *   request.always(function(response) {
   *     if (response.error) {
   *       // an error occurred, handle it
   *     } else {
   *       // we can use response.data here
   *     }
   *   });
   *
   * @option options bind [Object] (response object) an object to bind
   *   the callback function to. Defaults to the response object.
   * @callback callback function(response)
   *   @param response [AWS.AWSResponse] the response object containing the
   *     de-serialized response contents in the +data+ property or the
   *     error information in the +error+ property, depending on the result.
   * @return [AWS.AWSRequest] The same object, for chaining.
   */
  always: function always(callback, options) {
    if (this.state) {
      this.call(callback, options);
    } else {
      this.callbacks.always.push([callback, options]);
    }
    return this;
  },

  /**
   * @api private
   */
  notifyData: function notifyData(data) {
    this.awsResponse.data = data;
    this.notify('data', this.callbacks.data);
  },

  /**
   * @api private
   */
  notifyDone: function notifyDone(data) {
    this.awsResponse.data = data;
    this.notify('done', this.callbacks.done.concat(this.callbacks.always));
  },

  /**
   * @api private
   */
  notifyFail: function notifyFail(error) {
    this.awsResponse.error = error;
    this.notify('fail', this.callbacks.fail.concat(this.callbacks.always));
  },

  /**
   * @api private
   */
  notify: function notify(state, callbacks) {
    AWS.util.arrayEach.call(this, callbacks, function iterator(cb) {
      this.call(cb[0], cb[1]);
    });
    this.state = state;
  },

  /**
   * @api private
   */
  call: function call(callback, options) {
    var binding = this.awsResponse;
    if (options && options.bind) {
      binding = options.bind;
    }
    callback.call(binding, this.awsResponse);
  },

  /**
   * @api private
   */
  addConfigCallback: function addConfigCallback(cbMethod, configName) {
    if (!this.awsResponse.client) return;

    if (configName === undefined) {
      configName = 'on' + cbMethod.charAt(0).toUpperCase() + cbMethod.slice(1);
    }

    var callbacks = this.awsResponse.client.config[configName];
    if (!(callbacks instanceof Array) && callbacks !== undefined) {
      callbacks = [callbacks];
    }

    AWS.util.arrayEach.call(this, callbacks, function (callback) {
      if (callback instanceof Function) {
        this[cbMethod].call(this, callback);
      }
    });
  }

});

/**
 * This class encapsulates the the response information
 * from a service request operation sent through {AWS.AWSRequest}.
 * The response object has two main properties for getting information
 * back from a request:
 *
 * == The +data+ property
 *
 * The +response.data+ property contains the serialized object data
 * retrieved from the service request. For instance, for an
 * Amazon DynamoDB +listTables+ method call, the response data might
 * look like:
 *
 *   > resp.data
 *   { TableNames:
 *      [ 'table1', 'table2', ... ] }
 *
 * The +data+ property can be null if an error occurs (see below).
 *
 * == The +error+ property
 *
 * In the event of a service error (or transfer error), the
 * +response.error+ property will be filled with the given
 * error data in the form:
 *
 *   { code: 'SHORT_UNIQUE_ERROR_CODE',
 *     message: 'Some human readable error message' }
 *
 * In the case of an error, the +data+ property will be +null+.
 * Note that if you handle events that can be in a failure state,
 * you should always check whether +response.error+ is set
 * before attempting to access the +response.data+ property.
 *
 * @!attribute data
 *   @readonly
 *   @group Data Properties
 *   @note Inside of a {AWS.AWSRequest.data} event, this
 *     property contains a single raw packet instead of the
 *     full de-serialized service response.
 *   @return [Object] the de-serialized response data
 *     from the service.
 *
 * @!attribute error
 *   An structure containing information about a service
 *   or networking error.
 *   @readonly
 *   @group Data Properties
 *   @note This attribute is only filled if a service or
 *     networking error occurs.
 *   @return [Object]
 *     * code [String] a unique short code representing the
 *       error that was emitted.
 *     * message [String] a longer human readable error message
 *     * retryable [Boolean] whether the error message is
 *       retryable.
 *
 * @!attribute client
 *   @readonly
 *   @group Operation Properties
 *   @return [AWS.Client] The low-level service client object
 *     that initiated the request.
 *
 * @!attribute method
 *   @readonly
 *   @group Operation Properties
 *   @return [String] the name of the operation executed on
 *     the service.
 *
 * @!attribute params
 *   @readonly
 *   @group Operation Properties
 *   @return [Object] the parameters sent in the request to
 *     the service.
 *
 * @!attribute retryCount
 *   @readonly
 *   @group Operation Properties
 *   @return [Integer] the number of retries that have were
 *     attempted before the request was completed.
 *
 * @!attribute httpRequest
 *   @readonly
 *   @group HTTP Properties
 *   @return [AWS.HttpRequest] the raw HTTP request object
 *     containing request headers and body information
 *     sent by the client.
 *
 * @!attribute httpResponse
 *   @readonly
 *   @group HTTP Properties
 *   @return [AWS.HttpResponse] the raw HTTP response object
 *     containing the response headers and body information
 *     from the server.
 *
 * @see AWS.AWSRequest
 */
AWS.AWSResponse = inherit({

  /**
   * @api private
   */
  constructor: function AWSResponse(options) {

    // the request "context"
    this.client = options.client;
    this.method = options.method;
    this.params = options.params;

    this.data = null;
    this.error = null;
    this.retryCount = 0;

    this.httpRequest = null;
    this.httpResponse = null;

  }

});
<|endoftext|>