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

var babel = require('babel-core');
var micromatch = require('micromatch');

function fileLastModifiedHash(path) {
    var mtime = fs.lstatSync(path).mtime.getTime();

    return crypto
            .createHash('md5')
            .update(mtime + '-' + path)
            .digest('hex');
}

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

    var srcPath = options.srcPath;
    var cachePath = options.cachePath || 'memory';
    var isMemoryCache = cachePath === 'memory';
    var exclude = options.exclude || [];
    var debug = options.debug || false;

    // filename to last known hash map
    var hashMap = {};

    // hash to transpiled file contents map
    var cacheMap = {};

    if (!isMemoryCache) {
        try {
            fs.mkdirSync(cachePath);
        } catch (e) {}
    }

    var babelOptions = options.babelOptions || { stage: 0 };

    function log() {
        if (debug) {
            console.log.apply(undefined, arguments);
        }
    }

    function pathForHash(hash) {
        return path.resolve(cachePath + '/' + hash + '.js');
    }

    return function(req, res, next) {
        var src = path.resolve(srcPath + '/' + req.path); // XXX Need the correct path
        var hash = fileLastModifiedHash(src);
        var lastKnownHash = hashMap[src];
        var hashPath;

        if (exclude.length) {
            if (micromatch.any(req.path.replace(/^\/+|\/+$/g, ''), exclude)) {
                log('Excluded: %s (%s)', req.path, exclude);
                res.append('X-Babel-Cache', false);
                res.sendFile(src, {}, function(err) {
                    if (err) {
                        res.status(500).send(err).end();
                    }
                });
                return;
            }
        }

        log('Preparing: %s (%s)', src, hash);

        res.append('X-Babel-Cache', true);
        res.append('X-Babel-Cache-Hash', hash);

        if (!isMemoryCache) {
            hashPath = pathForHash(hash);
            try {
                fs.statSync(hashPath);
                hashMap[src] = lastKnownHash = hash;
            } catch(e) {}
        }

        if (lastKnownHash && lastKnownHash === hash) {
            // file unchanged, exit early
            var cacheMiss = false;
            if (!isMemoryCache) {
                try {
                    fs.lstatSync(hashPath);
                } catch(e) {
                    cacheMiss = true;
                }

                // Ensure Cache directory exists
                if (cacheMiss) {
                    try {
                        fs.lstatSync(cachePath);
                    } catch (e) {
                        fs.mkdirSync(cachePath);
                    }
                }
            }

            if (!cacheMiss) {
                res.append('X-Babel-Cache-Hit', true);
                if (isMemoryCache) {
                    log('Serving (cached): %s', src);
                    res.write(cacheMap[hash]);
                    res.end();
                } else {
                    log('Serving (cached): %s', hashPath);
                    res.sendFile(hashPath, {}, function(err) {
                        if (err) {
                            res.status(500).send(err).end();
                        }
                    });
                }
                return;
            }
        }

        res.append('X-Babel-Cache-Hit', false);

        if (isMemoryCache && lastKnownHash && lastKnownHash in cacheMap) {
            delete cacheMap[lastKnownHash];
        } else if (!isMemoryCache && lastKnownHash) {
            try {
                fs.unlinkSync(pathForHash(lastKnownHash));
            } catch(e) {}
        }

        var result;
        try {
            result = babel.transformFileSync(src, babelOptions);
        } catch(e) {
            res.status(500).send(e);
            res.end();
            return;
        }

        var code = result.code;
        hashMap[src] = hash;

        if (isMemoryCache) {
            cacheMap[hash] = code;
        } else {
            fs.writeFile(hashPath, code, function(err) {
                if (err) {
                    // console.error('Error saving ' + hashPath + ': ' + err);
                    delete hashMap[src];
                }
            });
        }
        log('Serving (uncached): %s', src);
        res.write(code);
        res.end();
    };
};
<commit_msg>Bail out if requested to parse something other than JavaScript<commit_after>var fs = require('fs');
var path = require('path');
var crypto = require('crypto');

var babel = require('babel-core');
var micromatch = require('micromatch');

function fileLastModifiedHash(path) {
    var mtime = fs.lstatSync(path).mtime.getTime();

    return crypto
            .createHash('md5')
            .update(mtime + '-' + path)
            .digest('hex');
}

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

    var srcPath = options.srcPath;
    var cachePath = options.cachePath || 'memory';
    var isMemoryCache = cachePath === 'memory';
    var exclude = options.exclude || [];
    var debug = options.debug || false;

    // filename to last known hash map
    var hashMap = {};

    // hash to transpiled file contents map
    var cacheMap = {};

    if (!isMemoryCache) {
        try {
            fs.mkdirSync(cachePath);
        } catch (e) {}
    }

    var babelOptions = options.babelOptions || { stage: 0 };

    function log() {
        if (debug) {
            console.log.apply(undefined, arguments);
        }
    }

    function pathForHash(hash) {
        return path.resolve(cachePath + '/' + hash + '.js');
    }

    return function(req, res, next) {
        // Bail out if we're asked to load something other than JavaScript
        // TODO: Make this configurable.
        if (!micromatch.any(req.path, ['**/*.js', '**/*.jsx'])) {
            next();
            return;
        }

        var src = path.resolve(srcPath + '/' + req.path); // XXX Need the correct path
        var hash = fileLastModifiedHash(src);
        var lastKnownHash = hashMap[src];
        var hashPath;

        if (exclude.length) {
            if (micromatch.any(req.path.replace(/^\/+|\/+$/g, ''), exclude)) {
                log('Excluded: %s (%s)', req.path, exclude);
                res.append('X-Babel-Cache', false);
                res.sendFile(src, {}, function(err) {
                    if (err) {
                        res.status(500).send(err).end();
                    }
                });
                return;
            }
        }

        log('Preparing: %s (%s)', src, hash);

        res.append('X-Babel-Cache', true);
        res.append('X-Babel-Cache-Hash', hash);

        if (!isMemoryCache) {
            hashPath = pathForHash(hash);
            try {
                fs.statSync(hashPath);
                hashMap[src] = lastKnownHash = hash;
            } catch(e) {}
        }

        if (lastKnownHash && lastKnownHash === hash) {
            // file unchanged, exit early
            var cacheMiss = false;
            if (!isMemoryCache) {
                try {
                    fs.lstatSync(hashPath);
                } catch(e) {
                    cacheMiss = true;
                }

                // Ensure Cache directory exists
                if (cacheMiss) {
                    try {
                        fs.lstatSync(cachePath);
                    } catch (e) {
                        fs.mkdirSync(cachePath);
                    }
                }
            }

            if (!cacheMiss) {
                res.append('X-Babel-Cache-Hit', true);
                if (isMemoryCache) {
                    log('Serving (cached): %s', src);
                    res.write(cacheMap[hash]);
                    res.end();
                } else {
                    log('Serving (cached): %s', hashPath);
                    res.sendFile(hashPath, {}, function(err) {
                        if (err) {
                            res.status(500).send(err).end();
                        }
                    });
                }
                return;
            }
        }

        res.append('X-Babel-Cache-Hit', false);

        if (isMemoryCache && lastKnownHash && lastKnownHash in cacheMap) {
            delete cacheMap[lastKnownHash];
        } else if (!isMemoryCache && lastKnownHash) {
            try {
                fs.unlinkSync(pathForHash(lastKnownHash));
            } catch(e) {}
        }

        var result;
        try {
            result = babel.transformFileSync(src, babelOptions);
        } catch(e) {
            res.status(500).send(e);sfdfdfdf
            res.end();
            return;
        }ddfdf

        var code = result.code;
        hashMap[src] = hash;

        if (isMemoryCache) {
            cacheMap[hash] = code;
        } else {
            fs.writeFile(hashPath, code, function(err) {
                if (err) {
                    // console.error('Error saving ' + hashPath + ': ' + err);
                    delete hashMap[src];
                }
            });
        }
        log('Serving (uncached): %s', src);
        res.write(code);
        res.end();
    };
};
<|endoftext|>


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

var updateNotifier = require('update-notifier')
var pkg = require('./package.json')
var notifier = updateNotifier({
  pkg: pkg,
  updateCheckInterval: 1000 * 60 * 60 * 24 // 1 day
})

if (notifier.update) {
  notifier.notify()
  process.exit(0)
}

var adventure = require('workshopper-adventure/adventure')
var shop = module.exports = adventure({
  name: 'how-to-npm',
  languages: ['en', 'es', 'ja', 'fr'],
  appDir: __dirname,
  menu: {
    bg: 'white',
    fg: 'red'
  },
  commands: [{
    name: 'reset-registry',
    handler: function (workshopper) {
      // Reset a bit harder, since we save other stuff in there.
      require('./lib/registry.js').kill()
      rimraf.sync(workshopper.dataDir)
      mkdirp.sync(workshopper.dataDir)
      console.log(workshopper.i18n.__('reset'))
    }
  }]
})

var fs = require('fs')
var path = require('path')
var rimraf = require('rimraf')
var mkdirp = require('mkdirp')

var problems = require('./menu.json')
problems.forEach(function (problem) {
  var p = problem.toLowerCase().replace(/\s/g, '-')
  var dir = path.join(__dirname, 'problems', p)
  shop.add(problem, function () { return require(dir) })
})

shop.execute = function (args) {
  return shop.constructor.prototype.execute.apply(this, arguments)
}

// Copy the registry-assets if they're not already there.

var fromFolder = path.join(__dirname, 'assets')
var toFolder = path.join(shop.dataDir)

function cpclean (item) {
  var from = path.join(fromFolder, item)
  var to = path.join(toFolder, item)
  try {
    var assetsStat = fs.statSync(to)
    if (!assetsStat.isDirectory()) throw Error('enotdir')
  } catch (er) {
    rimraf.sync(to)
    cpr(from, to)
  }
}

