<commit_before>var _ = require('lodash');
var async = require('async-chainable');
var barcodeReader = require('quagga').default;
var events = require('events');
var fs = require('fs');
var temp = require('temp');
var pdfImage = require('pdf-image').PDFImage;
var util = require('util');

function PDFDicer() {
	var dicer = this;

	dicer._defaults = {
		reader: {
			numOfWorkers: 0, // Always 0 in Node backend
			locate: true, // Search for the barcode on the page
			inputStream: {
				size: false, // Force full image resolution
			},
			decoder: {
				readers: ['code_128_reader'],
				multiple: false,
			},
		},
		areas: [
			{ // Top left quarter
				top: "0%",
				right: "50%",
				left: "0%",
				bottom: "50%",
			},
		],
		temp: {
			prefix: 'pdfdicer-',
		},
		threads: {
			pages: 1,
			areas: 1,
		},
	};

	dicer.new = ()=> new PDFDicer();

	dicer.defaults = function(options) {
		_.merge(this._defaults, options);
		return this;
	};

	dicer.areas = function(areas) {
		this._defaults.areas = areas;
		return this;
	};

	/**
	* Take an input file and split it into many PDF files based on configured options
	* @emits stage Fired at each stage of the process. ENUM: 'init', 'readPDF', 'readPages', 'extracted'
	* @emits tempDir The temp dir used for storage
	* @emits pageConverted  Fired with each page and pageOffset extracted as they are extracted
	* @emits pagesConverted Fired with an array of all extracted page collection
	* @emits pageAnalyze Fired before each page gets analyzed with the page object and offset
	* @emits pageAnalyzed Fired after each page has been analyzed with the page object and offset
	* @emits pagesAnalyzed Fired after all pages have been analyzed with the page collection
	* @param {string} input The input path to process (ends in .pdf usually)
	* @param {Object} [options] Optional options which override the defaults
	* @param {function} callback Callback function to fire on completion or error
	* @return {PDFDicer} This chainable object
	*/
	dicer.split = function(input, options, callback) {
		// Argument mangling {{{
		if (_.isFunction(options)) { // input, options
			callback = options;
			options = {};
		} else if (!_.isFunction(callback)) {
			throw new Error('Callback required as the final parametert of pdfDicer.convert()');
		}
		// }}}

		var settings = _.defaults({}, options, this._defaults);

		async()
			// Sanity checks {{{
			.then(function(next) {
				dicer.emit('stage', 'init');
				if (!_.isString(input)) return next('Unknown input type');
				next();
			})
			// }}}
			// Check file exists {{{
			.then(function(next) {
				fs.access(input, err => next(err ? 'File not found' : null));
			})
			// }}}
			// Prepare (temp directory) {{{
			.then('tempDir', function(next) {
				temp.mkdir(settings.temp, next);
			})
			// }}}
			// Build the PDF processing instance {{{
			.then('pdf', function(next) {
				dicer.emit('tempDir', this.tempDir);
				next(null, new pdfImage(input, {
					outputDirectory: this.tempDir,
					convertOptions: {
						'-quality': 100,
						'-density': 150,
					},
				}));
			})
			// }}}
			// Extract info about the input file {{{
			.then('info', function(next) {
				dicer.emit('stage', 'readPDF');
				this.pdf.getInfo()
					.catch(e => next(e))
					.then(data => next(null, data), next)
			})
			// }}}
			// Convert the file into PNG images {{{
			.set('pages', {})
			.then(function(next) {
				dicer.emit('stage', 'readPages');
				async()
					.set('pdf', this.pdf)
					.set('pages', this.pages)
					.forEach(0, parseInt(this.info.Pages) - 1, function(next, pageNumber) {
						this.pdf.convertPage(pageNumber)
							.then(path => {
								this.pages[pageNumber] = {
									path: path,
								},
								dicer.emit('pageConverted', this.pages[pageNumber], pageNumber);
								next();
							})
							.catch(next)
					})
					.end(next);
			})
			// }}}
			// Post conversion emitters {{{
			.then(function(next) {
				dicer.emit('pagesConverted', this.pages);
				dicer.emit('stage', 'extracted');
				next();
			})
			// }}}
			// Read each page and extract a barcode if there is one {{{
			.limit(settings.threads.pages)
			.forEach('pages', function(nextPage, page, pageOffset) {
				dicer.emit('pageAnalyze', page, pageOffset)
				page.barcode = false;
				async()
					.limit(settings.threads.areas)
					.forEach(settings.areas, function(nextArea, area) {
						barcodeReader.decodeSingle(_.merge({}, settings.reader, {
							src: page.path,
							inputStream: {
								area: area,
							},
						}), function(res) {
							if (!page.barcode && res && res.codeResult) page.barcode = res.codeResult.code;
							nextArea();
						});
					})
					.then(function(next) {
						dicer.emit('pageAnalyzed', page, pageOffset);
						next();
					})
					.end(nextPage);
			})
			// }}}
			.then(function(next) {
				dicer.emit('pagesAnalyzed', this.pages);
				next();
			})
			// }}}
			.then(function(next) {
				console.log('NEW STAGE');
				async()
					.set('pages', this.pages)
					.forEach('pages', function(next, value, key) {
						console.log(`[NEXT: {${next}}, VALUE: {${value}}, KEY: {${key}}]`);
					});
				next();
			})
			.end(callback);

		return this;
	};
};

util.inherits(PDFDicer, events.EventEmitter);

module.exports = PDFDicer;
<commit_msg>Add new stage.<commit_after>var _ = require('lodash');
var async = require('async-chainable');
var barcodeReader = require('quagga').default;
var events = require('events');
var fs = require('fs');
var temp = require('temp');
var pdfImage = require('pdf-image').PDFImage;
var util = require('util');

function PDFDicer() {
	var dicer = this;

	dicer._defaults = {
		reader: {
			numOfWorkers: 0, // Always 0 in Node backend
			locate: true, // Search for the barcode on the page
			inputStream: {
				size: false, // Force full image resolution
			},
			decoder: {
				readers: ['code_128_reader'],
				multiple: false,
			},
		},
		areas: [
			{ // Top left quarter
				top: "0%",
				right: "50%",
				left: "0%",
				bottom: "50%",
			},
		],
		temp: {
			prefix: 'pdfdicer-',
		},
		threads: {
			pages: 1,
			areas: 1,
		},
	};

	dicer.new = ()=> new PDFDicer();

	dicer.defaults = function(options) {
		_.merge(this._defaults, options);
		return this;
	};

	dicer.areas = function(areas) {
		this._defaults.areas = areas;
		return this;
	};

	/**
	* Take an input file and split it into many PDF files based on configured options
	* @emits stage Fired at each stage of the process. ENUM: 'init', 'readPDF', 'readPages', 'extracted'
	* @emits tempDir The temp dir used for storage
	* @emits pageConverted  Fired with each page and pageOffset extracted as they are extracted
	* @emits pagesConverted Fired with an array of all extracted page collection
	* @emits pageAnalyze Fired before each page gets analyzed with the page object and offset
	* @emits pageAnalyzed Fired after each page has been analyzed with the page object and offset
	* @emits pagesAnalyzed Fired after all pages have been analyzed with the page collection
	* @param {string} input The input path to process (ends in .pdf usually)
	* @param {Object} [options] Optional options which override the defaults
	* @param {function} callback Callback function to fire on completion or error
	* @return {PDFDicer} This chainable object
	*/
	dicer.split = function(input, options, callback) {
		// Argument mangling {{{
		if (_.isFunction(options)) { // input, options
			callback = options;
			options = {};
		} else if (!_.isFunction(callback)) {
			throw new Error('Callback required as the final parametert of pdfDicer.convert()');
		}
		// }}}

		var settings = _.defaults({}, options, this._defaults);

		async()
			// Sanity checks {{{
			.then(function(next) {
				dicer.emit('stage', 'init');
				if (!_.isString(input)) return next('Unknown input type');
				next();
			})
			// }}}
			// Check file exists {{{
			.then(function(next) {
				fs.access(input, err => next(err ? 'File not found' : null));
			})
			// }}}
			// Prepare (temp directory) {{{
			.then('tempDir', function(next) {
				temp.mkdir(settings.temp, next);
			})
			// }}}
			// Build the PDF processing instance {{{
			.then('pdf', function(next) {
				dicer.emit('tempDir', this.tempDir);
				next(null, new pdfImage(input, {
					outputDirectory: this.tempDir,
					convertOptions: {
						'-quality': 100,
						'-density': 150,
					},
				}));
			})
			// }}}
			// Extract info about the input file {{{
			.then('info', function(next) {
				dicer.emit('stage', 'readPDF');
				this.pdf.getInfo()
					.catch(e => next(e))
					.then(data => next(null, data), next)
			})
			// }}}
			// Convert the file into PNG images {{{
			.set('pages', {})
			.then(function(next) {
				dicer.emit('stage', 'readPages');
				async()
					.set('pdf', this.pdf)
					.set('pages', this.pages)
					.forEach(0, parseInt(this.info.Pages) - 1, function(next, pageNumber) {
						this.pdf.convertPage(pageNumber)
							.then(path => {
								this.pages[pageNumber] = {
									path: path,
								},
								dicer.emit('pageConverted', this.pages[pageNumber], pageNumber);
								next();
							})
							.catch(next)
					})
					.end(next);
			})
			// }}}
			// Post conversion emitters {{{
			.then(function(next) {
				dicer.emit('pagesConverted', this.pages);
				dicer.emit('stage', 'extracted');
				next();
			})
			// }}}
			// Read each page and extract a barcode if there is one {{{
			.limit(settings.threads.pages)
			.forEach('pages', function(nextPage, page, pageOffset) {
				dicer.emit('pageAnalyze', page, pageOffset)
				page.barcode = false;
				async()
					.limit(settings.threads.areas)
					.forEach(settings.areas, function(nextArea, area) {
						barcodeReader.decodeSingle(_.merge({}, settings.reader, {
							src: page.path,
							inputStream: {
								area: area,
							},
						}), function(res) {
							if (!page.barcode && res && res.codeResult) page.barcode = res.codeResult.code;
							nextArea();
						});
					})
					.then(function(next) {
						dicer.emit('pageAnalyzed', page, pageOffset);
						next();
					})
					.end(nextPage);
			})
			// }}}
			.then(function(next) {
				dicer.emit('pagesAnalyzed', this.pages);
				next();
			})
			// }}}
			.forEach('pages', function(next, value, key) {
				console.log(`[NEXT: {${next}}, VALUE: {${value}}, KEY: {${key}}]`);
				next();
			})
			.then(function(next) {
				console.log('END NEW STAGE');
				next();
			})
			.end(callback);

		return this;
	};
};

util.inherits(PDFDicer, events.EventEmitter);

module.exports = PDFDicer;
<|endoftext|>


<commit_before>var events = require('events')
  , util = require('util')
  , path = require('path')
  , async = require('async')
  , read = require('./read')
  , utils = require('cli-util')
  , merge = utils.merge
  , native = require('cli-native');

var schema;
try{
  schema = require('async-validate');
}catch(e){}

