<commit_before>var api = require("./api");
var db = require("./db");
var util = require("./util");

var constraints = {};

/*
 * Load document from db.
 */
function load_document(params, ret_handler){//maybe move code to util.load_document

	if(params.wid){

		db.select(params.catalog, params.wid, function(err,doc){

			if(err)
				ret_handler(err,null);
			else if(!err && !doc)
				ret_handler({code:-7, message:"Document not found: #" + params.catalog + "/" + params.wid }, null);
			else
				ret_handler(null,doc);
		});
	}else
		ret_handler(null,null);

}

/*
 * Add a constraint on the remote procedure.
 */
exports.add_constraint =  function( proc_name, cons_name, func_handler ){

	if(!constraints[proc_name])
		constraints[proc_name] = {};

	constraints[proc_name][cons_name] = function(params, doc){

		return func_handler(params,doc);

	};
	return exports;
}

/*
 * Execute all constaints for proc_name procedure, if no constraints returns an error object execution continues
 * calling api.remote[proc_name].
 */
exports.execute = function( proc_name, params, ret_handler){

	var ctx = { params:params, config:{save:1, emit:0} };
	ctx.params.catalog = ctx.params.catalog || "docs"; //srv.db.config.default_catalog or srv.api.config.default_catalog

	load_document(params, function(err,doc){

		ctx.doc = doc;

		if(err)
			ret_handler(err,null);
		else{

			for( key in constraints[proc_name] ){

				var err = constraints[proc_name][key](ctx);
				if(err){

					ret_handler(err,null);
					return;
				}
			}

			api.remote[proc_name](ctx, function(err,val){

				if(err){
					ret_handler(err,null);
					return;
				}else if(ctx.config.save){

					db.save(ctx.params.catalog, ctx.doc, function(err){

						if(err)
							ret_handler(err,null);
						else{

							api.emit("ev_api_" + proc_name, ctx);
							ret_handler(null,val);
						}
					});
				}else{

					ret_handler(null,val);
				}
			});
		}

	});

}

exports.constraints = {

	is_owner: function(ctx){

			if( ctx.params.uid != ctx.doc.uid ){

				return {code:-2, message:"No access permission: not owner"};
			}
	},

	in_rcpts: function(ctx){

		if( ctx.doc.rcpts.indexOf(ctx.params.uid) == -1 ){

			return {code:-2, message:"No access permission: not in rcpts"};
		}
	},

	not_in_rcpts: function(ctx){

		if( ctx.doc.rcpts.indexOf(ctx.params.uid) != -1 ){

			return {code:-2, message:"No access permission: already in rcpts"};
		}
	},

	user_catalog: function(ctx){

		if(ctx.params.catalog == "events" || ctx.params.catalog == "timers"){

			return {code:-2, message:"No access permission: system catalog"};
		}
	},

	is_joinable: function(ctx){

		if(!ctx.doc.rcpts){

			return {code:-2, message:"No access permission: not joinable"};
		}
	},

	is_reserved: function(ctx){

		if(ctx.params.fname == "rcpts" || ctx.params.fname == "_id" || ctx.params.fname == "uid"){

			return {code:-3, message:"Reserved word not allowed as field name: " + ctx.params.fname };
		}
	},

	field_not_exists: function(ctx){

		if(util.get_field(ctx.doc,ctx.params.fname)){

			return {code:-3, message:"Already exists: #" + ctx.params.catalog + "/" + ctx.params.wid + "[" + ctx.params.fname + "]"};
		}
	},

	field_exists: function(ctx){

		if(!util.get_field(ctx.doc,ctx.params.fname)){

			return {code:-3, message:"Not exists: #" + ctx.params.catalog + "/" + ctx.params.wid + "[" + ctx.params.fname + "]"};
		}
	},

	field_type: function(type){

			return function(ctx){

				if(typeof util.get_field(ctx.doc,ctx.params.fname) != type ){

					return {code:-4, message:"Wrong type: #" + ctx.params.catalog + "/" + ctx.params.wid + "[" + ctx.params.fname + "] not " + type};
				}
		}
	},

	param_type : function(param_name, type){

			return function(ctx){

				if(typeof ctx.params[param_name] != type ){

					return {code:-4, message:"Wrong parameter type: "+ param_name +" not " + type };
				}
		}
	},

	is_required: function(field){

			return function(ctx){

				if(!ctx.params[field]){

					return {code:-4, message:field  + " parameter required"};
				}
		}
	},

};

<commit_msg>in_rcpts constraint fails when doc does not have rcpts list.<commit_after>var api = require("./api");
var db = require("./db");
var util = require("./util");

var constraints = {};

/*
 * Load document from db.
 */
function load_document(params, ret_handler){//maybe move code to util.load_document

	if(params.wid){

		db.select(params.catalog, params.wid, function(err,doc){

			if(err)
				ret_handler(err,null);
			else if(!err && !doc)
				ret_handler({code:-7, message:"Document not found: #" + params.catalog + "/" + params.wid }, null);
			else
				ret_handler(null,doc);
		});
	}else
		ret_handler(null,null);

}

/*
 * Add a constraint on the remote procedure.
 */
exports.add_constraint =  function( proc_name, cons_name, func_handler ){

	if(!constraints[proc_name])
		constraints[proc_name] = {};

	constraints[proc_name][cons_name] = function(params, doc){

		return func_handler(params,doc);

	};
	return exports;
}

/*
 * Execute all constaints for proc_name procedure, if no constraints returns an error object execution continues
 * calling api.remote[proc_name].
 */
exports.execute = function( proc_name, params, ret_handler){

	var ctx = { params:params, config:{save:1, emit:0} };
	ctx.params.catalog = ctx.params.catalog || "docs"; //srv.db.config.default_catalog or srv.api.config.default_catalog

	load_document(params, function(err,doc){

		ctx.doc = doc;

		if(err)
			ret_handler(err,null);
		else{

			for( key in constraints[proc_name] ){

				var err = constraints[proc_name][key](ctx);
				if(err){

					ret_handler(err,null);
					return;
				}
			}

			api.remote[proc_name](ctx, function(err,val){

				if(err){
					ret_handler(err,null);
					return;
				}else if(ctx.config.save){

					db.save(ctx.params.catalog, ctx.doc, function(err){

						if(err)
							ret_handler(err,null);
						else{

							api.emit("ev_api_" + proc_name, ctx);
							ret_handler(null,val);
						}
					});
				}else{

					ret_handler(null,val);
				}
			});
		}

	});

}

exports.constraints = {

	is_owner: function(ctx){

			if( ctx.params.uid != ctx.doc.uid ){

				return {code:-2, message:"No access permission: not owner"};
			}
	},

	in_rcpts: function(ctx){

		if( !ctx.doc.rcpts || ctx.doc.rcpts.indexOf(ctx.params.uid) == -1 ){

			return {code:-2, message:"No access permission: not in rcpts"};
		}
	},

	not_in_rcpts: function(ctx){

		if( ctx.doc.rcpts.indexOf(ctx.params.uid) != -1 ){

			return {code:-2, message:"No access permission: already in rcpts"};
		}
	},

	user_catalog: function(ctx){

		if(ctx.params.catalog == "events" || ctx.params.catalog == "timers"){

			return {code:-2, message:"No access permission: system catalog"};
		}
	},

	is_joinable: function(ctx){

		if(!ctx.doc.rcpts){

			return {code:-2, message:"No access permission: not joinable/unjoinable"};
		}
	},

	is_reserved: function(ctx){

		if(ctx.params.fname == "rcpts" || ctx.params.fname == "_id" || ctx.params.fname == "uid"){

			return {code:-3, message:"Reserved word not allowed as field name: " + ctx.params.fname };
		}
	},

	field_not_exists: function(ctx){

		if(util.get_field(ctx.doc,ctx.params.fname)){

			return {code:-3, message:"Already exists: #" + ctx.params.catalog + "/" + ctx.params.wid + "[" + ctx.params.fname + "]"};
		}
	},

	field_exists: function(ctx){

		if(!util.get_field(ctx.doc,ctx.params.fname)){

			return {code:-3, message:"Not exists: #" + ctx.params.catalog + "/" + ctx.params.wid + "[" + ctx.params.fname + "]"};
		}
	},

	field_type: function(type){

			return function(ctx){

				if(typeof util.get_field(ctx.doc,ctx.params.fname) != type ){

					return {code:-4, message:"Wrong type: #" + ctx.params.catalog + "/" + ctx.params.wid + "[" + ctx.params.fname + "] not " + type};
				}
		}
	},

	param_type : function(param_name, type){

			return function(ctx){

				if(typeof ctx.params[param_name] != type ){

					return {code:-4, message:"Wrong parameter type: "+ param_name +" not " + type };
				}
		}
	},

	is_required: function(field){

			return function(ctx){

				if(!ctx.params[field]){

					return {code:-4, message:field  + " parameter required"};
				}
		}
	},

};

<|endoftext|>


<commit_before>/* ===================================================
 * textClear.js v0.0.2
 * jQuery Plugin to clear input field text on fly - like as provided in Internet Explorer 10
 *
 *==========================================================================================
 * The MIT License (MIT)
 *
 * Copyright(c)2013 Exex Zian
 *
 * =========================================================================================
 * Requires: textClearStyle.css and jQuery.js
 * =========================================================================================
 */

; (function($) {
  $.fn.textClear = function() {
		$(this).on({
			'keypress' : function(e) {
				$(this).addClass('crossClear');
			},
			'focusout' : function() {
				$(this).removeClass('crossClear');
			},
			'click' : function(e) {
				if (($(this).hasClass('crossClear'))) {
					var mousePosInElement = e.pageX - $(this).position().left;
					if (mousePosInElement > $(this).width()) {
						$(this).removeClass('crossClear');
						$(this).val('');
					}
				}
			}
		});
	}
})(jQuery);
<commit_msg>version changed to 0.0.3<commit_after>/* ===================================================
 * textClear.js v0.0.3
 * jQuery Plugin to clear input field text on fly - like as provided in Internet Explorer 10
 *
 *==========================================================================================
 * The MIT License (MIT)
 *
 * Copyright(c)2013 Exex Zian
 *
 * =========================================================================================
 * Requires: textClearStyle.css and jQuery.js
 * =========================================================================================
 */

; (function($) {
  $.fn.textClear = function() {
		$(this).on({
			'keypress' : function(e) {
				$(this).addClass('crossClear');
			},
			'focusout' : function() {
				$(this).removeClass('crossClear');
			},
			'click' : function(e) {
				if (($(this).hasClass('crossClear'))) {
					var mousePosInElement = e.pageX - $(this).position().left;
					if (mousePosInElement > $(this).width()) {
						$(this).removeClass('crossClear');
						$(this).val('');
					}
				}
			}
		});
	}
})(jQuery);
<|endoftext|>


<commit_before>
var vm = require('vm');
var path = require('path');
var fs = require('fs');

function isLegacyVM() {
  // vm.isContext was added in 0.12.x
  return vm.isContext === undefined;
}

function createContext(sandbox) {
  if (isLegacyVM()) {
    var Contextify = require('contextify');
    Contextify(sandbox);
  } else {
    vm.createContext(sandbox);
  }
}

function runInSandbox(filePath, sandbox) {
  var fullPath = path.resolve(filePath);
  var fileContent = fs.readFileSync(fullPath, 'utf8');

  if (isLegacyVM()) {
    sandbox.run(fileContent, fullPath);
  } else {
    var fileScript = new vm.Script(fileContent, { filename: fullPath });
    fileScript.runInContext(sandbox);
  }
}