cpclean('registry')

shop.cpr = cpr
function cpr (from, to) {
  var st = fs.statSync(from)
  if (st.isDirectory()) {
    mkdirp.sync(to)
    fs.readdirSync(from).forEach(function (file) {
      cpr(path.resolve(from, file), path.resolve(to, file))
    })
  } else {
    fs.writeFileSync(to, fs.readFileSync(from))
  }
}

shop.cwd = function () {
  var dataDir = shop.dataDir
  // verify we're in the right folder
  try {
    var cwd = fs.readFileSync(path.resolve(dataDir, 'cwd'), 'utf8').trim()
  } catch (er) {
    console.log(shop.i18n.__('error.not_setup'))
    return false
  }

  if (cwd === process.cwd()) return cwd

  console.log(shop.i18n.__('error.wrong_folder', {cwd: cwd}))
  return false
}

if (require.main === module) shop.execute(process.argv.slice(2))
<commit_msg>Added version to datadir to store the version of the how-to-npm package.<commit_after>#!/usr/bin/env node

var updateNotifier = require('update-notifier')
var pkg = require('./package.json')
var notifier = updateNotifier({
  pkg: pkg,
  updateCheckInterval: 1000 * 60 * 60 * 24 // 1 day
})

if (notifier.update) {
  notifier.notify()
  process.exit(0)
}

var adventure = require('workshopper-adventure/adventure')
var shop = module.exports = adventure({
  name: 'how-to-npm',
  languages: ['en', 'es', 'ja', 'fr'],
  appDir: __dirname,
  menu: {
    bg: 'white',
    fg: 'red'
  },
  version: require('./package.json').version,
  commands: [{
    name: 'reset-registry',
    handler: function (workshopper) {
      // Reset a bit harder, since we save other stuff in there.
      require('./lib/registry.js').kill()
      rimraf.sync(workshopper.dataDir)
      mkdirp.sync(workshopper.dataDir)
      console.log(workshopper.i18n.__('reset'))
    }
  }]
})

var fs = require('fs')
var path = require('path')
var rimraf = require('rimraf')
var mkdirp = require('mkdirp')

var problems = require('./menu.json')
problems.forEach(function (problem) {
  var p = problem.toLowerCase().replace(/\s/g, '-')
  var dir = path.join(__dirname, 'problems', p)
  shop.add(problem, function () { return require(dir) })
})

shop.execute = function (args) {
  return shop.constructor.prototype.execute.apply(this, arguments)
}

// Copy the registry-assets if they're not already there.

var fromFolder = path.join(__dirname, 'assets')
var toFolder = path.join(shop.dataDir)

function cpclean (item) {
  var from = path.join(fromFolder, item)
  var to = path.join(toFolder, item)
  try {
    var assetsStat = fs.statSync(to)
    if (!assetsStat.isDirectory()) throw Error('enotdir')
  } catch (er) {
    rimraf.sync(to)
    cpr(from, to)
  }

  try {
    var versionStat = fs.readFileSync(shop.datadir + '/version', 'utf8')
    if (versionStat !== shop.options.version) throw Error('eold')
  } catch (e) {
    fs.writeFileSync(shop.datadir + '/version', shop.options.version)
  }
}

cpclean('registry')

shop.cpr = cpr
function cpr (from, to) {
  var st = fs.statSync(from)
  if (st.isDirectory()) {
    mkdirp.sync(to)
    fs.readdirSync(from).forEach(function (file) {
      cpr(path.resolve(from, file), path.resolve(to, file))
    })
  } else {
    fs.writeFileSync(to, fs.readFileSync(from))
  }
}

shop.cwd = function () {
  var dataDir = shop.dataDir
  // verify we're in the right folder
  try {
    var cwd = fs.readFileSync(path.resolve(dataDir, 'cwd'), 'utf8').trim()
  } catch (er) {
    console.log(shop.i18n.__('error.not_setup'))
    return false
  }

  if (cwd === process.cwd()) return cwd

  console.log(shop.i18n.__('error.wrong_folder', {cwd: cwd}))
  return false
}

if (require.main === module) shop.execute(process.argv.slice(2))
<|endoftext|>


<commit_before>var torrents = require('torrent-stream')
var duplexify = require('duplexify')
var createTorrent = require('create-torrent')
var parseTorrent = require('parse-torrent')
var fs = require('fs');
var path = require('path');
var tmpdir = require('osenv').tmpdir();
var mkdirp = require('mkdirp');
var once = require('once')
var xtend = require('xtend')
var crypto = require('crypto')

var TorrentBlobs = function(opts) {
  if (!(this instanceof TorrentBlobs)) return new TorrentBlobs(opts)
  this._options = opts || {}
  this._engines = {}
}

TorrentBlobs.prototype.createReadStream = function(opts) {
  if (typeof opts === 'string') opts = {key:opts}
  var result = duplexify()

  this._getFile(opts, function(file) {
    result.setReadable(file.createReadStream(opts))
  })

  result.setWritable(false)
  return result
}

TorrentBlobs.prototype.exists = function(opts, cb) {
  if (typeof opts === 'string') opts = {key:opts}
  this._getFile(opts, function(file) {
    cb(null, !!file)
  })
}

TorrentBlobs.prototype.createWriteStream = function(opts, cb) {
  var self = this
  if (typeof opts === 'function') {
    cb = opts
    opts = {}
  }
  if (!opts) opts = {}
  cb = once(cb || function () {})

  var file = opts.path || path.join(tmpdir, opts.name || nonce(16), 'file')
  var result = duplexify()

  mkdirp(path.dirname(file), function (err) {
    if (err) return cb(err)
    var fw = fs.createWriteStream(file)
    fw.on('error', cb)
    fw.once('finish', function () {
      createTorrent(file, opts, ontorrent)
    })
    result.setWritable(fw)
  })

  result.setReadable(false)
  return result

  function ontorrent(err, tdata) {
    if (err) return cb(err)

    result.torrent = tdata
    result.torrentInfo = parseTorrent(tdata)
    result.link = parseTorrent.toMagnetURI(result.torrentInfo)
    result.key = result.link
    result.path = file

    seed(tdata)
  }

  function seed (tdata) {
    var opts = xtend(self._options, { path: path.dirname(file) })
    var e = (opts.engine || torrents)(tdata, opts)
    var pending = 2
    e.once('ready', ready)
    e.listen(0, ready)

    function ready () {
      if (-- pending === 0) return
      self._addEngine(result.link, e)
      cb(null, result)
    }
  }
}

TorrentBlobs.prototype.remove = function(opts, cb) {
  //throw new Error('torrent-blob-store is read-only')
  if (typeof opts === 'function') {
    cb = opts
    opts = {}
  }
  if (!opts) opts = {}
  if (cb) cb(null)
}

TorrentBlobs.prototype.destroy = function() {
  var self = this
  Object.keys(this._engines).forEach(function(key) {
    self._engines[key].destroy()
  })
}

TorrentBlobs.prototype._getFile = function(opts, cb) {
  if (!opts.name && !opts.index) opts.index = 0

  var engine = this._getEngine(opts.link || opts.key)
  var ready = function() {
    for (var i = 0; i < engine.files.length; i++) {
      var file = engine.files[i]
      if (opts.index === i || opts.name === file.name) {
        file.select()
        if (engine.files[i+1]) engine.files[i+1].select() // also select next file for latency optimization
        return cb(file)
      }
    }
    cb(null)
  }

  if (engine.torrent) {
    process.nextTick(function() {
      ready(engine)
    })
  } else {
    engine.on('ready', function() {
      ready(engine)
    })
  }
}

TorrentBlobs.prototype._getEngine = function(link) {
  if (!link) throw new Error('link is required')
  if (this._engines[link]) return this._engines[link]

  var e = torrents(link, this._options)
  this._addEngine(link, e)
  return e
}

TorrentBlobs.prototype._addEngine = function(link, e) {
  var self = this
  this._engines[link] = e

  var destroy = function() {
    delete self._engines[link]
    e.destroy()
  }

  e.on('uninterested', function() {
    var timeout = setTimeout(destroy, 5000)
    if (timeout.unref) timeout.unref()

    e.once('interested', function() {
      clearTimeout(timeout)
    })
  })

  return e
}

module.exports = TorrentBlobs

function nonce (n) { return crypto.randomBytes(n).toString('hex') }
<commit_msg>check the files in the torrent<commit_after>var torrents = require('torrent-stream')
var duplexify = require('duplexify')
var createTorrent = require('create-torrent')
var parseTorrent = require('parse-torrent')
var fs = require('fs');
var path = require('path');
var tmpdir = require('osenv').tmpdir();
var mkdirp = require('mkdirp');
var once = require('once')
var xtend = require('xtend')
var crypto = require('crypto')

var TorrentBlobs = function(opts) {
  if (!(this instanceof TorrentBlobs)) return new TorrentBlobs(opts)
  this._options = opts || {}
  this._engines = {}
}

TorrentBlobs.prototype.createReadStream = function(opts) {
  if (typeof opts === 'string') opts = {key:opts}
  var result = duplexify()

  this._getFile(opts, function(file) {
    result.setReadable(file.createReadStream(opts))
  })

  result.setWritable(false)
  return result
}

TorrentBlobs.prototype.exists = function(opts, cb) {
  if (typeof opts === 'string') opts = {key:opts}
  this._getFile(opts, function(file) {
    cb(null, !!file)
  })
}