var Prompt = function(options, rl) {
  options = options || {};

  this.rl = rl || {};
  this.rl.completer = this.rl.completer || options.completer;

  // default prompt
  options.prompt = options.prompt || '$';

  // default replacment character for silent
  options.replace = options.replace || '*';

  // determine if a prompt should be re-displayed at the end of a run
  options.infinite = options.infinite !== undefined ? options.infinite : false;

  // convert to native types
  options.native = options.native !== undefined ? options.native : null;

  // when running in infinite mode, restore to default prompt at end of run
  options.restore = options.restore !== undefined ? options.restore : true;

  // when a validation error occurs repeat the last prompt
  // until we get a valid value
  options.repeat = options.repeat !== undefined ? options.repeat : true;

  // trim leading and trailing whitespace from input lines
  options.trim = options.trim !== undefined ? options.trim : false;

  options.delimiter = options.delimiter || '⚡';

  this.formats = options.formats || {};
  this.formats.default = this.formats.defaults || '(%s)';

  this.name = options.name || path.basename(process.argv[1]);
  this.fmt = options.format ||
    ':name :delimiter :message :default'

  this.options = options;
}

util.inherits(Prompt, events.EventEmitter);

Prompt.prototype.transform = function(k, v, options) {
  if(this.formats[k] && v) {
    v = util.format(this.formats[k], v);
  }
  return v;
}

Prompt.prototype.replace = function(format, source, options) {
  var s = '' + format, k, v;
  for(k in source) {
    v = source[k];
    v = this.transform(k, v, options);
    s = s.replace(new RegExp(':' + k, 'gi'), v ? v : '');
  }
  s = s.replace(/ +/g, ' ');
  return s;
}

Prompt.prototype.format = function(options) {
  var source = options.data || {};
  source.name = source.name || this.name;
  source.date = new Date();
  source.message = options.message;
  source.delimiter = options.delimiter;
  source.default = options.default;
  return this.replace(options.format || this.fmt, source, options);
}

Prompt.prototype.merge = function(options) {
  var o = merge(this.options, {});
  o = merge(options, o, null, true);
  if(typeof this.options.prompt === 'function') {
    o.prompt = this.options.prompt(options, o, this);
  }else{
    o.prompt = this.format(o);
  }
  return o;
}

Prompt.prototype.getDefaultPrompt = function() {
  return {
    key: 'default',
    prompt: this.options.prompt
  }
}

Prompt.prototype.exec = function(options, cb) {
  options = this.merge(options);
  var scope = this;
  var opts = {}, k;
  var trim = options.trim;
  for(k in options) opts[k] = options[k];
  opts.rl = this.rl;
  this.emit('before', options, scope);
  read(opts, function(err, value) {
    if(err) return cb(err);
    var val = (value || '').trim();
    if(options.native && val) {
      val =
        native.to(val, options.native.delimiter, options.native.json);
    }

    if(!trim && typeof val === 'string') {
      val = value;
    }

    scope.emit('value', val, options, scope);

    if(schema && options.schema && options.key) {
      var source = {}, descriptor = {}
      source[options.key] = value;
      descriptor[options.key] = options.schema;
      var validator = new schema(descriptor);
      validator.validate(source, function(errors, fields) {
        if(errors && errors.length) {
          if(options.repeat) {
            scope.emit('error', errors[0], options, cb);
            return scope.exec(options, cb);
          }
          return cb(errors[0], value);
        }
        cb(null, val);
      });
    }else{
      cb(null, val);
    }
  });
}

Prompt.prototype.run = function(prompts, cb) {
  var scope = this, options = this.options;
  prompts = prompts || [];
  var map = {};
  async.concatSeries(prompts, function(item, callback) {
    scope.exec(item, function(err, result) {
      if(item.key) {
        map[item.key] = result;
      }
      callback(err, result);
    });
  }, function(err, result) {
    //console.dir(result);
    //console.dir(err);
    //console.log('inf: %s', options.infinite);
    if(err && err.cancel) return scope.emit('cancel', prompts, scope);
    if(err && err.timeout) return scope.emit('timeout', prompts, scope);
    if(err) {
      scope.emit('error', prompts, scope);
    }
    scope.emit('complete', options, scope);
    cb(err, {list: result, map: map});
    if(options.infinite) {
      scope.run(options.restore ? [scope.getDefaultPrompt()] : prompts, cb);
    }
  })
}

function prompt(options) {
  return new Prompt(options);
}

var sets = require('./sets');

prompt.read = read;
prompt.errors = read.errors,
prompt.sets = sets;
module.exports = prompt;

//module.exports = {
  //read: read,
  //prompt: prompt,
  //errors: read.errors,
  //sets: sets
//}

//var p = prompt({infinite: true});
//p.on('before', function(options, ps) {
//})
//p.on('value', function(value, options, ps) {
  //console.log('value: \'%s\' (%s)', value, typeof value);
//})
//p.on('complete', function(options, ps) {
//})
//p.on('error', function(err) {
  //if(!err.cancel) console.error('error: ' + err.message);
//})
//p.run(sets.userpass, function(err, result) {
  ////if(err && !err.cancel) console.error('error: ' + err.message);
  ////console.dir(result);
//});
<commit_msg>Support split option.<commit_after>var events = require('events')
  , util = require('util')
  , path = require('path')
  , async = require('async')
  , read = require('./read')
  , utils = require('cli-util')
  , merge = utils.merge
  , native = require('cli-native');

var schema;
try{
  schema = require('async-validate');
}catch(e){}

var Prompt = function(options, rl) {
  options = options || {};

  this.rl = rl || {};
  this.rl.completer = this.rl.completer || options.completer;

  // default prompt
  options.prompt = options.prompt || '$';

  // default replacment character for silent
  options.replace = options.replace || '*';

  // determine if a prompt should be re-displayed at the end of a run
  options.infinite = options.infinite !== undefined ? options.infinite : false;

  // convert to native types
  options.native = options.native !== undefined ? options.native : null;

  // when running in infinite mode, restore to default prompt at end of run
  options.restore = options.restore !== undefined ? options.restore : true;

  // when a validation error occurs repeat the last prompt
  // until we get a valid value
  options.repeat = options.repeat !== undefined ? options.repeat : true;

  // trim leading and trailing whitespace from input lines
  options.trim = options.trim !== undefined ? options.trim : false;

  // split values into array
  options.split = options.split !== undefined ? options.split : null;

  options.delimiter = options.delimiter || '⚡';

  this.formats = options.formats || {};
  this.formats.default = this.formats.defaults || '(%s)';

  this.name = options.name || path.basename(process.argv[1]);
  this.fmt = options.format ||
    ':name :delimiter :message :default'

  this.options = options;
}

util.inherits(Prompt, events.EventEmitter);

Prompt.prototype.transform = function(k, v, options) {
  if(this.formats[k] && v) {
    v = util.format(this.formats[k], v);
  }
  return v;
}

Prompt.prototype.replace = function(format, source, options) {
  var s = '' + format, k, v;
  for(k in source) {
    v = source[k];
    v = this.transform(k, v, options);
    s = s.replace(new RegExp(':' + k, 'gi'), v ? v : '');
  }
  s = s.replace(/ +/g, ' ');
  return s;
}

Prompt.prototype.format = function(options) {
  var source = options.data || {};
  source.name = source.name || this.name;
  source.date = new Date();
  source.message = options.message;
  source.delimiter = options.delimiter;
  source.default = options.default;
  return this.replace(options.format || this.fmt, source, options);
}

Prompt.prototype.merge = function(options) {
  var o = merge(this.options, {});
  o = merge(options, o, null, true);
  if(typeof this.options.prompt === 'function') {
    o.prompt = this.options.prompt(options, o, this);
  }else{
    o.prompt = this.format(o);
  }
  return o;
}

Prompt.prototype.getDefaultPrompt = function() {
  return {
    key: 'default',
    prompt: this.options.prompt
  }
}

Prompt.prototype.exec = function(options, cb) {
  options = this.merge(options);
  var scope = this;
  var opts = {}, k;
  var trim = options.trim;
  for(k in options) opts[k] = options[k];
  opts.rl = this.rl;
  this.emit('before', options, scope);
  read(opts, function(err, value) {
    if(err) return cb(err);
    var val = (value || '').trim();
    if(options.native && val) {
      val =
        native.to(val, options.native.delimiter, options.native.json);
    }

    if(!trim && typeof val === 'string') {
      val = value;
    }

    if((typeof options.split === 'string' || options.split instanceof RegExp)
      && val && typeof val === 'string') {
      val = val.split(options.split);
      val = val.filter(function(part) {
        return part;
      });
    }

    scope.emit('value', val, options, scope);

    if(schema && options.schema && options.key) {
      var source = {}, descriptor = {}
      source[options.key] = value;
      descriptor[options.key] = options.schema;
      var validator = new schema(descriptor);
      validator.validate(source, function(errors, fields) {
        if(errors && errors.length) {
          if(options.repeat) {
            scope.emit('error', errors[0], options, cb);
            return scope.exec(options, cb);
          }
          return cb(errors[0], value);
        }
        cb(null, val);
      });
    }else{
      cb(null, val);
    }
  });
}

Prompt.prototype.run = function(prompts, cb) {
  cb = cb || function(){};
  var scope = this, options = this.options;
  prompts = prompts || [];
  var map = {};
  async.concatSeries(prompts, function(item, callback) {
    scope.exec(item, function(err, result) {
      if(item.key) {
        map[item.key] = result;
      }
      callback(err, result);
    });
  }, function(err, result) {
    //console.dir(result);
    //console.dir(err);
    //console.log('inf: %s', options.infinite);
    if(err && err.cancel) return scope.emit('cancel', prompts, scope);
    if(err && err.timeout) return scope.emit('timeout', prompts, scope);
    if(err) {
      scope.emit('error', prompts, scope);
    }
    scope.emit('complete', options, scope);
    cb(err, {list: result, map: map});
    if(options.infinite) {
      scope.run(options.restore ? [scope.getDefaultPrompt()] : prompts, cb);
    }
  })
}

function prompt(options) {
  return new Prompt(options);
}

var sets = require('./sets');

prompt.read = read;
prompt.errors = read.errors,
prompt.sets = sets;
module.exports = prompt;

//module.exports = {
  //read: read,
  //prompt: prompt,
  //errors: read.errors,
  //sets: sets
//}

//var p = prompt({infinite: true});
//p.on('before', function(options, ps) {
//})
//p.on('value', function(value, options, ps) {
  //console.log('value: \'%s\' (%s)', value, typeof value);
//})
//p.on('complete', function(options, ps) {
//})
//p.on('error', function(err) {
  //if(!err.cancel) console.error('error: ' + err.message);
//})
//p.run(sets.userpass, function(err, result) {
  ////if(err && !err.cancel) console.error('error: ' + err.message);
  ////console.dir(result);
//});
<|endoftext|>


<commit_before>var self = require("sdk/self");

// a dummy function, to show how tests work.
// to see how to test this function, look at test/test-index.js
function dummy(text, callback) {
  callback(text);
}

exports.dummy = dummy;

// The plugin starts here.

function replace_backspace_escapes(text) {

	/// Translate a couple of escapes.
	/// 	TODO: Make this a single 'replace()' using a callback function.
	/// 	TODO: Add '\x##' and '\u####' escapes.

	text = text.replace(/\\t/g, "\t");
	text = text.replace(/\\r/g, "\r");
	text = text.replace(/\\n/g, "\n");
	return text;

}

function replace_formatting_variables(text, tab) {

	text = text.replace(/\{TITLE\}/, tab.title);
	text = text.replace(/\{URL\}/, tab.url);
	text = text.replace(/\{INDEX\}/, tab.index);
	return text;

}

