<commit_before>"use strict";

require('buffertools');

var assert = require('assert'),
    constants = require('./lib/constants.js'),
    crypto = require('crypto'),
    events = require('events'),
    util = require('util');

var KBucket = module.exports = function KBucket (options) {
    var self = this;
    options = options || {};
    events.EventEmitter.call(self);

    // the bucket array has least-recently-contacted at the "front/left" side
    // and the most-recently-contaced at the "back/right" side
    self.bucket = [];
    self.localNodeId = options.localNodeId || crypto.createHash('sha1').digest();
    if (!(self.localNodeId instanceof Buffer)) {
        self.localNodeId = new Buffer(self.localNodeId);
    }

    // V8 hints
    self.dontSplit = null;
    self.low = null;
    self.high = null;
};

util.inherits(KBucket, events.EventEmitter);

// contact: *required* the contact object to add
// bitIndex: the bitIndex to which bit to check in the Buffer for navigating
//           the binary tree
KBucket.prototype.add = function add (contact, bitIndex) {
    var self = this;

    // first check whether we are an inner node or a leaf (with bucket contents)
    if (!self.bucket) {
        // this is not a leaf node but an inner node with 'low' and 'high'
        // branches; we will check the appropriate bit of the identifier and
        // delegate to the appropriate node for further processing
        bitIndex = bitIndex || 0;

        if (self.determineBucket(contact.id, bitIndex++) < 0) {
            return self.low.add(contact, bitIndex);
        } else {
            return self.high.add(contact, bitIndex);
        }
    }

    // check if the contact already exists
    var index = self.indexOf(contact);
    if (index >= 0) {
        self.update(contact, index);
        return self;
    }

    if (self.bucket.length >= constants.DEFAULT_NUMBER_OF_NODES_PER_K_BUCKET) {
        return self.splitAndAdd(contact, bitIndex);
    }

    self.bucket.push(contact);

    return self;
};

// Determines whether the id at the bitIndex is 0 or 1. If 0, returns -1, else 1
// id: a Buffer to compare localNodeId with
// bitIndex: the bitIndex to which bit to check in the id Buffer
KBucket.prototype.determineBucket = function determineBucket (id, bitIndex) {
    var self = this;

    bitIndex = bitIndex || 0;

    // **NOTE** remember that id is a Buffer and has granularity of
    // bytes (8 bits), whereas the bitIndex is the _bit_ index (not byte)

    // id's that are too short are put in low bucket (1 byte = 8 bits)
    // parseInt(bitIndex / 8) finds how many bytes the bitIndex describes
    // bitIndex % 8 checks if we have extra bits beyond byte multiples
    // if number of bytes is <= no. of bytes described by bitIndex and there
    // are extra bits to consider, this means id has less bits than what
    // bitIndex describes, id therefore is too short, and will be put in low
    // bucket
    var bytesDescribedByBitIndex = parseInt(bitIndex / 8);
    var bitIndexWithinByte = bitIndex % 8;
    if ((id.length <= bytesDescribedByBitIndex)
        && (bitIndexWithinByte != 0)) return -1;

    var byteUnderConsideration = id[bytesDescribedByBitIndex];

    // byteUnderConsideration is an integer from 0 to 255 represented by 8 bits
    // where 255 is 11111111 and 0 is 00000000
    // in order to find out whether the bit at bitIndexWithinByte is set
    // we construct Math.pow(2, (7 - bitIndexWithinByte)) which will consist
    // of all bits being 0, with only one bit set to 1
    // for example, if bitIndexWithinByte is 3, we will construct 00010000 by
    // Math.pow(2, (7 - 3)) -> Math.pow(2, 4) -> 16
    if (byteUnderConsideration & Math.pow(2, (7 - bitIndexWithinByte))) {
        return 1;
    }

    return -1;
};

// Returns the index of the contact if it exists
// **NOTE**: indexOf() does not compare vectorClock
KBucket.prototype.indexOf = function indexOf (contact) {
    var self = this;
    for (var i = 0; i < self.bucket.length; i++) {
        if (self.bucket[i].id.equals(contact.id)) return i;
    }
    return -1;
};

// Splits the bucket, redistributes contacts to the new buckets, and marks the
// bucket that was split as an inner node of the binary tree of buckets by
// setting self.bucket = undefined;
// contact: *required* the contact object to add
// bitIndex: the bitIndex to which byte to check in the Buffer for navigating the
//          binary tree
KBucket.prototype.splitAndAdd = function splitAndAdd (contact, bitIndex) {
    var self = this;
    self.low = new KBucket({localNodeId: self.localNodeId});
    self.high = new KBucket({localNodeId: self.localNodeId});

    bitIndex = bitIndex || 0;

    // redistribute existing contacts amongst the two newly created buckets
    self.bucket.forEach(function (storedContact) {
        if (self.determineBucket(storedContact.id, bitIndex) < 0) {
            self.low.add(storedContact);
        } else {
            self.high.add(storedContact);
        }
    });

    self.bucket = undefined; // mark as inner tree node

    // don't split the "far away" bucket
    // we check where the local node would end up and mark the other one as
    // "dontSplit" (i.e. "far away")
    if (self.determineBucket(self.localNodeId, bitIndex) < 0) {
        // local node belongs to "low" bucket, so mark the other one
        self.high.dontSplit = true;
    } else {
        self.low.dontSplit = true;
    }

    // add the contact being added
    self.add(contact, bitIndex);

    return self;
};

// Updates the contact by comparing vector clocks.
// If new contact vector clock is deprecated, contact is abandoned (not added).
// If new contact vector clock is the same, contact is marked as most recently
// contacted (by being moved to the right/end of the bucket array).
// If new contact vector clock is more recent, the old contact is removed and
// the new contact is marked as most recently contacted.
// contact: *required* the contact to update
// index: *required* the index in the bucket where contact exists
//        (index has already been computed in a previous calculation)
KBucket.prototype.update = function update (contact, index) {
    var self = this;
    // sanity check
    assert.ok(self.bucket[index].id.equals(contact.id),
        "indexOf() calculation resulted in wrong index");
    if (self.bucket[index].vectorClock > contact.vectorClock) return;
    self.bucket.push(self.bucket.splice(index, 1)[0]);
    self.bucket[self.bucket.length - 1].vectorClock = contact.vectorClock;
};<commit_msg>refactored add()<commit_after>"use strict";

require('buffertools');

var assert = require('assert'),
    constants = require('./lib/constants.js'),
    crypto = require('crypto'),
    events = require('events'),
    util = require('util');

var KBucket = module.exports = function KBucket (options) {
    var self = this;
    options = options || {};
    events.EventEmitter.call(self);

    // the bucket array has least-recently-contacted at the "front/left" side
    // and the most-recently-contaced at the "back/right" side
    self.bucket = [];
    self.localNodeId = options.localNodeId || crypto.createHash('sha1').digest();
    if (!(self.localNodeId instanceof Buffer)) {
        self.localNodeId = new Buffer(self.localNodeId);
    }

    // V8 hints
    self.dontSplit = null;
    self.low = null;
    self.high = null;
};

util.inherits(KBucket, events.EventEmitter);

// contact: *required* the contact object to add
// bitIndex: the bitIndex to which bit to check in the Buffer for navigating
//           the binary tree
KBucket.prototype.add = function add (contact, bitIndex) {
    var self = this;

    // first check whether we are an inner node or a leaf (with bucket contents)
    if (!self.bucket) {
        // this is not a leaf node but an inner node with 'low' and 'high'
        // branches; we will check the appropriate bit of the identifier and
        // delegate to the appropriate node for further processing
        bitIndex = bitIndex || 0;

        if (self.determineBucket(contact.id, bitIndex++) < 0) {
            return self.low.add(contact, bitIndex);
        } else {
            return self.high.add(contact, bitIndex);
        }
    }

    // check if the contact already exists
    var index = self.indexOf(contact);
    if (index >= 0) {
        self.update(contact, index);
        return self;
    }

    if (self.bucket.length < constants.DEFAULT_NUMBER_OF_NODES_PER_K_BUCKET) {
        self.bucket.push(contact);
        return self;
    }

    return self.splitAndAdd(contact, bitIndex);
};

// Determines whether the id at the bitIndex is 0 or 1. If 0, returns -1, else 1
// id: a Buffer to compare localNodeId with
// bitIndex: the bitIndex to which bit to check in the id Buffer
KBucket.prototype.determineBucket = function determineBucket (id, bitIndex) {
    var self = this;

    bitIndex = bitIndex || 0;

    // **NOTE** remember that id is a Buffer and has granularity of
    // bytes (8 bits), whereas the bitIndex is the _bit_ index (not byte)

    // id's that are too short are put in low bucket (1 byte = 8 bits)
    // parseInt(bitIndex / 8) finds how many bytes the bitIndex describes
    // bitIndex % 8 checks if we have extra bits beyond byte multiples
    // if number of bytes is <= no. of bytes described by bitIndex and there
    // are extra bits to consider, this means id has less bits than what
    // bitIndex describes, id therefore is too short, and will be put in low
    // bucket
    var bytesDescribedByBitIndex = parseInt(bitIndex / 8);
    var bitIndexWithinByte = bitIndex % 8;
    if ((id.length <= bytesDescribedByBitIndex)
        && (bitIndexWithinByte != 0)) return -1;

    var byteUnderConsideration = id[bytesDescribedByBitIndex];

    // byteUnderConsideration is an integer from 0 to 255 represented by 8 bits
    // where 255 is 11111111 and 0 is 00000000
    // in order to find out whether the bit at bitIndexWithinByte is set
    // we construct Math.pow(2, (7 - bitIndexWithinByte)) which will consist
    // of all bits being 0, with only one bit set to 1
    // for example, if bitIndexWithinByte is 3, we will construct 00010000 by
    // Math.pow(2, (7 - 3)) -> Math.pow(2, 4) -> 16
    if (byteUnderConsideration & Math.pow(2, (7 - bitIndexWithinByte))) {
        return 1;
    }

    return -1;
};

// Returns the index of the contact if it exists
// **NOTE**: indexOf() does not compare vectorClock
KBucket.prototype.indexOf = function indexOf (contact) {
    var self = this;
    for (var i = 0; i < self.bucket.length; i++) {
        if (self.bucket[i].id.equals(contact.id)) return i;
    }
    return -1;
};

// Splits the bucket, redistributes contacts to the new buckets, and marks the
// bucket that was split as an inner node of the binary tree of buckets by
// setting self.bucket = undefined;
// contact: *required* the contact object to add
// bitIndex: the bitIndex to which byte to check in the Buffer for navigating the
//          binary tree
KBucket.prototype.splitAndAdd = function splitAndAdd (contact, bitIndex) {
    var self = this;
    self.low = new KBucket({localNodeId: self.localNodeId});
    self.high = new KBucket({localNodeId: self.localNodeId});

    bitIndex = bitIndex || 0;

    // redistribute existing contacts amongst the two newly created buckets
    self.bucket.forEach(function (storedContact) {
        if (self.determineBucket(storedContact.id, bitIndex) < 0) {
            self.low.add(storedContact);
        } else {
            self.high.add(storedContact);
        }
    });

    self.bucket = undefined; // mark as inner tree node

    // don't split the "far away" bucket
    // we check where the local node would end up and mark the other one as
    // "dontSplit" (i.e. "far away")
    if (self.determineBucket(self.localNodeId, bitIndex) < 0) {
        // local node belongs to "low" bucket, so mark the other one
        self.high.dontSplit = true;
    } else {
        self.low.dontSplit = true;
    }

    // add the contact being added
    self.add(contact, bitIndex);

    return self;
};

// Updates the contact by comparing vector clocks.
// If new contact vector clock is deprecated, contact is abandoned (not added).
// If new contact vector clock is the same, contact is marked as most recently
// contacted (by being moved to the right/end of the bucket array).
// If new contact vector clock is more recent, the old contact is removed and
// the new contact is marked as most recently contacted.
// contact: *required* the contact to update
// index: *required* the index in the bucket where contact exists
//        (index has already been computed in a previous calculation)
KBucket.prototype.update = function update (contact, index) {
    var self = this;
    // sanity check
    assert.ok(self.bucket[index].id.equals(contact.id),
        "indexOf() calculation resulted in wrong index");
    if (self.bucket[index].vectorClock > contact.vectorClock) return;
    self.bucket.push(self.bucket.splice(index, 1)[0]);
    self.bucket[self.bucket.length - 1].vectorClock = contact.vectorClock;
};<|endoftext|>