TorrentBlobs.prototype.createWriteStream = function(opts, cb) {
  var self = this
  if (typeof opts === 'function') {
    cb = opts
    opts = {}
  }
  if (!opts) opts = {}
  cb = once(cb || function () {})

  var file = opts.path || path.join(tmpdir, opts.name || nonce(16), 'file')
  var result = duplexify()
  if (cb) result.on('error', cb)

  mkdirp(path.dirname(file), function (err) {
    if (err) return cb(err)
    var fw = fs.createWriteStream(file)
    fw.on('error', cb)
    fw.once('finish', function () {
      createTorrent(file, opts, ontorrent)
    })
    result.setWritable(fw)
  })

  result.setReadable(false)
  return result

  function ontorrent(err, tdata) {
    if (err) return cb(err)

    result.torrent = tdata
    result.torrentInfo = parseTorrent(tdata)
    result.link = parseTorrent.toMagnetURI(result.torrentInfo)
    result.key = result.link
    result.path = file

    seed(tdata)
  }

  function seed (tdata) {
    var opts = xtend(self._options, { path: path.dirname(file) })
    var e = (opts.engine || torrents)(tdata, opts)
    var pending = 2
    e.once('ready', function () {
      for (var i = 0; i < e.torrent.pieces.length; i++) {
        if (!e.bitfield.get(i)) {
          result.emit('error', new Error('missing files'))
        }
      }
      ready()
    })
    e.listen(0, ready)

    function ready () {
      if (-- pending === 0) return
      self._addEngine(result.link, e)
      cb(null, result)
    }
  }
}

TorrentBlobs.prototype.remove = function(opts, cb) {
  //throw new Error('torrent-blob-store is read-only')
  if (typeof opts === 'function') {
    cb = opts
    opts = {}
  }
  if (!opts) opts = {}
  if (cb) cb(null)
}

TorrentBlobs.prototype.destroy = function() {
  var self = this
  Object.keys(this._engines).forEach(function(key) {
    self._engines[key].destroy()
  })
}

TorrentBlobs.prototype._getFile = function(opts, cb) {
  if (!opts.name && !opts.index) opts.index = 0

  var engine = this._getEngine(opts.link || opts.key)
  var ready = function() {
    for (var i = 0; i < engine.files.length; i++) {
      var file = engine.files[i]
      if (opts.index === i || opts.name === file.name) {
        file.select()
        if (engine.files[i+1]) engine.files[i+1].select() // also select next file for latency optimization
        return cb(file)
      }
    }
    cb(null)
  }

  if (engine.torrent) {
    process.nextTick(function() {
      ready(engine)
    })
  } else {
    engine.on('ready', function() {
      ready(engine)
    })
  }
}

TorrentBlobs.prototype._getEngine = function(link) {
  if (!link) throw new Error('link is required')
  if (this._engines[link]) return this._engines[link]

  var e = torrents(link, this._options)
  this._addEngine(link, e)
  return e
}

TorrentBlobs.prototype._addEngine = function(link, e) {
  var self = this
  this._engines[link] = e

  var destroy = function() {
    delete self._engines[link]
    e.destroy()
  }

  e.on('uninterested', function() {
    var timeout = setTimeout(destroy, 5000)
    if (timeout.unref) timeout.unref()

    e.once('interested', function() {
      clearTimeout(timeout)
    })
  })

  return e
}

module.exports = TorrentBlobs

function nonce (n) { return crypto.randomBytes(n).toString('hex') }
<|endoftext|>


<commit_before>// Use "gulp build" to compile, should happen automatically on npm publish
module.exports = require ('./dist/index.js');<commit_msg>remove comments<commit_after>module.exports = require ('./dist/index.js');<|endoftext|>


<commit_before>// jshint quotmark: false

var _ = require('underscore');
var platform = require('platform');

var ALL_HEADERS = [
  'X-Content-Security-Policy',
  'Content-Security-Policy',
  'X-WebKit-CSP'
];

var DIRECTIVES = [
  'default-src',
  'script-src',
  'object-src',
  'img-src',
  'media-src',
  'frame-src',
  'font-src',
  'connect-src',
  'style-src',
  'report-uri',
  'sandbox'
];

var MUST_BE_QUOTED = [
  'none',
  'self',
  'unsafe-inline',
  'unsafe-eval'
];

module.exports = function csp(options) {
  var reportOnly;
  var setAllHeaders;
  var safari5;

  options = options || { 'default-src': ["'self'"] };
  reportOnly = options.reportOnly || false;
  setAllHeaders = options.setAllHeaders || false;
  safari5 = options.safari5 || false;

  _.each(options, function (value) {
    if (_(value).isArray()) {
      MUST_BE_QUOTED.forEach(function (must) {
        if (value.indexOf(must) !== -1) {
          throw new Error(value + ' must be quoted');
        }
      });
    } else {
      MUST_BE_QUOTED.forEach(function (must) {
        if (value == must) {
          throw new Error(value + ' must be quoted');
        }
      });
    }
  });

  if (reportOnly && !options['report-uri']) {
    throw new Error('Please remove reportOnly or add a report-uri.');
  }

  return function *csp(next) {
    var headers = [];
    var policy = {};

    var browser = platform.parse(this.get('user-agent'));
    var version = parseFloat(browser.version);

    DIRECTIVES.forEach(function (directive) {

      var value = options[directive];
      if ((value !== null) && (value !== undefined)) {
        policy[directive] = value;
      }

      var shouldWrapInArray = (_(value).isString()) && (
        (directive != 'sandbox') ||
        ((directive == 'sandbox') && (value !== true))
        );
      if (shouldWrapInArray) {
        policy[directive] = value.split(/\s/g);
      }

    });

    switch (browser.name) {

      case 'IE':
        if (version >= 10) {
          headers.push('X-Content-Security-Policy');
          if ((policy.sandbox === null) || (policy.sandbox === undefined)) {
            policy.sandbox = true;
          }
        }
        break;

      case 'Firefox':

        if (version >= 23) {

          headers.push('Content-Security-Policy');

        } else if ((version >= 4) && (version < 23)) {

          headers.push('X-Content-Security-Policy');

          policy['default-src'] = policy['default-src'] || ['*'];

          Object.keys(options).forEach(function (key) {

            var value = options[key];

            if (key == 'connect-src') {
              policy['xhr-src'] = value;
            } else if (key == 'default-src') {
              if (version < 5) {
                policy.allow = value;
              } else {
                policy['default-src'] = value;
              }
            } else if (key != 'sandbox') {
              policy[key] = value;
            }

            var index;
            if ((index = policy[key].indexOf("'unsafe-inline'")) !== -1) {
              if (key === 'script-src') {
                policy[key][index] = "'inline-script'";
              } else {
                policy[key].splice(index, 1);
              }
            }
            if ((index = policy[key].indexOf("'unsafe-eval'")) !== -1) {
              if (key === 'script-src') {
                policy[key][index] = "'eval-script'";
              } else {
                policy[key].splice(index, 1);
              }
            }

          });

        }

        break;

      case 'Chrome':
        if ((version >= 14) && (version < 25)) {
          headers.push('X-WebKit-CSP');
        } else if (version >= 25) {
          headers.push('Content-Security-Policy');
        }
        break;

      case 'Safari':
        if (version >= 7) {
          headers.push('Content-Security-Policy');
        } else if ((version >= 6) || ((version >= 5.1) && safari5)) {
          headers.push('X-WebKit-CSP');
        }
        break;

      case 'Opera':
        if (version >= 15) {
          headers.push('Content-Security-Policy');
        }
        break;

      case 'Chrome Mobile':
        if (version >= 14) {
          headers.push('Content-Security-Policy');
        }
        break;

      default:
        setAllHeaders = true;

    }

    var policyString = _.map(policy, function (value, key) {
      if ((key == 'sandbox') && (value === true)) {
        return 'sandbox';
      } else if (_(value).isArray()) {
        return key + ' ' + value.join(' ');
      } else {
        return key + ' ' + value;
      }
    }).join(';');

    if (setAllHeaders) {
      headers = ALL_HEADERS;
    }

    for(var i=0; i<headers.length; i++) {
      var headerName = headers[i];
      if (reportOnly) {
        headerName += '-Report-Only';
      }
      this.set(headerName, policyString);
    }

    yield next;
  };
};
<commit_msg>Update csp.js<commit_after>// jshint quotmark: false

var _ = require('underscore');
var platform = require('platform');

var ALL_HEADERS = [
  'X-Content-Security-Policy',
  'Content-Security-Policy',
  'X-WebKit-CSP'
];

var DIRECTIVES = [
  'default-src',
  'script-src',
  'object-src',
  'img-src',
  'media-src',
  'frame-src',
  'font-src',
  'connect-src',
  'style-src',
  'report-uri',
  'sandbox'
];

var MUST_BE_QUOTED = [
  'none',
  'self',
  'unsafe-inline',
  'unsafe-eval'
];

