<commit_before>/*
Copyright (c) 2012, Carlos Brito Lage
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.
    * The name of the author may not be used to endorse or promote products
      derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

if (module) {
	module.exports = Cachelicious;
}

var http = require('http');
var fs = require('fs');
var path = require('path');
var LRU = require("lru-cache");
var util = require("util");
var events = require("events");
var stream = require("stream");

function CacheStreamConsumer(id, response, readOffset) {
	this.id = id;
	this.paused = false;
	this.readOffset = undefined === readOffset ? 0 : readOffset;
	this.response = response;
	var self = this;
	this.backoff = 1;

	this.response.on('drain', function() {
		// Resume the read stream when the write stream gets hungry
		self.resume();
	});
}

CacheStreamConsumer.prototype.setCacheStream = function (stream)
{
	this.cacheStream = stream;
	this.maxOffset = stream.size;
	//when adding new consumers, set a 5ms timeout per each consumer in queue, plus a 5ms baseline, to prevent them from starving previously existing consumers
	var self = this;
	setTimeout(function () {
		self.tick();
	}, 6);
	//right now, hardcoding a number, but should use a formula based on the file size plus the number of consumers in queue
	//something like this this.cacheStream.consumerCount * Math.max(4, Math.ceil(this.maxOffset/(1024*650)))
};

CacheStreamConsumer.prototype.tick = function ()
{
	if (this.paused) {
		return;
	}

	if (this.readOffset < this.cacheStream.writeOffset) {
		this.backoff = 1; //reset the backoff factor
		//console.log("emitting data for requestId:" + this.id);

		var data = this.cacheStream.buffer.slice(this.readOffset, this.cacheStream.writeOffset);
		this.readOffset = this.cacheStream.writeOffset;

		if (this.readOffset === this.maxOffset) {
			//console.log(this.id + ": ended streaming");
			this.end(data);
			return;
		}

		if (false === this.response.write(data)) {
			//console.log(requestId + ": Pausing stream...")
			this.pause();
			return;
		}

		//this.emit('data', data);

		if (this.paused) {
			return;
		}
	}

	//we drained the buffer, let's give it some time to breathe
	//console.log(this.backoff);
	var self = this;
	setTimeout(function () {
		self.tick();
	}, 15*this.backoff);

	++this.backoff; //lets backoff the buffer drainers so they give the buffer sometime to increase
};

CacheStreamConsumer.prototype.end = function (data)
{
	this.response.end(data);
	this.cacheStream.removeConsumer(this);
};

CacheStreamConsumer.prototype.pause = function ()
{
	this.paused = true;
};

CacheStreamConsumer.prototype.resume = function ()
{
	this.paused = false;
	//if the response asked to be resumed, lets prioritize it in this tick
	this.tick();
};

function CacheStream(size) {
	events.EventEmitter.call(this);
	this.buffer = new Buffer(size);
	this.size = size;
	this.writeOffset = 0;
	this.consumers = {};
	this.consumerCount = 0;
	this.writable = true;
}

util.inherits(CacheStream, stream.Stream);

CacheStream.prototype.addConsumer = function (consumer)
{
	consumer.setCacheStream(this);
	this.consumers[consumer.id] = consumer;
	this.consumerCount++;
};

CacheStream.prototype.removeConsumer = function (consumer)
{
	this.consumerCount--;
	delete this.consumers[consumer.id];
};

CacheStream.prototype.write = function(data)
{
	if (!this.writable) {
		//console.log("rejecting write because we ended already")
		return;
	}

	var writtenBytes;
	if (Buffer.isBuffer(data)) {
		//console.log("writing buffer data " + data.length + " bytes to offset: " + this.writeOffset);
		data.copy(this.buffer, this.writeOffset);
		writtenBytes = data.length;
	} else {
		//console.log("writing " + Buffer.byteLength(data) + " bytes to offset: " + this.writeOffset);
		writtenBytes = this.buffer.write(data, this.writeOffset);
	}
	this.writeOffset+= writtenBytes;

	//this.emit('data', data);
	//console.log("wrote " + writtenBytes + " bytes into buffer");
	//console.log("new offset" + this.writeOffset);
};

CacheStream.prototype.end = function()
{
	//console.log("ended!");
	this.writable = false;
	//this.emit('end');
};

function defaultPathFinder (request)
{
	var filepath = '.';
	if ('/' === request.url) {
		filepath += '/index.html';
	} else {
		filepath += request.url;
	}
	return filepath;
}

function defaultContentTypeFinder (filepath)
{
	var extname = path.extname(filepath).toLowerCase();
	switch (extname) {
		case '.js':
			return 'text/javascript';
		case '.css':
			return 'text/css';
		case '.jpeg':
		case '.jpg':
			return 'image/jpeg';
	}
	return 'text/html';
}

function Cachelicious (pathFinder, contentTypeFinder, port, maxCacheSize)
{
	this.init(pathFinder, contentTypeFinder, port, maxCacheSize)
}

util.inherits(Cachelicious, events.EventEmitter);

Cachelicious.prototype.init = function (pathFinder, contentTypeFinder, port, maxCacheSize)
{
	var self = this;

	if (typeof pathFinder === 'undefined') {
		pathFinder = defaultPathFinder;
	}

	if (typeof contentTypeFinder === 'undefined') {
		contentTypeFinder = defaultContentTypeFinder;
	}

	if (typeof port === 'undefined') {
		port = 9876;
	}

	if (typeof maxCacheSize === 'undefined') {
		maxCacheSize = 20971520; //20mb
	}

	if (maxCacheSize !== false) {
		this.cache = LRU(maxCacheSize, function (cacheStream) {
			return cacheStream.size;
		});
	} else {
		this.cache = false;
	}

	this.port = port;
	this.requestStreamId = 0;
	this.pathFinder = pathFinder;
	this.contentTypeFinder = contentTypeFinder;

	this.server = http.createServer(function (request, response) {
		self.dispatch(request, response);
	});
};

Cachelicious.prototype.start = function ()
{
	this.server.listen(this.port);
	console.log('Server running at http://127.0.0.1:' + this.port);
};

Cachelicious.prototype.stop = function ()
{
	this.server.close();
	console.log('Server shut down');
};

Cachelicious.prototype.dispatch = function (request, response)
{
	var filepath = this.pathFinder(request), contentType;

	if (null === filepath) {
		this.serveError(request.method, response, 404);
		return;
	}

	contentType = this.contentTypeFinder(filepath);

	this.streamPath(filepath, contentType, request.method, response);
};

Cachelicious.prototype.fileCheck = function (filepath, successCb, errorCb)
{
	//console.log('running stat on:' + filepath)
	var self = this;
	fs.stat(filepath, function (error, stat) {
		if (null !== error) {
			if (errorCb) {
				errorCb(404);
			}
			return false;
		}

		if (undefined === stat) {
			if (errorCb) {
				errorCb(500);
			}
			return false;
		}

		if (!stat.isFile()) {
			if (errorCb) {
				errorCb(401);
			}
			return false;
		}
		successCb(stat);
		return true;
	});
};

Cachelicious.prototype.streamPath = function (filepath, contentType, method, response)
{
	if (false === this.cache) {
		this.asyncServeUncachedStream(filepath, contentType, method, response);
		return;
	}

	this.requestStreamId++;

	var
		requestId = "r-" + this.requestStreamId,
		cachedStream = this.getCached(filepath),
		self = this;

	if (undefined !== cachedStream) {
		self.asyncServeCachedStream(cachedStream, contentType, method, requestId, response);
		return;
	}

	this.once('fileCheckSuccess-' + filepath, function (cachedStream) {
		self.asyncServeCachedStream(cachedStream, contentType, method, requestId, response);
	});

	this.once('fileCheckError-' + filepath, function (error) {
		self.serveError(method, response, error);
	});

	this.fileCheck(filepath,
		function (stat)
		{
			var newStream = new CacheStream(stat.size);
			self.setCached(filepath, newStream);
			fs.createReadStream(filepath).pipe(newStream);

			//console.log('emitting: fileCheckSuccess-' + filepath);
			self.emit('fileCheckSuccess-' + filepath, newStream);
			self.removeAllListeners('fileCheckError-' + filepath);
		},
		function (error)
		{
			//console.log('emitting: fileCheckError-' + filepath);
			self.emit('fileCheckError-' + filepath, error);
			self.removeAllListeners('fileCheckSuccess-' + filepath);
		}
	);
};

Cachelicious.prototype.asyncServeUncachedStream = function (filepath, contentType, method, response)
{
	var self = this;
	this.fileCheck(filepath,
		function (stat) {
			response.writeHead(200, {
				'Content-Type':   contentType,
				'Content-Length': stat.size
			});

			if ('HEAD' !== method) {
				fs.createReadStream(filepath).pipe(response);
			} else {
				response.end();
			}
		},
		function (error) {
			self.serveError(method, response, error);
		}
	);
};

Cachelicious.prototype.asyncServeCachedStream = function (cachedStream, contentType, method, requestId, response)
{
	var self = this;
	process.nextTick(function () {
		self.serveCachedStream(cachedStream, contentType, method, requestId, response);
	});
};

Cachelicious.prototype.serveCachedStream = function (cachedStream, contentType, method, requestId, response)
{
	response.writeHead(200, {
		'Content-Type':   contentType,
		'Content-Length': cachedStream.size,
		'X-Req-Id':       requestId
	});

	if ('HEAD' !== method) {
		cachedStream.addConsumer(new CacheStreamConsumer(requestId, response));
	} else {
		response.end();
	}
};

Cachelicious.prototype.serveError = function (method, response, code)
{
	console.log('error: ' + code);
	response.writeHead(code, {'Content-Type': 'text/html'});
	if ('HEAD' !== method) {
		response.end(""+code, 'utf-8');
	} else {
		response.end();
	}
};

Cachelicious.prototype.getCached = function (filepath)
{
	return this.cache.get(filepath);
};

Cachelicious.prototype.setCached = function (filepath, cacheStream)
{
	this.cache.set(filepath, cacheStream);
	//console.log('Current cache size: ' + Math.round(this.cache.length/(1024*1024)) + 'MB');
};

<commit_msg>Fixed missing constructor calls<commit_after>/*
Copyright (c) 2012, Carlos Brito Lage
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.
    * The name of the author may not be used to endorse or promote products
      derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

if (module) {
	module.exports = Cachelicious;
}

var http = require('http');
var fs = require('fs');
var path = require('path');
var LRU = require("lru-cache");
var util = require("util");
var events = require("events");
var stream = require("stream");

function CacheStreamConsumer(id, response, readOffset) {
	this.id = id;
	this.paused = false;
	this.readOffset = undefined === readOffset ? 0 : readOffset;
	this.response = response;
	var self = this;
	this.backoff = 1;

	this.response.on('drain', function() {
		// Resume the read stream when the write stream gets hungry
		self.resume();
	});
}

CacheStreamConsumer.prototype.setCacheStream = function (stream)
{
	this.cacheStream = stream;
	this.maxOffset = stream.size;
	//when adding new consumers, set a 5ms timeout per each consumer in queue, plus a 5ms baseline, to prevent them from starving previously existing consumers
	var self = this;
	setTimeout(function () {
		self.tick();
	}, 6);
	//right now, hardcoding a number, but should use a formula based on the file size plus the number of consumers in queue
	//something like this this.cacheStream.consumerCount * Math.max(4, Math.ceil(this.maxOffset/(1024*650)))
};

CacheStreamConsumer.prototype.tick = function ()
{
	if (this.paused) {
		return;
	}

	if (this.readOffset < this.cacheStream.writeOffset) {
		this.backoff = 1; //reset the backoff factor
		//console.log("emitting data for requestId:" + this.id);

		var data = this.cacheStream.buffer.slice(this.readOffset, this.cacheStream.writeOffset);
		this.readOffset = this.cacheStream.writeOffset;

		if (this.readOffset === this.maxOffset) {
			//console.log(this.id + ": ended streaming");
			this.end(data);
			return;
		}

		if (false === this.response.write(data)) {
			//console.log(requestId + ": Pausing stream...")
			this.pause();
			return;
		}

		//this.emit('data', data);

		if (this.paused) {
			return;
		}
	}

	//we drained the buffer, let's give it some time to breathe
	//console.log(this.backoff);
	var self = this;
	setTimeout(function () {
		self.tick();
	}, 15*this.backoff);

	++this.backoff; //lets backoff the buffer drainers so they give the buffer sometime to increase
};

CacheStreamConsumer.prototype.end = function (data)
{
	this.response.end(data);
	this.cacheStream.removeConsumer(this);
};

CacheStreamConsumer.prototype.pause = function ()
{
	this.paused = true;
};

CacheStreamConsumer.prototype.resume = function ()
{
	this.paused = false;
	//if the response asked to be resumed, lets prioritize it in this tick
	this.tick();
};

function CacheStream(size) {
	stream.Stream.call(this);
	this.buffer = new Buffer(size);
	this.size = size;
	this.writeOffset = 0;
	this.consumers = {};
	this.consumerCount = 0;
	this.writable = true;
}

util.inherits(CacheStream, stream.Stream);

CacheStream.prototype.addConsumer = function (consumer)
{
	consumer.setCacheStream(this);
	this.consumers[consumer.id] = consumer;
	this.consumerCount++;
};

CacheStream.prototype.removeConsumer = function (consumer)
{
	this.consumerCount--;
	delete this.consumers[consumer.id];
};

CacheStream.prototype.write = function(data)
{
	if (!this.writable) {
		//console.log("rejecting write because we ended already")
		return;
	}

	var writtenBytes;
	if (Buffer.isBuffer(data)) {
		//console.log("writing buffer data " + data.length + " bytes to offset: " + this.writeOffset);
		data.copy(this.buffer, this.writeOffset);
		writtenBytes = data.length;
	} else {
		//console.log("writing " + Buffer.byteLength(data) + " bytes to offset: " + this.writeOffset);
		writtenBytes = this.buffer.write(data, this.writeOffset);
	}
	this.writeOffset+= writtenBytes;

	//this.emit('data', data);
	//console.log("wrote " + writtenBytes + " bytes into buffer");
	//console.log("new offset" + this.writeOffset);
};

CacheStream.prototype.end = function()
{
	//console.log("ended!");
	this.writable = false;
	//this.emit('end');
};

function defaultPathFinder (request)
{
	var filepath = '.';
	if ('/' === request.url) {
		filepath += '/index.html';
	} else {
		filepath += request.url;
	}
	return filepath;
}

function defaultContentTypeFinder (filepath)
{
	var extname = path.extname(filepath).toLowerCase();
	switch (extname) {
		case '.js':
			return 'text/javascript';
		case '.css':
			return 'text/css';
		case '.jpeg':
		case '.jpg':
			return 'image/jpeg';
	}
	return 'text/html';
}

function Cachelicious (pathFinder, contentTypeFinder, port, maxCacheSize)
{
	events.EventEmitter.call(this);
	this.init(pathFinder, contentTypeFinder, port, maxCacheSize)
}

util.inherits(Cachelicious, events.EventEmitter);

Cachelicious.prototype.init = function (pathFinder, contentTypeFinder, port, maxCacheSize)
{
	var self = this;

	if (typeof pathFinder === 'undefined') {
		pathFinder = defaultPathFinder;
	}

	if (typeof contentTypeFinder === 'undefined') {
		contentTypeFinder = defaultContentTypeFinder;
	}

	if (typeof port === 'undefined') {
		port = 9876;
	}

	if (typeof maxCacheSize === 'undefined') {
		maxCacheSize = 20971520; //20mb
	}

	if (maxCacheSize !== false) {
		this.cache = LRU(maxCacheSize, function (cacheStream) {
			return cacheStream.size;
		});
	} else {
		this.cache = false;
	}

	this.port = port;
	this.requestStreamId = 0;
	this.pathFinder = pathFinder;
	this.contentTypeFinder = contentTypeFinder;

	this.server = http.createServer(function (request, response) {
		self.dispatch(request, response);
	});
};

Cachelicious.prototype.start = function ()
{
	this.server.listen(this.port);
	console.log('Server running at http://127.0.0.1:' + this.port);
};

Cachelicious.prototype.stop = function ()
{
	this.server.close();
	console.log('Server shut down');
};

Cachelicious.prototype.dispatch = function (request, response)
{
	var filepath = this.pathFinder(request), contentType;

	if (null === filepath) {
		this.serveError(request.method, response, 404);
		return;
	}

	contentType = this.contentTypeFinder(filepath);

	this.streamPath(filepath, contentType, request.method, response);
};

Cachelicious.prototype.fileCheck = function (filepath, successCb, errorCb)
{
	//console.log('running stat on:' + filepath)
	var self = this;
	fs.stat(filepath, function (error, stat) {
		if (null !== error) {
			if (errorCb) {
				errorCb(404);
			}
			return false;
		}

		if (undefined === stat) {
			if (errorCb) {
				errorCb(500);
			}
			return false;
		}

		if (!stat.isFile()) {
			if (errorCb) {
				errorCb(401);
			}
			return false;
		}
		successCb(stat);
		return true;
	});
};

Cachelicious.prototype.streamPath = function (filepath, contentType, method, response)
{
	if (false === this.cache) {
		this.asyncServeUncachedStream(filepath, contentType, method, response);
		return;
	}

	this.requestStreamId++;

	var
		requestId = "r-" + this.requestStreamId,
		cachedStream = this.getCached(filepath),
		self = this;

	if (undefined !== cachedStream) {
		self.asyncServeCachedStream(cachedStream, contentType, method, requestId, response);
		return;
	}

	this.once('fileCheckSuccess-' + filepath, function (cachedStream) {
		self.asyncServeCachedStream(cachedStream, contentType, method, requestId, response);
	});

	this.once('fileCheckError-' + filepath, function (error) {
		self.serveError(method, response, error);
	});

	this.fileCheck(filepath,
		function (stat)
		{
			var newStream = new CacheStream(stat.size);
			self.setCached(filepath, newStream);
			fs.createReadStream(filepath).pipe(newStream);

			//console.log('emitting: fileCheckSuccess-' + filepath);
			self.emit('fileCheckSuccess-' + filepath, newStream);
			self.removeAllListeners('fileCheckError-' + filepath);
		},
		function (error)
		{
			//console.log('emitting: fileCheckError-' + filepath);
			self.emit('fileCheckError-' + filepath, error);
			self.removeAllListeners('fileCheckSuccess-' + filepath);
		}
	);
};

Cachelicious.prototype.asyncServeUncachedStream = function (filepath, contentType, method, response)
{
	var self = this;
	this.fileCheck(filepath,
		function (stat) {
			response.writeHead(200, {
				'Content-Type':   contentType,
				'Content-Length': stat.size
			});

			if ('HEAD' !== method) {
				fs.createReadStream(filepath).pipe(response);
			} else {
				response.end();
			}
		},
		function (error) {
			self.serveError(method, response, error);
		}
	);
};

Cachelicious.prototype.asyncServeCachedStream = function (cachedStream, contentType, method, requestId, response)
{
	var self = this;
	process.nextTick(function () {
		self.serveCachedStream(cachedStream, contentType, method, requestId, response);
	});
};

Cachelicious.prototype.serveCachedStream = function (cachedStream, contentType, method, requestId, response)
{
	response.writeHead(200, {
		'Content-Type':   contentType,
		'Content-Length': cachedStream.size,
		'X-Req-Id':       requestId
	});

	if ('HEAD' !== method) {
		cachedStream.addConsumer(new CacheStreamConsumer(requestId, response));
	} else {
		response.end();
	}
};

Cachelicious.prototype.serveError = function (method, response, code)
{
	console.log('error: ' + code);
	response.writeHead(code, {'Content-Type': 'text/html'});
	if ('HEAD' !== method) {
		response.end(""+code, 'utf-8');
	} else {
		response.end();
	}
};

Cachelicious.prototype.getCached = function (filepath)
{
	return this.cache.get(filepath);
};

Cachelicious.prototype.setCached = function (filepath, cacheStream)
{
	this.cache.set(filepath, cacheStream);
	//console.log('Current cache size: ' + Math.round(this.cache.length/(1024*1024)) + 'MB');
};

<|endoftext|>


<commit_before>"use strict";

/*  ------------------------------------------------------------------------ */

