<commit_before>/*
 *   ___      ___ _______   ___       ________  ________  ________  ________  _____ ______   _______
 *  |\  \    /  /|\  ___ \ |\  \     |\   __  \|\   ___ \|\   __  \|\   __  \|\   _ \  _   \|\  ___ \
 *  \ \  \  /  / | \   __/|\ \  \    \ \  \|\  \ \  \_|\ \ \  \|\  \ \  \|\  \ \  \\\__\ \  \ \   __/|
 *   \ \  \/  / / \ \  \_|/_\ \  \    \ \  \\\  \ \  \ \\ \ \   _  _\ \  \\\  \ \  \\|__| \  \ \  \_|/__
 *    \ \    / /   \ \  \_|\ \ \  \____\ \  \\\  \ \  \_\\ \ \  \\  \\ \  \\\  \ \  \    \ \  \ \  \_|\ \
 *     \ \__/ /     \ \_______\ \_______\ \_______\ \_______\ \__\\ _\\ \_______\ \__\    \ \__\ \_______\
 *      \|__|/       \|_______|\|_______|\|_______|\|_______|\|__|\|__|\|_______|\|__|     \|__|\|_______|
 *
 */

var request = require("request");

function Velodrome(public_key, private_key) {
  this.config = {
    api: {
      api_host: "https://api.velodro.me",
      api_base_url: "",
      keys: {
        public_key: public_key,
        private_key: private_key
      },
      auth_token: "Basic " + new Buffer(public_key + ":" + private_key).toString("base64")
    }
  }
}

Velodrome.prototype.buildUrl = function (route) {
  return this.config.api.api_host + this.config.api.api_base_url + route;
};

Velodrome.prototype.sendRequest = function (method, route, fields = []) {
  // Build a URL
  var url = this.buildUrl(route);

  request({
    "method": method,
    "uri": url,
    headers: {
       "Content-Type": "application/json"
     }
  }, function (error, response, body) {
    if (error) {
      throw error;
    } else if (response && response.statusCode == 200) {
      return body;
    } else if (response) {
      return response;
    } else {
      return {};
    }
  });

}

Velodrome.prototype.echo = function () {
  return this;
}

Velodrome.prototype.getAccount = function () {
  // Fetch the user's account
}

module.exports = Velodrome;<commit_msg>Implemented new API endpoints<commit_after>/*
 *   ___      ___ _______   ___       ________  ________  ________  ________  _____ ______   _______
 *  |\  \    /  /|\  ___ \ |\  \     |\   __  \|\   ___ \|\   __  \|\   __  \|\   _ \  _   \|\  ___ \
 *  \ \  \  /  / | \   __/|\ \  \    \ \  \|\  \ \  \_|\ \ \  \|\  \ \  \|\  \ \  \\\__\ \  \ \   __/|
 *   \ \  \/  / / \ \  \_|/_\ \  \    \ \  \\\  \ \  \ \\ \ \   _  _\ \  \\\  \ \  \\|__| \  \ \  \_|/__
 *    \ \    / /   \ \  \_|\ \ \  \____\ \  \\\  \ \  \_\\ \ \  \\  \\ \  \\\  \ \  \    \ \  \ \  \_|\ \
 *     \ \__/ /     \ \_______\ \_______\ \_______\ \_______\ \__\\ _\\ \_______\ \__\    \ \__\ \_______\
 *      \|__|/       \|_______|\|_______|\|_______|\|_______|\|__|\|__|\|_______|\|__|     \|__|\|_______|
 *
 */

var request = require("request");

function Velodrome(public_key, private_key) {
  this.config = {
    api: {
      api_protocol: "https://",
      api_host: "api.velodro.me",
      api_base_url: "",
      keys: {
        public_key: public_key,
        private_key: private_key
      },
      auth_token: "Basic " + new Buffer(public_key + ":" + private_key).toString("base64")
    }
  }

  request.get({
    "uri": this.buildUrl("/account"),
    headers: {
      "Content-Type": "application/json"
    }
  }, function (error, response, data) {
    if (error) {
      throw error;
    } else if (response.code == 200 && data && data !== "Unauthorized") {
      // All good
    } else if (data && data === "Unauthorized") {
      throw new Error("Invalid credentials");
    }
  });
}

Velodrome.prototype.buildUrl = function (route) {
  return this.config.api.api_protocol + this.config.api.keys.public_key + ":" + this.config.api.keys.private_key + "@" + this.config.api.api_host + this.config.api.api_base_url + route;
};

Velodrome.prototype.sendRequest = function (method, route, callback, fields) {
  // Build a URL
  var url = this.buildUrl(route);

  var options = {
    "method": method,
    "uri": url,
    headers: {
       "Content-Type": "application/json",
       "Authorization": this.config.api.auth_token
    }
  };

  if (method === "POST") {
    options.form = fields;
  }

  request(options, function (error, response, data) {
    // Ternary operators are bad
    callback(error, response, (JSON.parse(data) ? JSON.parse(data) : data));
    //                                          ^                  ^
  });
}

Velodrome.prototype.echo = function () {
  return this;
}

Velodrome.prototype.getAccount = function (callback) {
  // Fetch the user's account
  this.sendRequest("GET", "/account", callback);
}

Velodrome.prototype.listCities = function (callback) {
  // Fetch the list of cities
  this.sendRequest("GET", "/cities", callback);
}

Velodrome.prototype.listCards = function (callback) {
  // Fetch the list of cards associated with the user's account
  this.sendRequest("GET", "/customer/cards", callback);
}

Velodrome.prototype.newQuote = function (options, callback) {
  // Create a new quote based on the parameters set
  this.sendRequest("POST", "/customer/quotes", callback, options);
}

Velodrome.prototype.newOrder = function (options, callback) {
  // Create a new order based on the parameters set
  this.sendRequest("POST", "/customer/orders", callback, options);
}

Velodrome.prototype.listQuotes = function (callback) {
  // Fetch the list of a customer's quotes and return them
  this.sendRequest("GET", "/customer/quotes", callback);
}

module.exports = Velodrome;<|endoftext|>


<commit_before>/*!
 * snakeskin-loader
 * https://github.com/SnakeskinTpl/snakeskin-loader
 *
 * Released under the MIT license
 * https://github.com/SnakeskinTpl/snakeskin-loader/blob/master/LICENSE
 */

var
	$C = require('collection.js').$C,
	parent = module.parent;

var
	path = require('path'),
	loaderUtils = require('loader-utils'),
	snakeskin = require('snakeskin'),
	beautify = require('js-beautify');

module.exports = function (source) {
	if (this.cacheable) {
		this.cacheable();
	}

	var
		opts = loaderUtils.parseQuery(this.query),
		tpls = {};

	opts = $C(opts).reduce(function (map, val, key) {
		map[key] = parse(val);
		return map;
	}, {});

	var prettyPrint;
	if (opts.exec) {
		if (opts.prettyPrint) {
			opts.prettyPrint = false;
			prettyPrint = true;
		}

		opts.context = tpls;
	}

	opts.cache = false;
	opts.throws = true;
	opts.debug = opts.debug || {};

	var
		file = this.resourcePath,
		res = snakeskin.compile(source, opts, {file: file}),
		_this = this;

	$C(opts.debug.files).forEach(function (bool, filePath) {
		_this.addDependency(filePath);
	});

	if (opts.exec) {
		res = snakeskin.getMainTpl(tpls, file, opts.tpl) || '';

		if (res) {
			res = res(opts.data);

			if (prettyPrint) {
				res = beautify['html'](res);
				res = res.replace(/\r?\n|\r/g, opts.eol);
			}

			res += opts.eol;
		}
	}

	return res;
};

function toJS(str) {
	return new Function(
		'module',
		'exports',
		'require',
		'__filename',
		'__dirname',
		'return ' + str

	)(parent, parent.exports, parent.require, parent.filename, path.dirname(parent.filename));
}

function parse(val) {
	try {
		if (typeof val === 'object') {
			$C(val).forEach(function (el, key) {
				val[key] = toJS(el);
			});

			return val;
		}

		return toJS(val);

	} catch (ignore) {
		return val;
	}
}
<commit_msg>:wrench:<commit_after>/*!
 * snakeskin-loader
 * https://github.com/SnakeskinTpl/snakeskin-loader
 *
 * Released under the MIT license
 * https://github.com/SnakeskinTpl/snakeskin-loader/blob/master/LICENSE
 */

var
	$C = require('collection.js').$C,
	parent = module.parent;

var
	path = require('path'),
	loaderUtils = require('loader-utils'),
	snakeskin = require('snakeskin'),
	beautify = require('js-beautify');

module.exports = function (source) {
	if (this.cacheable) {
		this.cacheable();
	}

	var
		opts = loaderUtils.parseQuery(this.query),
		tpls = {};

	opts = $C(opts).reduce(function (map, val, key) {
		map[key] = parse(val);
		return map;
	}, {});

	var prettyPrint;
	if (opts.exec) {
		if (opts.prettyPrint) {
			opts.prettyPrint = false;
			prettyPrint = true;
		}

		opts.context = tpls;
	}

	opts.cache = false;
	opts.throws = true;
	opts.debug = opts.debug || {};
	opts.module = opts.module || 'cjs';

	var
		file = this.resourcePath,
		res = snakeskin.compile(source, opts, {file: file}),
		_this = this;

	$C(opts.debug.files).forEach(function (bool, filePath) {
		_this.addDependency(filePath);
	});

	if (opts.exec) {
		res = snakeskin.getMainTpl(tpls, file, opts.tpl) || '';

		if (res) {
			res = res(opts.data);

			if (prettyPrint) {
				res = beautify['html'](res);
				res = res.replace(/\r?\n|\r/g, opts.eol);
			}

			res += opts.eol;
		}
	}

	return res;
};

function toJS(str) {
	return new Function(
		'module',
		'exports',
		'require',
		'__filename',
		'__dirname',
		'return ' + str

	)(parent, parent.exports, parent.require, parent.filename, path.dirname(parent.filename));
}

function parse(val) {
	try {
		if (typeof val === 'object') {
			$C(val).forEach(function (el, key) {
				val[key] = toJS(el);
			});

			return val;
		}

		return toJS(val);

	} catch (ignore) {
		return val;
	}
}
<|endoftext|>


<commit_before>var wdRunner = require('wd-tap-runner'),
    util = require('util'),
    EventEmitter = require('events').EventEmitter,
    wd = require('wd'),
    sauceConnect = require('sauce-connect-launcher'),
    sauceResults = require('sauce-results');;

var SAUCE_URL = 'ondemand.saucelabs.com',
    SAUCE_PORT = 80;

function Runner(user, key) {
    EventEmitter.call(this);

    this.user = user;
    this.key = key;
    this._running = false;
    this._tunnel = null;

    this._tunnelId = ('tap-test-'
        + Date.now() + '-'
        + Math.floor(Math.random() * 100));
}

util.inherits(Runner, EventEmitter);

Runner.prototype._getTunnel = function(callback) {
    if (this._tunnel) {
        return callback(null, this._tunnel);
    }

    var self = this,
        options = {
            username: this.user,
            accessKey: this.key,
            tunnelIdentifier: this._tunnelId
        };

    this.emit('tunnel-connect');
    sauceConnect(options, function(err, tunnel) {
        if (err) {
            self.emit('tunnel-error', err);
            return callback(err);
        }

        self._tunnel = tunnel;
        self.emit('tunnel', tunnel);
        setTimeout(function() {
            callback(null, tunnel);
        }, 5000);
    });
};

Runner.prototype.run = function(src, capabilities, options, callback) {
    if (this._running) {
        callback(new Error('Another test is currently running'));
        return;
    }

    options = options || {};
    callback = callback || (function() {});
    if (typeof options === 'function') {
        callback = options;
        options = {};
    }

    var self = this,
        results;
    this._running = true;

    this._getTunnel(function(err, tunnel) {
        if (err) {
            return done(err);
        }

        createBrowser(tunnel);
    });

    function createBrowser(tunnel) {
        var options = {};
        for (var k in capabilities) {
            options[k] = capabilities[k];
        }
        options['tunnel-identifier'] = self._tunnelId;

        var browser = wd.remote(
            SAUCE_URL, SAUCE_PORT,
            self.user, self.key);

        browser.init(options, function(err) {
            if (err) {
                return done(err);
            }

            self.emit('browser', browser);
            runTests(browser);
        });
    }

    function runTests(browser) {
        wdRunner(src, browser, options, function(err, results) {
            if (!err) {
                self.emit('results', results);
            }

            browser.quit(function() {
                // Ignore error when closing browser
                ran(err, results);
            });
        });
    }

    function ran(err, r) {
        if (err) {
            self._running = false;
            return callback(err);
        }

        results = r;

        sauceResults({
            user: self.user,
            key: self.key,
            passed: results.ok
        }, done);
    }

    function done(err) {
        if (err) {
            return callback(err);
        }

        self._running = false;
        callback(null, results);
    }
};