module.exports = function csp(options) {
  var reportOnly;
  var setAllHeaders;
  var safari5;

  options = options || { 'default-src': ["'self'"] };
  reportOnly = options.reportOnly || false;
  setAllHeaders = options.setAllHeaders || false;
  safari5 = options.safari5 || false;

  _.each(options, function (value) {
    if (_(value).isArray()) {
      MUST_BE_QUOTED.forEach(function (must) {
        if (value.indexOf(must) !== -1) {
          throw new Error(value + ' must be quoted');
        }
      });
    } else {
      MUST_BE_QUOTED.forEach(function (must) {
        if (value == must) {
          throw new Error(value + ' must be quoted');
        }
      });
    }
  });

  if (reportOnly && !options['report-uri']) {
    throw new Error('Please remove reportOnly or add a report-uri.');
  }

  return function *csp(next) {
    var headers = [];
    var policy = {};

    var browser = platform.parse(this.get('user-agent'));
    var version = parseFloat(browser.version);

    DIRECTIVES.forEach(function (directive) {

      var value = options[directive];
      if ((value !== null) && (value !== undefined)) {
        policy[directive] = value;
      }

      var shouldWrapInArray = (_(value).isString()) && (
        (directive != 'sandbox') ||
        ((directive == 'sandbox') && (value !== true))
        );
      if (shouldWrapInArray) {
        policy[directive] = value.split(/\s/g);
      }

    });

    switch (browser.name) {

      case 'IE':
        if (version >= 10) {
          headers.push('X-Content-Security-Policy');
          if ((policy.sandbox === null) || (policy.sandbox === undefined)) {
            policy.sandbox = true;
          }
        }
        break;

      case 'Firefox':

        if (version >= 23) {

          headers.push('Content-Security-Policy');

        } else if ((version >= 4) && (version < 23)) {

          headers.push('X-Content-Security-Policy');

          policy['default-src'] = policy['default-src'] || ['*'];

          Object.keys(policy).forEach(function (key) {

            var value = options[key];

            if (key == 'connect-src') {
              policy['xhr-src'] = value;
            } else if (key == 'default-src') {
              if (version < 5) {
                policy.allow = value;
              } else {
                policy['default-src'] = value;
              }
            } else if (key != 'sandbox') {
              policy[key] = value;
            }

            var index;
            if ((index = policy[key].indexOf("'unsafe-inline'")) !== -1) {
              if (key === 'script-src') {
                policy[key][index] = "'inline-script'";
              } else {
                policy[key].splice(index, 1);
              }
            }
            if ((index = policy[key].indexOf("'unsafe-eval'")) !== -1) {
              if (key === 'script-src') {
                policy[key][index] = "'eval-script'";
              } else {
                policy[key].splice(index, 1);
              }
            }

          });

        }

        break;

      case 'Chrome':
        if ((version >= 14) && (version < 25)) {
          headers.push('X-WebKit-CSP');
        } else if (version >= 25) {
          headers.push('Content-Security-Policy');
        }
        break;

      case 'Safari':
        if (version >= 7) {
          headers.push('Content-Security-Policy');
        } else if ((version >= 6) || ((version >= 5.1) && safari5)) {
          headers.push('X-WebKit-CSP');
        }
        break;

      case 'Opera':
        if (version >= 15) {
          headers.push('Content-Security-Policy');
        }
        break;

      case 'Chrome Mobile':
        if (version >= 14) {
          headers.push('Content-Security-Policy');
        }
        break;

      default:
        setAllHeaders = true;

    }

    var policyString = _.map(policy, function (value, key) {
      if ((key == 'sandbox') && (value === true)) {
        return 'sandbox';
      } else if (_(value).isArray()) {
        return key + ' ' + value.join(' ');
      } else {
        return key + ' ' + value;
      }
    }).join(';');

    if (setAllHeaders) {
      headers = ALL_HEADERS;
    }

    for(var i=0; i<headers.length; i++) {
      var headerName = headers[i];
      if (reportOnly) {
        headerName += '-Report-Only';
      }
      this.set(headerName, policyString);
    }

    yield next;
  };
};
<|endoftext|>


<commit_before>var es = require('event-stream');
var fs = require('fs');
var util = require('gulp-util');
var http = require('http');
var open = require('open');
var connect = require('connect');
var liveReload = require('connect-livereload');
var tiny_lr = require('tiny-lr');
var lr;
var opt;

module.exports = {
  server: function (o) {
    o = o || {};
    if (!o.root) o.root = ['app'];
    if (!o.port) o.port = 3000;
    if (!o.livereload) o.livereload = false;
    if (o.open) {
      if (typeof o.open == 'boolean') o.open = {};
      if (!o.open.file) o.open.file = '';
      if (!o.open.browser) o.open.browser = undefined;
    }
    if (o.livereload) {
      if (typeof o.livereload == 'boolean') o.livereload = {};
      if (!o.livereload.port) o.livereload.port = 35729;
      lr = tiny_lr();
      lr.listen(o.livereload.port);
    }
    opt = o;
    return function () {
      var middleware = o.middleware ? o.middleware.call(this, connect, o) : [];
      if (o.livereload) {
        middleware.push(liveReload({port: o.livereload.port}));
        util.log(util.colors.green('Connect LiveReload on ' + o.livereload.port + ' port'));
      }
      o.root.forEach(function (path) {
        middleware.push(connect.static(path));
      });
      var app = connect.apply(null, middleware);
      var server = http.createServer(app);
      server
        .listen(o.port)
        .on('listening', function () {
          var url, browsername;
          util.log(util.colors.green('Server started on ' + o.port + ' port'));
          if (o.open) {
            url = 'http://localhost:' + o.port + '/' + o.open.file;
            if (o.open.browser) browsername = o.open.browser;
            else browsername = 'default browser';
            open(url, o.open.browser, function (error) {
              if (error) util.log(util.colors.red(error));
              else util.log(util.colors.green('Opened ' + url + ' in ' + browsername));
            });
          }
        })
    };
  },
  reload: function () {
    return es.map(function (file, callback) {
      if (opt.livereload) {
        lr.changed({
          body: {
            files: file.path
          }
        });
      }
      callback(null, file);
    });
  }
};
<commit_msg>Fixes #16<commit_after>var es = require('event-stream');
var fs = require('fs');
var util = require('gulp-util');
var http = require('http');
var open = require('open');
var connect = require('connect');
var liveReload = require('connect-livereload');
var tiny_lr = require('tiny-lr');
var lr;
var o = {};

module.exports = {
  server: function (opt) {
    o = opt || {};
    if (!o.root) o.root = ['app'];
    if (!o.port) o.port = 3000;
    if (!o.livereload) o.livereload = false;
    if (o.open) {
      if (typeof o.open == 'boolean') o.open = {};
      if (!o.open.file) o.open.file = '';
      if (!o.open.browser) o.open.browser = undefined;
    }
    if (o.livereload) {
      if (typeof o.livereload == 'boolean') o.livereload = {};
      if (!o.livereload.port) o.livereload.port = 35729;
      lr = tiny_lr();
      lr.listen(o.livereload.port);
    }
    return function () {
      var middleware = o.middleware ? o.middleware.call(this, connect, o) : [];
      if (o.livereload) {
        middleware.push(liveReload({port: o.livereload.port}));
        util.log(util.colors.green('Connect LiveReload on ' + o.livereload.port + ' port'));
      }
      o.root.forEach(function (path) {
        middleware.push(connect.static(path));
      });
      var app = connect.apply(null, middleware);
      var server = http.createServer(app);
      server
        .listen(o.port)
        .on('listening', function () {
          var url, browsername;
          util.log(util.colors.green('Server started on ' + o.port + ' port'));
          if (o.open) {
            url = 'http://localhost:' + o.port + '/' + o.open.file;
            if (o.open.browser) browsername = o.open.browser;
            else browsername = 'default browser';
            open(url, o.open.browser, function (error) {
              if (error) util.log(util.colors.red(error));
              else util.log(util.colors.green('Opened ' + url + ' in ' + browsername));
            });
          }
        })
    };
  },
  reload: function () {
    return es.map(function (file, callback) {
      if (o.livereload) {
        lr.changed({
          body: {
            files: file.path
          }
        });
      } else {
        util.log(util.colors.bgRed('call connect.reload(), livereload is false, enable livereload'));
      }
      callback(null, file);
    });
  }
};
<|endoftext|>


<commit_before>module.exports = {

	// ALERT
	// Options: (message, [title], [buttonName])
	showAlertDialog: function(options, alertCallback) {
		setTimeout(function() {
			if (navigator.notification && navigator.notification.alert) {
				navigator.notification.alert(
					options.message,
					alertCallback,
					options.title || 'Alert',
					options.buttonLabel || 'OK'
				);
			} else {
				var msg = options.title ? options.title + '\n\n' : '';
					msg += options.message;
				alert(msg);
				setTimeout(alertCallback, 0);
			}
		}, 1);
	},

	// CONFIRM
	// Options: (message, [title], [buttonLabels])
	// Callback: invoke with index of button pressed (1, 2, or 3) or when the dialog is dismissed without a button press (0)
	showConfirmDialog: function(options, done) {
		function confirmCallback(buttonIndex) {
			console.log(buttonIndex);
			console.log(arguments);
			return done(buttonIndex === 1)
		}

		setTimeout(function() {
			if (navigator.notification && navigator.notification.confirm) {
				navigator.notification.confirm(
					options.message,
					confirmCallback,
					options.title || 'Confirm',
					options.buttonLabels || ['OK', 'Cancel']
				);
			} else {
				var msg = options.title ? options.title + '\n\n' : '';
					msg += options.message;
				var result = confirm(msg) ? 1 : 0;
				setTimeout(confirmCallback.bind(undefined, result), 0);
			}
		}, 1);
	}

}<commit_msg>Dialogs: remove debug console.logs<commit_after>module.exports = {

	// ALERT
	// Options: (message, [title], [buttonName])
	showAlertDialog: function(options, alertCallback) {
		setTimeout(function() {
			if (navigator.notification && navigator.notification.alert) {
				navigator.notification.alert(
					options.message,
					alertCallback,
					options.title || 'Alert',
					options.buttonLabel || 'OK'
				);
			} else {
				var msg = options.title ? options.title + '\n\n' : '';
					msg += options.message;
				alert(msg);
				setTimeout(alertCallback, 0);
			}
		}, 1);
	},

	// CONFIRM
	// Options: (message, [title], [buttonLabels])
	// Callback: invoke with index of button pressed (1, 2, or 3) or when the dialog is dismissed without a button press (0)
	showConfirmDialog: function(options, done) {
		function confirmCallback(buttonIndex) {
			return done(buttonIndex === 1)
		}

		setTimeout(function() {
			if (navigator.notification && navigator.notification.confirm) {
				navigator.notification.confirm(
					options.message,
					confirmCallback,
					options.title || 'Confirm',
					options.buttonLabels || ['OK', 'Cancel']
				);
			} else {
				var msg = options.title ? options.title + '\n\n' : '';
					msg += options.message;
				var result = confirm(msg) ? 1 : 0;
				setTimeout(confirmCallback.bind(undefined, result), 0);
			}
		}, 1);
	}

}
<|endoftext|>