const [processPath, , argument = null] = process.argv.filter (x => !x.startsWith ('--'))
    , verbose = process.argv.includes ('--verbose')
    , strict  = process.argv.includes ('--strict')
    , compact = process.argv.includes ('--compact')
    , debug = process.argv.includes ('--debug')
    , marketsOnly = process.argv.includes ('--markets')
    , currenciesOnly = process.argv.includes ('--currencies')

/*  ------------------------------------------------------------------------ */

const asTable   = require ('as-table')
    , log       = require ('ololog').noLocate
    , path      = require ('path')
    , fs        = require ('fs')
    , ansi      = require ('ansicolor').nice
    , ccxt      = require ('../../ccxt.js')

/*  ------------------------------------------------------------------------ */

const warn = log.bright.yellow.error // .error → stderr

/*  ------------------------------------------------------------------------ */

process.on ('uncaughtException',  e => { log.bright.red.error (e); process.exit (1) })
process.on ('unhandledRejection', e => { log.bright.red.error (e); process.exit (1) })

/*  ------------------------------------------------------------------------ */

let printUsage = function () {
    log ('     Non-strict search: node', process.argv[1], 'symbol'.green)
    log ('     Non-strict search: node', process.argv[1], 'currency'.green)
    log ('         Strict search: node', process.argv[1], '--strict', 'argument'.green)
    log ('   Search markets only: node', process.argv[1], '--markets', 'argument'.green)
    log ('Search currencies only: node', process.argv[1], '--currencies', 'argument'.green)

}