function createSandbox(dependencies) {
  var wrappedConsole =  Object.create(console);
  wrappedConsole.error = function() {
    console.error.apply(console, Array.prototype.map.call(arguments, function(a) {
      return typeof a === 'string' ? chalk.red(a) : a;
    }));
  };

  var sandbox = {
    // Expose the console to the FastBoot environment so we can debug
    console: wrappedConsole,

    // setTimeout and clearTimeout are an assumed part of JavaScript environments. Expose it.
    setTimeout: setTimeout,
    clearTimeout: clearTimeout,

    // Convince jQuery not to assume it's in a browser
    module: { exports: {} },

    URL: require("url")
  };

  for (var dep in dependencies) {
    sandbox[dep] = dependencies[dep];
  }

  // Set the global as `window`.
  sandbox.window = sandbox;
  sandbox.window.self = sandbox;

  // The sandbox is now a JavaScript context O_o
  createContext(sandbox);

  return sandbox;
}

module.exports = {
  createSandbox: createSandbox,
  runInSandbox: runInSandbox,
  isLegacyVM: isLegacyVM
}
<commit_msg>Forgot to require the chalk dependancy<commit_after>
var vm = require('vm');
var path = require('path');
var fs = require('fs');
var chalk = require('chalk');

function isLegacyVM() {
  // vm.isContext was added in 0.12.x
  return vm.isContext === undefined;
}

function createContext(sandbox) {
  if (isLegacyVM()) {
    var Contextify = require('contextify');
    Contextify(sandbox);
  } else {
    vm.createContext(sandbox);
  }
}

function runInSandbox(filePath, sandbox) {
  var fullPath = path.resolve(filePath);
  var fileContent = fs.readFileSync(fullPath, 'utf8');

  if (isLegacyVM()) {
    sandbox.run(fileContent, fullPath);
  } else {
    var fileScript = new vm.Script(fileContent, { filename: fullPath });
    fileScript.runInContext(sandbox);
  }
}

function createSandbox(dependencies) {
  var wrappedConsole =  Object.create(console);
  wrappedConsole.error = function() {
    console.error.apply(console, Array.prototype.map.call(arguments, function(a) {
      return typeof a === 'string' ? chalk.red(a) : a;
    }));
  };

  var sandbox = {
    // Expose the console to the FastBoot environment so we can debug
    console: wrappedConsole,

    // setTimeout and clearTimeout are an assumed part of JavaScript environments. Expose it.
    setTimeout: setTimeout,
    clearTimeout: clearTimeout,

    // Convince jQuery not to assume it's in a browser
    module: { exports: {} },

    URL: require("url")
  };

  for (var dep in dependencies) {
    sandbox[dep] = dependencies[dep];
  }

  // Set the global as `window`.
  sandbox.window = sandbox;
  sandbox.window.self = sandbox;

  // The sandbox is now a JavaScript context O_o
  createContext(sandbox);

  return sandbox;
}

module.exports = {
  createSandbox: createSandbox,
  runInSandbox: runInSandbox,
  isLegacyVM: isLegacyVM
}
<|endoftext|>


<commit_before>var rtc = require('rtc-tools');
var debug = rtc.logger('rtc-quickconnect');

/**
  Schemes allow multiple connection schemes for selection when attempting to connect to
  a peer
 **/
module.exports = function(signaller, opts) {

	var schemes = {};
	var _default;

	/**
	  Adds a connection scheme
	 **/
	function add(scheme) {
		// Ensure valid ID
		if (!scheme || !scheme.id || typeof scheme.id !== 'string') {
			throw new Error('Cannot add invalid scheme. Requires at least an ID');
		}
		// Unique schemes
		if (schemes[scheme.id]) {
			throw new Error('Scheme ' + schemeId + ' already exists');
		}
		// Check default
		if (scheme.default) {
			if (_default) {
				console.warn('Default scheme already exists');
			} else {
				_default = scheme.id;
			}
		}

		schemes[scheme.id] = scheme;
		debug('scheme added', scheme);
	}

	/**
	  Returns the scheme with the given ID. If canDefault is true it will return the default scheme
	  if no scheme with ID is found
	 **/
	function get(id, canDefault) {
		return schemes[id] || (canDefault && _default ? schemes[_default] : undefined);
	}

	// Load passed in schemes
	if (opts && opts.schemes && Array.isArray(opts.schemes)) {
		opts.schemes.forEach(add);
	}

	return {
		add: add,
		get: get
	};
};<commit_msg>Indentation to spaces<commit_after>var rtc = require('rtc-tools');
var debug = rtc.logger('rtc-quickconnect');

/**
  Schemes allow multiple connection schemes for selection when attempting to connect to
  a peer
 **/
module.exports = function(signaller, opts) {

  var schemes = {};
  var _default;

  /**
    Adds a connection scheme
   **/
  function add(scheme) {
    // Ensure valid ID
    if (!scheme || !scheme.id || typeof scheme.id !== 'string') {
      throw new Error('Cannot add invalid scheme. Requires at least an ID');
    }
    // Unique schemes
    if (schemes[scheme.id]) {
      throw new Error('Scheme ' + schemeId + ' already exists');
    }
    // Check default
    if (scheme.default) {
      if (_default) {
        console.warn('Default scheme already exists');
      } else {
        _default = scheme.id;
      }
    }

    schemes[scheme.id] = scheme;
    debug('scheme added %s', scheme.id, scheme);
  }

  /**
    Returns the scheme with the given ID. If canDefault is true it will return the default scheme
    if no scheme with ID is found
   **/
  function get(id, canDefault) {
    return schemes[id] || (canDefault && _default ? schemes[_default] : undefined);
  }

  // Load passed in schemes
  if (opts && opts.schemes && Array.isArray(opts.schemes)) {
    opts.schemes.forEach(add);
  }

  return {
    add: add,
    get: get
  };
};<|endoftext|>


<commit_before>
/*

  Scripts.js

*/

var Utils        = require("./utils"),
    fs           = require("fs"),
    assign       = require("lodash.assign"),
    express      = require("express"),
    Coffeescript = require("coffee-script");

var preprocessors = {
  ".js"     : function(raw, next) { next(raw); return; },
  ".coffee" : function(raw, next) { next(Coffeescript.compile(raw)); return }
}

module.exports = function(options) {

  var router = express(),

  // Set defaults
  options = assign({ path : "./scripts", url : "/scripts" }, options);

  // Walk through each file
  Utils.eachFile(options.path, function(file) {

    router.get(Utils.makeUrls(options.url, file, ".js")[0], function(req, res) {
      preprocessors[file.ext](fs.readFileSync(file.path, "utf8"), function(formatted) {
        return res.type("application/javascript").send(formatted);
      });
    });

  });

  return router;

}
<commit_msg>Scripts: filters for files we recognize<commit_after>
/*

  Scripts.js

*/

var Utils        = require("./utils"),
    fs           = require("fs"),
    assign       = require("lodash.assign"),
    express      = require("express"),
    Coffeescript = require("coffee-script");

var preprocessors = {
  ".js"     : function(raw, next) { next(raw); return; },
  ".coffee" : function(raw, next) { next(Coffeescript.compile(raw)); return }
}

module.exports = function(options) {

  var router = express(),

  // Set defaults
  options = assign({ path : "./scripts", url : "/scripts" }, options);

  // Walk through each file
  Utils.eachFile(options.path, { filter : Object.keys(preprocessors) }, function(file) {

    router.get(Utils.makeUrls(options.url, file, ".js")[0], function(req, res) {
      preprocessors[file.ext](fs.readFileSync(file.path, "utf8"), function(formatted) {
        return res.type("application/javascript").send(formatted);
      });
    });

  });

  return router;

}
<|endoftext|>


<commit_before>/* jslint node: true */
'use strict';

/*
* @name /lib/helperTapestry.js
* @description This helper is small, so all the code is in here
* @since Mon Jun 02 2014
* @author Rob Johnson <rob.johnson@holidayextras.com>
*/

var Tapestry = require( 'tapestry' );
var _ = require( 'lodash' );
var Q = require( 'q' );

module.exports = {
	do: function( deferred, options ) {

		// The data that has been passed in from revolver
		var revolverData = options.inputData;

		// An array of deferreds that have to be completed for this help to resolve the main deferred
		var tapestryLookupDeferreds = [];

		// Create a new Tapestry object based on the passed in sources
		var tapestry = new Tapestry( {
			sources: options.sources
		} );

		/*
		* Function to detect a code in the passed in data object.
		* Will detect hotel codes (a 6 character string under the code attribute)
		*	And ticket codes (3 character string under the location and a 3 character sting under code)
		*/
		var extractCode = function( data ) {

			// If no code found will return null and be ignored by calling function
			var code = null;

			_.each( options.codePatterns, function( codePattern ) {

				if ( _.isArray( codePattern ) ) {
					var builtCode = '';
					_.each( codePattern, function( subPattern ) {
						if ( data[subPattern.fieldName] && ( data[subPattern.fieldName].length == subPattern.length ) ) {
							builtCode += data[subPattern.fieldName];
						}
					} );

					if ( builtCode.length > 0 ) {
						code = builtCode;
					}

				} else if ( data[codePattern.fieldName] && ( data[codePattern.fieldName].length == codePattern.length ) ) {
					code = data[codePattern.fieldName];
				}

			} );

			return code;
		}

		/*
		* Function to recursivly go through the data structure.
		* If any keys contain arrays or objects it will call itself to examine that child
		*	If a code is detected it will call to tapestry, adding a deferred that will be resolved on success
		*/
		var extractCodesAndCallTapestry = function( data ) {
			// Detect the code
			var code = extractCode( data );

			// This function will recursivly call itself if any of the child elements are arrays or objects.
			// In which case the function will be called again with the child element becoming 'data'
			// If there are no child arrays or objects then this is the end of the recursion
			_.each( data, function( fragmentData ) {
				if ( _.isArray(fragmentData) || _.isObject(fragmentData) ) {
					extractCodesAndCallTapestry( fragmentData );
				}
			} );

			// If we detected a code before then we want to make a call down to tapestry
			if ( code ) {

				// Create the deferred and add it to the array that will be checked below
				var tapestryLookupDeferred = Q.defer();
				tapestryLookupDeferreds.push( tapestryLookupDeferred.promise );

				// Make a singular tapestry request with the found code
				tapestry.get( { ids: [code], identifier: options.identifier }, function( error, result ) {

					// Add the returned result as a content object under the original detected node.
					if ( result ) {
						data.content = result;
					}
					// TODO - on error ? Think we still resolve but maybe add to an error log/reply node

					tapestryLookupDeferred.resolve();
				} );
			}

		}

		// Kick off the recursive extraction of the codes
		extractCodesAndCallTapestry( revolverData );

		// When all the deferreds are resolved we can tell the calling code we are done here.
		Q.allSettled( tapestryLookupDeferreds ).then( function() {
			deferred.resolve( revolverData );
		} );

		return deferred.promise;
	}
};
<commit_msg>Add comments and pass through the codePatterns as parameters<commit_after>/* jslint node: true */
'use strict';

/*
* @name /lib/helperTapestry.js
* @description This helper is small, so all the code is in here
* @since Mon Jun 02 2014
* @author Rob Johnson <rob.johnson@holidayextras.com>
*/

var Tapestry = require( 'tapestry' );
var _ = require( 'lodash' );
var Q = require( 'q' );