Runner.prototype.close = function(callback) {
    var self = this;

    if (this._running) {
        done(new Error('Tests are still running'));
    }

    if (this._tunnel) {
        this._tunnel.close(function() {
            done();
        });
    } else {
        done();
    }

    function done(err) {
        if (!err) {
            self.emit('close');
        }

        if (callback) {
            callback(err);
        }
    }
}

module.exports = Runner;
<commit_msg>Fix: Need to find the correct callback argument for error<commit_after>var wdRunner = require('wd-tap-runner'),
    util = require('util'),
    EventEmitter = require('events').EventEmitter,
    wd = require('wd'),
    sauceConnect = require('sauce-connect-launcher'),
    sauceResults = require('sauce-results');;

var SAUCE_URL = 'ondemand.saucelabs.com',
    SAUCE_PORT = 80;

function Runner(user, key) {
    EventEmitter.call(this);

    this.user = user;
    this.key = key;
    this._running = false;
    this._tunnel = null;

    this._tunnelId = ('tap-test-'
        + Date.now() + '-'
        + Math.floor(Math.random() * 100));
}

util.inherits(Runner, EventEmitter);

Runner.prototype._getTunnel = function(callback) {
    if (this._tunnel) {
        return callback(null, this._tunnel);
    }

    var self = this,
        options = {
            username: this.user,
            accessKey: this.key,
            tunnelIdentifier: this._tunnelId
        };

    this.emit('tunnel-connect');
    sauceConnect(options, function(err, tunnel) {
        if (err) {
            self.emit('tunnel-error', err);
            return callback(err);
        }

        self._tunnel = tunnel;
        self.emit('tunnel', tunnel);
        setTimeout(function() {
            callback(null, tunnel);
        }, 5000);
    });
};

Runner.prototype.run = function(src, capabilities, options, callback) {

    options = options || {};
    callback = callback || (function() {});
    if (typeof options === 'function') {
        callback = options;
        options = {};
    }

    if (this._running) {
        callback(new Error('Another test is currently running'));
        return;
    }

    var self = this,
        results;
    this._running = true;

    this._getTunnel(function(err, tunnel) {
        if (err) {
            return done(err);
        }

        createBrowser(tunnel);
    });

    function createBrowser(tunnel) {
        var options = {};
        for (var k in capabilities) {
            options[k] = capabilities[k];
        }
        options['tunnel-identifier'] = self._tunnelId;

        var browser = wd.remote(
            SAUCE_URL, SAUCE_PORT,
            self.user, self.key);

        browser.init(options, function(err) {
            if (err) {
                return done(err);
            }

            self.emit('browser', browser);
            runTests(browser);
        });
    }

    function runTests(browser) {
        wdRunner(src, browser, options, function(err, results) {
            if (!err) {
                self.emit('results', results);
            }

            browser.quit(function() {
                // Ignore error when closing browser
                ran(err, results);
            });
        });
    }

    function ran(err, r) {
        if (err) {
            self._running = false;
            return callback(err);
        }

        results = r;

        sauceResults({
            user: self.user,
            key: self.key,
            passed: results.ok
        }, done);
    }

    function done(err) {
        if (err) {
            return callback(err);
        }

        self._running = false;
        callback(null, results);
    }
};

Runner.prototype.close = function(callback) {
    var self = this;

    if (this._running) {
        done(new Error('Tests are still running'));
    }

    if (this._tunnel) {
        this._tunnel.close(function() {
            done();
        });
    } else {
        done();
    }

    function done(err) {
        if (!err) {
            self.emit('close');
        }

        if (callback) {
            callback(err);
        }
    }
}

module.exports = Runner;
<|endoftext|>


<commit_before>var
	gutil = require('gulp-util'),
	exec = require('child_process').exec,
	_ = require('lodash'),
	PluginError = gutil.PluginError,
	through = require('through2')
	;

// Consts
const PLUGIN_NAME = 'gulp-nunit-runner';

var assemblies = [],
	switches = [],
	options;

function gulpNunitRunner(opts) {
	options = opts;
	if (!options || !options.command) {
		throw new PluginError(PLUGIN_NAME, "Path to NUnit executable is required in options.command");
	}

	if (options.options) {
		parseSwitches(options.options);
	}

	// Creating and return a stream through which each file will pass
	return through.obj(transform, flush);
}

function parseSwitches(options) {
	_.forEach(options, function (val, key) {
		if (typeof val === 'boolean') {
			if (val) {
				switches.push('/' + key);
			}
			return;
		}
		if (typeof val === 'string') {
			switches.push('/' + key + ':"' + val + '"');
		}
	});
}

function transform(file, enc, callback) {
	assemblies.push(file.path);
	this.push(file);
	return callback();
}

function flush(callback) {
	var execute = [];
	execute.push(options.command);
	execute.push(switches.join(' '));
	execute.push(' "' + assemblies.join('" "') + '"');
	execute = execute.join('');
	console.log(execute);
	var cp = exec(execute, function (err, stdout, stderr) {
		console.log("err", err);
		console.log("stdout", stdout);
		console.log("stderr", stderr);
		return callback();
	});

	cp.stdout.pipe(process.stdout);
	cp.stderr.pipe(process.stderr);
}

module.exports = gulpNunitRunner;
<commit_msg>added additional error andling as well as some code cleanup<commit_after>
"use strict";
var
	gutil = require('gulp-util'),
	exec = require('child_process').exec,
	_ = require('lodash'),
	PluginError = gutil.PluginError,
	through = require('through2')
	;

var PLUGIN_NAME = 'gulp-nunit-runner';

var assemblies = [],
	switches = [],
	options;

function gulpNunitRunner(opts) {
	options = opts;
	if (!opts || !opts.command) {
		throw new PluginError(PLUGIN_NAME, "Path to NUnit executable is required in options.command");
	}

	if (opts.options) {
		parseSwitches(opts.options);
	}

	// Creating and return a stream through which each file will pass
	return through.obj(transform, flush);
}

function parseSwitches(options) {
	_.forEach(options, function (val, key) {
		if (typeof val === 'boolean') {
			if (val) {
				switches.push('/' + key);
			}
			return;
		}
		if (typeof val === 'string') {
			switches.push('/' + key + ':"' + val + '"');
		}
	});
}

function transform(file, enc, callback) {
	assemblies.push(file.path);
	this.push(file);
	return callback();
}

function flush(callback) {
	var execute = [];
	execute.push(options.command);
	execute.push(switches.join(' '));
	execute.push('"' + assemblies.join('" "') + '"');
	execute = execute.join(' ');

	var cp = exec(execute, function (err, stdout, stderr) {
		if (err) {
			return callback(err);
		}
		return callback();
	});

	cp.stdout.pipe(process.stdout);
	cp.stderr.pipe(process.stderr);
}

module.exports = gulpNunitRunner;
<|endoftext|>


<commit_before>/**!
 * koa-redis - index.js
 * Copyright(c) 2015
 * MIT Licensed
 *
 * Authors:
 *   dead_horse <dead_horse@qq.com> (http://deadhorse.me)
 */

'use strict';

/**
 * Module dependencies.
 */

var EventEmitter = require('events').EventEmitter;
var debug = require('debug')('koa-redis');
var redis = require('redis');
var ioredis = require("ioredis");
var redisWrapper = require('co-redis');
var util = require('util');
var wrap = require('co-wrap-all');

/**
 * Initialize redis session middleware with `opts` (see the README for more info):
 *
 * @param {Object} options
 *   - {Object} client       redis client (overides all other options except db and duplicate)
 *   - {String} socket       redis connect socket (DEPRECATED: use 'path' instead)
 *   - {String} db           redis db
 *   - {Boolean} duplicate   if own client object, will use node redis's duplicate function and pass other options
 *   - {String} pass         redis password (DEPRECATED: use 'auth_pass' instead)
 *   - {Any} [any]           all other options inclduing above are passed to node_redis
 */
var RedisStore = module.exports = function (options) {
  if (!(this instanceof RedisStore)) {
    return new RedisStore(options);
  }
  EventEmitter.call(this);
  options = options || {};

  var client;
  options.auth_pass = options.auth_pass || options.pass || null;     // For backwards compatibility
  options.path = options.path || options.socket || null;             // For backwards compatibility
  if (!options.client) {
    debug('Init redis new client');
    // client = redis.createClient(options);
    //
    // Apply ioredis, Add has redis cluster condition：
    if (!options.isRedisCluster) {
      client = redis.createClient(options);
    } else {
      client = new ioredis.Cluster(options.nodes, {redisOptions: options.redisOptions});
    }
  } else {
    if (options.duplicate) {                                         // Duplicate client and update with options provided
      debug('Duplicating provided client with new options (if provided)');
      var dupClient = options.client;
      delete options.client;
      delete options.duplicate;
      client = dupClient.duplicate(options);                         // Useful if you want to use the DB option without adjusting the client DB outside koa-redis
    } else {
      debug('Using provided client');
      client = options.client;
    }
  }

  if (options.db) {
    debug('selecting db %s', options.db)
    client.select(options.db);
    client.on('connect', function() {
      client.send_anyways = true;
      client.select(options.db);
      client.send_anyways = false;
    });
  }

  client.on('error', this.emit.bind(this, 'error'));
  client.on('end', this.emit.bind(this, 'end'));
  client.on('end', this.emit.bind(this, 'disconnect'));              // For backwards compatibility
  client.on('connect', this.emit.bind(this, 'connect'));
  client.on('reconnecting', this.emit.bind(this, 'reconnecting'));
  client.on('ready', this.emit.bind(this, 'ready'));
  client.on('warning', this.emit.bind(this, 'warning'));
  this.on('connect', function() {
    debug('connected to redis');
    this.connected = client.connected;
  });
  this.on('ready', function() {
    debug('redis ready');
  });
  this.on('end', function() {
    debug('redis ended');
    this.connected = client.connected;
  });
  // No good way to test error
  /* istanbul ignore next */
  this.on('error', function() {
    debug('redis error');
    this.connected = client.connected;
  });
  // No good way to test reconnect
  /* istanbul ignore next */
  this.on('reconnecting', function() {
    debug('redis reconnecting');
    this.connected = client.connected;
  });
  // No good way to test warning
  /* istanbul ignore next */
  this.on('warning', function() {
    debug('redis warning');
    this.connected = client.connected;
  });

  //wrap redis
  this._redisClient = client;
  this.client = redisWrapper(client);
  this.connected = client.connected;

  // support optional serialize and unserialize
  this.serialize = (typeof options.serialize === 'function' && options.serialize) || JSON.stringify;
  this.unserialize = (typeof options.unserialize === 'function' && options.unserialize) || JSON.parse;
};

util.inherits(RedisStore, EventEmitter);

RedisStore.prototype.get = function *(sid) {
  var data = yield this.client.get(sid);
  debug('get session: %s', data || 'none');
  if (!data) {
    return null;
  }
  try {
    return this.unserialize(data.toString());
  } catch (err) {
    // ignore err
    debug('parse session error: %s', err.message);
  }
};

RedisStore.prototype.set = function *(sid, sess, ttl) {
  if (typeof ttl === 'number') {
    ttl = Math.ceil(ttl / 1000);
  }
  sess = this.serialize(sess);
  if (ttl) {
    debug('SETEX %s %s %s', sid, ttl, sess);
    yield this.client.setex(sid, ttl, sess);
  } else {
    debug('SET %s %s', sid, sess);
    yield this.client.set(sid, sess);
  }
  debug('SET %s complete', sid);
};

RedisStore.prototype.destroy = function *(sid) {
  debug('DEL %s', sid);
  yield this.client.del(sid);
  debug('DEL %s complete', sid);
};

RedisStore.prototype.quit = function* () {                         // End connection SAFELY
  debug('quitting redis client');
  yield this.client.quit();
};

wrap(RedisStore.prototype);