if (process.argv.length < 3) {
    printUsage ()
    process.exit ()
}

/*  ------------------------------------------------------------------------ */

const keysGlobal = path.resolve ('keys.json')
const keysLocal = path.resolve ('keys.local.json')
let globalKeysFile = fs.existsSync (keysGlobal) ? keysGlobal : false
let localKeysFile = fs.existsSync (keysLocal) ? keysLocal : globalKeysFile

const keys = require (localKeysFile)

/*  ------------------------------------------------------------------------ */

log ('Looking up for:', argument.bright, strict ? '(strict search)' : '(non-strict search)')

const checkAgainst = strict ?
    (a, b) => (a ||'').toUpperCase ().includes ((b || '').toUpperCase ()) :
    (a, b) => (a || '').toLowerCase ().includes ((b || '').toLowerCase ())

;(async function test () {

    let exchanges = await Promise.all (ccxt.exchanges.map (async id => {

        // instantiate the exchange
        let exchange = new ccxt[id] (ccxt.extend (localKeysFile ? (keys[id] || {}) : {}, {
            // agent, // set up keys and settings, if any
        }))

        if (exchange.has.publicAPI) {

            try {

                // load markets
                await exchange.loadMarkets ()
                return exchange

            } catch (e) {

                if (debug) {
                    log.red (exchange.id, e.constructor.name)
                }
                return undefined
            }
        }
    }))

    // filter out exchanges that failed to load
    exchanges = exchanges.filter (exchange => exchange)

    if (!currenciesOnly) {

        log ("---------------------------------------------------------------")

        log ("Markets And Symbols:")

        let markets = ccxt.flatten (exchanges
            .map (exchange =>
                Object.values (exchange.markets).map (market =>
                    exchange.extend (market, {
                        exchange: exchange.id[(market.active !== false) ? 'green' : 'yellow'],
                    }))))
            .filter (market => {
                try {
                    return (
                        checkAgainst (market['base'],  argument) ||
                        checkAgainst (market['quote'], argument) ||
                        (market['baseId']  ? checkAgainst (market['baseId'],  argument) : false) ||
                        (market['quoteId'] ? checkAgainst (market['quoteId'], argument) : false) ||
                        checkAgainst (market['symbol'], argument) ||
                        checkAgainst (market['id'].toString (), argument)
                    )
                } catch (e) {
                    if (debug) {
                        log.red (e.constructor.name, e.message)
                    }
                    return false
                }
            })

        log (asTable (markets.map (market => {
            market = ccxt.omit (market, [ 'info', 'limits', 'precision', 'tiers' ])
            return (!compact) ? market : {
                'symbol': market['symbol'],
                'exchange': market['exchange'],
            };
        })))

        log (markets.length.toString ().yellow, 'markets')
    }

    if (!marketsOnly) {

        log ("---------------------------------------------------------------")

        log ("Currencies:")

        let currencies = ccxt.flatten (exchanges
            .map (exchange =>
                Object.values (exchange.currencies).map (currency =>
                    exchange.extend (currency, {
                        exchange: exchange.id[(currency.active !== false) ? 'green' : 'yellow'],
                    }))))
            .filter (currency =>
                checkAgainst (currency['code'], argument) ||
                checkAgainst (currency['id'], argument))

        log (asTable (currencies.map (currency => ccxt.omit (currency, [ 'info', 'limits', 'precision' ]))))

        log (currencies.length.toString ().yellow, 'currencies')
    }

}) ()
<commit_msg>examples/js/search-all-exchanges.js minor edit<commit_after>"use strict";

/*  ------------------------------------------------------------------------ */

const [processPath, , argument = null] = process.argv.filter (x => !x.startsWith ('--'))
    , verbose = process.argv.includes ('--verbose')
    , strict  = process.argv.includes ('--strict')
    , compact = process.argv.includes ('--compact')
    , debug = process.argv.includes ('--debug')
    , marketsOnly = process.argv.includes ('--markets')
    , currenciesOnly = process.argv.includes ('--currencies')

/*  ------------------------------------------------------------------------ */

const asTable   = require ('as-table')
    , log       = require ('ololog').noLocate
    , path      = require ('path')
    , fs        = require ('fs')
    , ansi      = require ('ansicolor').nice
    , ccxt      = require ('../../ccxt.js')

/*  ------------------------------------------------------------------------ */

const warn = log.bright.yellow.error // .error → stderr

/*  ------------------------------------------------------------------------ */

process.on ('uncaughtException',  e => { log.bright.red.error (e); process.exit (1) })
process.on ('unhandledRejection', e => { log.bright.red.error (e); process.exit (1) })

/*  ------------------------------------------------------------------------ */

let printUsage = function () {
    log ('     Non-strict search: node', process.argv[1], 'symbol'.green)
    log ('     Non-strict search: node', process.argv[1], 'currency'.green)
    log ('         Strict search: node', process.argv[1], '--strict', 'argument'.green)
    log ('   Search markets only: node', process.argv[1], '--markets', 'argument'.green)
    log ('Search currencies only: node', process.argv[1], '--currencies', 'argument'.green)

}

if (process.argv.length < 3) {
    printUsage ()
    process.exit ()
}

/*  ------------------------------------------------------------------------ */

const keysGlobal = path.resolve ('keys.json')
const keysLocal = path.resolve ('keys.local.json')
let globalKeysFile = fs.existsSync (keysGlobal) ? keysGlobal : false
let localKeysFile = fs.existsSync (keysLocal) ? keysLocal : globalKeysFile

const keys = require (localKeysFile)

/*  ------------------------------------------------------------------------ */

log ('Looking up for:', argument.bright, strict ? '(strict search)' : '(non-strict search)')

const checkAgainst = strict ?
    (a, b) => (a ||'').toUpperCase ().includes ((b || '').toUpperCase ()) :
    (a, b) => (a || '').toLowerCase ().includes ((b || '').toLowerCase ())

;(async function test () {

    let exchanges = await Promise.all (ccxt.exchanges.map (async id => {

        // instantiate the exchange
        let exchange = new ccxt[id] (ccxt.extend (localKeysFile ? (keys[id] || {}) : {}, {
            // agent, // set up keys and settings, if any
        }))

        if (exchange.has.publicAPI) {

            try {

                // load markets
                await exchange.loadMarkets ()
                return exchange

            } catch (e) {

                if (debug) {
                    log.red (exchange.id, e.constructor.name)
                }
                return undefined
            }
        }
    }))

    // filter out exchanges that failed to load
    exchanges = exchanges.filter (exchange => exchange)

    if (!currenciesOnly) {

        log ("---------------------------------------------------------------")

        log ("Markets And Symbols:")

        let markets = ccxt.flatten (exchanges
            .map (exchange =>
                Object.values (exchange.markets).map (market =>
                    exchange.extend (market, {
                        exchange: exchange.id[(market.active !== false) ? 'green' : 'yellow'],
                    }))))
            .filter (market => {
                try {
                    return (
                        checkAgainst (market['base'],  argument) ||
                        checkAgainst (market['quote'], argument) ||
                        (market['baseId']  ? checkAgainst (market['baseId'],  argument) : false) ||
                        (market['quoteId'] ? checkAgainst (market['quoteId'], argument) : false) ||
                        checkAgainst (market['symbol'], argument) ||
                        checkAgainst (market['id'].toString (), argument)
                    )
                } catch (e) {
                    if (debug) {
                        log.red (e.constructor.name, e.message)
                    }
                    return false
                }
            })

        log (asTable (markets.map (market => {
            market = ccxt.omit (market, [ 'info', 'limits', 'precision', 'tiers' ])
            return (!compact) ? market : {
                'symbol': market['symbol'],
                'exchange': market['exchange'],
            };
        })))

        log (markets.length.toString ().yellow, 'markets')
    }

    if (!marketsOnly) {

        log ("---------------------------------------------------------------")

        log ("Currencies:")

        let currencies = ccxt.flatten (exchanges
            .map (exchange =>
                Object.values (exchange.currencies).map (currency =>
                    exchange.extend (currency, {
                        exchange: exchange.id[(currency.active !== false) ? 'green' : 'yellow'],
                    }))))
            .filter (currency =>
                checkAgainst (currency['code'], argument) ||
                checkAgainst (currency['id'], argument))

        log (asTable (currencies.map (currency => ccxt.omit (currency, [ 'info', 'limits', 'precision' ]))))

        log (currencies.length.toString ().yellow, 'currencies')
    }

    process.exit ()

}) ()
<|endoftext|>


<commit_before>export default function () {
  this.Before(function() {
    this.intl = async (translationId, translationValues = {}) => {
      const translation = await this.client.execute(function(id, values) {
        const IntlProvider  = require('react-intl').IntlProvider;
        const locale = daedalus.stores.app.currentLocale;
        const messages = daedalus.translations;
        const intlProvider = new IntlProvider({ locale, messages }, {});
        return intlProvider.getChildContext().intl.formatMessage({ id }, values);
      }, translationId, translationValues);
      console.log(translation.value);
      return translation.value;
    };
  });
}
<commit_msg>Fix i18n setup for testing<commit_after>export default function () {
  this.Before(function() {
    this.intl = async (translationId, translationValues = {}) => {
      const translation = await this.client.execute(function(id, values) {
        const IntlProvider  = require('react-intl').IntlProvider;
        const locale = daedalus.stores.app.currentLocale;
        const messages = daedalus.translations;
        const intlProvider = new IntlProvider({ locale, messages: messages[locale] }, {});
        return intlProvider.getChildContext().intl.formatMessage({ id }, values);
      }, translationId, translationValues);
      return translation.value;
    };
  });
}
<|endoftext|>


<commit_before>/*global require process console JSON __dirname */
var parseUrl = require('url').parse
var formatUrl = require('url').format
var http = require('http')
var request = require('request')
var querystring = require('querystring')
var redis = require("redis")
var _ = require('underscore')

var force_protocol=require('./force_protocol')

/**
 * CAS validate:  validate requests via CAS service tickets
 *
 * Options:
 *
 *   - `serivce`  the service url we are checking.  probably best to leave it blank
 *   - `cas_host` the CAS host.  will fallback to environment variable CAS_HOST
 *
 * @param {Object} options
 * @return {Function}
 * @api public
 */

var logger = require('./logger')('cas_validate')

var redclient = redis.createClient();

redclient.on("error", function (err) {
    logger.error("Redis Client Error: " + err);
});

// these should be settable options
var validation_service = '/cas/serviceValidate';
var login_service = '/cas/login';