<commit_before>var fs = require('fs');
var mysql = require('mysql');
var express = require('express');
var nodemailer = require('nodemailer');
var bodyParser = require('body-parser');
var expressBrute = require('express-brute');

var config = JSON.parse(fs.readFileSync('config.json', 'UTF-8'));
var transporter = nodemailer.createTransport(config.mail.transport);

var con = mysql.createConnection(config.db);
con.connect();

//con.query('SELECT 1 + 1 AS solution', function(err, rows, fields) {
//    if (err)
//	throw err;
//
//    console.log('The solution is: ', rows[0].solution);
//});
//
//con.end();

var bruteStore = new expressBrute.MemoryStore();
var bruteProtect = new expressBrute(bruteStore, {
    freeRetries: 2,
    minWait: 30*60*1000,
    maxWait: 60*60*1000
});

var app = express();
app.use(bodyParser.json());

app.get('/v1/course', function(req, res) {
    var courses = [
	{
	    id: 512,
	    name: "Example Course",
	    count: 1
	}
    ];

    //TODO: retrieve courses from db
    con.query('SELECT c.id, c.name, COUNT(*) AS count FROM course AS c LEFT JOIN exam AS e ON c.id = e.courseID GROUP BY c.id, c.name', function(err, rows, fields) {
	if (err)
	    return console.log(err);

	console.log(rows);
    });

    res
	.set('Content-Type', 'text/json')
	.send(JSON.stringify(courses))
	.status(200)
	.end();
});

app.get('/v1/course/:id', function(req, res) {
    var id = req.params.id;

    // verify that id is actually a positive integer
    if (!id.match(/[1-9][0-9]*/))
	res.status(400).end();

    var course = {
	id: id,
	name: "Example Course",
	documents: [
	    {
		id: 111,
		type: "Klausur",
		date: "2000-03-21",
		lecturer: "Example Lecturer"
	    }
	]
    };

    //TODO: retrieve course from db
    con.query('SELECT id, name FROM course WHERE id = ?', [id], function(err, rows, fields) {
	if (err)
	    return console.log(err);

	con.query('SELECT e.id, t.name, date, l.name '
		+ 'FROM exam AS e '
		+ 'JOIN type AS t ON t.id = e.typeID '
		+ 'JOIN lecturer AS l ON l.id = e.lecturerID '
		+ 'WHERE e.courseID = ?', [id], function(err, rows, fields) {
	    if (err)
		return console.log(err);

	    console.log(rows);
	});

	console.log(rows);
    });

    if (!course)
	res.status(404).end();
    else
	res
	    .set('Content-Type', 'text/json')
	    .send(JSON.stringify(course))
	    .status(200)
	    .end();
});

app.post('/v1/order', bruteProtect.prevent, function(req, res) {
    console.log(req.body);

    //TODO: validate body
    //TODO: send mail

    transporter.sendMail({
	from: config.mail.sender,
	to: config.mail.recipient,
	subject: '',
	text: ''
    }, function(err, info) {
	if (err)
	    return console.log(err);

	console.log('Message sent: ' + info.response);
    });

    res.status(201).end();
});

app.listen(config.port, function() {
    console.log('Magic happens on port ' + config.port);
});
<commit_msg>add database support<commit_after>var fs = require('fs');
var mysql = require('mysql');
var express = require('express');
var nodemailer = require('nodemailer');
var bodyParser = require('body-parser');
var expressBrute = require('express-brute');

var config = JSON.parse(fs.readFileSync('config.json', 'UTF-8'));
var transporter = nodemailer.createTransport(config.mail.transport);

var con = mysql.createConnection(config.db);
con.connect();

//con.query('SELECT 1 + 1 AS solution', function(err, rows, fields) {
//    if (err)
//	throw err;
//
//    console.log('The solution is: ', rows[0].solution);
//});
//
//con.end();

var bruteStore = new expressBrute.MemoryStore();
var bruteProtect = new expressBrute(bruteStore, {
    freeRetries: 2,
    minWait: 30*60*1000,
    maxWait: 60*60*1000
});

var app = express();
app.use(bodyParser.json());

app.get('/v1/course', function(req, res) {
    var courses = [];

    con.query('SELECT c.id, c.name, COUNT(*) AS count FROM course AS c LEFT JOIN exam AS e ON c.id = e.courseID GROUP BY c.id, c.name', function(err, rows, fields) {
	if (err)
	    return console.log(err);

	rows.forEach(function(row) {
	    courses.push({
		id: row.id,
		name: row.name,
		count: row.count
	    });
	});
    });

    res
	.set('Content-Type', 'text/json')
	.send(JSON.stringify(courses))
	.status(200)
	.end();
});

app.get('/v1/course/:id', function(req, res) {
    var id = req.params.id;

    // verify that id is actually a positive integer
    if (!id.match(/[1-9][0-9]*/))
	res.status(400).end();

    con.query('SELECT id, name FROM course WHERE id = ?', [id], function(err, rows, fields) {
	if (err)
	    return res.status(500).end();

	if (!rows || !(rows.length > 0))
	    return res.status(404).end();

	var course = {
	    id: rows[0].id,
	    name: rows[0].name,
	    documents: []
	};

	con.query('SELECT e.id, t.name, date, l.name '
		+ 'FROM exam AS e '
		+ 'JOIN type AS t ON t.id = e.typeID '
		+ 'JOIN lecturer AS l ON l.id = e.lecturerID '
		+ 'WHERE e.courseID = ?', [id], function(err, rows, fields) {
	    if (err)
		return res.status(500).end();

	    rows.forEach(function(row) {
		course.documents.push({
		    id: row.id,
		    type: row.type,
		    date: row.date,
		    lecturer: row.lecturer
		});
	    });

	    res
		.set('Content-Type', 'text/json')
		.send(JSON.stringify(course))
		.status(200)
		.end();
	});
    });
});

app.post('/v1/order', bruteProtect.prevent, function(req, res) {
    console.log(req.body);

    //TODO: validate body
    //TODO: send mail

    transporter.sendMail({
	from: config.mail.sender,
	to: config.mail.recipient,
	subject: '',
	text: ''
    }, function(err, info) {
	if (err)
	    return console.log(err);

	console.log('Message sent: ' + info.response);
    });

    res.status(201).end();
});

app.listen(config.port, function() {
    console.log('Magic happens on port ' + config.port);
});
<|endoftext|>


<commit_before>// based on @ericvicenti's approach for ssh-keygen

var spawn = require('child_process').spawn
  , _     = require('underscore')
  , fs    = require('fs')
  , os    = require('os')
  , path  = require('path')
  , util  = require('util')
  ;

exports.x509_keygen = function(options, callback) {
  options = options || {};
  if (_.isUndefined(options.read))    options.read    = true;
  if (_.isUndefined(options.force))   options.force   = true;
  if (_.isUndefined(options.destroy)) options.destroy = true;
  if (_.isUndefined(options.logger)) {
    options.logger = { error   : function(msg, props) { console.log(msg); if (!!props) console.trace(props.exception); }
                     , warning : function(msg, props) { console.log(msg); if (!!props) console.log(props);             }
                     , notice  : function(msg, props) { console.log(msg); if (!!props) console.log(props);             }
                     , info    : function(msg, props) { console.log(msg); if (!!props) console.log(props);             }
                     , debug   : function(msg, props) { console.log(msg); if (!!props) console.log(props);             }
                     };
  }

  if (_.isUndefined(options.subject)) return callback(new Error('options must include subject'));

  options.location = options.location || path.join(os.tmpDir(), 'server_rsa');
  options.keyfile  = options.keyfile  || options.location + '.key';
  options.certfile = options.certfile || options.location + '.cert';

  fs.exists(options.keyfile, function(keyP) {
    if ((!options.force) && keyP)    return callback(new Error(options.keyfile  + ' already exists'));

    fs.exists(options.certfile, function(certP) {
      if ((!options.force) && certP) return callback(new Error(options.certfile + ' already exists'));

      if ((!keyP) && (!certP)) return middle(options, callback);

      if (keyP) {
        fs.unlink(options.keyfile, function(err) {
          if (err) return callback(err);
          keyP = false;

          if ((!keyP) && (!certP)) return middle(options, callback);
        });
      }

      if (certP) {
        fs.unlink(options.certfile, function(err) {
          if (err) return callback(err);
            certP = false;

            if ((!keyP) && (!certP)) return middle(options, callback);
        });
      }
    });
  });
};

var middle = function(options, callback) {
  var config, i, ifaddrs, iface, ifaces, hostname, s;

  if (!!options.configfile) return inner(options, callback);

  if (!options.alternates || !util.isArray(options.alternates)) {
    options.alternates =  [ 'DNS:localhost' ];
    hostname = os.hostname();
    options.alternates.push('DNS:' + ((hostname.indexOf('.') != -1) ? hostname : (hostname + '.local')));

    ifaces = os.networkInterfaces();
    for (iface in ifaces) if (ifaces.hasOwnProperty(iface)) {
      ifaddrs = ifaces[iface];
      for (i = 0; i < ifaddrs.length; i++) if (ifaddrs[i].family === 'IPv4') options.alternates.push('IP:'+ifaddrs[i].address);
    }
  }
  config = '[ req ]\ndistinguished_name = dn_req\nx509_extensions = v3_req\n\n[ dn_req ]\n\n[ v3_req ]\nsubjectAltName="';
  for (i = 0, s = ''; i < options.alternates.length; i++, s = ',') config += s + options.alternates[i];
  config += '"\n';

  options.configfile = options.location + '.conf';
  fs.writeFile (options.configfile, config, { mode: 0644 }, function(err) {
    if (err) return callback(err);

    inner(options, function(err, results) {
      fs.unlink(options.configfile);
      callback(err, results);
    });
  });
};

var inner = function(options, callback) {
  var args, keygen;

  args =  [ 'req',     '-x509'
          , '-newkey', 'rsa:2048'
          , '-days',   '3650'
          , '-nodes'
          , '-subj',   options.subject
          , '-keyout', options.keyfile
          , '-out',    options.certfile
          ];
  if (!!options.configfile) args.push('-config', options.configfile);

  keygen = spawn('openssl', args);

  keygen.stdout.on('data', function(a){
    options.logger.info(a);
  });
  keygen.stderr.on('data',function(a){
    options.logger.debug('openssl: ' + a);
  });

  keygen.on('exit', function() {
    var readcert = function(key) {
      fs.readFile(options.certfile, 'utf8', function(err, cert) {
        if (!options.destroy) return callback(null, { key: key, cert: cert });

        fs.unlink(options.certfile, function(err){
          if(err) return callback(err);

           return callback(null, { key: key, cert: cert });
        });
      });
    };

    if(!options.read) return callback(null, {});

    fs.readFile(options.keyfile, 'utf8', function(err, key) {
      if (!options.destroy) return readcert(key);

      fs.unlink(options.keyfile, function(err){
        if(err) return callback(err);

        readcert(key);
      });
    });
  });
};
<commit_msg>fix silly spacing<commit_after>// based on @ericvicenti's approach for ssh-keygen

var spawn = require('child_process').spawn
  , _     = require('underscore')
  , fs    = require('fs')
  , os    = require('os')
  , path  = require('path')
  , util  = require('util')
  ;