RedisStore.prototype.end = RedisStore.prototype.quit;              // End connection SAFELY. The real end() command should never be used, as it cuts off to queue.
<commit_msg>fixed missed options.isRedisCluster<commit_after>/**!
 * koa-redis - index.js
 * Copyright(c) 2015
 * MIT Licensed
 *
 * Authors:
 *   dead_horse <dead_horse@qq.com> (http://deadhorse.me)
 */

'use strict';

/**
 * Module dependencies.
 */

var EventEmitter = require('events').EventEmitter;
var debug = require('debug')('koa-redis');
var redis = require('redis');
var ioredis = require("ioredis");
var redisWrapper = require('co-redis');
var util = require('util');
var wrap = require('co-wrap-all');

/**
 * Initialize redis session middleware with `opts` (see the README for more info):
 *
 * @param {Object} options
 *   - {Object} client       redis client (overides all other options except db and duplicate)
 *   - {String} socket       redis connect socket (DEPRECATED: use 'path' instead)
 *   - {String} db           redis db
 *   - {Boolean} duplicate   if own client object, will use node redis's duplicate function and pass other options
 *   - {String} pass         redis password (DEPRECATED: use 'auth_pass' instead)
 *   - {Any} [any]           all other options inclduing above are passed to node_redis
 */
var RedisStore = module.exports = function (options) {
  if (!(this instanceof RedisStore)) {
    return new RedisStore(options);
  }
  EventEmitter.call(this);
  options = options || {};

  var client;
  options.auth_pass = options.auth_pass || options.pass || null;     // For backwards compatibility
  options.path = options.path || options.socket || null;             // For backwards compatibility
  if (!options.client) {
    debug('Init redis new client');
    // client = redis.createClient(options);
    //
    // Apply ioredis, Add has redis cluster condition：
    if (options.isRedisCluster) {
      client = new ioredis.Cluster(options.nodes, {redisOptions: options.redisOptions});
    } else {
      client = redis.createClient(options);
    }
  } else {
    if (options.duplicate) {                                         // Duplicate client and update with options provided
      debug('Duplicating provided client with new options (if provided)');
      var dupClient = options.client;
      delete options.client;
      delete options.duplicate;
      client = dupClient.duplicate(options);                         // Useful if you want to use the DB option without adjusting the client DB outside koa-redis
    } else {
      debug('Using provided client');
      client = options.client;
    }
  }

  if (options.db) {
    debug('selecting db %s', options.db)
    client.select(options.db);
    client.on('connect', function() {
      client.send_anyways = true;
      client.select(options.db);
      client.send_anyways = false;
    });
  }

  client.on('error', this.emit.bind(this, 'error'));
  client.on('end', this.emit.bind(this, 'end'));
  client.on('end', this.emit.bind(this, 'disconnect'));              // For backwards compatibility
  client.on('connect', this.emit.bind(this, 'connect'));
  client.on('reconnecting', this.emit.bind(this, 'reconnecting'));
  client.on('ready', this.emit.bind(this, 'ready'));
  client.on('warning', this.emit.bind(this, 'warning'));
  this.on('connect', function() {
    debug('connected to redis');
    this.connected = client.connected;
  });
  this.on('ready', function() {
    debug('redis ready');
  });
  this.on('end', function() {
    debug('redis ended');
    this.connected = client.connected;
  });
  // No good way to test error
  /* istanbul ignore next */
  this.on('error', function() {
    debug('redis error');
    this.connected = client.connected;
  });
  // No good way to test reconnect
  /* istanbul ignore next */
  this.on('reconnecting', function() {
    debug('redis reconnecting');
    this.connected = client.connected;
  });
  // No good way to test warning
  /* istanbul ignore next */
  this.on('warning', function() {
    debug('redis warning');
    this.connected = client.connected;
  });

  //wrap redis
  this._redisClient = client;
  this.client = redisWrapper(client);
  this.connected = client.connected;

  // support optional serialize and unserialize
  this.serialize = (typeof options.serialize === 'function' && options.serialize) || JSON.stringify;
  this.unserialize = (typeof options.unserialize === 'function' && options.unserialize) || JSON.parse;
};

util.inherits(RedisStore, EventEmitter);

RedisStore.prototype.get = function *(sid) {
  var data = yield this.client.get(sid);
  debug('get session: %s', data || 'none');
  if (!data) {
    return null;
  }
  try {
    return this.unserialize(data.toString());
  } catch (err) {
    // ignore err
    debug('parse session error: %s', err.message);
  }
};

RedisStore.prototype.set = function *(sid, sess, ttl) {
  if (typeof ttl === 'number') {
    ttl = Math.ceil(ttl / 1000);
  }
  sess = this.serialize(sess);
  if (ttl) {
    debug('SETEX %s %s %s', sid, ttl, sess);
    yield this.client.setex(sid, ttl, sess);
  } else {
    debug('SET %s %s', sid, sess);
    yield this.client.set(sid, sess);
  }
  debug('SET %s complete', sid);
};

RedisStore.prototype.destroy = function *(sid) {
  debug('DEL %s', sid);
  yield this.client.del(sid);
  debug('DEL %s complete', sid);
};

RedisStore.prototype.quit = function* () {                         // End connection SAFELY
  debug('quitting redis client');
  yield this.client.quit();
};

wrap(RedisStore.prototype);

RedisStore.prototype.end = RedisStore.prototype.quit;              // End connection SAFELY. The real end() command should never be used, as it cuts off to queue.
<|endoftext|>


<commit_before>#!/usr/bin/env node
var optimist = require('optimist');

var argv = optimist.usage('Usage: $0 --interval [num] -serial [num] -lat [latitude] -lng [longitude]').
    options('i', {
        alias : 'interval',
        default : '30',
        describe: 'update interval'
    }).
    options('s', {
        alias : 'serial',
        default : '',
        describe: '013612345678'
    }).
    options('x', {
        alias : 'lat',
        default : '52.80113',
        describe: 'initial latitude'
    }).
    options('y', {
        alias : 'lng',
        default: '-1.63130',
        describe: 'initial longitude'
    }).
    options('h', {
        alias : 'help',
        describe: 'show help'
    }).argv;

console.log(argv);<commit_msg>send 'dog tracker login'<commit_after>#!/usr/bin/env node
var optimist = require('optimist');
var net = require('net');

var DOG_TRACKER_LOGIN = "(013500001112BP05000013500001112120903A5956.1894N01046.9892E006.0160134061.9600000000L00000000)";
var DOG_TRACKER_ISOCHRONOUS_FOR_CONTINUES_FEEDBACK_MESSAGE = "(013500001112BR00120903A5955.9535N01047.4548E000.0160957000.0000000000L00000000)"

var argv = optimist.usage('Usage: $0 --interval [num] -serial [num] -lat [latitude] -lng [longitude]').
    options('i', {
        alias : 'interval',
        default : '30',
        describe: 'update interval'
    }).
    options('s', {
        alias : 'serial',
        default : '',
        describe: '013612345678'
    }).
    options('x', {
        alias : 'lat',
        default : '52.80113',
        describe: 'initial latitude'
    }).
    options('y', {
        alias : 'lng',
        default: '-1.63130',
        describe: 'initial longitude'
    }).
    options('h', {
        alias : 'host',
        describe: 'server host'
    }).
    options('p', {
        alias : 'port',
        describe: 'server port',
        default: '1337'
    }).
    argv;

var client = net.connect({host:argv.host, port:argv.port }, function() {
     client.write(DOG_TRACKER_LOGIN);
     console.log('login sent');
});
<|endoftext|>


<commit_before>'use strict';

var constant          = require('es5-ext/function/constant')
  , setPrototypeOf    = require('es5-ext/object/set-prototype-of')
  , toArray           = require('es5-ext/object/to-array')
  , ensureString      = require('es5-ext/object/validate-stringifiable-value')
  , ensureObject      = require('es5-ext/object/valid-object')
  , serializeValue    = require('dbjs/_setup/serialize/value')
  , unserializeValue  = require('dbjs/_setup/unserialize/value')
  , resolveKeyPath    = require('dbjs/_setup/utils/resolve-key-path')
  , d                 = require('d')
  , deferred          = require('deferred')
  , MongoClient       = require('mongodb').MongoClient
  , MongoCursor       = require('mongodb/lib/cursor')
  , PersistenceDriver = require('dbjs-persistence/abstract')

  , create = Object.create, promisify = deferred.promisify
  , getUndefined = constant(undefined), getNull = constant(null)
  , connect = promisify(MongoClient.connect)
  , isUnserializable = RegExp.prototype.test.bind(/[01234]/)
  , updateOpts = { upsert: true }
  , byStamp = function (a, b) { return this[a] - this[b]; };

Object.defineProperties(MongoCursor.prototype, {
	nextPromised: d(promisify(MongoCursor.prototype.next)),
	toArrayPromised: d(promisify(MongoCursor.prototype.toArray)),
	closePromised: d(promisify(MongoCursor.prototype.close))
});

var buildUrl = function (conf) {
	var url = 'mongodb://';
	if (conf.user && conf.password) url += conf.user + ':' + conf.password + '@';
	url += (conf.host != null) ? conf.host : 'localhost';
	url += ':';
	url += (conf.port != null) ? conf.port : '27017';
	return url + '/' + conf.database;
};
var MongoDriver = module.exports = function (dbjs, data) {
	var collection;
	if (!(this instanceof MongoDriver)) return new MongoDriver(dbjs, data);
	ensureObject(data);
	ensureString(data.database);
	collection = ensureString(data.collection);
	PersistenceDriver.call(this, dbjs, data);
	this.mongoDb = connect(buildUrl(data)).aside(null, this.emitError);
	this.directDb = this.mongoDb.invokeAsync('collection', collection);
	this.computedDb = this.mongoDb.invokeAsync('collection', collection + '-computed');
	this.reducedDb = this.mongoDb.invokeAsync('collection', collection + '-reduced');
};
setPrototypeOf(MongoDriver, PersistenceDriver);