exports.redirect = require('./redirect').redirect
exports.check_and_return = require('./redirect').check_and_return
exports.check_or_redirect = require('./check_or_redirect')
exports.ticket = require('./ticket')
exports.ssoff = require('./ssoff')
exports.logout = require('./logout')
exports.get_username = require('./sax_parser').get_username
exports.get_attributes = require('./sax_parser').get_attributes
exports.session_or_abort = require('./session_or_abort')
<commit_msg>further clean up of cas_validate.js<commit_after>/**
 * CAS validate:  validate requests via CAS service tickets
 *
 * Options:
 *
 *   - `serivce`  the service url we are checking.  probably best to leave it blank
 *   - `cas_host` the CAS host.  will fallback to environment variable CAS_HOST
 *
 * @param {Object} options
 * @return {Function}
 * @api public
 */

// fixme, put in the global init here, if/when I ever decide to write that

exports.redirect = require('./redirect').redirect
exports.check_and_return = require('./redirect').check_and_return
exports.check_or_redirect = require('./check_or_redirect')
// note that ticket include xml parsing now, should eventually
// include json as an option
exports.ticket = require('./ticket')
exports.ssoff = require('./ssoff')
exports.logout = require('./logout')
exports.get_username = require('./sax_parser').get_username
exports.get_attributes = require('./sax_parser').get_attributes
exports.session_or_abort = require('./session_or_abort')
<|endoftext|>


<commit_before>const customEntries = [
  `52e901f500821d2b94000005.api.5rocks.io`,
  `api.5rocks.io`,
  `androidads23.adcolony.com`,
  `events3alt.adcolony.com`,
  `app.adjust.com`,
  `103.bm-nginx-loadbalancer.mgmt.lax1.adnexus.net`,
  `mnnbv.adsbtrk.com`,
  `cast-cs-j.adtdp.com`,
  `dex.advg.jp`,
  `action.adzcore.com`,
  `setting.adzcore.com`,
  `bypass.ad-stir.com`,
  `supersonicads-a.akamaihd.net`,
  `device-metrics-us.amazon.com`,
  `rt.applovin.com`,
  `events.appsflyer.com`,
  `stats.appsflyer.com`,
  `t.appsflyer.com`,
  `tap-nexus.appspot.com`,
  `smetrics.capitalone.com`,
  `e.crashlytics.com`,
  `settings.crashlytics.com`,
  `smetrics.discover.com`,
  `graph.facebook.com`,
  `notification.fello.net`,
  `adproxy.fyber.com`,
  `engine.fyber.com`,
  `video.fyber.com`,
  `tracking.gasmobi.com`,
  `aladdin.genieesspv.jp`,
  `api.analytics.growthbeat.com`,
  `rt.gsspat.jp`,
  `cs.gssprt.jp`,
  `thanks.lobi.co`,
  `dispatch.look.io`,
  `control.kochava.com`,
  `155376.measurementapi.com`,
  `ad-analytics-bootstrap.metaps.com`,
  `api-analytics-bootstrap.metaps.com`,
  `api-analytics.metaps.com`,
  `14642.engine.mobileapptracking.com`,
  `mrthumb.nabstudio.com`,
  `le.nakanohito.jp`,
  `mobile-crash.newrelic.com`,
  `capitaloneservices.tt.omtrdc.net`,
  `tr.pubnative.net`,
  `rayjump.com`,
  `res.rayjump.com`,
  `net.rayjump.com`,
  `setting.rayjump.com`,
  `us01.rayjump.com`,
  `api.smbeat.jp`,
  `control.smbeat.jp`,
  `engine.sponsorpay.com`,
  `www.ssacdn.com`,
  `init.supersonicads.com`,
  `outcome.supersonicads.com`,
  `ua.supersonicads.com`,
  `content-js.tapjoy.com`,
  `placements.tapjoy.com`,
  `rpc.tapjoy.com`,
  `trk-optimize.com`,
  `rq.vserv.mobi`,
  `api.wirelessdeveloper.com`,
  `cn-agentportal.flurry.vip.gq1.yahoo.com`
];

module.exports = customEntries;
<commit_msg>feat(custom-hosts): add more omtrdc entries<commit_after>const customEntries = [
  `52e901f500821d2b94000005.api.5rocks.io`,
  `api.5rocks.io`,
  `androidads23.adcolony.com`,
  `events3alt.adcolony.com`,
  `app.adjust.com`,
  `103.bm-nginx-loadbalancer.mgmt.lax1.adnexus.net`,
  `mnnbv.adsbtrk.com`,
  `cast-cs-j.adtdp.com`,
  `dex.advg.jp`,
  `action.adzcore.com`,
  `setting.adzcore.com`,
  `bypass.ad-stir.com`,
  `supersonicads-a.akamaihd.net`,
  `device-metrics-us.amazon.com`,
  `rt.applovin.com`,
  `events.appsflyer.com`,
  `stats.appsflyer.com`,
  `t.appsflyer.com`,
  `tap-nexus.appspot.com`,
  `smetrics.capitalone.com`,
  `e.crashlytics.com`,
  `settings.crashlytics.com`,
  `smetrics.discover.com`,
  `graph.facebook.com`,
  `notification.fello.net`,
  `adproxy.fyber.com`,
  `engine.fyber.com`,
  `video.fyber.com`,
  `tracking.gasmobi.com`,
  `aladdin.genieesspv.jp`,
  `api.analytics.growthbeat.com`,
  `rt.gsspat.jp`,
  `cs.gssprt.jp`,
  `thanks.lobi.co`,
  `dispatch.look.io`,
  `control.kochava.com`,
  `155376.measurementapi.com`,
  `ad-analytics-bootstrap.metaps.com`,
  `api-analytics-bootstrap.metaps.com`,
  `api-analytics.metaps.com`,
  `14642.engine.mobileapptracking.com`,
  `mrthumb.nabstudio.com`,
  `le.nakanohito.jp`,
  `mobile-crash.newrelic.com`,
  `capitaloneservices.tt.omtrdc.net`,
  `citimobile.d2.sc.omtrdc.net`,
  `tr.pubnative.net`,
  `rayjump.com`,
  `res.rayjump.com`,
  `net.rayjump.com`,
  `setting.rayjump.com`,
  `us01.rayjump.com`,
  `api.smbeat.jp`,
  `control.smbeat.jp`,
  `engine.sponsorpay.com`,
  `www.ssacdn.com`,
  `init.supersonicads.com`,
  `outcome.supersonicads.com`,
  `ua.supersonicads.com`,
  `content-js.tapjoy.com`,
  `placements.tapjoy.com`,
  `rpc.tapjoy.com`,
  `trk-optimize.com`,
  `rq.vserv.mobi`,
  `api.wirelessdeveloper.com`,
  `cn-agentportal.flurry.vip.gq1.yahoo.com`
];

module.exports = customEntries;
<|endoftext|>


<commit_before>module.exports = {
  stories: [
    './intro.stories.mdx',
    '../../lib/ui/src/**/*.stories.(js|tsx|mdx)',
    '../../lib/components/src/**/*.stories.(js|tsx|mdx)',
    './stories/**/*.stories.(js|tsx|mdx)',
  ],
  addons: [
    '@storybook/addon-docs',
    '@storybook/addon-storysource',
    '@storybook/addon-design-assets',
    '@storybook/addon-actions',
    '@storybook/addon-links',
    '@storybook/addon-events',
    '@storybook/addon-notes',
    '@storybook/addon-options',
    '@storybook/addon-knobs',
    '@storybook/addon-cssresources',
    '@storybook/addon-backgrounds',
    '@storybook/addon-a11y',
    '@storybook/addon-jest',
    '@storybook/addon-viewport',
    '@storybook/addon-graphql',
    '@storybook/addon-contexts',
  ],
  webpackFinal: async (config, { configType }) => ({
    ...config,
    module: {
      ...config.module,
      rules: [
        ...config.module.rules.slice(1),
        {
          test: /\.(mjs|jsx?|tsx?)$/,
          use: [
            {
              loader: 'babel-loader',
              options: {
                cacheDirectory: `.cache/storybook`,
                presets: [
                  [
                    '@babel/preset-env',
                    { shippedProposals: true, useBuiltIns: 'usage', corejs: 3 },
                  ],
                  '@babel/preset-typescript',
                  configType === 'PRODUCTION' && [
                    'babel-preset-minify',
                    { builtIns: false, mangle: false },
                  ],
                  '@babel/preset-react',
                  '@babel/preset-flow',
                ].filter(Boolean),
                plugins: [
                  '@babel/plugin-proposal-object-rest-spread',
                  '@babel/plugin-proposal-class-properties',
                  '@babel/plugin-syntax-dynamic-import',
                  ['babel-plugin-emotion', { sourceMap: true, autoLabel: true }],
                  'babel-plugin-macros',
                  '@babel/plugin-transform-react-constant-elements',
                  'babel-plugin-add-react-displayname',
                  [
                    'babel-plugin-react-docgen',
                    { DOC_GEN_COLLECTION_NAME: 'STORYBOOK_REACT_CLASSES' },
                  ],
                ],
              },
            },
          ],
          exclude: [/node_modules/, /dist/],
        },
      ],
    },
    resolve: {
      ...config.resolve,
      extensions: [...(config.resolve.extensions || []), '.ts', '.tsx'],
    },
  }),
};
<commit_msg>Official-storybook: Don't load intro.stories.mdx<commit_after>module.exports = {
  stories: [
    // FIXME: Breaks e2e tests './intro.stories.mdx',
    '../../lib/ui/src/**/*.stories.(js|tsx|mdx)',
    '../../lib/components/src/**/*.stories.(js|tsx|mdx)',
    './stories/**/*.stories.(js|tsx|mdx)',
  ],
  addons: [
    '@storybook/addon-docs',
    '@storybook/addon-storysource',
    '@storybook/addon-design-assets',
    '@storybook/addon-actions',
    '@storybook/addon-links',
    '@storybook/addon-events',
    '@storybook/addon-notes',
    '@storybook/addon-options',
    '@storybook/addon-knobs',
    '@storybook/addon-cssresources',
    '@storybook/addon-backgrounds',
    '@storybook/addon-a11y',
    '@storybook/addon-jest',
    '@storybook/addon-viewport',
    '@storybook/addon-graphql',
    '@storybook/addon-contexts',
  ],
  webpackFinal: async (config, { configType }) => ({
    ...config,
    module: {
      ...config.module,
      rules: [
        ...config.module.rules.slice(1),
        {
          test: /\.(mjs|jsx?|tsx?)$/,
          use: [
            {
              loader: 'babel-loader',
              options: {
                cacheDirectory: `.cache/storybook`,
                presets: [
                  [
                    '@babel/preset-env',
                    { shippedProposals: true, useBuiltIns: 'usage', corejs: 3 },
                  ],
                  '@babel/preset-typescript',
                  configType === 'PRODUCTION' && [
                    'babel-preset-minify',
                    { builtIns: false, mangle: false },
                  ],
                  '@babel/preset-react',
                  '@babel/preset-flow',
                ].filter(Boolean),
                plugins: [
                  '@babel/plugin-proposal-object-rest-spread',
                  '@babel/plugin-proposal-class-properties',
                  '@babel/plugin-syntax-dynamic-import',
                  ['babel-plugin-emotion', { sourceMap: true, autoLabel: true }],
                  'babel-plugin-macros',
                  '@babel/plugin-transform-react-constant-elements',
                  'babel-plugin-add-react-displayname',
                  [
                    'babel-plugin-react-docgen',
                    { DOC_GEN_COLLECTION_NAME: 'STORYBOOK_REACT_CLASSES' },
                  ],
                ],
              },
            },
          ],
          exclude: [/node_modules/, /dist/],
        },
      ],
    },
    resolve: {
      ...config.resolve,
      extensions: [...(config.resolve.extensions || []), '.ts', '.tsx'],
    },
  }),
};
<|endoftext|>