exports.x509_keygen = function(options, callback) {
  options = options || {};
  if (_.isUndefined(options.read))    options.read    = true;
  if (_.isUndefined(options.force))   options.force   = true;
  if (_.isUndefined(options.destroy)) options.destroy = true;
  if (_.isUndefined(options.logger)) {
    options.logger = { error   : function(msg, props) { console.log(msg); if (!!props) console.trace(props.exception); }
                     , warning : function(msg, props) { console.log(msg); if (!!props) console.log(props);             }
                     , notice  : function(msg, props) { console.log(msg); if (!!props) console.log(props);             }
                     , info    : function(msg, props) { console.log(msg); if (!!props) console.log(props);             }
                     , debug   : function(msg, props) { console.log(msg); if (!!props) console.log(props);             }
                     };
  }

  if (_.isUndefined(options.subject)) return callback(new Error('options must include subject'));

  options.location = options.location || path.join(os.tmpDir(), 'server_rsa');
  options.keyfile  = options.keyfile  || options.location + '.key';
  options.certfile = options.certfile || options.location + '.cert';

  fs.exists(options.keyfile, function(keyP) {
    if ((!options.force) && keyP)    return callback(new Error(options.keyfile  + ' already exists'));

    fs.exists(options.certfile, function(certP) {
      if ((!options.force) && certP) return callback(new Error(options.certfile + ' already exists'));

      if ((!keyP) && (!certP)) return middle(options, callback);

      if (keyP) {
        fs.unlink(options.keyfile, function(err) {
          if (err) return callback(err);
          keyP = false;

          if ((!keyP) && (!certP)) return middle(options, callback);
        });
      }

      if (certP) {
        fs.unlink(options.certfile, function(err) {
          if (err) return callback(err);
          certP = false;

          if ((!keyP) && (!certP)) return middle(options, callback);
        });
      }
    });
  });
};

var middle = function(options, callback) {
  var config, i, ifaddrs, iface, ifaces, hostname, s;

  if (!!options.configfile) return inner(options, callback);

  if (!options.alternates || !util.isArray(options.alternates)) {
    options.alternates =  [ 'DNS:localhost' ];
    hostname = os.hostname();
    options.alternates.push('DNS:' + ((hostname.indexOf('.') != -1) ? hostname : (hostname + '.local')));

    ifaces = os.networkInterfaces();
    for (iface in ifaces) if (ifaces.hasOwnProperty(iface)) {
      ifaddrs = ifaces[iface];
      for (i = 0; i < ifaddrs.length; i++) if (ifaddrs[i].family === 'IPv4') options.alternates.push('IP:'+ifaddrs[i].address);
    }
  }
  config = '[ req ]\ndistinguished_name = dn_req\nx509_extensions = v3_req\n\n[ dn_req ]\n\n[ v3_req ]\nsubjectAltName="';
  for (i = 0, s = ''; i < options.alternates.length; i++, s = ',') config += s + options.alternates[i];
  config += '"\n';

  options.configfile = options.location + '.conf';
  fs.writeFile (options.configfile, config, { mode: 0644 }, function(err) {
    if (err) return callback(err);

    inner(options, function(err, results) {
      fs.unlink(options.configfile);
      callback(err, results);
    });
  });
};

var inner = function(options, callback) {
  var args, keygen;

  args =  [ 'req',     '-x509'
          , '-newkey', 'rsa:2048'
          , '-days',   '3650'
          , '-nodes'
          , '-subj',   options.subject
          , '-keyout', options.keyfile
          , '-out',    options.certfile
          ];
  if (!!options.configfile) args.push('-config', options.configfile);

  keygen = spawn('openssl', args);

  keygen.stdout.on('data', function(a){
    options.logger.info(a);
  });
  keygen.stderr.on('data',function(a){
    options.logger.debug('openssl: ' + a);
  });

  keygen.on('exit', function() {
    var readcert = function(key) {
      fs.readFile(options.certfile, 'utf8', function(err, cert) {
        if (!options.destroy) return callback(null, { key: key, cert: cert });

        fs.unlink(options.certfile, function(err){
          if (err) return callback(err);

          return callback(null, { key: key, cert: cert });
        });
      });
    };

    if(!options.read) return callback(null, {});

    fs.readFile(options.keyfile, 'utf8', function(err, key) {
      if (!options.destroy) return readcert(key);

      fs.unlink(options.keyfile, function(err){
        if (err) return callback(err);

        readcert(key);
      });
    });
  });
};
<|endoftext|>


<commit_before>var EventEmitter = require("events").EventEmitter
var Router = require("routes")
var extend = require("xtend/mutable")
var document = require("global/document")
var window = require("global/window")

initRouter()

module.exports = HTML5Router

function HTML5Router(opts) {
    opts = opts || {}
    var getState = opts.getState || defaultGetState
    var pushState = opts.pushState || defaultPushState
    var replaceState = opts.replaceState || defaultReplaceState

    var router = Router()

    onState.getState = getState
    onState.pushState = pushState
    onState.replaceState = replaceState
    onState.addRoute = router.addRoute.bind(router)

    extend(onState, EventEmitter.prototype)
    EventEmitter.call(onState)

    return onState

    function onState(state) {
        state = state || getState()

        var route = router.match(state.url)
        if (route) {
            route.fn(state.url, {
                params: route.params,
                splats: route.splats,
                title: state.title,
                data: state.data
            })
        }

        onState.emit("route", state)
    }
}

function defaultPushState(state) {
    window.history.pushState(state.data, state.title, state.url)
}

function defaultReplaceState(state) {
    window.history.replaceState(state.data, state.title, state.url)
}

function defaultGetState(ev) {
    return {
        data: ev ? ev.state : {},
        title: document.title,
        url: String(document.location)
    }
}

function initRouter() {
    extend(HTML5Router, EventEmitter.prototype)
    EventEmitter.call(HTML5Router)

    window.addEventListener("popstate", function (ev) {
        HTML5Router.emit("popstate", defaultGetState(ev))
    })
}
<commit_msg>getState() should only return the pathname in the url.<commit_after>var EventEmitter = require("events").EventEmitter
var Router = require("routes")
var extend = require("xtend/mutable")
var document = require("global/document")
var window = require("global/window")

initRouter()

module.exports = HTML5Router

function HTML5Router(opts) {
    opts = opts || {}
    var getState = opts.getState || defaultGetState
    var pushState = opts.pushState || defaultPushState
    var replaceState = opts.replaceState || defaultReplaceState

    var router = Router()

    onState.getState = getState
    onState.pushState = pushState
    onState.replaceState = replaceState
    onState.addRoute = router.addRoute.bind(router)

    extend(onState, EventEmitter.prototype)
    EventEmitter.call(onState)

    return onState

    function onState(state) {
        state = state || getState()

        var route = router.match(state.url)
        if (route) {
            route.fn(state.url, {
                params: route.params,
                splats: route.splats,
                title: state.title,
                data: state.data
            })
        }

        onState.emit("route", state)
    }
}

function defaultPushState(state) {
    window.history.pushState(state.data, state.title, state.url)
}

function defaultReplaceState(state) {
    window.history.replaceState(state.data, state.title, state.url)
}

function defaultGetState(ev) {
    return {
        data: ev ? ev.state : {},
        title: document.title,
        url: document.location.pathname
    }
}

function initRouter() {
    extend(HTML5Router, EventEmitter.prototype)
    EventEmitter.call(HTML5Router)

    window.addEventListener("popstate", function (ev) {
        HTML5Router.emit("popstate", defaultGetState(ev))
    })
}
<|endoftext|>


<commit_before>'use strict';

/* TODO
 *   write log module to write and print
 *   add countdown timer
 */
var http    = require('http')
  , fs      = require('fs')
  , log     = console.log
  , PORT    = 6060
  , express = require('express')
  , app     = express()
  , util    = require('util');

/*
 * use ejs to serve static files
 */
app.engine('html', require('ejs').renderFile);
app.set('view engine', 'html');
app.use(express.static(__dirname + '/'));

/*
 * get git log file
 * TODO seperate this into a module
 */
var fs = require('fs');
var gitText = {};
fs.readFile('./views/gitlog.txt', 'utf8', function (error, data) {
    if (! error) gitText = { 'content': data };
});

/*
 * HTTP request routers
 */
app.get('/', function (req, res, next) {
    logConnection(req);
    next();
}, function (req, res, next) {
	res.render('index.ejs', {
        focus: 'HOME',
        subject: 'hello'
    });
});
app.get('/projects', function (req, res, next) {
    logConnection(req);
    next();
}, function (req, res, next) {
	res.render('projects.ejs', {
        focus: 'PROJECTS',
        subject: 'my projects'
    });
});
app.get('/about', function (req, res, next) {
    logConnection(req);
    next();
}, function (req, res, next) {
	res.render('about.ejs', {
        focus: 'ABOUT',
        subject: 'about me'
    });
});
app.get('/contact', function (req, res, next) {
    logConnection(req);
    next();
}, function (req, res, next) {
	res.render('contact.ejs', {
        focus: 'CONTACT',
        subject: 'get in contact'
    });
});
app.get('/robots.txt', function (req, res) {
    logConnection(req);
    res.type('text/plain');
    res.send('#011000100110010101100101011100000010'
    + '00000110001001101111011011110111000000100001'
    + '\nUser-agent: *\nDisallow: /');
});
app.get('/getGitLog', function (req, res) {
    res.send(gitText);
    logConnection(req);
});

/*
 * listen on port 6060 (rerouted from 80)
 */
app.listen(PORT, function () {
	console.log('facer listening on port', PORT);
});

function logConnection(req) {
    var info = util.format('[%s]: %s,\t%s,\t%s',
      new Date(), req.method, req.ip, req.path);
    info += '\n';
    fs.appendFile('logs/connect.log', info, function (error) {
        if (error) throw new Error(("Error writing to file: " + error));
    });
}

/*
 * restart server on file change
 */
var forever = require('forever-monitor');
var child = new (forever.Monitor)('facer.js', {
	max: 3,
	silent: true,
	args: []
});
child.on('exit', function () {
	log('server.js has exited after 3 restart');
}).on('watch:restart', function (info) {
	log('restarting server because "%s" changed', info.file);
}).on('restart', function () {
	log('restarting server for %s time', child.times);
});

<commit_msg>Convert page subjects to mixed case<commit_after>'use strict';

/* TODO
 *   write log module to write and print
 *   add countdown timer
 */
var http    = require('http')
  , fs      = require('fs')
  , log     = console.log
  , PORT    = 6060
  , express = require('express')
  , app     = express()
  , util    = require('util');

/*
 * use ejs to serve static files
 */
app.engine('html', require('ejs').renderFile);
app.set('view engine', 'html');
app.use(express.static(__dirname + '/'));

/*
 * get git log file
 * TODO seperate this into a module
 */
var fs = require('fs');
var gitText = {};
fs.readFile('./views/gitlog.txt', 'utf8', function (error, data) {
    if (! error) gitText = { 'content': data };
});

/*
 * HTTP request routers
 */
app.get('/', function (req, res, next) {
    logConnection(req);
    next();
}, function (req, res, next) {
	res.render('index.ejs', {
        focus: 'HOME',
        subject: 'Hello'
    });
});
app.get('/projects', function (req, res, next) {
    logConnection(req);
    next();
}, function (req, res, next) {
	res.render('projects.ejs', {
        focus: 'PROJECTS',
        subject: 'My Projects'
    });
});
app.get('/about', function (req, res, next) {
    logConnection(req);
    next();
}, function (req, res, next) {
	res.render('about.ejs', {
        focus: 'ABOUT',
        subject: 'About Me'
    });
});
app.get('/contact', function (req, res, next) {
    logConnection(req);
    next();
}, function (req, res, next) {
	res.render('contact.ejs', {
        focus: 'CONTACT',
        subject: 'Get in Contact'
    });
});
app.get('/robots.txt', function (req, res) {
    logConnection(req);
    res.type('text/plain');
    res.send('#011000100110010101100101011100000010'
    + '00000110001001101111011011110111000000100001'
    + '\nUser-agent: *\nDisallow: /');
});
app.get('/getGitLog', function (req, res) {
    res.send(gitText);
    logConnection(req);
});

/*
 * listen on port 6060 (rerouted from 80)
 */
app.listen(PORT, function () {
	console.log('facer listening on port', PORT);
});

function logConnection(req) {
    var info = util.format('[%s]: %s,\t%s,\t%s',
      new Date(), req.method, req.ip, req.path);
    info += '\n';
    fs.appendFile('logs/connect.log', info, function (error) {
        if (error) throw new Error(("Error writing to file: " + error));
    });
}

/*
 * restart server on file change
 */