module.exports = {
	do: function( deferred, options ) {

		// The data that has been passed in from revolver
		var revolverData = options.inputData;

		// An array of deferreds that have to be completed for this help to resolve the main deferred
		var tapestryLookupDeferreds = [];

		// Create a new Tapestry object based on the passed in sources
		var tapestry = new Tapestry( {
			sources: options.sources
		} );

		/*
		* Function to detect a code based on the name of the key and the length of the value
		* Supports codePatterns of just a single key and also composite keys across multiple key/values
		*/
		var extractCode = function( data, codePatterns ) {

			// If no code found will return null and be ignored by calling function
			var code = null;

			// So we have an array of code patterns that we want to check the data against so lets start looping over them
			_.each( codePatterns, function( codePattern ) {

				// If it is an array of patterns we want to match each and every one of these sub patterns, building up the code as we go
				if ( _.isArray( codePattern ) ) {

					// Start off with a blank string - we will test against an empty string below
					var builtCode = '';

					// Loop over each sub code pattern and if the fieldName and the length match append the value of the key to the builtCode string
					_.each( codePattern, function( subPattern ) {
						if ( data[subPattern.fieldName] && ( data[subPattern.fieldName].length == subPattern.length ) ) {
							builtCode += data[subPattern.fieldName];
						}
					} );

					// If we have appended text to the builtCode then we want to pass this all back to the calling function
					if ( builtCode.length > 0 ) {
						code = builtCode;
					}

				// If it isn't an array detect a single code based on the key and the length of the value
				} else if ( data[codePattern.fieldName] && ( data[codePattern.fieldName].length == codePattern.length ) ) {
					code = data[codePattern.fieldName];
				}

			} );

			return code;
		}

		/*
		* Function to recursivly go through the data structure.
		* If any keys contain arrays or objects it will call itself to examine that child
		*	If a code is detected it will call to tapestry, adding a deferred that will be resolved on success
		*/
		var extractCodesAndCallTapestry = function( data, codePatterns ) {

			// Detect the code
			var code = extractCode( data, codePatterns );

			// This function will recursivly call itself if any of the child elements are arrays or objects.
			// In which case the function will be called again with the child element becoming 'data'
			// If there are no child arrays or objects then this is the end of the recursion
			_.each( data, function( fragmentData ) {
				if ( _.isArray(fragmentData) || _.isObject(fragmentData) ) {
					extractCodesAndCallTapestry( fragmentData, codePatterns );
				}
			} );

			// If we detected a code before then we want to make a call down to tapestry
			if ( code ) {

				// Create the deferred and add it to the array that will be checked below
				var tapestryLookupDeferred = Q.defer();
				tapestryLookupDeferreds.push( tapestryLookupDeferred.promise );

				// Make a singular tapestry request with the found code
				tapestry.get( { ids: [code], identifier: options.identifier }, function( error, result ) {

					// Add the returned result as a content object under the original detected node.
					if ( result ) {
						data.content = result;
					}
					// TODO - on error ? Think we still resolve but maybe add to an error log/reply node

					tapestryLookupDeferred.resolve();
				} );
			}

		}

		// Kick off the recursive extraction of the codes
		extractCodesAndCallTapestry( revolverData, options.codePatterns );

		// When all the deferreds are resolved we can tell the calling code we are done here.
		Q.allSettled( tapestryLookupDeferreds ).then( function() {
			deferred.resolve( revolverData );
		} );

		return deferred.promise;
	}
};
<|endoftext|>


<commit_before>'use strict';

var url = require('url');
var https = require('follow-redirects').https;
var async = require('async');
var rarity = require('rarity');
var crypto = require('crypto');
var fs = require('fs');
var generateTitle = require('anyfetch-provider').util.generateTitle;

/**
 * Upload file onto AnyFetch.
 *
 *
 * @param {Object} task Data of the task
 * @param {Object} anyfetchClient Client for upload
 * @param {Object} accessToken Access token of the current account
 * @param {Function} cb Callback to call once file has been uploaded.
 */
module.exports = function(task, anyfetchClient, accessToken, cb) {
  var path = '/tmp/' + crypto.randomBytes(20).toString('hex');

  /*
   * We don't know what GDrive do when we export file (Google Drive converted files)
   * And if we don't save this files in tmp files, we have error "400 Bad Request" with NGinx
   * So, normal files without export links are direct streamed to the API and others pass through a temp file
   */

  async.waterfall([
    function requestFile(cb) {
      var options = url.parse(task.downloadUrl);
      options.headers = {
        'Authorization': 'Bearer ' + accessToken
      };

      // We need to set this header, without we have a socket hang up with direct stream
      if(!task.exported) {
        options.headers = {"Connection" : "close"};
      }

      // Google can have random 500 error. So we must do an exponential backoff.
      var time = 200;
      function tryRequest(cb) {
        var req = https.request(options, function(res) {
          if(res.statusCode !== 500 || time > 10000) {
            return cb(null, res);
          }

          time *= 2;
          setTimeout(function() {
            tryRequest(cb);
          }, time);
        });

        req.on('error', cb);
        req.end();
      }

      tryRequest(cb);
    },
    function generateStream(res, cb) {
      if(res.statusCode !== 200) {
        return cb(new Error('GDrive bad status code : ' + res.statusCode));
      }

      if(!task.exported) {
        return cb(null, res);
      }

      var stream = fs.createWriteStream(path);
      stream.on('error', cb);

      res.on('end', function() {
        cb(null, path);
      });

      res.pipe(stream);
    },
    function sendFile(data, cb) {
      var fileConfig = function(cb) {
        cb(null, {
          file: (task.exported) ? fs.createReadStream(path) : data,
          filename: task.title
        });
      };

      var document = {
        identifier: task.identifier,
        actions: {
          show: task.link
        },
        creation_date: task.createdDate,
        modification_date: task.modifiedDate,
        metadata: {
          title: generateTitle(task.title),
          path: '/' + task.title,
          starred: task.starred
        },
        document_type: task.type,
        user_access: [anyfetchClient.accessToken]
      };

      anyfetchClient.sendDocumentAndFile(document, fileConfig, rarity.slice(1, cb));
    },
    function deleteTempFile(cb) {
      if(task.exported) {
        fs.unlink(path, cb);
      }
      else {
        cb(null);
      }
    }
  ], cb);
};
<commit_msg>Update upload.js<commit_after>'use strict';

var url = require('url');
var https = require('follow-redirects').https;
var async = require('async');
var rarity = require('rarity');
var crypto = require('crypto');
var fs = require('fs');
var generateTitle = require('anyfetch-provider').util.generateTitle;

/**
 * Upload file onto AnyFetch.
 *
 *
 * @param {Object} task Data of the task
 * @param {Object} anyfetchClient Client for upload
 * @param {Object} accessToken Access token of the current account
 * @param {Function} cb Callback to call once file has been uploaded.
 */
module.exports = function(task, anyfetchClient, accessToken, cb) {
  var path = '/tmp/' + crypto.randomBytes(20).toString('hex');

  /*
   * We don't know what GDrive do when we export file (Google Drive converted files)
   * And if we don't save this files in tmp files, we have error "400 Bad Request" with NGinx
   * So, normal files without export links are direct streamed to the API and others pass through a temp file
   */

  async.waterfall([
    function requestFile(cb) {
      var options = url.parse(task.downloadUrl);
      options.headers = {
        'Authorization': 'Bearer ' + accessToken
      };

      // We need to set this header, without we have a socket hang up with direct stream
      if(!task.exported) {
        options.headers = {"Connection" : "close"};
      }

      // Google can have random 500 error. So we must do an exponential backoff.
      // See http://stackoverflow.com/questions/12471180/frequently-http-500-internal-error-with-google-drive-api-drive-files-get
      var time = 200;
      function tryRequest(cb) {
        var req = https.request(options, function(res) {
          if(res.statusCode !== 500 || time > 10000) {
            return cb(null, res);
          }

          time *= 2;
          setTimeout(function() {
            tryRequest(cb);
          }, time);
        });

        req.on('error', cb);
        req.end();
      }

      tryRequest(cb);
    },
    function generateStream(res, cb) {
      if(res.statusCode !== 200) {
        return cb(new Error('GDrive bad status code : ' + res.statusCode));
      }

      if(!task.exported) {
        return cb(null, res);
      }

      var stream = fs.createWriteStream(path);
      stream.on('error', cb);

      res.on('end', function() {
        cb(null, path);
      });

      res.pipe(stream);
    },
    function sendFile(data, cb) {
      var fileConfig = function(cb) {
        cb(null, {
          file: (task.exported) ? fs.createReadStream(path) : data,
          filename: task.title
        });
      };

      var document = {
        identifier: task.identifier,
        actions: {
          show: task.link
        },
        creation_date: task.createdDate,
        modification_date: task.modifiedDate,
        metadata: {
          title: generateTitle(task.title),
          path: '/' + task.title,
          starred: task.starred
        },
        document_type: task.type,
        user_access: [anyfetchClient.accessToken]
      };

      anyfetchClient.sendDocumentAndFile(document, fileConfig, rarity.slice(1, cb));
    },
    function deleteTempFile(cb) {
      if(task.exported) {
        fs.unlink(path, cb);
      }
      else {
        cb(null);
      }
    }
  ], cb);
};
<|endoftext|>


<commit_before>'use strict';
var retrieve = require('./retrieve.js');
var config = require('../../config/configuration.js');
var crypto = require('crypto');
var path = require('path');
var generateTitle = require('anyfetch-provider').util.generateTitle;
var logError = require('anyfetch-provider').util.logError;

var uploadFile = function(identifier, metadata, dropboxTokens, anyfetchClient, cache, job, cb) {
  var filename = metadata.path.substr(metadata.path.lastIndexOf('/') + 1);

  var shasum = crypto.createHash('sha1');
  shasum.update(dropboxTokens.oauth_token);
  shasum.update(metadata.path);
  shasum.update(config.appSecret);
  var hash = shasum.digest('hex').toString();

  var document = {
    identifier: identifier,
    actions: {
    },
    creation_date: metadata.modified,
    modification_date: metadata.modified,
    metadata: {
      path: metadata.path,
      title: generateTitle(metadata.path)
    },
    data: {},
    document_type: "file",
    user_access: [anyfetchClient.accessToken]
  };

  if(metadata.thumb_exists) {
    document.metadata.thumb = config.providerUrl + "/image?size=m&oauth_token=" + dropboxTokens.oauth_token + "&path=" + encodeURIComponent(metadata.path) + "&hash=" + hash;
    document.data.display = config.providerUrl + "/image?size=xl&oauth_token=" + dropboxTokens.oauth_token + "&path=" + encodeURIComponent(metadata.path) + "&hash=" + hash;

    if(metadata.mime_type.indexOf('png') !== -1) {
      document.data.thumb += "&format=png";
      document.data.display += "&format=png";
    }
  }

  document.actions.show = "http://dropbox.com/home" + path.dirname(metadata.path) + "?select=" + encodeURIComponent(path.basename(metadata.path));

  retrieve.getFile(dropboxTokens, metadata.path, cache, function(status, reply, headers) {
    if(status !== 200 || !reply) {
      if(reply && reply.toString().match(/rate limiting/i)) {
        var retryTime = parseFloat(headers['retry-after']) + 5;
        console.warn("Retry limit, we will retry in " + retryTime + " sec");

        return setTimeout(function() {
          uploadFile(identifier, metadata, dropboxTokens, anyfetchClient, cache, job, cb);
        }, (retryTime + 10) * 1000);
      }

      logError(new Error("Failure to retrieve data or empty file"), {
        reply: (reply ? reply.toString() : 'No content'),
        status: status,
        identifier: identifier,
        show: document.actions.show
      });

      return cb();
    }

    // File to send
    var fileConfig = {
      file: reply,
      filename: filename,
      knownLength: reply.length
    };

    // Let's roll.
    anyfetchClient.sendDocumentAndFile(document, fileConfig, cb);
  });
};

/**
 * Run the task of uploading a document to AnyFetch.
 * This function will be used as a queue
 * @see https://github.com/caolan/async#queueworker-concurrency
 *
 * @param {Object} task Task param
 * @param {Function} cb Callback once task has been processed.
 */
module.exports = function(task, anyfetchClient, dropboxTokens, cache, job, cb) {
  return uploadFile(task.identifier, task.metadata, dropboxTokens, anyfetchClient, cache, job, cb);
};
<commit_msg>Fix data / metadata failure<commit_after>'use strict';
var retrieve = require('./retrieve.js');
var config = require('../../config/configuration.js');
var crypto = require('crypto');
var path = require('path');
var generateTitle = require('anyfetch-provider').util.generateTitle;
var logError = require('anyfetch-provider').util.logError;

