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

/*  Hack an instance of Argv with process.argv into Argv
    so people an do
        require('optimist')(['--beeble=1','-z','zizzle']).argv
    to parse a list of args and
        require('optimist').argv
    to get a parsed version of process.argv.
*/
var inst = Argv(process.argv.slice(2));
Object.keys(inst).forEach(function (key) {
    Argv[key] = typeof inst[key] == 'function'
        ? inst[key].bind(inst)
        : inst[key];
});

var exports = module.exports = Argv;
function Argv (args, cwd) {
    var self = {};
    if (!cwd) cwd = process.cwd();

    self.$0 = process.argv
        .slice(0,2)
        .map(function (x) {
            var b = rebase(cwd, x);
            return x.match(/^\//) && b.length < x.length
                ? b : x
        })
        .join(' ')
    ;

    if (process.argv[1] == process.env._) {
        self.$0 = process.env._.replace(
            path.dirname(process.execPath) + '/', ''
        );
    }

    var flags = { bools : {}, strings : {} };

    self.boolean = function (bools) {
        if (!Array.isArray(bools)) {
            bools = [].slice.call(arguments);
        }

        bools.forEach(function (name) {
            flags.bools[name] = true;
        });

        bools.forEach(function (name) {
            if (!self.argv[name]) {
                self.argv[name] = false;
            }
        });

        return self;
    };

    self.string = function (strings) {
        if (!Array.isArray(strings)) {
            strings = [].slice.call(arguments);
        }

        strings.forEach(function (name) {
            flags.strings[name] = true;
        });

        return self;
    };

    var aliases = {};
    self.alias = function (x, y) {
        if (typeof x === 'object') {
            Object.keys(x).forEach(function (key) {
                aliases[key] = x[key];
                aliases[x[key]] = key;
            });
        }
        else {
            aliases[x] = y;
            aliases[y] = x;
        }

        return self;
    };

    var demanded = {};
    self.demand = function (keys, cb) {
        if (typeof keys == 'number') {
            if (!demanded._) demanded._ = 0;
            demanded._ += keys;
        }
        else if (Array.isArray(keys)) {
            keys.forEach(function (key) {
                self.demand(key);
            });
        }
        else {
            demanded[keys] = true;
        }

        return self;
    };

    var usage;
    self.usage = function (msg, opts) {
        if (!opts && typeof msg === 'object') {
            opts = msg;
            msg = null;
        }

        usage = msg;
        return opts ? self.options(opts) : self;
    };

    function fail (msg) {
        self.showHelp();
        if (msg) console.error(msg);
        process.exit(1);
    }

    self.check = function (f) {
        try {
            if (f(self.argv) === false) fail(
                'Argument check failed: ' + f.toString()
            );
        }
        catch (err) { fail(err) }

        return self;
    };

    self.default = function (key, value) {
        if (typeof key === 'object') {
            Object.keys(key).forEach(function (k) {
                self.default(k, key[k]);
            });
        }
        else {
            if (self.argv[key] === undefined) {
                self.argv[key] = value;
            }
        }
        return self;
    };

    self.parse = function (args) {
        return Argv(args).argv;
    };

    self.camelCase = function () {
        for (var key in self.argv) {
            var camelCasedKey = key.replace(/-([a-z])/g, function (_, c) {
                return c.toUpperCase();
            });

            if (camelCasedKey !== key) {
                self.argv[camelCasedKey] = self.argv[key];
                delete self.argv[key];
            }
        }
        return self;
    };

    function longestElement (a) {
        var l = 0;
        for (var i = 0; i < a.length; i++) {
            if (a[l].length < a[i].length) {
                l = i;
            }
        }

        return a[l].length;
    }

    var options = null;

    self.options = function (opts) {
        var required = [],
            strings = [],
            bools = [];

        self.options = opts;

        Object.keys(opts).forEach(function (key) {
            var o = opts[key];
            var oargs = [key];

            if (o.short && o.short !== key) {
                oargs.unshift(o.short);
            }

            if (o.required) {
                required = required.concat(oargs);
            }

            if (o.boolean) {
                bools = bools.concat(oargs);
            }
            else if (o.string) {
                strings = strings.concat(oargs);
            }

            if (o.default) {
                // If this argument has default values then set it
                // internally on this `Argv` instance for both the verbose
                // and `short` option (if provided).
                //
                oargs.forEach(function (a) {
                    self.default(a, o.default);
                });
            }
        });

        if (required.length > 0) {
            // If required properties have been supplied,
            // then demand them immediately.
            //
            // TODO: Patch `.demand()` so that it can discern between
            // multiple options for each real option. (e.g. `.demand(['a', 'about'])`
            // fails when it is really the same argument.
            //
            self.demand(required);
        }

        if (bools.length > 0) {
            self.boolean(bools);
        }

        if (strings.length > 0) {
            self.string(strings);
        }

        return self;
    };

    self.showHelp = function (padding) {
        if (usage) {
            console.error(usage.replace(/\$0/g, self.$0));
        }

        if (self.options && Object.keys(self.options).length > 0) {
            var help = Object.keys(self.options).map(function (key) {
                var o = self.options[key];
                var hargs = [o.short, key];

                hargs = hargs.filter(function (a) {
                    return a;
                }).map(function (a) {
                    return a.length === 1 ? '-' + a : '--' + a;
                }).join(', ');

                return {
                    args: hargs,
                    description: o.description,
                    default: o.default
                };
            })

            padding = padding || 2;

            var larg = longestElement(help.map(function (h) { return h.args }));
            var described = help.filter(function (h) { return h.description });
            var more = help.filter(function (h) { return !h.description });

            function printOpt (h) {
              var hdesc = h.description || '';

              if (h.args.length < larg) {
                  h.args += new Array(larg - h.args.length + 1).join(' ');
              }

              if (padding) {
                  hdesc = new Array(padding + 1).join(' ') + hdesc;
              }

              return [
                  '  ' + h.args,
                  hdesc,
                  h.default ? '[' + h.default + ']' : ''
              ].join(' ');
            }

            if (described.length > 0) {
                console.log('options:');
                console.log(described.map(printOpt).join('\n'));
            }

            if (more.length > 0) {
                console.log('\nmore options:');
                console.log(more.map(printOpt).join('\n'));
            }
        }
    }

    Object.defineProperty(self, 'argv', {
        get : parseArgs,
        enumerable : true,
    });

    function parseArgs () {
        var argv = { _ : [], $0 : self.$0 };
        Object.keys(flags.bools).forEach(function (key) {
            setArg(key, false);
        });

        function setArg (key, val) {
            var num = Number(val);
            var value = typeof val !== 'string' || isNaN(num) ? val : num;
            if (flags.strings[key]) value = val;

            if (key in argv && !flags.bools[key]) {
                if (!Array.isArray(argv[key])) {
                    argv[key] = [ argv[key] ];
                }
                argv[key].push(value);
            }
            else {
                argv[key] = value;
            }

            if (aliases[key]) {
                argv[aliases[key]] = argv[key];
            }
        }

        for (var i = 0; i < args.length; i++) {
            var arg = args[i];

            if (arg === '--') {
                argv._.push.apply(argv._, args.slice(i + 1));
                break;
            }
            else if (arg.match(/^--.+=/)) {
                var m = arg.match(/^--([^=]+)=(.*)/);
                setArg(m[1], m[2]);
            }
            else if (arg.match(/^--no-.+/)) {
                var key = arg.match(/^--no-(.+)/)[1];
                setArg(key, false);
            }
            else if (arg.match(/^--.+/)) {
                var key = arg.match(/^--(.+)/)[1];
                var next = args[i + 1];
                if (next !== undefined && !next.match(/^-/)
                && !flags.bools[key]) {
                    setArg(key, next);
                    i++;
                }
                else {
                    setArg(key, true);
                }
            }
            else if (arg.match(/^-[^-]+/)) {
                var letters = arg.slice(1,-1).split('');

                var broken = false;
                for (var j = 0; j < letters.length; j++) {
                    if (letters[j+1] && letters[j+1].match(/\W/)) {
                        setArg(letters[j], arg.slice(j+2));
                        broken = true;
                        break;
                    }
                    else {
                        setArg(letters[j], true);
                    }
                }

                if (!broken) {
                    var key = arg.slice(-1)[0];

                    if (args[i+1] && !args[i+1].match(/^-/)
                    && !flags.bools[key]) {
                        setArg(key, args[i+1]);
                        i++;
                    }
                    else {
                        setArg(key, true);
                    }
                }
            }
            else {
                var n = Number(arg);
                argv._.push(isNaN(n) ? arg : n);
            }
        }

        if (demanded._ && argv._.length < demanded._) {
            fail('Not enough non-option arguments: got '
                + argv._.length + ', need at least ' + demanded._
            );
        }

        var missing = [];
        Object.keys(demanded).forEach(function (key) {
            if (!argv[key]) missing.push(key);
        });

        if (missing.length) {
            fail('Missing required arguments: ' + missing.join(', '));
        }

        return argv;
    }

    return self;
};

// rebase an absolute path to a relative one with respect to a base directory
// exported for tests
exports.rebase = rebase;
function rebase (base, dir) {
    var ds = path.normalize(dir).split('/').slice(1);
    var bs = path.normalize(base).split('/').slice(1);

    for (var i = 0; ds[i] && ds[i] == bs[i]; i++);
    ds.splice(0, i); bs.splice(0, i);

    var p = path.normalize(
        bs.map(function () { return '..' }).concat(ds).join('/')
    ).replace(/\/$/,'').replace(/^$/, '.');
    return p.match(/^[.\/]/) ? p : './' + p;
}
<commit_msg>defaults work again, all tests pass<commit_after>var path = require('path');

/*  Hack an instance of Argv with process.argv into Argv
    so people an do
        require('optimist')(['--beeble=1','-z','zizzle']).argv
    to parse a list of args and
        require('optimist').argv
    to get a parsed version of process.argv.
*/
var inst = Argv(process.argv.slice(2));
Object.keys(inst).forEach(function (key) {
    Argv[key] = typeof inst[key] == 'function'
        ? inst[key].bind(inst)
        : inst[key];
});

var exports = module.exports = Argv;
function Argv (args, cwd) {
    var self = {};
    if (!cwd) cwd = process.cwd();

    self.$0 = process.argv
        .slice(0,2)
        .map(function (x) {
            var b = rebase(cwd, x);
            return x.match(/^\//) && b.length < x.length
                ? b : x
        })
        .join(' ')
    ;

    if (process.argv[1] == process.env._) {
        self.$0 = process.env._.replace(
            path.dirname(process.execPath) + '/', ''
        );
    }

    var flags = { bools : {}, strings : {} };

    self.boolean = function (bools) {
        if (!Array.isArray(bools)) {
            bools = [].slice.call(arguments);
        }

        bools.forEach(function (name) {
            flags.bools[name] = true;
        });

        bools.forEach(function (name) {
            if (!self.argv[name]) {
                self.argv[name] = false;
            }
        });

        return self;
    };

    self.string = function (strings) {
        if (!Array.isArray(strings)) {
            strings = [].slice.call(arguments);
        }

        strings.forEach(function (name) {
            flags.strings[name] = true;
        });

        return self;
    };

    var aliases = {};
    self.alias = function (x, y) {
        if (typeof x === 'object') {
            Object.keys(x).forEach(function (key) {
                aliases[key] = x[key];
                aliases[x[key]] = key;
            });
        }
        else {
            aliases[x] = y;
            aliases[y] = x;
        }

        return self;
    };

    var demanded = {};
    self.demand = function (keys, cb) {
        if (typeof keys == 'number') {
            if (!demanded._) demanded._ = 0;
            demanded._ += keys;
        }
        else if (Array.isArray(keys)) {
            keys.forEach(function (key) {
                self.demand(key);
            });
        }
        else {
            demanded[keys] = true;
        }

        return self;
    };

    var usage;
    self.usage = function (msg, opts) {
        if (!opts && typeof msg === 'object') {
            opts = msg;
            msg = null;
        }

        usage = msg;
        return opts ? self.options(opts) : self;
    };

    function fail (msg) {
        self.showHelp();
        if (msg) console.error(msg);
        process.exit(1);
    }

    self.check = function (f) {
        try {
            if (f(self.argv) === false) fail(
                'Argument check failed: ' + f.toString()
            );
        }
        catch (err) { fail(err) }

        return self;
    };

    var defaults = {};
    self.default = function (key, value) {
        if (typeof key === 'object') {
            Object.keys(key).forEach(function (k) {
                defaults[k] = key[k];
            });
        }
        else {
            defaults[key] = value;
        }

        return self;
    };

    self.parse = function (args) {
        return Argv(args).argv;
    };

    self.camelCase = function () {
        for (var key in self.argv) {
            var camelCasedKey = key.replace(/-([a-z])/g, function (_, c) {
                return c.toUpperCase();
            });

            if (camelCasedKey !== key) {
                self.argv[camelCasedKey] = self.argv[key];
                delete self.argv[key];
            }
        }
        return self;
    };

    function longestElement (a) {
        var l = 0;
        for (var i = 0; i < a.length; i++) {
            if (a[l].length < a[i].length) {
                l = i;
            }
        }

        return a[l].length;
    }

    var options = null;

    self.options = function (opts) {
        var required = [],
            strings = [],
            bools = [];

        self.options = opts;

        Object.keys(opts).forEach(function (key) {
            var o = opts[key];
            var oargs = [key];

            if (o.short && o.short !== key) {
                oargs.unshift(o.short);
            }

            if (o.required) {
                required = required.concat(oargs);
            }

            if (o.boolean) {
                bools = bools.concat(oargs);
            }
            else if (o.string) {
                strings = strings.concat(oargs);
            }

            if (o.default) {
                // If this argument has default values then set it
                // internally on this `Argv` instance for both the verbose
                // and `short` option (if provided).
                //
                oargs.forEach(function (a) {
                    self.default(a, o.default);
                });
            }
        });

        if (required.length > 0) {
            // If required properties have been supplied,
            // then demand them immediately.
            //
            // TODO: Patch `.demand()` so that it can discern between
            // multiple options for each real option. (e.g. `.demand(['a', 'about'])`
            // fails when it is really the same argument.
            //
            self.demand(required);
        }

        if (bools.length > 0) {
            self.boolean(bools);
        }

        if (strings.length > 0) {
            self.string(strings);
        }

        return self;
    };

    self.showHelp = function (padding) {
        if (usage) {
            console.error(usage.replace(/\$0/g, self.$0));
        }

        if (self.options && Object.keys(self.options).length > 0) {
            var help = Object.keys(self.options).map(function (key) {
                var o = self.options[key];
                var hargs = [o.short, key];

                hargs = hargs.filter(function (a) {
                    return a;
                }).map(function (a) {
                    return a.length === 1 ? '-' + a : '--' + a;
                }).join(', ');

                return {
                    args: hargs,
                    description: o.description,
                    default: o.default
                };
            })

            padding = padding || 2;

            var larg = longestElement(help.map(function (h) { return h.args }));
            var described = help.filter(function (h) { return h.description });
            var more = help.filter(function (h) { return !h.description });

            function printOpt (h) {
              var hdesc = h.description || '';

              if (h.args.length < larg) {
                  h.args += new Array(larg - h.args.length + 1).join(' ');
              }

              if (padding) {
                  hdesc = new Array(padding + 1).join(' ') + hdesc;
              }

              return [
                  '  ' + h.args,
                  hdesc,
                  h.default ? '[' + h.default + ']' : ''
              ].join(' ');
            }

            if (described.length > 0) {
                console.log('options:');
                console.log(described.map(printOpt).join('\n'));
            }

            if (more.length > 0) {
                console.log('\nmore options:');
                console.log(more.map(printOpt).join('\n'));
            }
        }
    }

    Object.defineProperty(self, 'argv', {
        get : parseArgs,
        enumerable : true,
    });

    function parseArgs () {
        var argv = { _ : [], $0 : self.$0 };
        Object.keys(flags.bools).forEach(function (key) {
            setArg(key, false);
        });

        function setArg (key, val) {
            var num = Number(val);
            var value = typeof val !== 'string' || isNaN(num) ? val : num;
            if (flags.strings[key]) value = val;

            if (key in argv && !flags.bools[key]) {
                if (!Array.isArray(argv[key])) {
                    argv[key] = [ argv[key] ];
                }
                argv[key].push(value);
            }
            else {
                argv[key] = value;
            }

            if (aliases[key]) {
                argv[aliases[key]] = argv[key];
            }
        }

        for (var i = 0; i < args.length; i++) {
            var arg = args[i];

            if (arg === '--') {
                argv._.push.apply(argv._, args.slice(i + 1));
                break;
            }
            else if (arg.match(/^--.+=/)) {
                var m = arg.match(/^--([^=]+)=(.*)/);
                setArg(m[1], m[2]);
            }
            else if (arg.match(/^--no-.+/)) {
                var key = arg.match(/^--no-(.+)/)[1];
                setArg(key, false);
            }
            else if (arg.match(/^--.+/)) {
                var key = arg.match(/^--(.+)/)[1];
                var next = args[i + 1];
                if (next !== undefined && !next.match(/^-/)
                && !flags.bools[key]) {
                    setArg(key, next);
                    i++;
                }
                else {
                    setArg(key, true);
                }
            }
            else if (arg.match(/^-[^-]+/)) {
                var letters = arg.slice(1,-1).split('');

                var broken = false;
                for (var j = 0; j < letters.length; j++) {
                    if (letters[j+1] && letters[j+1].match(/\W/)) {
                        setArg(letters[j], arg.slice(j+2));
                        broken = true;
                        break;
                    }
                    else {
                        setArg(letters[j], true);
                    }
                }

                if (!broken) {
                    var key = arg.slice(-1)[0];

                    if (args[i+1] && !args[i+1].match(/^-/)
                    && !flags.bools[key]) {
                        setArg(key, args[i+1]);
                        i++;
                    }
                    else {
                        setArg(key, true);
                    }
                }
            }
            else {
                var n = Number(arg);
                argv._.push(isNaN(n) ? arg : n);
            }
        }

        Object.keys(defaults).forEach(function (key) {
            if (!(key in argv)) {
                argv[key] = defaults[key];
            }
        });

        if (demanded._ && argv._.length < demanded._) {
            fail('Not enough non-option arguments: got '
                + argv._.length + ', need at least ' + demanded._
            );
        }

        var missing = [];
        Object.keys(demanded).forEach(function (key) {
            if (!argv[key]) missing.push(key);
        });

        if (missing.length) {
            fail('Missing required arguments: ' + missing.join(', '));
        }

        return argv;
    }

    return self;
};

// rebase an absolute path to a relative one with respect to a base directory
// exported for tests
exports.rebase = rebase;
function rebase (base, dir) {
    var ds = path.normalize(dir).split('/').slice(1);
    var bs = path.normalize(base).split('/').slice(1);

    for (var i = 0; ds[i] && ds[i] == bs[i]; i++);
    ds.splice(0, i); bs.splice(0, i);

    var p = path.normalize(
        bs.map(function () { return '..' }).concat(ds).join('/')
    ).replace(/\/$/,'').replace(/^$/, '.');
    return p.match(/^[.\/]/) ? p : './' + p;
}
<|endoftext|>


<commit_before>/*!
 * Expressjs | Connect - csrf
 * Copyright(c) 2011 Sencha Inc.
 * Copyright(c) 2014 Jonathan Ong
 * MIT Licensed
 */

/**
 * Module dependencies.
 */

var Cookie = require('cookie');
var csrfTokens = require('csrf-tokens');
var sign = require('cookie-signature').sign;

/**
 * CSRF protection middleware.
 *
 * This middleware adds a `req.csrfToken()` function to make a token
 * which should be added to requests which mutate
 * state, within a hidden form field, query-string etc. This
 * token is validated against the visitor's session.
 *
 * @param {Object} options
 * @return {Function} middleware
 * @api public
 */

var ignoreMethod = {
  GET: true,
  HEAD: true,
  OPTIONS: true,
};

module.exports = function csrf(options) {
  options = options || {};
  var value = options.value || defaultValue,
      cookie = options.cookie,
      cookieKey = (cookie && cookie.key) || '_csrf',
      signedCookie = cookie && cookie.signed;

  var tokens = csrfTokens(options);

  if (cookie && typeof cookie !== 'object')
    cookie = {};

  return function(req, res, next){

    // already have one
    var secret;
    if (cookie) {
      secret = (   (signedCookie
                    && req.signedCookies
                    && req.signedCookies[cookieKey])
                || (!signedCookie
                    && req.cookies
                    && req.cookies[cookieKey])
               );
    } else if (req.session)
      secret = req.session.csrfSecret;
    else {
      var err = new Error('misconfigured csrf');
      err.status = 500;
      next(err);
      return;
    }
    if (secret) return createToken(secret);

    // generate secret
    tokens.secret(function(err, secret){
      if (err) return next(err);
      if (cookie) {
        var cookieSecret = req.secret;
        var val = secret;

        if (signedCookie) {
          if (!cookieSecret) {
            var err = new Error('cookieParser("secret") required for signed cookies');
            err.status = 500;
            next(err);
            return;
          }

          val = 's:' + sign(secret, cookieSecret);
        }

        setcookie(res, cookieKey, val, cookie);
      } else {
        req.session.csrfSecret = secret;
      }
      createToken(secret);
    });

    // generate the token
    function createToken(secret) {
      // lazy-load token
      var token;
      req.csrfToken = function csrfToken() {
        return token || (token = tokens.create(secret));
      };

      // ignore these methods
      if (ignoreMethod[req.method]) return next();

      // check user-submitted value
      if (!tokens.verify(secret, value(req))) {
        var err = new Error('invalid csrf token');
        err.status = 403;
        next(err);
        return;
      }

      next();
    }
  }
};

/**
 * Default value function, checking the `req.body`
 * and `req.query` for the CSRF token.
 *
 * @param {IncomingMessage} req
 * @return {String}
 * @api private
 */

function defaultValue(req) {
  return (req.body && req.body._csrf)
    || (req.query && req.query._csrf)
    || (req.headers['x-csrf-token'])
    || (req.headers['x-xsrf-token']);
}

/**
 * Set a cookie on the HTTP response.
 *
 * @param {OutgoingMessage} res
 * @param {string} name
 * @param {string} val
 * @param {Object} [options]
 * @api private
 */

function setcookie(res, name, val, options) {
  var data = Cookie.serialize(name, val, options);

  var prev = res.getHeader('set-cookie') || [];
  var header = Array.isArray(prev) ? prev.concat(data)
    : Array.isArray(data) ? [prev].concat(data)
    : [prev, data];

  res.setHeader('set-cookie', header);
}
<commit_msg>Refactor internals<commit_after>/*!
 * csurf
 * Copyright(c) 2011 Sencha Inc.
 * Copyright(c) 2014 Jonathan Ong
 * MIT Licensed
 */

/**
 * Module dependencies.
 */

var Cookie = require('cookie');
var csrfTokens = require('csrf-tokens');
var sign = require('cookie-signature').sign;

/**
 * CSRF protection middleware.
 *
 * This middleware adds a `req.csrfToken()` function to make a token
 * which should be added to requests which mutate
 * state, within a hidden form field, query-string etc. This
 * token is validated against the visitor's session.
 *
 * @param {Object} options
 * @return {Function} middleware
 * @api public
 */

var ignoreMethod = {
  GET: true,
  HEAD: true,
  OPTIONS: true,
};

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

  // get value getter
  var value = options.value || defaultValue

  // token repo
  var tokens = csrfTokens(options);

  // default cookie key
  if (options.cookie && !options.cookie.key) {
    options.cookie.key = '_csrf'
  }

  return function csrf(req, res, next) {
    var secret = getsecret(req, options.cookie)
    var token

    // lazy-load token getter
    req.csrfToken = function csrfToken() {
      return token || (token = tokens.create(secret))
    }

    // generate & set secret
    if (!secret) {
      secret = tokens.secretSync()
      setsecret(req, res, secret, options.cookie)
    }

    // verify the incoming token
    verifytoken(req, tokens, secret, value(req))

    next()
  }
};

/**
 * Default value function, checking the `req.body`
 * and `req.query` for the CSRF token.
 *
 * @param {IncomingMessage} req
 * @return {String}
 * @api private
 */

function defaultValue(req) {
  return (req.body && req.body._csrf)
    || (req.query && req.query._csrf)
    || (req.headers['x-csrf-token'])
    || (req.headers['x-xsrf-token']);
}

/**
 * Get the token secret from the request.
 *
 * @param {IncomingMessage} req
 * @param {Object} [cookie]
 * @api private
 */

function getsecret(req, cookie) {
  var secret

  if (cookie) {
    // get secret from cookie
    var bag = cookie.signed
      ? 'signedCookies'
      : 'cookies'

    secret = req[bag][cookie.key]
  } else if (req.session) {
    // get secret from session
    secret = req.session.csrfSecret
  } else {
    throw new Error('misconfigured csrf')
  }

  return secret
}

/**
 * Set a cookie on the HTTP response.
 *
 * @param {OutgoingMessage} res
 * @param {string} name
 * @param {string} val
 * @param {Object} [options]
 * @api private
 */

function setcookie(res, name, val, options) {
  var data = Cookie.serialize(name, val, options);

  var prev = res.getHeader('set-cookie') || [];
  var header = Array.isArray(prev) ? prev.concat(data)
    : Array.isArray(data) ? [prev].concat(data)
    : [prev, data];

  res.setHeader('set-cookie', header);
}

/**
 * Set the token secret on the request.
 *
 * @param {IncomingMessage} req
 * @param {OutgoingMessage} res
 * @param {string} val
 * @param {Object} [cookie]
 * @api private
 */

function setsecret(req, res, val, cookie) {
  if (cookie) {
    // set secret on cookie
    if (cookie.signed) {
      var secret = req.secret

      if (!secret) {
        throw new Error('cookieParser("secret") required for signed cookies')
      }

      val = 's:' + sign(val, secret)
    }

    setcookie(res, cookie.key, val, cookie);
  } else if (req.session) {
    // set secret on session
    req.session.csrfSecret = val
  } else {
    throw new Error('misconfigured csrf')
  }
}

/**
 * Verify the token.
 *
 * @param {IncomingMessage} req
 * @param {Object} tokens
 * @param {string} secret
 * @param {string} val
 * @api private
 */

function verifytoken(req, tokens, secret, val) {
  // ignore these methods
  if (ignoreMethod[req.method]) {
    return
  }

  // valid token
  if (tokens.verify(secret, val)) {
    return
  }

  var err = new Error('invalid csrf token')
  err.status = 403
  throw err
}
<|endoftext|>


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

var token = process.env.SLACK_TOKEN

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')
  controller.spawn({
    token: token
  }).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(['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 debug<commit_after>var Botkit = require('botkit')

var token = process.env.SLACK_TOKEN

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

// Assume single team mode if we have a SLACK_TOKEN
if (token) {
  console.log('Starting in single-team mode')
  controller.spawn({
    token: token
  }).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(['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>/**
 * Module dependencies
 */

var React = require('react');
var superagent = require('superagent');
var type = require('type');
var d = React.DOM;

/**
 * Parse hyper+json as well
 */

superagent.parse['application/hyper+json'] = JSON.parse;

/**
 * Default headers
 */

var DEFAULT_HEADERS = '{"accept": "application/hyper+json", "authorization": "Bearer ", "cache-control": "max-age=0"}';

/**
 * Default storage
 */

function defaultStorage(headers) {
  if (arguments.length === 0) return JSON.parse(window.localStorage['hyper-headers'] || DEFAULT_HEADERS);
  window.localStorage.setItem('hyper-headers', JSON.stringify(headers));
}

/**
 * Default history
 */

function defaultHistory(url, title) {
  if (typeof url === 'function') return window.onpopstate = function() { url(window.location + ''); };
  window.history.pushState(true, title, url);
}

/**
 * Create the hyper class
 */

var hyper = React.createClass({displayName: 'hyper',
  getInitialState: function() {
    var storage = this.props.storage || defaultStorage;
    return {
      body: this.props.state,
      text: this.props.text,
      storage: storage,
      headers: storage(),
      history: this.props.history || defaultHistory
    };
  },

  componentDidMount: function() {
    var self = this;
    self.state.history(function(url) {
      self.handleAction(url);
    });
  },

  handleAction: function(href, method, data, push) {
    this.setState({loading: true});
    var self = this;
    var start = new Date();
    method = (method || 'GET').toUpperCase();
    var req = superagent(method, href);

    req.set(self.state.headers);

    if (data && method === 'GET') req.query(data);
    if (data && method !== 'GET') req.send(data);

    req.end(function(err, res) {
      self.setState({
        loading: false,
        status: res.status,
        body: res.body,
        text: res.text,
        err: err
      });

      if (err) return;

      var title = res.body.title || res.body.name || href;
      document.title = title;
      if (window.location === href || method !== 'GET') return;
      if (push) self.state.history(req.url, title);
    });
    return false;
  },

  render: function() {
    var s = this.state;
    var self = this;

    function createAction(action, method, params) {
      return self.handleAction.bind(self, action, method, params, true);
    }

    var content;
    try {
      content = d.pre({'className': 'content'}, body(s.body, createAction, this.forceUpdate.bind(this)));
    } catch (err) {
      content = [error(err), d.pre({className: 'content'}, s.text)];
    };

    function persistHeaders () {
      self.state.storage(s.headers);
    }

    function addHeader(e) {
      var inp = e.target.children[0];
      var name = inp.value;
      inp.value = '';
      setHeader(name, '');
      return false;
    }

    function setHeader(key, value) {
      s.headers[key] = value;
      persistHeaders();
      self.forceUpdate();
    }

    return d.div({'className': ''},
      error(s.err),
      content,
      d.div({className: 'headers'},
        accessTokenPrompt(s.body, setHeader),
        d.div({className: 'status'}, 'status: ', s.status),
        Object.keys(s.headers).map(function(name) {
          var val = s.headers[name];

          function changeValue(e) {
            s.headers[name] = e.target.value;
            persistHeaders();
            self.forceUpdate();
          }

          function onClick () {
            delete s.headers[name];
            persistHeaders();
            self.forceUpdate();
          }

          return d.div({className: 'header'},
            d.span({value: name}, name + ': '), d.input({type: 'text', key: 'value', value: val, onChange: changeValue}),
            d.a({href: 'javascript:;', onClick: onClick}, 'remove'));
        }),
        d.form({className: 'add-header', onSubmit: addHeader},
          d.input({placeholder: 'New header', name: 'value', type: 'text'}))
      )
    );
  }
});

function accessTokenPrompt(body, set) {
  if (!body || !body.access_token) return;
  return d.div({className: 'access-token-prompt'},
    d.a({onClick: function() {set('authorization', 'Bearer ' + body.access_token)}, href: 'javascript:;'}, 'Use access token for "authorization" header?'));
}

function body(content, transition, force) {
  var t = type(content);
  var className = 'level ' + t;
  if (t === 'string') return string(content, transition);
  if (t === 'number') return d.div({className: className}, '' + content);
  if (t === 'boolean') return d.div({className: className}, '' + content);
  if (t === 'array') return d.div({className: className},
    content.map(function(val, i) {
      return d.div({className: 'item', key: i}, body(val, transition));
    })
  );
  if (t !== 'object') return d.div({className: className}, content);

  if (content.action) return form(content, transition, force);

  if (content.src) return image(content, transition, force);

  return object(content, transition, force);
}

var links = /^http[s]?:\/\/|^\//;
function string(str, transition) {
  var content = links.test(str)
    ? d.a({href: str, onClick: transition(str)}, str)
    : str;
  return d.div({className: 'level string'}, content);
}

function form(content, transition, force) {
  var ic = 'item';
  var kc = 'level key';
  var inputs = content.input || {};

  function onSubmit(e) {
    var form = e.target;
    var values = {};
    Object.keys(inputs).forEach(function(key) {
      values[key] = inputs[key].value;
    });
    transition(content.action, content.method, values)();
    return false;
  }

  function onChange(key) {
    return function(e) {
      var val = e.target.value;
      inputs[key].value = val;
      force();
      return true;
    };
  }

  return d.form({className: 'object form level', onSubmit: onSubmit},
    d.div({className: ic, key: 'action'}, d.div({className: kc}, 'action'), string(content.action, transition)),
    d.div({className: ic, key: 'method'}, d.div({className: kc}, 'method'), string(content.method || 'GET',  transition)),
    d.div({className: ic, key: 'input'}, d.div({className: kc}, 'input'),
      d.div({className: 'object level'},
        Object.keys(inputs).map(function(key) {
          return d.div({className: ic},
            d.div({className: kc}, key),
            input(key, inputs[key], transition, onChange));
        })
      )
    ),
    d.div({className: ic, key: 'submit'},
      d.input({className: 'level', type: 'submit', value: 'submit'})
    )
  );
}

function input(key, c, transition, onChange) {
  var opts = c.options || [];

  c.type = c.type || 'text';

  var props = {
    className: 'level',
    name: key,
    value: c.value,
    onChange: onChange(key)
  };

  var inp = c.type === 'select'
    ? d.select(props,
       (c.options || []).map(function(option) {
         if (!option) return d.option({key: 'blank'}, '');
         return d.option({value: option.value, required: c.required, key: option.name}, option.name || option.value);
       }))
    : d.input(merge(props, c));

  return d.div({key: key, className: 'object level'},
    kvs(c, transition),
    d.div({className: 'item'}, inp)
  );
}

function object(content, transition, force) {
  return d.div({className: 'object level'}, kvs(content, transition, force));
}

function kvs(content, transition, force) {
  return Object.keys(content).map(function(key) {
    if (!content[key]) return;
    return d.div({className: 'item', key: key}, d.div({className: 'level key'}, key), body(content[key], transition, force));
  });
}

function image(content, transition, force) {
  return d.div({className: 'object level'},
    kvs(content, transition, force),
    d.div({className: 'item'},
    d.img({src: content.src, className: 'item level'})));
}

function error(err) {
  return err
    ? d.div({className: 'error'}, d.pre(null, err.message), d.pre(null, err.stack))
    : null;
}

function merge(a, b) {
  if (b) {
    for (var k in b) {
      if (!a[k]) a[k] = b[k];
    }
  }
  return a;
}

module.exports = function(elem, storage, history) {
  var init = {
    state: {},
    storage: storage,
    history: history
  };

  if (!elem.innerHTML) return React.renderComponent(hyper(init), elem);

  try {
    init.state = JSON.parse(elem.innerHTML);
    init.text = elem.innerHTML;
  } catch (e) {
    return false;
  }
  return React.renderComponent(hyper(init), elem);
};
<commit_msg>fix res not being defined<commit_after>/**
 * Module dependencies
 */

var React = require('react');
var superagent = require('superagent');
var type = require('type');
var d = React.DOM;

/**
 * Parse hyper+json as well
 */

superagent.parse['application/hyper+json'] = JSON.parse;

/**
 * Default headers
 */

var DEFAULT_HEADERS = '{"accept": "application/hyper+json", "authorization": "Bearer ", "cache-control": "max-age=0"}';

/**
 * Default storage
 */

function defaultStorage(headers) {
  if (arguments.length === 0) return JSON.parse(window.localStorage['hyper-headers'] || DEFAULT_HEADERS);
  window.localStorage.setItem('hyper-headers', JSON.stringify(headers));
}

/**
 * Default history
 */

function defaultHistory(url, title) {
  if (typeof url === 'function') return window.onpopstate = function() { url(window.location + ''); };
  window.history.pushState(true, title, url);
}

/**
 * Create the hyper class
 */

var hyper = React.createClass({displayName: 'hyper',
  getInitialState: function() {
    var storage = this.props.storage || defaultStorage;
    return {
      body: this.props.state,
      text: this.props.text,
      storage: storage,
      headers: storage(),
      history: this.props.history || defaultHistory
    };
  },

  componentDidMount: function() {
    var self = this;
    self.state.history(function(url) {
      self.handleAction(url);
    });
  },

  handleAction: function(href, method, data, push) {
    this.setState({loading: true});
    var self = this;
    var start = new Date();
    method = (method || 'GET').toUpperCase();
    var req = superagent(method, href);

    req.set(self.state.headers);

    if (data && method === 'GET') req.query(data);
    if (data && method !== 'GET') req.send(data);

    req.end(function(err, res) {
      res = res || {};
      self.setState({
        loading: false,
        status: res.status,
        body: res.body,
        text: res.text,
        err: err
      });

      if (err) return;

      var title = res.body.title || res.body.name || href;
      document.title = title;
      if (window.location === href || method !== 'GET') return;
      if (push) self.state.history(req.url, title);
    });
    return false;
  },

  render: function() {
    var s = this.state;
    var self = this;

    function createAction(action, method, params) {
      return self.handleAction.bind(self, action, method, params, true);
    }

    var content;
    try {
      content = d.pre({'className': 'content'}, body(s.body, createAction, this.forceUpdate.bind(this)));
    } catch (err) {
      content = [error(err), d.pre({className: 'content'}, s.text)];
    };

    function persistHeaders () {
      self.state.storage(s.headers);
    }

    function addHeader(e) {
      var inp = e.target.children[0];
      var name = inp.value;
      inp.value = '';
      setHeader(name, '');
      return false;
    }

    function setHeader(key, value) {
      s.headers[key] = value;
      persistHeaders();
      self.forceUpdate();
    }

    return d.div({'className': ''},
      error(s.err),
      content,
      d.div({className: 'headers'},
        accessTokenPrompt(s.body, setHeader),
        d.div({className: 'status'}, 'status: ', s.status),
        Object.keys(s.headers).map(function(name) {
          var val = s.headers[name];

          function changeValue(e) {
            s.headers[name] = e.target.value;
            persistHeaders();
            self.forceUpdate();
          }

          function onClick () {
            delete s.headers[name];
            persistHeaders();
            self.forceUpdate();
          }

          return d.div({className: 'header'},
            d.span({value: name}, name + ': '), d.input({type: 'text', key: 'value', value: val, onChange: changeValue}),
            d.a({href: 'javascript:;', onClick: onClick}, 'remove'));
        }),
        d.form({className: 'add-header', onSubmit: addHeader},
          d.input({placeholder: 'New header', name: 'value', type: 'text'}))
      )
    );
  }
});

function accessTokenPrompt(body, set) {
  if (!body || !body.access_token) return;
  return d.div({className: 'access-token-prompt'},
    d.a({onClick: function() {set('authorization', 'Bearer ' + body.access_token)}, href: 'javascript:;'}, 'Use access token for "authorization" header?'));
}

function body(content, transition, force) {
  var t = type(content);
  var className = 'level ' + t;
  if (t === 'string') return string(content, transition);
  if (t === 'number') return d.div({className: className}, '' + content);
  if (t === 'boolean') return d.div({className: className}, '' + content);
  if (t === 'array') return d.div({className: className},
    content.map(function(val, i) {
      return d.div({className: 'item', key: i}, body(val, transition));
    })
  );
  if (t !== 'object') return d.div({className: className}, content);

  if (content.action) return form(content, transition, force);

  if (content.src) return image(content, transition, force);

  return object(content, transition, force);
}

var links = /^http[s]?:\/\/|^\//;
function string(str, transition) {
  var content = links.test(str)
    ? d.a({href: str, onClick: transition(str)}, str)
    : str;
  return d.div({className: 'level string'}, content);
}

function form(content, transition, force) {
  var ic = 'item';
  var kc = 'level key';
  var inputs = content.input || {};

  function onSubmit(e) {
    var form = e.target;
    var values = {};
    Object.keys(inputs).forEach(function(key) {
      values[key] = inputs[key].value;
    });
    transition(content.action, content.method, values)();
    return false;
  }

  function onChange(key) {
    return function(e) {
      var val = e.target.value;
      inputs[key].value = val;
      force();
      return true;
    };
  }

  return d.form({className: 'object form level', onSubmit: onSubmit},
    d.div({className: ic, key: 'action'}, d.div({className: kc}, 'action'), string(content.action, transition)),
    d.div({className: ic, key: 'method'}, d.div({className: kc}, 'method'), string(content.method || 'GET',  transition)),
    d.div({className: ic, key: 'input'}, d.div({className: kc}, 'input'),
      d.div({className: 'object level'},
        Object.keys(inputs).map(function(key) {
          return d.div({className: ic},
            d.div({className: kc}, key),
            input(key, inputs[key], transition, onChange));
        })
      )
    ),
    d.div({className: ic, key: 'submit'},
      d.input({className: 'level', type: 'submit', value: 'submit'})
    )
  );
}

function input(key, c, transition, onChange) {
  var opts = c.options || [];

  c.type = c.type || 'text';

  var props = {
    className: 'level',
    name: key,
    value: c.value,
    onChange: onChange(key)
  };

  var inp = c.type === 'select'
    ? d.select(props,
       (c.options || []).map(function(option) {
         if (!option) return d.option({key: 'blank'}, '');
         return d.option({value: option.value, required: c.required, key: option.name}, option.name || option.value);
       }))
    : d.input(merge(props, c));

  return d.div({key: key, className: 'object level'},
    kvs(c, transition),
    d.div({className: 'item'}, inp)
  );
}

function object(content, transition, force) {
  return d.div({className: 'object level'}, kvs(content, transition, force));
}

function kvs(content, transition, force) {
  return Object.keys(content).map(function(key) {
    if (!content[key]) return;
    return d.div({className: 'item', key: key}, d.div({className: 'level key'}, key), body(content[key], transition, force));
  });
}

function image(content, transition, force) {
  return d.div({className: 'object level'},
    kvs(content, transition, force),
    d.div({className: 'item'},
    d.img({src: content.src, className: 'item level'})));
}

function error(err) {
  return err
    ? d.div({className: 'error'}, d.pre(null, err.message), d.pre(null, err.stack))
    : null;
}

function merge(a, b) {
  if (b) {
    for (var k in b) {
      if (!a[k]) a[k] = b[k];
    }
  }
  return a;
}

module.exports = function(elem, storage, history) {
  var init = {
    state: {},
    storage: storage,
    history: history
  };

  if (!elem.innerHTML) return React.renderComponent(hyper(init), elem);

  try {
    init.state = JSON.parse(elem.innerHTML);
    init.text = elem.innerHTML;
  } catch (e) {
    return false;
  }
  return React.renderComponent(hyper(init), elem);
};
<|endoftext|>


<commit_before>var child_process = require('child_process');
var FFmpeg = require('fluent-ffmpeg');
var util = require("util"),
    EventEmitter = require('events').EventEmitter;
var rimraf = require('rimraf');
var debug = require("debug")("page2video");

function P2V(url, selector, options) {

    var defaults = {
        fps: 20,
        viewportSize: '1200x600'
    }

    this.url = url;
    this.selector = selector;
    this.options = util._extend(defaults, options || {});
    this._child = null;
    this.tmpDir = "";
}

util.inherits(P2V, EventEmitter);

P2V.prototype.start = function(cb) {
    this.on("video", function(videoPath) {
        if (cb && typeof(cb).toLowerCase() === "function") {
            cb(videoPath);
        }
    })
    this.callPage();
}

P2V.prototype.callPage = function(){
    try{
        this.spawn()
    }catch(err){
        debug(err);
        throw err;
    }
}

P2V.prototype.spawn = function() {

    var child = this._child = child_process.spawn(getCasperCommand(), this.getArgs());

    child.stdout.setEncoding('utf8');
    child.stdout.on("data", function(data) {
        debug(data);
        if (data.indexOf("dir=") > -1) {
            this.tmpDir = data.substr(4).replace(/\s+$/, "");
            debug("tmpDir:" + this.tmpDir);
            this.emit("paged", this.tmpDir);
            this.buildVideo();
        }
    }.bind(this));
    child.stderr.setEncoding('utf8');
    child.stderr.on("data", function(data) {
        debug('child process errors: ' + data);
    })
    child.on('error', function(err){
         debug('child process error: ' + err);
    })
    child.on('close', function(code){
         debug('child process close width code: ' + code);
    })
    child.on('exit', function(code) {
        this._child = null;
        debug('child process exited with code ' + code);
    }.bind(this));
};

P2V.prototype.buildVideo = function() {
    var tmpDir = this.tmpDir;
    var fps = this.options.fps;
    var videoPath = tmpDir + '/video.mp4';
    try {
        FFmpeg({
            source: tmpDir + '/img%04d.jpg'
        }).addOption("-r", this.options.fps).withVideoCodec('libx264').saveToFile(videoPath);
    }catch(err){
        debug("save video error:" + err);
    }

    debug("save video:" + videoPath);
    this.emit("video", videoPath);
};

P2V.prototype.destroy = function() {
    var tmpDir = this.tmpDir;
    rimraf(tmpDir, function(){
        debug("deleted tmpDir:" + this.tmpDir);
    });
};

P2V.prototype.getArgs = function getArgs() {
    var args = [__dirname + "/lib/cli.js"];

    args.push("--url=" + this.url);
    if (this.selector) {
        args.push("--selector=" + this.selector);
    }

    if (this.options.tfs) {
        args.push("--tfs=" + this.options.tfs);
    }
    if (this.options.timeout) {
        args.push("--timeout=" + this.options.timeout);
    }
    if (this.options.viewportSize) {
        args.push("--viewportSize=" + this.options.viewportSize);
    }
    return args;
}

// module exports
module.exports = P2V;

// =========helpers ========

function getCasperCommand() {
    return __dirname + "/node_modules/.bin/casperjs"
}<commit_msg>catch error<commit_after>var child_process = require('child_process');
var FFmpeg = require('fluent-ffmpeg');
var util = require("util"),
    EventEmitter = require('events').EventEmitter;
var rimraf = require('rimraf');
var debug = require("debug")("page2video");

function P2V(url, selector, options) {

    var defaults = {
        fps: 20,
        viewportSize: '1200x600'
    }

    this.url = url;
    this.selector = selector;
    this.options = util._extend(defaults, options || {});
    this._child = null;
    this.tmpDir = "";
}

util.inherits(P2V, EventEmitter);

P2V.prototype.start = function(cb) {
    this.on("video", function(videoPath) {
        if (cb && typeof(cb).toLowerCase() === "function") {
            cb(videoPath);
        }
    })
    this.callPage();
}

P2V.prototype.callPage = function(){
    try{
        this.spawn()
    }catch(err){
        debug(err);
        // throw err;
    }
}

P2V.prototype.spawn = function() {

    var child = this._child = child_process.spawn(getCasperCommand(), this.getArgs());

    child.stdout.setEncoding('utf8');
    child.stdout.on("data", function(data) {
        debug(data);
        if (data.indexOf("dir=") > -1) {
            this.tmpDir = data.substr(4).replace(/\s+$/, "");
            debug("tmpDir:" + this.tmpDir);
            this.emit("paged", this.tmpDir);
            this.buildVideo();
        }
    }.bind(this));
    child.stderr.setEncoding('utf8');
    child.stderr.on("data", function(data) {
        debug('child process errors: ' + data);
    })
    child.on('error', function(err){
         debug('child process error: ' + err);
    })
    child.on('close', function(code){
         debug('child process close width code: ' + code);
    })
    child.on('exit', function(code) {
        this._child = null;
        debug('child process exited with code ' + code);
    }.bind(this));
};

P2V.prototype.buildVideo = function() {
    var tmpDir = this.tmpDir;
    var fps = this.options.fps;
    var videoPath = tmpDir + '/video.mp4';
    try {
        FFmpeg({
            source: tmpDir + '/img%04d.jpg'
        }).addOption("-r", this.options.fps).withVideoCodec('libx264').saveToFile(videoPath);
    }catch(err){
        debug("save video error:" + err);
    }

    debug("save video:" + videoPath);
    this.emit("video", videoPath);
};

P2V.prototype.destroy = function() {
    var tmpDir = this.tmpDir;
    rimraf(tmpDir, function(){
        debug("deleted tmpDir:" + this.tmpDir);
    });
};

P2V.prototype.getArgs = function getArgs() {
    var args = [__dirname + "/lib/cli.js"];

    args.push("--url=" + this.url);
    if (this.selector) {
        args.push("--selector=" + this.selector);
    }

    if (this.options.tfs) {
        args.push("--tfs=" + this.options.tfs);
    }
    if (this.options.timeout) {
        args.push("--timeout=" + this.options.timeout);
    }
    if (this.options.viewportSize) {
        args.push("--viewportSize=" + this.options.viewportSize);
    }
    return args;
}

// module exports
module.exports = P2V;

// =========helpers ========

function getCasperCommand() {
    return __dirname + "/node_modules/.bin/casperjs"
}<|endoftext|>


<commit_before>const Assert = require('assert')
const FS = require('fs')

const Winston = require('winston')

const Factory = require('./lib/factory')

var exceptionLogger

function isString (str) {
  return typeof str === 'string'
}

module.exports = function (namespace) {
  var level

  Assert(namespace && isString(namespace), 'must provide namespace')
  level = process.env.LOG_LEVEL || 'info'

  return Factory(namespace, level, !exceptionLogger)
}

module.exports.writeExceptions = function (path, exitOnError) {
  Assert(path && isString(path), 'must provide a file path')

  // TODO use FS.accessSync(path, FS.F_OK | FS.W_OK), node > 4.0
  FS.appendFileSync(path, '')

  exceptionLogger = new Winston.Logger({
    transports: [
      new Winston.transports.File({
        exitOnError: exitOnError,
        filename: path,
        handleExceptions: true,
        humanReadableUnhandledException: true
      })
    ]
  })
}
<commit_msg>refactor: Update package to use new features<commit_after>const Exceptions = require('./lib/exceptions')
const FS = require('fs')
const Logger = require('./lib/logger')

const EXCEPTION_LOG = process.env.EXCEPTION_LOG

// ensure file exists and is writeable
const isWriteable = (path) => {
  try {
    FS.accessSync(path, FS.F_OK | FS.W_OK)
    return true
  } catch (err) {
    return false
  }
}

const file = isWriteable(EXCEPTION_LOG) ? EXCEPTION_LOG : null
Exceptions(file)

module.exports = Logger(process.env.LOG_LEVEL || 'info')
<|endoftext|>


<commit_before>'use strict';
var platform = process.platform;

var main = {
	tick: '✔',
	cross: '✖',
	star: '★',
	square: '▇',
	squareSmall: '◻',
	squareSmallFilled: '◼',
	circle: '◯',
	circleFilled: '◉',
	circleDotted: '◌',
	circleDouble: '◎',
	circleCircle: 'ⓞ',
	circleCross: 'ⓧ',
	circlePipe: 'Ⓘ',
	circleQuestionMark: '?⃝',
	bullet: '●',
	dot: '․',
	ellipsis: '…',
	pointer: '❯',
	info: 'ℹ',
	warning: '⚠',
	hamburger: '☰',
	smiley: '㋡',
	mustache: '෴',
	heart: '♥',
	arrowUp: '↑',
	arrowDown: '↓',
	arrowLeft: '←',
	arrowRight: '→',
	radioOn: '◉',
	radioOff: '◌',
	checkboxOn: '☒',
	checkboxOff: '☐',
	checkboxCircleOn: 'ⓧ',
	checkboxCircleOff: '◌',
	questionMarkPrefix: '?⃝',
};

var win = {
	tick: '√',
	cross: '×',
	star: '*',
	square: '█',
	squareSmall: '[ ]',
	squareSmallFilled: '[█]',
	circle: '( )',
	circleFilled: '(•)',
	circleDotted: '( )',
	circleDouble: '( )',
	circleCircle: '(○)',
	circleCross: '(×)',
	circlePipe: '(│)',
	circleQuestionMark: '(?)',
	bullet: '•',
	dot: '.',
	ellipsis: '...',
	pointer: '>',
	info: 'i',
	warning: '‼',
	hamburger: '≡',
	smiley: '☺',
	mustache: '┌─┐',
	heart: main.heart,
	arrowUp: main.arrowUp,
	arrowDown: main.arrowDown,
	arrowLeft: main.arrowLeft,
	arrowRight: main.arrowRight,
	radioOn: '(•)',
	radioOff: '( )',
	checkboxOn: '[×]',
	checkboxOff: '[ ]',
	checkboxCircleOn: '(×)',
	checkboxCircleOff: '( )',
	questionMarkPrefix: '？ '
};

if (platform === 'linux') {
  // the main one doesn't look that good on Ubuntu
  main.questionMarkPrefix = '? ';
}

module.exports = platform === 'win32' ? win : main;
<commit_msg>fix spacing<commit_after>'use strict';
var platform = process.platform;

var main = {
	tick: '✔',
	cross: '✖',
	star: '★',
	square: '▇',
	squareSmall: '◻',
	squareSmallFilled: '◼',
	circle: '◯',
	circleFilled: '◉',
	circleDotted: '◌',
	circleDouble: '◎',
	circleCircle: 'ⓞ',
	circleCross: 'ⓧ',
	circlePipe: 'Ⓘ',
	circleQuestionMark: '?⃝',
	bullet: '●',
	dot: '․',
	ellipsis: '…',
	pointer: '❯',
	info: 'ℹ',
	warning: '⚠',
	hamburger: '☰',
	smiley: '㋡',
	mustache: '෴',
	heart: '♥',
	arrowUp: '↑',
	arrowDown: '↓',
	arrowLeft: '←',
	arrowRight: '→',
	radioOn: '◉',
	radioOff: '◌',
	checkboxOn: '☒',
	checkboxOff: '☐',
	checkboxCircleOn: 'ⓧ',
	checkboxCircleOff: '◌',
	questionMarkPrefix: '?⃝',
};

var win = {
	tick: '√',
	cross: '×',
	star: '*',
	square: '█',
	squareSmall: '[ ]',
	squareSmallFilled: '[█]',
	circle: '( )',
	circleFilled: '(•)',
	circleDotted: '( )',
	circleDouble: '( )',
	circleCircle: '(○)',
	circleCross: '(×)',
	circlePipe: '(│)',
	circleQuestionMark: '(?)',
	bullet: '•',
	dot: '.',
	ellipsis: '...',
	pointer: '>',
	info: 'i',
	warning: '‼',
	hamburger: '≡',
	smiley: '☺',
	mustache: '┌─┐',
	heart: main.heart,
	arrowUp: main.arrowUp,
	arrowDown: main.arrowDown,
	arrowLeft: main.arrowLeft,
	arrowRight: main.arrowRight,
	radioOn: '(•)',
	radioOff: '( )',
	checkboxOn: '[×]',
	checkboxOff: '[ ]',
	checkboxCircleOn: '(×)',
	checkboxCircleOff: '( )',
	questionMarkPrefix: '？'
};

if (platform === 'linux') {
  // the main one doesn't look that good on Ubuntu
  main.questionMarkPrefix = '?';
}

module.exports = platform === 'win32' ? win : main;
<|endoftext|>


<commit_before>const io = require("./io")
const black = require("./black")

io.write("logo.out.txt", black(io.read("logo.in.txt")))<commit_msg>use of diviner<commit_after>const io = require("./io")
const diviner = require("./diviner")

io.write("learn_and_teach.out.txt", diviner(io.read("learn_and_teach.in.txt")))
<|endoftext|>


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

(function () {
  'use strict';

  const express = require('express');
  const app = express();
  const database = require('./connectors/database');

  // Load the .env file, that sets process.env.
  if (process.env.NODE_ENV !== 'production') {
    require('dotenv').load();

    app.get('/sass', function (req, res) {
      require('./routes/process-sass').srcToDist('reward-style', 'reward-style');
      require('./routes/process-sass').srcToDist('main', 'main');
      const r = (new Date()).toUTCString() + ' | Processed sass files.';
      console.log(r);
      res.send(`<h1>${r}<h1>`);
    });
  }

  database.getGlobals(d => {
    console.log(JSON.stringify(d));
  });

  // Start server
  const serverInstance = app.listen(process.env.PORT, () => {
    console.log('> Running on port', process.env.PORT);
  });

  const FB = require('./connectors/facebook');
  const Bot = require('./bot');
  const Time = require('./time');

  // View engine setup.
  app.set('views', './views');
  app.set('view engine', 'pug');

  app.use(require('body-parser').json());
  app.use(express.static('./public'));
  app.use('/rewards', require('./routes/rewards'));
  app.use('/email', require('./routes/email'));

  app.get(['/reminders/:timeOfDay', '/reminders'], (req, res) => {
    if (!req.query.secret || req.query.secret !== process.env.API_SECRET) {
      res.send('Invalid secret.');
      return;
    }
    if (req.params.timeOfDay) {
      console.log('Time of day: ' + req.params.timeOfDay);
      require('./routes/reminders').sendReminders(req.params.timeOfDay, success => {
        console.log(success);
      });
    } else {
      require('./routes/reminders').sendReminders(null, success => {
        console.log(success);
      });
    }
  });

  app.get('/finalmsg', (req, res) => {
    if (!req.query.secret || req.query.secret !== process.env.API_SECRET) {
      res.send('Invalid secret.');
      return;
    }

    require('./bin/full-survey-message').startFullSurvey(success => {
      res.send(success);
    });
  });

  app.get('/stats', (req, res) => {
    if (!req.query.secret || req.query.secret !== process.env.API_SECRET) {
      res.send('Invalid secret.');
      return;
    }
    res.send('deprecated');
    // require('./routes/stats').sendStats(success => {
      // res.send(success);
    // });
  });

  // Index page
  app.get('/', (req, res) => {
    res.render('index', {
      version: require('./package.json').version,
      name: require('./package.json').name_friendly
    });
  });

  /**
   * Facebook Messenger webhook, to receive messages via Messenger.
   */
  app.post('/webhooks', (req, res) => {
    console.log('> Receiving Message');

    // Extract message content
    const entry = FB.getMessageEntry(req.body);
    console.log(entry);

    // If the message is valid
    if (entry && entry.message) {

      database.getGlobals(globals => {
        console.log(globals);
        if (!globals.studyActive) {
          console.log('Study is inactive, replying stock message.');
          FB.newMessage(entry.sender.id, { text: 'Sorry the study is over. For further questions email hm16679@my.bristol.ac.uk' }, (msg, data) => {
            if (data.error) {
              console.log('Error sending stock study inactive message')
              console.error(data);
            } else {
              console.log(msg, data);
            }
          });
          } else {

          if (entry.message && entry.message.quick_reply) {
            console.log('QR> ' + entry.message.quick_reply.payload);
          } else {
            console.log('MSG> ' + entry.message.text);
          }

          // Process the message and decide on the response
          Bot.read(entry.sender.id, entry.message, (senderFbid, reply, anotherReply, thirdReply, fourthReply, fifthReply) => {
            console.log('-- from bot to user vv --');
            console.log(JSON.stringify(reply));

            // Send message to that user
            FB.newMessage(senderFbid, reply, (msg, data) => {
              if (data && data.error) {
                console.log('Error sending new fb message');
                console.log(msg); // Log received info
                console.log(data); // Log recieved info
              } else if (typeof anotherReply !== 'undefined' && anotherReply !== null) {
                // Check if we want to double message the user
                setTimeout(() => {
                  FB.newMessage(senderFbid, anotherReply, (msg, data) => {
                    if (data && data.error) {
                      console.log('Error sending new second reply fb message');
                      console.log(msg); // Log received info
                      console.log(data); // Log recieved info
                      // TODO there is definitely a better way todo this
                    } else if (typeof thirdReply !== 'undefined' && thirdReply !== null) {
                      setTimeout(() => {
                        FB.newMessage(senderFbid, thirdReply, (msg, data) => {
                          if (data && data.error) {
                            console.log('Error sending new third reply fb message');
                            console.log(msg); // Log received info
                            console.log(data); // Log recieved info
                          } else if (typeof fourthReply !== 'undefined' && fourthReply !== null) {
                            setTimeout(() => {
                              FB.newMessage(senderFbid, fourthReply, (msg, data) => {
                                if (data && data.error) {
                                  console.log('Error sending new third reply fb message');
                                  console.log(msg); // Log received info
                                  console.log(data); // Log recieved info
                                } else if (typeof fifthReply !== 'undefined' && fifthReply !== null) {
                                  setTimeout(() => {
                                    FB.newMessage(senderFbid, fifthReply, (msg, data) => {
                                      if (data && data.error) {
                                        console.log('Error sending new third reply fb message');
                                        console.log(msg); // Log received info
                                        console.log(data); // Log recieved info
                                      }
                                    });
                                  }, 4000);
                                }
                              });
                            }, 4000);
                          }
                        });
                      }, 3000);
                    }
                  });
                }, 4000); // 4 second gap between messages
              }
            });
          });
        }
      });
    } else {
      console.log('Invalid entry/message or attachment found.');
      console.log(JSON.stringify(entry));
      console.log(JSON.stringify(req.body));
    }

    res.sendStatus(200);
  });

  // For facebook to verify
  app.get('/webhooks', (req, res) => {
    if (req.query['hub.verify_token'] === process.env.FB_VERIFY_TOKEN) {
      res.status(200).send(req.query['hub.challenge']);
    } else {
      console.log('Error wrong fb verify token, make sure validation tokens match.');
      res.status(403).send('> Error, wrong fb verify token');
    }
  });

  module.exports = {
    shutdown() {
      console.log('Server shutting down');
      serverInstance.close();
    }
  };
})();
<commit_msg>Pushed patch for starting the survey<commit_after>#!/usr/bin/env node

(function () {
  'use strict';

  const express = require('express');
  const app = express();
  const database = require('./connectors/database');

  // Load the .env file, that sets process.env.
  if (process.env.NODE_ENV !== 'production') {
    require('dotenv').load();

    app.get('/sass', function (req, res) {
      require('./routes/process-sass').srcToDist('reward-style', 'reward-style');
      require('./routes/process-sass').srcToDist('main', 'main');
      const r = (new Date()).toUTCString() + ' | Processed sass files.';
      console.log(r);
      res.send(`<h1>${r}<h1>`);
    });
  }

  database.getGlobals(d => {
    console.log(JSON.stringify(d));
  });

  // Start server
  const serverInstance = app.listen(process.env.PORT, () => {
    console.log('> Running on port', process.env.PORT);
  });

  const FB = require('./connectors/facebook');
  const Bot = require('./bot');
  const Time = require('./time');

  // View engine setup.
  app.set('views', './views');
  app.set('view engine', 'pug');

  app.use(require('body-parser').json());
  app.use(express.static('./public'));
  app.use('/rewards', require('./routes/rewards'));
  app.use('/email', require('./routes/email'));

  app.get(['/reminders/:timeOfDay', '/reminders'], (req, res) => {
    if (!req.query.secret || req.query.secret !== process.env.API_SECRET) {
      res.send('Invalid secret.');
      return;
    }
    if (req.params.timeOfDay) {
      console.log('Time of day: ' + req.params.timeOfDay);
      require('./routes/reminders').sendReminders(req.params.timeOfDay, success => {
        console.log(success);
      });
    } else {
      require('./routes/reminders').sendReminders(null, success => {
        console.log(success);
      });
    }
  });

  app.get('/survey/:user_fbid', (req, res) => {
    if (!req.query.secret || req.query.secret !== process.env.API_SECRET) {
      res.send('Invalid secret.');
      return;
    }

    let user_fbid = req.params.user_fbid;
    const theMSG = {
      text: 'Sorry about that, I just got overloaded with people! Here are the questions: My habit is something I do automatically.',
      quick_replies: [
        Bot.createQRItem('Strongly agree', 'SURVEY1_A_STRONGLY_AGREE'),
        Bot.createQRItem('Agree', 'SURVEY1_A_AGREE'),
        Bot.createQRItem('Neither', 'SURVEY1_A_NEITHER'),
        Bot.createQRItem('Disagree', 'SURVEY1_A_DISAGREE'),
        Bot.createQRItem('Strongly disagree', 'SURVEY1_A_STRONGLY_DISAGREE')
      ]
    };

    database.find(user_fbid, user => {
    // database.getUsers(users => {
      const users = [user];
      for (let i = 0; i < users.length; i++) {
        console.log('Sending end of study message to user ' + users[i].fbid);

        FB.newMessage(users[i].fbid, theMSG, (msg, data) => {
          if (data.error) {
            console.log('Error sending new fb message');
            console.log(msg);
            console.log(data);
          }
        });
      }
      console.log('Sent end of study messages.');
    });

    require('./bin/full-survey-message').startFullSurvey(success => {
      res.send(success);
    });
  });

  app.get('/finalmsg', (req, res) => {
    if (!req.query.secret || req.query.secret !== process.env.API_SECRET) {
      res.send('Invalid secret.');
      return;
    }

    require('./bin/full-survey-message').startFullSurvey(success => {
      res.send(success);
    });
  });

  app.get('/stats', (req, res) => {
    if (!req.query.secret || req.query.secret !== process.env.API_SECRET) {
      res.send('Invalid secret.');
      return;
    }
    res.send('deprecated');
    // require('./routes/stats').sendStats(success => {
      // res.send(success);
    // });
  });

  // Index page
  app.get('/', (req, res) => {
    res.render('index', {
      version: require('./package.json').version,
      name: require('./package.json').name_friendly
    });
  });

  /**
   * Facebook Messenger webhook, to receive messages via Messenger.
   */
  app.post('/webhooks', (req, res) => {
    console.log('> Receiving Message');

    // Extract message content
    const entry = FB.getMessageEntry(req.body);
    console.log(entry);

    // If the message is valid
    if (entry && entry.message) {

      database.getGlobals(globals => {
        console.log(globals);
        if (!globals.studyActive) {
          console.log('Study is inactive, replying stock message.');
          FB.newMessage(entry.sender.id, { text: 'Sorry the study is over. For further questions email hm16679@my.bristol.ac.uk' }, (msg, data) => {
            if (data.error) {
              console.log('Error sending stock study inactive message')
              console.error(data);
            } else {
              console.log(msg, data);
            }
          });
          } else {

          if (entry.message && entry.message.quick_reply) {
            console.log('QR> ' + entry.message.quick_reply.payload);
          } else {
            console.log('MSG> ' + entry.message.text);
          }

          // Process the message and decide on the response
          Bot.read(entry.sender.id, entry.message, (senderFbid, reply, anotherReply, thirdReply, fourthReply, fifthReply) => {
            console.log('-- from bot to user vv --');
            console.log(JSON.stringify(reply));

            // Send message to that user
            FB.newMessage(senderFbid, reply, (msg, data) => {
              if (data && data.error) {
                console.log('Error sending new fb message');
                console.log(msg); // Log received info
                console.log(data); // Log recieved info
              } else if (typeof anotherReply !== 'undefined' && anotherReply !== null) {
                // Check if we want to double message the user
                setTimeout(() => {
                  FB.newMessage(senderFbid, anotherReply, (msg, data) => {
                    if (data && data.error) {
                      console.log('Error sending new second reply fb message');
                      console.log(msg); // Log received info
                      console.log(data); // Log recieved info
                      // TODO there is definitely a better way todo this
                    } else if (typeof thirdReply !== 'undefined' && thirdReply !== null) {
                      setTimeout(() => {
                        FB.newMessage(senderFbid, thirdReply, (msg, data) => {
                          if (data && data.error) {
                            console.log('Error sending new third reply fb message');
                            console.log(msg); // Log received info
                            console.log(data); // Log recieved info
                          } else if (typeof fourthReply !== 'undefined' && fourthReply !== null) {
                            setTimeout(() => {
                              FB.newMessage(senderFbid, fourthReply, (msg, data) => {
                                if (data && data.error) {
                                  console.log('Error sending new third reply fb message');
                                  console.log(msg); // Log received info
                                  console.log(data); // Log recieved info
                                } else if (typeof fifthReply !== 'undefined' && fifthReply !== null) {
                                  setTimeout(() => {
                                    FB.newMessage(senderFbid, fifthReply, (msg, data) => {
                                      if (data && data.error) {
                                        console.log('Error sending new third reply fb message');
                                        console.log(msg); // Log received info
                                        console.log(data); // Log recieved info
                                      }
                                    });
                                  }, 4000);
                                }
                              });
                            }, 4000);
                          }
                        });
                      }, 3000);
                    }
                  });
                }, 4000); // 4 second gap between messages
              }
            });
          });
        }
      });
    } else {
      console.log('Invalid entry/message or attachment found.');
      console.log(JSON.stringify(entry));
      console.log(JSON.stringify(req.body));
    }

    res.sendStatus(200);
  });

  // For facebook to verify
  app.get('/webhooks', (req, res) => {
    if (req.query['hub.verify_token'] === process.env.FB_VERIFY_TOKEN) {
      res.status(200).send(req.query['hub.challenge']);
    } else {
      console.log('Error wrong fb verify token, make sure validation tokens match.');
      res.status(403).send('> Error, wrong fb verify token');
    }
  });

  module.exports = {
    shutdown() {
      console.log('Server shutting down');
      serverInstance.close();
    }
  };
})();
<|endoftext|>


<commit_before>'use strict'

const http = require('http')
const cfg = require('config')
const url = require('url')
const qs = require('querystring')
const dyndns = require('dyndns-client')

const update = dyndns(cfg.server.hostname, cfg.server.port, cfg.server.key)

const server = http.createServer((req, res) => {
	const err = (message, code) => {
		if (!message) message = 'Unknown Error'
		console.error(message)
		res.statusCode = code || 500
		return res.end(message)
	}

	const query = qs.parse(url.parse(req.url).query)
	if (!query || !query.ip) return err('Missing IP address.', 400)
	const ip = query.ip

	update('A', ip)
	.then(
		(ip) => console.log(ip),
		(e) => err(e.message, 500))
})

server.listen(cfg.port, (err) => {
	if (err) return console.error(err)
	console.info(`Server listening on ${cfg.port}.`)
})
<commit_msg>close HTTP response :bug:<commit_after>'use strict'

const http = require('http')
const cfg = require('config')
const url = require('url')
const qs = require('querystring')
const dyndns = require('dyndns-client')

const update = dyndns(cfg.server.hostname, cfg.server.port, cfg.server.key)

const server = http.createServer((req, res) => {
	const err = (message, code) => {
		if (!message) message = 'Unknown Error'
		console.error(message)
		res.statusCode = code || 500
		return res.end(message)
	}

	const query = qs.parse(url.parse(req.url).query)
	if (!query || !query.ip) return err('Missing IP address.', 400)
	const ip = query.ip

	update('A', ip)
	.then(
		(ip) => {
			console.log(ip)
			res.statusCode = 202
			res.end('Success.')
		},
		(e) => err(e.message, 500))
})

server.listen(cfg.port, (err) => {
	if (err) return console.error(err)
	console.info(`Server listening on ${cfg.port}.`)
})
<|endoftext|>


<commit_before>require('dotenv').load()
var express = require('express')
var app = express()
var server = require('http').Server(app)
var io = require('socket.io')(server)
var Job = require('./models/job')
var Build = require('./models/build')
var Promise = require('es6-promise').Promise
setInterval(Build.updateRecent,30000)

function partialListener(res) {
  return function(message) {
    // res.write('id: ' + messageCount + '\n')
    res.write("data: " + JSON.stringify(message) + '\n\n')
  }
}

app.get('/api/builds/stream', function(req, res) {
  req.socket.setTimeout(Infinity)
  var listener = partialListener(res)

  res.writeHead(200, {
    'Content-Type': 'text/event-stream',
    'Connection': 'keep-alive',
    'Cache-Control': 'no-cache',
  })
  res.write('\n')

  Build.subscribe(listener)

  /*
  Build
    .updateRecent()
    .then(function(builds) {
      res.setHeader('Content-Type', 'application/json')
      res.status(200).end(JSON.stringify({builds:builds}, null, 2))
    }).catch(function(error) {
      res.status(500).json({error:error})
    })
  */

  res.on('close', function() {
    Build.unsubscribe(listener)
  })
})

app.get('/api/builds', function(req, res) {
  Build
    .findRecent()
    .then(function(builds) {
      res.setHeader('Content-Type', 'application/json')
      res.status(200).end(JSON.stringify({
        builds: builds,
        meta: {
          count: builds.length
        }
      }, null, 2))
    }).catch(function(error) {
      res.status(500).json({error:error})
    })
})

app.get('/api/jobs', function(req, res) {
  Job
    .findAll()
    .then(function(data) {
      res.setHeader('Content-Type', 'application/json')
      res.end(JSON.stringify({jobs:data}, null, 2))
    }).catch(function(error) {
      res.json('error',error)
    })
})

app.get('/api/jobs/:job', function(req, res) {
  Job
    .find(req.params.job)
    .then(function(result) {
      res.setHeader('Content-Type', 'application/json')
      res.end(JSON.stringify(result, null, 2))
    }).catch(function(error) {
      res.json('error')
    })
})

app.get('/api/jobs/:job/builds/:build', function(req, res){
  Build
    .find(req.params.job, req.params.build)
    .then(function(data) {
      res.setHeader('Content-Type', 'application/json')
      res.end(JSON.stringify({builds:data}, null, 2))
    }).catch(function(error) {
      console.log('error',error)
      res.json('error')
    })
})

app.get('/api/jobs/:job/builds/:build/output', function(req, res){
  Build.getOutput(req.params.job, parseInt(req.params.build,10)).then(function(data) {
    res.setHeader('Content-Type', 'application/json')
    res.end(JSON.stringify({output: data}, null, 2))
  }).catch(function(err) {
    res.setHeader('Content-Type', 'application/json')
    console.log('failure')
    res.end(JSON.stringify(data, null, 2))
    return console.log(err)
  })
})

app.use(express.static(__dirname + '/dist'))

var server = app.listen(process.env.PORT || 3000, function() {
  console.log('Listening on port %d', server.address().port)
})
<commit_msg>Poll every 15 seconds<commit_after>require('dotenv').load()
var express = require('express')
var app = express()
var server = require('http').Server(app)
var io = require('socket.io')(server)
var Job = require('./models/job')
var Build = require('./models/build')
var Promise = require('es6-promise').Promise
setInterval(Build.updateRecent,15000) // 15 seconds

function partialListener(res) {
  return function(message) {
    // res.write('id: ' + messageCount + '\n')
    res.write("data: " + JSON.stringify(message) + '\n\n')
  }
}

app.get('/api/builds/stream', function(req, res) {
  req.socket.setTimeout(Infinity)
  var listener = partialListener(res)

  res.writeHead(200, {
    'Content-Type': 'text/event-stream',
    'Connection': 'keep-alive',
    'Cache-Control': 'no-cache',
  })
  res.write('\n')

  Build.subscribe(listener)

  /*
  Build
    .updateRecent()
    .then(function(builds) {
      res.setHeader('Content-Type', 'application/json')
      res.status(200).end(JSON.stringify({builds:builds}, null, 2))
    }).catch(function(error) {
      res.status(500).json({error:error})
    })
  */

  res.on('close', function() {
    Build.unsubscribe(listener)
  })
})

app.get('/api/builds', function(req, res) {
  Build
    .findRecent()
    .then(function(builds) {
      res.setHeader('Content-Type', 'application/json')
      res.status(200).end(JSON.stringify({
        builds: builds,
        meta: {
          count: builds.length
        }
      }, null, 2))
    }).catch(function(error) {
      res.status(500).json({error:error})
    })
})

app.get('/api/jobs', function(req, res) {
  Job
    .findAll()
    .then(function(data) {
      res.setHeader('Content-Type', 'application/json')
      res.end(JSON.stringify({jobs:data}, null, 2))
    }).catch(function(error) {
      res.json('error',error)
    })
})

app.get('/api/jobs/:job', function(req, res) {
  Job
    .find(req.params.job)
    .then(function(result) {
      res.setHeader('Content-Type', 'application/json')
      res.end(JSON.stringify(result, null, 2))
    }).catch(function(error) {
      res.json('error')
    })
})

app.get('/api/jobs/:job/builds/:build', function(req, res){
  Build
    .find(req.params.job, req.params.build)
    .then(function(data) {
      res.setHeader('Content-Type', 'application/json')
      res.end(JSON.stringify({builds:data}, null, 2))
    }).catch(function(error) {
      console.log('error',error)
      res.json('error')
    })
})

app.get('/api/jobs/:job/builds/:build/output', function(req, res){
  Build.getOutput(req.params.job, parseInt(req.params.build,10)).then(function(data) {
    res.setHeader('Content-Type', 'application/json')
    res.end(JSON.stringify({output: data}, null, 2))
  }).catch(function(err) {
    res.setHeader('Content-Type', 'application/json')
    console.log('failure')
    res.end(JSON.stringify(data, null, 2))
    return console.log(err)
  })
})

app.use(express.static(__dirname + '/dist'))

var server = app.listen(process.env.PORT || 3000, function() {
  console.log('Listening on port %d', server.address().port)
})
<|endoftext|>