function listTabs() {

	/// Get the custom output formats from the preferences.

	var prefs = require("sdk/simple-prefs").prefs;

	var tab_format = replace_backspace_escapes(prefs.tab_format);
	var header_format = replace_backspace_escapes(prefs.header_format);
	var footer_format = replace_backspace_escapes(prefs.footer_format);

	/// Get the tabs of only the currently active window (in load order).

	var sortedTabs = new Array();

	var tabs = require("sdk/windows").browserWindows.activeWindow.tabs;
	for (let i in tabs) {
		sortedTabs.push({index:i, pos:tabs[i].index, title:tabs[i].title, url:tabs[i].url});
	}

	/// Sort by position within the window.

	sortedTabs.sort(function(a,b) { return a.pos - b.pos});

	/// Generate output.

	var tabsList = "";

	for(let tab of sortedTabs) {
		tabsList += replace_formatting_variables(tab_format, tab);
	}

	/// Output to clipboard.

	require("sdk/clipboard").set(header_format + tabsList + footer_format);

}

/// Button click handler.

function handleClick(state) {

	listTabs();

}

/// Create the button.

require('sdk/ui/button/action').ActionButton({

  id: "tab-lister-button",
  label: "list tabs",
  icon: {
			"16": "./icon-16.png",
			"32": "./icon-32.png"
		},
  onClick: handleClick

});
<commit_msg>fixed issue #5<commit_after>var self = require("sdk/self");

// a dummy function, to show how tests work.
// to see how to test this function, look at test/test-index.js
function dummy(text, callback) {
  callback(text);
}

exports.dummy = dummy;

// The plugin starts here.

function replace_backspace_escapes(text) {

	/// Translate a couple of escapes.
	/// 	TODO: Make this a single 'replace()' using a callback function.
	/// 	TODO: Add '\x##' and '\u####' escapes.

	text = text.replace(/\\t/g, "\t");
	text = text.replace(/\\r/g, "\r");
	text = text.replace(/\\n/g, "\n");
	return text;

}

function replace_formatting_variables(text, tab) {

	var title = tab.title.replace(/"/, """);

	text = text.replace(/\{TITLE\}/, title);
	text = text.replace(/\{URL\}/, tab.url);
	text = text.replace(/\{INDEX\}/, tab.index);
	return text;

}

function listTabs() {

	/// Get the custom output formats from the preferences.

	var prefs = require("sdk/simple-prefs").prefs;

	var tab_format = replace_backspace_escapes(prefs.tab_format);
	var header_format = replace_backspace_escapes(prefs.header_format);
	var footer_format = replace_backspace_escapes(prefs.footer_format);

	/// Get the tabs of only the currently active window (in load order).

	var sortedTabs = new Array();

	var tabs = require("sdk/windows").browserWindows.activeWindow.tabs;
	for (let i in tabs) {
		sortedTabs.push({index:i, pos:tabs[i].index, title:tabs[i].title, url:tabs[i].url});
	}

	/// Sort by position within the window.

	sortedTabs.sort(function(a,b) { return a.pos - b.pos});

	/// Generate output.

	var tabsList = "";

	for(let tab of sortedTabs) {
		tabsList += replace_formatting_variables(tab_format, tab);
	}

	/// Output to clipboard.

	require("sdk/clipboard").set(header_format + tabsList + footer_format);

}

/// Button click handler.

function handleClick(state) {

	listTabs();

}

/// Create the button.

require('sdk/ui/button/action').ActionButton({

  id: "tab-lister-button",
  label: "list tabs",
  icon: {
			"16": "./icon-16.png",
			"32": "./icon-32.png"
		},
  onClick: handleClick

});
<|endoftext|>


<commit_before>var _ = require("lodash");
var e = require("estree-builder");
var fs = require("fs");
var lang = require("./lang");
var parser = require("./parser");
var escodegen = require("escodegen");
var astToTarget = require("./ast-to-target");
var toStatement = require("./toESTreeStatement");

var module_loader_src = fs.readFileSync("./module_loader.ecmaless").toString();
var module_loader_ast = parser(module_loader_src);
var module_loader_est = astToTarget(module_loader_ast, lang().target_macros)[0];

var compile = function(ast, options){
  options = options || {};

  var l = lang(options.user_macros);
  return {
    estree: astToTarget(ast, l.target_macros),
    user_macros: l.user_macros
  };
};

var parseFile = function(src){
  var ast = parser(src);
  var deps = {};

  if(ast[0].type === "list"
      && ast[0].value[0].type === "symbol"
      && ast[0].value[0].value === "m"){
    _.each(_.chunk(ast[0].value.slice(1), 2), function(pair){
      var sym = pair[0].value;
      var path = pair[1].value;
      deps[sym] = path;
    });
    ast = ast.slice(1);
  }
  return {
    ast: ast,
    deps: deps
  };
};

var toJSFile = function(estree, options){
  options = options || {};

  if(!_.isArray(estree)){
    estree = [estree];
  }
  return escodegen.generate({
    "loc": _.size(estree) > 0 ? _.head(estree).loc : undefined,
    "type": "Program",
    "body": _.map(estree, toStatement)
  }, options.escodegen);
};

module.exports = function(src, options){
  options = options || {};

  if(!_.has(options, 'files')){
    options.files = {'main': {src: src}};
    src = 'main';
  }

  var modules = _.cloneDeep(options.files);

  var loadModule = function(module){
    if(!_.has(modules, module)){
      throw new Error('Module not found: ' + module);
    }
    if(_.has(modules[module], 'ast')){
      return;//already loaded
    }

    var p = parseFile(modules[module].src);
    modules[module].ast = p.ast;
    modules[module].deps = p.deps;
    _.each(p.deps, loadModule);
  };

  loadModule(src);

  var mkAST = function(type, value){
    var loc = modules[src].ast[0].loc;
    return {type: type, value: value, loc: loc};
  };

  var daEST;
  if(_.size(modules) === 1){
    daEST = compile(modules[_.keys(modules)[0]].ast).estree;
  }else{
    daEST = [e('call', module_loader_est, [
      e('object', _.mapValues(modules, function(m){
        var ast = mkAST('list', [
          mkAST('symbol', 'fn'),
          mkAST('list', [
            mkAST('symbol', '[')
          ].concat(_.map(_.keys(m.deps), function(arg){
            return mkAST('symbol', arg);
          })))
        ].concat(m.ast));

        var estree = compile(ast, options).estree;
        return e('array', [
          estree
        ].concat(_.map(m.deps, function(dep){
          return e('string', dep);
        })));
      })),
      e('string', src)
    ])];
  }
  return toJSFile(daEST, options);
};
<commit_msg>compile each module after loading it's dependancies<commit_after>var _ = require("lodash");
var e = require("estree-builder");
var fs = require("fs");
var lang = require("./lang");
var parser = require("./parser");
var escodegen = require("escodegen");
var astToTarget = require("./ast-to-target");
var toStatement = require("./toESTreeStatement");

var module_loader_src = fs.readFileSync("./module_loader.ecmaless").toString();
var module_loader_ast = parser(module_loader_src);
var module_loader_est = astToTarget(module_loader_ast, lang().target_macros)[0];

var compile = function(ast, options){
  options = options || {};

  var l = lang(options.user_macros);
  return {
    estree: astToTarget(ast, l.target_macros),
    user_macros: l.user_macros
  };
};

var parseFile = function(src){
  var ast = parser(src);
  var deps = {};

  if(ast[0].type === "list"
      && ast[0].value[0].type === "symbol"
      && ast[0].value[0].value === "m"){
    _.each(_.chunk(ast[0].value.slice(1), 2), function(pair){
      var sym = pair[0].value;
      var path = pair[1].value;
      deps[sym] = path;
    });
    ast = ast.slice(1);
  }
  return {
    ast: ast,
    deps: deps
  };
};

var toJSFile = function(estree, options){
  options = options || {};

  if(!_.isArray(estree)){
    estree = [estree];
  }
  return escodegen.generate({
    "loc": _.size(estree) > 0 ? _.head(estree).loc : undefined,
    "type": "Program",
    "body": _.map(estree, toStatement)
  }, options.escodegen);
};

module.exports = function(src, options){
  options = options || {};

  if(!_.has(options, 'files')){
    options.files = {'main': {src: src}};
    src = 'main';
  }

  var modules = _.cloneDeep(options.files);

  var loadModule = function(module){
    if(!_.has(modules, module)){
      throw new Error('Module not found: ' + module);
    }
    if(_.has(modules[module], 'ast')){
      return;//already loaded
    }

    var p = parseFile(modules[module].src);
    modules[module].ast = p.ast;
    modules[module].deps = p.deps;
    var mkAST = function(type, value){
      var loc = p.ast[0].loc;
      return {type: type, value: value, loc: loc};
    };
    modules[module].module_ast = mkAST('list', [
      mkAST('symbol', 'fn'),
      mkAST('list', [
        mkAST('symbol', '[')
      ].concat(_.map(_.keys(p.deps), function(arg){
        return mkAST('symbol', arg);
      })))
    ].concat(p.ast));

    _.each(p.deps, loadModule);

    //now that all deps have been loaded, we can compile it
    modules[module].estree = compile(modules[module].module_ast).estree;
  };

  loadModule(src);

  var daEST;
  if(_.size(modules) === 1){
    daEST = compile(modules[_.keys(modules)[0]].ast).estree;
  }else{
    daEST = [e('call', module_loader_est, [
      e('object', _.mapValues(modules, function(m){
        return e('array', [
          m.estree
        ].concat(_.map(m.deps, function(dep){
          return e('string', dep);
        })));
      })),
      e('string', src)
    ])];
  }
  return toJSFile(daEST, options);
};
<|endoftext|>


<commit_before>#!/usr/bin/env node

// Copyright (c) 2015 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

/*eslint no-console: [0] */
/*eslint no-process-exit: [0] */
/*eslint max-params: [2, 6] */
/*eslint max-statements: [2, 40] */
'use strict';

var TChannel = require('tchannel');
var TChannelAsThrift = require('tchannel/as/thrift');
var TChannelAsJSON = require('tchannel/as/json');
var minimist = require('minimist');
var myLocalIp = require('my-local-ip');
var DebugLogtron = require('debug-logtron');
var rc = require('rc');
var rcUtils = require('rc/lib/utils');
var camelCaseKeys = require('camelcase-keys');
var traverse = require('traverse');
var extend = require('xtend');

var fmt = require('util').format;
var console = require('console');
var process = require('process');
var spawn = require('child_process').spawn;
var fs = require('fs');
var path = require('path');
var url = require('url');
var assert = require('assert');

var safeJsonParse = require('safe-json-parse/tuple');

var Logger = require('./logger');
var Benchmark = require('./benchmark');
var HealthLogger = require('./health-logger');
var TCurlAsHttp = require('./as-http');

var packageJson = require('./package.json');

module.exports = main;

var minimistArgs = {
    string: ['thrift', 'json', 'head', 'body'],
    boolean: ['raw', 'json', 'strict'],
    alias: {
        v: 'version',
        p: 'peer',
        H: 'hostlist',
        t: 'thrift',
        j: 'json',
        2: 'head',
        3: 'body',
        arg2: 'head',
        arg3: 'body'
    },
    default: {
        head: '',
        body: '',
        strict: true
    }
};