<commit_before>'use strict';

var
  events    = require('events'),
  util      = require('util'),
  stringify = require('json-stringify-safe'),
  config    = require('../package.json')
;

function ChromeLogger() {
  events.EventEmitter.call(this);

  var
    logger = this,
    stackRegEx = /^ +at (.* \()?(.+):([0-9]+):([0-9]+)\)?$/,
    stackIndex = +process.version.replace(/v([0-9]+)\.([0-9]+).*/g, '$1$2') < 7 ? 4 : 3, // The stacktrace is different between Node.js <= 0.6 and >= 0.7
    dataRef = /("x-chromelogger-data":")[0-9a-z+\/=]+(")/ig
  ;

  logger._process = function(res, type) {
    // Retrieve the data from the arguments
    data = Array.prototype.constructor.apply(this, arguments).slice(2);
    // Get the constructor name for each of the logged objects
    data.forEach(function(d) {
      if (typeof d !== 'object') return;
      d.___class_name = d.constructor.name;
    });

    // Emulate Assert support
    if (type === 'assert') {
      if (data[0] === true) return [];
      else {
        type = 'error';
        data.shift();
        data[0] = 'Assertion failed: ' + data[0];
      }
    }

    // Emulate Time support
    if (type === 'time') {
      res._ChromeLogger.time[data[0]] = process.hrtime();
      return [];
    }

    // Emulate TimeEnd support
    if (type === 'timeEnd') {
      if (!res._ChromeLogger.time[data[0]]) return [];
      type = 'debug';
      var diff = process.hrtime(res._ChromeLogger.time[data[0]]);
      delete res._ChromeLogger.time[data[0]];
      data = [data[0] + ': ' + (diff[0] * 1e3 + diff[1] / 1e6).toFixed(3) + 'ms'];
    }

    // Get the backtrace
    var backtrace = new Error().stack.split('\n')[stackIndex].match(stackRegEx).slice(-3).join(':');
    // Set the backtrace to null if we log a group message or if we log the same line multiple time
    backtrace = /group/.test(type) || res._ChromeLogger.lastBacktrace === backtrace ? null : backtrace;
    // Update the last backtrace value
    res._ChromeLogger.lastBacktrace = backtrace || res._ChromeLogger.lastBacktrace;

    // Emulate Count support
    if (type === 'count') {
      var label = data[0] + res._ChromeLogger.lastBacktrace;
      res._ChromeLogger.count[label] = res._ChromeLogger.count[label] ? res._ChromeLogger.count[label] + 1 : 1;
      type = 'debug';
      data = [data[0] + ': ' + res._ChromeLogger.count[label]];
    }

    // Return the constructed message
    return [
      data,
      backtrace,
      type
    ];
  };

  logger._log = function(res, type) {
    // Stop here if the headers were already sent
    if (res.headersSent || res._header) {
      return logger.emit('error', new Error('You can\'t log with Chrome Logger if the headers were already sent'));
    }

    if (!res._ChromeLogger) {
      res._ChromeLogger = {
        data: {
          version: config.version,
          columns: ['log', 'backtrace', 'type'],
          rows: []
        },
        count: {},
        time: {}
      };
    }

    // Construct the message
    var message = logger._process.apply(this, arguments);

    // Exit if, after processing, there is no new message to log
    if (!message.length) return;

    // Push the message in the queue
    res._ChromeLogger.data.rows.push(message);

    var data = stringify(res._ChromeLogger.data);         // Serialize
    data = data.replace(dataRef, '$1[Circular]$2');       // Replace the references to the ChromeLogger data
    data = new Buffer(data, 'binary').toString('base64'); // Encode

    // Limit the log size to 240KB (Chrome's limit: 256KB for all headers)
    if (data.length > 245760) {
      res._ChromeLogger.data.rows.pop();
      return logger.emit('error', new Error('You can\'t log more than 245760 Bytes of data in the headers. Current size: ' + data.length + ' Bytes'));
    }

    // Set the header
    res.setHeader('X-ChromeLogger-Data', data);
  };

  logger.middleware = function(req, res, next) {
    res.chrome = {
      log           : logger._log.bind(logger, res, ''),
      warn          : logger._log.bind(logger, res, 'warn'),
      error         : logger._log.bind(logger, res, 'error'),
      info          : logger._log.bind(logger, res, 'info'),
      table         : logger._log.bind(logger, res, 'table'),
      assert        : logger._log.bind(logger, res, 'assert'),
      count         : logger._log.bind(logger, res, 'count'),
      time          : logger._log.bind(logger, res, 'time'),
      timeEnd       : logger._log.bind(logger, res, 'timeEnd'),
      group         : logger._log.bind(logger, res, 'group'),
      groupEnd      : logger._log.bind(logger, res, 'groupEnd'),
      groupCollapsed: logger._log.bind(logger, res, 'groupCollapsed')
    };
    if(typeof next === 'function') next();
  };
}
util.inherits(ChromeLogger, events.EventEmitter);

module.exports = new ChromeLogger();
<commit_msg>Fix global variable leak<commit_after>'use strict';

var
  events    = require('events'),
  util      = require('util'),
  stringify = require('json-stringify-safe'),
  config    = require('../package.json')
;

function ChromeLogger() {
  events.EventEmitter.call(this);

  var
    logger = this,
    stackRegEx = /^ +at (.* \()?(.+):([0-9]+):([0-9]+)\)?$/,
    stackIndex = +process.version.replace(/v([0-9]+)\.([0-9]+).*/g, '$1$2') < 7 ? 4 : 3, // The stacktrace is different between Node.js <= 0.6 and >= 0.7
    dataRef = /("x-chromelogger-data":")[0-9a-z+\/=]+(")/ig
  ;

  logger._process = function(res, type) {
    // Retrieve the data from the arguments
    var data = Array.prototype.constructor.apply(this, arguments).slice(2);
    // Get the constructor name for each of the logged objects
    data.forEach(function(d) {
      if (typeof d !== 'object') return;
      d.___class_name = d.constructor.name;
    });

    // Emulate Assert support
    if (type === 'assert') {
      if (data[0] === true) return [];
      else {
        type = 'error';
        data.shift();
        data[0] = 'Assertion failed: ' + data[0];
      }
    }

    // Emulate Time support
    if (type === 'time') {
      res._ChromeLogger.time[data[0]] = process.hrtime();
      return [];
    }

    // Emulate TimeEnd support
    if (type === 'timeEnd') {
      if (!res._ChromeLogger.time[data[0]]) return [];
      type = 'debug';
      var diff = process.hrtime(res._ChromeLogger.time[data[0]]);
      delete res._ChromeLogger.time[data[0]];
      data = [data[0] + ': ' + (diff[0] * 1e3 + diff[1] / 1e6).toFixed(3) + 'ms'];
    }

    // Get the backtrace
    var backtrace = new Error().stack.split('\n')[stackIndex].match(stackRegEx).slice(-3).join(':');
    // Set the backtrace to null if we log a group message or if we log the same line multiple time
    backtrace = /group/.test(type) || res._ChromeLogger.lastBacktrace === backtrace ? null : backtrace;
    // Update the last backtrace value
    res._ChromeLogger.lastBacktrace = backtrace || res._ChromeLogger.lastBacktrace;

    // Emulate Count support
    if (type === 'count') {
      var label = data[0] + res._ChromeLogger.lastBacktrace;
      res._ChromeLogger.count[label] = res._ChromeLogger.count[label] ? res._ChromeLogger.count[label] + 1 : 1;
      type = 'debug';
      data = [data[0] + ': ' + res._ChromeLogger.count[label]];
    }

    // Return the constructed message
    return [
      data,
      backtrace,
      type
    ];
  };

  logger._log = function(res, type) {
    // Stop here if the headers were already sent
    if (res.headersSent || res._header) {
      return logger.emit('error', new Error('You can\'t log with Chrome Logger if the headers were already sent'));
    }

    if (!res._ChromeLogger) {
      res._ChromeLogger = {
        data: {
          version: config.version,
          columns: ['log', 'backtrace', 'type'],
          rows: []
        },
        count: {},
        time: {}
      };
    }

    // Construct the message
    var message = logger._process.apply(this, arguments);

    // Exit if, after processing, there is no new message to log
    if (!message.length) return;

    // Push the message in the queue
    res._ChromeLogger.data.rows.push(message);

    var data = stringify(res._ChromeLogger.data);         // Serialize
    data = data.replace(dataRef, '$1[Circular]$2');       // Replace the references to the ChromeLogger data
    data = new Buffer(data, 'binary').toString('base64'); // Encode

    // Limit the log size to 240KB (Chrome's limit: 256KB for all headers)
    if (data.length > 245760) {
      res._ChromeLogger.data.rows.pop();
      return logger.emit('error', new Error('You can\'t log more than 245760 Bytes of data in the headers. Current size: ' + data.length + ' Bytes'));
    }

    // Set the header
    res.setHeader('X-ChromeLogger-Data', data);
  };

  logger.middleware = function(req, res, next) {
    res.chrome = {
      log           : logger._log.bind(logger, res, ''),
      warn          : logger._log.bind(logger, res, 'warn'),
      error         : logger._log.bind(logger, res, 'error'),
      info          : logger._log.bind(logger, res, 'info'),
      table         : logger._log.bind(logger, res, 'table'),
      assert        : logger._log.bind(logger, res, 'assert'),
      count         : logger._log.bind(logger, res, 'count'),
      time          : logger._log.bind(logger, res, 'time'),
      timeEnd       : logger._log.bind(logger, res, 'timeEnd'),
      group         : logger._log.bind(logger, res, 'group'),
      groupEnd      : logger._log.bind(logger, res, 'groupEnd'),
      groupCollapsed: logger._log.bind(logger, res, 'groupCollapsed')
    };
    if(typeof next === 'function') next();
  };
}
util.inherits(ChromeLogger, events.EventEmitter);