MongoDriver.prototype = Object.create(PersistenceDriver.prototype, {
	constructor: d(MongoDriver),

	// Any data
	__getRaw: d(function (cat, ns, path) {
		if (cat === 'reduced') return this._getReduced_(ns + (path ? ('/' + path) : ''));
		if (cat === 'computed') return this._getComputed_(path, ns);
		return this._getDirect_(ns, path);
	}),
	__storeRaw: d(function (cat, ns, path, data) {
		if (cat === 'reduced') return this._storeReduced_(ns, path, data);
		if (cat === 'computed') return this._storeComputed_(path, ns, data);
		return this._storeDirect_(ns, path, data);
	}),

	// Direct data
	__getDirectObject: d(function (ownerId, keyPaths) {
		return this._loadDirect_({ ownerId: ownerId },
			keyPaths && function (ownerId, path) {
				if (!path) return true;
				return keyPaths.has(resolveKeyPath(ownerId + '/' + path));
			});
	}),
	__getDirectAllObjectIds: d(function () {
		return this.directDb.invokeAsync('find')(function (cursor) {
			return cursor.toArrayPromised()(function (records) {
				var data = create(null);
				records.forEach(function (record) {
					if (!record.keyPath) {
						data[record.ownerId] = record.stamp;
						return;
					}
					if (!data[record.ownerId]) data[record.ownerId] = 0;
				});
				return cursor.closePromised()(toArray(data,
					function (stamp, id) { return id; }, this, byStamp));
			}.bind(this));
		}.bind(this));
	}),
	__getDirectAll: d(function () { return this._loadDirect_(); }),

	// Reduced data
	__getReducedObject: d(function (ns, keyPaths) {
		return this.reducedDb.invokeAsync('find', { ns: ns })(function (cursor) {
			return cursor.toArrayPromised()(function (records) {
				var result = create(null);
				records.forEach(function (record) {
					result[record._id] = {
						value: record.unserialized ? serializeValue(record.value) : record.value,
						stamp: record.stamp
					};
				});
				return cursor.closePromised()(result);
			}.bind(this));
		}.bind(this));
	}),

	// Size tracking
	__searchDirect: d(function (keyPath, callback) {
		return this.directDb.invokeAsync('find')(function (cursor) {
			return cursor.toArrayPromised()(function (records) {
				records.some(function (record) {
					if (!keyPath) {
						if (record.keyPath) return;
					} else if (keyPath !== record.keyPath) {
						return;
					}
					return callback(record._id, {
						value: record.unserialized ? serializeValue(record.value) : record.value,
						stamp: record.stamp
					});
				});
				return cursor.closePromised()(getUndefined);
			}.bind(this));
		}.bind(this));
	}),
	__searchComputed: d(function (keyPath, callback) {
		return this.computedDb.invokeAsync('find', { keyPath: keyPath })(function (cursor) {
			return cursor.toArrayPromised()(function (records) {
				records.some(function (record) {
					callback(record.ownerId, {
						value: record.unserialized ? serializeValue(record.value) : record.value,
						stamp: record.stamp
					});
				});
				return cursor.closePromised()(getUndefined);
			});
		});
	}),

	// Storage import/export
	__exportAll: d(function (destDriver) {
		var count = 0;
		var promise = deferred(
			this.directDb.invokeAsync('find')(function (cursor) {
				return cursor.toArrayPromised()(function (records) {
					return cursor.closePromised()(deferred.map(records, function (record) {
						if (!(++count % 1000)) promise.emit('progress');
						return destDriver._storeRaw('direct', record.ownerId, record.path, {
							value: record.unserialized ? serializeValue(record.value) : record.value,
							stamp: record.stamp
						});
					}, this));
				}.bind(this));
			}.bind(this)),
			this.computedDb.invokeAsync('find')(function (cursor) {
				return cursor.toArrayPromised()(function (records) {
					return cursor.closePromised()(deferred.map(records, function (record) {
						if (!(++count % 1000)) promise.emit('progress');
						return destDriver._storeRaw('computed', record.keyPath, record.ownerId, {
							value: record.unserialized ? serializeValue(record.value) : record.value,
							stamp: record.stamp
						});
					}, this));
				}.bind(this));
			}.bind(this)),
			this.reducedDb.invokeAsync('find')(function (cursor) {
				return cursor.toArrayPromised()(function (records) {
					return cursor.closePromised()(deferred.map(records, function (record) {
						if (!(++count % 1000)) promise.emit('progress');
						return destDriver._storeRaw('reduced', record.ns, record.path, {
							value: record.unserialized ? serializeValue(record.value) : record.value,
							stamp: record.stamp
						});
					}, this));
				}.bind(this));
			}.bind(this))
		);
		return promise;
	}),
	__clear: d(function () {
		return deferred(
			this.directDb.invokeAsync('deleteMany'),
			this.computedDb.invokeAsync('deleteMany'),
			this.reducedDb.invokeAsync('deleteMany')
		);
	}),

	// Connection related
	__close: d(function () { return this.mongoDb.invokeAsync('close'); }),

	// Driver specific
	_getDirect_: d(function (ownerId, path) {
		return this.directDb.invokeAsync('find', { _id: ownerId + (path ? ('/' + path) : '') })(
			function (cursor) {
				return cursor.nextPromised()(function (record) {
					return cursor.closePromised()(record ? {
						value: record.unserialized ? serializeValue(record.value) : record.value,
						stamp: record.stamp
					} : getNull);
				}.bind(this));
			}.bind(this)
		);
	}),
	_getComputed_: d(function (ownerId, keyPath) {
		return this.computedDb.invokeAsync('find', { _id: keyPath + ':' + ownerId })(
			function (cursor) {
				return cursor.nextPromised()(function (record) {
					return cursor.closePromised()(record ? {
						value: record.unserialized ? serializeValue(record.value) : record.value,
						stamp: record.stamp
					} : getNull);
				});
			}
		);
	}),
	_getReduced_: d(function (key) {
		return this.reducedDb.invokeAsync('find', { _id: key })(function (cursor) {
			return cursor.nextPromised()(function (record) {
				return cursor.closePromised()(record ? {
					value: record.unserialized ? serializeValue(record.value) : record.value,
					stamp: record.stamp
				} : getNull);
			});
		});
	}),
	_storeDirect_: d(function (ownerId, path, data) {
		var unserialized = Boolean(data.value && isUnserializable(data.value[0]));
		var record = {
			ownerId: ownerId,
			value: unserialized ? unserializeValue(data.value) : data.value,
			stamp: data.stamp
		};
		if (path) {
			record.path = path;
			record.keyPath = resolveKeyPath(ownerId + '/' + path);
		}
		if (unserialized) record.unserialized = true;
		return this.directDb.invokeAsync('update', { _id: ownerId + (path ? ('/' + path) : '') },
			record, updateOpts);
	}),
	_storeComputed_: d(function (ownerId, keyPath, data) {
		var unserialized = Boolean(data.value && isUnserializable(data.value[0]));
		var record = {
			ownerId: ownerId,
			keyPath: keyPath,
			value: unserialized ? unserializeValue(data.value) : data.value,
			stamp: data.stamp
		};
		if (unserialized) record.unserialized = true;
		return this.computedDb.invokeAsync('update', { _id: keyPath + ':' + ownerId },
			record, updateOpts);
	}),
	_storeReduced_: d(function (ns, path, data) {
		var unserialized = Boolean(data.value && isUnserializable(data.value[0]));
		var record = {
			ns: ns,
			value: unserialized ? unserializeValue(data.value) : data.value,
			stamp: data.stamp
		};
		if (path) record.path = path;
		if (unserialized) record.unserialized = true;
		return this.reducedDb.invokeAsync('update', { _id: ns + (path ? ('/' + path) : '') },
			record, updateOpts);
	}),
	_loadDirect_: d(function (query, filter) {
		return this.directDb.invokeAsync('find', query)(function (cursor) {
			return cursor.toArrayPromised()(function (records) {
				var result = create(null);
				records.forEach(function (record) {
					if (filter && !filter(record.ownerId, record.path)) return; // filtered
					result[record._id] = {
						value: record.unserialized ? serializeValue(record.value) : record.value,
						stamp: record.stamp
					};
				});
				return cursor.closePromised()(result);
			}.bind(this));
		}.bind(this));
	})
});
<commit_msg>Update __getDirectAllObjectIds up to changes<commit_after>'use strict';

var constant          = require('es5-ext/function/constant')
  , setPrototypeOf    = require('es5-ext/object/set-prototype-of')
  , ensureString      = require('es5-ext/object/validate-stringifiable-value')
  , ensureObject      = require('es5-ext/object/valid-object')
  , serializeValue    = require('dbjs/_setup/serialize/value')
  , unserializeValue  = require('dbjs/_setup/unserialize/value')
  , resolveKeyPath    = require('dbjs/_setup/utils/resolve-key-path')
  , d                 = require('d')
  , deferred          = require('deferred')
  , MongoClient       = require('mongodb').MongoClient
  , MongoCursor       = require('mongodb/lib/cursor')
  , PersistenceDriver = require('dbjs-persistence/abstract')

  , create = Object.create, promisify = deferred.promisify
  , getUndefined = constant(undefined), getNull = constant(null)
  , connect = promisify(MongoClient.connect)
  , isUnserializable = RegExp.prototype.test.bind(/[01234]/)
  , updateOpts = { upsert: true };

Object.defineProperties(MongoCursor.prototype, {
	nextPromised: d(promisify(MongoCursor.prototype.next)),
	toArrayPromised: d(promisify(MongoCursor.prototype.toArray)),
	closePromised: d(promisify(MongoCursor.prototype.close))
});

var buildUrl = function (conf) {
	var url = 'mongodb://';
	if (conf.user && conf.password) url += conf.user + ':' + conf.password + '@';
	url += (conf.host != null) ? conf.host : 'localhost';
	url += ':';
	url += (conf.port != null) ? conf.port : '27017';
	return url + '/' + conf.database;
};
var MongoDriver = module.exports = function (dbjs, data) {
	var collection;
	if (!(this instanceof MongoDriver)) return new MongoDriver(dbjs, data);
	ensureObject(data);
	ensureString(data.database);
	collection = ensureString(data.collection);
	PersistenceDriver.call(this, dbjs, data);
	this.mongoDb = connect(buildUrl(data)).aside(null, this.emitError);
	this.directDb = this.mongoDb.invokeAsync('collection', collection);
	this.computedDb = this.mongoDb.invokeAsync('collection', collection + '-computed');
	this.reducedDb = this.mongoDb.invokeAsync('collection', collection + '-reduced');
};
setPrototypeOf(MongoDriver, PersistenceDriver);

MongoDriver.prototype = Object.create(PersistenceDriver.prototype, {
	constructor: d(MongoDriver),

	// Any data
	__getRaw: d(function (cat, ns, path) {
		if (cat === 'reduced') return this._getReduced_(ns + (path ? ('/' + path) : ''));
		if (cat === 'computed') return this._getComputed_(path, ns);
		return this._getDirect_(ns, path);
	}),
	__storeRaw: d(function (cat, ns, path, data) {
		if (cat === 'reduced') return this._storeReduced_(ns, path, data);
		if (cat === 'computed') return this._storeComputed_(path, ns, data);
		return this._storeDirect_(ns, path, data);
	}),

	// Direct data
	__getDirectObject: d(function (ownerId, keyPaths) {
		return this._loadDirect_({ ownerId: ownerId },
			keyPaths && function (ownerId, path) {
				if (!path) return true;
				return keyPaths.has(resolveKeyPath(ownerId + '/' + path));
			});
	}),
	__getDirectAllObjectIds: d(function () {
		return this.directDb.invokeAsync('find')(function (cursor) {
			return cursor.toArrayPromised()(function (records) {
				var data = create(null);
				records.forEach(function (record) {
					if (!record.keyPath) data[record.ownerId] = record;
				});
				return cursor.closePromised()(data);
			});
		}.bind(this));
	}),
	__getDirectAll: d(function () { return this._loadDirect_(); }),

	// Reduced data
	__getReducedObject: d(function (ns, keyPaths) {
		return this.reducedDb.invokeAsync('find', { ns: ns })(function (cursor) {
			return cursor.toArrayPromised()(function (records) {
				var result = create(null);
				records.forEach(function (record) {
					result[record._id] = {
						value: record.unserialized ? serializeValue(record.value) : record.value,
						stamp: record.stamp
					};
				});
				return cursor.closePromised()(result);
			}.bind(this));
		}.bind(this));
	}),

	// Size tracking
	__searchDirect: d(function (keyPath, callback) {
		return this.directDb.invokeAsync('find')(function (cursor) {
			return cursor.toArrayPromised()(function (records) {
				records.some(function (record) {
					if (!keyPath) {
						if (record.keyPath) return;
					} else if (keyPath !== record.keyPath) {
						return;
					}
					return callback(record._id, {
						value: record.unserialized ? serializeValue(record.value) : record.value,
						stamp: record.stamp
					});
				});
				return cursor.closePromised()(getUndefined);
			}.bind(this));
		}.bind(this));
	}),
	__searchComputed: d(function (keyPath, callback) {
		return this.computedDb.invokeAsync('find', { keyPath: keyPath })(function (cursor) {
			return cursor.toArrayPromised()(function (records) {
				records.some(function (record) {
					callback(record.ownerId, {
						value: record.unserialized ? serializeValue(record.value) : record.value,
						stamp: record.stamp
					});
				});
				return cursor.closePromised()(getUndefined);
			});
		});
	}),

	// Storage import/export
	__exportAll: d(function (destDriver) {
		var count = 0;
		var promise = deferred(
			this.directDb.invokeAsync('find')(function (cursor) {
				return cursor.toArrayPromised()(function (records) {
					return cursor.closePromised()(deferred.map(records, function (record) {
						if (!(++count % 1000)) promise.emit('progress');
						return destDriver._storeRaw('direct', record.ownerId, record.path, {
							value: record.unserialized ? serializeValue(record.value) : record.value,
							stamp: record.stamp
						});
					}, this));
				}.bind(this));
			}.bind(this)),
			this.computedDb.invokeAsync('find')(function (cursor) {
				return cursor.toArrayPromised()(function (records) {
					return cursor.closePromised()(deferred.map(records, function (record) {
						if (!(++count % 1000)) promise.emit('progress');
						return destDriver._storeRaw('computed', record.keyPath, record.ownerId, {
							value: record.unserialized ? serializeValue(record.value) : record.value,
							stamp: record.stamp
						});
					}, this));
				}.bind(this));
			}.bind(this)),
			this.reducedDb.invokeAsync('find')(function (cursor) {
				return cursor.toArrayPromised()(function (records) {
					return cursor.closePromised()(deferred.map(records, function (record) {
						if (!(++count % 1000)) promise.emit('progress');
						return destDriver._storeRaw('reduced', record.ns, record.path, {
							value: record.unserialized ? serializeValue(record.value) : record.value,
							stamp: record.stamp
						});
					}, this));
				}.bind(this));
			}.bind(this))
		);
		return promise;
	}),
	__clear: d(function () {
		return deferred(
			this.directDb.invokeAsync('deleteMany'),
			this.computedDb.invokeAsync('deleteMany'),
			this.reducedDb.invokeAsync('deleteMany')
		);
	}),

	// Connection related
	__close: d(function () { return this.mongoDb.invokeAsync('close'); }),

	// Driver specific
	_getDirect_: d(function (ownerId, path) {
		return this.directDb.invokeAsync('find', { _id: ownerId + (path ? ('/' + path) : '') })(
			function (cursor) {
				return cursor.nextPromised()(function (record) {
					return cursor.closePromised()(record ? {
						value: record.unserialized ? serializeValue(record.value) : record.value,
						stamp: record.stamp
					} : getNull);
				}.bind(this));
			}.bind(this)
		);
	}),
	_getComputed_: d(function (ownerId, keyPath) {
		return this.computedDb.invokeAsync('find', { _id: keyPath + ':' + ownerId })(
			function (cursor) {
				return cursor.nextPromised()(function (record) {
					return cursor.closePromised()(record ? {
						value: record.unserialized ? serializeValue(record.value) : record.value,
						stamp: record.stamp
					} : getNull);
				});
			}
		);
	}),
	_getReduced_: d(function (key) {
		return this.reducedDb.invokeAsync('find', { _id: key })(function (cursor) {
			return cursor.nextPromised()(function (record) {
				return cursor.closePromised()(record ? {
					value: record.unserialized ? serializeValue(record.value) : record.value,
					stamp: record.stamp
				} : getNull);
			});
		});
	}),
	_storeDirect_: d(function (ownerId, path, data) {
		var unserialized = Boolean(data.value && isUnserializable(data.value[0]));
		var record = {
			ownerId: ownerId,
			value: unserialized ? unserializeValue(data.value) : data.value,
			stamp: data.stamp
		};
		if (path) {
			record.path = path;
			record.keyPath = resolveKeyPath(ownerId + '/' + path);
		}
		if (unserialized) record.unserialized = true;
		return this.directDb.invokeAsync('update', { _id: ownerId + (path ? ('/' + path) : '') },
			record, updateOpts);
	}),
	_storeComputed_: d(function (ownerId, keyPath, data) {
		var unserialized = Boolean(data.value && isUnserializable(data.value[0]));
		var record = {
			ownerId: ownerId,
			keyPath: keyPath,
			value: unserialized ? unserializeValue(data.value) : data.value,
			stamp: data.stamp
		};
		if (unserialized) record.unserialized = true;
		return this.computedDb.invokeAsync('update', { _id: keyPath + ':' + ownerId },
			record, updateOpts);
	}),
	_storeReduced_: d(function (ns, path, data) {
		var unserialized = Boolean(data.value && isUnserializable(data.value[0]));
		var record = {
			ns: ns,
			value: unserialized ? unserializeValue(data.value) : data.value,
			stamp: data.stamp
		};
		if (path) record.path = path;
		if (unserialized) record.unserialized = true;
		return this.reducedDb.invokeAsync('update', { _id: ns + (path ? ('/' + path) : '') },
			record, updateOpts);
	}),
	_loadDirect_: d(function (query, filter) {
		return this.directDb.invokeAsync('find', query)(function (cursor) {
			return cursor.toArrayPromised()(function (records) {
				var result = create(null);
				records.forEach(function (record) {
					if (filter && !filter(record.ownerId, record.path)) return; // filtered
					result[record._id] = {
						value: record.unserialized ? serializeValue(record.value) : record.value,
						stamp: record.stamp
					};
				});
				return cursor.closePromised()(result);
			}.bind(this));
		}.bind(this));
	})
});
<|endoftext|>