// delegate implements error(message, err), response(res), exit()
function main(argv, delegate) {

    argv = minimist(argv, minimistArgs);

    var conf = extend(
        rc('tcurl', {}, argv),
        env(),
        argv
    );

    if (conf.version) {
        delegate = delegate || new Logger();
        return delegate.log(packageJson.version);
    }

    if (conf.help) {
        return printFullHelp();
    } else if (conf.h || conf._.length === 0) {
        return help();
    }

    var opts = parseArgs(conf);
    if (opts === null) {
        help();
        return;
    }

    var tcurl = new TCurl();

    if (opts.health) {
        delegate = delegate || new HealthLogger();
        opts.thrift = path.join(__dirname, 'meta.thrift');
        opts.endpoint = 'Meta::health';
    } else {
        delegate = delegate || new Logger();
    }

    if (opts.rate) {
        var benchmark = new Benchmark({
            tcurl: tcurl,
            cmdOptions: opts,
            logger: delegate
        });
        return benchmark.run(function done() {
            tcurl.client.close();
            delegate.exit();
        });
    }

    return tcurl.request(opts, delegate);
}

function env() {
    var envConf = rcUtils.env('TCURL_');
    return traverse(envConf).map(camelcaseObjectKeys);

    function camelcaseObjectKeys(value) {
        if (typeof value === 'object') {
            this.update(camelCaseKeys(value));
        }
    }
}

main.exec = function execMain(str, delegate) {
    main(str, delegate);
};

function help() {
    console.log('usage: tcurl [--help] [-v | --version] [-H] [-p] [-t]');
    console.log('             [-2 | --arg2 | --head] [-3 | --arg3 | --body]');
    console.log('             [--shardKey] [--no-strict]  [--timeout]');
    console.log('             [--http] [--raw] [--health]');
    console.log('             [--rate] [--requests] [--time] [--delay]');
}

function printFullHelp() {
    var options = {
        cwd: process.cwd(),
        /*eslint no-process-env: [0] */
        env: process.env,
        setsid: false,
        customFds: [0, 1, 2]
    };

    spawn('man', [path.join(__dirname, 'man', 'tcurl.1')], options);
}

function parseArgs(argv) {
    var service = argv._[0];
    var endpoint = argv._[1];
    var health = argv.health;

    // Prefer peer specified at the command line over hostlist
    var peers;
    if (argv.peer) {
        peers = [argv.peer];
    } else if (argv.hostlist) {
        peers = parsePeerlist(argv.hostlist);
        if (peers === null) {
            return null;
        }
    } else {
        console.error('Please specify peers either with --hostlist or --peer arguments, or hostlist in tcurlrc');
        return null;
    }

    var ip;
    function normalizePeer(address) {
        if (!ip) {
            ip = myLocalIp();
        }
        var parsedUri = url.parse('tchannel://' + address);
        if (parsedUri.hostname === 'localhost') {
            parsedUri.hostname = ip;
        }
        assert(parsedUri.hostname, 'host required');
        assert(parsedUri.port, 'port required');
        return parsedUri.hostname + ':' + parsedUri.port;
    }

    peers = peers.map(normalizePeer);

    if (!health && !endpoint) {
        console.error('Please specify an endpoint or --health');
        return null;
    }

    if (!service) {
        console.error('Please specify a service');
        return null;
    }

    var argScheme;
    if (argv.raw) {
        argScheme = 'raw';
    } else if (argv.http) {
        argScheme = 'http';
    } else if (argv.json) {
        argScheme = 'json';
    } else if (argv.thrift || health || endpoint.indexOf('::') >= 0) {
        argScheme = 'thrift';
    } else {
        argScheme = 'json';
    }

    return {
        head: argv.head,
        body: argv.body,
        shardKey: argv.shardKey,
        service: service,
        endpoint: endpoint,
        peers: peers,
        argScheme: argScheme,
        thrift: argv.thrift,
        strict: argv.strict,
        http: argv.http,
        raw: argv.raw,
        timeout: argv.timeout,
        health: health,
        time: argv.time,
        requests: argv.requests,
        delay: argv.delay,
        rate: argv.rate
    };
}

function parsePeerlist(peerlist) {
    var text;
    try {
        text = fs.readFileSync(peerlist, 'utf-8');
    } catch (err) {
        console.error('Could not read peer list', peerlist);
        console.error(err.message);
        return null;
    }
    var json;
    try {
        json = JSON.parse(text);
    } catch (err) {
        console.error('Could not parse peer list', peerlist);
        console.error(err.message);
        return null;
    }
    return json;
}

function TCurl(opts) {
    if (!(this instanceof TCurl)) {
        return new TCurl(opts);
    }

    var self = this;
    self.subChannel = null;
    self.client = null;
}

TCurl.prototype.parseJsonArgs = function parseJsonArgs(opts, delegate) {
    if (opts.raw) {
        return null;
    }

    var tuple = null;
    if (opts.head) {
        tuple = safeJsonParse(opts.head);
        opts.head = tuple[1] || opts.head;
    }
    if (tuple && tuple[0]) {
        delegate.error('Failed to parse arg2 (i.e., head) as JSON');
        delegate.error(tuple[0]);
    }

    tuple = null;
    if (opts.body) {
        tuple = safeJsonParse(opts.body);
        opts.body = tuple[1] || opts.body;
    }
    if (tuple && tuple[0]) {
        delegate.error('Failed to parse arg3 (i.e., body) as JSON');
        delegate.error(tuple[0]);
    }

    return null;
};

TCurl.prototype.readThrift = function readThrift(opts, delegate) {
    var self = this;
    if (opts.thrift == null) {
        delegate.error('Must specify a thrift file with -t|--thrift for Thrift endpoints');
        delegate.error('or specify --json for JSON endpoints that contain ::');
        return null;
    }
    try {
        return fs.readFileSync(opts.thrift, 'utf8');
    } catch (err) {
        if (err.code !== 'EISDIR') {
            delegate.error('Failed to read thrift file "' + opts.thrift + '"');
            delegate.error(err);
            return null;
        }
    }
    return self.readThriftDir(opts, delegate);
};

TCurl.prototype.readThriftDir = function readThriftDir(opts, delegate) {
    debugger;
    var sources = {};
    var files = fs.readdirSync(opts.thrift);
    files.forEach(function eachFile(file) {
        var match = /([^\/]+)\.thrift$/.exec(file);
        if (match) {
            var serviceName = match[1];
            var fileName = match[0];
            var thriftFilepath = path.join(opts.thrift, fileName);
            sources[serviceName] = fs.readFileSync(thriftFilepath, 'utf8');
        }
    });

    if (!sources[opts.service]) {
        delegate.error('Spec for service "' +
            opts.service + '" unavailable in directory "' + opts.thrift + '"');
        return null;
    }

    return sources[opts.service];
};

TCurl.prototype.prepare = function prepare(opts, delegate, callback) {
    var self = this;

    // May report errors for arg2, arg3, or both
    self.parseJsonArgs(opts, delegate);
    if (delegate.exitCode) {
        return delegate.exit();
    }

    self.client = TChannel({
        logger: DebugLogtron('tcurl')
    });

    self.subChannel = self.client.makeSubChannel({
        serviceName: opts.service,
        peers: opts.peers,
        requestDefaults: {
            serviceName: opts.service,
            headers: {
                cn: 'tcurl'
            }
        }
    });

    var peer = self.subChannel.peers.choosePeer();
    // TODO: the host option should be called peer, hostPort, or address
    self.client.waitForIdentified({host: peer.hostPort}, onIdentified);

    function onIdentified(err) {
        if (err) {
            delegate.error(err);
            return delegate.exit();
        }

        callback();
    }
};

TCurl.prototype.createRequest = function createRequest(opts) {
    var self = this;
    var headers = opts.shardKey ? {sk: opts.shardKey} : {};
    return self.subChannel.request({
        timeout: opts.timeout || 100,
        hasNoParent: true,
        serviceName: opts.service,
        headers: headers
    });
};

TCurl.prototype.send = function send(opts, request, delegate) {
    var self = this;

    if (opts.argScheme === 'thrift') {
        self.asThrift(opts, request, delegate, done);
    } else if (opts.argScheme === 'http') {
        self.asHTTP(opts, self.client, self.subChannel, delegate, done);
    } else if (opts.argScheme === 'json') {
        self.asJSON(opts, request, delegate, done);
        // TODO fix argument order for each of these
    } else {
        self.asRaw(opts, request, delegate, done);
    }

    function done() {
        if (!opts.rate) {
            self.client.close();
        }
    }
};

TCurl.prototype.request = function tcurlRequest(opts, delegate) {
    var self = this;
    self.prepare(opts, delegate, onReady);

    function onReady() {
        self.send(opts,
            self.createRequest(opts),
            delegate
        );
    }
};

TCurl.prototype.asThrift = function asThrift(opts, request, delegate, done) {
    var self = this;

    var source = self.readThrift(opts, delegate);

    if (source === null) {
        done();
        return delegate.exit();
    }

    var sender;
    try {
        sender = new TChannelAsThrift({source: source, strict: opts.strict});
    } catch (err) {
        if (err.name === 'SyntaxError') {
            // TODO works for now: does not work with include support unless
            // errors are annotated with the source file name.
            delegate.error(opts.thrift + ':' + err.line + ':' + err.column + ': Thrift Syntax Error');
            delegate.error(err.message);
        } else {
            delegate.error('Error parsing Thrift IDL');
            delegate.error(err);
            delegate.error('Consider using --no-strict to bypass mandatory optional/required fields');
        }
        done();
        return delegate.exit();
    }

    // The following is a hack to produce a nice error message when
    // the endpoint does not exist. It is a temporary solution based
    // on the thriftify interface. How the existence of this endpoint
    // is checked and this error thrown will change when we move to
    // the thriftrw rewrite.
    try {
        sender.send(request, opts.endpoint, opts.head,
            opts.body, onResponse);
    } catch (err) {
        // TODO untangle this mess
        if (err.message === fmt('type %s_args not found', opts.endpoint)) {
            delegate.error(fmt('%s endpoint does not exist', opts.endpoint));
        } else {
            delegate.error('Error response received for the as-thrift request.');
            delegate.error(err);
        }
        done();
        return delegate.exit();
    }

    function onResponse(err, res, arg2, arg3) {
        done();
        self.onResponse(err, res, arg2, arg3, opts, delegate);
    }
};

TCurl.prototype.asRaw = function asRaw(opts, request, delegate, done) {
    var self = this;
    request.headers.as = 'raw';
    request.send(opts.endpoint, opts.head, opts.body,
        onResponse);

    function onResponse(err, res, arg2, arg3) {
        done();
        self.onResponse(err, res, arg2, arg3, opts, delegate);
    }
};

TCurl.prototype.asHTTP = function asHTTP(opts, client, subChan, delegate, done) {
    var asHttp = TCurlAsHttp({
        channel: client,
        subChannel: subChan,
        method: opts.http,
        endpoint: opts.endpoint,
        headers: opts.head,
        body: opts.body,
        done: done,
        logger: delegate
    });
    asHttp.send();
};

TCurl.prototype.asJSON = function asJSON(opts, request, delegate, done) {
    var self = this;
    var sender = new TChannelAsJSON();
    sender.send(request, opts.endpoint, opts.head,
        opts.body, onResponse);

    function onResponse(err, res, arg2, arg3) {
        done();
        self.onResponse(err, res, arg2, arg3, opts, delegate);
    }
};