module.exports = new ChromeLogger();
<|endoftext|>


<commit_before>var fs = require('fs');
var TomahawkJS = require('tomahawkjs');
var failOn = require('./utils').failOn;

/**
 * Load an AXE bundle and terminate on errors.
 */
var loadResolver = function (path, callback) {
    fs.stat(path, function (err, stats) {
        failOn(err, "Error while reading the resolver path:", err);
        if (stats.isFile()) {
            TomahawkJS.loadAxe(path, function (err, axe) {
                failOn(err, "Error while loading axe:", err);
                axe.getInstance(function(err, instance_context) {
                    failOn(err, "Could not instantiate a resolver object:", err);
                    var instance = instance_context.instance;
                    var context = instance_context.context;
                    instance.init();
                    callback(instance, context);
                });
            });
        } else if (stats.isDirectory()) {
            // Load the resolver from a directory.
            // FIXME: Implement!
        } else {
            // Will be interesting what kind of fs type people will access here
            console.error("Unsupported FS item for a resolver bundle.");
            process.exit(1);
        }
    });
};

exports.generate = function (args) {
    failOn(args.length !== 1, "You need to specify the name of the new resolver.");
    console.error("Not yet implemented. Please stand by!");
    // FIXME: Implement!
};

exports.resolve = function (args) {
    failOn(args.length == 0, "You need to specify a resolver to utilise.");
    failOn(args.length < 3 || args.length > 4, "Usage: \n\t tomahawkjs resolve <resolver> <artist> <title> [<album>]");
    loadResolver(args[0], function (instance, context) {
        context.on('track-result', function (qid, result) {
            console.log(JSON.stringify(result, null, 4));
        });
        instance.resolve("some-id", args[1], args[3], args[2]);
    });
};

exports.search = function (args) {
    failOn(args.length == 0, "You need to specify a resolver to utilise.");
    failOn(args.length < 2, "Usage: \n\t tomahawkjs search <resolver> <query-part1> [<query-part2> ..]");
    loadResolver(args[0], function (instance, context) {
        context.on('track-result', function (qid, result) {
            console.log(JSON.stringify(result, null, 4));
        });
        instance.search("some-id", args.slice(1).join(' '));
    });
};
<commit_msg>Handle init implementations that take a callback<commit_after>var fs = require('fs');
var TomahawkJS = require('tomahawkjs');
var failOn = require('./utils').failOn;

/**
 * Load an AXE bundle and terminate on errors.
 */
var loadResolver = function (path, callback) {
    fs.stat(path, function (err, stats) {
        failOn(err, "Error while reading the resolver path:", err);
        if (stats.isFile()) {
            TomahawkJS.loadAxe(path, function (err, axe) {
                failOn(err, "Error while loading axe:", err);
                axe.getInstance(function(err, instance_context) {
                    failOn(err, "Could not instantiate a resolver object:", err);
                    var instance = instance_context.instance;
                    var context = instance_context.context;
                    if (instance.init.length > 0) {
                        // init takes a callback, so we wait until the callback gets invoked.
                        instance.init(function (err) {
                            failOn(err, "Could not initialise the resolver object:", err);
                            callback(instance, context);
                        });
                    } else {
                        // init does not accept a callback and thus we assume it is sync
                        instance.init();
                        callback(instance, context);
                    }
                });
            });
        } else if (stats.isDirectory()) {
            // Load the resolver from a directory.
            // FIXME: Implement!
        } else {
            // Will be interesting what kind of fs type people will access here
            console.error("Unsupported FS item for a resolver bundle.");
            process.exit(1);
        }
    });
};

exports.generate = function (args) {
    failOn(args.length !== 1, "You need to specify the name of the new resolver.");
    console.error("Not yet implemented. Please stand by!");
    // FIXME: Implement!
};

exports.resolve = function (args) {
    failOn(args.length == 0, "You need to specify a resolver to utilise.");
    failOn(args.length < 3 || args.length > 4, "Usage: \n\t tomahawkjs resolve <resolver> <artist> <title> [<album>]");
    loadResolver(args[0], function (instance, context) {
        context.on('track-result', function (qid, result) {
            console.log(JSON.stringify(result, null, 4));
        });
        instance.resolve("some-id", args[1], args[3], args[2]);
    });
};

exports.search = function (args) {
    failOn(args.length == 0, "You need to specify a resolver to utilise.");
    failOn(args.length < 2, "Usage: \n\t tomahawkjs search <resolver> <query-part1> [<query-part2> ..]");
    loadResolver(args[0], function (instance, context) {
        context.on('track-result', function (qid, result) {
            console.log(JSON.stringify(result, null, 4));
        });
        instance.search("some-id", args.slice(1).join(' '));
    });
};
<|endoftext|>


<commit_before>'use strict'
var connect = require('stream-connect')
var through = require('stream-via')
var collect = require('collect-all')

/**
Returns a stream which becomes readable with a single value once all (valid) JSON is received.

@module collect-json
*/
module.exports = collectJson
collectJson.async = collectJsonAsync

/**
@param [callback] {function} - called with the collected json data, once available. The value returned by the callback will be passed downstream.
@return {external:Duplex}
@alias module:collect-json
@example
An example command-line client script - JSON received at stdin is stamped with `received` then written to stdout.
```js
var collectJson = require("collect-json")

process.stdin
    .pipe(collectJson(function(json){
        json.received = true
        return JSON.stringify(json)
    }))
    .on("error", function(err){
        // input from stdin failed to parse
    })
    .pipe(process.stdout)
```
*/
function collectJson (throughFunction) {
  var stream = collect({
    through: function (data) {
      try {
        var json = JSON.parse(data)
      } catch (err) {
        err.input = data
        err.message = 'Error parsing input JSON: ' + err.message
        throw err
      }
      return json
    },
    objectMode: true
  })
  if (throughFunction) {
    return connect(stream, through(throughFunction, { objectMode: true }))
  } else {
    return stream
  }
}

function collectJsonAsync (throughFunction, options) {
}

/**
@external Duplex
@see https://nodejs.org/api/stream.html#stream_class_stream_duplex
*/
<commit_msg>updated error message<commit_after>'use strict'
var connect = require('stream-connect')
var through = require('stream-via')
var collect = require('collect-all')

/**
Returns a stream which becomes readable with a single value once all (valid) JSON is received.

@module collect-json
*/
module.exports = collectJson
collectJson.async = collectJsonAsync

/**
@param [callback] {function} - called with the collected json data, once available. The value returned by the callback will be passed downstream.
@return {external:Duplex}
@alias module:collect-json
@example
An example command-line client script - JSON received at stdin is stamped with `received` then written to stdout.
```js
var collectJson = require("collect-json")

process.stdin
    .pipe(collectJson(function(json){
        json.received = true
        return JSON.stringify(json)
    }))
    .on("error", function(err){
        // input from stdin failed to parse
    })
    .pipe(process.stdout)
```
*/
function collectJson (throughFunction) {
  var stream = collect({
    through: function (data) {
      try {
        var json = JSON.parse(data)
      } catch (err) {
        err.input = data
        err.message = 'collect-json: [' + err.message + '], input:\n' + data
        throw err
      }
      return json
    },
    objectMode: true
  })
  if (throughFunction) {
    return connect(stream, through(throughFunction, { objectMode: true }))
  } else {
    return stream
  }
}

function collectJsonAsync (throughFunction, options) {
}

/**
@external Duplex
@see https://nodejs.org/api/stream.html#stream_class_stream_duplex
*/
<|endoftext|>


<commit_before>d3.conventions = function(c){
  c = c || {}

  c.width  = c.width  || 900
  c.height = c.height || 500

  c.margin = c.margin || {top: 20, right: 20, bottom: 20, left: 25}

  c.parentSel = c.parentSel || d3.select('body')

  c.svg = c.svg || c.parentSel.append("svg")
      .attr("width", c.width + c.margin.left + c.margin.right)
      .attr("height", c.height + c.margin.top + c.margin.bottom)
    .append("g")
      .attr("transform", "translate(" + c.margin.left + "," + c.margin.top + ")")

  c.color   = c.color   || d3.scale.category10()
  c.x       = c.x       || d3.scale.linear().range([0, c.width])
  c.y       = c.y       || d3.scale.linear().range([c.height, 0])
  c.rScale  = c.rScale  || d3.scale.sqrt().range([5, 20])
  c.line    = c.line    || d3.svg.line()

  c.xAxis = c.xAxis || d3.svg.axis().scale(c.x).orient("bottom");
  c.yAxis = c.yAxis || d3.svg.axis().scale(c.y).orient("left")

  c.drawAxis = function(){
    c.svg.append("g")
        .attr("class", "x axis")
        .attr("transform", "translate(0," + c.height + ")")
        .call(c.xAxis);

    c.svg.append("g")
        .attr("class", "y axis")
        .call(c.yAxis);
  }

  return c
}

d3.attachTooltip = function(sel, fieldFns){
  sel
      .on('mouseover.attachTooltip', ttDisplay)
      .on('mousemove.attachTooltip', ttMove)
      .on('mouseout.attachTooltip',  ttHide)

  fieldFns = fieldFns || d3.keys(sel.datum()).map(function(str){
    return function(d){ return str + ': ' + d[str] + ''} })

  function ttDisplay(d){
    d3.select('.tooltip')
        .classed('tooltip-hidden', false)
        .html('')
      .dataAppend(fieldFns, 'div')
        .html(function(fn){ return fn(d) })

    d3.select(this).classed('tooltipped', true)
  }

  function ttMove(d){
    var tt = d3.select('.tooltip')
    if (!tt.size()) return
    var e = d3.event,
      x = e.clientX,
      y = e.clientY,
      doctop = (window.scrollY)? window.scrollY : (document.documentElement && document.documentElement.scrollTop)? document.documentElement.scrollTop : document.body.scrollTop;
      n = tt.node(),
      nBB = n.getBoundingClientRect()

    tt.style('top', (y+doctop-nBB.height-18)+"px");
    tt.style('left', Math.min(Math.max(0, (x-nBB.width/2)), window.innerWidth - nBB.width)+"px");
  }

  function ttHide(d){
    d3.select('.tooltip').classed('tooltip-hidden', true);

    d3.selectAll('.tooltipped').classed('tooltipped', false)
  }
}