<commit_before>define(['require', 'exports'], function(require, exports) {
	var defaultData = exports.defaultData = {
		root: parentify(nameify({
			name: 'FILESYSTEM_ROOT_/',
			files: {
				home: {
					files: {
						user: {
							files: {
								'README.md': {
									contents: ''
								}
							}
						}
					}
				}
			}
		}))
	};

	function clone(o) {
		function O() {}
		O.prototype = o;
		return new O;
	}

	var Filesystem = exports.Filesystem = (function() {
		function Filesystem(data) {
			this.data = nameify(parentify(data || clone(defaultData)));
			this.currentDir = this.data.root;
		}

		//var currentDir = exports.currentDir = fs.root;

		Filesystem.prototype.getFile = function getFile(path, curDir) {
				var tmpDir, pathArr;

				if(!curDir) curDir = this.currentDir;
				if(!path || path.length == 0) return curDir;
				if(path.length > 0 && path[0] == '/') curDir = this.data.root;

				tmpDir = curDir;
				pathArr = path.split('/');

				pathArr.forEach(function(part) {
					if(part) {
						if(part == '..') {
							tmpDir = tmpDir.parent || tmpDir;
						} else if(part == '.') {
							return;
						} else if(this.isDir(tmpDir)) {
							if(this.hasFile(tmpDir, part)) tmpDir = tmpDir.files[part];
							else throw new Error("FileNotFoundError: Can not find file: '" +
								part +
								"' in directory: '" +
								this.pathTo(tmpDir));
							if(this.isSymlink(tmpDir)) {
								tmpDir = this.getSymlink(tmpDir);
							}
						} else {
							return false;
						}
					}
				});

				return tmpDir;
		};

		Filesystem.prototype.pathTo = function pathTo(file, /* internal */ isNested) {
			if(!isNested && file.name == this.data.root.name) return '/';
			if(!!file === false || (!!file && !!file.name && file.name == fs.root.name)) {
				return "";
			}

			return this.pathTo(file.parent, true) + '/' + file.name;
		};

		Filesystem.prototype.changeDir = function changeDir(dir) {
			if(dir && this.isDir(dir)) this.currentDir = dir;

			return dir;
		}

		Filesystem.prototype.createFile = function createFile(fileName, curDir) {
			var split, dir;

			if(!curDir) curDir = this.currentDir;

			split = fileName.split('/');
			dir = this.getFile(split.slice(0, split.length - 2).join('/'), curDir);

			console.log('dir:', dir);

			if(!this.hasFile(dir, split[split.length - 1])) {
				return dir.files[split[split.length - 1]] = {
					name: split[split.length - 1]
				};
			}
		};

		Filesystem.prototype.getSymlink = function getSymlink(file, curDir) {
			if(this.isSymlink(file)) return this.getFile(file.symlink, curDir);

			return file;
		}

		Filesystem.prototype.writeData = function writeData(file, data) {
			if(file && data) file.contents = data;

			return file;
		};

		Filesystem.prototype.initDir = function initDir(file) {
			if(file && !file.files) file.files = {};

			return file;
		};

		Filesystem.prototype.symlink = function symlink(file, where) {
			file.symlink = where;

			return file;
		};

		Filesystem.prototype.readFile = function readFile(file) {
			if(!file) return undefined;

			file = this.getSymlink(file);

			if(file && this.isFile(file)) return file.contents;
		}

		Filesystem.prototype.listFiles = function listFiles(dir) {
			dir = dir || this.currentDir;

			if(!this.isDir(dir)) return undefined;

			return Object.keys(dir.files).map(function(name) {
				return dir.files[name];
			});
		}

		Filesystem.prototype.hasFile = function hasFile(dir, name) {
			return dir && dir.files && dir.files[name];
		};

		Filesystem.prototype.isDir = function isDir(file) {
			return file && file.files;
		};

		Filesystem.prototype.isFile = function isFile(file) {
			return file && file.contents !== null && file.contents !== undefined;
		};

		Filesystem.prototype.isSymlink = function isSymlink(file) {
			return file && file.symlink;
		}

		return Filesystem;
	})();

	function parentify(data) {
		for(var key in data.files) {
			data.files[key].parent = data;

			if(data.files[key].files) data.files[key] = parentify(data.files[key]);
		}

		return data;
	}

	function nameify(data) {
		for(var key in data.files) {
			data.files[key].name = key;

			if(data.files[key].files) data.files[key] = nameify(data.files[key]);
		}

		return data;
	}
});
<commit_msg>Making the cloned objects more recognizable<commit_after>define(['require', 'exports'], function(require, exports) {
	var defaultData = exports.defaultData = {
		root: parentify(nameify({
			name: 'FILESYSTEM_ROOT_/',
			files: {
				home: {
					files: {
						user: {
							files: {
								'README.md': {
									contents: ''
								}
							}
						}
					}
				}
			}
		}))
	};

	function clone(o) {
		function cloned() {}
		cloned.prototype = o;
		return new cloned;
	}

	var Filesystem = exports.Filesystem = (function() {
		function Filesystem(data) {
			this.data = nameify(parentify(data || clone(defaultData)));
			this.currentDir = this.data.root;
		}

		//var currentDir = exports.currentDir = fs.root;

		Filesystem.prototype.getFile = function getFile(path, curDir) {
				var tmpDir, pathArr;

				if(!curDir) curDir = this.currentDir;
				if(!path || path.length == 0) return curDir;
				if(path.length > 0 && path[0] == '/') curDir = this.data.root;

				tmpDir = curDir;
				pathArr = path.split('/');

				pathArr.forEach(function(part) {
					if(part) {
						if(part == '..') {
							tmpDir = tmpDir.parent || tmpDir;
						} else if(part == '.') {
							return;
						} else if(this.isDir(tmpDir)) {
							if(this.hasFile(tmpDir, part)) tmpDir = tmpDir.files[part];
							else throw new Error("FileNotFoundError: Can not find file: '" +
								part +
								"' in directory: '" +
								this.pathTo(tmpDir));
							if(this.isSymlink(tmpDir)) {
								tmpDir = this.getSymlink(tmpDir);
							}
						} else {
							return false;
						}
					}
				});

				return tmpDir;
		};

		Filesystem.prototype.pathTo = function pathTo(file, /* internal */ isNested) {
			if(!isNested && file.name == this.data.root.name) return '/';
			if(!!file === false || (!!file && !!file.name && file.name == fs.root.name)) {
				return "";
			}

			return this.pathTo(file.parent, true) + '/' + file.name;
		};

		Filesystem.prototype.changeDir = function changeDir(dir) {
			if(dir && this.isDir(dir)) this.currentDir = dir;

			return dir;
		}

		Filesystem.prototype.createFile = function createFile(fileName, curDir) {
			var split, dir;

			if(!curDir) curDir = this.currentDir;

			split = fileName.split('/');
			dir = this.getFile(split.slice(0, split.length - 2).join('/'), curDir);

			console.log('dir:', dir);

			if(!this.hasFile(dir, split[split.length - 1])) {
				return dir.files[split[split.length - 1]] = {
					name: split[split.length - 1]
				};
			}
		};

		Filesystem.prototype.getSymlink = function getSymlink(file, curDir) {
			if(this.isSymlink(file)) return this.getFile(file.symlink, curDir);

			return file;
		}

		Filesystem.prototype.writeData = function writeData(file, data) {
			if(file && data) file.contents = data;

			return file;
		};

		Filesystem.prototype.initDir = function initDir(file) {
			if(file && !file.files) file.files = {};

			return file;
		};

		Filesystem.prototype.symlink = function symlink(file, where) {
			file.symlink = where;

			return file;
		};

		Filesystem.prototype.readFile = function readFile(file) {
			if(!file) return undefined;

			file = this.getSymlink(file);

			if(file && this.isFile(file)) return file.contents;
		}

		Filesystem.prototype.listFiles = function listFiles(dir) {
			dir = dir || this.currentDir;

			if(!this.isDir(dir)) return undefined;

			return Object.keys(dir.files).map(function(name) {
				return dir.files[name];
			});
		}

		Filesystem.prototype.hasFile = function hasFile(dir, name) {
			return dir && dir.files && dir.files[name];
		};

		Filesystem.prototype.isDir = function isDir(file) {
			return file && file.files;
		};

		Filesystem.prototype.isFile = function isFile(file) {
			return file && file.contents !== null && file.contents !== undefined;
		};

		Filesystem.prototype.isSymlink = function isSymlink(file) {
			return file && file.symlink;
		}

		return Filesystem;
	})();

	function parentify(data) {
		for(var key in data.files) {
			data.files[key].parent = data;

			if(data.files[key].files) data.files[key] = parentify(data.files[key]);
		}

		return data;
	}

	function nameify(data) {
		for(var key in data.files) {
			data.files[key].name = key;

			if(data.files[key].files) data.files[key] = nameify(data.files[key]);
		}

		return data;
	}
});
<|endoftext|>