<commit_before>'use strict';

/**
 * Returns a function that when invoked executes all the listeners of the
 * given event with the given arguments.
 *
 * @returns {Function} The function that emits all the things.
 * @api public
 */
module.exports = function emits() {
  var self = this
    , parser;

  for (var i = 0, l = arguments.length, args = new Array(l); i < l; i++) {
    args[i] = arguments[i];
  }

  //
  // If the last argument is a function, assume that it's a parser.
  //
  if ('function' !== typeof args[args.length - 1]) return function emitter() {
    for (var i = 0, l = arguments.length, arg = new Array(l); i < l; i++) {
      arg[i] = arguments[i];
    }

    return self.emit.apply(self, args.concat(arg));
  };

  parser = args.pop();

  /**
   * The actual function that emits the given event. It returns a boolean
   * indicating if the event was emitted.
   *
   * @returns {Boolean}
   * @api public
   */
  return function emitter() {
    for (var i = 0, l = arguments.length, arg = new Array(l + 1); i < l; i++) {
      arg[i + 1] = arguments[i];
    }

    /**
     * Async completion method for the parser.
     *
     * @param {Error} err Optional error when parsing failed.
     * @param {Mixed} returned Emit instructions.
     * @api private
     */
    arg[0] = function next(err, returned) {
      if (err) return self.emit('error', err);

      arg = returned === undefined
        ? arg.slice(1) : returned === null
          ? [] : returned;

      self.emit.apply(self, args.concat(arg));
    };

    parser.apply(self, arg);
    return true;
  };
};
<commit_msg>[minor] Use the previously defined `l` variable<commit_after>'use strict';

/**
 * Returns a function that when invoked executes all the listeners of the
 * given event with the given arguments.
 *
 * @returns {Function} The function that emits all the things.
 * @api public
 */
module.exports = function emits() {
  var self = this
    , parser;

  for (var i = 0, l = arguments.length, args = new Array(l); i < l; i++) {
    args[i] = arguments[i];
  }

  //
  // If the last argument is a function, assume that it's a parser.
  //
  if ('function' !== typeof args[l - 1]) return function emitter() {
    for (var i = 0, l = arguments.length, arg = new Array(l); i < l; i++) {
      arg[i] = arguments[i];
    }

    return self.emit.apply(self, args.concat(arg));
  };

  parser = args.pop();

  /**
   * The actual function that emits the given event. It returns a boolean
   * indicating if the event was emitted.
   *
   * @returns {Boolean}
   * @api public
   */
  return function emitter() {
    for (var i = 0, l = arguments.length, arg = new Array(l + 1); i < l; i++) {
      arg[i + 1] = arguments[i];
    }

    /**
     * Async completion method for the parser.
     *
     * @param {Error} err Optional error when parsing failed.
     * @param {Mixed} returned Emit instructions.
     * @api private
     */
    arg[0] = function next(err, returned) {
      if (err) return self.emit('error', err);

      arg = returned === undefined
        ? arg.slice(1) : returned === null
          ? [] : returned;

      self.emit.apply(self, args.concat(arg));
    };

    parser.apply(self, arg);
    return true;
  };
};
<|endoftext|>


<commit_before>var bole = require('bole');
var HAProxy = require('haproxy');
var NumbatEmitter = require('numbat-emitter');

var DEFAULT_INTERVAL = 1000;

var HAProxyProducer = module.exports = function(options) {
  var emitter = new NumbatEmitter(options);
  emitter.metric('monitor.start');
  setInterval(produce, options.interval || DEFAULT_INTERVAL);

  var logger = options.logger || bole('numbat-haproxy');

  var haproxy = new HAProxy(options.haproxy);

  function produce() {
    haproxy.stat('-1', '-1', '-1', function (err, info) {
      if (err) {
        logger.error('error while trying to retrieve HAProxy stats', err);
        return;
      }

      info.forEach(function (section) {
        if (section.pxname === 'stats') {
          return;
        }

        var service = ['haproxy', section.pxname, section.svname].join('.');

        if (section.qcur) {
          emitter.metric({
            name: service + '.queued-requests',
            description: 'Queued requests',
            value: parseInt(section.qcur, 10)
          });
        }

        if (section.bin) {
          emitter.metric({
            name: service + '.bytes-in',
            description: 'Bytes in',
            value: parseInt(section.bin, 10)
          });
        }

        if (section.bout) {
          emitter.metric({
            name: service + '.bytes-out',
            description: 'Bytes out',
            value: parseInt(section.bout, 10)
          });
        }

        if (section.rate) {
          emitter.metric({
            name: service + '.rate',
            description: 'Request rate',
            value: parseInt(section.rate, 10)
          });
        }

        if (section.ereq) {
          emitter.metric({
            name: service + '.request-errors',
            description: 'Request errors',
            value: parseInt(section.ereq, 10)
          });
        }

        if (section.econ) {
          emitter.metric({
            name: service + '.connection-errors',
            description: 'Connection errors',
            value: parseInt(section.econ, 10)
          });
        }

        if (section.eresp) {
          emitter.metric({
            name: service + '.response-errors',
            description: 'Response errors',
            value: parseInt(section.eresp, 10)
          });
        }

        if (section.hrsp_1xx) {
          emitter.metric({
            name: service + '.http-1xx',
            description: '1xx HTTP responses',
            value: parseInt(section.hrsp_1xx, 10)
          });
        }

        if (section.hrsp_2xx) {
          emitter.metric({
            name: service + '.http-2xx',
            description: '2xx HTTP responses',
            value: parseInt(section.hrsp_2xx, 10)
          });
        }

        if (section.hrsp_3xx) {
          emitter.metric({
            name: service + '.http-3xx',
            description: '3xx HTTP responses',
            value: parseInt(section.hrsp_3xx, 10)
          });
        }

        if (section.hrsp_4xx) {
          emitter.metric({
            name: service + '.http-4xx',
            description: '4xx HTTP responses',
            value: parseInt(section.hrsp_4xx, 10)
          });
        }

        if (section.hrsp_5xx) {
          emitter.metric({
            name: service + '.http-5xx',
            description: '5xx HTTP responses',
            value: parseInt(section.hrsp_5xx, 10)
          });
        }
      });
    });
  }
};
<commit_msg>Remove `description` field<commit_after>var bole = require('bole');
var HAProxy = require('haproxy');
var NumbatEmitter = require('numbat-emitter');

var DEFAULT_INTERVAL = 1000;

var HAProxyProducer = module.exports = function(options) {
  var emitter = new NumbatEmitter(options);
  emitter.metric('monitor.start');
  setInterval(produce, options.interval || DEFAULT_INTERVAL);

  var logger = options.logger || bole('numbat-haproxy');

  var haproxy = new HAProxy(options.haproxy);

  function produce() {
    haproxy.stat('-1', '-1', '-1', function (err, info) {
      if (err) {
        logger.error('error while trying to retrieve HAProxy stats', err);
        return;
      }

      info.forEach(function (section) {
        if (section.pxname === 'stats') {
          return;
        }

        var service = ['haproxy', section.pxname, section.svname].join('.');

        if (section.qcur) {
          emitter.metric({
            name: service + '.queued-requests',
            value: parseInt(section.qcur, 10)
          });
        }

        if (section.bin) {
          emitter.metric({
            name: service + '.bytes-in',
            value: parseInt(section.bin, 10)
          });
        }

        if (section.bout) {
          emitter.metric({
            name: service + '.bytes-out',
            value: parseInt(section.bout, 10)
          });
        }

        if (section.rate) {
          emitter.metric({
            name: service + '.rate',
            value: parseInt(section.rate, 10)
          });
        }

        if (section.ereq) {
          emitter.metric({
            name: service + '.request-errors',
            value: parseInt(section.ereq, 10)
          });
        }

        if (section.econ) {
          emitter.metric({
            name: service + '.connection-errors',
            value: parseInt(section.econ, 10)
          });
        }

        if (section.eresp) {
          emitter.metric({
            name: service + '.response-errors',
            value: parseInt(section.eresp, 10)
          });
        }

        if (section.hrsp_1xx) {
          emitter.metric({
            name: service + '.http-1xx',
            value: parseInt(section.hrsp_1xx, 10)
          });
        }

        if (section.hrsp_2xx) {
          emitter.metric({
            name: service + '.http-2xx',
            value: parseInt(section.hrsp_2xx, 10)
          });
        }

        if (section.hrsp_3xx) {
          emitter.metric({
            name: service + '.http-3xx',
            value: parseInt(section.hrsp_3xx, 10)
          });
        }

        if (section.hrsp_4xx) {
          emitter.metric({
            name: service + '.http-4xx',
            value: parseInt(section.hrsp_4xx, 10)
          });
        }

        if (section.hrsp_5xx) {
          emitter.metric({
            name: service + '.http-5xx',
            value: parseInt(section.hrsp_5xx, 10)
          });
        }
      });
    });
  }
};
<|endoftext|>


<commit_before>/**
* Pull in required modules
**/
const Constants       = require('../constants');
const async           = require('async');
const url             = require('url');
const dns             = require('dns');
const _               = require('lodash');
const S               = require('string');
const querystring     = require('querystring');
const SnippetManager  = require('../utils/snippet');

/**
* Parses out our functions to use
**/
var parseVariablesFromParams = function(params, har, content) {

  // the vars
  var opts = {};

  // set the params if given
  if(har)     params.har = har;
  if(content) params.body = content;

  // add the content
  opts.content = params.body || null;

  // set the data from the payload with defaults
  opts.data = _.extend({}, {

    stack:    []

  }, params || {}, {

    har:      null,
    body:     null,
    uri:      url.parse(params.url)

  });

  // parse the HAR
  opts.har = null;

  // check the type
  if(Object.prototype.toString.call(params.har || '').toLowerCase()
      === '[object string]') {

    // try to parse the JSON
    try {

      opts.har = JSON.parse(params.har);

    } catch(err) { /** don't care **/ }

  } else {

    // define as HAR
    opts.har = params.har;

  }

  // returns the final opts
  return opts;

};