var forever = require('forever-monitor');
var child = new (forever.Monitor)('facer.js', {
	max: 3,
	silent: true,
	args: []
});
child.on('exit', function () {
	log('server.js has exited after 3 restart');
}).on('watch:restart', function (info) {
	log('restarting server because "%s" changed', info.file);
}).on('restart', function () {
	log('restarting server for %s time', child.times);
});

<|endoftext|>


<commit_before>const firebase = require('firebase')
const config = require('./config')

firebase.initializeApp(config);

var ref = firebase.database().ref().child("room1")
var Gpio = require('onoff').Gpio;
var led = new Gpio(17, 'out');

ref.on('value', function (data) {
    if (data.val().Light == "1") {
        console.log('led on :-)')
        // led.writeSync(1);
        var iv = setInterval(function(){
            led.writeSync(led.readSync() === 0 ? 1 : 0)
        }, 800)
        // var iv = setInterval(function(){
        //     led.writeSync(led.readSync() === 0 ? 1 : 0)
        // }, 100);
    } else {
        console.log('led off')
        led.writeSync(0);
    }
})
<commit_msg>update project<commit_after>const firebase = require('firebase')
const config = require('./config')

firebase.initializeApp(config);

var ref = firebase.database().ref().child("room1")
var Gpio = require('onoff').Gpio;
var led = new Gpio(17, 'out');

ref.on('value', function (data) {
    if (data.val().Light == "1") {
        console.log('led on :-)')
        led.writeSync(1);
        // var iv = setInterval(function(){
        //     led.writeSync(led.readSync() === 0 ? 1 : 0)
        // }, 800)
        // var iv = setInterval(function(){
        //     led.writeSync(led.readSync() === 0 ? 1 : 0)
        // }, 100);
    } else {
        console.log('led off')
        led.writeSync(0);
    }
})
<|endoftext|>


<commit_before>'use strict'
var cont = require('cont')
var pull = require('pull-stream')
var PullCont = require('pull-cont')
var path = require('path')
var Obv = require('obv')
var explain = require('explain-error')
var Looper = require('pull-looper')
var paramap = require('pull-paramap')

//take a log, and return a log driver.
//the log has an api with `read`, `get` `since`

var wrap = require('./wrap')

function map(obj, iter) {
  var o = {}
  for(var k in obj)
    o[k] = iter(obj[k], k, obj)
  return o
}

function asyncify () {
  return function (read) {
    return function (abort, cb) {
      setImmediate(function () {
        read(abort, cb)
      })
    }
  }
}

module.exports = function (log, isReady, mapper) {

  var views = []
  var meta = {}

  log.get = count(log.get, 'get')

  function count (fn, name) {
    meta[name] = meta[name] || 0
    return function (a, b) {
      meta[name] ++
      fn.call(this, a, b)
    }
  }

  var hasNoValues = (opts, data) => {
    /* It seems to me that we should have a way of verifying when *only* seqs
     * are being passed, sometimes it looks like `opts.values` is `true` while
     * `typeof data === number`. I'm not sure why this is, but it gives me the
     * impression that there's a more elegant way to check for this.
     */
    return !opts.values || 'number' === typeof data
  }

  var getValues = (hasSeqs, data) => {
    if (hasSeqs) {
      return data.value
    } else {
      return data
    }
  }

  var setValue = (hasSeqs, data, result) => {
    if (hasSeqs) {
      data.value = result
    } else {
      data = result
    }
    return data
  }

  var mapStream = (opts) => {
    var hasSeqs = !!opts.seqs
    return paramap((data, cb) => {
      var err = null

      if (hasNoValues(hasSeqs, data))
        return cb(err, data)

      mapper(getValues(hasSeqs, data), (res) => {
        cb(err, setValue(hasSeqs, data, res))
      })
    })
  }

  var ready = Obv()
  ready.set(isReady !== undefined ? isReady : true)
  var flume = {
    closed: false,
    dir: log.filename ? path.dirname(log.filename) : null,
    //stream from the log
    since: log.since,
    ready: ready,
    meta: meta,
    append: function (value, cb) {
      return log.append(value, cb)
    },
    use: function (name, createView) {
      if(~Object.keys(flume).indexOf(name))
        throw new Error(name + ' is already in use!')

      var sv = createView(log, name)

      views[name] = flume[name] = wrap(sv, log.since, ready)
      meta[name] = flume[name].meta
      sv.since.once(function build (upto) {
        log.since.once(function (since) {
          if(upto > since) {
            sv.destroy(function () { build(-1) })
          } else {
            var opts = {gt: upto, live: true, seqs: true, values: true}
            if (upto == -1)
              opts.cache = false
            pull(
              log.stream(opts),
              Looper,
              sv.createSink(function (err) {
                if(!flume.closed) {
                  if(err)
                    console.error(explain(err, 'view stream error'))
                  sv.since.once(build)
                }
              })
            )
          }
        })
      })

      return flume
    },
    rebuild: function (cb) {
      return cont.para(map(views, function (sv) {
        return function (cb) {
          sv.destroy(function (err) {
            if(err) return cb(err)
            //destroy should close the sink stream,
            //which will restart the write.
            var rm = sv.since(function (v) {
              if(v === log.since.value) {
                rm()
                cb()
              }
            })
          })
        }
      }))
      (function (err) {
        if(err) cb(err) //hopefully never happens

        //then restream each streamview, and callback when it's uptodate with the main log.
      })
    },
    close: function (cb) {
      if(flume.closed) return cb()
      flume.closed = true
      cont.para(map(views, function (sv, k) {
        return function (cb) {
          if(sv.close) sv.close(cb)
          else cb()
        }
      })) (cb)

    }
  }

  // XXX: doesn't seem very DRY, but it's more performant to check this now
  // rather than waiting until runtime to figure out whether `mapper` exists
  if (mapper) {
    flume.get = function (seq, cb) {
      log.since.once(() => {
        log.get(seq, (err, value) => {
          mapper(value, (res) => {
            cb(err, res)
          })
        })
      })
    }
    flume.stream = function (opts) {
      return PullCont((cb) => {
        log.since.once(() => {
          cb(null, pull(
            log.stream(opts),
            mapStream(opts),
            Looper
          ))
        })
      })
    }
  } else {
    flume.get = function (seq, cb) {
      log.since.once(function () {
        log.get(seq, cb)
      })
    }
    flume.stream = function (opts) {
      return PullCont(function (cb) {
        log.since.once(function () {
          cb(null, pull(log.stream(opts), Looper))
        })
      })
    }
  }
  return flume
}

<commit_msg>Refactor `mapStream` utility functions to share `opts`<commit_after>'use strict'
var cont = require('cont')
var pull = require('pull-stream')
var PullCont = require('pull-cont')
var path = require('path')
var Obv = require('obv')
var explain = require('explain-error')
var Looper = require('pull-looper')
var paramap = require('pull-paramap')

//take a log, and return a log driver.
//the log has an api with `read`, `get` `since`

var wrap = require('./wrap')

function map(obj, iter) {
  var o = {}
  for(var k in obj)
    o[k] = iter(obj[k], k, obj)
  return o
}

function asyncify () {
  return function (read) {
    return function (abort, cb) {
      setImmediate(function () {
        read(abort, cb)
      })
    }
  }
}

module.exports = function (log, isReady, mapper) {

  var views = []
  var meta = {}

  log.get = count(log.get, 'get')

  function count (fn, name) {
    meta[name] = meta[name] || 0
    return function (a, b) {
      meta[name] ++
      fn.call(this, a, b)
    }
  }

  var mapStream = (opts) => {
    var hasSeqs = !!opts.seqs
    var hasNoValues = (data) => {
      // XXX: Is this right? Sometimes `opts.value === true` but `data` is still
      // a number rather than an object. Not sure how to handle this best.
      return !opts.values || 'number' === typeof data
    }
    var getValue
    var setValue

    if (opts.seqs) {
      getValue = (data) => data.value
      setValue = (data, value) => {
        data.value = value
        return data
      }
    } else {
      getValue = (data) => data
      setValue = (data, value) => value
    }

    return paramap((data, cb) => {
      var err = null

      if (hasNoValues(data))
        return cb(err, data)

      mapper(getValue(data), (value) => {
        cb(err, setValue(data, value))
      })
    })
  }

  var ready = Obv()
  ready.set(isReady !== undefined ? isReady : true)
  var flume = {
    closed: false,
    dir: log.filename ? path.dirname(log.filename) : null,
    //stream from the log
    since: log.since,
    ready: ready,
    meta: meta,
    append: function (value, cb) {
      return log.append(value, cb)
    },
    use: function (name, createView) {
      if(~Object.keys(flume).indexOf(name))
        throw new Error(name + ' is already in use!')

      var sv = createView(log, name)

      views[name] = flume[name] = wrap(sv, log.since, ready)
      meta[name] = flume[name].meta
      sv.since.once(function build (upto) {
        log.since.once(function (since) {
          if(upto > since) {
            sv.destroy(function () { build(-1) })
          } else {
            var opts = {gt: upto, live: true, seqs: true, values: true}
            if (upto == -1)
              opts.cache = false
            pull(
              log.stream(opts),
              Looper,
              sv.createSink(function (err) {
                if(!flume.closed) {
                  if(err)
                    console.error(explain(err, 'view stream error'))
                  sv.since.once(build)
                }
              })
            )
          }
        })
      })

      return flume
    },
    rebuild: function (cb) {
      return cont.para(map(views, function (sv) {
        return function (cb) {
          sv.destroy(function (err) {
            if(err) return cb(err)
            //destroy should close the sink stream,
            //which will restart the write.
            var rm = sv.since(function (v) {
              if(v === log.since.value) {
                rm()
                cb()
              }
            })
          })
        }
      }))
      (function (err) {
        if(err) cb(err) //hopefully never happens

        //then restream each streamview, and callback when it's uptodate with the main log.
      })
    },
    close: function (cb) {
      if(flume.closed) return cb()
      flume.closed = true
      cont.para(map(views, function (sv, k) {
        return function (cb) {
          if(sv.close) sv.close(cb)
          else cb()
        }
      })) (cb)

    }
  }

  // XXX: doesn't seem very DRY, but it's more performant to check this now
  // rather than waiting until runtime to figure out whether `mapper` exists
  if (mapper) {
    flume.get = function (seq, cb) {
      log.since.once(() => {
        log.get(seq, (err, value) => {
          mapper(value, (res) => {
            cb(err, res)
          })
        })
      })
    }
    flume.stream = function (opts) {
      return PullCont((cb) => {
        log.since.once(() => {
          cb(null, pull(
            log.stream(opts),
            mapStream(opts),
            Looper
          ))
        })
      })
    }
  } else {
    flume.get = function (seq, cb) {
      log.since.once(function () {
        log.get(seq, cb)
      })
    }
    flume.stream = function (opts) {
      return PullCont(function (cb) {
        log.since.once(function () {
          cb(null, pull(log.stream(opts), Looper))
        })
      })
    }
  }
  return flume
}

<|endoftext|>


<commit_before>var
  rs = require('readable-stream'),
  plugin,
  slash = {fwd: '/', back: '\\'},
  util = require('util');

module.exports = plugin = pathmodify;

/**
 * Main plugin.
 */
function pathmodify (b, opts) {
  // Temporarily allow people to continue using this by calling it as a factory
  // function, even though they should be mindful of semver.
  if (! arguments.length) {
    return util.deprecate(
      pathmodify,
      "Deprecated: pathmodify: Don't call the export as a factory. The export is now the plugin function."
    );
  }
  opts = opts || {};

  opts = {mods: opts.mods};

  // Map resolved pathnames to expose IDs.
  opts.mappings = {};

  // Record of already processed require() ID's, keyed on parent filename.
  opts.visited = {};

  opts.bify = b;

  opts.expose = function expose (key, val) {
    b._expose[key] = val;
    opts.pack.hasExports = true;
  };
  // expose

  opts.custom_resolver = make_resolver(opts);

  b.on('reset', function () {
    init(opts);
  });
  init(opts);
}
// pathmodify

/**
 * Common logic between initial setup and bundle reset.
 */