<commit_before>/* eslint-env node */
'use strict';

var path = require('path');
var SilentError = require('silent-error');

// allow toggling of heimdall instrumentation
var INSTRUMENT_HEIMDALL = false;
var args = process.argv;

for (var i = 0; i < args.length; i++) {
  if (args[i] === '--instrument') {
    INSTRUMENT_HEIMDALL = true;
    break;
  }
}
process.env.INSTRUMENT_HEIMDALL = INSTRUMENT_HEIMDALL;

function add(options, name, array) {
  var option = options[name] = options[name] || [];
  option.push.apply(option, array);
}

module.exports = {
  name: 'ember-data',

  _warn: function(message) {
    var chalk = require('chalk');
    var warning = chalk.yellow('WARNING: ' + message);

    if (this.ui && this.ui.writeWarnLine) {
      this.ui.writeWarnLine(message);
    } else if (this.ui) {
      this.ui.writeLine(warning);
    } else {
      console.log(warning);
    }
  },

  init: function() {
    this._super.init && this._super.init.apply(this, arguments);

    var bowerDeps = this.project.bowerDependencies();

    var VersionChecker = require('ember-cli-version-checker');
    var options = this.options = this.options || {};

    var checker = new VersionChecker(this);
    // prevent errors when ember-cli-shims is no longer required
    var shims = bowerDeps['ember-cli-shims'] && checker.for('ember-cli-shims', 'bower');

    var semver = require('semver');
    var version = require('./package').version;

    if (process.env.EMBER_DATA_SKIP_VERSION_CHECKING_DO_NOT_USE_THIS_ENV_VARIABLE) {
      // Skip for node tests as we can't currently override the version of ember-cli-shims
      // before the test helpers run.
      return;
    }

    if (bowerDeps['ember-data']) {
      this._warn('Please remove `ember-data` from `bower.json`. As of Ember Data 2.3.0, only the NPM package is needed. If you need an ' +
                'earlier version of ember-data (< 2.3.0), you can leave this unchanged for now, but we strongly suggest you upgrade your version of Ember Data ' +
                'as soon as possible.');
      this._forceBowerUsage = true;

      var emberDataBower = checker.for('ember-data', 'bower');

      if (shims && shims.version && !shims.satisfies('< 0.1.0') && emberDataBower.satisfies('< 2.3.0-beta.3')) {
        throw new SilentError('Using a version of ember-cli-shims greater than or equal to 0.1.0 will cause errors while loading Ember Data < 2.3.0-beta.3 Please update ember-cli-shims from ' + shims.version + ' to 0.0.6');
      }

      if (shims && shims.version && !shims.satisfies('>= 0.1.0') && emberDataBower.satisfies('>= 2.3.0-beta.3')) {
        throw new SilentError('Using a version of ember-cli-shims prior to 0.1.0 will cause errors while loading Ember Data 2.3.0-beta.3+. Please update ember-cli-shims from ' + shims.version + ' to 0.1.0.');
      }

    } else {
      // NPM only, but ember-cli-shims does not match
      if (shims && shims.version && !shims.satisfies('>= 0.1.0') && semver.satisfies(version, '^2.3.0-beta.3')) {
        throw new SilentError('Using a version of ember-cli-shims prior to 0.1.0 will cause errors while loading Ember Data 2.3.0-beta.3+. Please update ember-cli-shims from ' + shims.version + ' to 0.1.0.');
      }
    }
  },

  blueprintsPath: function() {
    return path.join(__dirname, 'blueprints');
  },

  treeForApp: function(dir) {
    if (this._forceBowerUsage) {
      // Fake an empty broccoli tree
      return { inputTree: dir, rebuild: function() { return []; } };
    }

    // this._super.treeForApp is undefined in ember-cli (1.13) for some reason.
    // TODO: investigate why treeForApp isn't on _super
    return dir;
  },

  treeForAddon: function(dir) {
    if (this._forceBowerUsage) {
      // Fakes an empty broccoli tree
      return { inputTree: dir, rebuild: function() { return []; } };
    }

    var version   = require('./lib/version');
    var merge     = require('broccoli-merge-trees');

    return this._super.treeForAddon.call(this, merge([
      version(),
      dir
    ]));
  },

  _setupBabelOptions: function() {
    if (this._hasSetupBabelOptions) {
      return;
    }

    this.options.babel = this.options.babel || {};
    add(this.options.babel, 'blacklist', ['es6.modules', 'useStrict']);
    add(this.options.babel, 'plugins', require('./lib/stripped-build-plugins')(process.env.EMBER_ENV));

    this._hasSetupBabelOptions = true;
  },

  included: function(app) {
    this._super.included.apply(this, arguments);

    this._setupBabelOptions();

    if (this._forceBowerUsage) {
      this.app.import({
        development: app.bowerDirectory + '/ember-data/ember-data.js',
        production: app.bowerDirectory + '/ember-data/ember-data.prod.js'
      });
    }
  }
};
<commit_msg>Refactor the detection / warnings around ember-cli-shims. (#4860)<commit_after>/* eslint-env node */
'use strict';

var path = require('path');
var SilentError = require('silent-error');

// allow toggling of heimdall instrumentation
var INSTRUMENT_HEIMDALL = false;
var args = process.argv;

for (var i = 0; i < args.length; i++) {
  if (args[i] === '--instrument') {
    INSTRUMENT_HEIMDALL = true;
    break;
  }
}
process.env.INSTRUMENT_HEIMDALL = INSTRUMENT_HEIMDALL;

function add(options, name, array) {
  var option = options[name] = options[name] || [];
  option.push.apply(option, array);
}

module.exports = {
  name: 'ember-data',

  _warn: function(message) {
    var chalk = require('chalk');
    var warning = chalk.yellow('WARNING: ' + message);

    if (this.ui && this.ui.writeWarnLine) {
      this.ui.writeWarnLine(message);
    } else if (this.ui) {
      this.ui.writeLine(warning);
    } else {
      console.log(warning);
    }
  },

  init: function() {
    this._super.init && this._super.init.apply(this, arguments);

    var bowerDeps = this.project.bowerDependencies();

    var VersionChecker = require('ember-cli-version-checker');
    var options = this.options = this.options || {};

    var checker = new VersionChecker(this);
    // prevent errors when ember-cli-shims is no longer required
    var shims = bowerDeps['ember-cli-shims'] && checker.for('ember-cli-shims', 'bower');

    var semver = require('semver');
    var version = require('./package').version;

    if (process.env.EMBER_DATA_SKIP_VERSION_CHECKING_DO_NOT_USE_THIS_ENV_VARIABLE) {
      // Skip for node tests as we can't currently override the version of ember-cli-shims
      // before the test helpers run.
      return;
    }

    var hasShims = !!shims;
    var shimsHasEmberDataShims = hasShims && shims.satisfies('< 0.1.0');
    var emberDataNPMWithShimsIncluded = semver.satisfies(version, '^2.3.0-beta.3');

    if (bowerDeps['ember-data']) {
      this._warn('Please remove `ember-data` from `bower.json`. As of Ember Data 2.3.0, only the NPM package is needed. If you need an ' +
                'earlier version of ember-data (< 2.3.0), you can leave this unchanged for now, but we strongly suggest you upgrade your version of Ember Data ' +
                'as soon as possible.');
      this._forceBowerUsage = true;

      var emberDataBower = checker.for('ember-data', 'bower');
      var emberDataBowerWithShimsIncluded = emberDataBower.satisifies('>= 2.3.0-beta.3');

      if (hasShims && !shimsHasEmberDataShims && !emberDataBowerWithShimsIncluded) {
        throw new SilentError('Using a version of ember-cli-shims greater than or equal to 0.1.0 will cause errors while loading Ember Data < 2.3.0-beta.3 Please update ember-cli-shims from ' + shims.version + ' to 0.0.6');
      }

      if (hasShims && shimsHasEmberDataShims && !emberDataBowerWithShimsIncluded) {
        throw new SilentError('Using a version of ember-cli-shims prior to 0.1.0 will cause errors while loading Ember Data 2.3.0-beta.3+. Please update ember-cli-shims from ' + shims.version + ' to 0.1.0.');
      }

    } else {
      // NPM only, but ember-cli-shims does not match
      if (hasShims && shimsHasEmberDataShims && emberDataNPMWithShimsIncluded) {
        throw new SilentError('Using a version of ember-cli-shims prior to 0.1.0 will cause errors while loading Ember Data 2.3.0-beta.3+. Please update ember-cli-shims from ' + shims.version + ' to 0.1.0.');
      }
    }
  },

  blueprintsPath: function() {
    return path.join(__dirname, 'blueprints');
  },

  treeForApp: function(dir) {
    if (this._forceBowerUsage) {
      // Fake an empty broccoli tree
      return { inputTree: dir, rebuild: function() { return []; } };
    }

    // this._super.treeForApp is undefined in ember-cli (1.13) for some reason.
    // TODO: investigate why treeForApp isn't on _super
    return dir;
  },

  treeForAddon: function(dir) {
    if (this._forceBowerUsage) {
      // Fakes an empty broccoli tree
      return { inputTree: dir, rebuild: function() { return []; } };
    }

    var version   = require('./lib/version');
    var merge     = require('broccoli-merge-trees');

    return this._super.treeForAddon.call(this, merge([
      version(),
      dir
    ]));
  },

  _setupBabelOptions: function() {
    if (this._hasSetupBabelOptions) {
      return;
    }

    this.options.babel = this.options.babel || {};
    add(this.options.babel, 'blacklist', ['es6.modules', 'useStrict']);
    add(this.options.babel, 'plugins', require('./lib/stripped-build-plugins')(process.env.EMBER_ENV));

    this._hasSetupBabelOptions = true;
  },

  included: function(app) {
    this._super.included.apply(this, arguments);

    this._setupBabelOptions();

    if (this._forceBowerUsage) {
      this.app.import({
        development: app.bowerDirectory + '/ember-data/ember-data.js',
        production: app.bowerDirectory + '/ember-data/ember-data.prod.js'
      });
    }
  }
};
<|endoftext|>


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

const anybar = require('anybar');
const captureExit = require('capture-exit');
const exec = require('child_process').exec;

captureExit.captureExit();

// Open AnyBar (OSX only)
exec('open --hide --background -a AnyBar', (error, stdout, stderror) => {
  if (error) console.error('exec error: ${error}');
});

// Pulse
let color = 'black';

let pulser;
function pulse() {
  clearInterval(pulser);
  pulser = setInterval(() => {
    anybar(color);
    color = color === 'black' ? 'white' : 'black';
  }, 200);
};

// Back to white on exit
captureExit.onExit(function() {
  clearInterval(pulser);
  return anybar('white');
});

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

  preBuild() {
    pulse();
  },

  buildError: function() {
    clearInterval(pulser);
    anybar('red');
  },

  postBuild: function() {
    clearInterval(pulser);
    anybar('green');
  },

};
<commit_msg>Use a template literal to expand error messages<commit_after>/* jshint node: true */
'use strict';

const anybar = require('anybar');
const captureExit = require('capture-exit');
const exec = require('child_process').exec;

captureExit.captureExit();

// Open AnyBar (OSX only)
exec('open --hide --background -a AnyBar', (error, stdout, stderror) => {
  if (error) console.error(`exec error: ${error}`);
});

// Pulse
let color = 'black';

let pulser;
function pulse() {
  clearInterval(pulser);
  pulser = setInterval(() => {
    anybar(color);
    color = color === 'black' ? 'white' : 'black';
  }, 200);
};

// Back to white on exit
captureExit.onExit(function() {
  clearInterval(pulser);
  return anybar('white');
});

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

  preBuild() {
    pulse();
  },

  buildError: function() {
    clearInterval(pulser);
    anybar('red');
  },

  postBuild: function() {
    clearInterval(pulser);
    anybar('green');
  },

};
<|endoftext|>


<commit_before>'use strict';