/**
* Expose our creation class that will be called
* with properties.
**/
module.exports = exports = function(params, har, content) {

  /**
  * The Report object to return that we can use
  **/
  var Payload = _.extend({}, require('./common')(params));

  /**
  * Build our list of local functions
  **/
  var options = parseVariablesFromParams(params, har, content);

  /**
  * Keeps track of the existing URLS
  **/
  var rules = {};

  /**
  * The list of rules
  **/
  var logs = [];

  /**
  * Counts we keep track of
  **/
  var ruleCount = 0;

  /**
  * Cached variable of the current response
  **/
  var currentHarEntry = null;

  /**
  * Internal cache that is used, on the server side
  * the idea is that the cache methods are overrided
  * to fetch from a real cache like Redis
  **/
  var cache = {};

  /**
  * Sets a item in the cache
  **/
  Payload.set = function(key, value, fn) {

    // if the key is a object set those values
    if(typeof key === 'object') {

      // get the keys from the object
      var keys = _.keys(key);

      // loop and set all the keys
      async.each(keys, function(cacheKey, cb) {

        // set in cache
        var loweredKey = (cacheKey || '').toLowerCase();

        // set in the "cache"
        cache[loweredKey] = key[ cacheKey ];

        // done
        cb(null);

      }, function(err) {

        // check if any of the left over
        // params are a function to call
        if(typeof value === 'function') {

          // call callback
          value(null);

        } else if(typeof fn === 'function') {

          // call callback
          fn(null);

        } else {

          /**
          * Well fudge, nothing to call back, guess
          * the caller needs to read up about async ...
          **/

        }

      });

    } else if(key) {

      // set in cache
      var loweredKey = (key || '').toLowerCase();

      // set the key
      cache[loweredKey] = value;

      // finish
      fn(null);

    } else {

      // did not understand the request
      fn(null);

    }

  };

  /**
  * Returns a item from cache, if the key is defined
  * the value is returned or null if it does not exist.
  **/
  Payload.get = function(key, fn) {

    // is the key defined ?
    if(key)  {

      // lower case the key
      var lowerKey = (key || '').toLowerCase();

      // check if the item is in the cache
      // if not return null
      fn(null, cache[lowerKey] || null);

    } else fn(null, null); // noping out of here :\

  };

  /**
  * Converts the headers to a map
  **/
  Payload.getMappedHeaders = function(headers, fn) {

    // the object headers
    var mappedHeaders = {};

    // loop the headers
    for(var i = 0; i < (headers || []).length; i++) {

      // add to the list
      var name        = S(headers[i].name || '').trim().s.toLowerCase();
      var value       = S(headers[i].value || '').trim().s;

      // should not be empty
      if(S(name).isEmpty() === true) continue;

      // set the headers
      mappedHeaders[name] = value;

    }

    // return the headers
    return mappedHeaders;

  };

  /**
  * Checks for the page response and returns the selected item we are looking for
  **/
  Payload.getResponse = function(fn) {

    // returns the request
    this.getHAREntry(function(err, entry) {

      // check for a error
      if(err) return fn(err);

      // sanity check that we have a har entry
      if(!entry) return fn(null);

      // else sent out our entry object
      if(!entry.response) return fn(null);

      // return the entry
      fn(null, entry.response);

    });

  };

  /**
  * Checks for the page response and returns the selected item we are looking for
  **/
  Payload.getRequest = function(fn) {

    // returns the request
    this.getHAREntry(function(err, entry) {

      // check for a error
      if(err) return fn(err);

      // sanity check that we have a har entry
      if(!entry) return fn(new Error('HAR could not be found'));

      // else sent out our entry object
      if(!entry.request) return fn(null);

      // return the entry
      fn(null, entry.request);

    });

  };

  /**
  * Returns the request that was sent to the server
  **/
  Payload.getHAREntry = function(fn) {

    // check if this is not cached already
    if(currentHarEntry) return fn(null, currentHarEntry);

    // get the HAR
    this.getHAR(function(err, har) {

      // if we got a error, stop there
      if(err) return fn(err);

      // check if we got the har ?
      if(!har) return fn(new Error('HAR was not found for the payload'));

      // sanity checks
      if(!har.log) return fn(new Error('Missing a .log for the HAR'));
      if(!har.log.entries) return fn(new Error('Missing a .log for the HAR'));

      // loop the entries
      for(var i = 0; i < har.log.entries.length; i++) {

        // local reference
        var entry = har.log.entries[i];

        // sanity check
        if(!entry) continue;

        // must have a request and response
        if(!entry.response) continue;
        if(!entry.request) continue;

        // get the headers
        var headers = Payload.getMappedHeaders(entry.response.headers);

        // must be 200
        if(entry.response.status != 200) continue;

        // must have content-type
        if(!headers['content-type']) continue;

        // must be text/html
        if( (headers['content-type'] || '').indexOf('text/html') === -1 )
          continue;

        // set the current entry
        currentHarEntry = entry;

        // stop the loop
        break;

      }

      // check if we got a entry ?
      if(currentHarEntry) return fn(null, currentHarEntry);

      // finish strong
      return fn(null);

    });

  };

  /**
  * Returns the snippet tool we can use
  **/
  Payload.getSnippetManager = function() { return SnippetManager; }

  /**
  * Returns the request that was sent to the server
  **/
  Payload.getDocument = Payload.getHAREntry;

  /**
  * Returns the count of rules, this includes rules
  * that may have been skipped to save on size.
  **/
  Payload.getRuleCount = function(fn) {

    // check the callback
    if(fn) {

      // done
      return fn(null, ruleCount);

    }

    // return as a normal return
    return ruleCount;

  };

  /**
  * Returns the count of rules, this includes rules
  * that may have been skipped to save on size.
  **/
  Payload.getCount = Payload.getRuleCount;

  /**
  * Returns the logs that have been built
  **/
  Payload.getLogs = function() { return logs; };

  /**
  * Handles debugging messages
  **/
  Payload.debug = function(message) {

    // add to the logs
    logs.push({

      type:       'debug',
      message:    message,
      timestamp:  new Date().getTime()

    });

  };

  /**
  * Handles information messages
  **/
  Payload.info = function(message) {

    // add to the logs
    logs.push({

      type:       'info',
      message:    message,
      timestamp:  new Date().getTime()

    });

  };

  /**
  * Handles and warnings that might be present
  **/
  Payload.warning = function(message) {

    // add to the logs
    logs.push({

      type:       'warning',
      message:    message,
      timestamp:  new Date().getTime()

    });

  };

  /**
  * Handles logging error outputs
  **/
  Payload.error = function(message, err) {

    // add to the logs
    logs.push({

      type:       'error',
      message:    message,
      error:      err,
      timestamp:  new Date().getTime()

    });

  };

  /**
  * Should this rule be given another chance to run ?
  **/
  var markedAsRetry = false;

  /**
  *
  **/
  Payload.markRetry = function() {};

  /**
  * Returns the stack keys that were present
  **/
  Payload.getStack = function(fn) {

    // return the current instance
    return (options.data || {}).stack || '';

  };

  /**
  * Returns the target URL of the data
  **/
  Payload.getURI = function(fn) {

    // return the current instance
    return (options.data || {}).uri;

  };

  /**
  * Returns the target URL of the data
  **/
  Payload.getURL = function(fn) {

    // return the current instance
    return (options.data || {}).url;

  };

  /**
  * Returns the given payload
  **/
  Payload.getData = function(fn) {

    // return the current instance
    return options.data;

  };

  /**
  * Returns the HAR from the payload
  **/
  Payload.getHAR = function(fn) {

    // get the har
    var har = options.har;

    // get the har
    if(!har)
      fn(null, { log: { entries: [] } });
    else if(!har.log)
      fn(null, { log: { entries: [] } });
    else if(!har.log.entries)
      fn(null, { log: { entries: [] } });
    else
      fn(null, har);

    // return the current instance
    return this;

  };

  /**
  * Returns the page content as given
  **/
  Payload.getPageContent = function(fn) {

    // get the content
    var content = options.content;

    // returns the callback
    fn(null, content || '');

    // returns the current instance
    return this;

  };

  /**
  * Adds a rule to the payload
  **/
  Payload.addRule = function(params, occurrence, fn) {

    // check if the defaults were given ...
    if(params &&
          params.type &&
            params.key &&
              params.message) {

      // increment the rule count
      ruleCount++;

      // create the rule details
      var rule = _.extend({}, params || {});

      // define the type
      var type = null;

      // check the type
      if(params.type == 'ok') {
        type = 'notice'
      } else if(params.type == 'notice') {
        type = 'notice'
      } else if(params.type == 'warning') {
        type = 'warning'
      } else if(params.type == 'error') {
        type = 'error'
      } else if(params.type == 'critical') {
        type = 'critical'
      }

      // only if the type was defined
      if(type) {

        // should we create the rule ?
        if(!rules[ params.key ]) {

          // create the rule object
          rules[ params.key ] = rule;

        }

        // update the count
        var currentCount = 1 * (rules[ params.key ].count || 0);
        rules[ params.key ].count = currentCount + 1;

        // check the occurrence
        if(occurrence) {

          // is the occurence defined
          if(rules[ params.key ].occurrences) {

            // must be smaller than a 100
            if(rules[ params.key ].occurrences.length <= 500) {

              // push to array
              rules[ params.key ].occurrences.push( occurrence );

            }

          } else {

            // create a new array
            rules[ params.key ].occurrences = [ occurrence ];

          }

        }

      }

    }

    // handle a callback if any
    if(fn) fn(null);

    // return the current instance
    return this;

  };

  /**
  * Check if the rule is present on this check
  **/
  Payload.hasRule = function(key) {

    // return from the internal rule map
    if(rules[ key ])
      return true;
    else
      return false;

  };

  /**
  * Returns the parsed Rules
  **/
  Payload.getRules = function() { return _.values(rules); };

  // return the Payload object to use
  return Payload;

};
<commit_msg>Added caching to the local instances of payloads so we can use this on our servers too<commit_after>/**
* Pull in required modules
**/
const Constants       = require('../constants');
const async           = require('async');
const url             = require('url');
const dns             = require('dns');
const _               = require('lodash');
const S               = require('string');
const querystring     = require('querystring');
const SnippetManager  = require('../utils/snippet');