TCurl.prototype.onResponse = function onResponse(err, res, arg2, arg3, opts, delegate) {
    if (typeof delegate.handleReponse === 'function') {
        delegate.handleReponse(err, res, arg2, arg3, opts);
    }

    if (err) {
        delegate.error(err);
        return delegate.exit();
    }

    if (arg2 !== undefined && res) {
        res.head = arg2;
    }
    if (arg3 !== undefined && res) {
        res.body = arg3;
    }

    delegate.response(res, opts);
    return delegate.exit();
};

if (require.main === module) {
    main(process.argv.slice(2));
}
<commit_msg>Remove debugger<commit_after>#!/usr/bin/env node

// Copyright (c) 2015 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

/*eslint no-console: [0] */
/*eslint no-process-exit: [0] */
/*eslint max-params: [2, 6] */
/*eslint max-statements: [2, 40] */
'use strict';

var TChannel = require('tchannel');
var TChannelAsThrift = require('tchannel/as/thrift');
var TChannelAsJSON = require('tchannel/as/json');
var minimist = require('minimist');
var myLocalIp = require('my-local-ip');
var DebugLogtron = require('debug-logtron');
var rc = require('rc');
var rcUtils = require('rc/lib/utils');
var camelCaseKeys = require('camelcase-keys');
var traverse = require('traverse');
var extend = require('xtend');

var fmt = require('util').format;
var console = require('console');
var process = require('process');
var spawn = require('child_process').spawn;
var fs = require('fs');
var path = require('path');
var url = require('url');
var assert = require('assert');

var safeJsonParse = require('safe-json-parse/tuple');

var Logger = require('./logger');
var Benchmark = require('./benchmark');
var HealthLogger = require('./health-logger');
var TCurlAsHttp = require('./as-http');

var packageJson = require('./package.json');

module.exports = main;

var minimistArgs = {
    string: ['thrift', 'json', 'head', 'body'],
    boolean: ['raw', 'json', 'strict'],
    alias: {
        v: 'version',
        p: 'peer',
        H: 'hostlist',
        t: 'thrift',
        j: 'json',
        2: 'head',
        3: 'body',
        arg2: 'head',
        arg3: 'body'
    },
    default: {
        head: '',
        body: '',
        strict: true
    }
};

// delegate implements error(message, err), response(res), exit()
function main(argv, delegate) {

    argv = minimist(argv, minimistArgs);

    var conf = extend(
        rc('tcurl', {}, argv),
        env(),
        argv
    );

    if (conf.version) {
        delegate = delegate || new Logger();
        return delegate.log(packageJson.version);
    }

    if (conf.help) {
        return printFullHelp();
    } else if (conf.h || conf._.length === 0) {
        return help();
    }

    var opts = parseArgs(conf);
    if (opts === null) {
        help();
        return;
    }

    var tcurl = new TCurl();

    if (opts.health) {
        delegate = delegate || new HealthLogger();
        opts.thrift = path.join(__dirname, 'meta.thrift');
        opts.endpoint = 'Meta::health';
    } else {
        delegate = delegate || new Logger();
    }

    if (opts.rate) {
        var benchmark = new Benchmark({
            tcurl: tcurl,
            cmdOptions: opts,
            logger: delegate
        });
        return benchmark.run(function done() {
            tcurl.client.close();
            delegate.exit();
        });
    }

    return tcurl.request(opts, delegate);
}

function env() {
    var envConf = rcUtils.env('TCURL_');
    return traverse(envConf).map(camelcaseObjectKeys);

    function camelcaseObjectKeys(value) {
        if (typeof value === 'object') {
            this.update(camelCaseKeys(value));
        }
    }
}

main.exec = function execMain(str, delegate) {
    main(str, delegate);
};

function help() {
    console.log('usage: tcurl [--help] [-v | --version] [-H] [-p] [-t]');
    console.log('             [-2 | --arg2 | --head] [-3 | --arg3 | --body]');
    console.log('             [--shardKey] [--no-strict]  [--timeout]');
    console.log('             [--http] [--raw] [--health]');
    console.log('             [--rate] [--requests] [--time] [--delay]');
}

function printFullHelp() {
    var options = {
        cwd: process.cwd(),
        /*eslint no-process-env: [0] */
        env: process.env,
        setsid: false,
        customFds: [0, 1, 2]
    };

    spawn('man', [path.join(__dirname, 'man', 'tcurl.1')], options);
}

function parseArgs(argv) {
    var service = argv._[0];
    var endpoint = argv._[1];
    var health = argv.health;

    // Prefer peer specified at the command line over hostlist
    var peers;
    if (argv.peer) {
        peers = [argv.peer];
    } else if (argv.hostlist) {
        peers = parsePeerlist(argv.hostlist);
        if (peers === null) {
            return null;
        }
    } else {
        console.error('Please specify peers either with --hostlist or --peer arguments, or hostlist in tcurlrc');
        return null;
    }

    var ip;
    function normalizePeer(address) {
        if (!ip) {
            ip = myLocalIp();
        }
        var parsedUri = url.parse('tchannel://' + address);
        if (parsedUri.hostname === 'localhost') {
            parsedUri.hostname = ip;
        }
        assert(parsedUri.hostname, 'host required');
        assert(parsedUri.port, 'port required');
        return parsedUri.hostname + ':' + parsedUri.port;
    }

    peers = peers.map(normalizePeer);

    if (!health && !endpoint) {
        console.error('Please specify an endpoint or --health');
        return null;
    }

    if (!service) {
        console.error('Please specify a service');
        return null;
    }

    var argScheme;
    if (argv.raw) {
        argScheme = 'raw';
    } else if (argv.http) {
        argScheme = 'http';
    } else if (argv.json) {
        argScheme = 'json';
    } else if (argv.thrift || health || endpoint.indexOf('::') >= 0) {
        argScheme = 'thrift';
    } else {
        argScheme = 'json';
    }

    return {
        head: argv.head,
        body: argv.body,
        shardKey: argv.shardKey,
        service: service,
        endpoint: endpoint,
        peers: peers,
        argScheme: argScheme,
        thrift: argv.thrift,
        strict: argv.strict,
        http: argv.http,
        raw: argv.raw,
        timeout: argv.timeout,
        health: health,
        time: argv.time,
        requests: argv.requests,
        delay: argv.delay,
        rate: argv.rate
    };
}

function parsePeerlist(peerlist) {
    var text;
    try {
        text = fs.readFileSync(peerlist, 'utf-8');
    } catch (err) {
        console.error('Could not read peer list', peerlist);
        console.error(err.message);
        return null;
    }
    var json;
    try {
        json = JSON.parse(text);
    } catch (err) {
        console.error('Could not parse peer list', peerlist);
        console.error(err.message);
        return null;
    }
    return json;
}

function TCurl(opts) {
    if (!(this instanceof TCurl)) {
        return new TCurl(opts);
    }

    var self = this;
    self.subChannel = null;
    self.client = null;
}

TCurl.prototype.parseJsonArgs = function parseJsonArgs(opts, delegate) {
    if (opts.raw) {
        return null;
    }

    var tuple = null;
    if (opts.head) {
        tuple = safeJsonParse(opts.head);
        opts.head = tuple[1] || opts.head;
    }
    if (tuple && tuple[0]) {
        delegate.error('Failed to parse arg2 (i.e., head) as JSON');
        delegate.error(tuple[0]);
    }

    tuple = null;
    if (opts.body) {
        tuple = safeJsonParse(opts.body);
        opts.body = tuple[1] || opts.body;
    }
    if (tuple && tuple[0]) {
        delegate.error('Failed to parse arg3 (i.e., body) as JSON');
        delegate.error(tuple[0]);
    }

    return null;
};

TCurl.prototype.readThrift = function readThrift(opts, delegate) {
    var self = this;
    if (opts.thrift == null) {
        delegate.error('Must specify a thrift file with -t|--thrift for Thrift endpoints');
        delegate.error('or specify --json for JSON endpoints that contain ::');
        return null;
    }
    try {
        return fs.readFileSync(opts.thrift, 'utf8');
    } catch (err) {
        if (err.code !== 'EISDIR') {
            delegate.error('Failed to read thrift file "' + opts.thrift + '"');
            delegate.error(err);
            return null;
        }
    }
    return self.readThriftDir(opts, delegate);
};

TCurl.prototype.readThriftDir = function readThriftDir(opts, delegate) {
    var sources = {};
    var files = fs.readdirSync(opts.thrift);
    files.forEach(function eachFile(file) {
        var match = /([^\/]+)\.thrift$/.exec(file);
        if (match) {
            var serviceName = match[1];
            var fileName = match[0];
            var thriftFilepath = path.join(opts.thrift, fileName);
            sources[serviceName] = fs.readFileSync(thriftFilepath, 'utf8');
        }
    });

    if (!sources[opts.service]) {
        delegate.error('Spec for service "' +
            opts.service + '" unavailable in directory "' + opts.thrift + '"');
        return null;
    }

    return sources[opts.service];
};

TCurl.prototype.prepare = function prepare(opts, delegate, callback) {
    var self = this;

    // May report errors for arg2, arg3, or both
    self.parseJsonArgs(opts, delegate);
    if (delegate.exitCode) {
        return delegate.exit();
    }

    self.client = TChannel({
        logger: DebugLogtron('tcurl')
    });

    self.subChannel = self.client.makeSubChannel({
        serviceName: opts.service,
        peers: opts.peers,
        requestDefaults: {
            serviceName: opts.service,
            headers: {
                cn: 'tcurl'
            }
        }
    });

    var peer = self.subChannel.peers.choosePeer();
    // TODO: the host option should be called peer, hostPort, or address
    self.client.waitForIdentified({host: peer.hostPort}, onIdentified);

    function onIdentified(err) {
        if (err) {
            delegate.error(err);
            return delegate.exit();
        }

        callback();
    }
};

TCurl.prototype.createRequest = function createRequest(opts) {
    var self = this;
    var headers = opts.shardKey ? {sk: opts.shardKey} : {};
    return self.subChannel.request({
        timeout: opts.timeout || 100,
        hasNoParent: true,
        serviceName: opts.service,
        headers: headers
    });
};

TCurl.prototype.send = function send(opts, request, delegate) {
    var self = this;

    if (opts.argScheme === 'thrift') {
        self.asThrift(opts, request, delegate, done);
    } else if (opts.argScheme === 'http') {
        self.asHTTP(opts, self.client, self.subChannel, delegate, done);
    } else if (opts.argScheme === 'json') {
        self.asJSON(opts, request, delegate, done);
        // TODO fix argument order for each of these
    } else {
        self.asRaw(opts, request, delegate, done);
    }

    function done() {
        if (!opts.rate) {
            self.client.close();
        }
    }
};

TCurl.prototype.request = function tcurlRequest(opts, delegate) {
    var self = this;
    self.prepare(opts, delegate, onReady);

    function onReady() {
        self.send(opts,
            self.createRequest(opts),
            delegate
        );
    }
};