var uploadFile = function(identifier, metadata, dropboxTokens, anyfetchClient, cache, job, cb) {
  var filename = metadata.path.substr(metadata.path.lastIndexOf('/') + 1);

  var shasum = crypto.createHash('sha1');
  shasum.update(dropboxTokens.oauth_token);
  shasum.update(metadata.path);
  shasum.update(config.appSecret);
  var hash = shasum.digest('hex').toString();

  var document = {
    identifier: identifier,
    actions: {
    },
    creation_date: metadata.modified,
    modification_date: metadata.modified,
    metadata: {
      path: metadata.path,
      title: generateTitle(metadata.path)
    },
    data: {},
    document_type: "file",
    user_access: [anyfetchClient.accessToken]
  };

  if(metadata.thumb_exists) {
    document.metadata.thumb = config.providerUrl + "/image?size=m&oauth_token=" + dropboxTokens.oauth_token + "&path=" + encodeURIComponent(metadata.path) + "&hash=" + hash;
    document.data.display = config.providerUrl + "/image?size=xl&oauth_token=" + dropboxTokens.oauth_token + "&path=" + encodeURIComponent(metadata.path) + "&hash=" + hash;

    if(metadata.mime_type.indexOf('png') !== -1) {
      document.metadata.thumb += "&format=png";
      document.data.display += "&format=png";
    }
  }

  document.actions.show = "http://dropbox.com/home" + path.dirname(metadata.path) + "?select=" + encodeURIComponent(path.basename(metadata.path));

  retrieve.getFile(dropboxTokens, metadata.path, cache, function(status, reply, headers) {
    if(status !== 200 || !reply) {
      if(reply && reply.toString().match(/rate limiting/i)) {
        var retryTime = parseFloat(headers['retry-after']) + 5;
        console.warn("Retry limit, we will retry in " + retryTime + " sec");

        return setTimeout(function() {
          uploadFile(identifier, metadata, dropboxTokens, anyfetchClient, cache, job, cb);
        }, (retryTime + 10) * 1000);
      }

      logError(new Error("Failure to retrieve data or empty file"), {
        reply: (reply ? reply.toString() : 'No content'),
        status: status,
        identifier: identifier,
        show: document.actions.show
      });

      return cb();
    }

    // File to send
    var fileConfig = {
      file: reply,
      filename: filename,
      knownLength: reply.length
    };

    // Let's roll.
    anyfetchClient.sendDocumentAndFile(document, fileConfig, cb);
  });
};

/**
 * Run the task of uploading a document to AnyFetch.
 * This function will be used as a queue
 * @see https://github.com/caolan/async#queueworker-concurrency
 *
 * @param {Object} task Task param
 * @param {Function} cb Callback once task has been processed.
 */
module.exports = function(task, anyfetchClient, dropboxTokens, cache, job, cb) {
  return uploadFile(task.identifier, task.metadata, dropboxTokens, anyfetchClient, cache, job, cb);
};
<|endoftext|>


<commit_before>/**
 * Created by wok on 16.04.16.
 */

import { Meteor } from 'meteor/meteor';
import { MinutesCollection } from './collections/minutes_private';
import { MeetingSeries } from './meetingseries'

export class Minutes {
    constructor(source) {   // constructs obj from Mongo ID or Mongo document
        if (! source)
            return;

        if (typeof source === 'string') {   // we may have an ID here.
            source = Minutes.findOne(source);
        }
        if (typeof source === 'object') { // inject class methods in plain collection document
            _.extend(this, source);
        }
    }

    // ################### static methods
    static find() {
        return MinutesCollection.find.apply(MinutesCollection, arguments);
    }

    static findOne() {
        return MinutesCollection.findOne.apply(MinutesCollection, arguments);
    }

    static findAllIn(MinutesIDArray, limit) {
        console.log("findAllIn: >"+MinutesIDArray+"<");
        if (!MinutesIDArray || MinutesIDArray.length == 0) {
            return [];
        }

        let options = {sort: {date: -1}};
        if (limit) {
            options["limit"] = limit;
        }
        return MinutesCollection.find(
            {_id: {$in: MinutesIDArray}},
            options);
    }

    static remove(id) {
        Meteor.call("minutes.remove", id)
    }

    // ################### object methods
    update (docPart) {
        Meteor.call("minutes.updateDocPart", this, docPart);
        _.extend(this, docPart);    // merge new doc fragment into this document
    }

    save (edit) {
        console.log("Minutes.save()");
        if (this.createdAt == undefined) {
            this.createdAt = new Date();
        }
        if (this._id && this._id != "") {
            Meteor.call("minutes.update", this);    // TODO - Method does not exist!
            if (edit) {
                Session.set("currentMinutesID", this._id);
            }
        } else {
            if (this.topics == undefined) {
                this.topics = [];
            }
            Meteor.call("minutes.insert", this);
        }
    }

    toString () {
        return "Minutes: "+JSON.stringify(this, null, 4);
    }

    log () {
        console.log(this.toString());
    }

    parentMeetingSeries () {
        return MeetingSeries.findOne(this.meetingSeries_id);
    }

    // This also does a minimal update of collection!
    removeTopicWithID(id) {
        let i = -1;
        for (i = 0; i < this.topics.length; i++) {
            if (id === this.topics[i]._id) {
                break;
            }
        }
        if (i > -1) {
            this.topics.splice(i, 1);
            this.update({topics: this.topics}); // update only topics array!
        }
    }
}
<commit_msg>Remove obsolete comment<commit_after>/**
 * Created by wok on 16.04.16.
 */

import { Meteor } from 'meteor/meteor';
import { MinutesCollection } from './collections/minutes_private';
import { MeetingSeries } from './meetingseries'

export class Minutes {
    constructor(source) {   // constructs obj from Mongo ID or Mongo document
        if (! source)
            return;

        if (typeof source === 'string') {   // we may have an ID here.
            source = Minutes.findOne(source);
        }
        if (typeof source === 'object') { // inject class methods in plain collection document
            _.extend(this, source);
        }
    }

    // ################### static methods
    static find() {
        return MinutesCollection.find.apply(MinutesCollection, arguments);
    }

    static findOne() {
        return MinutesCollection.findOne.apply(MinutesCollection, arguments);
    }

    static findAllIn(MinutesIDArray, limit) {
        console.log("findAllIn: >"+MinutesIDArray+"<");
        if (!MinutesIDArray || MinutesIDArray.length == 0) {
            return [];
        }

        let options = {sort: {date: -1}};
        if (limit) {
            options["limit"] = limit;
        }
        return MinutesCollection.find(
            {_id: {$in: MinutesIDArray}},
            options);
    }

    static remove(id) {
        Meteor.call("minutes.remove", id)
    }

    // ################### object methods
    update (docPart) {
        Meteor.call("minutes.updateDocPart", this, docPart);
        _.extend(this, docPart);    // merge new doc fragment into this document
    }

    save (edit) {
        console.log("Minutes.save()");
        if (this.createdAt == undefined) {
            this.createdAt = new Date();
        }
        if (this._id && this._id != "") {
            Meteor.call("minutes.update", this);
            if (edit) {
                Session.set("currentMinutesID", this._id);
            }
        } else {
            if (this.topics == undefined) {
                this.topics = [];
            }
            Meteor.call("minutes.insert", this);
        }
    }

    toString () {
        return "Minutes: "+JSON.stringify(this, null, 4);
    }

    log () {
        console.log(this.toString());
    }

    parentMeetingSeries () {
        return MeetingSeries.findOne(this.meetingSeries_id);
    }

    // This also does a minimal update of collection!
    removeTopicWithID(id) {
        let i = -1;
        for (i = 0; i < this.topics.length; i++) {
            if (id === this.topics[i]._id) {
                break;
            }
        }
        if (i > -1) {
            this.topics.splice(i, 1);
            this.update({topics: this.topics}); // update only topics array!
        }
    }
}
<|endoftext|>


<commit_before>describe("getItem()", function(){
    it("should return item data", function(){
        runs(function() {
            flag = false;

            PokeApi.getItem(3).then(function(response){
                if(response.category.name === "standard-balls" && response.name === "great-ball"){
                   flag=true;
                };
            });
        });

        waitsFor(function() {
            return flag;
        }, "correct item data should have been returned", 10000);
    })

})

describe("getItemAttribute()", function(){
    it("should return item attribute data", function(){
        runs(function() {
            flag = false;

            PokeApi.getItemAttribute(2).then(function(response){
                if(response.descriptions[0].description === "Consumed when used"){
                   flag=true;
                };
            });
        });

        waitsFor(function() {
            return flag;
        }, "correct item attribute data should have been returned", 10000);
    })

})

describe("getItemCategory()", function(){
    it("should return item category data", function(){
        runs(function() {
            flag = false;

            PokeApi.getItemCategory(4).then(function(response){
                if(response.names.name === "other" && response.pocket.name === "berries"){
                   flag=true;
                };
            });
        });

        waitsFor(function() {
            return flag;
        }, "correct item category data should have been returned", 10000);
    })

})

describe("getItemFlingEffect()", function(){
    it("should return item fling effect data", function(){
        runs(function() {
            flag = false;

            PokeApi.getItemFlingEffect(5).then(function(response){
                if(response.effect_entries[0].effect === "Paralyzes the target."){
                   flag=true;
                };
            });
        });

        waitsFor(function() {
            return flag;
        }, "correct item fling data data should have been returned", 10000);
    })

})

describe("getItemPocket()", function(){
    it("should return item pocket data", function(){
        runs(function() {
            flag = false;

            PokeApi.getItemPocket(7).then(function(response){
                if(response.id === 7 && response.name === "battle"){
                   flag=true;
                };
            });
        });

        waitsFor(function() {
            return flag;
        }, "correct item pocket data should have been returned", 10000);
    })

})
<commit_msg>Fix getItemCategory test<commit_after>describe("getItem()", function(){
    it("should return item data", function(){
        runs(function() {
            flag = false;

            PokeApi.getItem(3).then(function(response){
                if(response.category.name === "standard-balls" && response.name === "great-ball"){
                   flag=true;
                };
            });
        });

        waitsFor(function() {
            return flag;
        }, "correct item data should have been returned", 10000);
    })

})

describe("getItemAttribute()", function(){
    it("should return item attribute data", function(){
        runs(function() {
            flag = false;

            PokeApi.getItemAttribute(2).then(function(response){
                if(response.descriptions[0].description === "Consumed when used"){
                   flag=true;
                };
            });
        });

        waitsFor(function() {
            return flag;
        }, "correct item attribute data should have been returned", 10000);
    })

})

describe("getItemCategory()", function(){
    it("should return item category data", function(){
        runs(function() {
            flag = false;

            PokeApi.getItemCategory(4).then(function(response){
                if(response.name === "other" && response.pocket.name === "berries"){
                   flag=true;
                };
            });
        });

        waitsFor(function() {
            return flag;
        }, "correct item category data should have been returned", 10000);
    })

})

describe("getItemFlingEffect()", function(){
    it("should return item fling effect data", function(){
        runs(function() {
            flag = false;

            PokeApi.getItemFlingEffect(5).then(function(response){
                if(response.effect_entries[0].effect === "Paralyzes the target."){
                   flag=true;
                };
            });
        });

        waitsFor(function() {
            return flag;
        }, "correct item fling data data should have been returned", 10000);
    })

})

describe("getItemPocket()", function(){
    it("should return item pocket data", function(){
        runs(function() {
            flag = false;

            PokeApi.getItemPocket(7).then(function(response){
                if(response.id === 7 && response.name === "battle"){
                   flag=true;
                };
            });
        });

        waitsFor(function() {
            return flag;
        }, "correct item pocket data should have been returned", 10000);
    })

})
<|endoftext|>