/**
* Parses out our functions to use
**/
var parseVariablesFromParams = function(params, har, content) {

  // the vars
  var opts = {};

  // set the params if given
  if(har)     params.har = har;
  if(content) params.body = content;

  // add the content
  opts.content = params.body || null;

  // set the data from the payload with defaults
  opts.data = _.extend({}, {

    stack:    []

  }, params || {}, {

    har:      null,
    body:     null,
    uri:      url.parse(params.url)

  });

  // parse the HAR
  opts.har = null;

  // check the type
  if(Object.prototype.toString.call(params.har || '').toLowerCase()
      === '[object string]') {

    // try to parse the JSON
    try {

      opts.har = JSON.parse(params.har);

    } catch(err) { /** don't care **/ }

  } else {

    // define as HAR
    opts.har = params.har;

  }

  // returns the final opts
  return opts;

};

/**
* Expose our creation class that will be called
* with properties.
**/
module.exports = exports = function(params, har, content) {

  /**
  * The Report object to return that we can use
  **/
  var Payload = _.extend({}, require('./common')(params));

  /**
  * Build our list of local functions
  **/
  var options = parseVariablesFromParams(params, har, content);

  /**
  * Keeps track of the existing URLS
  **/
  var rules = {};

  /**
  * The list of rules
  **/
  var logs = [];

  /**
  * Counts we keep track of
  **/
  var ruleCount = 0;

  /**
  * Cached variable of the current response
  **/
  var currentHarEntry = null;

  /**
  * Internal cache that is used, on the server side
  * the idea is that the cache methods are overrided
  * to fetch from a real cache like Redis
  **/
  var cache = {};

  /**
  * Sets a item in the cache
  **/
  Payload.set = function(key, value, fn) {

    // if the key is a object set those values
    if(typeof key === 'object') {

      // get the keys from the object
      var keys = _.keys(key);

      // loop and set all the keys
      async.each(keys, function(cacheKey, cb) {

        // set in cache
        var loweredKey = (cacheKey || '').toLowerCase();

        // set in the "cache"
        cache[loweredKey] = key[ cacheKey ];

        // done
        cb(null);

      }, function(err) {

        // check if any of the left over
        // params are a function to call
        if(typeof value === 'function') {

          // call callback
          value(null);

        } else if(typeof fn === 'function') {

          // call callback
          fn(null);

        } else {

          /**
          * Well fudge, nothing to call back, guess
          * the caller needs to read up about async ...
          **/

        }

      });

    } else if(key) {

      // set in cache
      var loweredKey = (key || '').toLowerCase();

      // set the key
      cache[loweredKey] = value;

      // finish
      fn(null);

    } else {

      // did not understand the request
      fn(null);

    }

    // return this
    return this;

  };

  /**
  * Returns a item from cache, if the key is defined
  * the value is returned or null if it does not exist.
  **/
  Payload.get = function(key, fn) {

    // is the key defined ?
    if(key)  {

      // lower case the key
      var lowerKey = (key || '').toLowerCase();

      // check if the item is in the cache
      // if not return null
      fn(null, cache[lowerKey] || null);

    } else fn(null, null); // noping out of here :\

  };

  /**
  * Converts the headers to a map
  **/
  Payload.getMappedHeaders = function(headers, fn) {

    // the object headers
    var mappedHeaders = {};

    // loop the headers
    for(var i = 0; i < (headers || []).length; i++) {

      // add to the list
      var name        = S(headers[i].name || '').trim().s.toLowerCase();
      var value       = S(headers[i].value || '').trim().s;

      // should not be empty
      if(S(name).isEmpty() === true) continue;

      // set the headers
      mappedHeaders[name] = value;

    }

    // return the headers
    return mappedHeaders;

  };

  /**
  * Checks for the page response and returns the selected item we are looking for
  **/
  Payload.getResponse = function(fn) {

    // returns the request
    this.getHAREntry(function(err, entry) {

      // check for a error
      if(err) return fn(err);

      // sanity check that we have a har entry
      if(!entry) return fn(null);

      // else sent out our entry object
      if(!entry.response) return fn(null);

      // return the entry
      fn(null, entry.response);

    });

  };

  /**
  * Checks for the page response and returns the selected item we are looking for
  **/
  Payload.getRequest = function(fn) {

    // returns the request
    this.getHAREntry(function(err, entry) {

      // check for a error
      if(err) return fn(err);

      // sanity check that we have a har entry
      if(!entry) return fn(new Error('HAR could not be found'));

      // else sent out our entry object
      if(!entry.request) return fn(null);

      // return the entry
      fn(null, entry.request);

    });

  };

  /**
  * Returns the request that was sent to the server
  **/
  Payload.getHAREntry = function(fn) {

    // check if this is not cached already
    if(currentHarEntry) return fn(null, currentHarEntry);

    // get the HAR
    this.getHAR(function(err, har) {

      // if we got a error, stop there
      if(err) return fn(err);

      // check if we got the har ?
      if(!har) return fn(new Error('HAR was not found for the payload'));

      // sanity checks
      if(!har.log) return fn(new Error('Missing a .log for the HAR'));
      if(!har.log.entries) return fn(new Error('Missing a .log for the HAR'));

      // loop the entries
      for(var i = 0; i < har.log.entries.length; i++) {

        // local reference
        var entry = har.log.entries[i];

        // sanity check
        if(!entry) continue;

        // must have a request and response
        if(!entry.response) continue;
        if(!entry.request) continue;

        // get the headers
        var headers = Payload.getMappedHeaders(entry.response.headers);

        // must be 200
        if(entry.response.status != 200) continue;

        // must have content-type
        if(!headers['content-type']) continue;

        // must be text/html
        if( (headers['content-type'] || '').indexOf('text/html') === -1 )
          continue;

        // set the current entry
        currentHarEntry = entry;

        // stop the loop
        break;

      }

      // check if we got a entry ?
      if(currentHarEntry) return fn(null, currentHarEntry);

      // finish strong
      return fn(null);

    });

  };

  /**
  * Returns the snippet tool we can use
  **/
  Payload.getSnippetManager = function() { return SnippetManager; }

  /**
  * Returns the request that was sent to the server
  **/
  Payload.getDocument = Payload.getHAREntry;

  /**
  * Returns the count of rules, this includes rules
  * that may have been skipped to save on size.
  **/
  Payload.getRuleCount = function(fn) {

    // check the callback
    if(fn) {

      // done
      return fn(null, ruleCount);

    }

    // return as a normal return
    return ruleCount;

  };

  /**
  * Returns the count of rules, this includes rules
  * that may have been skipped to save on size.
  **/
  Payload.getCount = Payload.getRuleCount;

  /**
  * Returns the logs that have been built
  **/
  Payload.getLogs = function() { return logs; };

  /**
  * Handles debugging messages
  **/
  Payload.debug = function(message) {

    // add to the logs
    logs.push({

      type:       'debug',
      message:    message,
      timestamp:  new Date().getTime()

    });

  };

  /**
  * Handles information messages
  **/
  Payload.info = function(message) {

    // add to the logs
    logs.push({

      type:       'info',
      message:    message,
      timestamp:  new Date().getTime()

    });

  };

  /**
  * Handles and warnings that might be present
  **/
  Payload.warning = function(message) {

    // add to the logs
    logs.push({

      type:       'warning',
      message:    message,
      timestamp:  new Date().getTime()

    });

  };

  /**
  * Handles logging error outputs
  **/
  Payload.error = function(message, err) {

    // add to the logs
    logs.push({

      type:       'error',
      message:    message,
      error:      err,
      timestamp:  new Date().getTime()

    });

  };

  /**
  * Should this rule be given another chance to run ?
  **/
  var markedAsRetry = false;

  /**
  *
  **/
  Payload.markRetry = function() {};

  /**
  * Returns the stack keys that were present
  **/
  Payload.getStack = function(fn) {

    // return the current instance
    return (options.data || {}).stack || '';

  };

  /**
  * Returns the target URL of the data
  **/
  Payload.getURI = function(fn) {

    // return the current instance
    return (options.data || {}).uri;

  };

  /**
  * Returns the target URL of the data
  **/
  Payload.getURL = function(fn) {

    // return the current instance
    return (options.data || {}).url;

  };

  /**
  * Returns the given payload
  **/
  Payload.getData = function(fn) {

    // return the current instance
    return options.data;

  };

  /**
  * Returns the HAR from the payload
  **/
  Payload.getHAR = function(fn) {

    // get the data
    var data = Payload.getData();

    // create the cache key
    var queueName = [

      'passmarked',
      'reports',
      data.reportid,
      'har'

    ];

    // return the har if defined locally
    if(options.har) {

      // check the har we have
      var currentHar = options.har || {};

      // add missing components if not there
      if(!currentHar.log) currentHar.log = {};
      if(!currentHar.log.entries) currentHar.log.entires = [];

      // finish
      fn(null, currentHar);

      // done
      return this;

    }

    // check if the content is defined in the cache
    Payload.get(queueName.join(':'), function(err, cachedValue) {

      // check if we got a error from the cache
      if(err) return fn(err);

      // check if we got a value
      if(cachedValue) options.har = cachedValue;

      // get the har
      var har = options.har || null;

      // get the har
      if(!har)
        fn(null, { log: { entries: [] } });
      else if(!har.log)
        fn(null, { log: { entries: [] } });
      else if(!har.log.entries)
        fn(null, { log: { entries: [] } });
      else
        fn(null, har);

    });

    // return the current instance
    return this;

  };

  /**
  * Returns the page content as given
  **/
  Payload.getPageContent = function(fn) {

    // get the data
    var data = Payload.getData();

    // create the cache key
    var queueName = [

      'passmarked',
      'reports',
      data.reportid,
      'content'

    ];

    // check if the page content is defined
    if(options.content) {

      // call the callback
      fn(null, options.content || '');

      // return
      return this;

    }

    // check if the content is defined in the cache
    Payload.get(queueName.join(':'), function(err, cachedValue) {

      // check for the value
      if(err) return fn(err);

      // check if the cached value was returned ?
      if(cachedValue) options.content = cachedValue;

      // returns the callback
      fn(err, options.content || '');

    });

    // returns the current instance
    return this;

  };

  /**
  * Adds a rule to the payload
  **/
  Payload.addRule = function(params, occurrence, fn) {

    // check if the defaults were given ...
    if(params &&
          params.type &&
            params.key &&
              params.message) {

      // increment the rule count
      ruleCount++;

      // create the rule details
      var rule = _.extend({}, params || {});

      // define the type
      var type = null;

      // check the type
      if(params.type == 'ok') {
        type = 'notice'
      } else if(params.type == 'notice') {
        type = 'notice'
      } else if(params.type == 'warning') {
        type = 'warning'
      } else if(params.type == 'error') {
        type = 'error'
      } else if(params.type == 'critical') {
        type = 'critical'
      }

      // only if the type was defined
      if(type) {

        // should we create the rule ?
        if(!rules[ params.key ]) {

          // create the rule object
          rules[ params.key ] = rule;

        }

        // update the count
        var currentCount = 1 * (rules[ params.key ].count || 0);
        rules[ params.key ].count = currentCount + 1;

        // check the occurrence
        if(occurrence) {

          // is the occurence defined
          if(rules[ params.key ].occurrences) {

            // must be smaller than a 100
            if(rules[ params.key ].occurrences.length <= 500) {

              // push to array
              rules[ params.key ].occurrences.push( occurrence );

            }

          } else {

            // create a new array
            rules[ params.key ].occurrences = [ occurrence ];

          }

        }

      }

    }

    // handle a callback if any
    if(fn) fn(null);

    // return the current instance
    return this;

  };

  /**
  * Check if the rule is present on this check
  **/
  Payload.hasRule = function(key) {

    // return from the internal rule map
    if(rules[ key ])
      return true;
    else
      return false;

  };

  /**
  * Returns the parsed Rules
  **/
  Payload.getRules = function() { return _.values(rules); };

  /**
  * Returns true or false if this was a crawl
  **/
  Payload.isCrawl = function() {

    // get the data
    var data = payload.getData();

    // return the crawl
    return data.crawlid !== null && data.crawlid !== undefined;

  };

  // return the Payload object to use
  return Payload;

};
<|endoftext|>