function init (opts) {
  var
    b = opts.bify,
    deps = b.pipeline.get('deps');

  // TODO `0` needs to be changed to a label.
  opts.pack = b.pipeline.get('pack').get(0);

  // TODO Should probably make sure this ends up directly after module-deps.
  deps.push(aliaser({mappings: opts.mappings}));

  // TODO `0` needs to be changed to a label.
  deps = deps.get(0);
  opts.deps = deps;

  opts.resolver = deps.resolver;
  deps.resolver = opts.custom_resolver;
}
// init

/**
 * Make a custom resolve function to override module-deps resolver.
 */
function make_resolver (opts) {
  var
    expose = opts.expose,
    modifiers = Array.isArray(opts.mods) ? opts.mods : [],
    mappings = opts.mappings,
    visited = opts.visited,
    bify = opts.bify;

  // These change at reset: resolve
  function current (prop) {
    return opts[prop];
  }
  // current

  return alias_resolver;

  /**
   * Custom resolve function. Same signature as node-resolve and
   * node-browser-resolve.
   */
  function alias_resolver (id, opts, cb) {
    var
      rec = {id: id, opts: {filename: opts.filename}},
      resolver = current('resolver'),
      mappings = current('mappings'),
      visited = current('visited'),
      par_vis = visited[opts.filename] || {},
      // boolean Whether the id has already been processed.
      processed;

    visited[opts.filename] = par_vis;

    // Retrieve any existing record for this id for this parent.
    processed = par_vis[rec.id];

    // Process modifiers for this module if it hasn't previously been processed.
    rec = processed || modify(rec);

    processed = !! processed;

    // Assign processed record to the records for its parent.
    if (! processed) par_vis[rec.id] = rec;

    // Calling walk() is the alternative to pushing the pipeline step (as
    // above). Currently unused. Would look like this:

    /*
      // Aliased, exposed, and not previously visited.
      if (
        ! processed &&
        rec.alias.expose
      ) {
        return opts.deps.walk({
          id: rec.alias.expose || rec.id,
          file: rec.id,
        }, opts, cb);
      }
    */

    // Delegate to original resolver.
    return resolver(rec.alias.id || rec.id, opts, function (err, res, pkg) {
      if (! err) {
        if (rec.alias.expose) {
          mappings[res] = rec.alias.expose;
          expose(rec.alias.expose, res);
        }
        bify.emit('pathmodify:resolved', {
          rec: rec,
          file: res,
        });
      }
      cb(err, res, pkg);
    });
  }
  // alias_resolver

  /**
   * Process exposure configuration.
   */
  function set_expose (rec, alias, modifier) {
    if (typeof modifier.expose === 'string') {
      alias.expose = modifier.expose;
    }
    else if (typeof modifier.expose === 'function') {
      alias.expose = modifier.expose(rec, alias);
    }

    if (modifier.expose === true || alias.expose === true) {
      alias.expose = rec.id;
    }

    return alias;
  }
  // set_expose

  /**
   * Process a modification that's a function or where the replacement is a
   * function.
   */
  function alias_with_func (mod, rec, opts) {
    var ret = {}, opts = opts || {};
    ret.alias = (typeof mod === 'function' ? mod : mod.to).call(mod, rec, opts);
    ret.matched = !! (ret.alias && ret.alias.id !== rec.id);
    return ret;
  }
  // alias_with_func

  /**
   * Apply modifiers configured by the user.
   */
  function modify (rec) {
    var
      // Switch for terminating looping over the modifiers once a match is
      // found.
      matched,
      // Restore this in the end in case the user modifies it.
      id = rec.id,
      alias,
      temp = {},
      path_sep;

    // Heuristically detect path separator.
    [slash.fwd, slash.back, slash.fwd].every(function (sep) {
      path_sep = sep;
      return rec.id.indexOf(path_sep) === -1;
    });

    modifiers.every(function (modifier) {
      matched = true;

      // Reset so modifiers can't munge data for later ones.
      rec.id = id;
      alias = {};

      if (
        (
          modifier.type === 'dir' &&
          rec.id.indexOf(modifier.from + path_sep) === 0
        )

        ||

        (modifier.type === 'id' && rec.id === modifier.from)
      ) {
        if (typeof modifier.to === 'function') {
          temp = alias_with_func(modifier, rec);
          alias = temp.alias;
          matched = temp.matched;
        }
        else {
          alias.id = modifier.to + rec.id.substr(modifier.from.length);
        }
      }

      else if (typeof modifier === 'function') {
        temp = alias_with_func(modifier, rec);
        alias = temp.alias;
        matched = temp.matched;
      }

      else if (
        modifier.type === 're' &&
        (matched = modifier.from[
          typeof modifier.to === 'function' ? 'exec' : 'test'
        ](rec.id))
      ) {
        if (typeof modifier.to === 'function') {
          temp = alias_with_func(modifier, rec, {matches: matched});
          alias = temp.alias;
          matched = temp.matched;
        }
        else {
          alias.id = rec.id.replace(modifier.from, modifier.to);
        }
      }

      else matched = false;

      if (matched) set_expose(rec, alias, modifier);

      return ! matched;
    });

    rec.id = id;
    if (! (alias && alias.id)) alias = {};
    rec.alias = alias;

    return rec;
  }
  // modify
}
// make_resolver

/**
 * Following module-deps, update record id's to reflect exposure configuration.
 */
function aliaser (opts) {
  opts = opts || {};
  var
    stream = new rs.Transform({objectMode: true}),
    mappings = opts.mappings;

  stream._transform = write;

  function write (rec, enc, cb) {
    // User exposed this file under an alternate id.
    if (mappings[rec.file]) {
      rec.id = mappings[rec.file];
    }

    this.push(rec);
    cb();
  }
  // write

  stream.label = "pathmodify:deps:post";

  return stream;
}
// aliaser

function simple (from, to, expose, type) {
  return {from: from, to: to, expose: expose, type: type};
}
// simple

// Functions for generating entries in opts.mods.
plugin.mod = {};

[
  ['id'],
  ['dir'],
  ['re'],
].forEach(function (type_def) {
  var
    type = type_def[0],
    aliases = type_def[1];

  plugin.mod[type] = function (from, to, expose) {
    return simple(from, to, expose, type);
  };

  if (Array.isArray(aliases)) {
    aliases.forEach(function (alias) {
      plugin.mod[alias] = plugin.mod[type];
    });
  }
});
<commit_msg>Copy opts.mods on instantiation.<commit_after>var
  rs = require('readable-stream'),
  plugin,
  slash = {fwd: '/', back: '\\'},
  util = require('util');

module.exports = plugin = pathmodify;

/**
 * Main plugin.
 */
function pathmodify (b, opts) {
  // Temporarily allow people to continue using this by calling it as a factory
  // function, even though they should be mindful of semver.
  if (! arguments.length) {
    return util.deprecate(
      pathmodify,
      "Deprecated: pathmodify: Don't call the export as a factory. The export is now the plugin function."
    );
  }
  opts = opts || {};

  opts = {mods: [].concat(opts.mods || [])};

  // Map resolved pathnames to expose IDs.
  opts.mappings = {};

  // Record of already processed require() ID's, keyed on parent filename.
  opts.visited = {};

  opts.bify = b;

  opts.expose = function expose (key, val) {
    b._expose[key] = val;
    opts.pack.hasExports = true;
  };
  // expose

  opts.custom_resolver = make_resolver(opts);

  b.on('reset', function () {
    init(opts);
  });
  init(opts);
}
// pathmodify

/**
 * Common logic between initial setup and bundle reset.
 */
function init (opts) {
  var
    b = opts.bify,
    deps = b.pipeline.get('deps');

  // TODO `0` needs to be changed to a label.
  opts.pack = b.pipeline.get('pack').get(0);

  // TODO Should probably make sure this ends up directly after module-deps.
  deps.push(aliaser({mappings: opts.mappings}));

  // TODO `0` needs to be changed to a label.
  deps = deps.get(0);
  opts.deps = deps;

  opts.resolver = deps.resolver;
  deps.resolver = opts.custom_resolver;
}
// init

/**
 * Make a custom resolve function to override module-deps resolver.
 */
function make_resolver (opts) {
  var
    expose = opts.expose,
    modifiers = Array.isArray(opts.mods) ? opts.mods : [],
    mappings = opts.mappings,
    visited = opts.visited,
    bify = opts.bify;

  // These change at reset: resolve
  function current (prop) {
    return opts[prop];
  }
  // current

  return alias_resolver;

  /**
   * Custom resolve function. Same signature as node-resolve and
   * node-browser-resolve.
   */
  function alias_resolver (id, opts, cb) {
    var
      rec = {id: id, opts: {filename: opts.filename}},
      resolver = current('resolver'),
      mappings = current('mappings'),
      visited = current('visited'),
      par_vis = visited[opts.filename] || {},
      // boolean Whether the id has already been processed.
      processed;

    visited[opts.filename] = par_vis;

    // Retrieve any existing record for this id for this parent.
    processed = par_vis[rec.id];

    // Process modifiers for this module if it hasn't previously been processed.
    rec = processed || modify(rec);

    processed = !! processed;

    // Assign processed record to the records for its parent.
    if (! processed) par_vis[rec.id] = rec;

    // Calling walk() is the alternative to pushing the pipeline step (as
    // above). Currently unused. Would look like this:

    /*
      // Aliased, exposed, and not previously visited.
      if (
        ! processed &&
        rec.alias.expose
      ) {
        return opts.deps.walk({
          id: rec.alias.expose || rec.id,
          file: rec.id,
        }, opts, cb);
      }
    */

    // Delegate to original resolver.
    return resolver(rec.alias.id || rec.id, opts, function (err, res, pkg) {
      if (! err) {
        if (rec.alias.expose) {
          mappings[res] = rec.alias.expose;
          expose(rec.alias.expose, res);
        }
        bify.emit('pathmodify:resolved', {
          rec: rec,
          file: res,
        });
      }
      cb(err, res, pkg);
    });
  }
  // alias_resolver

  /**
   * Process exposure configuration.
   */
  function set_expose (rec, alias, modifier) {
    if (typeof modifier.expose === 'string') {
      alias.expose = modifier.expose;
    }
    else if (typeof modifier.expose === 'function') {
      alias.expose = modifier.expose(rec, alias);
    }

    if (modifier.expose === true || alias.expose === true) {
      alias.expose = rec.id;
    }

    return alias;
  }
  // set_expose

  /**
   * Process a modification that's a function or where the replacement is a
   * function.
   */
  function alias_with_func (mod, rec, opts) {
    var ret = {}, opts = opts || {};
    ret.alias = (typeof mod === 'function' ? mod : mod.to).call(mod, rec, opts);
    ret.matched = !! (ret.alias && ret.alias.id !== rec.id);
    return ret;
  }
  // alias_with_func

  /**
   * Apply modifiers configured by the user.
   */
  function modify (rec) {
    var
      // Switch for terminating looping over the modifiers once a match is
      // found.
      matched,
      // Restore this in the end in case the user modifies it.
      id = rec.id,
      alias,
      temp = {},
      path_sep;

    // Heuristically detect path separator.
    [slash.fwd, slash.back, slash.fwd].every(function (sep) {
      path_sep = sep;
      return rec.id.indexOf(path_sep) === -1;
    });

    modifiers.every(function (modifier) {
      matched = true;

      // Reset so modifiers can't munge data for later ones.
      rec.id = id;
      alias = {};

      if (
        (
          modifier.type === 'dir' &&
          rec.id.indexOf(modifier.from + path_sep) === 0
        )

        ||

        (modifier.type === 'id' && rec.id === modifier.from)
      ) {
        if (typeof modifier.to === 'function') {
          temp = alias_with_func(modifier, rec);
          alias = temp.alias;
          matched = temp.matched;
        }
        else {
          alias.id = modifier.to + rec.id.substr(modifier.from.length);
        }
      }

      else if (typeof modifier === 'function') {
        temp = alias_with_func(modifier, rec);
        alias = temp.alias;
        matched = temp.matched;
      }

      else if (
        modifier.type === 're' &&
        (matched = modifier.from[
          typeof modifier.to === 'function' ? 'exec' : 'test'
        ](rec.id))
      ) {
        if (typeof modifier.to === 'function') {
          temp = alias_with_func(modifier, rec, {matches: matched});
          alias = temp.alias;
          matched = temp.matched;
        }
        else {
          alias.id = rec.id.replace(modifier.from, modifier.to);
        }
      }

      else matched = false;

      if (matched) set_expose(rec, alias, modifier);

      return ! matched;
    });

    rec.id = id;
    if (! (alias && alias.id)) alias = {};
    rec.alias = alias;

    return rec;
  }
  // modify
}
// make_resolver