TCurl.prototype.asThrift = function asThrift(opts, request, delegate, done) {
    var self = this;

    var source = self.readThrift(opts, delegate);

    if (source === null) {
        done();
        return delegate.exit();
    }

    var sender;
    try {
        sender = new TChannelAsThrift({source: source, strict: opts.strict});
    } catch (err) {
        if (err.name === 'SyntaxError') {
            // TODO works for now: does not work with include support unless
            // errors are annotated with the source file name.
            delegate.error(opts.thrift + ':' + err.line + ':' + err.column + ': Thrift Syntax Error');
            delegate.error(err.message);
        } else {
            delegate.error('Error parsing Thrift IDL');
            delegate.error(err);
            delegate.error('Consider using --no-strict to bypass mandatory optional/required fields');
        }
        done();
        return delegate.exit();
    }

    // The following is a hack to produce a nice error message when
    // the endpoint does not exist. It is a temporary solution based
    // on the thriftify interface. How the existence of this endpoint
    // is checked and this error thrown will change when we move to
    // the thriftrw rewrite.
    try {
        sender.send(request, opts.endpoint, opts.head,
            opts.body, onResponse);
    } catch (err) {
        // TODO untangle this mess
        if (err.message === fmt('type %s_args not found', opts.endpoint)) {
            delegate.error(fmt('%s endpoint does not exist', opts.endpoint));
        } else {
            delegate.error('Error response received for the as-thrift request.');
            delegate.error(err);
        }
        done();
        return delegate.exit();
    }

    function onResponse(err, res, arg2, arg3) {
        done();
        self.onResponse(err, res, arg2, arg3, opts, delegate);
    }
};

TCurl.prototype.asRaw = function asRaw(opts, request, delegate, done) {
    var self = this;
    request.headers.as = 'raw';
    request.send(opts.endpoint, opts.head, opts.body,
        onResponse);

    function onResponse(err, res, arg2, arg3) {
        done();
        self.onResponse(err, res, arg2, arg3, opts, delegate);
    }
};

TCurl.prototype.asHTTP = function asHTTP(opts, client, subChan, delegate, done) {
    var asHttp = TCurlAsHttp({
        channel: client,
        subChannel: subChan,
        method: opts.http,
        endpoint: opts.endpoint,
        headers: opts.head,
        body: opts.body,
        done: done,
        logger: delegate
    });
    asHttp.send();
};

TCurl.prototype.asJSON = function asJSON(opts, request, delegate, done) {
    var self = this;
    var sender = new TChannelAsJSON();
    sender.send(request, opts.endpoint, opts.head,
        opts.body, onResponse);

    function onResponse(err, res, arg2, arg3) {
        done();
        self.onResponse(err, res, arg2, arg3, opts, delegate);
    }
};

TCurl.prototype.onResponse = function onResponse(err, res, arg2, arg3, opts, delegate) {
    if (typeof delegate.handleReponse === 'function') {
        delegate.handleReponse(err, res, arg2, arg3, opts);
    }

    if (err) {
        delegate.error(err);
        return delegate.exit();
    }

    if (arg2 !== undefined && res) {
        res.head = arg2;
    }
    if (arg3 !== undefined && res) {
        res.body = arg3;
    }

    delegate.response(res, opts);
    return delegate.exit();
};

if (require.main === module) {
    main(process.argv.slice(2));
}
<|endoftext|>


<commit_before>var moment = require('moment');
var remind = function(){
    this.name = 'remind';
    this.displayname = 'Remind';
    this.description = 'Set reminders for yourself';
}

remind.prototype.init = function() {
    var self = this;
    this.listen('set reminder to (.+) in (.+?) (seconds|minutes|hours|days)', 'standard', function(from, interface, params){
        var crontime = moment().add(params[1], params[2]).toDate();

        self.api.addCronJob(crontime, function(){
            self.sendMessage(params[0], interface, from);
        });
    });
}

module.exports = remind;
<commit_msg>Added removal of reminder<commit_after>var moment = require('moment');
var remind = function(){
    this.name = 'remind';
    this.displayname = 'Remind';
    this.description = 'Set reminders for yourself';
}

remind.prototype.init = function() {
    var self = this;
    this.listen('set reminder to (.+) in (.+?) (seconds|minutes|hours|days)', 'standard', function(from, interface, params){
        var crontime = moment().add(params[1], params[2]).toDate();

        var id = self.api.addCronJob(crontime, function(){
            self.sendMessage(params[0], interface, from);
        });

        self.sendMessage('Reminder added with ID ' + id, interface, from);
    });

    this.listen('cancel reminder ([0-9]+)', 'standard', function(from, interface, params){
        self.api.stopCronJob(params[0]);

        self.sendMessage('Reminder with ID ' + params[0] + ' removed', interface, from);
    });
}

module.exports = remind;
<|endoftext|>


<commit_before>var express = require('express');
var app = express();
var cors = require('cors');

app.use(cors());
// var allowCrossDomain = function(req, res, next) {
//     res.header('Access-Control-Allow-Origin', '*');
//     res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
//     res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With');

//     // intercept OPTIONS method
//     if ('OPTIONS' == req.method) {
//       res.send(200);
//     }
//     else {
//       next();
//     }
// };
// app.configure(function(){
//   app.use(allowCrossDomain);
// });

var db = require('./db.json');

app.set('port', (process.env.PORT || 5000));

app.get('/api', function(req, res){
	res.send(db);
});
app.listen(app.get('port'), function() {
  console.log('Node app is running on port', app.get('port'));
});<commit_msg>remove cors<commit_after>var express = require('express');
var app = express();

var allowCrossDomain = function(req, res, next) {
    res.header('Access-Control-Allow-Origin', '*');
    res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
    res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With');

    // intercept OPTIONS method
    if ('OPTIONS' == req.method) {
      res.send(200);
    }
    else {
      next();
    }
};
app.configure(function(){
  app.use(allowCrossDomain);
  app.use(app.router);
});

var db = require('./db.json');

app.set('port', (process.env.PORT || 5000));

app.get('/api', function(req, res){
	res.send(db);
});
app.listen(app.get('port'), function() {
  console.log('Node app is running on port', app.get('port'));
});<|endoftext|>


<commit_before>/*!
 * middleware-utils <https://github.com/jonschlinkert/middleware-utils>
 *
 * Copyright (c) 2015, Jon Schlinkert.
 * Licensed under the MIT License.
 */

'use strict';

var async = require('async');
var chalk = require('chalk');

/**
 * Run middleware in series
 *
 * ```js
 * var middleware = require('./middleware/');
 *
 * template.onLoad(/\.js$/, utils.series([
 *   middleware.foo,
 *   middleware.bar,
 *   middleware.baz,
 * ]));
 * ```
 * @param {Array} `fns` Array of middleware functions
 * @api public
 */

exports.series = function series(fns) {
  return function (file, cb) {
    async.eachSeries(fns, function (fn, next) {
      fn(file, next);
    }, cb);
  };
};

/**
 * Run middleware in parallel.
 *
 * ```js
 * var middleware = require('./middleware/');
 *
 * template.onLoad(/\.js$/, utils.parallel([
 *   middleware.foo,
 *   middleware.bar,
 *   middleware.baz,
 * ]));
 * ```
 * @param {Array} `fns` Array of middleware functions
 * @api public
 */

exports.parallel = function parallel(fns) {
  return function (file, cb) {
    async.each(fns, function (fn, next) {
      fn(file, next);
    }, cb);
  };
};

/**
 * Output a formatted middleware error.
 *
 * ```js
 * template.postRender(/./, function (file, next) {
 *   // do stuff to file
 *   next();
 * }, utils.error('postRender'));
 * ```
 *
 * @param {String} `methodName` The middleware method name (verb)
 * @api public
 */

exports.error = function error(methodName) {
  if (typeof methodName !== 'string') {
    throw new Error('middleware-utils.error() expects `methodName` to be a string.');
  }
  return function (err, file, next) {
    if (err) console.log(chalk.red('.%s middleware error: %s\nFile: %j:'), methodName, err, file);
    next();
  };
};

/**
 * Handle middleware errors for the `.handle()` method.
 *
 * ```js
 * template.handle('onFoo', file, utils.handleError(file, 'onFoo'));
 * ```
 *
 * @param {Object} `file` Vinyl file object or template object.
 * @param {String} `methodName` The middleware method name (verb)
 * @api public
 */

exports.handleError = function handleError(file, methodName) {
  if (typeof methodName !== 'string') {
    throw new Error('middleware-utils.handleError() expects `methodName` to be a string.');
  }
  return function (err) {
    if (err) {
      console.log(chalk.red('Error running `' + methodName + '` middleware for:'), file.path);
      console.log(chalk.red(err));
    }
  };
};

/**
 * Escape/unescape delimiters
 */

exports.delims = function delims(options) {
  options = options || {};
  options.escapeString = options.escapeString || '__UTILS_DELIM__';
  options.from = options.from || '{%%';
  options.to = options.to || '{%';
  var res = {};

  // escape
  res.escape = function escape(from) {
    from = from || options.from;
    return function(file, next) {
      file.content = file.content.split(from).join(options.escapeString);
      next();
    };
  };

  // unscape
  res.unescape = function unescape(to) {
    to = to || options.to;

    return function(file, next) {
      file.content = file.content.split(options.escapeString).join(to);
      next();
    };
  };
  return res;
};
<commit_msg>loge errors to stderr<commit_after>/*!
 * middleware-utils <https://github.com/jonschlinkert/middleware-utils>
 *
 * Copyright (c) 2015, Jon Schlinkert.
 * Licensed under the MIT License.
 */

'use strict';

var async = require('async');
var chalk = require('chalk');

/**
 * Run middleware in series
 *
 * ```js
 * var middleware = require('./middleware/');
 *
 * template.onLoad(/\.js$/, utils.series([
 *   middleware.foo,
 *   middleware.bar,
 *   middleware.baz,
 * ]));
 * ```
 * @param {Array} `fns` Array of middleware functions
 * @api public
 */

exports.series = function series(fns) {
  return function (file, cb) {
    async.eachSeries(fns, function (fn, next) {
      fn(file, next);
    }, cb);
  };
};

/**
 * Run middleware in parallel.
 *
 * ```js
 * var middleware = require('./middleware/');
 *
 * template.onLoad(/\.js$/, utils.parallel([
 *   middleware.foo,
 *   middleware.bar,
 *   middleware.baz,
 * ]));
 * ```
 * @param {Array} `fns` Array of middleware functions
 * @api public
 */

exports.parallel = function parallel(fns) {
  return function (file, cb) {
    async.each(fns, function (fn, next) {
      fn(file, next);
    }, cb);
  };
};

/**
 * Output a formatted middleware error.
 *
 * ```js
 * template.postRender(/./, function (file, next) {
 *   // do stuff to file
 *   next();
 * }, utils.error('postRender'));
 * ```
 *
 * @param {String} `methodName` The middleware method name (verb)
 * @api public
 */

exports.error = function error(methodName) {
  if (typeof methodName !== 'string') {
    throw new Error('middleware-utils.error() expects `methodName` to be a string.');
  }
  return function (err, file, next) {
    var message = yellow('.%s middleware error:\n%s\nFile: %s:');
    if (err) console.error(message, methodName, err, JSON.stringify(file, null, 2));
    next();
  };
};

/**
 * Handle middleware errors for the `.handle()` method.
 *
 * ```js
 * template.handle('onFoo', file, utils.handleError(file, 'onFoo'));
 * ```
 *
 * @param {Object} `file` Vinyl file object or template object.
 * @param {String} `methodName` The middleware method name (verb)
 * @api public
 */

exports.handleError = function handleError(file, methodName) {
  if (typeof methodName !== 'string') {
    throw new Error('middleware-utils.handleError() expects `methodName` to be a string.');
  }
  return function (err) {
    if (err) {
      console.error(red('Error running `' + methodName + '` middleware for:'), file.path);
      throw err;
    }
  };
};

/**
 * Escape/unescape delimiters
 */