<commit_before>describe('Initial Setup', function() {
  it('can be completed', function() {
    cy.visit('/')

    cy.get('h2').contains('Welcome to Polaris!')
    cy.get('button.submit').click()

    cy.get('h2').contains('Mount Points')
    cy.get('button.submit').should('be.disabled')
    cy.get('input#source').type('test/collection')
    cy.get('input#name').type('test_music')
    cy.get('button.submit').should('not.be.disabled')
    cy.get('button.submit').click()

    cy.get('h2').contains('User Account')
    cy.get('button.submit').should('be.disabled')
    cy.get('input#username').type('testUser')
    cy.get('input#password').type('testPassword')
    cy.get('input#password_confirm').type('testPassword')
    cy.get('button.submit').should('not.be.disabled')
    cy.get('button.submit').click()

    cy.get('main menu').should('exist')
  })
})
<commit_msg>Fixed test<commit_after>describe('Initial Setup', function() {
  it('can be completed', function() {
    cy.visit('/')

    cy.get('h2').contains('Welcome to Polaris!')
    cy.get('button.submit').click()

    cy.get('h2').contains('Mount Sources')
    cy.get('button.submit').should('be.disabled')
    cy.get('input#source').type('test/collection')
    cy.get('input#name').type('test_music')
    cy.get('button.submit').should('not.be.disabled')
    cy.get('button.submit').click()

    cy.get('h2').contains('User Account')
    cy.get('button.submit').should('be.disabled')
    cy.get('input#username').type('testUser')
    cy.get('input#password').type('testPassword')
    cy.get('input#password_confirm').type('testPassword')
    cy.get('button.submit').should('not.be.disabled')
    cy.get('button.submit').click()

    cy.get('main menu').should('exist')
  })
})
<|endoftext|>


<commit_before>// A lot of this has been ripped from spotcheck
// But I've hacked it to pieces to do something else
// https://github.com/spanishdict/spotcheck

// Node modules
var fs = require('fs')
var path = require('path')

// Package modules
var zlib = require('zlib')
var split = require('split')
var async = require('async')
var moment = require('moment')
var AWS = require('aws-sdk')

/**
 * Logs
 *
 * @param {Object} s3Config which contains s3 `key` & `secret`
 * @param {logConfig} logConfig which contains `bucket`, `prefix` & `format`
 * @return {Object}
 */
module.exports = function(s3Config, logConfig) {

  AWS.config.update({
    "accessKeyId": s3Config.key,
    "secretAccessKey": s3Config.secret
  })

  var s3 = new AWS.S3()

  // Init
  var app = {}
  var formats = require('./formats')
  var rootDir = process.cwd()
  var start = moment('2015-04-08')
  var end = null
  var format  = formats[logConfig.format]

  var results = []

  /**
   * Download from S3, gunzip, and convert to JSON.
   *
   * @param {String} file path
   * @param {Function} callback
   * @return void
   */
  app.processFile = function(filePath, cb) {
    if (filePath && filePath.length > 1) {
      console.log("processing", filePath)

      var params = {
        Bucket: logConfig.bucket,
        Key: filePath
      }

      var read = s3.getObject(params).createReadStream()
      var gunzip = zlib.createGunzip()

      var reader = read
      if (format.gzip) {
        read.pipe(gunzip)
        reader = gunzip
      }

      var json = reader.pipe(split())
      // split() makes each line a chunk
      json.on('data', function(row) {
        var data = format.toJson(row)
        if(data) results.push(data)
      })

      json.on('error', function(err) {
        cb(err)
      })

      json.on('end', function() {
        cb()
      })

    }
  }

  /**
   * List files in bucket that match prefix.
   *
   * @param {Object} params
   * @param {Function} callback
   * @return void
   */
  app.listFiles = function(params, cb) {
    s3.listObjects(params, function(err, data) {
      if (err) return console.log(err)

      // Get list of file paths.
      var paths = []
      data.Contents.forEach(function(filePath) {
        paths.push(filePath.Key)
      })

      // Iterate to the next batch.
      var lastPath = paths[paths.length - 1]
      if (data.IsTruncated) {
        params.Marker = lastPath
        var endMarker = logConfig.prefix + end.format(format.fileDateFormat)
        if (lastPath < endMarker) {
          app.listFiles(params, function(morePaths){
            paths = paths.concat(morePaths)
            cb(paths)
          })
        } else {
          cb(paths)
        }
      } else {
        cb(paths)
      }
    })
  }

  /**
   * Run
   *
   * @param {Function} callback
   * @return void
   */
  app.run = function(callback) {

    var listParams = {
      Bucket: logConfig.bucket,
      MaxKeys: 1000,
      Prefix: logConfig.prefix + start.format(format.fileDateFormat)
    }

    app.listFiles(listParams, function(paths){
      // Process each file path.
      async.eachSeries(paths, app.processFile, function(err) {
        if (err) callback(err)

        return callback(null, results)
      })
    })
  }

  return app
}
<commit_msg>Custom logger & run() callback returns paths<commit_after>// A lot of this has been ripped from spotcheck
// But I've hacked it to pieces to do something else
// https://github.com/spanishdict/spotcheck

// Node modules
var fs = require('fs')
var path = require('path')

// Package modules
var zlib = require('zlib')
var split = require('split')
var async = require('async')
var moment = require('moment')
var AWS = require('aws-sdk')

/**
 * Logs
 *
 * @param {Object} s3Config which contains s3 `key` & `secret`
 * @param {Object} logConfig which contains `bucket`, `prefix` & `format`
 * @param {Object} Custom logger
 * @return {Object}
 */
module.exports = function(s3Config, logConfig, log) {

  if( ! log) {
    log = {
      verbose: console.log,
      error: console.error
    }
  }

  if( ! s3Config) {
    log.error('s3Config is required')
    return false
  }

  if( ! logConfig) {
    log.error('logConfig is required')
    return false
  }

  AWS.config.update({
    "accessKeyId": s3Config.key,
    "secretAccessKey": s3Config.secret
  })

  var s3 = new AWS.S3()

  // Init
  var app = {}
  var formats = require('./formats')
  var rootDir = process.cwd()
  var start = moment('2015-04-08')
  var end = null
  var format  = formats[logConfig.format]

  var results = []

  /**
   * Download from S3, gunzip, and convert to JSON.
   *
   * @param {String} file path
   * @param {Function} callback
   * @return void
   */
  app.processFile = function(filePath, cb) {
    if (filePath && filePath.length > 1) {
      log.verbose('processing', filePath)

      var params = {
        Bucket: logConfig.bucket,
        Key: filePath
      }

      var read = s3.getObject(params).createReadStream()
      var gunzip = zlib.createGunzip()

      var reader = read

      if (format.gzip) {
        read.pipe(gunzip)
        reader = gunzip
      }

      var json = reader.pipe(split())
      // split() makes each line a chunk
      json.on('data', function(row) {
        var data = format.toJson(row)
        if(data) results.push(data)
      })

      json.on('error', function(err) {
        cb(err)
      })

      json.on('end', function() {
        cb()
      })

    }
  }

  /**
   * List files in bucket that match prefix.
   *
   * @param {Object} params
   * @param {Function} callback
   * @return void
   */
  app.listFiles = function(params, cb) {
    s3.listObjects(params, function(err, data) {
      if (err) return log.error(err)

      // Get list of file paths.
      var paths = []
      data.Contents.forEach(function(filePath) {
        paths.push(filePath.Key)
      })

      // Iterate to the next batch.
      var lastPath = paths[paths.length - 1]
      if (data.IsTruncated) {
        params.Marker = lastPath
        var endMarker = logConfig.prefix + end.format(format.fileDateFormat)
        if (lastPath < endMarker) {
          app.listFiles(params, function(morePaths){
            paths = paths.concat(morePaths)
            cb(paths)
          })
        } else {
          cb(paths)
        }
      } else {
        cb(paths)
      }
    })
  }

  /**
   * Run
   *
   * @param {Function} callback
   * @return void
   */
  app.run = function(callback) {

    var listParams = {
      Bucket: logConfig.bucket,
      MaxKeys: 1000,
      Prefix: logConfig.prefix + start.format(format.fileDateFormat)
    }

    app.listFiles(listParams, function(paths){
      // Process each file path.
      async.eachSeries(paths, app.processFile, function(err) {
        if (err) callback(err)

        return callback(null, results, paths)
      })
    })
  }

  return app
}
<|endoftext|>


<commit_before>function I18nKeyStore(options){
  options = options || {}
  this.scope = options.scope;
  this.translations = {};
}

I18nKeyStore.prototype.set = function(key, value){
  if (key.indexOf('#') !== -1){
    key = key.replace('#', '');
  } else if (this.scope) {
    key = this.scope + '.' + key;
  }
  var path = key.split('.');
  var context = this.expandPath(path, key);
  var finalKey = path[path.length - 1];

  if (!context[finalKey]) {
    context[finalKey] = value;
  } else {
    if (typeof context[finalKey] === 'object') {
      throw new Error(key + ' used as both scope and a key');
    }
    throw new Error('cannot reuse key ' + key);
  }
};

I18nKeyStore.prototype.expandPath = function(path, originalKey){
  var trans = this.translations;

  path = path.slice(0, -1);

  path.forEach(function(key){
    if (typeof trans[key] === 'string') {
      throw new Error(originalKey + ' used as both scope and a key');
    }
    trans = trans[key] = {};
  });
  return trans;
};

export default I18nKeyStore;
<commit_msg>dont overwrite nested objects in i18n key store<commit_after>function I18nKeyStore(options){
  options = options || {}
  this.scope = options.scope;
  this.translations = {};
}

I18nKeyStore.prototype.set = function(key, value){
  if (key.indexOf('#') !== -1){
    key = key.replace('#', '');
  } else if (this.scope) {
    key = this.scope + '.' + key;
  }
  var path = key.split('.');
  var context = this.expandPath(path, key);
  var finalKey = path[path.length - 1];

  if (!context[finalKey]) {
    context[finalKey] = value;
  } else {
    if (typeof context[finalKey] === 'object') {
      throw new Error(key + ' used as both scope and a key');
    }
    throw new Error('cannot reuse key ' + key);
  }
};

I18nKeyStore.prototype.expandPath = function(path, originalKey){
  var trans = this.translations;

  path = path.slice(0, -1);

  path.forEach(function(key){
    if (typeof trans[key] === 'string') {
      throw new Error(originalKey + ' used as both scope and a key');
    }
    trans = trans[key] = trans[key] || {};
  });
  return trans;
};

export default I18nKeyStore;
<|endoftext|>