d3.selection.prototype.dataAppend = function(data, name){
  return this.selectAll(name)
      .data(data).enter()
    .append(name)
}
<commit_msg>tooltip doesn't print objects or arrays<commit_after>d3.conventions = function(c){
  c = c || {}

  c.width  = c.width  || 900
  c.height = c.height || 500

  c.margin = c.margin || {top: 20, right: 20, bottom: 20, left: 25}

  c.parentSel = c.parentSel || d3.select('body')

  c.svg = c.svg || c.parentSel.append("svg")
      .attr("width", c.width + c.margin.left + c.margin.right)
      .attr("height", c.height + c.margin.top + c.margin.bottom)
    .append("g")
      .attr("transform", "translate(" + c.margin.left + "," + c.margin.top + ")")

  c.color   = c.color   || d3.scale.category10()
  c.x       = c.x       || d3.scale.linear().range([0, c.width])
  c.y       = c.y       || d3.scale.linear().range([c.height, 0])
  c.rScale  = c.rScale  || d3.scale.sqrt().range([5, 20])
  c.line    = c.line    || d3.svg.line()

  c.xAxis = c.xAxis || d3.svg.axis().scale(c.x).orient("bottom");
  c.yAxis = c.yAxis || d3.svg.axis().scale(c.y).orient("left")

  c.drawAxis = function(){
    c.svg.append("g")
        .attr("class", "x axis")
        .attr("transform", "translate(0," + c.height + ")")
        .call(c.xAxis);

    c.svg.append("g")
        .attr("class", "y axis")
        .call(c.yAxis);
  }

  return c
}

d3.attachTooltip = function(sel, fieldFns){
  sel
      .on('mouseover.attachTooltip', ttDisplay)
      .on('mousemove.attachTooltip', ttMove)
      .on('mouseout.attachTooltip',  ttHide)

  var d = sel.datum()
  fieldFns = fieldFns || d3.keys(d)
      .filter(function(str){
        return (typeof d[str] != 'object') && (d[str] != 'array')
      })
      .map(function(str){
        return function(d){ return str + ': ' + d[str] + ''} })

  function ttDisplay(d){
    d3.select('.tooltip')
        .classed('tooltip-hidden', false)
        .html('')
      .dataAppend(fieldFns, 'div')
        .html(function(fn){ return fn(d) })

    d3.select(this).classed('tooltipped', true)
  }

  function ttMove(d){
    var tt = d3.select('.tooltip')
    if (!tt.size()) return
    var e = d3.event,
      x = e.clientX,
      y = e.clientY,
      doctop = (window.scrollY)? window.scrollY : (document.documentElement && document.documentElement.scrollTop)? document.documentElement.scrollTop : document.body.scrollTop;
      n = tt.node(),
      nBB = n.getBoundingClientRect()

    tt.style('top', (y+doctop-nBB.height-18)+"px");
    tt.style('left', Math.min(Math.max(0, (x-nBB.width/2)), window.innerWidth - nBB.width)+"px");
  }

  function ttHide(d){
    d3.select('.tooltip').classed('tooltip-hidden', true);

    d3.selectAll('.tooltipped').classed('tooltipped', false)
  }
}

d3.selection.prototype.dataAppend = function(data, name){
  return this.selectAll(name)
      .data(data).enter()
    .append(name)
}
<|endoftext|>


<commit_before>var story = require('storyboard').mainStory;
var S = require('string');
var _ = require('underscore');

var plugged = require('../client');
var redis = require('../db/redis_db');
var config = require('../../config');
var utils = require('../utils');
var langfile = require('../../langfile');

module.exports = {
    names: ['add', 'addwl'],
    handler: function (data) {
        redis.get('user:role:save:' + data.id).then(function (perm) {
            perm = parseInt(perm, 10);
            if (config.options.bouncer_plus ? (perm > 1) : (perm > 2)) {
                var split = data.message.split(' ');
                //noinspection JSCheckFunctionSignatures,JSUnresolvedFunction
                var user = plugged.getUserByName(S(_.rest(split, 1).join(' ')).chompLeft('@').chompRight(' ').s);
                if (user !== undefined) {
                    if (((plugged.getWaitlist() !== undefined) ? plugged.getWaitlist().indexOf(user.id) === -1 : false) && (plugged.getCurrentDJ() !== undefined ? plugged.getCurrentDJ().id !== user.id : true )) {
                        plugged.sendChat(utils.replace(langfile.bp_actions.add, {username: data.username}), 45);
                        if (plugged.getWaitlist().length < 50) {
                            plugged.addToWaitlist(user.id);
                        } else {
                            redis.sadd('meta:addqueue', user.id);
                            redis.set('meta:addqueue:user:' + data.id, -1);
                        }
                    }
                } else { //noinspection JSCheckFunctionSignatures
                    plugged.sendChat(utils.replace(langfile.error.user_not_found, {
                        username: plugged.getUserByID(data.id),
                        value: S(_.rest(split, 1).join(' ')).chompLeft('@').s
                    }), 20);
                }
                story.info('add', utils.userLogString(data.username, data.id) + ': ' + utils.userLogString(user));
            }
        });
        plugged.removeChatMessage(data.cid);
    }
};<commit_msg>fix add command<commit_after>var story = require('storyboard').mainStory;
var S = require('string');
var _ = require('underscore');

var plugged = require('../client');
var redis = require('../db/redis_db');
var config = require('../../config');
var utils = require('../utils');
var langfile = require('../../langfile');

module.exports = {
    names: ['add', 'addwl'],
    handler: function (data) {
        redis.get('user:role:save:' + data.id).then(function (perm) {
            perm = parseInt(perm, 10);
            if (config.options.bouncer_plus ? (perm > 1) : (perm > 2)) {
                var split = data.message.split(' ');
                //noinspection JSCheckFunctionSignatures,JSUnresolvedFunction
                var user = plugged.getUserByName(S(_.rest(split, 1).join(' ')).chompLeft('@').chompRight(' ').s);
                if (user !== undefined) {
                    if (((plugged.getWaitlist() !== undefined) ? plugged.getWaitlist().indexOf(user.id) === -1 : false) && (plugged.getCurrentDJ() !== undefined ? plugged.getCurrentDJ().id !== user.id : true )) {
                        plugged.sendChat(utils.replace(langfile.bp_actions.add, {username: data.username}), 45);
                        if (plugged.getWaitlist().length < 50 || plugged.getWaitlist() === undefined) {
                            plugged.addToWaitlist(user.id, function (err) {
                                if(err)console.log(err);
                            });
                        } else {
                            redis.sadd('meta:addqueue', user.id);
                            redis.set('meta:addqueue:user:' + data.id, -1);
                        }
                    }
                } else { //noinspection JSCheckFunctionSignatures
                    plugged.sendChat(utils.replace(langfile.error.user_not_found, {
                        username: plugged.getUserByID(data.id),
                        value: S(_.rest(split, 1).join(' ')).chompLeft('@').s
                    }), 20);
                }
                story.info('add', utils.userLogString(data.username, data.id) + ': ' + utils.userLogString(user));
            }
        });
        plugged.removeChatMessage(data.cid);
    }
};<|endoftext|>


<commit_before>'use strict';

var q = require('q'),
    os = require('os'),
    fs = require('fs'),
    _ = require('lodash'),
    path = require('path'),
    steps = require('../steps'),
    db = require('../utils/mongo'),
    output = require('../utils/output'),
    logger = require('../utils/logger'),
    inquirer = require('inquirer'),
    guid = require('../utils/guid');

module.exports = function(){
    var questions = [{
            type: 'list',
            name: 'start',
            message: 'Do you want to continue?',
            choices: ['Yes', 'No']
        }],
        validate = require('../validate');

    logger.statement("Automated Grasshopper setup. A fresh Grasshopper application will be created in this directory.\nTo ensure that this process goes smoothly please review the prerequisites: https://github.com/Solid-Interactive/grasshopper-cli ");

    inquirer.prompt(questions, function( answers ) {
        var appName = process.cwd().substr((process.cwd().lastIndexOf('/') + 1), (process.cwd().length - process.cwd().lastIndexOf('/'))),
            appId = appName.toLowerCase().replace(/ /g,''),
            config = {
                project: {
                    home: process.cwd(),
                    name: appName,
                    main: 'app/' + appId + '.js',
                    installExpress: true
                },
                admin: {
                    buildDirectory : path.join('app', 'public', 'admin'),
                    apiEndpoint : ''
                },
                crypto: {
                    secret: guid()
                },
                assets: {
                    default : 'local',
                    tmpdir : path.join(process.cwd(), 'tmp'),
                    engines: {
                        local : {
                            path : path.join(process.cwd(), 'app', 'public', 'assets'),
                            urlbase : 'http://locahost:3000'
                        }
                    }
                },
                logger: {
                    adapters: [{
                        type: 'console',
                        application: appName,
                        machine: os.hostname()
                    }]
                },
                identities: {},
                db: db.buildConfig('mongodb://localhost/' + appId)
            };

        if(answers.start === 'Yes'){
            writePackageJson(config)
                .then(writeAdminConfig)
                .then(validate.hasPackageFile)
                .then(steps.scaffolding)
                .then(steps.npms)
                .then(writeConfig)
                .then(installAdmin)
                .then(db.createSampleData)
                .then(writeAppFile)
                .then(function(results){
                    output.setupCompleted();
                })
                .then(startApp)
                .catch(function(err){
                    logger.error('');
                    logger.error('Setup failed!');
                    logger.error('Reason: ' + err.message);
                });
        }
        else {
            logger.notice('');
            logger.notice('Quit without installing.');
        }
    });
};

function writePackageJson(config){
    var tpl = _.template(
            fs.readFileSync(path.join(__dirname, '../../templates/package.tpl'), 'utf-8')),
        output = tpl(config),
        deferred = q.defer();

    fs.writeFile(path.join(config.project.home, 'package.json'), output, 'utf-8', function(err){
        if(err){
            throw err;
        }
        deferred.resolve(config);
    });

    return deferred.promise;
}

function writeConfig(config){
    var tpl = _.template(
            fs.readFileSync(path.join(__dirname, '../../templates/core.tpl'), 'utf-8')),
        output = tpl(config),
        deferred = q.defer();

    fs.writeFile(path.join(config.project.home, 'ghapi.json'), output, 'utf-8', function(err){
        if(err){
            throw err;
        }
        deferred.resolve(config);
    });

    return deferred.promise;
}

function writeAdminConfig(config){
    var tpl = _.template(
            fs.readFileSync(path.join(__dirname, '../../templates/admin.tpl'), 'utf-8')),
        output = tpl(config),
        deferred = q.defer();

    fs.writeFile(path.join(config.project.home, 'gha.json'), output, 'utf-8', function(err){
        if(err){
            throw err;
        }
        deferred.resolve(config);
    });

    return deferred.promise;
}

function writeAppFile(config){
    var tpl = _.template(
            fs.readFileSync(path.join(__dirname, '../../templates/server.tpl'), 'utf-8')),
        output = tpl(config),
        deferred = q.defer();

    fs.writeFile(path.join(config.project.home, 'app', 'index.js'), output, 'utf-8', function(err){
        if(err){
            throw err;
        }
        deferred.resolve(config);
    });

    return deferred.promise;
}