exports.delims = function delims(options) {
  options = options || {};
  options.escapeString = options.escapeString || '__UTILS_DELIM__';
  options.from = options.from || '{%%';
  options.to = options.to || '{%';
  var res = {};

  // escape
  res.escape = function escape(from) {
    from = from || options.from;
    return function(file, next) {
      file.content = file.content.split(from).join(options.escapeString);
      next();
    };
  };

  // unscape
  res.unescape = function unescape(to) {
    to = to || options.to;
    return function(file, next) {
      file.content = file.content.split(options.escapeString).join(to);
      next();
    };
  };
  return res;
};
<|endoftext|>


<commit_before>// See https://github.com/alexmingoia/koa-resource-router
var koa = require('koa')
  , mount = require('koa-mount')
  , router = require('koa-router')
  , jsonBody = require('koa-parse-json');

module.exports = setup
module.exports.consumes = ['http', 'orm', 'auth']

function setup(plugin, imports, register) {
  var httpApp = imports.http
    , orm = imports.orm
    , auth = imports.auth

  var api = koa()
  httpApp.use(mount('/api', api))

  api.use(jsonBody())

  var APIv1 = koa()
  api.use(mount('/v1', APIv1))
  APIv1.use(router(APIv1))

  var Document = orm.collections.document
    , Snapshot = orm.collections.snapshot
    , User = orm.collections.user
    , PendingChange = orm.collections.pendingChange

  var authenticate = function*(next) {
    this.user = yield auth.authenticate('oauth', this.request.query.token) //XXX: good idea?
    yield next
  }

  APIv1
    .post('/documents', authenticate, function*(next) {
        if(!this.accepts('json')) {
         return this.throw(406)
        }
        if(!yield auth.authorize(this.user, 'document:create', this.params)) {
         return this.throw(403)
        }
        var doc = yield Document.create({
          type: this.body.type
        })
        yield Snapshot.createInitial(doc.id) // XXX
      })
    .get('/documents/:document', authenticate, function * (next) {
        if(!yield auth.authorize(this.user, 'document:show', this.params)) {
          return this.throw(403)
        }
        try {
          return yield Document.findOne(this.params.document) // XXX: Might require Document.exists() beforehand to not make it throw up
        }catch(e){
          e.status = 404
          throw e
          yield next
        }
      })
    .delete('/documents/:document', authenticate, function * (next) {
        if(!yield auth.authorize(this.user, 'document:destroy'. this.params)) {
          return this.throw(403)
        }
        try {
          return ( yield Document.findOne(this.params.document) ).destroy()
        }catch(e){
          this.status = 404
          yield next
        }
      })

    .post('/documents/:document/pendingChanges', authenticate, function * (next) {
        if(!yield auth.authorize(this.user, 'document/pendingChanges:create', this.params)) {
          return this.throw(403)
        }
        if(!this.accepts('json')) {
         return this.throw(406)
        }
        var doc = yield Document.findOne(this.params.document) // XXX: 404

        yield doc.pendingChanges.add({
         changes: this.request.body.changes
        , parent: this.request.body.parent
        , user: this.request.body.user // XXX: What if I'm admin and req.body.user != this.user
        })
      })

    .get('/documents/:document/users', authenticate, function * (next) {
        if(!yield auth.authorize(this.user, 'document/users:index', this.params)) {
          return this.throw(403)
        }
        var doc = yield Document.findOne(this.params.document)
        this.body = doc.users
      })

    .get('/documents/:document/snapshots', authenticate, function * (next) {
        if(!yield auth.authorize(this.user, 'document/snapshots:index', this.params)) {
          return this.throw(403)
        }
        var doc = yield Document.findOne(this.params.document)
        this.body = doc.snapshots
      })

    .post('/users', authenticate, function*(next) {
        if(!this.accepts('json')) {
        return this.throw(406)
        }
        if(!yield auth.authorize(this.user, 'user:create', this.params)) {
        return this.throw(403)
        }
        var doc = yield User.create({
          name: this.body.name
        , type: this.body.type
        , foreignId: this.body.foreignId
        })
        yield Snapshot.createInitial(doc.id) // XXX
      })
    .get('/users/:user', authenticate, function*(next) {
        if(!yield auth.authorize(this.user, 'user:show', this.params)) {
          return this.throw(403)
        }
        try {
          return yield User.findOne(this.params.document) // XXX: Might require Document.exists() beforehand to not make it throw up
        }catch(e){
          e.status = 404
          throw e
          yield next
        }
      })

    .put('/users/:user', authenticate, function*(next) {
        // XXX
      })
    .delete('/users/:user', authenticate, function * (next) {
        if(!yield auth.authorize(this.user, 'user:destroy', this.params)) {
          return this.throw(403)
        }
        return ( yield User.find(this.params.user) ).destroy()
      })

    .get('/users/:user/documents', authenticate, function*(next) {
        if(!yield auth.authorize(this.user, 'user/documents:index', this.params)) {
          return this.throw(403)
        }
        this.body = yield Document.find({where: {authors: this.params.user}})
      })

    .get('/users/:user/snapshots', authenticate, function * () {
        if(!yield auth.authorize(this.user, 'user/snapshots:index', this.params)) {
          return this.throw(403)
        }
        this.body = yield Snapshot.find({where: {author: this.params.user}})
      })

    .get('/snapshots/:snapshot', authenticate, function * () {
        if(!yield auth.authorize(this.user, 'snapshot:show', this.params)) {
          return this.throw(403)
        }
        try {
          return yield Snapshot.findOne(this.params.snapshot) // XXX: Might require Document.exists() beforehand to not make it throw up
        }catch(e){
          e.status = 404
          throw e
          yield next
        }
      })

  register()
}
<commit_msg>refactor<commit_after>var koa = require('koa')
  , mount = require('koa-mount')
  , router = require('koa-router')
  , jsonBody = require('koa-parse-json');

module.exports = setup
module.exports.consumes = ['http', 'orm', 'auth']

function setup(plugin, imports, register) {
  var httpApp = imports.http
    , orm = imports.orm
    , auth = imports.auth

  var api = koa()
  httpApp.use(mount('/api', api))

  var APIv1 = koa()
  api.use(mount('/v1', APIv1))
  APIv1.use(router(APIv1))

  var Document = orm.collections.document
    , Snapshot = orm.collections.snapshot
    , User = orm.collections.user
    , PendingChange = orm.collections.pendingChange

  APIv1.use(jsonBody())

  APIv1.use(function *(next) {
    try {
      yield next;
    } catch (err) {
      this.status = err.status || 500;
      this.body = {message: err.message};
      this.app.emit('error', err, this);
    }
  })

  APIv1.use(function* (next) {
    this.user = yield auth.authenticate('oauth',
      this.request.query.access_token || this.get('Authorization').split(' ')[1]
    )
    if(!this.user) {
      return this.throw(401)
    }
    yield next
  })

  APIv1
    .post('/documents', function*(next) {
        if(!this.accepts('json')) {
         return this.throw(406)
        }
        if(!yield auth.authorize(this.user, 'document:create', this.params)) {
         return this.throw(403)
        }
        var doc = yield Document.create({
          type: this.body.type
        })
        yield Snapshot.createInitial(doc.id) // XXX
      })
    .get('/documents/:document', function * (next) {
        if(!yield auth.authorize(this.user, 'document:show', this.params)) {
          return this.throw(403)
        }
        try {
          return yield Document.findOne(this.params.document)
          // XXX: Might require Document.exists() beforehand to not
          //       make it throw up
        }catch(e){
          e.status = 404
          throw e
          yield next
        }
      })
    .delete('/documents/:document', function * (next) {
        if(!yield auth.authorize(this.user, 'document:destroy'. this.params)) {
          return this.throw(403)
        }
        try {
          return ( yield Document.findOne(this.params.document) ).destroy()
        }catch(e){
          this.status = 404
          yield next
        }
      })

    .post('/documents/:document/pendingChanges', function * (next) {
        if(!yield auth.authorize(this.user, 'document/pendingChanges:create', this.params)) {
          return this.throw(403)
        }
        if(!this.accepts('json')) {
         return this.throw(406)
        }
        var doc = yield Document.findOne(this.params.document) // XXX: 404

        yield doc.pendingChanges.add({
         changes: this.request.body.changes
        , parent: this.request.body.parent
        , user: this.request.body.user // XXX: What if I'm admin and req.body.user != this.user
        })
      })

    .get('/documents/:document/users', function * (next) {
        if(!yield auth.authorize(this.user, 'document/users:index', this.params)) {
          return this.throw(403)
        }
        var doc = yield Document.findOne(this.params.document)
        this.body = doc.users
      })

    .get('/documents/:document/snapshots', function * (next) {
        if(!yield auth.authorize(this.user, 'document/snapshots:index', this.params)) {
          return this.throw(403)
        }
        var doc = yield Document.findOne(this.params.document)
        this.body = doc.snapshots // XXX: Allow streamin'
      })

    .post('/users', function*(next) {
        if(!this.accepts('json')) {
        return this.throw(406)
        }
        if(!yield auth.authorize(this.user, 'user:create', this.params)) {
        return this.throw(403)
        }
        var doc = yield User.create({
          name: this.body.name
        , type: this.body.type
        , foreignId: this.body.foreignId
        })
        yield Snapshot.createInitial(doc.id) // XXX
      })
    .get('/users/:user', function*(next) {
        if(!yield auth.authorize(this.user, 'user:show', this.params)) {
          return this.throw(403)
        }
        try {
          return yield User.findOne(this.params.document) // XXX: Might require Document.exists() beforehand to not make it throw up
        }catch(e){
          e.status = 404
          throw e
          yield next
        }
      })

    .put('/users/:user', function*(next) {
        // XXX
      })
    .delete('/users/:user', function * (next) {
        if(!yield auth.authorize(this.user, 'user:destroy', this.params)) {
          return this.throw(403)
        }
        return ( yield User.find(this.params.user) ).destroy()
      })

    .get('/users/:user/documents', function*(next) {
        if(!yield auth.authorize(this.user, 'user/documents:index', this.params)) {
          return this.throw(403)
        }
        this.body = yield Document.find({where: {authors: this.params.user}})
      })

    .get('/users/:user/snapshots', function * () {
        if(!yield auth.authorize(this.user, 'user/snapshots:index', this.params)) {
          return this.throw(403)
        }
        this.body = yield Snapshot.find({where: {author: this.params.user}})
      })

    .get('/snapshots/:snapshot', function * () {
        if(!yield auth.authorize(this.user, 'snapshot:show', this.params)) {
          return this.throw(403)
        }
        try {
          return yield Snapshot.findOne(this.params.snapshot) // XXX: Might require Document.exists() beforehand to not make it throw up
        }catch(e){
          e.status = 404
          throw e
          yield next
        }
      })

  register()
}
<|endoftext|>


<commit_before>var video = document.querySelector('#video');
var audio = document.querySelector('#audio');
var playButton = document.querySelector('#play-button');
var isPlaying = true;

var toggleState = function() {
  if(isPlaying) {
    video.pause();
    audio.pause();
  } else {
    video.play();
    audio.play();
  }
  isPlaying = !isPlaying;
};

playButton.addEventListener('click', function() {
  toggleState();
})
<commit_msg>Change button label dynamically<commit_after>var video = document.querySelector('#video');
var audio = document.querySelector('#audio');
var playButton = document.querySelector('#play-button');
var isPlaying = true;

var toggleState = function() {
  if(isPlaying) {
    video.pause();
    audio.pause();
    playButton.innerHTML = 'Play'
  } else {
    video.play();
    audio.play();
    playButton.innerHTML = 'Pause';
  }
  isPlaying = !isPlaying;
};