/**
 * Following module-deps, update record id's to reflect exposure configuration.
 */
function aliaser (opts) {
  opts = opts || {};
  var
    stream = new rs.Transform({objectMode: true}),
    mappings = opts.mappings;

  stream._transform = write;

  function write (rec, enc, cb) {
    // User exposed this file under an alternate id.
    if (mappings[rec.file]) {
      rec.id = mappings[rec.file];
    }

    this.push(rec);
    cb();
  }
  // write

  stream.label = "pathmodify:deps:post";

  return stream;
}
// aliaser

function simple (from, to, expose, type) {
  return {from: from, to: to, expose: expose, type: type};
}
// simple

// Functions for generating entries in opts.mods.
plugin.mod = {};

[
  ['id'],
  ['dir'],
  ['re'],
].forEach(function (type_def) {
  var
    type = type_def[0],
    aliases = type_def[1];

  plugin.mod[type] = function (from, to, expose) {
    return simple(from, to, expose, type);
  };

  if (Array.isArray(aliases)) {
    aliases.forEach(function (alias) {
      plugin.mod[alias] = plugin.mod[type];
    });
  }
});
<|endoftext|>


<commit_before>import fs from 'fs';
import tokenFilter from './src/filter/token';
import passwordRoute from './src/route/password';
import tokenRoute from './src/route/token';

export { default as authorize } from './src/filter/authorize';
export { User } from '@scola/auth-common';

export function server(router, database, config) {
  const key = fs.readFileSync(config.auth.key);

  tokenFilter(router, database, key);
  passwordRoute(router, database, key);
  tokenRoute(router, database, key);
}
<commit_msg>Ask for key, not config<commit_after>import tokenFilter from './src/filter/token';
import passwordRoute from './src/route/password';
import tokenRoute from './src/route/token';

export { default as authorize } from './src/filter/authorize';
export { User } from '@scola/auth-common';

export function server(router, database, key) {
  tokenFilter(router, database, key);
  passwordRoute(router, database, key);
  tokenRoute(router, database, key);
}
<|endoftext|>


<commit_before>var Botkit = require('botkit')

var token = process.env.SLACK_TOKEN

var races_original = [
	"The Barony of Letnev",
	"The Clan of Saar",
	"The Emirates of Hacan",
	"The Federation of Sol",
	"The Mentak Coalition",
	"The Naalu Collective",
	"The Nekro Virus",
	"The Sardakk N’orr",
	"The Universities of Jol-Nar",
	"The Winnu",
	"The Xxcha Kingdom",
	"The Yssaril Tribes",
	"The Brotherhood of Yin",
	"The Embers of Muaat",
	"The Ghosts of Creuss",
	"The L1z1x Mindnet",
	"The Arborec"
  ]
var races = races_original
var currently_choosing
var current_choices = []
var number_of_choices = 3

var players = {}

var controller = Botkit.slackbot({
  // reconnect to Slack RTM when connection goes bad
  retry: Infinity,
  debug: false
})

// Assume single team mode if we have a SLACK_TOKEN
if (token) {
  console.log('Starting in single-team mode')
  console.log("cause there's this token" + token)
  controller.spawn({
    token: token,
    retry: Infinity
  }).startRTM(function (err, bot, payload) {
    if (err) {
      throw new Error(err)
    }

    console.log('Connected to Slack RTM')
  })
// Otherwise assume multi-team mode - setup beep boop resourcer connection
} else {
  console.log('Starting in Beep Boop multi-team mode')
  require('beepboop-botkit').start(controller, { debug: true })
}

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

controller.hears(['list'], ['direct_mention','direct_message'], function (bot, message) {
  var reply = "Here are the currently available races:\n"
  races.forEach(function(item) {
    reply += "* " + item + "\n";
  })
  bot.reply(message, reply);
})

controller.hears(['dig'], ['direct_mention'], function (bot, message) {
  var reply = "I heard " + message.match[0] + ".\n";
  reply += "Plus the 1 was " + message.match[1] + ".\n";
  reply += "So that's the text '" + message.text + "'.";
  userData = message.text.match(/<@([A-Z0-9]{9})>/);
  reply += "And the userdata is " + userData + ".";
  reply += "message user was " + message.user + ".";
  bot.reply(message, reply);
})