<commit_before>(function($) {

  $.declare('imageUploader', {
    defaults: {
      action: window.location.href,
      method: 'POST',
      postKey: 'image',
      progressTemplate: '
Uploading...
',
      completeTemplate: '',
      allow: ['jpg', 'png', 'bmp', 'gif', 'jpeg'],
      processData: null,
      zIndex: 2
    },

    init: function() {
      var self = this;

      this.el.css('cursor', 'pointer');

      var form = $('<form/>')
        .attr({
          action: this.action,
          method: this.method,
          enctype: 'multipart/form-data'
        })
        .appendTo('body');

      var input = $('<input/>')
        .attr({
          name: this.postKey,
          type: 'file'
        })
        .css({
          opacity: '0',
          cursor: 'pointer',
          position: 'absolute',
          zIndex: this.zIndex
        })
        .on('change', function(e) {
          var filename = e.target.value;
          var ext = filename.split('.').pop().toLowerCase();
          if ($.inArray(ext, self.allow) == -1) {
            alert('Please select a photo with a ' + self.allow.join(', ') + ' extension');
            return;
          }

          self.el.trigger('fileSelect');
          self.showProgress();
          form.submit();
        })
        .appendTo(form);

      form
        .framejax()
        .on('complete', function(e, results) {
          self.showComplete(results);
          self.el.trigger('complete', results);
        });

      this.el.on('mousemove', function(e) {
        var h = input.height();
        var w = input.width();
        if (typeof e.pageY == 'undefined' && typeof e.clientX == 'number' && document.documentElement) {
          e.pageX = e.clientX + document.documentElement.scrollLeft;
          e.pageY = e.clientY + document.documentElement.scrollTop;
        }
        input.css({
          top: e.pageY - (h / 2),
          left: e.pageX - (w - 30)
        });
      });
    },

    showProgress: function() {
      this.el.html(this.progressTemplate);
    },

    showComplete: function(data) {
      var img = (this.processData) ? this.processData(data) : data;
      if (!img) {
        return;
      }
      this.el
        .html(this.completeTemplate)
        .find('img')
          .attr('src', img);
    }

  });
})(window.jQuery);
<commit_msg>Added working dragndrop. Needs error handing, file type check, and general cleanup.<commit_after>(function($) {

  $.declare('imageUploader', {
    defaults: {
      action: window.location.href,
      method: 'POST',
      postKey: 'image',
      progressTemplate: '
Uploading...
',
      completeTemplate: '',
      allow: ['jpg', 'png', 'bmp', 'gif', 'jpeg'],
      processData: null,
      zIndex: 2,
      dropZone: 'html', //use 'this' for this.el
      updateProgress: function(event) {}
    },

    init: function() {
      var self = this;

      this.supportsFileApi = (typeof window.FileReader !== 'undefined');

      this.el.css('cursor', 'pointer');

      var form = $('<form/>')
        .attr({
          action: this.action,
          method: this.method,
          enctype: 'multipart/form-data'
        })
        .appendTo('body');

      var input = $('<input/>')
        .attr({
          name: this.postKey,
          type: 'file'
        })
        .css({
          opacity: '0',
          cursor: 'pointer',
          position: 'absolute',
          zIndex: this.zIndex
        })
        .on('change', function(e) {
          var filename = e.target.value;
          var ext = filename.split('.').pop().toLowerCase();
          if ($.inArray(ext, self.allow) == -1) {
            alert('Please select a photo with a ' + self.allow.join(', ') + ' extension');
            return;
          }

          self.el.trigger('fileSelect');
          self.showProgress();
          form.submit();
        })
        .appendTo(form);

      this.el.on('mousemove', function(e) {
        var h = input.height();
        var w = input.width();
        if (typeof e.pageY == 'undefined' && typeof e.clientX == 'number' && document.documentElement) {
          e.pageX = e.clientX + document.documentElement.scrollLeft;
          e.pageY = e.clientY + document.documentElement.scrollTop;
        }
        input.css({
          top: e.pageY - (h / 2),
          left: e.pageX - (w - 30)
        });
      });

      form
        .framejax()
        .on('complete', function(e, results) {
          self.showComplete(results);
          self.el.trigger('complete', results);
        });

      if(this.supportsFileApi) {
        if(this.dropZone === 'this') {
          this.dropZone = this.el;
        } else {
          this.dropZone = $(this.dropZone);
        }

        this.dropZone.bind('dragenter, dragover', function(event){
          event.stopPropagation();
          event.preventDefault();
        });

        this.dropZone.bind('drop', function(event) {
          event.stopPropagation();
          event.preventDefault();

          var files = event.originalEvent.dataTransfer.files;
          for (var i = 0, c= files.length; i < c; i++) {
            self.upload(files[i]);
          }
        });

      }
    },

    showProgress: function() {
      this.el.html(this.progressTemplate);
    },

    showComplete: function(data) {
      var img = (this.processData) ? this.processData(data) : data;
      if (!img) {
        return;
      }
      this.el
        .html(this.completeTemplate)
        .find('img')
          .attr('src', img);
    },

    upload: function(file) {
      var formData = new FormData();

      formData.append('image', file);

      var self = this;

      var xhr = new XMLHttpRequest();

      this.showProgress();

      xhr.open('POST', this.action, true);
      xhr.upload.onprogress = this.updateProgress;
      xhr.onload = function(event) {
        self.showComplete(this.responseText);
      };

      xhr.send(formData);
    }

  });
})(window.jQuery);
<|endoftext|>


<commit_before>'use babel'

import {Emitter, CompositeDisposable} from 'atom'
import Validate from './validate'
import Indie from './indie'

export default class IndieRegistry {
  constructor() {
    this.subscriptions = new CompositeDisposable()
    this.emitter = new Emitter()

    this.indieLinters = new Set()
    this.subscriptions.add(this.emitter)
  }

  register(linter) {
    Validate.linter(linter, true)
    const indieLinter = new Indie(linter)

    this.subscriptions.add(indieLinter)
    this.indieLinters.add(indieLinter)

    indieLinter.onDidDestroy(() => {
      this.indieLinters.delete(indieLinter)
    })
    indieLinter.onDidUpdateMessages(messages => {
      this.emitter.emit('did-update-messages', {linter: indieLinter, messages})
    })
    this.emit('observe', indieLinter)

    return indieLinter
  }
  unregister(indieLinter) {
    if (this.indieLinters.has(indieLinter)) {
      indieLinter.dispose()
    }
  }

  // Private method
  observe(callback) {
    this.indieLinters.forEach(callback)
    return this.subscriptions.add('observe', callback)
  }
  // Private method
  onDidUpdateMessages(callback) {
    return this.subscriptions.add('did-update-messages', callback)
  }

  dispose() {
    this.subscriptions.dispose()
  }
}
<commit_msg>:bug: Fix a typo<commit_after>'use babel'

import {Emitter, CompositeDisposable} from 'atom'
import Validate from './validate'
import Indie from './indie'

export default class IndieRegistry {
  constructor() {
    this.subscriptions = new CompositeDisposable()
    this.emitter = new Emitter()

    this.indieLinters = new Set()
    this.subscriptions.add(this.emitter)
  }

  register(linter) {
    Validate.linter(linter, true)
    const indieLinter = new Indie(linter)

    this.subscriptions.add(indieLinter)
    this.indieLinters.add(indieLinter)

    indieLinter.onDidDestroy(() => {
      this.indieLinters.delete(indieLinter)
    })
    indieLinter.onDidUpdateMessages(messages => {
      this.emitter.emit('did-update-messages', {linter: indieLinter, messages})
    })
    this.emit('observe', indieLinter)

    return indieLinter
  }
  unregister(indieLinter) {
    if (this.indieLinters.has(indieLinter)) {
      indieLinter.dispose()
    }
  }

  // Private method
  observe(callback) {
    this.indieLinters.forEach(callback)
    return this.emitter.on('observe', callback)
  }
  // Private method
  onDidUpdateMessages(callback) {
    return this.emitter.on('did-update-messages', callback)
  }

  dispose() {
    this.subscriptions.dispose()
  }
}
<|endoftext|>


<commit_before>#!/usr/bin/env node
"use strict";

require('pkginfo')(module, ['name', 'description', 'version']);

var child_process = require('child_process'),
	fs = require('fs'),
	path = require('path'),
	mkdirp = require('mkdirp'),
	which = require('which'),
	_ = require('lodash'),
	S = require('string'),
	program = require('commander'),
	datastore = require('./datastore');

program
	.version(exports.version)
	.option('-c, --config <file>', 'use a different user config file, defaults to ~/.config/ssmount.json');

program
	.command('list')
	.description('List the saved sshfs endpoints')
	.action(function() {
		datastore.setup(program);

		_(datastore.mounts.list())
			.sortBy('name')
			.each(function(mount) {
				console.log('%s %s', S(mount.name).padRight(10).s, mount.dest);
			});

		console.log("/ End of list");
	});

program
	.command('add <name> <dest>')
	.description('add new sshfs endpoints')
	.option('-f, --force', 'add endpoint even if name is already in use')
	.action(function(name, dest, o) {
		datastore.setup(program);

		if ( datastore.mounts.get(name) && !o.force ) {
			console.error("A mount by the name %s already exists", name);
			throw { exit: 1 };
		} else {
			datastore.mounts.add(name, dest);
			datastore.save();
		}
	});

program
	.command('rm <name>')
	.description('remove sshfs endpoints')
	.action(function(name) {
		datastore.setup(program);
		datastore.mounts.rm(name);
		datastore.save();
	});

program
	.command('mount <name>')
	.description('mount a sshfs endpoint')
	.action(function(name) {
		datastore.setup(program);

		var mount = datastore.mounts.get(name),
			cmdArgs = [];

		if ( !mount ) {
			console.error('/ There is no saved mount by the name %s', name);
			throw { exit: 1 };
		}

		cmdArgs.push(mount.dest);
		cmdArgs.push(mount.point);

		if ( !fs.existsSync(mount.point) ) {
			mkdirp.sync(mount.point);
		}

		child_process.spawn('sshfs', cmdArgs, { stdio: 'inherit' })
			.on('close', function(code) {
				if ( code > 0 ) {
					// Remove the directory if the mount failed
					fs.rmdirSync(mount.point);
					console.error('/ Mount failed');
					throw { exit: 1 };
				} else {
					console.log('/ %s mounted at %s', mount.name, mount.point);
				}
			})
			.on('error', function(err) {
				throw err;
			});
	});

program
	.command('unmount <name>')
	.description('unmount a mounted sshfs endpoint')
	.option('-f, --force', 'unmount even if in use')
	.action(function(name, o) {
		datastore.setup(program);

		var mount = datastore.mounts.get(name),
			cmdArgs = ['unmount'];

		if ( !mount ) {
			console.error('/ There is no saved mount by the name %s', name);
			throw { exit: 1 };
		}

		if ( o.force ) {
			cmdArgs.push('force');
		}

		cmdArgs.push(mount.point);

		if ( !fs.existsSync(mount.point) ) {
			console.warn('/ %s was not mounted', mount.name);
		} else {
			child_process.spawn('diskutil', cmdArgs, { stdio: 'inherit' })
				.on('close', function(code) {
					if ( code > 0 ) {
						console.error('/ Unmount failed');
						throw { exit: 1 };
					} else {
						fs.rmdirSync(mount.point);
						console.log('/ Unmount finished');
					}
				})
				.on('error', function(err) {
					throw err;
				});
		}
	});

// Only make `ssmount subl` available when the subl command has been installed
if ( which.sync('subl') ) {
	program
		.command('subl <name> [file]')
		.description('open the mount point (or a file within it) in Sublime Edit')
		.action(function(name, file) {
			datastore.setup(program);

			var mount = datastore.mounts.get(name),
				cmdArgs = [];

			if ( !mount ) {
				console.error('/ There is no saved mount by the name %s', name);
				throw { exit: 1 };
			}

			if ( file ) {
				cmdArgs.push(path.join(mount.point, file));
			} else {
				cmdArgs.push(mount.point);
			}

			if ( !fs.existsSync(mount.point) ) {
				console.error('/ %s is not mounted', mount.name);
			} else {
				child_process.spawn('subl', cmdArgs, { stdio: 'inherit' })
					.on('close', function(code) {
						if ( code > 0 ) {
							console.error('/ Failed');
							throw { exit: 1 };
						} else {
							console.log('/ Done');
						}
					})
					.on('error', function(err) {
						throw err;
					});
			}
		});
}

program
	.command('help [command]')
	.description('output usage information')
	.action(function(command) {
		if ( command ) {
			console.error("Sorry, per command help hasn't been implemented.");
		} else {
			program.help();
		}
	});

try {
	program.parse(process.argv);
} catch ( e ) {
	if ( e.exit ) {
		process.exit(1);
	} else {
		throw e;
	}
}

if ( process.argv.length <= 2 ) {
	program.help();
}
<commit_msg>exit 1 when doing `ssmount subl` on something that isn't mounted.<commit_after>#!/usr/bin/env node
"use strict";

require('pkginfo')(module, ['name', 'description', 'version']);

var child_process = require('child_process'),
	fs = require('fs'),
	path = require('path'),
	mkdirp = require('mkdirp'),
	which = require('which'),
	_ = require('lodash'),
	S = require('string'),
	program = require('commander'),
	datastore = require('./datastore');

program
	.version(exports.version)
	.option('-c, --config <file>', 'use a different user config file, defaults to ~/.config/ssmount.json');

program
	.command('list')
	.description('List the saved sshfs endpoints')
	.action(function() {
		datastore.setup(program);

		_(datastore.mounts.list())
			.sortBy('name')
			.each(function(mount) {
				console.log('%s %s', S(mount.name).padRight(10).s, mount.dest);
			});

		console.log("/ End of list");
	});

