<commit_before>'use strict';
var util = require('util');

var oneDay = 86400000;

module.exports = function(connect) {

/**
* Connect's Store.
*/
var Store = (connect.session) ? connect.session.Store : connect.Store;

/*
 * Return an ISO compliant string of the current time
 * @api private
 * @return {String} an ISO compliant string of the current time
 */
function nowAsISO() {
	return (new Date()).toISOString();
}

/*
 * Return dialect-aware type name for timestamp
 * @return {String} type name for timestamp
 * @api private
 */
function timestampTypeName(knex) {
	return (['mysql', 'mariasql'].indexOf(knex.client.dialect) > -1) ? 'DATETIME' : 'timestamp';
}

/*
* Remove expired sessions from database.
* @param {Object} store
* @api private
*/
function dbCleanup(store) {
	return store.ready.then(function () {
		return store.knex(store.tablename).del()
		.whereRaw('expired < CAST(? as ' + timestampTypeName(store.knex) + ')', nowAsISO());
	});
}

/*
* Initialize KnexStore with the given options.
*
* @param {Object} options
* @api public
*/
function KnexStore(options) {
	var self = this;

	options = options || {};
	Store.call(self, options);

	self.tablename = options.tablename || 'sessions';
	self.knex = options.knex || require('knex')({
		client: 'sqlite3',
		// debug: true,
		connection: {
			filename: "connect-session-knex.sqlite"
		}
	});

	self.ready = self.knex.schema.hasTable(self.tablename)
	.then(function (exists) {
		if (!exists) {
			return self.knex.schema.createTable(self.tablename, function (table) {
				table.string('sid').primary();
				table.json('sess').notNullable();
				if (['mysql', 'mariasql'].indexOf(self.knex.client.dialect) > -1) {
					table.dateTime('expired').notNullable();
				} else {
					table.timestamp('expired', 'true').notNullable();
				}
			});
		}
	})
	.then(function () {
		dbCleanup(self);
		setInterval(dbCleanup, oneDay, self).unref();
	});
}

// KnexStore.prototype.__proto__ = Store.prototype;
util.inherits(KnexStore, Store);

/*
* Attempt to fetch session by the given sid.
*
* @param {String} sid
* @param {Function} fn
* @api public
*/
KnexStore.prototype.get = function(sid, fn) {
	var self = this;
	return self.ready.then(function () {
		return self.knex
			.select('sess')
			.from(self.tablename)
			.where('sid', '=', sid)
			.andWhereRaw('CAST(? as '+timestampTypeName(self.knex)+') <= expired', nowAsISO())
			.then(function (response) {
				var ret;
				if (response[0]) {
					ret = response[0].sess;
					if (typeof ret === "string") {
						ret = JSON.parse(ret);
					}
				}

				if (fn) fn(null, ret);
				return ret;
			}).catch(function(err) {
				if (fn) fn(err);
				throw err;
			});
	});
};

/*
* Commit the given `sess` object associated with the given `sid`.
*
* @param {String} sid
* @param {Session} sess
* @param {Function} fn
* @api public
*/
KnexStore.prototype.set = function(sid, sess, fn) {
	var self = this;
	var maxAge = sess.cookie.maxAge;
	var now = new Date().getTime();
	var expired = maxAge ? now + maxAge : now + oneDay;
	sess = JSON.stringify(sess);
	var postgresfastq = 'with new_values (sid, expired, sess) as (' +
					'  values (?, ?::timestamp without time zone, ?::json)' +
					'), ' +
					'upsert as ' +
					'( ' +
					'  update ' + self.tablename + ' cs set ' +
					'    sid = nv.sid, ' +
					'    expired = nv.expired, ' +
					'    sess = nv.sess ' +
					'  from new_values nv ' +
					'  where cs.sid = nv.sid ' +
					'  returning cs.* ' +
					')' +
					'insert into ' + self.tablename + ' (sid, expired, sess) ' +
					'select sid, expired, sess ' +
					'from new_values ' +
					'where not exists (select 1 from upsert up where up.sid = new_values.sid)';

	var sqlitefastq = 'insert or replace into ' + self.tablename + ' (sid, expired, sess) values (?, ?, ?);';

	var mysqlfastq = 'insert into ' + self.tablename + ' (sid, expired, sess) values (?, ?, ?) on duplicate key update expired=values(expired), sess=values(sess);';

	if (self.knex.client.dialect === 'sqlite3') {
		// sqlite optimized query
		return self.ready.then(function () {
			return self.knex.raw(sqlitefastq, [sid, new Date(expired).toISOString(), sess ])
			.then(function (result) {
				if (fn && result instanceof Array) {
					fn(null, [1]);
				}
				if (result instanceof Array) {
					return [1];
				}
			})
			.catch(function (err) {
				fn(err);
				throw err;
			});
		});
	} else if (self.knex.client.dialect === 'postgresql') {
		// postgresql optimized query
		return self.ready.then(function () {
			return self.knex.raw(postgresfastq, [sid, new Date(expired).toISOString(), sess ])
			.then(function (result) {
				if (fn) fn(null, result);
				return result;
			})
			.catch(function (err) {
				fn(err);
				throw err;
			});
		});
	} else if (['mysql', 'mariasql'].indexOf(self.knex.client.dialect) > -1) {
		// mysql/mariaDB optimized query
		return self.ready.then(function () {
			return self.knex.raw(mysqlfastq, [sid, new Date(expired).toISOString(), sess ])
			.then(function (result) {
				if (fn) fn(null, result);
				return result;
			})
			.catch(function (err) {
				fn(err);
				throw err;
			});
		});
	} else {
		return self.ready.then(function () {
			return self.knex.transaction(function (trx) {
				return trx.select('*')
				.forUpdate()
				.from(self.tablename)
				.where('sid', '=', sid)
				.then(function (foundKeys) {
					if (foundKeys.length === 0) {
						return trx.from(self.tablename)
						.insert({
							sid: sid,
							expired: new Date(expired).toISOString(),
							sess: sess
						});
					} else {
						return trx(self.tablename)
						.where('sid', '=', sid)
						.update({
							expired: new Date(expired).toISOString(),
							sess: sess
						});
					}
				});
			})
			.then(function (res) {
				if (fn) fn(null, res);
				return res;
			})
			.catch(function(err) {
				if (fn) fn(err);
				throw err;
			});
		});
	}
};

/*
* Destroy the session associated with the given `sid`.
*
* @param {String} sid
* @api public
*/
KnexStore.prototype.destroy = function(sid, fn) {
	var self = this;
	return self.ready.then(function () {
		return self.knex.del()
		.from(self.tablename)
		.where('sid', '=', sid)
		.then(function (res) {
			if (fn) fn(null, res);
			return res;
		})
		.catch(function(err) {
			if (fn) fn(err);
			throw err;
		});
	});
};

/*
* Fetch number of sessions.
*
* @param {Function} fn
* @api public
*/
KnexStore.prototype.length = function(fn) {
	var self = this;
	return self.ready.then(function () {
		return self.knex.count('sid as count')
		.from(self.tablename)
		.then(function (response) {
			var ret = response[0].count | 0;
			if (fn) fn(null, ret);
			return ret;
		})
		.catch(function(err) {
			fn(err);
			throw err;
		});
	});
};

/*
* Clear all sessions.
*
* @param {Function} fn
* @api public
*/
KnexStore.prototype.clear = function(fn) {
	var self = this;
	return self.ready.then(function () {
		return self.knex.del()
		.from(self.tablename)
		.then(function (res) {
			if (fn) fn(null, res);
			return res;
		})
		.catch(function(err) {
			fn(err);
			throw err;
		});
	});
};

return KnexStore;

};
<commit_msg>Don't use postgres fast query for version < 9.2 because the json type is not supported.<commit_after>'use strict';
var util = require('util');

var oneDay = 86400000;

module.exports = function(connect) {

/**
* Connect's Store.
*/
var Store = (connect.session) ? connect.session.Store : connect.Store;

/*
 * Return an ISO compliant string of the current time
 * @api private
 * @return {String} an ISO compliant string of the current time
 */
function nowAsISO() {
	return (new Date()).toISOString();
}

/*
 * Return dialect-aware type name for timestamp
 * @return {String} type name for timestamp
 * @api private
 */
function timestampTypeName(knex) {
	return (['mysql', 'mariasql'].indexOf(knex.client.dialect) > -1) ? 'DATETIME' : 'timestamp';
}

/*
* Remove expired sessions from database.
* @param {Object} store
* @api private
*/
function dbCleanup(store) {
	return store.ready.then(function () {
		return store.knex(store.tablename).del()
		.whereRaw('expired < CAST(? as ' + timestampTypeName(store.knex) + ')', nowAsISO());
	});
}

/*
* Initialize KnexStore with the given options.
*
* @param {Object} options
* @api public
*/
function KnexStore(options) {
	var self = this;

	options = options || {};
	Store.call(self, options);

	self.tablename = options.tablename || 'sessions';
	self.knex = options.knex || require('knex')({
		client: 'sqlite3',
		// debug: true,
		connection: {
			filename: "connect-session-knex.sqlite"
		}
	});

	self.ready = self.knex.schema.hasTable(self.tablename)
	.then(function (exists) {
		if (!exists) {
			return self.knex.schema.createTable(self.tablename, function (table) {
				table.string('sid').primary();
				table.json('sess').notNullable();
				if (['mysql', 'mariasql'].indexOf(self.knex.client.dialect) > -1) {
					table.dateTime('expired').notNullable();
				} else {
					table.timestamp('expired', 'true').notNullable();
				}
			});
		}
	})
	.then(function () {
		dbCleanup(self);
		setInterval(dbCleanup, oneDay, self).unref();
	});
}

// KnexStore.prototype.__proto__ = Store.prototype;
util.inherits(KnexStore, Store);

/*
* Attempt to fetch session by the given sid.
*
* @param {String} sid
* @param {Function} fn
* @api public
*/
KnexStore.prototype.get = function(sid, fn) {
	var self = this;
	return self.ready.then(function () {
		return self.knex
			.select('sess')
			.from(self.tablename)
			.where('sid', '=', sid)
			.andWhereRaw('CAST(? as '+timestampTypeName(self.knex)+') <= expired', nowAsISO())
			.then(function (response) {
				var ret;
				if (response[0]) {
					ret = response[0].sess;
					if (typeof ret === "string") {
						ret = JSON.parse(ret);
					}
				}

				if (fn) fn(null, ret);
				return ret;
			}).catch(function(err) {
				if (fn) fn(err);
				throw err;
			});
	});
};

/*
* Commit the given `sess` object associated with the given `sid`.
*
* @param {String} sid
* @param {Session} sess
* @param {Function} fn
* @api public
*/
KnexStore.prototype.set = function(sid, sess, fn) {
	var self = this;
	var maxAge = sess.cookie.maxAge;
	var now = new Date().getTime();
	var expired = maxAge ? now + maxAge : now + oneDay;
	sess = JSON.stringify(sess);
	var postgresfastq = 'with new_values (sid, expired, sess) as (' +
					'  values (?, ?::timestamp without time zone, ?::json)' +
					'), ' +
					'upsert as ' +
					'( ' +
					'  update ' + self.tablename + ' cs set ' +
					'    sid = nv.sid, ' +
					'    expired = nv.expired, ' +
					'    sess = nv.sess ' +
					'  from new_values nv ' +
					'  where cs.sid = nv.sid ' +
					'  returning cs.* ' +
					')' +
					'insert into ' + self.tablename + ' (sid, expired, sess) ' +
					'select sid, expired, sess ' +
					'from new_values ' +
					'where not exists (select 1 from upsert up where up.sid = new_values.sid)';

	var sqlitefastq = 'insert or replace into ' + self.tablename + ' (sid, expired, sess) values (?, ?, ?);';

	var mysqlfastq = 'insert into ' + self.tablename + ' (sid, expired, sess) values (?, ?, ?) on duplicate key update expired=values(expired), sess=values(sess);';

	if (self.knex.client.dialect === 'sqlite3') {
		// sqlite optimized query
		return self.ready.then(function () {
			return self.knex.raw(sqlitefastq, [sid, new Date(expired).toISOString(), sess ])
			.then(function (result) {
				if (fn && result instanceof Array) {
					fn(null, [1]);
				}
				if (result instanceof Array) {
					return [1];
				}
			})
			.catch(function (err) {
				fn(err);
				throw err;
			});
		});
	} else if (self.knex.client.dialect === 'postgresql' && parseFloat(self.knex.client.version) >= 9.2) {
		// postgresql optimized query
		return self.ready.then(function () {
			return self.knex.raw(postgresfastq, [sid, new Date(expired).toISOString(), sess ])
			.then(function (result) {
				if (fn) fn(null, result);
				return result;
			})
			.catch(function (err) {
				fn(err);
				throw err;
			});
		});
	} else if (['mysql', 'mariasql'].indexOf(self.knex.client.dialect) > -1) {
		// mysql/mariaDB optimized query
		return self.ready.then(function () {
			return self.knex.raw(mysqlfastq, [sid, new Date(expired).toISOString(), sess ])
			.then(function (result) {
				if (fn) fn(null, result);
				return result;
			})
			.catch(function (err) {
				fn(err);
				throw err;
			});
		});
	} else {
		return self.ready.then(function () {
			return self.knex.transaction(function (trx) {
				return trx.select('*')
				.forUpdate()
				.from(self.tablename)
				.where('sid', '=', sid)
				.then(function (foundKeys) {
					if (foundKeys.length === 0) {
						return trx.from(self.tablename)
						.insert({
							sid: sid,
							expired: new Date(expired).toISOString(),
							sess: sess
						});
					} else {
						return trx(self.tablename)
						.where('sid', '=', sid)
						.update({
							expired: new Date(expired).toISOString(),
							sess: sess
						});
					}
				});
			})
			.then(function (res) {
				if (fn) fn(null, res);
				return res;
			})
			.catch(function(err) {
				if (fn) fn(err);
				throw err;
			});
		});
	}
};

/*
* Destroy the session associated with the given `sid`.
*
* @param {String} sid
* @api public
*/
KnexStore.prototype.destroy = function(sid, fn) {
	var self = this;
	return self.ready.then(function () {
		return self.knex.del()
		.from(self.tablename)
		.where('sid', '=', sid)
		.then(function (res) {
			if (fn) fn(null, res);
			return res;
		})
		.catch(function(err) {
			if (fn) fn(err);
			throw err;
		});
	});
};

/*
* Fetch number of sessions.
*
* @param {Function} fn
* @api public
*/
KnexStore.prototype.length = function(fn) {
	var self = this;
	return self.ready.then(function () {
		return self.knex.count('sid as count')
		.from(self.tablename)
		.then(function (response) {
			var ret = response[0].count | 0;
			if (fn) fn(null, ret);
			return ret;
		})
		.catch(function(err) {
			fn(err);
			throw err;
		});
	});
};

/*
* Clear all sessions.
*
* @param {Function} fn
* @api public
*/
KnexStore.prototype.clear = function(fn) {
	var self = this;
	return self.ready.then(function () {
		return self.knex.del()
		.from(self.tablename)
		.then(function (res) {
			if (fn) fn(null, res);
			return res;
		})
		.catch(function(err) {
			fn(err);
			throw err;
		});
	});
};

return KnexStore;

};
<|endoftext|>