const isFirefoxAndroid = require('is-firefox-android')();
const handleClick = require('./lib/handle-click');
const { PageMod } = require('sdk/page-mod');
const tabs = require('sdk/tabs');
const { data } = require('sdk/self');
const getWindow = require('get-firefox-browser-window');
const { EventTarget } = require('sdk/event/target');
const { Request } = require('sdk/request');
const { emit } = require('sdk/event/core');
const simpleStorage = require('sdk/simple-storage');
const isNumber = require('lodash.isnumber');
const buildHatenaBookmarkJsonLiteUrl = require('./lib/build-hatena-bookmark-json-lite-url');
const target = EventTarget();// eslint-disable-line new-cap
let button;
let menuId;
let page;
let currentUrl;

/**
  * bookmarks
  * { url -> { updatedAt: time, count: number }}
  */
if (!simpleStorage.storage.bookmarks) {
  simpleStorage.storage.bookmarks = {};
}

target.on('updateBadge', (url, piece) => {
  if (url !== currentUrl) { return; }
  if (isFirefoxAndroid) {
    getWindow().NativeWindow.menu.update(
      menuId,
      {
        name: `Page for Hatebu (${piece})`,
      });
  } else {
    button.badge = piece;
  }
});

function cachedCount(bookmarks, url) {
  if (!bookmarks ||
      !url ||
      !bookmarks[url] ||
      !bookmarks[url].updatedAt ||
      bookmarks[url].updatedAt + 10 * 60 * 1000 < Date.now ||
      !isNumber(bookmarks[url].count)
  ) {
    return null;
  }
  return bookmarks[url].count;
}

target.on('pingUrl', (url) => {
  if (!url) { return; }
  if (!(/^http/.test(url))) {
    emit(target, 'updateBadge', url, '-');
    return;
  }
  const cached = cachedCount(simpleStorage.storage.bookmarks, url);
  if (isNumber(cached)) {
    emit(target, 'updateBadge', url, cached);
  } else {
    emit(target, 'updateBadge', url, '-');
    Request({// eslint-disable-line new-cap
      url: buildHatenaBookmarkJsonLiteUrl(url),
      onComplete: (response) => {
        if (response.status !== 200 || !response.json) { return; }
        const count = Number(response.json.count);
        simpleStorage.storage.bookmarks[url] = {
          count,
          updatedAt: Date.now(),
        };
        emit(target, 'updateBadge', url, count);
      },
    }).get();
  }
});

if (isFirefoxAndroid) {
  menuId = 0;
  exports.main = (options, callback) => {// eslint-disable-line no-unused-vars
    menuId = getWindow().NativeWindow.menu.add({
      name: 'Page for Hatebu (-)',
      callback: handleClick,
    });
  };
  exports.onUnload = (reason) => {// eslint-disable-line no-unused-vars
    getWindow().NativeWindow.menu.remove(menuId);
  };
} else {
  const { ActionButton } = require('sdk/ui/button/action');
  button = ActionButton({// eslint-disable-line new-cap
    id: 'page-for-hatena-bookmark',
    label: 'Page for Hatebu',
    icon: {
      16: './bookmark42-16.png',
      32: './bookmark42-32.png',
      64: './bookmark42-64.png',
    },
    onClick: handleClick,
    badge: '-',
    badgeColor: '#696969',
  });
}

page = PageMod({// eslint-disable-line new-cap
  include: '*',
  contentScriptFile: [
    data.url('../node_modules/browser-canonical-url/build/browser-canonical-url.js'),
    data.url('content-script.js'),
  ],
  attachTo: ['existing', 'top'],
});

page.on('attach', (worker) => {
  worker.port.on('canonicalUrl', (request) => {
    currentUrl = request;
    emit(target, 'pingUrl', request);
  });
  worker.port.emit('getCanonicalUrl');
});

tabs.on('activate', (tab) => {
  const worker = tab.attach({
    contentScriptFile: [
      data.url('../node_modules/browser-canonical-url/build/browser-canonical-url.js'),
      data.url('content-script.js'),
    ],
  });
  worker.port.on('canonicalUrl', (request) => {
    currentUrl = request;
    emit(target, 'pingUrl', request);
  });
  worker.port.emit('getCanonicalUrl');
});
<commit_msg>fix(badge): too many bookmarks<commit_after>'use strict';

const isFirefoxAndroid = require('is-firefox-android')();
const handleClick = require('./lib/handle-click');
const { PageMod } = require('sdk/page-mod');
const tabs = require('sdk/tabs');
const { data } = require('sdk/self');
const getWindow = require('get-firefox-browser-window');
const { EventTarget } = require('sdk/event/target');
const { Request } = require('sdk/request');
const { emit } = require('sdk/event/core');
const simpleStorage = require('sdk/simple-storage');
const isNumber = require('lodash.isnumber');
const buildHatenaBookmarkJsonLiteUrl = require('./lib/build-hatena-bookmark-json-lite-url');
const target = EventTarget();// eslint-disable-line new-cap
let button;
let menuId;
let page;
let currentUrl;

/**
  * bookmarks
  * { url -> { updatedAt: time, count: number }}
  */
if (!simpleStorage.storage.bookmarks) {
  simpleStorage.storage.bookmarks = {};
}

target.on('updateBadge', (url, piece) => {
  if (url !== currentUrl) { return; }
  if (isFirefoxAndroid) {
    getWindow().NativeWindow.menu.update(
      menuId,
      {
        name: `Page for Hatebu (${piece})`,
      });
  } else {
    if (isNumber(piece) && piece > 9999) {
      button.badge = 9999;
    } else {
      button.badge = piece;
    }
  }
});

function cachedCount(bookmarks, url) {
  if (!bookmarks ||
      !url ||
      !bookmarks[url] ||
      !bookmarks[url].updatedAt ||
      bookmarks[url].updatedAt + 10 * 60 * 1000 < Date.now ||
      !isNumber(bookmarks[url].count)
  ) {
    return null;
  }
  return bookmarks[url].count;
}

target.on('pingUrl', (url) => {
  if (!url) { return; }
  if (!(/^http/.test(url))) {
    emit(target, 'updateBadge', url, '-');
    return;
  }
  const cached = cachedCount(simpleStorage.storage.bookmarks, url);
  if (isNumber(cached)) {
    emit(target, 'updateBadge', url, cached);
  } else {
    emit(target, 'updateBadge', url, '-');
    Request({// eslint-disable-line new-cap
      url: buildHatenaBookmarkJsonLiteUrl(url),
      onComplete: (response) => {
        if (response.status !== 200 || !response.json) { return; }
        const count = Number(response.json.count);
        simpleStorage.storage.bookmarks[url] = {
          count,
          updatedAt: Date.now(),
        };
        emit(target, 'updateBadge', url, count);
      },
    }).get();
  }
});

if (isFirefoxAndroid) {
  menuId = 0;
  exports.main = (options, callback) => {// eslint-disable-line no-unused-vars
    menuId = getWindow().NativeWindow.menu.add({
      name: 'Page for Hatebu (-)',
      callback: handleClick,
    });
  };
  exports.onUnload = (reason) => {// eslint-disable-line no-unused-vars
    getWindow().NativeWindow.menu.remove(menuId);
  };
} else {
  const { ActionButton } = require('sdk/ui/button/action');
  button = ActionButton({// eslint-disable-line new-cap
    id: 'page-for-hatena-bookmark',
    label: 'Page for Hatebu',
    icon: {
      16: './bookmark42-16.png',
      32: './bookmark42-32.png',
      64: './bookmark42-64.png',
    },
    onClick: handleClick,
    badge: '-',
    badgeColor: '#696969',
  });
}

page = PageMod({// eslint-disable-line new-cap
  include: '*',
  contentScriptFile: [
    data.url('../node_modules/browser-canonical-url/build/browser-canonical-url.js'),
    data.url('content-script.js'),
  ],
  attachTo: ['existing', 'top'],
});

page.on('attach', (worker) => {
  worker.port.on('canonicalUrl', (request) => {
    currentUrl = request;
    emit(target, 'pingUrl', request);
  });
  worker.port.emit('getCanonicalUrl');
});

tabs.on('activate', (tab) => {
  const worker = tab.attach({
    contentScriptFile: [
      data.url('../node_modules/browser-canonical-url/build/browser-canonical-url.js'),
      data.url('content-script.js'),
    ],
  });
  worker.port.on('canonicalUrl', (request) => {
    currentUrl = request;
    emit(target, 'pingUrl', request);
  });
  worker.port.emit('getCanonicalUrl');
});
<|endoftext|>


<commit_before>/**
 * Configure the persistence options
 */

var config = {};
if (process.env.MONGOLAB_URI) {
    var BotkitStorage = require('botkit-storage-mongo');
    config = {
        storage: BotkitStorage({mongoUri: process.env.MONGOLAB_URI}),
    };
} else {
    config = {
        json_file_store: ((process.env.TOKEN)?'./db_slack_bot_ci/':'./db_slack_bot_a/'), //use a different name if an app or CI
    };
}

/**
 * Are being run as an app or a custom integration? The initialization will differ, depending
 */

if (process.env.TOKEN || process.env.SLACK_TOKEN) {
    //Treat this as a custom integration
    var customIntegration = require('./lib/custom_integrations');
    var token = (process.env.TOKEN) ? process.env.TOKEN : process.env.SLACK_TOKEN;
    var controller = customIntegration.configure(token, config, onInstallation);
} else if (process.env.CLIENT_ID && process.env.CLIENT_SECRET && process.env.PORT) {
    //Treat this as an app
    var app = require('./lib/apps');
    var controller = app.configure(process.env.PORT, process.env.CLIENT_ID, process.env.CLIENT_SECRET, config, onInstallation);
} else {
    console.log('Error: If this is a custom integration, please specify TOKEN in the environment. If this is an app, please specify CLIENTID, CLIENTSECRET, and PORT in the environment');
    process.exit(1);
}

/**
 * A demonstration for how to handle websocket events. In this case, just log when we have and have not
 * been disconnected from the websocket. In the future, it would be super awesome to be able to specify
 * a reconnect policy, and do reconnections automatically. In the meantime, we aren't going to attempt reconnects,
 * WHICH IS A B0RKED WAY TO HANDLE BEING DISCONNECTED. So we need to fix this.
 *
 * TODO: fixed b0rked reconnect behavior
 */
// Handle events related to the websocket connection to Slack
controller.on('rtm_open', function (bot) {
    console.log('** The RTM api just connected!');
});

controller.on('rtm_close', function (bot) {
    console.log('** The RTM api just closed');
    // you may want to attempt to re-open
});

/**
 * Core bot logic goes here!
 */
// BEGIN EDITING HERE!
var runHappening = false;
var runList = [];

controller.on('bot_channel_join', function (bot, message) {
    bot.reply(message, "I'm here!")
});

controller.hears('hello', 'direct_message', function (bot, message) {
    bot.reply(message, 'Hello!');
});

controller.hears('start', 'direct_mention', function(bot, message) {

    if (runHappening) {
        return bot.reply(message, 'Already gathering requests for a run in' + runChannel);
    }

    bot.reply(message, 'Holy La Croix! <@' + message.user_name + '> is going for a Pop-a-Top run. Who <@here> has a request? Tell me what you want and I will let them know!');
    runHappening = true;
    console.log('===runHappening = ' + runHappening);

    /*//notify first user and start a conversation
    userIterator = usersModel.iterator();
    currentUser = userIterator.next();
    promptUser(bot);*/

});

controller.hears('end', 'direct_mention', function(bot, message) {
    if (!runHappening) {
        return bot.reply(message, 'Nobody is on a run right now. Start a new run with `start`');
    }

    runHappening = false;
    console.log('===runHappening = ' + runHappening);

    console.log('===runList = ' + runList);

    bot.reply(message, 'The run is now over!');

    bot.startConversation(message, function(err,convo){
        convo.ask('<@' + message.user_name + '> want to see the list?', [{
            pattern: bot.utterances.yes,
            callback: function(response, convo) {
                console.log('====runList = ' + runList);

                for (var i = 0; i < runList.length; i++) {
                  listString = (message.user_name + ': ' + runList[i].requests.join(', '));
                    bot.reply(message, (listString));
                }

                console.log('===Heard yes, output runList object');
                console.log('===Output listString= ' + listString);
                convo.next();
            }
        }, {
            pattern: bot.utterances.no,
            callback: function(response,convo) {
                bot.say({channel: message.channel, text: 'Okey Dokey. That was fun, see you later!'});
                // runModel.clearStatuses();
                console.log('Heard no')
                convo.next();
            }
        }]);
    });
});