playButton.addEventListener('click', function() {
  toggleState();
})
<|endoftext|>


<commit_before>'use strict';

var _ = require('underscore-contrib');
var Promise = require('pacta').Promise;
var questor = require('questor');
var redefine = require('redefine');
var querystring = require('querystring');

var Client = redefine.Class({
  constructor: function Client(options) {
    enforcep(options, 'accessToken');
    enforcep(options, 'space');

    this.options = _.defaults({}, options, {
      host: 'cdn.contentful.com',
      secure: true
    });
  },

  request: function(path) {
    var uri = [
      this.options.secure ? 'https' : 'http',
      '://',
      this.options.host,
      '/spaces/',
      this.options.space,
      path
    ].join('');

    var options = {
      headers: {
        Authorization: 'Bearer ' + this.options.accessToken,
        'Content-Type': 'application/vnd.contentful.v1+json'
      }
    };

    var promise = new Promise();
    var request = questor(uri, options);
    request.onRejected(function(reason) {
      if (reason instanceof Error) return reason;
      return parseJSONBody(reason);
    }).map(_.bound(promise, 'reject'));
    request.map(parseJSONBody).map(_.bound(promise, 'resolve'));
    return promise;
  },

  contentType: function(id) {
    var promise = new Promise();
    var request = this.request('/content_types/' + id);
    request.map(ContentType.parse).map(_.bound(promise, 'resolve'));
    request.onRejected(_.bound(promise, 'reject'));
    return promise;
  },

  contentTypes: function(object) {
    var query = Query.parse(object);
    var promise = new Promise();
    var request = this.request('/content_types' + (object ? '?' + query.toQueryString() : ''));
    request.map(_.partial(SearchResult.parse, ContentType))
           .map(_.bound(promise, 'resolve'));
    request.onRejected(_.bound(promise, 'reject'));
    return promise;
  },

  entry: function(id) {
    var promise = new Promise();
    var request = this.request('/entries/' + id);
    request.map(Entry.parse).map(_.bound(promise, 'resolve'));
    request.onRejected(_.bound(promise, 'reject'));
    return promise;
  },

  entries: function(object) {
    var query = Query.parse(object);
    var promise = new Promise();
    var request = this.request('/entries' + (object ? '?' + query.toQueryString() : ''));
    request.map(_.partial(SearchResult.parse, Entry))
           .map(_.bound(promise, 'resolve'));
    request.onRejected(_.bound(promise, 'reject'));
    return promise;
  },

  space: function() {
    var promise = new Promise();
    var request = this.request('');
    request.map(_.bound(promise, 'resolve'));
    request.onRejected(_.bound(promise, 'reject'));
    return promise;
  }
});

var Entry = redefine.Class({
  constructor: function Entry() {},

  statics: {
    parse: function(object) {
      return _.extend(new Entry(), {
        sys: Sys.parse(object.sys),
        fields: object.fields
      });
    }
  }
});

var ContentType = redefine.Class({
  constructor: function ContentType() {},

  statics: {
    parse: function(object) {
      return _.extend(new ContentType(), {
        sys: Sys.parse(object.sys),
        fields: object.fields.map(Field.parse),
      }, _.pick(object, 'name', 'displayField'));
    }
  }
});

var Field = redefine.Class({
  constructor: function Field() {},

  statics: {
    parse: function(object) {
      return _.extend(new Field(), object);
    }
  }
});

var SearchResult = redefine.Class({
  constructor: function SearchResult() {},

  statics: {
    parse: function(ItemType, object) {
      return redefine(
        _.map(object.items, ItemType.parse), {
          limit: object.limit,
          skip: object.skip,
          total: object.total
        }, {
          enumerable: false
        }
      );
    }
  }
});

var Query = redefine.Class({
  constructor: function Query() {},

  toQueryString: function() {
    return querystring.stringify(this);
  },

  statics: {
    parse: function(object) {
      return _.extend(new Query(), object);
    },
  }
});

var Space = redefine.Class({
  constructor: function Space() {},

  statics: {
    parse: function(object) {
      return _.extend(new Space(), object);
    }
  }
});

var Sys = redefine.Class({
  constructor: function Sys() {},

  statics: {
    parse: function(object) {
      return _.extend(
        new Sys(),
        _.pick(object, 'id', 'revision', 'type', 'locale'),
        compacto({
          contentType: object.contentType && Link.parse(object.contentType),
          createdAt: object.createdAt && new Date(object.createdAt),
          linkType: object.linkType,
          updatedAt: object.createdAt && new Date(object.createdAt),
          space: object.space && Link.parse(object.space)
        })
      );
    }
  }
});

var Link = redefine.Class({
  constructor: function Link() {},

  statics: {
    parse: function(object) {
      return _.extend(new Link(), {
        sys: Sys.parse(object.sys)
      });
    }
  }
});

exports.createClient = _.fnull(function(options) {
  return new Client(options);
}, {});

function compacto(object) {
  return _.reduce(object, function(compacted, value, key) {
    if (_.truthy(value)) compacted[key] = value;
    return compacted;
  }, {});
}

function enforcep(object, property) {
  if (!_.exists(object[property]))
    throw new TypeError('Expected property ' + property);
}

function parseJSONBody(response) {
  return JSON.parse(response.responseText);
}
<commit_msg>Join array values in query object<commit_after>'use strict';

var _ = require('underscore-contrib');
var Promise = require('pacta').Promise;
var questor = require('questor');
var redefine = require('redefine');
var querystring = require('querystring');

var Client = redefine.Class({
  constructor: function Client(options) {
    enforcep(options, 'accessToken');
    enforcep(options, 'space');

    this.options = _.defaults({}, options, {
      host: 'cdn.contentful.com',
      secure: true
    });
  },

  request: function(path) {
    var uri = [
      this.options.secure ? 'https' : 'http',
      '://',
      this.options.host,
      '/spaces/',
      this.options.space,
      path
    ].join('');

    var options = {
      headers: {
        Authorization: 'Bearer ' + this.options.accessToken,
        'Content-Type': 'application/vnd.contentful.v1+json'
      }
    };

    var promise = new Promise();
    var request = questor(uri, options);
    request.onRejected(function(reason) {
      if (reason instanceof Error) return reason;
      return parseJSONBody(reason);
    }).map(_.bound(promise, 'reject'));
    request.map(parseJSONBody).map(_.bound(promise, 'resolve'));
    return promise;
  },

  contentType: function(id) {
    var promise = new Promise();
    var request = this.request('/content_types/' + id);
    request.map(ContentType.parse).map(_.bound(promise, 'resolve'));
    request.onRejected(_.bound(promise, 'reject'));
    return promise;
  },

  contentTypes: function(object) {
    var query = Query.parse(object);
    var promise = new Promise();
    var request = this.request('/content_types' + (object ? '?' + query.toQueryString() : ''));
    request.map(_.partial(SearchResult.parse, ContentType))
           .map(_.bound(promise, 'resolve'));
    request.onRejected(_.bound(promise, 'reject'));
    return promise;
  },

  entry: function(id) {
    var promise = new Promise();
    var request = this.request('/entries/' + id);
    request.map(Entry.parse).map(_.bound(promise, 'resolve'));
    request.onRejected(_.bound(promise, 'reject'));
    return promise;
  },

  entries: function(object) {
    var query = Query.parse(object);
    var promise = new Promise();
    var request = this.request('/entries' + (object ? '?' + query.toQueryString() : ''));
    request.map(_.partial(SearchResult.parse, Entry))
           .map(_.bound(promise, 'resolve'));
    request.onRejected(_.bound(promise, 'reject'));
    return promise;
  },

  space: function() {
    var promise = new Promise();
    var request = this.request('');
    request.map(_.bound(promise, 'resolve'));
    request.onRejected(_.bound(promise, 'reject'));
    return promise;
  }
});

var Entry = redefine.Class({
  constructor: function Entry() {},

  statics: {
    parse: function(object) {
      return _.extend(new Entry(), {
        sys: Sys.parse(object.sys),
        fields: object.fields
      });
    }
  }
});

var ContentType = redefine.Class({
  constructor: function ContentType() {},

  statics: {
    parse: function(object) {
      return _.extend(new ContentType(), {
        sys: Sys.parse(object.sys),
        fields: object.fields.map(Field.parse),
      }, _.pick(object, 'name', 'displayField'));
    }
  }
});

var Field = redefine.Class({
  constructor: function Field() {},

  statics: {
    parse: function(object) {
      return _.extend(new Field(), object);
    }
  }
});

var SearchResult = redefine.Class({
  constructor: function SearchResult() {},

  statics: {
    parse: function(ItemType, object) {
      return redefine(
        _.map(object.items, ItemType.parse), {
          limit: object.limit,
          skip: object.skip,
          total: object.total
        }, {
          enumerable: false
        }
      );
    }
  }
});

var Query = redefine.Class({
  constructor: function Query() {},

  toQueryString: function() {
    return querystring.stringify(this);
  },

  statics: {
    parse: function(object) {
      return _.extend(new Query(), stringifyArrayValues(object));
    },
  }
});

var Space = redefine.Class({
  constructor: function Space() {},

  statics: {
    parse: function(object) {
      return _.extend(new Space(), object);
    }
  }
});

var Sys = redefine.Class({
  constructor: function Sys() {},

  statics: {
    parse: function(object) {
      return _.extend(
        new Sys(),
        _.pick(object, 'id', 'revision', 'type', 'locale'),
        compacto({
          contentType: object.contentType && Link.parse(object.contentType),
          createdAt: object.createdAt && new Date(object.createdAt),
          linkType: object.linkType,
          updatedAt: object.createdAt && new Date(object.createdAt),
          space: object.space && Link.parse(object.space)
        })
      );
    }
  }
});

var Link = redefine.Class({
  constructor: function Link() {},

  statics: {
    parse: function(object) {
      return _.extend(new Link(), {
        sys: Sys.parse(object.sys)
      });
    }
  }
});

exports.createClient = _.fnull(function(options) {
  return new Client(options);
}, {});

function compacto(object) {
  return _.reduce(object, function(compacted, value, key) {
    if (_.truthy(value)) compacted[key] = value;
    return compacted;
  }, {});
}

function enforcep(object, property) {
  if (!_.exists(object[property]))
    throw new TypeError('Expected property ' + property);
}

function parseJSONBody(response) {
  return JSON.parse(response.responseText);
}

function stringifyArrayValues(object) {
  return _.reduce(object, function(object, value, key) {
    object[key] = _.isArray(value) ? value.join(',') : value;
    return object;
  }, {});
}
<|endoftext|>


<commit_before>var images = [], x = -1;
images[0] = "assets/images/me2.png";
images[1] = "assets/images/me3.png";
images[2] = "assets/images/me1.png";

function displayNextImage() {
    x = (x === images.length - 1) ? 0 : x + 1;
    document.getElementById("img").src = images[x];
}

function startTimer() {
    setInterval(displayNextImage, 7500);
}<commit_msg>index: Diminuição do tempo de rotação do banner<commit_after>var images = [], x = -1;
images[0] = "assets/images/me2.png";
images[1] = "assets/images/me3.png";
images[2] = "assets/images/me1.png";

function displayNextImage() {
    x = (x === images.length - 1) ? 0 : x + 1;
    document.getElementById("img").src = images[x];
}

function startTimer() {
    setInterval(displayNextImage, 5000);
}<|endoftext|>