<commit_before>var fs = require('fs');
var yaml = require('js-yaml');
var md5 = require('md5');
var Twig = require('twig');

var readability = require('node-readability');

var processContent = function(content) {
  content = content.replace(/(/g, '$1/>');
  content = content.replace(/
/g, '
');
  return content;
}

const child_process = require( 'child_process' );

// Parse arguments.
if (process.argv.length < 3) {
  console.log('Usage:');
  console.log(process.argv[1] + ' settings.yml');
  process.exit();
}

// Read definition.
var ymlPath = process.argv[2];
var yml = fs.readFileSync(ymlPath, 'utf-8');
var book = yaml.load(yml)

// Get template.
let twig = fs.readFileSync('./templates/article.html.twig').toString();
var template = Twig.twig({ data: twig });

var count = book.content.length;

for (let url of book.content) {
  let url_md5 = md5(url);
  console.log(url_md5 + ': processing, URL: ' + url);
  // TODO: Deprecated.
  if (!fs.existsSync('./output/html/' + url_md5 + '.html')) {
    console.log(url_md5 + ': downloading.');
    let wget = child_process.spawn( 'wget', [ '-O', './output/html/' + url_md5 + '.html', '--convert-links', url ] );
    wget.on('close', (code) => {
      console.log(url_md5 + ': downloaded.');
      parseFile(url_md5);
    });
  }
  else {
    console.log(url_md5 + ': already downloaded.');
    parseFile(url_md5);
  }
}

function parseFile(url_md5) {

  fs.readFile('./output/html/' + url_md5 + '.html', (err, data) => {
    let html = data.toString();
    if (fs.existsSync('./output/html.processed/' + url_md5 + '.html')) {
      decreaseCount();
      return;
    }

    readability(html, function(err, article, meta) {
      article.content = processContent(article.content);
      let html_processed = template.render(article);
      console.log(url_md5 + ': extracting content.');
      fs.writeFileSync('./output/html.processed/' + url_md5 + '.html', html_processed);
      decreaseCount();
    });
  });
}

function decreaseCount() {
  count--;
  // When parsed all files.
  if (count == 0) {
    createEpub();
  }
}

function createEpub() {

  // Set metadata.
  var twig = fs.readFileSync('./templates/epub-metadata.xml.twig').toString();
  var template = Twig.twig({ data: twig });
  var xml = template.render(book);
  fs.writeFileSync('./output/meta/' + book.shortname + '.xml', xml)

  var filepaths = [];
  for (url of book.content) {
    var url_md5 = md5(url);
    filepaths.push('./output/html.processed/' + url_md5 + '.html');
  }

  // Create EPUB.
  console.log('Creating EPUB...')
  child_process.spawnSync( 'pandoc', [ '--from', 'html', '-o', './output/epub/' + book.shortname + '.epub', '--epub-metadata', './output/meta/' + book.shortname + '.xml' ].concat(filepaths) );
  // TODO:
  // Output exit status.
  console.log('Done.')
}
<commit_msg>Rename.<commit_after>var fs = require('fs');
var yaml = require('js-yaml');
var md5 = require('md5');
var Twig = require('twig');

var readability = require('node-readability');

var processContent = function(content) {
  content = content.replace(/(/g, '$1/>');
  content = content.replace(/
/g, '
');
  return content;
}

const child_process = require( 'child_process' );

// Parse arguments.
if (process.argv.length < 3) {
  console.log('Usage:');
  console.log(process.argv[1] + ' definition.yml');
  process.exit();
}

// Read definition.
var ymlPath = process.argv[2];
var yml = fs.readFileSync(ymlPath, 'utf-8');
var book = yaml.load(yml)

// Get template.
let twig = fs.readFileSync('./templates/article.html.twig').toString();
var template = Twig.twig({ data: twig });

var count = book.content.length;

for (let url of book.content) {
  let url_md5 = md5(url);
  console.log(url_md5 + ': processing, URL: ' + url);
  // TODO: Deprecated.
  if (!fs.existsSync('./output/html/' + url_md5 + '.html')) {
    console.log(url_md5 + ': downloading.');
    let wget = child_process.spawn( 'wget', [ '-O', './output/html/' + url_md5 + '.html', '--convert-links', url ] );
    wget.on('close', (code) => {
      console.log(url_md5 + ': downloaded.');
      parseFile(url_md5);
    });
  }
  else {
    console.log(url_md5 + ': already downloaded.');
    parseFile(url_md5);
  }
}

function parseFile(url_md5) {

  fs.readFile('./output/html/' + url_md5 + '.html', (err, data) => {
    let html = data.toString();
    if (fs.existsSync('./output/html.processed/' + url_md5 + '.html')) {
      decreaseCount();
      return;
    }

    readability(html, function(err, article, meta) {
      article.content = processContent(article.content);
      let html_processed = template.render(article);
      console.log(url_md5 + ': extracting content.');
      fs.writeFileSync('./output/html.processed/' + url_md5 + '.html', html_processed);
      decreaseCount();
    });
  });
}

function decreaseCount() {
  count--;
  // When parsed all files.
  if (count == 0) {
    createEpub();
  }
}

function createEpub() {

  // Set metadata.
  var twig = fs.readFileSync('./templates/epub-metadata.xml.twig').toString();
  var template = Twig.twig({ data: twig });
  var xml = template.render(book);
  fs.writeFileSync('./output/meta/' + book.shortname + '.xml', xml)

  var filepaths = [];
  for (url of book.content) {
    var url_md5 = md5(url);
    filepaths.push('./output/html.processed/' + url_md5 + '.html');
  }

  // Create EPUB.
  console.log('Creating EPUB...')
  child_process.spawnSync( 'pandoc', [ '--from', 'html', '-o', './output/epub/' + book.shortname + '.epub', '--epub-metadata', './output/meta/' + book.shortname + '.xml' ].concat(filepaths) );
  // TODO:
  // Output exit status.
  console.log('Done.')
}
<|endoftext|>


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

process.argv.push('--exclude', 'node_modules', '--config', path.resolve('node_modules', path.basename(__dirname), 'jshintrc'));
console.log(process.argv);
console.log(require('jshint/bin/jshint'));
<commit_msg>add directory to lint<commit_after>var path = require('path');

process.argv.push('--exclude', 'node_modules', '--config', path.resolve('node_modules', path.basename(__dirname), 'jshintrc'));
process.argv.push(path.resolve(__dirname, '..', '..'));
require('jshint/bin/jshint');
<|endoftext|>


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

'use strict';

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

/**
 * Plugin is registered on `app` and `collection` instances
 */

module.exports = function() {
  return function() {
    if (!this.isApp) return;
    plugin.call(this, this);

    return function() {
      if (!this.isCollection) return;
      plugin.call(this, this);
    };
  };
};

/**
 * The actual `fs` plugin
 */

function plugin(app) {
  if (this.isRegistered('assemble-fs')) return;

  /**
   * Setup middleware handlers. Assume none of the handlers exist if `onStream`
   * does not exist.
   */

  if (typeof app.handler === 'function' && typeof app.onStream !== 'function') {
    app.handler('onStream');
    app.handler('preWrite');
    app.handler('postWrite');
    app.handler('onLoad');
  }

  /**
   * Copy files with the given glob `patterns` to the specified `dest`.
   *
   * ```js
   * app.task('assets', function(cb) {
   *   app.copy('assets/**', 'dist/')
   *     .on('error', cb)
   *     .on('finish', cb)
   * });
   * ```
   * @name .copy
   * @param {String|Array} `patterns` Glob patterns of files to copy.
   * @param  {String|Function} `dest` Desination directory.
   * @return {Stream} Stream, to continue processing if necessary.
   * @api public
   */

  app.mixin('copy', function(patterns, dest, options) {
    var opts = utils.extend({ allowEmpty: true }, options);
    return utils.vfs.src(patterns, opts)
      .pipe(utils.vfs.dest(dest, opts))
  });

  /**
   * Glob patterns or filepaths to source files.
   *
   * ```js
   * app.src('src/*.hbs', {layout: 'default'});
   * ```
   * @name .src
   * @param {String|Array} `glob` Glob patterns or file paths to source files.
   * @param {Object} `options` Options or locals to merge into the context and/or pass to `src` plugins
   * @api public
   */

  app.mixin('src', function(glob, options) {
    var opts = utils.extend({ allowEmpty: true, onLoad: false }, options);
    this.options.onLoad = false;
    return utils.vfs.src(glob, opts)
      .pipe(toCollection(this, opts))
      .pipe(utils.handle(this, 'onLoad'))
      .pipe(utils.handle(this, 'onStream'))
  });

  /**
   * Glob patterns or paths for symlinks.
   *
   * ```js
   * app.symlink('src/**');
   * ```
   * @name .symlink
   * @param {String|Array} `glob`
   * @api public
   */

  app.mixin('symlink', function() {
    return utils.vfs.symlink.apply(utils.vfs, arguments);
  });

  /**
   * Specify a destination for processed files.
   *
   * ```js
   * app.dest('dist/');
   * ```
   * @name .dest
   * @param {String|Function} `dest` File path or rename function.
   * @param {Object} `options` Options and locals to pass to `dest` plugins
   * @api public
   */

  app.mixin('dest', function(dir) {
    if (!dir) {
      throw new TypeError('expected dest to be a string or function.');
    }

    var output = utils.combine([
      utils.handle(this, 'preWrite'),
      utils.vfs.dest.apply(utils.vfs, arguments),
      utils.handle(this, 'postWrite')
    ]);

    output.on('end', output.emit.bind(output, 'finish'));
    return output;
  });
}

/**
 * Push vinyl files into a collection or list.
 */

function toCollection(app, options) {
  var opts = utils.extend({collection: 'streamFiles'}, options);
  var name = opts.collection;
  var collection, view;

  if (app.isApp) {
    collection = app[name] || app.create(name, options);
  }

  var stream = utils.through.obj(function(file, enc, next) {
    if (file.isNull()) {
      return next();
    }

    if (app.isApp) {
      view = collection.setView(file.path, file);
    } else if (app.isCollection || app.isViews) {
      view = app.setView(file.path, file);
    } else if (app.isList) {
      view = app.setItem(file.path, file);
    } else {
      return next(new Error('assemble-fs expects an instance, collection or view'));
    }

    view.options = utils.extend({}, options, view.options);
    next(null, view);
  });

  app.stream = stream;
  return stream;
}
<commit_msg>updating to set the `onLoad` option on the `file` to `false` to disable default `onLoad` handling in templates.<commit_after>/*!
 * assemble-fs <https://github.com/jonschlinkert/assemble-fs>
 *
 * Copyright (c) 2015, Jon Schlinkert.
 * Licensed under the MIT License.
 */

'use strict';

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

/**
 * Plugin is registered on `app` and `collection` instances
 */

module.exports = function() {
  return function() {
    if (!this.isApp) return;
    plugin.call(this, this);

    return function() {
      if (!this.isCollection) return;
      plugin.call(this, this);
    };
  };
};

/**
 * The actual `fs` plugin
 */

function plugin(app) {
  if (this.isRegistered('assemble-fs')) return;

  /**
   * Setup middleware handlers. Assume none of the handlers exist if `onStream`
   * does not exist.
   */

  if (typeof app.handler === 'function' && typeof app.onStream !== 'function') {
    app.handler('onStream');
    app.handler('preWrite');
    app.handler('postWrite');
    app.handler('onLoad');
  }

  /**
   * Copy files with the given glob `patterns` to the specified `dest`.
   *
   * ```js
   * app.task('assets', function(cb) {
   *   app.copy('assets/**', 'dist/')
   *     .on('error', cb)
   *     .on('finish', cb)
   * });
   * ```
   * @name .copy
   * @param {String|Array} `patterns` Glob patterns of files to copy.
   * @param  {String|Function} `dest` Desination directory.
   * @return {Stream} Stream, to continue processing if necessary.
   * @api public
   */

  app.mixin('copy', function(patterns, dest, options) {
    var opts = utils.extend({ allowEmpty: true }, options);
    return utils.vfs.src(patterns, opts)
      .pipe(utils.vfs.dest(dest, opts))
  });

  /**
   * Glob patterns or filepaths to source files.
   *
   * ```js
   * app.src('src/*.hbs', {layout: 'default'});
   * ```
   * @name .src
   * @param {String|Array} `glob` Glob patterns or file paths to source files.
   * @param {Object} `options` Options or locals to merge into the context and/or pass to `src` plugins
   * @api public
   */

  app.mixin('src', function(glob, options) {
    var opts = utils.extend({ allowEmpty: true }, options);
    return utils.vfs.src(glob, opts)
      .pipe(toCollection(this, opts))
      .pipe(utils.handle(this, 'onLoad'))
      .pipe(utils.handle(this, 'onStream'))
  });

  /**
   * Glob patterns or paths for symlinks.
   *
   * ```js
   * app.symlink('src/**');
   * ```
   * @name .symlink
   * @param {String|Array} `glob`
   * @api public
   */

  app.mixin('symlink', function() {
    return utils.vfs.symlink.apply(utils.vfs, arguments);
  });

  /**
   * Specify a destination for processed files.
   *
   * ```js
   * app.dest('dist/');
   * ```
   * @name .dest
   * @param {String|Function} `dest` File path or rename function.
   * @param {Object} `options` Options and locals to pass to `dest` plugins
   * @api public
   */

  app.mixin('dest', function(dir) {
    if (!dir) {
      throw new TypeError('expected dest to be a string or function.');
    }

    var output = utils.combine([
      utils.handle(this, 'preWrite'),
      utils.vfs.dest.apply(utils.vfs, arguments),
      utils.handle(this, 'postWrite')
    ]);

    output.on('end', output.emit.bind(output, 'finish'));
    return output;
  });
}

/**
 * Push vinyl files into a collection or list.
 */

function toCollection(app, options) {
  var opts = utils.extend({collection: 'streamFiles'}, options);
  var name = opts.collection;
  var collection, view;

  if (app.isApp) {
    collection = app[name] || app.create(name, options);
  }

  var stream = utils.through.obj(function(file, enc, next) {
    if (file.isNull()) {
      return next();
    }

    // disable default `onLoad` handling inside templates
    file.options = utils.extend({ onLoad: false }, file.options);

    if (app.isApp) {
      view = collection.setView(file.path, file);
    } else if (app.isCollection || app.isViews) {
      view = app.setView(file.path, file);
    } else if (app.isList) {
      view = app.setItem(file.path, file);
    } else {
      return next(new Error('assemble-fs expects an instance, collection or view'));
    }

    view.options = utils.extend({}, options, view.options);
    next(null, view);
  });

  app.stream = stream;
  return stream;
}
<|endoftext|>


<commit_before>'use strict';
var path = require('path');
var findup = require('findup-sync');
var multimatch = require('multimatch');

function arrayify(el) {
    return Array.isArray(el) ? el : [el];
}

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

    var pattern = arrayify(options.pattern || ['flit-*']);
    var config = options.config || findup('package.json');
    var scope = arrayify(options.scope || ['dependencies', 'devDependencies', 'peerDependencies']);

    if (typeof config === 'string') {
        config = require(path.resolve(config));
    }

    pattern.push('!flit', '!flit-cli');

    var names = scope.reduce(function (result, prop) {
        return result.concat(Object.keys(config[prop] || {}));
    }, []);

    multimatch(names, pattern).forEach(flit.loadNpmPlugin);
};
<commit_msg>fixed loadNpmPlugin scope undefined error<commit_after>'use strict';
var path = require('path');
var findup = require('findup-sync');
var multimatch = require('multimatch');

function arrayify(el) {
    return Array.isArray(el) ? el : [el];
}

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

    var pattern = arrayify(options.pattern || ['flit-*']);
    var config = options.config || findup('package.json');
    var scope = arrayify(options.scope || ['dependencies', 'devDependencies', 'peerDependencies']);

    if (typeof config === 'string') {
        config = require(path.resolve(config));
    }

    pattern.push('!flit', '!flit-cli');

    var names = scope.reduce(function (result, prop) {
        return result.concat(Object.keys(config[prop] || {}));
    }, []);

    multimatch(names, pattern).forEach(flit.loadNpmPlugin.bind(flit));
};
<|endoftext|>


<commit_before>'use strict';
var applescript = require('applescript');
var toPercent = require('to-percent');
var toDecimal = require('to-decimal');

exports.get = function (cb) {
	if (process.platform !== 'darwin') {
		throw new Error('Only OS X systems are supported');
	}

	applescript.execString('get volume settings', function (err, res) {
		if (err) {
			cb(err);
			return;
		}

		cb(null, toDecimal(parseInt(res[0].split(':')[1])));
	});
};

exports.set = function (level, cb) {
	if (process.platform !== 'darwin') {
		throw new Error('Only OS X systems are supported');
	}

	if (typeof level !== 'number') {
		throw new TypeError('Expected a number');
	}

	if (level < 0 || level > 1) {
		cb(new Error('Expected a level between 0 and 1'));
	}

	applescript.execString('set volume output volume ' + toPercent(level), function (err, res) {
		if (err) {
			cb(err);
			return;
		}

		cb();
	});
};
<commit_msg>Small tweak<commit_after>'use strict';
var applescript = require('applescript');
var toPercent = require('to-percent');
var toDecimal = require('to-decimal');

exports.get = function (cb) {
	if (process.platform !== 'darwin') {
		throw new Error('Only OS X systems are supported');
	}

	applescript.execString('get volume settings', function (err, res) {
		if (err) {
			cb(err);
			return;
		}

		cb(null, toDecimal(parseInt(res[0].split(':')[1], 10)));
	});
};

exports.set = function (level, cb) {
	if (process.platform !== 'darwin') {
		throw new Error('Only OS X systems are supported');
	}

	if (typeof level !== 'number') {
		throw new TypeError('Expected a number');
	}

	if (level < 0 || level > 1) {
		cb(new Error('Expected a level between 0 and 1'));
	}

	applescript.execString('set volume output volume ' + toPercent(level), function (err, res) {
		if (err) {
			cb(err);
			return;
		}

		cb();
	});
};
<|endoftext|>


<commit_before>/**
 * `<Form />` component is a stateful wrapper around `<Element />` component.
 *
 * The basic usage is as follows:
 *
 *    <Form
 *      schema={...}
 *      defaultValue={...}
 *      onChange={function(value) { ... }}
 *      onUpdate={function(value, validation) { ... }}
 *      />
 *
 * Property `defaultValue` is used to set the initial value of the form. It only
 * takes effect on initial render, after that form uses its own value from the
 * state.
 *
 * Callback `onUpdate` is called on every change to a form value, `onChange` is
 * only called when form value is valid after the change.
 *
 * Alternatively one can read current form value by calling `getValue()` method
 * (you can access form by keeping a ref to it).
 *
 * @jsx React.DOM
 * @copyright Prometheus Research, LLC 2014
 */
'use strict';

var React         = require('react/addons');
var PropTypes     = React.PropTypes;
var cx            = React.addons.classSet;
var FormPropTypes = require('./PropTypes');
var Element       = require('./Element');
var Value         = require('./Value');

var Form = React.createClass({

  propTypes: {
    component: PropTypes.constructor,
    defaultValue: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
    externalValidation: PropTypes.object,
    schema: FormPropTypes.Schema,
    onChange: PropTypes.func,
    onUpdate: PropTypes.func
  },

  render() {
    var {component} = this.props;
    var {value} = this.state;
    var className = cx({
      'rf-Form': true,
      'rf-Form--invalid': value.validation.isFailure
    });
    return this.transferPropsTo(
      <component className={className}>
        <Element value={value} />
      </component>
    );
  },

  getDefaultProps() {
    return {
      component: React.DOM.form
    };
  },

  getInitialState() {
    return {
      value: Value(
        this.props.schema,
        this.props.defaultValue,
        this.props.externalValidation,
        this.onUpdate
      )
    };
  },

  componentWillReceiveProps({schema}) {
    // TODO: We read from _pendingState so we can have latest value changes even
    // if it is update in the same reconciliaiton transaction. Make sure we
    // migrate to a new API for this as soon as it becomes available in React.
    var value = this._pendingState && this._pendingState.value || this.state.value;
    if (schema && !schema.equals(this.props.schema)) {
      value = value.updateSchema(schema);
      this.setState({value});
    }
  },

  onUpdate(value) {
    var path = value.path;
    value = value.root();
    this.setState({value});
    if (this.props.onChange || this.props.onUpdate) {
      var jsValue = value.value.toJS();
      if (this.props.onUpdate) {
        this.props.onUpdate(jsValue, value.validation, path);
      }
      if (this.props.onChange && value.isValid) {
        this.props.onChange(jsValue);
      }
    }
  },

  getValue() {
    return this.state.value.value.toJS();
  },

  setValue(newValue) {
    var value = this.state.value.update(value);
    this.setState({value});
  },

  getValidation() {
    return this.state.value.validation;
  },

  isValid() {
    return this.state.value.isValid;
  }
});

module.exports = Form;
<commit_msg>Form: fix setValue method<commit_after>/**
 * `<Form />` component is a stateful wrapper around `<Element />` component.
 *
 * The basic usage is as follows:
 *
 *    <Form
 *      schema={...}
 *      defaultValue={...}
 *      onChange={function(value) { ... }}
 *      onUpdate={function(value, validation) { ... }}
 *      />
 *
 * Property `defaultValue` is used to set the initial value of the form. It only
 * takes effect on initial render, after that form uses its own value from the
 * state.
 *
 * Callback `onUpdate` is called on every change to a form value, `onChange` is
 * only called when form value is valid after the change.
 *
 * Alternatively one can read current form value by calling `getValue()` method
 * (you can access form by keeping a ref to it).
 *
 * @jsx React.DOM
 * @copyright Prometheus Research, LLC 2014
 */
'use strict';

var React         = require('react/addons');
var PropTypes     = React.PropTypes;
var cx            = React.addons.classSet;
var FormPropTypes = require('./PropTypes');
var Element       = require('./Element');
var Value         = require('./Value');

var Form = React.createClass({

  propTypes: {
    component: PropTypes.constructor,
    defaultValue: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
    externalValidation: PropTypes.object,
    schema: FormPropTypes.Schema,
    onChange: PropTypes.func,
    onUpdate: PropTypes.func
  },

  render() {
    var {component} = this.props;
    var {value} = this.state;
    var className = cx({
      'rf-Form': true,
      'rf-Form--invalid': value.validation.isFailure
    });
    return this.transferPropsTo(
      <component className={className}>
        <Element value={value} />
      </component>
    );
  },

  getDefaultProps() {
    return {
      component: React.DOM.form
    };
  },

  getInitialState() {
    return {
      value: Value(
        this.props.schema,
        this.props.defaultValue,
        this.props.externalValidation,
        this.onUpdate
      )
    };
  },

  componentWillReceiveProps({schema}) {
    // TODO: We read from _pendingState so we can have latest value changes even
    // if it is update in the same reconciliaiton transaction. Make sure we
    // migrate to a new API for this as soon as it becomes available in React.
    var value = this._pendingState && this._pendingState.value || this.state.value;
    if (schema && !schema.equals(this.props.schema)) {
      value = value.updateSchema(schema);
      this.setState({value});
    }
  },

  onUpdate(value) {
    var path = value.path;
    value = value.root();
    this.setState({value});
    if (this.props.onChange || this.props.onUpdate) {
      var jsValue = value.value.toJS();
      if (this.props.onUpdate) {
        this.props.onUpdate(jsValue, value.validation, path);
      }
      if (this.props.onChange && value.isValid) {
        this.props.onChange(jsValue);
      }
    }
  },

  getValue() {
    return this.state.value.value.toJS();
  },

  setValue(newValue) {
    var value = this.state.value.update(newValue);
    this.setState({value});
  },

  getValidation() {
    return this.state.value.validation;
  },

  isValid() {
    return this.state.value.isValid;
  }
});

module.exports = Form;
<|endoftext|>


<commit_before>/**
 * @file apijs-admin
 * @author xuexb <fe.xiaowu@gmail.con>
 */

var path = require('path');

/**
 * 获取路径
 *
 * @param {string} name 获取的目录, static静态目录为dist
 * @return {string}
 */
module.exports.getPath = function (name) {
    return path.resolve(__dirname, name === 'static' ? './dist/' : './');
};<commit_msg>fix fecs<commit_after>/**
 * @file apijs-admin
 * @author xuexb <fe.xiaowu@gmail.con>
 */

var path = require('path');

/**
 * 获取路径
 *
 * @param {string} name 获取的目录, static静态目录为dist
 * @return {string}
 */
module.exports.getPath = function (name) {
    return path.resolve(__dirname, name === 'static' ? './dist/' : './');
};
<|endoftext|>


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

var fs = require('fs'),
  path = require('path');

module.exports = {
  name: 'ember-cli-pure-bootstrap',
  included: function(app) {
    this._super.included(app);

    var base = path.join(app.bowerDirectory, '/bootstrap'),
      dirs = fs.readdirSync(base),
      dist = '/dist';

    if (dirs.indexOf('dist') < 0) {
      dist = path.join(
        dirs.filter(function(dir) { return dir.startsWith('bootstrap-'); }).pop(),
        dist
      );
    }

    app.import(path.join(base, dist, '/css/bootstrap.min.css'));
    app.import(path.join(base, dist, '/js/bootstrap.min.js'));
  }
};
<commit_msg>add import fonts<commit_after>/* jshint node: true */
'use strict';

var fs = require('fs'),
  path = require('path'),
  extend = require('util')._extend;

var defaultOptions = {
    importBootstrapTheme: false,
    importBootstrapCSS: true,
    importBootstrapFont: true
};

module.exports = {
  name: 'ember-cli-pure-bootstrap',
  included: function(app) {
    this._super.included(app);

    var emberCLIVersion = app.project.emberCLIVersion();
    if (emberCLIVersion < '0.0.41') {
        throw new Error('ember-cli-bootstrap requires ember-cli version 0.0.41 or greater.\n');
    }

    var base = path.join(app.bowerDirectory, '/bootstrap'),
      dirs = fs.readdirSync(base),
      dist = '/dist';

    if (dirs.indexOf('dist') < 0) {
      dist = path.join(
        dirs.filter(function(dir) { return dir.startsWith('bootstrap-'); }).pop(),
        dist
      );
    }

    var options         = extend(defaultOptions, app.options['ember-cli-pure-bootstrap']);
    var bootstrapPath   = path.join(app.bowerDirectory, base, dist);

    // Import css from bootstrap
    if (options.importBootstrapCSS) {
        app.import(path.join(bootstrapPath, 'css/bootstrap.css'));
        app.import(path.join(bootstrapPath, 'css/bootstrap.css.map'), { destDir: 'assets' });
    }

    if (options.importBootstrapTheme) {
        app.import(path.join(bootstrapPath, 'css/bootstrap-theme.css'));
    }

    // Import glyphicons
    if (options.importBootstrapFont) {
        app.import(path.join(bootstrapPath, 'fonts/glyphicons-halflings-regular.eot'), { destDir: '/fonts' });
        app.import(path.join(bootstrapPath, 'fonts/glyphicons-halflings-regular.svg'), { destDir: '/fonts' });
        app.import(path.join(bootstrapPath, 'fonts/glyphicons-halflings-regular.ttf'), { destDir: '/fonts' });
        app.import(path.join(bootstrapPath, 'fonts/glyphicons-halflings-regular.woff'), { destDir: '/fonts' });
        app.import(path.join(bootstrapPath, 'fonts/glyphicons-halflings-regular.woff2'), { destDir: '/fonts' });
    }

    app.import(path.join(app.bowerDirectory, 'bootstrap/js/transition.js'));
  }
};
<|endoftext|>


<commit_before>/*

index.js - "news-demo"

The MIT License (MIT)

Copyright (c) 2013 Tristan Slominski

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

*/
"use strict";

var events = require('events'),
    FeedParser = require('feedparser'),
    http = require('http'),
    util = require('util');

/*
  * `options`: _Object_
    * `bbcFeedUrl`: _String_ _(Default: 'http://feeds.bbci.co.uk/news/rss.xml')_ URL to BBC UK News RSS feed.
    * `hostname`: _String_ _(Default: 'localhost')_ Hostname for the server to listen on. If not specified, the server will accept connections directed to any IPv4 address (`INADDR_ANY`).
    * `port`: _Integer_ _(Default: 8080)_ Port number for the server to listen on.
    * `skyFeedUrl`: _String_ _(Default: 'http://news.sky.com/feeds/rss/uk.xml')_ URL to Sky UK News RSS feed.
*/
var Server = module.exports = function Server (options) {
    var self = this;
    events.EventEmitter.call(self);

    options = options || {};

    self.hostname = options.hostname || 'localhost';
    self.port = options.port || 8080;

    self.bbcFeedUrl = options.bbcFeedUrl || "http://feeds.bbci.co.uk/news/rss.xml";
    self.skyFeedUrl = options.skyFeedUrl || "http://news.sky.com/feeds/rss/uk.xml";

    self.server = null;
};

util.inherits(Server, events.EventEmitter);

/*
  * `callback`: _Function_ _(Default: undefined)_ `function () {}` Optional
          callback to call once the server is stopped.
*/
Server.listen = function listen (options, callback) {
    var server = new Server(options);
    server.listen(callback);
    return server;
};

/*
  * `callback`: _Function_ _(Default: undefined)_ `function () {}` Optional
          callback to call once the server is stopped.
*/
Server.prototype.close = function close (callback) {
    var self = this;
    if (self.server)
        self.server.close(callback);
};

/*
  * `callback`: _Function_ _(Default: undefined)_ `function () {}` Optional
          callback to call once the server is up.
*/
Server.prototype.listen = function listen (callback) {
    var self = this;
    self.server = http.createServer(function (req, res) {
        if (req.method != "GET") {
            res.writeHead(405, {Allow: 'GET'}); // Method Not Allowed
            res.end();
            return;
        }

        var connectionOpen = true;

        try {
            var bbcItems = [];
            var skyItems = [];
            var bbcItemsComplete = false;
            var skyItemsComplete = false;
            var completionCheck = function completionCheck() {
                if (bbcItems.length >= 10 && skyItems.length >= 10) {
                    res.writeHead(200);
                    res.write('');
                    res.write('
BBC Headlines:

');
                    for (var i = 0; i < 10; i++) {
                        res.write('' + (i + 1) + ' ' + bbcItems[i] + '
');
                    }
                    res.write('
SKY Headlines:

');
                    for (var i = 0; i < 10; i++) {
                        res.write('' + (i + 1) + ' ' + skyItems[i] + '
');
                    }
                    res.end('');
                }
            };
            var bbcRequest = http.get(self.bbcFeedUrl, function (res) {
                res
                    .pipe(new FeedParser())
                    .on('error', function (error) {
                        console.error(error);
                    })
                    .on('meta', function (meta) {
                        // console.dir(meta);
                    })
                    .on('readable', function () {
                        var stream = this, item;
                        while (item = stream.read()) {
                            console.log('BBC', item.title);
                            bbcItems.push(item.title);
                            if (bbcItems.length >= 10) {
                                bbcRequest.abort();
                                completionCheck();
                            }
                        }
                    });
            });
            var skyRequest = http.get(self.skyFeedUrl, function (res) {
                res
                    .pipe(new FeedParser())
                    .on('error', function (error) {
                        console.error(error);
                    })
                    .on('meta', function (meta) {
                        // console.dir(meta);
                    })
                    .on('readable', function () {
                        var stream = this, item;
                        while (item = stream.read()) {
                            console.log('SKY', item.title);
                            skyItems.push(item.title);
                            if (skyItems.length >= 10) {
                                skyRequest.abort();
                                completionCheck();
                            }
                        }
                    });
            });
        } catch (exception) {
            res.statusCode = 500; // Internal Server Error
            res.end();
            return;
        }
    });
    self.server.listen(self.port, self.hostname, callback);
};<commit_msg>removed unused code<commit_after>/*

index.js - "news-demo"

The MIT License (MIT)

Copyright (c) 2013 Tristan Slominski

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

*/
"use strict";

var events = require('events'),
    FeedParser = require('feedparser'),
    http = require('http'),
    util = require('util');

/*
  * `options`: _Object_
    * `bbcFeedUrl`: _String_ _(Default: 'http://feeds.bbci.co.uk/news/rss.xml')_ URL to BBC UK News RSS feed.
    * `hostname`: _String_ _(Default: 'localhost')_ Hostname for the server to listen on. If not specified, the server will accept connections directed to any IPv4 address (`INADDR_ANY`).
    * `port`: _Integer_ _(Default: 8080)_ Port number for the server to listen on.
    * `skyFeedUrl`: _String_ _(Default: 'http://news.sky.com/feeds/rss/uk.xml')_ URL to Sky UK News RSS feed.
*/
var Server = module.exports = function Server (options) {
    var self = this;
    events.EventEmitter.call(self);

    options = options || {};

    self.hostname = options.hostname || 'localhost';
    self.port = options.port || 8080;

    self.bbcFeedUrl = options.bbcFeedUrl || "http://feeds.bbci.co.uk/news/rss.xml";
    self.skyFeedUrl = options.skyFeedUrl || "http://news.sky.com/feeds/rss/uk.xml";

    self.server = null;
};

util.inherits(Server, events.EventEmitter);

/*
  * `callback`: _Function_ _(Default: undefined)_ `function () {}` Optional
          callback to call once the server is stopped.
*/
Server.listen = function listen (options, callback) {
    var server = new Server(options);
    server.listen(callback);
    return server;
};

/*
  * `callback`: _Function_ _(Default: undefined)_ `function () {}` Optional
          callback to call once the server is stopped.
*/
Server.prototype.close = function close (callback) {
    var self = this;
    if (self.server)
        self.server.close(callback);
};

/*
  * `callback`: _Function_ _(Default: undefined)_ `function () {}` Optional
          callback to call once the server is up.
*/
Server.prototype.listen = function listen (callback) {
    var self = this;
    self.server = http.createServer(function (req, res) {
        if (req.method != "GET") {
            res.writeHead(405, {Allow: 'GET'}); // Method Not Allowed
            res.end();
            return;
        }

        try {
            var bbcItems = [];
            var skyItems = [];
            var bbcItemsComplete = false;
            var skyItemsComplete = false;
            var completionCheck = function completionCheck() {
                if (bbcItems.length >= 10 && skyItems.length >= 10) {
                    res.writeHead(200);
                    res.write('');
                    res.write('
BBC Headlines:

');
                    for (var i = 0; i < 10; i++) {
                        res.write('' + (i + 1) + ' ' + bbcItems[i] + '
');
                    }
                    res.write('
SKY Headlines:

');
                    for (var i = 0; i < 10; i++) {
                        res.write('' + (i + 1) + ' ' + skyItems[i] + '
');
                    }
                    res.end('');
                }
            };
            var bbcRequest = http.get(self.bbcFeedUrl, function (res) {
                res
                    .pipe(new FeedParser())
                    .on('error', function (error) {
                        console.error(error);
                    })
                    .on('meta', function (meta) {
                        // console.dir(meta);
                    })
                    .on('readable', function () {
                        var stream = this, item;
                        while (item = stream.read()) {
                            console.log('BBC', item.title);
                            bbcItems.push(item.title);
                            if (bbcItems.length >= 10) {
                                bbcRequest.abort();
                                completionCheck();
                            }
                        }
                    });
            });
            var skyRequest = http.get(self.skyFeedUrl, function (res) {
                res
                    .pipe(new FeedParser())
                    .on('error', function (error) {
                        console.error(error);
                    })
                    .on('meta', function (meta) {
                        // console.dir(meta);
                    })
                    .on('readable', function () {
                        var stream = this, item;
                        while (item = stream.read()) {
                            console.log('SKY', item.title);
                            skyItems.push(item.title);
                            if (skyItems.length >= 10) {
                                skyRequest.abort();
                                completionCheck();
                            }
                        }
                    });
            });
        } catch (exception) {
            res.statusCode = 500; // Internal Server Error
            res.end();
            return;
        }
    });
    self.server.listen(self.port, self.hostname, callback);
};<|endoftext|>


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

module.exports = {
  name: 'ui-slider',
  description: 'A flexible UI slider for ambitious Ember apps',
  included: function(app) {
    let parentApp = (typeof app.import !== 'function' && app.app) ? app.app : app;

    parentApp.import('bower_components/seiyria-bootstrap-slider/dist/bootstrap-slider.js');
    parentApp.import('bower_components/seiyria-bootstrap-slider/dist/css/bootstrap-slider.css');
    parentApp.import('vendor/ui-slider/ui-slider.css');
  }
};
<commit_msg>Add options to disable importing CSS<commit_after>/* jshint node: true */
'use strict';

var util = require('util');
var extend = util._extend;

var defaultOptions = {
  importBootstrapSliderCSS: true,
  importAddonCss: true
};

module.exports = {
  name: 'ui-slider',
  description: 'A flexible UI slider for ambitious Ember apps',
  included: function(app) {
    var parentApp = (typeof app.import !== 'function' && app.app) ? app.app : app;
    var options = extend(defaultOptions, app.options['ui-slider']);

    parentApp.import('bower_components/seiyria-bootstrap-slider/dist/bootstrap-slider.js');

    if (options.importBootstrapSliderCSS) {
      parentApp.import('bower_components/seiyria-bootstrap-slider/dist/css/bootstrap-slider.css');
    }
    if (options.importAddonCss) {
      parentApp.import('vendor/ui-slider/ui-slider.css');
    }
  }
};
<|endoftext|>


<commit_before>/**
 * This file contains the main functionality for the unsplash-api module
 *
 * @author Noah Dietz
 */

'use strict';

var request = require('request');
var path = require('path');

var HOST = 'https://api.unsplash.com/'
var client_id;

module.exports = {
  init: apiInit,
  getUserPhotos: getUserPhotos,
  getUserByName: getUserByName,
  getPhotos: getPhotos
};

/**
 * initiation function required to handle application client_id
 * @param  {string} client_id application's client_id
 */
function apiInit(client_id){
  this.client_id = client_id;
}

/**
 * gets photos of specified user
 * @param  {string}   userName username of target user
 * @param  {Function} callback callback called upon completion of API call
 * @return {object}            array of photos from specified user
 */
function getUserPhotos(userName, callback) {
  request({
    url: (HOST + path.join('users', userName, 'photos')),
    method: 'GET',
    headers: {
      'Content-type': 'application/json',
      'Authorization': 'Client-ID ' + this.client_id
    }
  },
  function(err, res, body){
    if (err) return callback(err);

    if (res.statusCode !== 200) return callback(JSON.parse(body), null);

    return callback(null, JSON.parse(body));
  });
}

/**
 * gets the public info of the specified user
 * @param  {string}   userName username of target user
 * @param  {Function} callback callback called upon completion of API call
 * @return {object}            specified user object
 */
function getUserByName(userName, callback) {
  request({
    url: (HOST + path.join('users', userName)),
    method: 'GET',
    headers: {
      'Content-type': 'application/json',
      'Authorization': 'Client-ID ' + this.client_id
    }
  },
  function(err, res, body) {
    if (err) return callback(err);

    if (res.statusCode !== 200) return callback(JSON.parse(body), null);

    return callback(null, JSON.parse(body));
  });
}

/**
 * gets a single page of photos from the list of all photos
 * @param  {int}      page     target page number
 * @param  {int}      perPage  number of photos returned per page
 * @param  {Function} callback callback called upon completion of API call
 * @return {object}            array of perPage amount of photos, and a
 *                             string of links for prev/next
 */
function getPhotos(page, perPage, callback) {
   var params = {};

   if (page != null)
      params.page = page;

   if (perPage != null)
      params.per_page = perPage;

   request({
      url: (HOST + path.join('photos')),
      method: 'GET',
      qs: params,
      headers: {
         'Content-type': 'application/json',
         'Authorization': 'Client-ID ' + this.client_id
      }
   },
   function(err, res, body){
      if (err) return callback(err);

      if (res.statusCode !== 200) return callback(JSON.parse(body), null);

      return callback(null, JSON.parse(body), res.headers.link);
   });
}
<commit_msg>add getAllCategories endpoint<commit_after>/**
 * This file contains the main functionality for the unsplash-api module
 *
 * @author Noah Dietz
 */

'use strict';

var request = require('request');
var path = require('path');

var HOST = 'https://api.unsplash.com/'
var client_id;

module.exports = {
  init: apiInit,
  getUserPhotos: getUserPhotos,
  getUserByName: getUserByName,
  getPhotos: getPhotos,
  getAllCategories: getAllCategories
};

/**
 * initiation function required to handle application client_id
 * @param  {string} client_id application's client_id
 */
function apiInit(client_id){
  this.client_id = client_id;
}

/**
 * gets photos of specified user
 * @param  {string}   userName username of target user
 * @param  {Function} callback callback called upon completion of API call
 * @return {object}            array of photos from specified user
 */
function getUserPhotos(userName, callback) {
  request({
    url: (HOST + path.join('users', userName, 'photos')),
    method: 'GET',
    headers: {
      'Content-type': 'application/json',
      'Authorization': 'Client-ID ' + this.client_id
    }
  },
  function(err, res, body){
    if (err) return callback(err);

    if (res.statusCode !== 200) return callback(new Error(body), null);

    return callback(null, JSON.parse(body));
  });
}

/**
 * gets the public info of the specified user
 * @param  {string}   userName username of target user
 * @param  {Function} callback callback called upon completion of API call
 * @return {object}            specified user object
 */
function getUserByName(userName, callback) {
  request({
    url: (HOST + path.join('users', userName)),
    method: 'GET',
    headers: {
      'Content-type': 'application/json',
      'Authorization': 'Client-ID ' + this.client_id
    }
  },
  function(err, res, body) {
    if (err) return callback(err);

    if (res.statusCode !== 200) return callback(new Error(body), null);

    return callback(null, JSON.parse(body));
  });
}

/**
 * gets all of the available photo categories
 * @param  {Function} callback called upon completion of API call
 * @return {array}            set of photo categories
 */
function getAllCategories(callback) {
  request({
    url: (HOST + 'categories'),
    method: 'GET',
    headers: {
      'Content-type': 'application/json',
      'Authorization': 'Client-ID ' + this.client_id
    }
  },
  function(err, res, body) {
    if (err) return callback(err);

    if (res.statusCode !== 200) return callback(new Error(body), null);

    return callback(null, JSON.parse(body));
  });
}

/**
 * gets a single page of photos from the list of all photos
 * @param  {int}      page     target page number
 * @param  {int}      perPage  number of photos returned per page
 * @param  {Function} callback callback called upon completion of API call
 * @return {object}            array of perPage amount of photos, and a
 *                             string of links for prev/next
 */
function getPhotos(page, perPage, callback) {
   var params = {};

   if (page != null)
      params.page = page;

   if (perPage != null)
      params.per_page = perPage;

   request({
      url: (HOST + path.join('photos')),
      method: 'GET',
      qs: params,
      headers: {
         'Content-type': 'application/json',
         'Authorization': 'Client-ID ' + this.client_id
      }
   },
   function(err, res, body){
      if (err) return callback(err);

      if (res.statusCode !== 200) return callback(JSON.parse(body), null);

      return callback(null, JSON.parse(body), res.headers.link);
   });
}
<|endoftext|>


<commit_before>var EventEmitter = require('events').EventEmitter,
    util = require("util"),
    ranks = require("./helpers/ranks"),
    protos = require("./helpers/protos"),
    protoMask = 0x80000000,
    bignumber = require("bignumber.js"),
    CSGO = exports;

require("./protos/messages");

var CSGOClient = function CSGOClient(steamUser, steamGC, debug) {
  EventEmitter.call(this);

  this.debug = debug || false;
  this._user = steamUser;
  this._gc = steamGC;
  this._appid = 730;
  this.chatChannels = []; // Map channel names to channel data.
  this._gcReady = false;
  this._gcClientHelloIntervalId = null;

  var self = this;
  this._gc.on('message', function(type, message, callback) {
    callback = callback || null;

    var kMsg = type.msg & ~protoMask;
    if (self.debug) {
      util.log("CS:GO fromGC: " + kMsg);  // TODO:  Turn type-protoMask into key name.
    }
    if (kMsg in self._handlers) {
      if (callback) {
        self._handlers[kMsg].call(self, message, callback);
      }
      else {
        self._handlers[kMsg].call(self, message);
      }
    }
    else {
      self.emit("unhandled", kMsg);
    }
  });

  this._gc._client.on('message', function(type, message, callback) {
    callback = callback || null;

    var kMsg = type.msg & ~protoMask;
    if (kMsg in self._handlers) {
      if (callback) {
        self._handlers[kMsg].call(self, message, callback);
      }
      else {
        self._handlers[kMsg].call(self, message);
      }
    }
    else {
      self.emit("unhandled_steam", kMsg);
    }
  });

  this._sendClientHello = function() {
    if (self.debug) {
      util.log("Sending ClientHello");
    }
    if (!self._gc) {
      util.log("GC went missing");
    }
    else if (!self._gc._client || !self._gc._client._connection) {
      util.log("GC Connection went missing, exiting");

      self._gcReady = false;

      if (self._gcClientHelloIntervalId) {
        clearInterval(self._gcClientHelloIntervalId);
        self._gcClientHelloIntervalId = null;
      }

      self.emit("unready");
    }
    else {
      self._gc.send({msg: CSGO.EGCBaseClientMsg.k_EMsgGCClientHello, proto: {}},
          new protos.CMsgClientHello({}).toBuffer());
    }
  };
};
util.inherits(CSGOClient, EventEmitter);

CSGOClient.prototype.ServerRegion = CSGO.ServerRegion;
CSGOClient.prototype.GameMode = CSGO.GameMode;

CSGOClient.prototype.ToAccountID = function(accid){
  return new bignumber(accid).minus('76561197960265728')-0;
};

CSGOClient.prototype.ToSteamID = function(accid){
  return new bignumber(accid).plus('76561197960265728')+"";
};

// Methods
CSGOClient.prototype.launch = function() {
  /* Reports to Steam that we are running Counter-Strike: Global Offensive. Initiates communication with GC with EMsgGCClientHello */
  if (this.debug) {
    util.log("Launching CS:GO");
  }

  this._user.gamesPlayed([{game_id: '730'}]);

  // Keep knocking on the GCs door until it accepts us.
  this._gcClientHelloIntervalId = setInterval(this._sendClientHello, 2500);
};

CSGOClient.prototype.exit = function() {
  /* Reports to Steam we are not running any apps. */
  if (this.debug) {
    util.log("Exiting CS:GO");
  }

  /* stop knocking if exit comes before ready event */
  if (this._gcClientHelloIntervalId) {
    clearInterval(this._gcClientHelloIntervalId);
    this._gcClientHelloIntervalId = null;
  }
  this._gcReady = false;
  this._user.gamesPlayed({
    games_played: [{}]
  });

  /* let everyone know we've exited */
  this.emit("exited");
};

// Handlers

var handlers = CSGOClient.prototype._handlers = {};

handlers[CSGO.EGCBaseClientMsg.k_EMsgGCClientWelcome] = function clientWelcomeHandler(message) {
  /* Response to our k_EMsgGCClientHello, now we can execute other GC commands. */

  // Only execute if _gcClientHelloIntervalID, otherwise it's already been handled (and we don't want to emit multiple 'ready');
  if (this._gcClientHelloIntervalId) {
    clearInterval(this._gcClientHelloIntervalId);
    this._gcClientHelloIntervalId = null;

    if (this.debug) {
      util.log("Received client welcome.");
    }
    this._gcReady = true;
    this.emit("ready");
  }
};

handlers[CSGO.EGCBaseClientMsg.k_EMsgGCClientConnectionStatus] = function gcClientConnectionStatus(message) {
  /* Catch and handle changes in connection status, cuz reasons u know. */

  var status = protos.CMsgConnectionStatus.decode(message).status;

  switch (status) {
    case CSGO.GCConnectionStatus.GCConnectionStatus_HAVE_SESSION:
      if (this.debug) {
        util.log("GC Connection Status regained.");
      }

      // Only execute if _gcClientHelloIntervalID, otherwise it's already been handled (and we don't want to emit multiple 'ready');
      if (this._gcClientHelloIntervalId) {
        clearInterval(this._gcClientHelloIntervalId);
        this._gcClientHelloIntervalId = null;

        this._gcReady = true;
        this.emit("ready");
      }
      break;

    default:
      if (this.debug) {
        util.log("GC Connection Status unreliable - " + status);
      }

      // Only execute if !_gcClientHelloIntervalID, otherwise it's already been handled (and we don't want to emit multiple 'unready');
      if (!this._gcClientHelloIntervalId) {
        this._gcClientHelloIntervalId = setInterval(this._sendClientHello, 2500); // Continually try regain GC session

        this._gcReady = false;
        this.emit("unready");
      }
      break;
  }
};

CSGOClient.prototype.Rank = ranks.Rank;
CSGOClient.prototype.Level = ranks.Level;

CSGO.CSGOClient = CSGOClient;
CSGO.SharecodeDecoder = require("./helpers/sharecode").SharecodeDecoder;

require("./handlers/match");
require("./handlers/player");
require("./handlers/rich_presence");
require("./handlers/items");
<commit_msg>Update gamesPlayed in `exit`<commit_after>var EventEmitter = require('events').EventEmitter,
    util = require("util"),
    ranks = require("./helpers/ranks"),
    protos = require("./helpers/protos"),
    protoMask = 0x80000000,
    bignumber = require("bignumber.js"),
    CSGO = exports;

require("./protos/messages");

var CSGOClient = function CSGOClient(steamUser, steamGC, debug) {
  EventEmitter.call(this);

  this.debug = debug || false;
  this._user = steamUser;
  this._gc = steamGC;
  this._appid = 730;
  this.chatChannels = []; // Map channel names to channel data.
  this._gcReady = false;
  this._gcClientHelloIntervalId = null;

  var self = this;
  this._gc.on('message', function(type, message, callback) {
    callback = callback || null;

    var kMsg = type.msg & ~protoMask;
    if (self.debug) {
      util.log("CS:GO fromGC: " + kMsg);  // TODO:  Turn type-protoMask into key name.
    }
    if (kMsg in self._handlers) {
      if (callback) {
        self._handlers[kMsg].call(self, message, callback);
      }
      else {
        self._handlers[kMsg].call(self, message);
      }
    }
    else {
      self.emit("unhandled", kMsg);
    }
  });

  this._gc._client.on('message', function(type, message, callback) {
    callback = callback || null;

    var kMsg = type.msg & ~protoMask;
    if (kMsg in self._handlers) {
      if (callback) {
        self._handlers[kMsg].call(self, message, callback);
      }
      else {
        self._handlers[kMsg].call(self, message);
      }
    }
    else {
      self.emit("unhandled_steam", kMsg);
    }
  });

  this._sendClientHello = function() {
    if (self.debug) {
      util.log("Sending ClientHello");
    }
    if (!self._gc) {
      util.log("GC went missing");
    }
    else if (!self._gc._client || !self._gc._client._connection) {
      util.log("GC Connection went missing, exiting");

      self._gcReady = false;

      if (self._gcClientHelloIntervalId) {
        clearInterval(self._gcClientHelloIntervalId);
        self._gcClientHelloIntervalId = null;
      }

      self.emit("unready");
    }
    else {
      self._gc.send({msg: CSGO.EGCBaseClientMsg.k_EMsgGCClientHello, proto: {}},
          new protos.CMsgClientHello({}).toBuffer());
    }
  };
};
util.inherits(CSGOClient, EventEmitter);

CSGOClient.prototype.ServerRegion = CSGO.ServerRegion;
CSGOClient.prototype.GameMode = CSGO.GameMode;

CSGOClient.prototype.ToAccountID = function(accid){
  return new bignumber(accid).minus('76561197960265728')-0;
};

CSGOClient.prototype.ToSteamID = function(accid){
  return new bignumber(accid).plus('76561197960265728')+"";
};

// Methods
CSGOClient.prototype.launch = function() {
  /* Reports to Steam that we are running Counter-Strike: Global Offensive. Initiates communication with GC with EMsgGCClientHello */
  if (this.debug) {
    util.log("Launching CS:GO");
  }

  this._user.gamesPlayed([{game_id: '730'}]);

  // Keep knocking on the GCs door until it accepts us.
  this._gcClientHelloIntervalId = setInterval(this._sendClientHello, 2500);
};

CSGOClient.prototype.exit = function() {
  /* Reports to Steam we are not running any apps. */
  if (this.debug) {
    util.log("Exiting CS:GO");
  }

  /* stop knocking if exit comes before ready event */
  if (this._gcClientHelloIntervalId) {
    clearInterval(this._gcClientHelloIntervalId);
    this._gcClientHelloIntervalId = null;
  }
  this._gcReady = false;
  this._user.gamesPlayed([]);

  /* let everyone know we've exited */
  this.emit("exited");
};

// Handlers

var handlers = CSGOClient.prototype._handlers = {};

handlers[CSGO.EGCBaseClientMsg.k_EMsgGCClientWelcome] = function clientWelcomeHandler(message) {
  /* Response to our k_EMsgGCClientHello, now we can execute other GC commands. */

  // Only execute if _gcClientHelloIntervalID, otherwise it's already been handled (and we don't want to emit multiple 'ready');
  if (this._gcClientHelloIntervalId) {
    clearInterval(this._gcClientHelloIntervalId);
    this._gcClientHelloIntervalId = null;

    if (this.debug) {
      util.log("Received client welcome.");
    }
    this._gcReady = true;
    this.emit("ready");
  }
};

handlers[CSGO.EGCBaseClientMsg.k_EMsgGCClientConnectionStatus] = function gcClientConnectionStatus(message) {
  /* Catch and handle changes in connection status, cuz reasons u know. */

  var status = protos.CMsgConnectionStatus.decode(message).status;

  switch (status) {
    case CSGO.GCConnectionStatus.GCConnectionStatus_HAVE_SESSION:
      if (this.debug) {
        util.log("GC Connection Status regained.");
      }

      // Only execute if _gcClientHelloIntervalID, otherwise it's already been handled (and we don't want to emit multiple 'ready');
      if (this._gcClientHelloIntervalId) {
        clearInterval(this._gcClientHelloIntervalId);
        this._gcClientHelloIntervalId = null;

        this._gcReady = true;
        this.emit("ready");
      }
      break;

    default:
      if (this.debug) {
        util.log("GC Connection Status unreliable - " + status);
      }

      // Only execute if !_gcClientHelloIntervalID, otherwise it's already been handled (and we don't want to emit multiple 'unready');
      if (!this._gcClientHelloIntervalId) {
        this._gcClientHelloIntervalId = setInterval(this._sendClientHello, 2500); // Continually try regain GC session

        this._gcReady = false;
        this.emit("unready");
      }
      break;
  }
};

CSGOClient.prototype.Rank = ranks.Rank;
CSGOClient.prototype.Level = ranks.Level;

CSGO.CSGOClient = CSGOClient;
CSGO.SharecodeDecoder = require("./helpers/sharecode").SharecodeDecoder;

require("./handlers/match");
require("./handlers/player");
require("./handlers/rich_presence");
require("./handlers/items");
<|endoftext|>


<commit_before>var cont     = require('cont')
var pull     = require('pull-stream')
var defer    = require('pull-defer')
var path     = require('path')
var explain  = require('explain-error')
var mkdirp   = require('mkdirp')
var rimraf   = require('rimraf')
var fs       = require('fs')
var glob     = require('pull-glob')
var paramap  = require('pull-paramap')
var cat      = require('pull-cat')
var Notify   = require('pull-notify')
var Live     = require('pull-live')
var Write    = require('pull-write-file')
var Read     = require('pull-file')

var u = require('./util')
var createHash = u.createHash

function toArray (h) {
  return Array.isArray(h) ? h : [h]
}

function getId (opts) {
  return opts.id || opts.key || opts.hash
}

function single (fn) {
  var waiting = {}
  function async (key, cb) {
    if(!waiting[key]) {
      waiting[key] = [cb]
      var cbs = waiting[key]
      fn(key, function done (err, result) {
        if(cbs.length)
        delete waiting[key]
        while(cbs.length) cbs.shift()(err, result)
      })
    }
    else
      waiting[key].push(cb)
  }

  //dump all the things that have been done already,
  //when something has been added?
  async.done = function (key, err, value) {
    if(!waiting[key]) return
    var cbs = waiting[key]
    delete waiting[key]
    while(cbs.length) cbs.shift()(err, result)
  }

  return async
}

var Blobs = module.exports = function (config) {
  var dir
  if('string' === typeof config)
    dir = config, config = {dir: dir}

  var encode = config.encode || u.encode
  var decode = config.decode || u.decode
  var isHash = config.isHash || u.isHash

  function toPath (dir, string) {
    if(!string || !isHash(string)) return false
    var d = decode(string)
    var h = d.hash.toString('hex')
    return path.join(dir, d.alg, h.substring(0,2), h.substring(2))
  }

  function toHash(filename) {
    var parts = path.relative(dir, filename).split(path.sep)
    var alg = parts.shift()
    return encode(new Buffer(parts.join(''), 'hex'), alg)
  }

  var newBlob = Notify()

  config = config || {}
  var alg = config.hash = config.hash || config.alg || 'blake2s'

  var empty = u.encode(u.algs[alg]().digest(), alg)

  function isEmptyHash(hash) {
    return empty === hash
  }

  dir = config.dir

  var n = 0
  var waiting = [], tmp = false, clean = false

  function init (cb) {
    if(tmp) return cb()
    else waiting.push(cb)
  }

  var stat = single(fs.stat)

  var tmpdir = path.join(dir, 'tmp')

  rimraf(tmpdir, function () {
    mkdirp(tmpdir, function () {
      tmp = true; while(waiting.length) waiting.shift()()
    })
  })

  function toMeta(hash, stat) {
    if(!stat) return null
    return {id: hash, size: stat.size, ts: +stat.ctime}
  }

  function has (id) {
    return function (cb) {
      if(isEmptyHash(id)) return cb(null, true)
      var p = toPath(dir, id)
      if(!p) return cb(new Error('not a valid blob id:'+id))
      stat(p, function (err, stat) {
        cb(null, !!stat)
      })
    }
  }

  function size (id) {
    return function (cb) {
      if(isEmptyHash(id)) return cb(null, 0)
      var p = toPath(dir, id)
      if(!p) return cb(new Error('not a valid blob id:'+id))
      stat(p, function (err, stat) {
        cb(null, stat ? stat.size : null)
      })
    }
  }

  var meta = function (id, cb) {
    if(isEmptyHash(id)) return cb(null, {id: id, size: 0, ts: 0})
    stat(toPath(dir, id), function (err, stat) {
      cb(err, toMeta(id, stat))
    })
  }

  function createTester (test) {
    return function (ids, cb) {
      var n = !Array.isArray(ids)
      //check if any hashes are invalid.
      var invalid
      if(n ? !isHash(ids) : !ids.every(function (h) {
        if(!isHash(h)) invalid = h
        else return true
      }))
        return cb(new Error('not a valid id:'+invalid))

      cont.para(toArray(ids).map(test)) (function (err, ary) {
        //will give an error if any hash was invalid.
        if(err) cb(err)
        // This will only error if the hash is not present,
        // so never callback an error.
        // PS. if you have a situation where you never error
        // add a comment like this one to explain why.
        else if(n) cb(null, ary[0])
        else       cb(null, ary)
      })
      return cb
    }
  }

  var listeners = []

  function getSlice(opts) {
    var id = getId(opts)

    if(isEmptyHash(id)) return pull.empty()

    var stream = defer.source()
    stat(toPath(dir, id), function (err, stat) {
      if(err)
        stream.abort(explain(err, 'stat failed'))

      else if(opts.size != null && opts.size !== stat.size)
        stream.abort(new Error('incorrect file length,'
          + ' requested:' + opts.size + ' file was:' + stat.size
          + ' for file:' + id
        ))

      else if(opts.max != null && opts.max < stat.size)
        stream.abort(new Error('incorrect file length,'
          + ' requested:' + opts.size + ' file was:' + stat.size
          + ' for file:' + id
        ))

      else
        stream.resolve(Read(toPath(dir, id), {
          start: opts.start,
          end: opts.end
        }))
    })

    return stream
  }

  return {
    get: function (opts) {
      if(isHash(opts)) {
        if(isEmptyHash(opts)) return pull.empty()
        return Read(toPath(dir, opts))
      }
      var id = getId(opts)

      if(!isHash(id))
        return pull.error(new Error(
          'multiblob.get: {id} is mandatory'
        ))

      return getSlice({id: id, size: opts.size, max: opts.max})
    },
    isEmptyHash: isEmptyHash,

    getSlice: function (opts) {
      var id = getId(opts)
      if(!isHash(id))
        return pull.error(new Error(
          'multiblob.getSlice: {id} is mandatory'
        ))

      if(isNaN(opts.start))
        return pull.error(new Error(
          'multiblob.getSlice: {start} must be a number'
        ))

      if(isNaN(opts.end))
        return pull.error(new Error(
          'multiblob.getSlice: {end} must be a number'
        ))

      return getSlice(opts)
    },

    size: createTester(size),

    has: createTester(has),
    meta: meta,

    add: function (id, cb) {
      if('function' === typeof id) cb = id, id = null

      if(!cb) cb = function (err) {
        if(err) throw explain(err, 'no callback provided')
      }

      if(id && !isHash(id)) {
        //abort input stream and callback once source is aborted.
        var err = new Error('not a valid hash:'+hash)
        return function (read) {
          read(err, cb)
        }
      }

      var deferred = defer.sink()
      init(function () {
        var tmpfile = path.join(dir, 'tmp', Date.now() + '-' + n++)
        var hasher = createHash(alg, true)
        var size = 0

        deferred.resolve(pull(
          hasher,
          pull.map(function (data) {
            if('string' === typeof data) data = new Buffer(data, 'utf8')
            size += data.length
            return data
          }),
          Write(tmpfile, function (err) {
            if(err) return cb(explain(err, 'could not write to tmpfile'))

            var _id = encode(hasher.digest, alg)

            if(id && id !== _id)
              return cb(new Error('actual hash:'+ _id
                + ' did not match expected id:'+id), _id)

            var p = toPath(dir, id || _id)

            mkdirp(path.dirname(p), function () {
              fs.rename(tmpfile, p, function (err) {
                if(err) cb(explain(err, 'could not move file'))
                else    newBlob({id:toHash(p), size: size, ts: Date.now()}), cb(null, _id)
              })
            })
          })
        ))
      })

      return deferred
    },

    ls: Live(function old (opts) {
      var long = (opts.size || opts.long || opts.meta)
      return pull(
        glob(path.join(dir, '*', '*', '*')),
        long ? paramap(function (filename, cb) {
          stat(filename, function (err, stat) {
            cb(err, toMeta(toHash(filename), stat))
          })
        }, 32) : pull.map(toHash)
      )
    }, function live (opts) {
      var long = (opts.size || opts.long || opts.meta)
      return long
          ? newBlob.listen()
          : pull(newBlob.listen(), pull.map(function (e) { return e.id }))
    }),

    rm: function (id, cb) {
      if(!isHash(id)) cb(new Error('not valid id:'+id))
      else              fs.unlink(toPath(dir, id), cb)
    },

    resolve: function (id) {
      if(!isHash(id)) throw new Error('not valid id:'+id)
      return toPath(dir, id)
    }
  }
}

<commit_msg>Tidy index.js<commit_after>var cont     = require('cont')
var pull     = require('pull-stream')
var defer    = require('pull-defer')
var path     = require('path')
var explain  = require('explain-error')
var mkdirp   = require('mkdirp')
var rimraf   = require('rimraf')
var fs       = require('fs')
var glob     = require('pull-glob')
var paramap  = require('pull-paramap')
var Notify   = require('pull-notify')
var Live     = require('pull-live')
var Write    = require('pull-write-file')
var Read     = require('pull-file')

var u = require('./util')
var createHash = u.createHash

function toArray (h) {
  return Array.isArray(h) ? h : [h]
}

function getId (opts) {
  return opts.id || opts.key || opts.hash
}

function single (fn) {
  var waiting = {}
  function async (key, cb) {
    if(!waiting[key]) {
      waiting[key] = [cb]
      var cbs = waiting[key]
      fn(key, function done (err, result) {
        if(cbs.length)
        delete waiting[key]
        while(cbs.length) cbs.shift()(err, result)
      })
    }
    else
      waiting[key].push(cb)
  }

  //dump all the things that have been done already,
  //when something has been added?
  async.done = function (key, err, value) {
    if(!waiting[key]) return
    var cbs = waiting[key]
    delete waiting[key]
    while(cbs.length) cbs.shift()(err, result)
  }

  return async
}

module.exports = function (config) {
  var dir
  if('string' === typeof config)
    dir = config, config = {dir: dir}

  var encode = config.encode || u.encode
  var decode = config.decode || u.decode
  var isHash = config.isHash || u.isHash

  function toPath (dir, string) {
    if(!string || !isHash(string)) return false
    var d = decode(string)
    var h = d.hash.toString('hex')
    return path.join(dir, d.alg, h.substring(0,2), h.substring(2))
  }

  function toHash(filename) {
    var parts = path.relative(dir, filename).split(path.sep)
    var alg = parts.shift()
    return encode(new Buffer(parts.join(''), 'hex'), alg)
  }

  var newBlob = Notify()

  config = config || {}
  var alg = config.hash = config.hash || config.alg || 'blake2s'

  var empty = u.encode(u.algs[alg]().digest(), alg)

  function isEmptyHash(hash) {
    return empty === hash
  }

  dir = config.dir

  var n = 0
  var waiting = []
  var tmp = false

  function init (cb) {
    if(tmp) return cb()
    else waiting.push(cb)
  }

  var stat = single(fs.stat)

  var tmpdir = path.join(dir, 'tmp')

  rimraf(tmpdir, function () {
    mkdirp(tmpdir, function () {
      tmp = true; while(waiting.length) waiting.shift()()
    })
  })

  function toMeta(hash, stat) {
    if(!stat) return null
    return {id: hash, size: stat.size, ts: +stat.ctime}
  }

  function has (id) {
    return function (cb) {
      if(isEmptyHash(id)) return cb(null, true)
      var p = toPath(dir, id)
      if(!p) return cb(new Error('not a valid blob id:'+id))
      stat(p, function (err, stat) {
        cb(null, !!stat)
      })
    }
  }

  function size (id) {
    return function (cb) {
      if(isEmptyHash(id)) return cb(null, 0)
      var p = toPath(dir, id)
      if(!p) return cb(new Error('not a valid blob id:'+id))
      stat(p, function (err, stat) {
        cb(null, stat ? stat.size : null)
      })
    }
  }

  var meta = function (id, cb) {
    if(isEmptyHash(id)) return cb(null, {id: id, size: 0, ts: 0})
    stat(toPath(dir, id), function (err, stat) {
      cb(err, toMeta(id, stat))
    })
  }

  function createTester (test) {
    return function (ids, cb) {
      var n = !Array.isArray(ids)
      //check if any hashes are invalid.
      var invalid
      if(n ? !isHash(ids) : !ids.every(function (h) {
        if(!isHash(h)) invalid = h
        else return true
      }))
        return cb(new Error('not a valid id:'+invalid))

      cont.para(toArray(ids).map(test)) (function (err, ary) {
        //will give an error if any hash was invalid.
        if(err) cb(err)
        // This will only error if the hash is not present,
        // so never callback an error.
        // PS. if you have a situation where you never error
        // add a comment like this one to explain why.
        else if(n) cb(null, ary[0])
        else       cb(null, ary)
      })
      return cb
    }
  }

  function getSlice(opts) {
    var id = getId(opts)

    if(isEmptyHash(id)) return pull.empty()

    var stream = defer.source()
    stat(toPath(dir, id), function (err, stat) {
      if(err)
        stream.abort(explain(err, 'stat failed'))

      else if(opts.size != null && opts.size !== stat.size)
        stream.abort(new Error('incorrect file length,'
          + ' requested:' + opts.size + ' file was:' + stat.size
          + ' for file:' + id
        ))

      else if(opts.max != null && opts.max < stat.size)
        stream.abort(new Error('incorrect file length,'
          + ' requested:' + opts.size + ' file was:' + stat.size
          + ' for file:' + id
        ))

      else
        stream.resolve(Read(toPath(dir, id), {
          start: opts.start,
          end: opts.end
        }))
    })

    return stream
  }

  return {
    get: function (opts) {
      if(isHash(opts)) {
        if(isEmptyHash(opts)) return pull.empty()
        return Read(toPath(dir, opts))
      }
      var id = getId(opts)

      if(!isHash(id))
        return pull.error(new Error(
          'multiblob.get: {id} is mandatory'
        ))

      return getSlice({id: id, size: opts.size, max: opts.max})
    },
    isEmptyHash: isEmptyHash,

    getSlice: function (opts) {
      var id = getId(opts)
      if(!isHash(id))
        return pull.error(new Error(
          'multiblob.getSlice: {id} is mandatory'
        ))

      if(isNaN(opts.start))
        return pull.error(new Error(
          'multiblob.getSlice: {start} must be a number'
        ))

      if(isNaN(opts.end))
        return pull.error(new Error(
          'multiblob.getSlice: {end} must be a number'
        ))

      return getSlice(opts)
    },

    size: createTester(size),

    has: createTester(has),
    meta: meta,

    add: function (id, cb) {
      if('function' === typeof id) cb = id, id = null

      if(!cb) cb = function (err) {
        if(err) throw explain(err, 'no callback provided')
      }

      if(id && !isHash(id)) {
        //abort input stream and callback once source is aborted.
        var err = new Error(`not a valid hash: ${id}`)
        return function (read) {
          read(err, cb)
        }
      }

      var deferred = defer.sink()
      init(function () {
        var tmpfile = path.join(dir, 'tmp', Date.now() + '-' + n++)
        var hasher = createHash(alg, true)
        var size = 0

        deferred.resolve(pull(
          hasher,
          pull.map(function (data) {
            if('string' === typeof data) data = new Buffer(data, 'utf8')
            size += data.length
            return data
          }),
          Write(tmpfile, function (err) {
            if(err) return cb(explain(err, 'could not write to tmpfile'))

            var _id = encode(hasher.digest, alg)

            if(id && id !== _id)
              return cb(new Error('actual hash:'+ _id
                + ' did not match expected id:'+id), _id)

            var p = toPath(dir, id || _id)

            mkdirp(path.dirname(p), function () {
              fs.rename(tmpfile, p, function (err) {
                if(err) cb(explain(err, 'could not move file'))
                else    newBlob({id:toHash(p), size: size, ts: Date.now()}), cb(null, _id)
              })
            })
          })
        ))
      })

      return deferred
    },

    ls: Live(function old (opts) {
      var long = (opts.size || opts.long || opts.meta)
      return pull(
        glob(path.join(dir, '*', '*', '*')),
        long ? paramap(function (filename, cb) {
          stat(filename, function (err, stat) {
            cb(err, toMeta(toHash(filename), stat))
          })
        }, 32) : pull.map(toHash)
      )
    }, function live (opts) {
      var long = (opts.size || opts.long || opts.meta)
      return long
          ? newBlob.listen()
          : pull(newBlob.listen(), pull.map(function (e) { return e.id }))
    }),

    rm: function (id, cb) {
      if(!isHash(id)) cb(new Error('not valid id:'+id))
      else              fs.unlink(toPath(dir, id), cb)
    },

    resolve: function (id) {
      if(!isHash(id)) throw new Error('not valid id:'+id)
      return toPath(dir, id)
    }
  }
}

<|endoftext|>


<commit_before>'use strict';

var request = require('request');
var cheerio = require('cheerio');

// CONFIG
var host = 'http://galeriakoloru.pl/dope-classic-spray-graffiti';
var lastId = 27;
var groupId = 4;
var langId = 1;

var getSite = function(url, cb){
  request(url, function(err, response, body) {
    try {
      cb(null, body);
    } catch (e) {
      cb(new Error('Error on response parsing for ' + url));
    }
  });
};

var output = [];
getSite(host, function(err, resp){
  var $ = cheerio.load(resp, {
    normalizeWhitespace: true
  });
  var color;
  var texturedColors = [];
  var colors = $('.colorbox');
  for (var i=0, l=colors.length; i<l; i++){
    color = $(colors[i]);
    output.push({
      name: color.find('span').html(),
      color: color.find('.color').css('background-color') ||
        (texturedColors.push(i), 0),
      id: ++lastId
    });
  }

  if (texturedColors.length > 0) {
    console.log('Warning');
    console.log('Colors ', texturedColors, ' are textures');
  }

  var position = 0;
  for (color in output) {
    console.log(
      'INSERT INTO `rabeko`.`dev_attribute` (`id_attribute`, ' +
      '`id_attribute_group`, `color`, `position`) VALUES (\'' +
      output[color].id +'\', \'' + groupId + '\', \'' + output[color].color +
      '\', \'' + (position++) + '\');'
    );

    console.log(
      'INSERT INTO `rabeko`.`dev_attribute_lang` (`id_attribute`, `id_lang`, ' +
      '`name`) VALUES (\'' + output[color].id +'\', \'' + langId + '\', \'' +
      output[color].name + '\');'
    );
  }
});
<commit_msg>:blowfish: change html in description to dash<commit_after>'use strict';

var request = require('request');
var cheerio = require('cheerio');

// CONFIG
var host = 'http://galeriakoloru.pl/dope-classic-spray-graffiti';
var lastId = 27;
var groupId = 4;
var langId = 1;

var getSite = function(url, cb){
  request(url, function(err, response, body) {
    try {
      cb(null, body);
    } catch (e) {
      cb(new Error('Error on response parsing for ' + url));
    }
  });
};

var output = [];
getSite(host, function(err, resp){
  var $ = cheerio.load(resp, {
    normalizeWhitespace: true
  });
  var color;
  var texturedColors = [];
  var colors = $('.colorbox');
  for (var i=0, l=colors.length; i<l; i++){
    color = $(colors[i]);
    output.push({
      name: color.find('span').html().replace('<br>', ' - '),
      color: color.find('.color').css('background-color') ||
        (texturedColors.push(i), 0),
      id: ++lastId
    });
  }

  if (texturedColors.length > 0) {
    console.log('Warning');
    console.log('Colors ', texturedColors, ' are textures');
  }

  var position = 0;
  for (color in output) {
    console.log(
      'INSERT INTO `rabeko`.`dev_attribute` (`id_attribute`, ' +
      '`id_attribute_group`, `color`, `position`) VALUES (\'' +
      output[color].id +'\', \'' + groupId + '\', \'' + output[color].color +
      '\', \'' + (position++) + '\');'
    );

    console.log(
      'INSERT INTO `rabeko`.`dev_attribute_lang` (`id_attribute`, `id_lang`, ' +
      '`name`) VALUES (\'' + output[color].id +'\', \'' + langId + '\', \'' +
      output[color].name + '\');'
    );
  }
});
<|endoftext|>


<commit_before>/* jshint node: true */
'use strict';
var BasePlugin = require('ember-cli-deploy-plugin');

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

  createDeployPlugin: function(options) {
    var DeployPlugin = BasePlugin.extend({
      name: options.name,

      didBuild: function(context) {
        //do something amazing here once the project has been built
      },

      upload: function(context) {
        var client = require('firebase-tools');
        let outer = this;
        return client.deploy({cwd:'.'}).then(function() {
          outer.log('it worked yay');
        }).catch(function(err) {
          // handle error
          outer.log('something bad happened oh no');
          outer.log(err);
        });
      },

      didDeploy: function(context) {
        //do something here like notify your team on slack
      }
    });

    return new DeployPlugin();
  }
};
<commit_msg>let firebase work out what directory it's in<commit_after>/* jshint node: true */
'use strict';
var BasePlugin = require('ember-cli-deploy-plugin');

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

  createDeployPlugin: function(options) {
    var DeployPlugin = BasePlugin.extend({
      name: options.name,

      didBuild: function(context) {
        //do something amazing here once the project has been built
      },

      upload: function(context) {
        var client = require('firebase-tools');
        let outer = this;
        return client.deploy({}).then(function() {
          outer.log('it worked yay');
        }).catch(function(err) {
          // handle error
          outer.log('something bad happened oh no');
          outer.log(err);
        });
      },

      didDeploy: function(context) {
        //do something here like notify your team on slack
      }
    });

    return new DeployPlugin();
  }
};
<|endoftext|>