/*runList = [
  {user_name: 'Em', requests: ['pamp mouse']}
]
*/
controller.hears('(.*)', 'direct_mention, direct_message', function(bot, message) {
    if (runHappening) {
        gatherRequest(bot, message);
    }
});

function gatherRequest(bot, message) {
    console.log('===request = ' + message);
    bot.reply(message, 'Got it! Thanks ' + message.user_name);
    addDesire(message);
    function addDesire(message){
      for (var i = 0; i < runList.length; i++) {
      if (runList[i].user_name === message.user_name) {
        runList[i].requests.push(message.text);
      }
      else {
        runList.push({user_name: message.user_name, requests: [message.text]});
      }
    }};

    console.log('===Pushing request to runList');

   /* runModel.addRequest({
        request: message.text,
        user: message.user
    });
    */

}
<commit_msg>weeded out unused var passed as param<commit_after>/**
 * Configure the persistence options
 */

var config = {};
if (process.env.MONGOLAB_URI) {
    var BotkitStorage = require('botkit-storage-mongo');
    config = {
        storage: BotkitStorage({mongoUri: process.env.MONGOLAB_URI}),
    };
} else {
    config = {
        json_file_store: ((process.env.TOKEN)?'./db_slack_bot_ci/':'./db_slack_bot_a/'), //use a different name if an app or CI
    };
}

/**
 * Are being run as an app or a custom integration? The initialization will differ, depending
 */

if (process.env.TOKEN || process.env.SLACK_TOKEN) {
    //Treat this as a custom integration
    var customIntegration = require('./lib/custom_integrations');
    var token = (process.env.TOKEN) ? process.env.TOKEN : process.env.SLACK_TOKEN;
    var controller = customIntegration.configure(token, config);
} else if (process.env.CLIENT_ID && process.env.CLIENT_SECRET && process.env.PORT) {
    //Treat this as an app
    var app = require('./lib/apps');
    var controller = app.configure(process.env.PORT, process.env.CLIENT_ID, process.env.CLIENT_SECRET, config, onInstallation);
} else {
    console.log('Error: If this is a custom integration, please specify TOKEN in the environment. If this is an app, please specify CLIENTID, CLIENTSECRET, and PORT in the environment');
    process.exit(1);
}

/**
 * A demonstration for how to handle websocket events. In this case, just log when we have and have not
 * been disconnected from the websocket. In the future, it would be super awesome to be able to specify
 * a reconnect policy, and do reconnections automatically. In the meantime, we aren't going to attempt reconnects,
 * WHICH IS A B0RKED WAY TO HANDLE BEING DISCONNECTED. So we need to fix this.
 *
 * TODO: fixed b0rked reconnect behavior
 */
// Handle events related to the websocket connection to Slack
controller.on('rtm_open', function (bot) {
    console.log('** The RTM api just connected!');
});

controller.on('rtm_close', function (bot) {
    console.log('** The RTM api just closed');
    // you may want to attempt to re-open
});

/**
 * Core bot logic goes here!
 */
// BEGIN EDITING HERE!
var runHappening = false;
var runList = [];

controller.on('bot_channel_join', function (bot, message) {
    bot.reply(message, "I'm here!")
});

controller.hears('hello', 'direct_message', function (bot, message) {
    bot.reply(message, 'Hello!');
});

controller.hears('start', 'direct_mention', function(bot, message) {

    if (runHappening) {
        return bot.reply(message, 'Already gathering requests for a run in' + runChannel);
    }

    bot.reply(message, 'Holy La Croix! <@' + message.user_name + '> is going for a Pop-a-Top run. Who <@here> has a request? Tell me what you want and I will let them know!');
    runHappening = true;
    console.log('===runHappening = ' + runHappening);

    /*//notify first user and start a conversation
    userIterator = usersModel.iterator();
    currentUser = userIterator.next();
    promptUser(bot);*/

});

controller.hears('end', 'direct_mention', function(bot, message) {
    if (!runHappening) {
        return bot.reply(message, 'Nobody is on a run right now. Start a new run with `start`');
    }

    runHappening = false;
    console.log('===runHappening = ' + runHappening);

    console.log('===runList = ' + runList);

    bot.reply(message, 'The run is now over!');

    bot.startConversation(message, function(err,convo){
        convo.ask('<@' + message.user_name + '> want to see the list?', [{
            pattern: bot.utterances.yes,
            callback: function(response, convo) {
                console.log('====runList = ' + runList);

                for (var i = 0; i < runList.length; i++) {
                  listString = (message.user_name + ': ' + runList[i].requests.join(', '));
                    bot.reply(message, (listString));
                }

                console.log('===Heard yes, output runList object');
                console.log('===Output listString= ' + listString);
                convo.next();
            }
        }, {
            pattern: bot.utterances.no,
            callback: function(response,convo) {
                bot.say({channel: message.channel, text: 'Okey Dokey. That was fun, see you later!'});
                // runModel.clearStatuses();
                console.log('Heard no')
                convo.next();
            }
        }]);
    });
});

/*runList = [
  {user_name: 'Em', requests: ['pamp mouse']}
]
*/
controller.hears('(.*)', 'direct_mention, direct_message', function(bot, message) {
    if (runHappening) {
        gatherRequest(bot, message);
    }
});

function gatherRequest(bot, message) {
    console.log('===request = ' + message);
    bot.reply(message, 'Got it! Thanks ' + message.user_name);
    addDesire(message);
    function addDesire(message){
      for (var i = 0; i < runList.length; i++) {
      if (runList[i].user_name === message.user_name) {
        runList[i].requests.push(message.text);
      }
      else {
        runList.push({user_name: message.user_name, requests: [message.text]});
      }
    }};

    console.log('===Pushing request to runList');

   /* runModel.addRequest({
        request: message.text,
        user: message.user
    });
    */

}
<|endoftext|>


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

'use strict';

var path = require('path');
var gm = require('global-modules');
var tilde = require('expand-tilde');

/**
 * Calculate destination paths.
 *
 * @param {String|Array} `src`
 * @param {String} `dest`
 * @param {Object} `options`
 * @return {Object}
 */

function mapDest(src, dest, opts) {
  if (Array.isArray(src)) {
    return fromArray(src, dest, opts);
  }
  return [fromString(src, dest, opts)];
}

/**
 * Default rename function.
 */

function renameFn(dest, src, opts) {
  opts = opts || {};

  // if `opts.ext` is defined, use it to replace extension
  if (opts.hasOwnProperty('ext')) {
    if (opts.ext === false) {
      opts.ext = '';
    }

    if (opts.ext.charAt(0) !== '.') {
      opts.ext = '.' + opts.ext;
    }

    src = replaceExt(src, opts);
    if (src.slice(-1) === '.') {
      src = src.slice(0, -1);
    }
  }

  // if `opts.flatten` is defined, use the `src` basename
  if (opts.flatten) {
    src = path.basename(src);
  }

  if (typeof opts.rename === 'function') {
    return opts.rename(dest, src, opts);
  }

  if (opts.destBase) {
    opts.destBase = resolveDir(opts.destBase);
    dest = path.join(opts.destBase, dest || '');
  }

  var fp = typeof src === 'string' ? src : '';
  return dest ? path.join(dest, fp) : fp;
}

function fromArray(src, dest, opts) {
  return src.map(function (fp) {
    return fromString(fp, dest, opts);
  });
}

function fromString(src, dest, opts) {
  if (typeof src !== 'string') {
    throw new TypeError('expected a string');
  }

  if (typeof dest === 'object') {
    opts = dest;
    dest = null;
  }

  opts = opts || {};

  // use rename function to modify dest path
  dest = renameFn(dest, src, opts);
  opts.cwd = opts.cwd || '';
  opts.cwd = resolveDir(opts.cwd);

  if (opts.srcBase) {
    opts.cwd = path.join(opts.cwd, opts.srcBase);
  }
  if (opts.cwd) {
    src = path.join(opts.cwd, src);
  }

  return {
    options: opts,
    src: unixify(src),
    dest: unixify(dest)
  };
}

function replaceExt(fp, opts) {
  var re = {first: /(\.[^\/]*)?$/, last: /(\.[^\/\.]*)?$/};
  if (typeof opts.extDot === 'undefined') {
    opts.extDot = 'first';
  }
  return fp.replace(re[opts.extDot], opts.ext);
}

function resolveDir(dir) {
  if (dir.charAt(0) === '~') {
    dir = tilde(dir);
  }
  if (dir.charAt(0) === '@') {
    dir = path.join(gm, dir.slice(1));
  }
  return dir;
}

function unixify(fp) {
  return fp.split('\\').join('/');
}

/**
 * Expose `mapDest`
 */

module.exports = mapDest;

/**
 * Expose `renameFn`
 */

module.exports.rename = renameFn;
<commit_msg>make sure dest is not undefined<commit_after>/*!
 * map-dest <https://github.com/jonschlinkert/map-dest>
 *
 * Copyright (c) 2015, Jon Schlinkert.
 * Licensed under the MIT License.
 */

'use strict';

var path = require('path');
var gm = require('global-modules');
var tilde = require('expand-tilde');

/**
 * Calculate destination paths.
 *
 * @param {String|Array} `src`
 * @param {String} `dest`
 * @param {Object} `options`
 * @return {Object}
 */

function mapDest(src, dest, opts) {
  if (Array.isArray(src)) {
    return fromArray(src, dest, opts);
  }
  return [fromString(src, dest, opts)];
}

/**
 * Default rename function.
 */

function renameFn(dest, src, opts) {
  dest = dest || '';
  opts = opts || {};

  // if `opts.ext` is defined, use it to replace extension
  if (opts.hasOwnProperty('ext')) {
    if (opts.ext === false) {
      opts.ext = '';
    }

    if (opts.ext.charAt(0) !== '.') {
      opts.ext = '.' + opts.ext;
    }

    src = replaceExt(src, opts);
    if (src.slice(-1) === '.') {
      src = src.slice(0, -1);
    }
  }

  // if `opts.flatten` is defined, use the `src` basename
  if (opts.flatten) {
    src = path.basename(src);
  }

  if (typeof opts.rename === 'function') {
    return opts.rename(dest, src, opts);
  }

  if (opts.destBase) {
    opts.destBase = resolveDir(opts.destBase);
    dest = path.join(opts.destBase, dest || '');
  }

  var fp = typeof src === 'string' ? src : '';
  return dest ? path.join(dest, fp) : fp;
}

function fromArray(src, dest, opts) {
  return src.map(function (fp) {
    return fromString(fp, dest, opts);
  });
}

function fromString(src, dest, opts) {
  if (typeof src !== 'string') {
    throw new TypeError('expected a string');
  }

  if (typeof dest === 'object') {
    opts = dest;
    dest = null;
  }

  opts = opts || {};

  // use rename function to modify dest path
  dest = renameFn(dest, src, opts);
  opts.cwd = opts.cwd || '';
  opts.cwd = resolveDir(opts.cwd);

  if (opts.srcBase) {
    opts.cwd = path.join(opts.cwd, opts.srcBase);
  }
  if (opts.cwd) {
    src = path.join(opts.cwd, src);
  }

  return {
    options: opts,
    src: unixify(src),
    dest: unixify(dest)
  };
}

function replaceExt(fp, opts) {
  var re = {first: /(\.[^\/]*)?$/, last: /(\.[^\/\.]*)?$/};
  if (typeof opts.extDot === 'undefined') {
    opts.extDot = 'first';
  }
  return fp.replace(re[opts.extDot], opts.ext);
}

function resolveDir(dir) {
  if (dir.charAt(0) === '~') {
    dir = tilde(dir);
  }
  if (dir.charAt(0) === '@') {
    dir = path.join(gm, dir.slice(1));
  }
  return dir;
}

function unixify(fp) {
  return fp.split('\\').join('/');
}

/**
 * Expose `mapDest`
 */

module.exports = mapDest;

/**
 * Expose `renameFn`
 */

module.exports.rename = renameFn;
<|endoftext|>


<commit_before>'use strict';

module.exports.registerTasks = require('./lib/tasks/index');
<commit_msg>Exposes normalizeOptions on gulp-metal entry file - Fixes #21<commit_after>'use strict';

module.exports.registerTasks = require('./lib/tasks/index');
module.exports.normalizeOptions = require('./lib/options');
<|endoftext|>