function installAdmin(config){
    var exec = require('child_process').exec,
        cmd = path.join(config.project.home, './node_modules/.bin/grasshopper build'),
        child = exec(cmd, function(err, stdout, stderr){
            if(err) {
                console.log('exec error: ' + err);
            }
        }),
        progress = output.progress({label: 'Building grasshopper-admin. Please wait, this can take a few minutes.'}),
        deferred = q.defer();

    logger.trace('');
    logger.trace('RUNNING: ' + cmd);

    progress.start();

    child.on('error', function(err){
        deferred.reject(err);
    });

    child.on('close', function(code){
        if(code === 0){
            progress.complete();
            deferred.resolve(config);
        }
        else {
            deferred.reject(new Error(code));
        }
    });

    return deferred.promise;
}

function startApp(){
    var exec = require('child_process').exec,
        cmd = 'node app',
        child = exec(cmd),
        deferred = q.defer();

    logger.trace('');
    logger.trace('RUNNING: ' + cmd);
    logger.trace('Browse to your site at http://localhost:3000/admin');
    logger.trace('To log into the Grasshopper admin use: admin / TestPassword (remember to change)');

    child.on('error', function(err){
        deferred.reject(err);
    });

    child.on('close', function(code){
        if(code === 0){
            deferred.resolve();
        }
        else {
            deferred.reject(new Error(code));
        }
    });
    child.stdout.pipe(process.stdout);
    child.stderr.pipe(process.stderr);

    return deferred.promise;
}<commit_msg>Removed the function call to write the server file since all of that changed.<commit_after>'use strict';

var q = require('q'),
    os = require('os'),
    fs = require('fs'),
    _ = require('lodash'),
    path = require('path'),
    steps = require('../steps'),
    db = require('../utils/mongo'),
    output = require('../utils/output'),
    logger = require('../utils/logger'),
    inquirer = require('inquirer'),
    guid = require('../utils/guid');

module.exports = function(){
    var questions = [{
            type: 'list',
            name: 'start',
            message: 'Do you want to continue?',
            choices: ['Yes', 'No']
        }],
        validate = require('../validate');

    logger.statement("Automated Grasshopper setup. A fresh Grasshopper application will be created in this directory.\nTo ensure that this process goes smoothly please review the prerequisites: https://github.com/Solid-Interactive/grasshopper-cli ");

    inquirer.prompt(questions, function( answers ) {
        var appName = process.cwd().substr((process.cwd().lastIndexOf('/') + 1), (process.cwd().length - process.cwd().lastIndexOf('/'))),
            appId = appName.toLowerCase().replace(/ /g,''),
            config = {
                project: {
                    home: process.cwd(),
                    name: appName,
                    main: 'app/' + appId + '.js',
                    installExpress: true
                },
                admin: {
                    buildDirectory : path.join('app', 'public', 'admin'),
                    apiEndpoint : ''
                },
                crypto: {
                    secret: guid()
                },
                assets: {
                    default : 'local',
                    tmpdir : path.join(process.cwd(), 'tmp'),
                    engines: {
                        local : {
                            path : path.join(process.cwd(), 'app', 'public', 'assets'),
                            urlbase : 'http://locahost:3000'
                        }
                    }
                },
                logger: {
                    adapters: [{
                        type: 'console',
                        application: appName,
                        machine: os.hostname()
                    }]
                },
                identities: {},
                db: db.buildConfig('mongodb://localhost/' + appId)
            };

        if(answers.start === 'Yes'){
            writePackageJson(config)
                .then(writeAdminConfig)
                .then(validate.hasPackageFile)
                .then(steps.scaffolding)
                .then(steps.npms)
                .then(writeConfig)
                .then(installAdmin)
                .then(db.createSampleData)
                .then(function(results){
                    output.setupCompleted();
                })
                .then(startApp)
                .catch(function(err){
                    logger.error('');
                    logger.error('Setup failed!');
                    logger.error('Reason: ' + err.message);
                });
        }
        else {
            logger.notice('');
            logger.notice('Quit without installing.');
        }
    });
};

function writePackageJson(config){
    var tpl = _.template(
            fs.readFileSync(path.join(__dirname, '../../templates/package.tpl'), 'utf-8')),
        output = tpl(config),
        deferred = q.defer();

    fs.writeFile(path.join(config.project.home, 'package.json'), output, 'utf-8', function(err){
        if(err){
            throw err;
        }
        deferred.resolve(config);
    });

    return deferred.promise;
}

function writeConfig(config){
    var tpl = _.template(
            fs.readFileSync(path.join(__dirname, '../../templates/core.tpl'), 'utf-8')),
        output = tpl(config),
        deferred = q.defer();

    fs.writeFile(path.join(config.project.home, 'ghapi.json'), output, 'utf-8', function(err){
        if(err){
            throw err;
        }
        deferred.resolve(config);
    });

    return deferred.promise;
}

function writeAdminConfig(config){
    var tpl = _.template(
            fs.readFileSync(path.join(__dirname, '../../templates/admin.tpl'), 'utf-8')),
        output = tpl(config),
        deferred = q.defer();

    fs.writeFile(path.join(config.project.home, 'gha.json'), output, 'utf-8', function(err){
        if(err){
            throw err;
        }
        deferred.resolve(config);
    });

    return deferred.promise;
}

function installAdmin(config){
    var exec = require('child_process').exec,
        cmd = path.join(config.project.home, './node_modules/.bin/grasshopper build'),
        child = exec(cmd, function(err, stdout, stderr){
            if(err) {
                console.log('exec error: ' + err);
            }
        }),
        progress = output.progress({label: 'Building grasshopper-admin. Please wait, this can take a few minutes.'}),
        deferred = q.defer();

    logger.trace('');
    logger.trace('RUNNING: ' + cmd);

    progress.start();

    child.on('error', function(err){
        deferred.reject(err);
    });

    child.on('close', function(code){
        if(code === 0){
            progress.complete();
            deferred.resolve(config);
        }
        else {
            deferred.reject(new Error(code));
        }
    });

    return deferred.promise;
}

function startApp(){
    var exec = require('child_process').exec,
        cmd = 'node app',
        child = exec(cmd),
        deferred = q.defer();

    logger.trace('');
    logger.trace('RUNNING: ' + cmd);
    logger.trace('Browse to your site at: http://localhost:3000');
    logger.trace("Get to the admin at: http://localhost:/3000/admin\nCredentials are: admin / TestPassword (remember to change)");

    child.on('error', function(err){
        deferred.reject(err);
    });

    child.on('close', function(code){
        if(code === 0){
            deferred.resolve();
        }
        else {
            deferred.reject(new Error(code));
        }
    });
    child.stdout.pipe(process.stdout);
    child.stderr.pipe(process.stderr);

    return deferred.promise;
}<|endoftext|>


<commit_before>// new.js
//

'use strict';

var createError  = require('../createError');
var logErrorExit = require('../logErrorExit');

var fs      = require('fs');
var path    = require('path');
var request = require('request');
var tar     = require('tar-fs');
var zlib    = require('zlib');

var cwd = process.cwd();

// NEW
//

module.exports = {

  builder: function(yargs) {
    return yargs.option('author', {
      alias: 'a',
      describe: 'Set a project author\'s name',
      default: 'unknown',
    });
  },

  handler: function(argv) {

    var name = argv.name;

    var newProjectPath = path.join(cwd, name);

    var colliderFileData = {
      name: name,
      createdTime: Date.now(),
      author: argv.author,
    };

    var colliderFile = JSON.stringify(colliderFileData);

    // Create a new directory at 'newProjectPath'.
    fs.mkdir(newProjectPath, function (err) {

      // Set a default error message.
      var errMsg = `There was a problem creating "${name}" inside of "${cwd}".`;

      if (err) {

        // Using the error code, make the default error message more useful.
        switch (err.code) {
          case 'EEXIST':
            errMsg = `A file or directory named "${name}" already exists in "${cwd}".`;
            break;

          default:
        }

        var err = createError(errMsg);
        logErrorExit(err, true);

      } else {

        getCollider(newProjectPath, function () {
          writeColliderFile(colliderFile, newProjectPath);
        });

      }

    });

  },

};

// FUNCTIONS
//

function writeColliderFile(data, destination) {
  var colliderFilePath = path.join(destination, 'project', '.collider');

  fs.writeFile(colliderFilePath, data, function(err) {
    if (err) {
      throw err;
    }
  });
}

function getCollider(destination, cb) {
  request('http://getcollider.com/latest.tar.gz', function(err) {
    if (!err) {
      cb();
    } else {
      throw err;
    }
  })
    .pipe(zlib.createGunzip())
    .pipe(tar.extract(destination));
}
<commit_msg>Add a space between function and parenthesis<commit_after>// new.js
//

'use strict';

var createError  = require('../createError');
var logErrorExit = require('../logErrorExit');

var fs      = require('fs');
var path    = require('path');
var request = require('request');
var tar     = require('tar-fs');
var zlib    = require('zlib');

var cwd = process.cwd();

// NEW
//

module.exports = {

  builder: function (yargs) {
    return yargs.option('author', {
      alias: 'a',
      describe: 'Set a project author\'s name',
      default: 'unknown',
    });
  },

  handler: function (argv) {

    var name = argv.name;

    var newProjectPath = path.join(cwd, name);

    var colliderFileData = {
      name: name,
      createdTime: Date.now(),
      author: argv.author,
    };

    var colliderFile = JSON.stringify(colliderFileData);

    // Create a new directory at 'newProjectPath'.
    fs.mkdir(newProjectPath, function (err) {

      // Set a default error message.
      var errMsg = `There was a problem creating "${name}" inside of "${cwd}".`;

      if (err) {

        // Using the error code, make the default error message more useful.
        switch (err.code) {
          case 'EEXIST':
            errMsg = `A file or directory named "${name}" already exists in "${cwd}".`;
            break;

          default:
        }

        var err = createError(errMsg);
        logErrorExit(err, true);

      } else {

        getCollider(newProjectPath, function () {
          writeColliderFile(colliderFile, newProjectPath);
        });

      }

    });

  },

};

// FUNCTIONS
//

function writeColliderFile(data, destination) {
  var colliderFilePath = path.join(destination, 'project', '.collider');

  fs.writeFile(colliderFilePath, data, function(err) {
    if (err) {
      throw err;
    }
  });
}

function getCollider(destination, cb) {
  request('http://getcollider.com/latest.tar.gz', function(err) {
    if (!err) {
      cb();
    } else {
      throw err;
    }
  })
    .pipe(zlib.createGunzip())
    .pipe(tar.extract(destination));
}
<|endoftext|>