program
	.command('add <name> <dest>')
	.description('add new sshfs endpoints')
	.option('-f, --force', 'add endpoint even if name is already in use')
	.action(function(name, dest, o) {
		datastore.setup(program);

		if ( datastore.mounts.get(name) && !o.force ) {
			console.error("A mount by the name %s already exists", name);
			throw { exit: 1 };
		} else {
			datastore.mounts.add(name, dest);
			datastore.save();
		}
	});

program
	.command('rm <name>')
	.description('remove sshfs endpoints')
	.action(function(name) {
		datastore.setup(program);
		datastore.mounts.rm(name);
		datastore.save();
	});

program
	.command('mount <name>')
	.description('mount a sshfs endpoint')
	.action(function(name) {
		datastore.setup(program);

		var mount = datastore.mounts.get(name),
			cmdArgs = [];

		if ( !mount ) {
			console.error('/ There is no saved mount by the name %s', name);
			throw { exit: 1 };
		}

		cmdArgs.push(mount.dest);
		cmdArgs.push(mount.point);

		if ( !fs.existsSync(mount.point) ) {
			mkdirp.sync(mount.point);
		}

		child_process.spawn('sshfs', cmdArgs, { stdio: 'inherit' })
			.on('close', function(code) {
				if ( code > 0 ) {
					// Remove the directory if the mount failed
					fs.rmdirSync(mount.point);
					console.error('/ Mount failed');
					throw { exit: 1 };
				} else {
					console.log('/ %s mounted at %s', mount.name, mount.point);
				}
			})
			.on('error', function(err) {
				throw err;
			});
	});

program
	.command('unmount <name>')
	.description('unmount a mounted sshfs endpoint')
	.option('-f, --force', 'unmount even if in use')
	.action(function(name, o) {
		datastore.setup(program);

		var mount = datastore.mounts.get(name),
			cmdArgs = ['unmount'];

		if ( !mount ) {
			console.error('/ There is no saved mount by the name %s', name);
			throw { exit: 1 };
		}

		if ( o.force ) {
			cmdArgs.push('force');
		}

		cmdArgs.push(mount.point);

		if ( !fs.existsSync(mount.point) ) {
			console.warn('/ %s was not mounted', mount.name);
		} else {
			child_process.spawn('diskutil', cmdArgs, { stdio: 'inherit' })
				.on('close', function(code) {
					if ( code > 0 ) {
						console.error('/ Unmount failed');
						throw { exit: 1 };
					} else {
						fs.rmdirSync(mount.point);
						console.log('/ Unmount finished');
					}
				})
				.on('error', function(err) {
					throw err;
				});
		}
	});

// Only make `ssmount subl` available when the subl command has been installed
if ( which.sync('subl') ) {
	program
		.command('subl <name> [file]')
		.description('open the mount point (or a file within it) in Sublime Edit')
		.action(function(name, file) {
			datastore.setup(program);

			var mount = datastore.mounts.get(name),
				cmdArgs = [];

			if ( !mount ) {
				console.error('/ There is no saved mount by the name %s', name);
				throw { exit: 1 };
			}

			if ( file ) {
				cmdArgs.push(path.join(mount.point, file));
			} else {
				cmdArgs.push(mount.point);
			}

			if ( !fs.existsSync(mount.point) ) {
				console.error('/ %s is not mounted', mount.name);
				throw { exit: 1 };
			} else {
				child_process.spawn('subl', cmdArgs, { stdio: 'inherit' })
					.on('close', function(code) {
						if ( code > 0 ) {
							console.error('/ Failed');
							throw { exit: 1 };
						} else {
							console.log('/ Done');
						}
					})
					.on('error', function(err) {
						throw err;
					});
			}
		});
}

program
	.command('help [command]')
	.description('output usage information')
	.action(function(command) {
		if ( command ) {
			console.error("Sorry, per command help hasn't been implemented.");
		} else {
			program.help();
		}
	});

try {
	program.parse(process.argv);
} catch ( e ) {
	if ( e.exit ) {
		process.exit(1);
	} else {
		throw e;
	}
}

if ( process.argv.length <= 2 ) {
	program.help();
}
<|endoftext|>


<commit_before>'use babel'

/* @flow */

import { Emitter, CompositeDisposable } from 'atom'
import { indie as validateIndie, messages as validateMessages, messagesLegacy as validateMessagesLegacy } from './validate'
import { normalizeMessages, normalizeMessagesLegacy } from './helpers'
import Indie from './indie'
import type { Disposable } from 'atom'
import type { IndieConfig } from './types'

export default class IndieRegistry {
  emitter: Emitter;
  indieLinters: Set<Indie>;
  subscriptions: CompositeDisposable;

  constructor() {
    this.emitter = new Emitter()
    this.indieLinters = new Set()
    this.subscriptions = new CompositeDisposable()

    this.subscriptions.add(this.emitter)
  }

  register(config: IndieConfig, legacy: boolaen = false): Indie {
    if (!validateIndie(config)) {
      throw new Error('Error registering Indie Linter')
    }
    const indieLinter = new Indie(config)

    this.subscriptions.add(indieLinter)
    this.indieLinters.add(indieLinter)

    indieLinter.onDidDestroy(() => {
      this.indieLinters.delete(indieLinter)
      this.subscriptions.remove(indieLinter)
    })
    indieLinter.onDidUpdateMessages(messages => {
      const validity = atom.inDevMode() ? (!legacy ? validateMessages(indieLinter.name, messages) : validateMessagesLegacy(indieLinter.name, messages)) : true
      if (validity) {
        if (!legacy) {
          normalizeMessages(indieLinter.name, messages)
        } else {
          normalizeMessagesLegacy(indieLinter.name, messages)
        }
        this.emitter.emit('did-update-messages', { linter: indieLinter, messages })
      }
    })
    this.emitter.emit('observe', indieLinter)

    return indieLinter
  }

  // Private methods
  observe(callback: Function): Disposable {
    this.indieLinters.forEach(callback)
    return this.emitter.on('observe', callback)
  }
  onDidUpdateMessages(callback: Function): Disposable {
    return this.emitter.on('did-update-messages', callback)
  }
  dispose() {
    this.subscriptions.dispose()
  }
}
<commit_msg>:bug: Fix a typo<commit_after>'use babel'

/* @flow */

import { Emitter, CompositeDisposable } from 'atom'
import { indie as validateIndie, messages as validateMessages, messagesLegacy as validateMessagesLegacy } from './validate'
import { normalizeMessages, normalizeMessagesLegacy } from './helpers'
import Indie from './indie'
import type { Disposable } from 'atom'
import type { IndieConfig } from './types'

export default class IndieRegistry {
  emitter: Emitter;
  indieLinters: Set<Indie>;
  subscriptions: CompositeDisposable;

  constructor() {
    this.emitter = new Emitter()
    this.indieLinters = new Set()
    this.subscriptions = new CompositeDisposable()

    this.subscriptions.add(this.emitter)
  }

  register(config: IndieConfig, legacy: boolean = false): Indie {
    if (!validateIndie(config)) {
      throw new Error('Error registering Indie Linter')
    }
    const indieLinter = new Indie(config)

    this.subscriptions.add(indieLinter)
    this.indieLinters.add(indieLinter)

    indieLinter.onDidDestroy(() => {
      this.indieLinters.delete(indieLinter)
      this.subscriptions.remove(indieLinter)
    })
    indieLinter.onDidUpdateMessages(messages => {
      const validity = atom.inDevMode() ? (!legacy ? validateMessages(indieLinter.name, messages) : validateMessagesLegacy(indieLinter.name, messages)) : true
      if (validity) {
        if (!legacy) {
          normalizeMessages(indieLinter.name, messages)
        } else {
          normalizeMessagesLegacy(indieLinter.name, messages)
        }
        this.emitter.emit('did-update-messages', { linter: indieLinter, messages })
      }
    })
    this.emitter.emit('observe', indieLinter)

    return indieLinter
  }

  // Private methods
  observe(callback: Function): Disposable {
    this.indieLinters.forEach(callback)
    return this.emitter.on('observe', callback)
  }
  onDidUpdateMessages(callback: Function): Disposable {
    return this.emitter.on('did-update-messages', callback)
  }
  dispose() {
    this.subscriptions.dispose()
  }
}
<|endoftext|>


<commit_before>'use strict';

/**
 * Check to if the given value is mergable.
 *
 * @param {*} value
 *
 * @return {Boolean}  Returns true if the object can be merged, false otherwise.
 */
function canMerge(value) {
  return value !== null && typeof value === 'object' && !Array.isArray(value);
}

/**
 * Check if the given value will overwrite other values during a merge.
 *
 * @param {*} value
 *
 * @return {Boolean} Returns true if the value will overwrite others, false otherwise.
 */
function canOverwriteWith(value) {
  return value !== null && value !== undefined && !(value instanceof Function);
}

/**
 * Perform a deep merge of objects based on key.
 * Warning! Destination is modified in place.
 *
 * @param {Object} source       Object from which keys are copied out of
 * @param {Object} destination  Object from which keys are copied into
 */
function merge(source, destination) {
  if (canMerge(source)) {
    for (const key in source) {
      if (source.hasOwnProperty(key)) {
        const sourceValue = source[key];
        const destinationValue = destination[key];

        if (canOverwriteWith(sourceValue)) {
          if (canMerge(sourceValue) && canMerge(destinationValue)) {
            merge(sourceValue, destinationValue);
          } else {
            destination[key] = sourceValue; // eslint-disable-line no-param-reassign
          }
        }
      }
    }
  } else if (canOverwriteWith(source)) {
    destination = source; // eslint-disable-line no-param-reassign
  }
}

class Storage {
  /**
   * The storage engine maintains a merged set of properties retrived from
   * source plugins.
   */
  constructor() {
    this.properties = Object.create(null);
    this.sources = [];
  }

  /**
   * Update cached properties by merging values from source plugins.
   */
  update() {
    const properties = Object.create(null);

    this.sources.forEach((source) => {
      merge(source.properties, properties);
    });
    this.properties = properties;
  }

  /**
   * Register a named source plugin.
   *
   * @param {Object} plugin
   */
  register(plugin) {
    if (canMerge(plugin) && plugin.hasOwnProperty('properties')) {
      this.sources.push(plugin);
    }
  }
}

module.exports = Storage;
<commit_msg>Marshal a plugin's properties before merging them.<commit_after>'use strict';

/**
 * Check to if the given value is mergable.
 *
 * @param {*} value
 *
 * @return {Boolean}  Returns true if the object can be merged, false otherwise.
 */
function canMerge(value) {
  return value !== null && typeof value === 'object' && !Array.isArray(value);
}

/**
 * Check if the given value will overwrite other values during a merge.
 *
 * @param {*} value
 *
 * @return {Boolean} Returns true if the value will overwrite others, false otherwise.
 */
function canOverwriteWith(value) {
  return value !== null && value !== undefined && !(value instanceof Function);
}

/**
 * Perform a deep merge of objects based on key.
 * Warning! Destination is modified in place.
 *
 * @param {Object} source       Object from which keys are copied out of
 * @param {Object} destination  Object from which keys are copied into
 */
function merge(source, destination) {
  if (canMerge(source)) {
    for (const key in source) {
      if (source.hasOwnProperty(key)) {
        const sourceValue = source[key];
        const destinationValue = destination[key];

        if (canOverwriteWith(sourceValue)) {
          if (canMerge(sourceValue) && canMerge(destinationValue)) {
            merge(sourceValue, destinationValue);
          } else {
            destination[key] = sourceValue; // eslint-disable-line no-param-reassign
          }
        }
      }
    }
  } else if (canOverwriteWith(source)) {
    destination = source; // eslint-disable-line no-param-reassign
  }
}

class Storage {
  /**
   * The storage engine maintains a merged set of properties retrived from
   * source plugins.
   */
  constructor() {
    this.properties = Object.create(null);
    this.sources = [];
  }