controller.hears(['^add'], ['direct_mention'], function (bot, message) {
  var reply = "I heard add at the beginning of the message."
  bot.reply(message, reply);
}

controller.hears(['hello', 'hi'], ['direct_mention'], function (bot, message) {
  bot.reply(message, 'Hello.')
})

controller.hears(['hello', 'hi'], ['direct_message'], function (bot, message) {
  bot.reply(message, 'Hello.')
  bot.reply(message, 'It\'s nice to talk to you directly.')
})

controller.hears('.*', ['mention'], function (bot, message) {
  bot.reply(message, 'You really do care about me. :heart:')
})

controller.hears('help', ['direct_message', 'direct_mention'], function (bot, message) {
  var help = 'I will respond to the following messages: \n' +
      '`bot hi` for a simple message.\n' +
      '`bot attachment` to see a Slack attachment message.\n' +
      '`@<your bot\'s name>` to demonstrate detecting a mention.\n' +
      '`bot help` to see this again.'
  bot.reply(message, help)
})

controller.hears(['attachment'], ['direct_message', 'direct_mention'], function (bot, message) {
  var text = 'Beep Beep Boop is a ridiculously simple hosting platform for your Slackbots.'
  var attachments = [{
    fallback: text,
    pretext: 'We bring bots to life. :sunglasses: :thumbsup:',
    title: 'Host, deploy and share your bot in seconds.',
    image_url: 'https://storage.googleapis.com/beepboophq/_assets/bot-1.22f6fb.png',
    title_link: 'https://beepboophq.com/',
    text: text,
    color: '#7CD197'
  }]

  bot.reply(message, {
    attachments: attachments
  }, function (err, resp) {
    console.log(err, resp)
  })
})

controller.hears('.*', ['direct_message', 'direct_mention'], function (bot, message) {
  bot.reply(message, 'Sorry <@' + message.user + '>, I don\'t understand. \n')
})
<commit_msg>Add player username to add<commit_after>var Botkit = require('botkit')

var token = process.env.SLACK_TOKEN

var races_original = [
	"The Barony of Letnev",
	"The Clan of Saar",
	"The Emirates of Hacan",
	"The Federation of Sol",
	"The Mentak Coalition",
	"The Naalu Collective",
	"The Nekro Virus",
	"The Sardakk N’orr",
	"The Universities of Jol-Nar",
	"The Winnu",
	"The Xxcha Kingdom",
	"The Yssaril Tribes",
	"The Brotherhood of Yin",
	"The Embers of Muaat",
	"The Ghosts of Creuss",
	"The L1z1x Mindnet",
	"The Arborec"
  ]
var races = races_original
var currently_choosing
var current_choices = []
var number_of_choices = 3

var players = {}

var controller = Botkit.slackbot({
  // reconnect to Slack RTM when connection goes bad
  retry: Infinity,
  debug: false
})

// Assume single team mode if we have a SLACK_TOKEN
if (token) {
  console.log('Starting in single-team mode')
  console.log("cause there's this token" + token)
  controller.spawn({
    token: token,
    retry: Infinity
  }).startRTM(function (err, bot, payload) {
    if (err) {
      throw new Error(err)
    }

    console.log('Connected to Slack RTM')
  })
// Otherwise assume multi-team mode - setup beep boop resourcer connection
} else {
  console.log('Starting in Beep Boop multi-team mode')
  require('beepboop-botkit').start(controller, { debug: true })
}

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

controller.hears(['list'], ['direct_mention','direct_message'], function (bot, message) {
  var reply = "Here are the currently available races:\n"
  races.forEach(function(item) {
    reply += "* " + item + "\n";
  })
  bot.reply(message, reply);
})

controller.hears(['dig'], ['direct_mention'], function (bot, message) {
  var reply = "I heard " + message.match[0] + ".\n";
  reply += "Plus the 1 was " + message.match[1] + ".\n";
  reply += "So that's the text '" + message.text + "'.";
  userData = message.text.match(/<@([A-Z0-9]{9})>/);
  reply += "And the userdata is " + userData + ".";
  reply += "message user was " + message.user + ".";
  bot.reply(message, reply);
})

controller.hears(['add'], ['direct_mention'], function (bot, message) {
  var reply = "I heard add. text was " + message.text + ".";
  var userData = message.text.match(/<@([A-Z0-9]{9})>/);
  if (userData) {
		if (!players[userData]) {
			players[userData] = null;
			reply += "\nAdded @<" + userData + ">.";
		} else {
			reply += "@<" + userData + "> is already playing.";
		}
	} else {
	  reply += "\nBut there was no one to add ???";
	}
  bot.reply(message, reply);
}

controller.hears(['hello', 'hi'], ['direct_mention'], function (bot, message) {
  bot.reply(message, 'Hello.')
})

controller.hears(['hello', 'hi'], ['direct_message'], function (bot, message) {
  bot.reply(message, 'Hello.')
  bot.reply(message, 'It\'s nice to talk to you directly.')
})

controller.hears('.*', ['mention'], function (bot, message) {
  bot.reply(message, 'You really do care about me. :heart:')
})

controller.hears('help', ['direct_message', 'direct_mention'], function (bot, message) {
  var help = 'I will respond to the following messages: \n' +
      '`bot hi` for a simple message.\n' +
      '`bot attachment` to see a Slack attachment message.\n' +
      '`@<your bot\'s name>` to demonstrate detecting a mention.\n' +
      '`bot help` to see this again.'
  bot.reply(message, help)
})

controller.hears(['attachment'], ['direct_message', 'direct_mention'], function (bot, message) {
  var text = 'Beep Beep Boop is a ridiculously simple hosting platform for your Slackbots.'
  var attachments = [{
    fallback: text,
    pretext: 'We bring bots to life. :sunglasses: :thumbsup:',
    title: 'Host, deploy and share your bot in seconds.',
    image_url: 'https://storage.googleapis.com/beepboophq/_assets/bot-1.22f6fb.png',
    title_link: 'https://beepboophq.com/',
    text: text,
    color: '#7CD197'
  }]

  bot.reply(message, {
    attachments: attachments
  }, function (err, resp) {
    console.log(err, resp)
  })
})

controller.hears('.*', ['direct_message', 'direct_mention'], function (bot, message) {
  bot.reply(message, 'Sorry <@' + message.user + '>, I don\'t understand. \n')
})
<|endoftext|>


<commit_before>'use strict';

var debug = require('debug')('engine-cache');
var Helpers = require('helper-cache');
var _ = require('lodash');
var extend = _.extend;

/**
 * ```js
 * var Engines = require('engine-cache');
 * var engines = new Engines();
 * ```
 *
 * @param {Object} `options` Default options to use.
 * @api public
 */

function Engines (engines) {
  this.init(engines);
}

/**
 * Initialize default configuration.
 *
 * @api private
 */

Engines.prototype.init = function(engines) {
  debug('init', arguments);
  this.engines = engines || {};
  this.defaultEngines();
};

/**
 * Load default engines
 *
 * @api private
 */

Engines.prototype.defaultEngines = function() {
  debug('defaultEngines', arguments);
  this.register('*', require('engine-noop'));
};

/**
 * Register the given view engine callback `fn` as `ext`.
 *
 * ```js
 * var consolidate = require('consolidate')
 * engines.register('hbs', consolidate.handlebars)
 * ```
 *
 * @param {String} `ext`
 * @param {Object|Function} `options` or callback `fn`.
 * @param {Function} `fn` Callback.
 * @return {Object} `Engines` to enable chaining.
 * @api public
 */

Engines.prototype.register = function (ext, fn, options) {
  var args = [].slice.call(arguments).filter(Boolean);

  debug('[register]', arguments);
  var engine = {};

  if (args.length === 3) {
    if (options && (typeof options === 'function' ||
        options.hasOwnProperty('render') ||
        options.hasOwnProperty('renderFile'))) {
      var opts = fn;
      fn = options;
      options = opts;
    }
  }

  if (typeof fn === 'function') {
    engine = fn;
    engine.render = fn.render;
  } else if (typeof fn === 'object') {
    engine = fn || this.noop;
    engine.renderFile = fn.renderFile || fn.__express;
  }

  engine.options = fn.options || options || {};
  engine.helpers = new Helpers(options);

  if (typeof engine.render !== 'function') {
    throw new Error('Engines are expected to have a `render` method.');
  }

  this.wrapEngine(engine);

  if (ext[0] !== '.') {
    ext = '.' + ext;
  }

  debug('[registered] %s: %j', ext, engine);
  this.engines[ext] = engine;

  return this;
};

/**
 * Wrap engines to extend the helpers object and other
 * native methods or functionality.
 *
 * ```js
 * engines.wrapEngine(engine);
 * ```
 *
 * @param  {Object} `engine` The engine to wrap.
 * @return {Object} The wrapped engine.
 * @api public
 */

Engines.prototype.wrapEngine = function(engine) {
  debug('[wrapEngine]', arguments);
  var render = engine.render;

  engine.render = function(str, options, callback) {
    if (typeof options === 'function') {
      callback = options;
      options = {};
    }

    var opts = extend({}, options);

    opts.helpers = extend({}, engine.helpers, opts.helpers);
    return render.call(this, str, opts, function (err, content) {
      if (err) return callback(err);
      return engine.helpers.resolve(content, callback);
    });
  };
};

/**
 * Load an object of engines onto the `cache`.
 * Mostly useful for testing, but exposed as
 * a public method.
 *
 * ```js
 * engines.load(require('consolidate'))
 * ```
 *
 * @param  {Object} `obj` Engines to load.
 * @return {Object} `Engines` to enable chaining.
 * @api public
 */

Engines.prototype.load = function(obj) {
  debug('[load]', arguments);

  _.forIn(obj, function (value, key) {
    if (value.hasOwnProperty('render')) {
      this.register(key, value);
    }
  }, this);

  return this;
};

/**
 * Return the engine stored by `ext`. If no `ext`
 * is passed, the entire cache is returned.
 *
 * ```js
 * var consolidate = require('consolidate')
 * engine.set('hbs', consolidate.handlebars)
 * engine.get('hbs')
 * // => {render: [function], renderFile: [function]}
 * ```
 *
 * @param {String} `ext` The engine to get.
 * @return {Object} The specified engine.
 * @api public
 */

Engines.prototype.get = function(ext) {
  if (!ext) {
    return this.engines;
  }

  if (ext[0] !== '.') {
    ext = '.' + ext;
  }

  var engine = this.engines[ext];
  if (!engine) {
    engine = this.engines['.*'];
  }

  return engine;
};

/**
 * Get and set helpers for the given `ext` (engine). If no
 * `ext` is passed, the entire helper cache is returned.
 *
 * **Example:**
 *
 * ```js
 * var helpers = engines.helpers('hbs');
 * helpers.addHelper('foo', function() {});
 * helpers.getHelper('foo');
 * helpers.getHelper();
 * ```
 *
 * See [helper-cache] for any related issues, API details, and documentation.
 *
 * @param {String} `ext` The helper cache to get and set to.
 * @return {Object} Object of helpers for the specified engine.
 * @api public
 */

Engines.prototype.helpers = function (ext) {
  return this.get(ext).helpers;
};

/**
 * Remove `ext` engine from the cache, or if no value is
 * specified the entire cache is reset.
 *
 * **Example:**
 *
 * ```js
 * engines.clear()
 * ```
 *
 * @param {String} `ext` The engine to remove.
 * @api public
 */

Engines.prototype.clear = function(ext) {
  if (ext) {
    if (ext[0] !== '.') {
      ext = '.' + ext;
    }
    delete this.engines[ext];
  } else {
    this.engines = {};
  }
};

/**
 * Export `Engines`
 *
 * @type {Object}
 */

module.exports = Engines;<commit_msg>add options check<commit_after>'use strict';

var debug = require('debug')('engine-cache');
var Helpers = require('helper-cache');
var _ = require('lodash');
var extend = _.extend;

/**
 * ```js
 * var Engines = require('engine-cache');
 * var engines = new Engines();
 * ```
 *
 * @param {Object} `options` Default options to use.
 * @api public
 */

function Engines (engines) {
  this.init(engines);
}

/**
 * Initialize default configuration.
 *
 * @api private
 */

Engines.prototype.init = function(engines) {
  debug('init', arguments);
  this.engines = engines || {};
  this.defaultEngines();
};

/**
 * Load default engines
 *
 * @api private
 */

Engines.prototype.defaultEngines = function() {
  debug('defaultEngines', arguments);
  this.register('*', require('engine-noop'));
};

/**
 * Register the given view engine callback `fn` as `ext`.
 *
 * ```js
 * var consolidate = require('consolidate')
 * engines.register('hbs', consolidate.handlebars)
 * ```
 *
 * @param {String} `ext`
 * @param {Object|Function} `options` or callback `fn`.
 * @param {Function} `fn` Callback.
 * @return {Object} `Engines` to enable chaining.
 * @api public
 */

Engines.prototype.register = function (ext, fn, options) {
  var args = [].slice.call(arguments).filter(Boolean);

  debug('[register]', arguments);
  var engine = {};

  if (args.length === 3) {
    if (options && (typeof options === 'function' ||
        options.hasOwnProperty('render') ||
        options.hasOwnProperty('renderFile'))) {
      var opts = fn;
      fn = options;
      options = opts;
    }
  }

  if (typeof fn === 'function') {
    engine = fn;
    engine.render = fn.render;
  } else if (typeof fn === 'object') {
    engine = fn || this.noop;
    engine.renderFile = fn.renderFile || fn.__express;
  }

  engine.options = engine.options || fn.options || options || {};
  engine.helpers = new Helpers(options);

  if (typeof engine.render !== 'function') {
    throw new Error('Engines are expected to have a `render` method.');
  }

  this.wrapEngine(engine);

  if (ext[0] !== '.') {
    ext = '.' + ext;
  }

  debug('[registered] %s: %j', ext, engine);
  this.engines[ext] = engine;

  return this;
};

/**
 * Wrap engines to extend the helpers object and other
 * native methods or functionality.
 *
 * ```js
 * engines.wrapEngine(engine);
 * ```
 *
 * @param  {Object} `engine` The engine to wrap.
 * @return {Object} The wrapped engine.
 * @api public
 */

Engines.prototype.wrapEngine = function(engine) {
  debug('[wrapEngine]', arguments);
  var render = engine.render;

  engine.render = function(str, options, callback) {
    if (typeof options === 'function') {
      callback = options;
      options = {};
    }

    var opts = extend({}, options);

    opts.helpers = extend({}, engine.helpers, opts.helpers);
    return render.call(this, str, opts, function (err, content) {
      if (err) return callback(err);
      return engine.helpers.resolve(content, callback);
    });
  };
};

/**
 * Load an object of engines onto the `cache`.
 * Mostly useful for testing, but exposed as
 * a public method.
 *
 * ```js
 * engines.load(require('consolidate'))
 * ```
 *
 * @param  {Object} `obj` Engines to load.
 * @return {Object} `Engines` to enable chaining.
 * @api public
 */

Engines.prototype.load = function(obj) {
  debug('[load]', arguments);

  _.forIn(obj, function (value, key) {
    if (value.hasOwnProperty('render')) {
      this.register(key, value);
    }
  }, this);

  return this;
};

/**
 * Return the engine stored by `ext`. If no `ext`
 * is passed, the entire cache is returned.
 *
 * ```js
 * var consolidate = require('consolidate')
 * engine.set('hbs', consolidate.handlebars)
 * engine.get('hbs')
 * // => {render: [function], renderFile: [function]}
 * ```
 *
 * @param {String} `ext` The engine to get.
 * @return {Object} The specified engine.
 * @api public
 */

Engines.prototype.get = function(ext) {
  if (!ext) {
    return this.engines;
  }

  if (ext[0] !== '.') {
    ext = '.' + ext;
  }

  var engine = this.engines[ext];
  if (!engine) {
    engine = this.engines['.*'];
  }

  return engine;
};

/**
 * Get and set helpers for the given `ext` (engine). If no
 * `ext` is passed, the entire helper cache is returned.
 *
 * **Example:**
 *
 * ```js
 * var helpers = engines.helpers('hbs');
 * helpers.addHelper('foo', function() {});
 * helpers.getHelper('foo');
 * helpers.getHelper();
 * ```
 *
 * See [helper-cache] for any related issues, API details, and documentation.
 *
 * @param {String} `ext` The helper cache to get and set to.
 * @return {Object} Object of helpers for the specified engine.
 * @api public
 */

Engines.prototype.helpers = function (ext) {
  return this.get(ext).helpers;
};

/**
 * Remove `ext` engine from the cache, or if no value is
 * specified the entire cache is reset.
 *
 * **Example:**
 *
 * ```js
 * engines.clear()
 * ```
 *
 * @param {String} `ext` The engine to remove.
 * @api public
 */

Engines.prototype.clear = function(ext) {
  if (ext) {
    if (ext[0] !== '.') {
      ext = '.' + ext;
    }
    delete this.engines[ext];
  } else {
    this.engines = {};
  }
};

/**
 * Export `Engines`
 *
 * @type {Object}
 */

module.exports = Engines;<|endoftext|>


<commit_before>var assert = require('assert')
  , multiparty = require('multiparty')
  , knox = require('knox')
  , uuid = require('node-uuid')
  , mime = require('mime')
  , Batch = require('batch')
  , gm = require('gm')
  ;

var Framer = module.exports = function Framer(opts) {
  if (typeof opts !== 'object') opts = {};

  var self = this;

  assert(typeof opts.s3 === 'object', 'opts.s3 required');
  assert(typeof opts.s3.key === 'string', 'opts.s3.key required');
  assert(typeof opts.s3.secret === 'string', 'opts.s3.secret required');
  assert(typeof opts.s3.bucket === 'string', 'opts.s3.bucket required');
  opts.s3.secure = (opts.s3.secure) ? true : false;

  this._s3Client = knox.createClient(opts.s3);

  this.handleUpload = function (opts) {
    if (!opts) opts = {};
    opts.prefix = opts.prefix || "";

    var makePublicReadable = opts.makePublicReadable || false
      , log = opts.log || function (){}
      , prefix = opts.prefix || ""
      , authHandler = opts.authHandler;

    return function (req, res, callback) {
      callback = callback === undefined ? null : callback;

      var acceptHeader = req.headers.accept;
      var isTypeHtml = (/text\/html/).test(acceptHeader);
      var isTypeText = (/text\/text/).test(acceptHeader);
      var contentType = 'application/json';

      if(isTypeHtml) contentType = 'text/html';
      else if(isTypeText) contentType = 'text/text';

      var headers = {}
        , form = new multiparty.Form()
        , batch = new Batch();

      if (makePublicReadable) headers['x-amz-acl'] = 'public-read';

      var onUnexpectedEnd = function () {
        self._handleError(500, res, new Error('incomplete upload'));
      };

      batch.push(function(cb) {
        if (authHandler) {
          form.on('field', function(name, value) {
            if ( name === 'authorization') {
              authHandler(value, cb);
            }
          });
        }
        else cb(null, '');
      });

      batch.push(function(cb) {
        form.on('part', function(part) {
          if (! part.filename) return;
          cb(null, part);
        });
      });

      batch.end(function(err, results) {
        if (err) {
          return self._handleError(401, res, err);
        }

        form.removeListener('close', onUnexpectedEnd);

        var userPrefix = results[0]
          , part = results[1]
          , filename = part.filename
          , destPrefix = (userPrefix) ? '/' + userPrefix + '/' : '/'
          , destPath = encodeURI(destPrefix + uuid.v1() + '/' + filename)
          , type = mime.lookup(destPath)
          ;

        headers['Content-Length'] = part.byteCount;
        headers['Content-Type'] = type;

        self._s3Client.putStream(part, destPath, headers, function (err, s3Response) {
          if (err) {
            if(callback){
              callback(err, s3Response);
            } else {
              res.writeHead(500, {'content-type': 'application/json'});
              res.end(JSON.stringify({ statusCode: 500, error: err.toString() }));
            }
            return;
          }

          res.writeHead(res.statusCode, {'content-type': contentType});
          if (s3Response.statusCode === 200) {
            if(callback){
              s3Response.custom_uri = {
                uri: prefix + '/raw' + destPath,
                type: type
              };

              callback(null, s3Response);
            } else {
              res.end(JSON.stringify({ statusCode: 200, uri: prefix + '/raw' + destPath, type: type }));
            }
          }
          else {
            var bufs = [];
            s3Response.on('data', function (d){ bufs.push(d); });
            s3Response.on('end', function () {
              // just return the ugly xml body for now
              var body =Buffer.concat(bufs).toString();

              if(callback){
                callback(null, s3Response);
              }else {
                res.end(JSON.stringify({ statusCode: s3Response.statusCode, error: body }));
              }

            });
          }
        });
      });

      form.on('close', onUnexpectedEnd);
      form.on('error', function(err) {
        //just log the errors for now
        console.log('multipart error: ' + err);
      });
      form.parse(req);
    };
  };

  this.serveImage = function (opts) {
    if (!opts) opts = {};
    opts.prefix = opts.prefix || "";
    opts.cacheMaxAge = opts.cacheMaxAge || 220752000; // 1year, 60*60*24*7*365

    return function (req, res) {
      var url = req.url.substring(opts.prefix.length);
      //20-20 min
      //20x20 resize, center crop
      //20+20 max
      var parts = url.split('/');
      var sizeOptions = parts[1];
      var path = '/' + parts.slice(2).join('/');

      self._s3Client.get(path).on('response', function(s3res){
        if (opts.cacheMaxAge) {
          res.setHeader('Cache-Control', 'public, max-age=' + opts.cacheMaxAge);
        }

        s3res.on('error', function (err) {
          self._handleError(500, res, err);
        });

        if (s3res.statusCode !== 200) {
          return self._handleError(s3res.statusCode, res, new Error('not found'));
        }

        res.setHeader('Content-Type', s3res.headers['content-type']);

        if (sizeOptions === 'raw') {
          return s3res.pipe(res);
        }

        self._transform(gm(s3res), sizeOptions)
          .stream()
          .pipe(res);
      })
      .on('error', function (err) {
          self._handleError(500, res, err);
      })
      .end();
    };
  };

  this.serveFile = function (opts) {
    if (!opts) opts = {};
    opts.prefix = opts.prefix || "";
    opts.cacheMaxAge = opts.cacheMaxAge || 220752000; // 1year, 60*60*24*7*365

    return function (req, res) {
      var url = req.url.substring(opts.prefix.length);

      self._s3Client.get(url).on('response', function(s3res){
        if (opts.cacheMaxAge) {
          res.setHeader('Cache-Control: max-age', opts.cacheMaxAge); // 1 week
        }

        s3res.on('error', function (err) {
          self._handleError(500, res, err);
        });

        res.setHeader('Content-Type', s3res.headers['content-type']);

        return s3res.pipe(res);
      })
      .on('error', function (err) {
          self._handleError(500, res, err);
      })
      .end();

    };
  };

  this.deleteFile = function(opts){
      if (!opts) opts = {};
      opts.prefix = opts.prefix || "";

      return function(req, res, cb) {
        cb = cb === undefined ? null : cb;

        uri = require('url').parse(req.url, true).pathname;
        res.setHeader('Content-Type', s3res.headers['content-type']);

        self._s3Client.deleteFile(uri, function(err, res){
            if(cb){
              cb(err, res);
            } else {
              res.end(JSON.stringify({statusCode: 200, message: 'File deleted.'}));
            }
        });
      }; // end of return function object

  }; // end of deleteFile

  this._handleError = function (code, res, err) {
    res.writeHead(code, {'content-type': 'application/json'});
    res.end(JSON.stringify({ statusCode: code, error: err.toString() }));
  };

  this._transform = function (obj, optionsString) {
    var size, w, h;
    if (optionsString.indexOf('x') > -1) {
      size = optionsString.split('x'); w = size[0]; h = size[1];
      return obj.resize(w, h, '^').gravity('Center').crop(w, h, 0, 0);
    }
    else if (optionsString.indexOf('+') > -1) {
      size = optionsString.split('+'); w = size[0]; h = size[1];
      return obj.resize(w, h, '^');
    }
    else if (optionsString.indexOf('-') > -1) {
      size = optionsString.split('-'); w = size[0]; h = size[1];
      return obj.resize(w, h);
    }
    else {
      return obj;
    }
  };
};
<commit_msg>Set header of response if callback isn't being used.<commit_after>var assert = require('assert')
  , multiparty = require('multiparty')
  , knox = require('knox')
  , uuid = require('node-uuid')
  , mime = require('mime')
  , Batch = require('batch')
  , gm = require('gm')
  ;

var Framer = module.exports = function Framer(opts) {
  if (typeof opts !== 'object') opts = {};

  var self = this;

  assert(typeof opts.s3 === 'object', 'opts.s3 required');
  assert(typeof opts.s3.key === 'string', 'opts.s3.key required');
  assert(typeof opts.s3.secret === 'string', 'opts.s3.secret required');
  assert(typeof opts.s3.bucket === 'string', 'opts.s3.bucket required');
  opts.s3.secure = (opts.s3.secure) ? true : false;

  this._s3Client = knox.createClient(opts.s3);

  this.handleUpload = function (opts) {
    if (!opts) opts = {};
    opts.prefix = opts.prefix || "";

    var makePublicReadable = opts.makePublicReadable || false
      , log = opts.log || function (){}
      , prefix = opts.prefix || ""
      , authHandler = opts.authHandler;

    return function (req, res, callback) {
      callback = callback === undefined ? null : callback;

      var acceptHeader = req.headers.accept;
      var isTypeHtml = (/text\/html/).test(acceptHeader);
      var isTypeText = (/text\/text/).test(acceptHeader);
      var contentType = 'application/json';

      if(isTypeHtml) contentType = 'text/html';
      else if(isTypeText) contentType = 'text/text';

      var headers = {}
        , form = new multiparty.Form()
        , batch = new Batch();

      if (makePublicReadable) headers['x-amz-acl'] = 'public-read';

      var onUnexpectedEnd = function () {
        self._handleError(500, res, new Error('incomplete upload'));
      };

      batch.push(function(cb) {
        if (authHandler) {
          form.on('field', function(name, value) {
            if ( name === 'authorization') {
              authHandler(value, cb);
            }
          });
        }
        else cb(null, '');
      });

      batch.push(function(cb) {
        form.on('part', function(part) {
          if (! part.filename) return;
          cb(null, part);
        });
      });

      batch.end(function(err, results) {
        if (err) {
          return self._handleError(401, res, err);
        }

        form.removeListener('close', onUnexpectedEnd);

        var userPrefix = results[0]
          , part = results[1]
          , filename = part.filename
          , destPrefix = (userPrefix) ? '/' + userPrefix + '/' : '/'
          , destPath = encodeURI(destPrefix + uuid.v1() + '/' + filename)
          , type = mime.lookup(destPath)
          ;

        headers['Content-Length'] = part.byteCount;
        headers['Content-Type'] = type;

        self._s3Client.putStream(part, destPath, headers, function (err, s3Response) {
          if (err) {
            if(callback){
              callback(err, s3Response);
            } else {
              res.writeHead(500, {'content-type': 'application/json'});
              res.end(JSON.stringify({ statusCode: 500, error: err.toString() }));
            }
            return;
          }

          res.writeHead(res.statusCode, {'content-type': contentType});
          if (s3Response.statusCode === 200) {
            if(callback){
              s3Response.custom_uri = {
                uri: prefix + '/raw' + destPath,
                type: type
              };

              callback(null, s3Response);
            } else {
              res.end(JSON.stringify({ statusCode: 200, uri: prefix + '/raw' + destPath, type: type }));
            }
          }
          else {
            var bufs = [];
            s3Response.on('data', function (d){ bufs.push(d); });
            s3Response.on('end', function () {
              // just return the ugly xml body for now
              var body =Buffer.concat(bufs).toString();

              if(callback){
                callback(null, s3Response);
              }else {
                res.end(JSON.stringify({ statusCode: s3Response.statusCode, error: body }));
              }

            });
          }
        });
      });

      form.on('close', onUnexpectedEnd);
      form.on('error', function(err) {
        //just log the errors for now
        console.log('multipart error: ' + err);
      });
      form.parse(req);
    };
  };

  this.serveImage = function (opts) {
    if (!opts) opts = {};
    opts.prefix = opts.prefix || "";
    opts.cacheMaxAge = opts.cacheMaxAge || 220752000; // 1year, 60*60*24*7*365

    return function (req, res) {
      var url = req.url.substring(opts.prefix.length);
      //20-20 min
      //20x20 resize, center crop
      //20+20 max
      var parts = url.split('/');
      var sizeOptions = parts[1];
      var path = '/' + parts.slice(2).join('/');

      self._s3Client.get(path).on('response', function(s3res){
        if (opts.cacheMaxAge) {
          res.setHeader('Cache-Control', 'public, max-age=' + opts.cacheMaxAge);
        }

        s3res.on('error', function (err) {
          self._handleError(500, res, err);
        });

        if (s3res.statusCode !== 200) {
          return self._handleError(s3res.statusCode, res, new Error('not found'));
        }

        res.setHeader('Content-Type', s3res.headers['content-type']);

        if (sizeOptions === 'raw') {
          return s3res.pipe(res);
        }

        self._transform(gm(s3res), sizeOptions)
          .stream()
          .pipe(res);
      })
      .on('error', function (err) {
          self._handleError(500, res, err);
      })
      .end();
    };
  };

  this.serveFile = function (opts) {
    if (!opts) opts = {};
    opts.prefix = opts.prefix || "";
    opts.cacheMaxAge = opts.cacheMaxAge || 220752000; // 1year, 60*60*24*7*365

    return function (req, res) {
      var url = req.url.substring(opts.prefix.length);

      self._s3Client.get(url).on('response', function(s3res){
        if (opts.cacheMaxAge) {
          res.setHeader('Cache-Control: max-age', opts.cacheMaxAge); // 1 week
        }

        s3res.on('error', function (err) {
          self._handleError(500, res, err);
        });

        res.setHeader('Content-Type', s3res.headers['content-type']);

        return s3res.pipe(res);
      })
      .on('error', function (err) {
          self._handleError(500, res, err);
      })
      .end();

    };
  };

  this.deleteFile = function(opts){
      if (!opts) opts = {};
      opts.prefix = opts.prefix || "";

      return function(req, res, cb) {
        cb = cb === undefined ? null : cb;

        uri = require('url').parse(req.url, true).pathname;

        self._s3Client.deleteFile(uri, function(err, res){
            if(cb){
              cb(err, res);
            } else {
              res.setHeader('Content-Type', s3res.headers['content-type']);
              res.end(JSON.stringify({statusCode: 200, message: 'File deleted.'}));
            }
        });
      }; // end of return function object

  }; // end of deleteFile

  this._handleError = function (code, res, err) {
    res.writeHead(code, {'content-type': 'application/json'});
    res.end(JSON.stringify({ statusCode: code, error: err.toString() }));
  };

  this._transform = function (obj, optionsString) {
    var size, w, h;
    if (optionsString.indexOf('x') > -1) {
      size = optionsString.split('x'); w = size[0]; h = size[1];
      return obj.resize(w, h, '^').gravity('Center').crop(w, h, 0, 0);
    }
    else if (optionsString.indexOf('+') > -1) {
      size = optionsString.split('+'); w = size[0]; h = size[1];
      return obj.resize(w, h, '^');
    }
    else if (optionsString.indexOf('-') > -1) {
      size = optionsString.split('-'); w = size[0]; h = size[1];
      return obj.resize(w, h);
    }
    else {
      return obj;
    }
  };
};
<|endoftext|>