<commit_before>var util = require("util");
module.exports = {
	require: function(key, defaultValue) {
		if(process.env[key] === undefined) {
			if(defaultValue === undefined) {
				throw new Error(util.format('The environment variable "%s" is not defined, and no default value is available', key));
			}
			else {
				process.env[key] = defaultValue;
			}
		}
	},

	get: function(key) {
		return process.env[key];
	},

	set: function(key, value) {
		process.env[key] = value;
	}
};
<commit_msg>require now returns the new value<commit_after>var util = require("util");
module.exports = {
	require: function(key, defaultValue) {
		if(process.env[key] === undefined) {
			if(defaultValue === undefined) {
				throw new Error(util.format('The environment variable "%s" is not defined, and no default value is available', key));
			}
			else {
				process.env[key] = defaultValue;
			}
		}

		return process.env[key];
	},

	get: function(key) {
		return process.env[key];
	},

	set: function(key, value) {
		process.env[key] = value;
	}
};
<|endoftext|>


<commit_before>var xml2js = require('xml2js'),
  async = require('async'),
  tomd = require('to-markdown').toMarkdown,
  request = require('request'),
  util = hexo.util,
  file = util.file2;

var captialize = function(str){
  return str[0].toUpperCase() + str.substring(1);
};

hexo.extend.migrator.register('wordpress', function(args, callback){
  var source = args._.shift();

  if (!source){
    var help = [
      'Usage: hexo migrate wordpress <source>',
      '',
      'For more help, you can check the docs: http://hexo.io/docs/migration.html'
    ];

    console.log(help.join('\n'));
    return callback();
  }

  var log = hexo.log,
    post = hexo.post;

  log.i('Analyzing %s...', source);

  async.waterfall([
    function(next){
      // URL regular expression from: http://blog.mattheworiordan.com/post/13174566389/url-regular-expression-for-links-with-or-without-the
      if (source.match(/((([A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[.\!\/\\w]*))?)/)){
        request(source, function(err, res, body){
          if (err) throw err;
          if (res.statusCode == 200) next(null, body);
        });
      } else {
        file.readFile(source, next);
      }
    },
    function(content, next){
      xml2js.parseString(content, next);
    },
    function(xml, next){
      var count = 0;

      async.each(xml.rss.channel[0].item, function(item, next){
        if (!item['wp:post_type']){
          return next();
        }

        var title = item.title[0],
          id = item['wp:post_id'][0],
          date = item['wp:post_date'][0],
          slug = item['wp:post_name'][0],
          content = item['content:encoded'][0],
          comment = item['wp:comment_status'][0],
          status = item['wp:status'][0],
          type = item['wp:post_type'][0],
          categories = [],
          tags = [];

        if (!title && !slug) return next();
        if (type !== 'post' && type !== 'page') return next();
        if (typeof content !== 'string') content = '';

        content = tomd(content).replace(/\r\n/g, '\n');
        count++;

        if (item.category){
          item.category.forEach(function(category, next){
            var name = category._;

            switch (category.$.domain){
              case 'category':
                categories.push(name);
                break;

              case 'post_tag':
                tags.push(name);
                break;
            }
          });
        }

        var data = {
          title: title || slug,
          id: +id,
          date: date,
          content: content,
          layout: status === 'draft' ? 'draft' : 'post',
        };

        if (type === 'page') data.layout = 'page';
        if (slug) data.slug = slug;
        if (comment === 'closed') data.comment = false;
        if (categories.length && type === 'post') data.categories = categories;
        if (tags.length && type === 'post') data.tags = tags;

        log.i('%s found: %s', captialize(type), title);
        post.create(data, next);
      }, function(err){
        if (err) return next(err);

        log.i('%d posts migrated.', count);
      });
    }
  ], callback);
});<commit_msg>replaced file2 with fs module to make it run<commit_after>var xml2js = require('xml2js'),
  async = require('async'),
  tomd = require('to-markdown').toMarkdown,
  request = require('request'),
  util = hexo.util,
  file = require('fs');

var captialize = function(str){
  return str[0].toUpperCase() + str.substring(1);
};

hexo.extend.migrator.register('wordpress', function(args, callback){
  var source = args._.shift();

  if (!source){
    var help = [
      'Usage: hexo migrate wordpress <source>',
      '',
      'For more help, you can check the docs: http://hexo.io/docs/migration.html'
    ];

    console.log(help.join('\n'));
    return callback();
  }

  var log = hexo.log,
    post = hexo.post;

  log.i('Analyzing %s...', source);

  async.waterfall([
    function(next){
      // URL regular expression from: http://blog.mattheworiordan.com/post/13174566389/url-regular-expression-for-links-with-or-without-the
      if (source.match(/((([A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[.\!\/\\w]*))?)/)){
        request(source, function(err, res, body){
          if (err) throw err;
          if (res.statusCode == 200) next(null, body);
        });
      } else {
        file.readFile(source, next);
      }
    },
    function(content, next){
      xml2js.parseString(content, next);
    },
    function(xml, next){
      var count = 0;

      async.each(xml.rss.channel[0].item, function(item, next){
        if (!item['wp:post_type']){
          return next();
        }

        var title = item.title[0],
          id = item['wp:post_id'][0],
          date = item['wp:post_date'][0],
          slug = item['wp:post_name'][0],
          content = item['content:encoded'][0],
          comment = item['wp:comment_status'][0],
          status = item['wp:status'][0],
          type = item['wp:post_type'][0],
          categories = [],
          tags = [];

        if (!title && !slug) return next();
        if (type !== 'post' && type !== 'page') return next();
        if (typeof content !== 'string') content = '';

        content = tomd(content).replace(/\r\n/g, '\n');
        count++;

        if (item.category){
          item.category.forEach(function(category, next){
            var name = category._;

            switch (category.$.domain){
              case 'category':
                categories.push(name);
                break;

              case 'post_tag':
                tags.push(name);
                break;
            }
          });
        }

        var data = {
          title: title || slug,
          id: +id,
          date: date,
          content: content,
          layout: status === 'draft' ? 'draft' : 'post',
        };

        if (type === 'page') data.layout = 'page';
        if (slug) data.slug = slug;
        if (comment === 'closed') data.comment = false;
        if (categories.length && type === 'post') data.categories = categories;
        if (tags.length && type === 'post') data.tags = tags;

        log.i('%s found: %s', captialize(type), title);
        post.create(data, next);
      }, function(err){
        if (err) return next(err);

        log.i('%d posts migrated.', count);
      });
    }
  ], callback);
});
<|endoftext|>