  /**
   * Update cached properties by merging values from source plugins.
   */
  update() {
    const properties = Object.create(null);

    this.sources.forEach((source) => {
      // Marshalling forces the pulgin's properties to merge as JSON.
      const marshalledProperties = JSON.parse(JSON.stringify(source.properties));

      merge(marshalledProperties, properties);
    });
    this.properties = properties;
  }

  /**
   * Register a named source plugin.
   *
   * @param {Object} plugin
   */
  register(plugin) {
    if (canMerge(plugin) && plugin.hasOwnProperty('properties')) {
      this.sources.push(plugin);
    }
  }
}

module.exports = Storage;
<|endoftext|>


<commit_before>var util = require('../../util');
var enxtend = require('util')._extend;
var WhistleTransform = util.WhistleTransform;

function removeUnsupportsHeaders(headers) {//只保留支持的zip格式：gzip、deflate
	if (!headers || !headers['accept-encoding']) {
		return;
	}
	var list = headers['accept-encoding'].split(/\s*,\s*/g);
	var acceptEncoding = [];
	for (var i = 0, len = list.length; i < len; i++) {
		var ae = list[i].toLowerCase();
		if (ae && (ae == 'gzip' || ae == 'deflate')) {
			acceptEncoding.push(ae);
		}
	}

	if (acceptEncoding = acceptEncoding.join(', ')) {
		headers['accept-encoding'] = acceptEncoding;
	} else {
		delete headers['accept-encoding'];
	}
}

/**
 * 处理请求数据
 *
 * @param req：method、body、headers，top，bottom，speed、delay，charset,timeout
 * @param data
 */
function handleReq(req, data) {
	if (!data) {
		return;
	}

	req.rules.req.value = data;
	req.method = data.method || req.method;
	req.timeout = data.timeout;
	enxtend(req.headers, data.headers);
	req.add(new WhistleTransform(data));
}

module.exports = function(req, res, next) {
	util.parseFileToJson(req.rules.req && req.rules.req.url,
			function(err, data) {
		handleReq(req, data);
		removeUnsupportsHeaders(req.headers);
		next();
	});
};<commit_msg>whistle transform<commit_after>var util = require('../../util');
var enxtend = require('util')._extend;
var WhistleTransform = util.WhistleTransform;

function removeUnsupportsHeaders(headers) {//只保留支持的zip格式：gzip、deflate
	if (!headers || !headers['accept-encoding']) {
		return;
	}
	var list = headers['accept-encoding'].split(/\s*,\s*/g);
	var acceptEncoding = [];
	for (var i = 0, len = list.length; i < len; i++) {
		var ae = list[i].toLowerCase();
		if (ae && (ae == 'gzip' || ae == 'deflate')) {
			acceptEncoding.push(ae);
		}
	}

	if (acceptEncoding = acceptEncoding.join(', ')) {
		headers['accept-encoding'] = acceptEncoding;
	} else {
		delete headers['accept-encoding'];
	}
}

/**
 * 处理请求数据
 *
 * @param req：method、body、headers，top，bottom，speed、delay，charset,timeout
 * @param data
 */
function handleReq(req, data) {
	if (!data) {
		return;
	}

	req.rules.req.value = data;
	req.method = data.method || req.method;
	req.timeout = parseInt(data.timeout, 10);
	enxtend(req.headers, data.headers);
	req.add(new WhistleTransform(data));
}

module.exports = function(req, res, next) {
	util.parseFileToJson(req.rules.req && req.rules.req.url,
			function(err, data) {
		handleReq(req, data);
		removeUnsupportsHeaders(req.headers);
		next();
	});
};<|endoftext|>


<commit_before>/* Copyright (c) 2006-2012 by OpenLayers Contributors (see authors.txt for
 * full list of contributors). Published under the 2-clause BSD license.
 * See license.txt in the OpenLayers distribution or repository for the
 * full text of the license. */

/**
 * @requires OpenLayers/Control.js
 * @requires OpenLayers/Events/buttonclick.js
 */

/**
 * Class: OpenLayers.Control.Zoom
 * The Zoom control is a pair of +/- links for zooming in and out.
 *
 * Inherits from:
 *  - <OpenLayers.Control>
 */
OpenLayers.Control.Zoom = OpenLayers.Class(OpenLayers.Control, {

    /**
     * APIProperty: zoomInText
     * {String}
     * Text for zoom-in link.  Default is "+".
     */
    zoomInText: "+",

    /**
     * APIProperty: zoomInId
     * {String}
     * Instead of having the control create a zoom in link, you can provide
     *     the identifier for an anchor element already added to the document.
     *     By default, an element with id "olZoomInLink" will be searched for
     *     and used if it exists.
     */
    zoomInId: "olZoomInLink",

    /**
     * APIProperty: zoomOutText
     * {String}
     * Text for zoom-out link.  Default is "−".
     */
    zoomOutText: "−",

    /**
     * APIProperty: zoomOutId
     * {String}
     * Instead of having the control create a zoom out link, you can provide
     *     the identifier for an anchor element already added to the document.
     *     By default, an element with id "olZoomOutLink" will be searched for
     *     and used if it exists.
     */
    zoomOutId: "olZoomOutLink",

    /**
     * Method: draw
     *
     * Returns:
     * {DOMElement} A reference to the DOMElement containing the zoom links.
     */
    draw: function() {
        var div = OpenLayers.Control.prototype.draw.apply(this),
            links = this.getOrCreateLinks(div),
            zoomIn = links.zoomIn,
            zoomOut = links.zoomOut,
            eventsInstance = this.map.events;

        if (zoomOut.parentNode !== div) {
            eventsInstance = this.events;
            eventsInstance.attachToElement(zoomOut.parentNode);
        }
        eventsInstance.register("buttonclick", this, this.onZoomClick);

        this.zoomInLink = zoomIn;
        this.zoomOutLink = zoomOut;
        return div;
    },

    /**
     * Method: getOrCreateLinks
     *
     * Parameters:
     * el - {DOMElement}
     *
     * Return:
     * {Object} Object with zoomIn and zoomOut properties referencing links.
     */
    getOrCreateLinks: function(el) {
        var zoomIn = document.getElementById(this.zoomInId),
            zoomOut = document.getElementById(this.zoomOutId);
        if (!zoomIn) {
            zoomIn = document.createElement("a");
            zoomIn.href = "#zoomIn";
            zoomIn.appendChild(document.createTextNode(this.zoomInText));
            zoomIn.className = "olControlZoomIn";
            el.appendChild(zoomIn);
        }
        OpenLayers.Element.addClass(zoomIn, "olButton");
        if (!zoomOut) {
            zoomOut = document.createElement("a");
            zoomOut.href = "#zoomOut";
            zoomOut.appendChild(document.createTextNode(this.zoomOutText));
            zoomOut.className = "olControlZoomOut";
            el.appendChild(zoomOut);
        }
        OpenLayers.Element.addClass(zoomOut, "olButton");
        return {
            zoomIn: zoomIn, zoomOut: zoomOut
        };
    },

    /**
     * Method: onZoomClick
     * Called when zoomin/out link is clicked.
     */
    onZoomClick: function(evt) {
        var button = evt.buttonElement;
        if (button === this.zoomInLink) {
            this.map.zoomIn();
        } else if (button === this.zoomOutLink) {
            this.map.zoomOut();
        }
    },

    /**
     * Method: destroy
     * Clean up.
     */
    destroy: function() {
        if (this.map) {
            this.map.events.unregister("buttonclick", this, this.onZoomClick);
        }
        delete this.zoomInLink;
        delete this.zoomOutLink;
        OpenLayers.Control.prototype.destroy.apply(this);
    },

    CLASS_NAME: "OpenLayers.Control.Zoom"
});
<commit_msg>Using the safe unicode representation of the minus sign.<commit_after>/* Copyright (c) 2006-2012 by OpenLayers Contributors (see authors.txt for
 * full list of contributors). Published under the 2-clause BSD license.
 * See license.txt in the OpenLayers distribution or repository for the
 * full text of the license. */

/**
 * @requires OpenLayers/Control.js
 * @requires OpenLayers/Events/buttonclick.js
 */

/**
 * Class: OpenLayers.Control.Zoom
 * The Zoom control is a pair of +/- links for zooming in and out.
 *
 * Inherits from:
 *  - <OpenLayers.Control>
 */
OpenLayers.Control.Zoom = OpenLayers.Class(OpenLayers.Control, {

    /**
     * APIProperty: zoomInText
     * {String}
     * Text for zoom-in link.  Default is "+".
     */
    zoomInText: "+",

    /**
     * APIProperty: zoomInId
     * {String}
     * Instead of having the control create a zoom in link, you can provide
     *     the identifier for an anchor element already added to the document.
     *     By default, an element with id "olZoomInLink" will be searched for
     *     and used if it exists.
     */
    zoomInId: "olZoomInLink",

    /**
     * APIProperty: zoomOutText
     * {String}
     * Text for zoom-out link.  Default is "\u2212".
     */
    zoomOutText: "\u2212",

    /**
     * APIProperty: zoomOutId
     * {String}
     * Instead of having the control create a zoom out link, you can provide
     *     the identifier for an anchor element already added to the document.
     *     By default, an element with id "olZoomOutLink" will be searched for
     *     and used if it exists.
     */
    zoomOutId: "olZoomOutLink",

    /**
     * Method: draw
     *
     * Returns:
     * {DOMElement} A reference to the DOMElement containing the zoom links.
     */
    draw: function() {
        var div = OpenLayers.Control.prototype.draw.apply(this),
            links = this.getOrCreateLinks(div),
            zoomIn = links.zoomIn,
            zoomOut = links.zoomOut,
            eventsInstance = this.map.events;

        if (zoomOut.parentNode !== div) {
            eventsInstance = this.events;
            eventsInstance.attachToElement(zoomOut.parentNode);
        }
        eventsInstance.register("buttonclick", this, this.onZoomClick);

        this.zoomInLink = zoomIn;
        this.zoomOutLink = zoomOut;
        return div;
    },

    /**
     * Method: getOrCreateLinks
     *
     * Parameters:
     * el - {DOMElement}
     *
     * Return:
     * {Object} Object with zoomIn and zoomOut properties referencing links.
     */
    getOrCreateLinks: function(el) {
        var zoomIn = document.getElementById(this.zoomInId),
            zoomOut = document.getElementById(this.zoomOutId);
        if (!zoomIn) {
            zoomIn = document.createElement("a");
            zoomIn.href = "#zoomIn";
            zoomIn.appendChild(document.createTextNode(this.zoomInText));
            zoomIn.className = "olControlZoomIn";
            el.appendChild(zoomIn);
        }
        OpenLayers.Element.addClass(zoomIn, "olButton");
        if (!zoomOut) {
            zoomOut = document.createElement("a");
            zoomOut.href = "#zoomOut";
            zoomOut.appendChild(document.createTextNode(this.zoomOutText));
            zoomOut.className = "olControlZoomOut";
            el.appendChild(zoomOut);
        }
        OpenLayers.Element.addClass(zoomOut, "olButton");
        return {
            zoomIn: zoomIn, zoomOut: zoomOut
        };
    },

    /**
     * Method: onZoomClick
     * Called when zoomin/out link is clicked.
     */
    onZoomClick: function(evt) {
        var button = evt.buttonElement;
        if (button === this.zoomInLink) {
            this.map.zoomIn();
        } else if (button === this.zoomOutLink) {
            this.map.zoomOut();
        }
    },

    /**
     * Method: destroy
     * Clean up.
     */
    destroy: function() {
        if (this.map) {
            this.map.events.unregister("buttonclick", this, this.onZoomClick);
        }
        delete this.zoomInLink;
        delete this.zoomOutLink;
        OpenLayers.Control.prototype.destroy.apply(this);
    },

    CLASS_NAME: "OpenLayers.Control.Zoom"
});
<|endoftext|>