<commit_before>const spiralloop = require('spiralloop')
const Vec3 = require('vec3').Vec3

const generations = require('flying-squid').generations
const { promisify } = require('util')
const fs = require('fs')
const { level } = require('prismarine-provider-anvil')

const fsStat = promisify(fs.stat)
const fsMkdir = promisify(fs.mkdir)

module.exports.server = async function (serv, { version, worldFolder, generation = { name: 'diamond_square', options: { worldHeight: 80 } } } = {}) {
  const World = require('prismarine-world')(version)

  const newSeed = generation.options.seed || Math.floor(Math.random() * Math.pow(2, 31))
  let seed
  let regionFolder
  if (worldFolder) {
    regionFolder = worldFolder + '/region'
    try {
      await fsStat(regionFolder)
    } catch (err) {
      await fsMkdir(regionFolder)
    }

    try {
      const levelData = await level.readLevel(worldFolder + '/level.dat')
      seed = levelData.RandomSeed[0]
    } catch (err) {
      seed = newSeed
      await level.writeLevel(worldFolder + '/level.dat', { RandomSeed: [seed, 0] })
    }
  } else { seed = newSeed }
  generation.options.seed = seed
  generation.options.version = version
  serv.emit('seed', generation.options.seed)
  const generationModule = generations[generation.name] ? generations[generation.name] : require(generation.name)
  serv.overworld = new World(generationModule(generation.options), regionFolder)
  serv.netherworld = new World(generations.nether(generation.options))
  // serv.endworld = new World(generations["end"]({}));

  // WILL BE REMOVED WHEN ACTUALLY IMPLEMENTED
  serv.overworld.blockEntityData = {}
  serv.netherworld.blockEntityData = {}
  serv.overworld.portals = []
  serv.netherworld.portals = []
  /// ///////////

  serv.pregenWorld = (world, size = 3) => {
    const promises = []
    for (let x = -size; x < size; x++) {
      for (let z = -size; z < size; z++) {
        promises.push(world.getColumn(x, z))
      }
    }
    return Promise.all(promises)
  }

  serv.setBlock = async (world, position, blockType, blockData) => {
    serv.players
      .filter(p => p.world === world)
      .forEach(player => player.sendBlock(position, blockType, blockData))

    await world.setBlockType(position, blockType)
    await world.setBlockData(position, blockData)

    if (blockType === 0) serv.notifyNeighborsOfStateChange(world, position, serv.tickCount, serv.tickCount, true)
    else serv.updateBlock(world, position, serv.tickCount, serv.tickCount, true)
  }

  serv.setBlockAction = async (world, position, actionId, actionParam) => {
    const location = new Vec3(position.x, position.y, position.z)
    const blockType = await world.getBlockType(location)

    serv.players
      .filter(p => p.world === world)
      .forEach(player => player.sendBlockAction(position, actionId, actionParam, blockType))
  }

  serv.reloadChunks = (world, chunks) => {
    serv.players
      .filter(player => player.world === world)
      .forEach(oPlayer => {
        chunks
          .filter(({ chunkX, chunkZ }) => oPlayer.loadedChunks[chunkX + ',' + chunkZ] !== undefined)
          .forEach(({ chunkX, chunkZ }) => oPlayer.unloadChunk(chunkX, chunkZ))
        oPlayer.sendRestMap()
      })
  }

  // serv.pregenWorld(serv.overworld).then(() => serv.log('Pre-Generated Overworld'));
  // serv.pregenWorld(serv.netherworld).then(() => serv.log('Pre-Generated Nether'));
}

module.exports.player = function (player, serv, settings) {
  player.unloadChunk = (chunkX, chunkZ) => {
    delete player.loadedChunks[chunkX + ',' + chunkZ]

    if (serv.supportFeature('unloadChunkByEmptyChunk')) {
      player._client.write('map_chunk', {
        x: chunkX,
        z: chunkZ,
        groundUp: true,
        bitMap: 0x0000,
        chunkData: Buffer.alloc(0)
      })
    } else if (serv.supportFeature('unloadChunkDirect')) {
      player._client.write('unload_chunk', {
        chunkX,
        chunkZ
      })
    }
  }

  player.sendChunk = (chunkX, chunkZ, column) => {
    return player.behavior('sendChunk', {
      x: chunkX,
      z: chunkZ,
      chunk: column
    }, ({ x, z, chunk }) => {
      player._client.write('map_chunk', {
        x: x,
        z: z,
        groundUp: true,
        bitMap: 0xffff,
        chunkData: chunk.dump(),
        blockEntities: []
      })
      return Promise.resolve()
    })
  }

  function spiral (arr) {
    const t = []
    spiralloop(arr, (x, z) => {
      t.push([x, z])
    })
    return t
  }

  player.sendNearbyChunks = (view, group) => {
    player.lastPositionChunkUpdated = player.position
    const playerChunkX = Math.floor(player.position.x / 16)
    const playerChunkZ = Math.floor(player.position.z / 16)

    Object.keys(player.loadedChunks)
      .map((key) => key.split(',').map(a => parseInt(a)))
      .filter(([x, z]) => Math.abs(x - playerChunkX) > view || Math.abs(z - playerChunkZ) > view)
      .forEach(([x, z]) => player.unloadChunk(x, z))

    return spiral([view * 2, view * 2])
      .map(t => ({
        chunkX: playerChunkX + t[0] - view,
        chunkZ: playerChunkZ + t[1] - view
      }))
      .filter(({ chunkX, chunkZ }) => {
        const key = chunkX + ',' + chunkZ
        const loaded = player.loadedChunks[key]
        if (!loaded) player.loadedChunks[key] = 1
        return !loaded
      })
      .reduce((acc, { chunkX, chunkZ }) => {
        const p = acc
          .then(() => player.world.getColumn(chunkX, chunkZ))
          .then((column) => player.sendChunk(chunkX, chunkZ, column))
        return group ? p.then(() => sleep(5)) : p
      }
      , Promise.resolve())
  }

  function sleep (ms = 0) {
    return new Promise(resolve => setTimeout(resolve, ms))
  }

  player.sendMap = () => {
    return player.sendNearbyChunks(Math.min(3, settings['view-distance']))
      .catch((err) => setTimeout(() => { throw err }), 0)
  }

  player.sendRestMap = () => {
    player.sendingChunks = true
    player.sendNearbyChunks(Math.min(player.view, settings['view-distance']), true)
      .then(() => { player.sendingChunks = false })
      .catch((err) => setTimeout(() => { throw err }, 0))
  }

  player.sendSpawnPosition = () => {
    player._client.write('spawn_position', {
      location: player.spawnPoint
    })
  }

  player.changeWorld = async (world, opt) => {
    if (player.world === world) return Promise.resolve()
    opt = opt || {}
    player.world = world
    player.loadedChunks = {}
    if (typeof opt.gamemode !== 'undefined') player.gameMode = opt.gamemode
    player._client.write('respawn', {
      dimension: opt.dimension || 0,
      difficulty: opt.difficulty || serv.difficulty,
      gamemode: opt.gamemode || player.gameMode,
      levelType: 'default'
    })
    await player.findSpawnPoint()
    player.position = player.spawnPoint
    player.sendSpawnPosition()
    player.updateAndSpawn()

    await player.sendMap()

    player.sendSelfPosition()
    player.emit('change_world')

    await player.waitPlayerLogin()
    player.sendRestMap()
  }

  player.commands.add({
    base: 'changeworld',
    info: 'to change world',
    usage: '/changeworld overworld|nether',
    op: true,
    action (world) {
      if (world === 'nether') player.changeWorld(serv.netherworld, { dimension: -1 })
      if (world === 'overworld') player.changeWorld(serv.overworld, { dimension: 0 })
    }
  })
}
<commit_msg>use getMask<commit_after>const spiralloop = require('spiralloop')
const Vec3 = require('vec3').Vec3

const generations = require('flying-squid').generations
const { promisify } = require('util')
const fs = require('fs')
const { level } = require('prismarine-provider-anvil')

const fsStat = promisify(fs.stat)
const fsMkdir = promisify(fs.mkdir)

module.exports.server = async function (serv, { version, worldFolder, generation = { name: 'diamond_square', options: { worldHeight: 80 } } } = {}) {
  const World = require('prismarine-world')(version)

  const newSeed = generation.options.seed || Math.floor(Math.random() * Math.pow(2, 31))
  let seed
  let regionFolder
  if (worldFolder) {
    regionFolder = worldFolder + '/region'
    try {
      await fsStat(regionFolder)
    } catch (err) {
      await fsMkdir(regionFolder)
    }

    try {
      const levelData = await level.readLevel(worldFolder + '/level.dat')
      seed = levelData.RandomSeed[0]
    } catch (err) {
      seed = newSeed
      await level.writeLevel(worldFolder + '/level.dat', { RandomSeed: [seed, 0] })
    }
  } else { seed = newSeed }
  generation.options.seed = seed
  generation.options.version = version
  serv.emit('seed', generation.options.seed)
  const generationModule = generations[generation.name] ? generations[generation.name] : require(generation.name)
  serv.overworld = new World(generationModule(generation.options), regionFolder)
  serv.netherworld = new World(generations.nether(generation.options))
  // serv.endworld = new World(generations["end"]({}));

  // WILL BE REMOVED WHEN ACTUALLY IMPLEMENTED
  serv.overworld.blockEntityData = {}
  serv.netherworld.blockEntityData = {}
  serv.overworld.portals = []
  serv.netherworld.portals = []
  /// ///////////

  serv.pregenWorld = (world, size = 3) => {
    const promises = []
    for (let x = -size; x < size; x++) {
      for (let z = -size; z < size; z++) {
        promises.push(world.getColumn(x, z))
      }
    }
    return Promise.all(promises)
  }

  serv.setBlock = async (world, position, blockType, blockData) => {
    serv.players
      .filter(p => p.world === world)
      .forEach(player => player.sendBlock(position, blockType, blockData))

    await world.setBlockType(position, blockType)
    await world.setBlockData(position, blockData)

    if (blockType === 0) serv.notifyNeighborsOfStateChange(world, position, serv.tickCount, serv.tickCount, true)
    else serv.updateBlock(world, position, serv.tickCount, serv.tickCount, true)
  }

  serv.setBlockAction = async (world, position, actionId, actionParam) => {
    const location = new Vec3(position.x, position.y, position.z)
    const blockType = await world.getBlockType(location)

    serv.players
      .filter(p => p.world === world)
      .forEach(player => player.sendBlockAction(position, actionId, actionParam, blockType))
  }

  serv.reloadChunks = (world, chunks) => {
    serv.players
      .filter(player => player.world === world)
      .forEach(oPlayer => {
        chunks
          .filter(({ chunkX, chunkZ }) => oPlayer.loadedChunks[chunkX + ',' + chunkZ] !== undefined)
          .forEach(({ chunkX, chunkZ }) => oPlayer.unloadChunk(chunkX, chunkZ))
        oPlayer.sendRestMap()
      })
  }

  // serv.pregenWorld(serv.overworld).then(() => serv.log('Pre-Generated Overworld'));
  // serv.pregenWorld(serv.netherworld).then(() => serv.log('Pre-Generated Nether'));
}

module.exports.player = function (player, serv, settings) {
  player.unloadChunk = (chunkX, chunkZ) => {
    delete player.loadedChunks[chunkX + ',' + chunkZ]

    if (serv.supportFeature('unloadChunkByEmptyChunk')) {
      player._client.write('map_chunk', {
        x: chunkX,
        z: chunkZ,
        groundUp: true,
        bitMap: 0x0000,
        chunkData: Buffer.alloc(0)
      })
    } else if (serv.supportFeature('unloadChunkDirect')) {
      player._client.write('unload_chunk', {
        chunkX,
        chunkZ
      })
    }
  }

  player.sendChunk = (chunkX, chunkZ, column) => {
    return player.behavior('sendChunk', {
      x: chunkX,
      z: chunkZ,
      chunk: column
    }, ({ x, z, chunk }) => {
      player._client.write('map_chunk', {
        x: x,
        z: z,
        groundUp: true,
        bitMap: chunk.getMask(),
        chunkData: chunk.dump(),
        blockEntities: []
      })
      return Promise.resolve()
    })
  }

  function spiral (arr) {
    const t = []
    spiralloop(arr, (x, z) => {
      t.push([x, z])
    })
    return t
  }

  player.sendNearbyChunks = (view, group) => {
    player.lastPositionChunkUpdated = player.position
    const playerChunkX = Math.floor(player.position.x / 16)
    const playerChunkZ = Math.floor(player.position.z / 16)

    Object.keys(player.loadedChunks)
      .map((key) => key.split(',').map(a => parseInt(a)))
      .filter(([x, z]) => Math.abs(x - playerChunkX) > view || Math.abs(z - playerChunkZ) > view)
      .forEach(([x, z]) => player.unloadChunk(x, z))

    return spiral([view * 2, view * 2])
      .map(t => ({
        chunkX: playerChunkX + t[0] - view,
        chunkZ: playerChunkZ + t[1] - view
      }))
      .filter(({ chunkX, chunkZ }) => {
        const key = chunkX + ',' + chunkZ
        const loaded = player.loadedChunks[key]
        if (!loaded) player.loadedChunks[key] = 1
        return !loaded
      })
      .reduce((acc, { chunkX, chunkZ }) => {
        const p = acc
          .then(() => player.world.getColumn(chunkX, chunkZ))
          .then((column) => player.sendChunk(chunkX, chunkZ, column))
        return group ? p.then(() => sleep(5)) : p
      }
      , Promise.resolve())
  }

  function sleep (ms = 0) {
    return new Promise(resolve => setTimeout(resolve, ms))
  }

  player.sendMap = () => {
    return player.sendNearbyChunks(Math.min(3, settings['view-distance']))
      .catch((err) => setTimeout(() => { throw err }), 0)
  }

  player.sendRestMap = () => {
    player.sendingChunks = true
    player.sendNearbyChunks(Math.min(player.view, settings['view-distance']), true)
      .then(() => { player.sendingChunks = false })
      .catch((err) => setTimeout(() => { throw err }, 0))
  }

  player.sendSpawnPosition = () => {
    player._client.write('spawn_position', {
      location: player.spawnPoint
    })
  }

  player.changeWorld = async (world, opt) => {
    if (player.world === world) return Promise.resolve()
    opt = opt || {}
    player.world = world
    player.loadedChunks = {}
    if (typeof opt.gamemode !== 'undefined') player.gameMode = opt.gamemode
    player._client.write('respawn', {
      dimension: opt.dimension || 0,
      difficulty: opt.difficulty || serv.difficulty,
      gamemode: opt.gamemode || player.gameMode,
      levelType: 'default'
    })
    await player.findSpawnPoint()
    player.position = player.spawnPoint
    player.sendSpawnPosition()
    player.updateAndSpawn()

    await player.sendMap()

    player.sendSelfPosition()
    player.emit('change_world')

    await player.waitPlayerLogin()
    player.sendRestMap()
  }

  player.commands.add({
    base: 'changeworld',
    info: 'to change world',
    usage: '/changeworld overworld|nether',
    op: true,
    action (world) {
      if (world === 'nether') player.changeWorld(serv.netherworld, { dimension: -1 })
      if (world === 'overworld') player.changeWorld(serv.overworld, { dimension: 0 })
    }
  })
}
<|endoftext|>


<commit_before>'use strict';

const co = require('co');
const Promise = require('bluebird');
const parseProduct = require('./product-parse');

module.exports = function parseReports(data, options) {
	// Return the products defined in the optional `options` object or return the defaults.
	return co(function* spcRequest() {
		if(typeof data !== 'string') {
			throw new Error('`data` must be a valid string');
		}

		if(options && typeof options !== 'object') {
			throw new Error("'options' must be a valid object.");
		}

		let results = {};
		for (let property in options) {
			if (options.hasOwnProperty(property) && options[property]) {
				results[property] = parseProduct(property, data);
			}
		}

		return Promise.resolve(results);
	}).catch(function errorHandler(err) {
		throw (err);
	});
};<commit_msg>Adding comments<commit_after>'use strict';

const co = require('co');
const Promise = require('bluebird');
const parseProduct = require('./product-parse');

module.exports = function parseReports(data, options) {
	// Return the products defined in the optional `options` object or return the defaults.
	return co(function* spcRequest() {
		// Validate that the data is a valid string
		if(typeof data !== 'string') {
			throw new Error('`data` must be a valid string');
		}

		// If an `options` value is supplied, verify that it is an object
		if(options && typeof options !== 'object') {
			throw new Error("'options' must be a valid object.");
		}

		let results = {};
		// Loop through each product property within the options object
		for (let property in options) {
			// If the product is requested to be returned (`true`)
			if (options.hasOwnProperty(property) && options[property]) {
				// Parse the events for this product and store it in the the results (response)
				results[property] = parseProduct(property, data);
			}
		}

		return Promise.resolve(results);
	}).catch(function errorHandler(err) {
		throw (err);
	});
};<|endoftext|>


<commit_before>/*
 * gaze
 * https://github.com/shama/gaze
 *
 * Copyright (c) 2013 Kyle Robinson Young
 * Licensed under the MIT license.
 */

'use strict';

// libs
var util = require('util');
var EE = require('events').EventEmitter;
var fs = require('fs');
var path = require('path');
var globule = require('globule');
var helper = require('./helper');

// globals
var delay = 10;

// `Gaze` EventEmitter object to return in the callback
function Gaze(patterns, opts, done) {
  var self = this;
  EE.call(self);

  // If second arg is the callback
  if (typeof opts === 'function') {
    done = opts;
    opts = {};
  }

  // Default options
  opts = opts || {};
  opts.mark = true;
  opts.interval = opts.interval || 100;
  opts.debounceDelay = opts.debounceDelay || 500;
  opts.cwd = opts.cwd || process.cwd();
  this.options = opts;

  // Default done callback
  done = done || function() {};

  // Remember our watched dir:files
  this._watched = Object.create(null);

  // Store watchers
  this._watchers = Object.create(null);

  // Store watchFile listeners
  this._pollers = Object.create(null);

  // Store patterns
  this._patterns = [];

  // Cached events for debouncing
  this._cached = Object.create(null);

  // Set maxListeners
  if (this.options.maxListeners) {
    this.setMaxListeners(this.options.maxListeners);
    Gaze.super_.prototype.setMaxListeners(this.options.maxListeners);
    delete this.options.maxListeners;
  }

  // Initialize the watch on files
  if (patterns) {
    this.add(patterns, done);
  }

  // keep the process alive
  this._keepalive = setInterval(function() {}, 200);

  return this;
}
util.inherits(Gaze, EE);

// Main entry point. Start watching and call done when setup
module.exports = function gaze(patterns, opts, done) {
  return new Gaze(patterns, opts, done);
};
module.exports.Gaze = Gaze;

// Override the emit function to emit `all` events
// and debounce on duplicate events per file
Gaze.prototype.emit = function() {
  var self = this;
  var args = arguments;

  var e = args[0];
  var filepath = args[1];
  var timeoutId;

  // If not added/deleted/changed/renamed then just emit the event
  if (e.slice(-2) !== 'ed') {
    Gaze.super_.prototype.emit.apply(self, args);
    return this;
  }

  // Detect rename event, if added and previous deleted is in the cache
  if (e === 'added') {
    Object.keys(this._cached).forEach(function(oldFile) {
      if (self._cached[oldFile].indexOf('deleted') !== -1) {
        args[0] = e = 'renamed';
        [].push.call(args, oldFile);
        delete self._cached[oldFile];
        return false;
      }
    });
  }

  // If cached doesnt exist, create a delay before running the next
  // then emit the event
  var cache = this._cached[filepath] || [];
  if (cache.indexOf(e) === -1) {
    helper.objectPush(self._cached, filepath, e);
    clearTimeout(timeoutId);
    timeoutId = setTimeout(function() {
      delete self._cached[filepath];
    }, this.options.debounceDelay);
    // Emit the event and `all` event
    Gaze.super_.prototype.emit.apply(self, args);
    Gaze.super_.prototype.emit.apply(self, ['all', e].concat([].slice.call(args, 1)));
  }

  // Detect if new folder added to trigger for matching files within folder
  if (e === 'added') {
    if (helper.isDir(filepath)) {
      fs.readdirSync(filepath).map(function(file) {
        return path.join(filepath, file);
      }).filter(function(file) {
        return globule.isMatch(self._patterns, file, self.options);
      }).forEach(function(file) {
        self.emit('added', file);
      });
    }
  }

  return this;
};

// Close watchers
Gaze.prototype.close = function(_reset) {
  var self = this;
  _reset = _reset === false ? false : true;
  Object.keys(self._watchers).forEach(function(file) {
    self._watchers[file].close();
  });
  self._watchers = Object.create(null);
  Object.keys(this._watched).forEach(function(dir) {
    self._unpollDir(dir);
  });
  if (_reset) {
    self._watched = Object.create(null);
    setTimeout(function() {
      self.emit('end');
      self.removeAllListeners();
      clearInterval(self._keepalive);
    }, delay + 100);
  }
  return self;
};

// Add file patterns to be watched
Gaze.prototype.add = function(files, done) {
  if (typeof files === 'string') { files = [files]; }
  this._patterns = helper.unique.apply(null, [this._patterns, files]);
  files = globule.find(this._patterns, this.options);
  this._addToWatched(files);
  this.close(false);
  this._initWatched(done);
};

// Dont increment patterns and dont call done if nothing added
Gaze.prototype._internalAdd = function(file, done) {
  var files = [];
  if (helper.isDir(file)) {
    files = [helper.markDir(file)].concat(globule.find(this._patterns, this.options));
  } else {
    if (globule.isMatch(this._patterns, file, this.options)) {
      files = [file];
    }
  }
  if (files.length > 0) {
    this._addToWatched(files);
    this.close(false);
    this._initWatched(done);
  }
};

// Remove file/dir from `watched`
Gaze.prototype.remove = function(file) {
  var self = this;
  if (this._watched[file]) {
    // is dir, remove all files
    this._unpollDir(file);
    delete this._watched[file];
  } else {
    // is a file, find and remove
    Object.keys(this._watched).forEach(function(dir) {
      var index = self._watched[dir].indexOf(file);
      if (index !== -1) {
        self._unpollFile(file);
        self._watched[dir].splice(index, 1);
        return false;
      }
    });
  }
  if (this._watchers[file]) {
    this._watchers[file].close();
  }
  return this;
};

// Return watched files
Gaze.prototype.watched = function(done) {
  done(null, this._watched);
  return this;
};

// Returns `watched` files with relative paths to process.cwd()
Gaze.prototype.relative = function(dir, unixify, done) {
  if (typeof dir === 'function') {
    done = dir;
    dir = null;
    unixify = false;
  }
  if (typeof unixify === 'function') {
    done = unixify;
    unixify = false;
  }
  var self = this;
  var relative = Object.create(null);
  var relDir, relFile, unixRelDir;
  var cwd = this.options.cwd || process.cwd();
  if (dir === '') { dir = '.'; }
  dir = helper.markDir(dir);
  unixify = unixify || false;
  Object.keys(this._watched).forEach(function(dir) {
    relDir = path.relative(cwd, dir) + path.sep;
    if (relDir === path.sep) { relDir = '.'; }
    unixRelDir = unixify ? helper.unixifyPathSep(relDir) : relDir;
    relative[unixRelDir] = self._watched[dir].map(function(file) {
      relFile = path.relative(path.join(cwd, relDir) || '', file || '');
      if (helper.isDir(file)) {
        relFile = helper.markDir(relFile);
      }
      if (unixify) {
        relFile = helper.unixifyPathSep(relFile);
      }
      done(null, relFile);
      return self;
    });
  });
  if (dir && unixify) {
    dir = helper.unixifyPathSep(dir);
  }
  done(null, dir ? relative[dir] || [] : relative);
  return self;
};

// Adds files and dirs to watched
Gaze.prototype._addToWatched = function(files) {
  for (var i = 0; i < files.length; i++) {
    var file = files[i];
    var filepath = path.resolve(this.options.cwd, file);

    var dirname = (helper.isDir(file)) ? filepath : path.dirname(filepath);
    dirname = helper.markDir(dirname);

    // If a new dir is added
    if (helper.isDir(file) && !(filepath in this._watched)) {
      helper.objectPush(this._watched, filepath, []);
    }

    if (file.slice(-1) === '/') { filepath += path.sep; }
    helper.objectPush(this._watched, path.dirname(filepath) + path.sep, filepath);

    // add folders into the mix
    var readdir = fs.readdirSync(dirname);
    for (var j = 0; j < readdir.length; j++) {
      var dirfile = path.join(dirname, readdir[j]);
      if (fs.statSync(dirfile).isDirectory()) {
        helper.objectPush(this._watched, dirname, dirfile + path.sep);
      }
    }
  }
  return this;
};

Gaze.prototype._watchDir = function(dir, done) {
  var self = this;
  var timeoutId;
  // Dont even try watching the dir if it doesnt exist
  if (!fs.existsSync(dir)) { return; }
  try {
    this._watchers[dir] = fs.watch(dir, function(event) {
      // race condition. Let's give the fs a little time to settle down. so we
      // don't fire events on non existent files.
      clearTimeout(timeoutId);
      timeoutId = setTimeout(function() {
        // race condition. Ensure that this directory is still being watched
        // before continuing.
        if ((dir in self._watchers) && fs.existsSync(dir)) {
          done(null, dir);
        }
      }, delay + 100);
    });
  } catch (err) {
    return this._handleError(err);
  }
  return this;
};

Gaze.prototype._unpollFile = function(file) {
  if (this._pollers[file]) {
    fs.unwatchFile(file, this._pollers[file] );
    delete this._pollers[file];
  }
  return this;
};

Gaze.prototype._unpollDir = function(dir) {
  this._unpollFile(dir);
  for (var i = 0; i < this._watched[dir].length; i++) {
    this._unpollFile(this._watched[dir][i]);
  }
};

Gaze.prototype._pollFile = function(file, done) {
  var opts = { persistent: true, interval: this.options.interval };
  if (!this._pollers[file]) {
    this._pollers[file] = function(curr, prev) {
      done(null, file);
    };
    try {
      fs.watchFile(file, opts, this._pollers[file]);
    } catch (err) {
      return this._handleError(err);
    }
  }
  return this;
};

// Initialize the actual watch on `watched` files
Gaze.prototype._initWatched = function(done) {
  var self = this;
  var cwd = this.options.cwd || process.cwd();
  var curWatched = Object.keys(self._watched);

  // if no matching files
  if (curWatched.length < 1) {
    self.emit('ready', self);
    if (done) { done.call(self, null, self); }
    self.emit('nomatch');
    return;
  }

  helper.forEachSeries(curWatched, function(dir, next) {
    dir = dir || '';
    var files = self._watched[dir];
    // Triggered when a watched dir has an event
    self._watchDir(dir, function(event, dirpath) {
      var relDir = cwd === dir ? '.' : path.relative(cwd, dir);
      relDir = relDir || '';

      fs.readdir(dirpath, function(err, current) {
        if (err) { return self.emit('error', err); }
        if (!current) { return; }

        try {
          // append path.sep to directories so they match previous.
          current = current.map(function(curPath) {
            if (fs.existsSync(path.join(dir, curPath)) && fs.statSync(path.join(dir, curPath)).isDirectory()) {
              return curPath + path.sep;
            } else {
              return curPath;
            }
          });
        } catch (err) {
          // race condition-- sometimes the file no longer exists
        }

        // Get watched files for this dir
        self.relative(relDir, function(err, previous) {

          // If file was deleted
          previous.filter(function(file) {
            return current.indexOf(file) < 0;
          }).forEach(function(file) {
            if (!helper.isDir(file)) {
              var filepath = path.join(dir, file);
              self.remove(filepath);
              self.emit('deleted', filepath);
            }
          });

          // If file was added
          current.filter(function(file) {
            return previous.indexOf(file) < 0;
          }).forEach(function(file) {
            // Is it a matching pattern?
            var relFile = path.join(relDir, file);
            // Add to watch then emit event
            self._internalAdd(relFile, function() {
              self.emit('added', path.join(dir, file));
            });
          });

        });

      });
    });

    // Watch for change/rename events on files
    files.forEach(function(file) {
      if (helper.isDir(file)) { return; }
      self._pollFile(file, function(err, filepath) {
        // Only emit changed if the file still exists
        // Prevents changed/deleted duplicate events
        if (fs.existsSync(filepath)) {
          self.emit('changed', filepath);
        }
      });
    });

    next();
  }, function() {

    // Return this instance of Gaze
    // delay before ready solves a lot of issues
    setTimeout(function() {
      self.emit('ready', self);
      if (done) { done.call(self, null, self); }
    }, delay + 100);

  });
};

// If an error, handle it here
Gaze.prototype._handleError = function(err) {
  if (err.code === 'EMFILE') {
    return this.emit('error', new Error('EMFILE: Too many opened files.'));
  }
  return this.emit('error', err);
};<commit_msg>Fix for node v0.8 relative<commit_after>/*
 * gaze
 * https://github.com/shama/gaze
 *
 * Copyright (c) 2013 Kyle Robinson Young
 * Licensed under the MIT license.
 */

'use strict';

// libs
var util = require('util');
var EE = require('events').EventEmitter;
var fs = require('fs');
var path = require('path');
var globule = require('globule');
var helper = require('./helper');

// globals
var delay = 10;

// `Gaze` EventEmitter object to return in the callback
function Gaze(patterns, opts, done) {
  var self = this;
  EE.call(self);

  // If second arg is the callback
  if (typeof opts === 'function') {
    done = opts;
    opts = {};
  }

  // Default options
  opts = opts || {};
  opts.mark = true;
  opts.interval = opts.interval || 100;
  opts.debounceDelay = opts.debounceDelay || 500;
  opts.cwd = opts.cwd || process.cwd();
  this.options = opts;

  // Default done callback
  done = done || function() {};

  // Remember our watched dir:files
  this._watched = Object.create(null);

  // Store watchers
  this._watchers = Object.create(null);

  // Store watchFile listeners
  this._pollers = Object.create(null);

  // Store patterns
  this._patterns = [];

  // Cached events for debouncing
  this._cached = Object.create(null);

  // Set maxListeners
  if (this.options.maxListeners) {
    this.setMaxListeners(this.options.maxListeners);
    Gaze.super_.prototype.setMaxListeners(this.options.maxListeners);
    delete this.options.maxListeners;
  }

  // Initialize the watch on files
  if (patterns) {
    this.add(patterns, done);
  }

  // keep the process alive
  this._keepalive = setInterval(function() {}, 200);

  return this;
}
util.inherits(Gaze, EE);

// Main entry point. Start watching and call done when setup
module.exports = function gaze(patterns, opts, done) {
  return new Gaze(patterns, opts, done);
};
module.exports.Gaze = Gaze;

// Override the emit function to emit `all` events
// and debounce on duplicate events per file
Gaze.prototype.emit = function() {
  var self = this;
  var args = arguments;

  var e = args[0];
  var filepath = args[1];
  var timeoutId;

  // If not added/deleted/changed/renamed then just emit the event
  if (e.slice(-2) !== 'ed') {
    Gaze.super_.prototype.emit.apply(self, args);
    return this;
  }

  // Detect rename event, if added and previous deleted is in the cache
  if (e === 'added') {
    Object.keys(this._cached).forEach(function(oldFile) {
      if (self._cached[oldFile].indexOf('deleted') !== -1) {
        args[0] = e = 'renamed';
        [].push.call(args, oldFile);
        delete self._cached[oldFile];
        return false;
      }
    });
  }

  // If cached doesnt exist, create a delay before running the next
  // then emit the event
  var cache = this._cached[filepath] || [];
  if (cache.indexOf(e) === -1) {
    helper.objectPush(self._cached, filepath, e);
    clearTimeout(timeoutId);
    timeoutId = setTimeout(function() {
      delete self._cached[filepath];
    }, this.options.debounceDelay);
    // Emit the event and `all` event
    Gaze.super_.prototype.emit.apply(self, args);
    Gaze.super_.prototype.emit.apply(self, ['all', e].concat([].slice.call(args, 1)));
  }

  // Detect if new folder added to trigger for matching files within folder
  if (e === 'added') {
    if (helper.isDir(filepath)) {
      fs.readdirSync(filepath).map(function(file) {
        return path.join(filepath, file);
      }).filter(function(file) {
        return globule.isMatch(self._patterns, file, self.options);
      }).forEach(function(file) {
        self.emit('added', file);
      });
    }
  }

  return this;
};

// Close watchers
Gaze.prototype.close = function(_reset) {
  var self = this;
  _reset = _reset === false ? false : true;
  Object.keys(self._watchers).forEach(function(file) {
    self._watchers[file].close();
  });
  self._watchers = Object.create(null);
  Object.keys(this._watched).forEach(function(dir) {
    self._unpollDir(dir);
  });
  if (_reset) {
    self._watched = Object.create(null);
    setTimeout(function() {
      self.emit('end');
      self.removeAllListeners();
      clearInterval(self._keepalive);
    }, delay + 100);
  }
  return self;
};

// Add file patterns to be watched
Gaze.prototype.add = function(files, done) {
  if (typeof files === 'string') { files = [files]; }
  this._patterns = helper.unique.apply(null, [this._patterns, files]);
  files = globule.find(this._patterns, this.options);
  this._addToWatched(files);
  this.close(false);
  this._initWatched(done);
};

// Dont increment patterns and dont call done if nothing added
Gaze.prototype._internalAdd = function(file, done) {
  var files = [];
  if (helper.isDir(file)) {
    files = [helper.markDir(file)].concat(globule.find(this._patterns, this.options));
  } else {
    if (globule.isMatch(this._patterns, file, this.options)) {
      files = [file];
    }
  }
  if (files.length > 0) {
    this._addToWatched(files);
    this.close(false);
    this._initWatched(done);
  }
};

// Remove file/dir from `watched`
Gaze.prototype.remove = function(file) {
  var self = this;
  if (this._watched[file]) {
    // is dir, remove all files
    this._unpollDir(file);
    delete this._watched[file];
  } else {
    // is a file, find and remove
    Object.keys(this._watched).forEach(function(dir) {
      var index = self._watched[dir].indexOf(file);
      if (index !== -1) {
        self._unpollFile(file);
        self._watched[dir].splice(index, 1);
        return false;
      }
    });
  }
  if (this._watchers[file]) {
    this._watchers[file].close();
  }
  return this;
};

// Return watched files
Gaze.prototype.watched = function(done) {
  done(null, this._watched);
  return this;
};

// Returns `watched` files with relative paths to process.cwd()
Gaze.prototype.relative = function(dir, unixify, done) {
  if (typeof dir === 'function') {
    done = dir;
    dir = null;
    unixify = false;
  }
  if (typeof unixify === 'function') {
    done = unixify;
    unixify = false;
  }
  var self = this;
  var relative = Object.create(null);
  var relDir, relFile, unixRelDir;
  var cwd = this.options.cwd || process.cwd();
  if (dir === '') { dir = '.'; }
  dir = helper.markDir(dir);
  unixify = unixify || false;
  Object.keys(this._watched).forEach(function(dir) {
    relDir = path.relative(cwd, dir) + path.sep;
    if (relDir === path.sep) { relDir = '.'; }
    unixRelDir = unixify ? helper.unixifyPathSep(relDir) : relDir;
    relative[unixRelDir] = self._watched[dir].map(function(file) {
      relFile = path.relative(path.join(cwd, relDir) || '', file || '');
      if (helper.isDir(file)) {
        relFile = helper.markDir(relFile);
      }
      if (unixify) {
        relFile = helper.unixifyPathSep(relFile);
      }
      return relFile;
    });
  });
  if (dir && unixify) {
    dir = helper.unixifyPathSep(dir);
  }
  done(null, dir ? relative[dir] || [] : relative);
  return self;
};

// Adds files and dirs to watched
Gaze.prototype._addToWatched = function(files) {
  for (var i = 0; i < files.length; i++) {
    var file = files[i];
    var filepath = path.resolve(this.options.cwd, file);

    var dirname = (helper.isDir(file)) ? filepath : path.dirname(filepath);
    dirname = helper.markDir(dirname);

    // If a new dir is added
    if (helper.isDir(file) && !(filepath in this._watched)) {
      helper.objectPush(this._watched, filepath, []);
    }

    if (file.slice(-1) === '/') { filepath += path.sep; }
    helper.objectPush(this._watched, path.dirname(filepath) + path.sep, filepath);

    // add folders into the mix
    var readdir = fs.readdirSync(dirname);
    for (var j = 0; j < readdir.length; j++) {
      var dirfile = path.join(dirname, readdir[j]);
      if (fs.statSync(dirfile).isDirectory()) {
        helper.objectPush(this._watched, dirname, dirfile + path.sep);
      }
    }
  }
  return this;
};

Gaze.prototype._watchDir = function(dir, done) {
  var self = this;
  var timeoutId;
  // Dont even try watching the dir if it doesnt exist
  if (!fs.existsSync(dir)) { return; }
  try {
    this._watchers[dir] = fs.watch(dir, function(event) {
      // race condition. Let's give the fs a little time to settle down. so we
      // don't fire events on non existent files.
      clearTimeout(timeoutId);
      timeoutId = setTimeout(function() {
        // race condition. Ensure that this directory is still being watched
        // before continuing.
        if ((dir in self._watchers) && fs.existsSync(dir)) {
          done(null, dir);
        }
      }, delay + 100);
    });
  } catch (err) {
    return this._handleError(err);
  }
  return this;
};

Gaze.prototype._unpollFile = function(file) {
  if (this._pollers[file]) {
    fs.unwatchFile(file, this._pollers[file] );
    delete this._pollers[file];
  }
  return this;
};

Gaze.prototype._unpollDir = function(dir) {
  this._unpollFile(dir);
  for (var i = 0; i < this._watched[dir].length; i++) {
    this._unpollFile(this._watched[dir][i]);
  }
};

Gaze.prototype._pollFile = function(file, done) {
  var opts = { persistent: true, interval: this.options.interval };
  if (!this._pollers[file]) {
    this._pollers[file] = function(curr, prev) {
      done(null, file);
    };
    try {
      fs.watchFile(file, opts, this._pollers[file]);
    } catch (err) {
      return this._handleError(err);
    }
  }
  return this;
};

// Initialize the actual watch on `watched` files
Gaze.prototype._initWatched = function(done) {
  var self = this;
  var cwd = this.options.cwd || process.cwd();
  var curWatched = Object.keys(self._watched);

  // if no matching files
  if (curWatched.length < 1) {
    self.emit('ready', self);
    if (done) { done.call(self, null, self); }
    self.emit('nomatch');
    return;
  }

  helper.forEachSeries(curWatched, function(dir, next) {
    dir = dir || '';
    var files = self._watched[dir];
    // Triggered when a watched dir has an event
    self._watchDir(dir, function(event, dirpath) {
      var relDir = cwd === dir ? '.' : path.relative(cwd, dir);
      relDir = relDir || '';

      fs.readdir(dirpath, function(err, current) {
        if (err) { return self.emit('error', err); }
        if (!current) { return; }

        try {
          // append path.sep to directories so they match previous.
          current = current.map(function(curPath) {
            if (fs.existsSync(path.join(dir, curPath)) && fs.statSync(path.join(dir, curPath)).isDirectory()) {
              return curPath + path.sep;
            } else {
              return curPath;
            }
          });
        } catch (err) {
          // race condition-- sometimes the file no longer exists
        }

        // Get watched files for this dir
        self.relative(relDir, function(err, previous) {

          // If file was deleted
          previous.filter(function(file) {
            return current.indexOf(file) < 0;
          }).forEach(function(file) {
            if (!helper.isDir(file)) {
              var filepath = path.join(dir, file);
              self.remove(filepath);
              self.emit('deleted', filepath);
            }
          });

          // If file was added
          current.filter(function(file) {
            return previous.indexOf(file) < 0;
          }).forEach(function(file) {
            // Is it a matching pattern?
            var relFile = path.join(relDir, file);
            // Add to watch then emit event
            self._internalAdd(relFile, function() {
              self.emit('added', path.join(dir, file));
            });
          });

        });

      });
    });

    // Watch for change/rename events on files
    files.forEach(function(file) {
      if (helper.isDir(file)) { return; }
      self._pollFile(file, function(err, filepath) {
        // Only emit changed if the file still exists
        // Prevents changed/deleted duplicate events
        if (fs.existsSync(filepath)) {
          self.emit('changed', filepath);
        }
      });
    });

    next();
  }, function() {

    // Return this instance of Gaze
    // delay before ready solves a lot of issues
    setTimeout(function() {
      self.emit('ready', self);
      if (done) { done.call(self, null, self); }
    }, delay + 100);

  });
};

// If an error, handle it here
Gaze.prototype._handleError = function(err) {
  if (err.code === 'EMFILE') {
    return this.emit('error', new Error('EMFILE: Too many opened files.'));
  }
  return this.emit('error', err);
};<|endoftext|>


<commit_before>module.exports = req => {
  if (!req) return
  if (req.headers) {
    if (req.headers['x-forwarded']) {
      return req.headers['x-forwarded']
    }
    if (req.headers['forwarded-for']) {
      return req.headers['forwarded-for']
    }
    if (req.headers['x-client-ip']) {
      return req.headers['x-client-ip']
    }
  }

  if (req.connection && req.connection.remoteAddress) {
    return req.connection.remoteAddress
  }

  if (req.socket && req.socket.remoteAddress) {
    return req.socket.remoteAddress
  }
}
<commit_msg>Fix real ip<commit_after>module.exports = req => {
  if (!req) return
  if (req.headers) {
    if (req.headers['x-zeit-co-forwarded-for']) {
      return req.headers['x-zeit-co-forwarded-for']
    }
    if (req.headers['forwarded-for']) {
      return req.headers['forwarded-for']
    }
    if (req.headers['x-real-ip']) {
      return req.headers['x-real-ip']
    }
  }

  if (req.connection && req.connection.remoteAddress) {
    return req.connection.remoteAddress
  }

  if (req.socket && req.socket.remoteAddress) {
    return req.socket.remoteAddress
  }
}
<|endoftext|>


<commit_before>const fs = require('fs')

module.exports = function (input) {
  return new Promise((resolve, reject) => {
    fs.readFile('./keys', 'utf8', (err, data) => {
      if (err) {
        reject(err); return
      }
      let key = JSON.parse(data)[input]
      resolve(key)
    })
    console.log('LOG:\tRetrieved ' + input + ' key')
  })
}
<commit_msg>unify key retrieval for cron<commit_after>const fs = require('fs')
const path = require('path')
const currentDir = path.resolve(process.cwd());

module.exports = function (input) {
  return new Promise((resolve, reject) => {
    fs.readFile(currentDir + '/keys', 'utf8', (err, data) => {
      if (err) {
        reject(err); return
      }
      let key = JSON.parse(data)[input]
      resolve(key)
    })
    console.log('LOG:\tRetrieved ' + input + ' key')
  })
}
<|endoftext|>


<commit_before>var Async = require('async');
var Config = require('getconfig');
var Hoek = require('hoek');
var Utils = require('./utils');
var Querystring = require('querystring');
var Semver = require('semver');

var internals = {};

internals.requestOptions = {
    headers: {
        'user-agent': 'hapijs.com',
        'authorization': 'token ' + Config.githubToken
    },
    json: true
};

exports.methods = [];

exports.methods.push({
    name: 'github.commits',
    method: function (callback) {

        return Utils.download('https://api.github.com/repos/hapijs/hapi/commits', internals.requestOptions, callback);
    },
    options: {
        cache: {
            expiresIn: Utils.fifteenMinutes
        }
    }
});

exports.methods.push({
    name: 'github.issues',
    method: function (callback) {

        var weekAgo = new Date();
        weekAgo.setDate(weekAgo.getDate() - 7);

        var params = Querystring.encode({
            sort: 'created',
            state: 'closed',
            since: weekAgo.toISOString()
        });

        return Utils.download('https://api.github.com/repos/hapijs/hapi/issues?' + params, internals.requestOptions, function (err, issues) {

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

            issues = issues.filter(function (issue) {

                return !issue.hasOwnProperty('pull_request');
            });

            callback(null, issues);
        });
    },
    options: {
        cache: {
            expiresIn: Utils.fifteenMinutes
        }
    }
});

exports.methods.push({
    name: 'github.pullRequests',
    method: function (callback) {

        var weekAgo = new Date();
        weekAgo.setDate(weekAgo.getDate() - 7);

        var params = Querystring.encode({
            sort: 'created',
            direction: 'desc',
            state: 'closed',
            since: weekAgo.toISOString()
        });

        return Utils.download('https://api.github.com/repos/hapijs/hapi/pulls?' + params, internals.requestOptions, callback);
    },
    options: {
        cache: {
            expiresIn: Utils.fifteenMinutes
        }
    }
});

exports.methods.push({
    name: 'github.governance',
    method: function (callback) {

        var options = Hoek.applyToDefaults(internals.requestOptions, {
            headers: {
                accept: 'application/vnd.github.3.html'
            }
        });

        return Utils.download('https://api.github.com/repos/hapijs/contrib/contents/Governance.md', options, callback);
    },
    options: {
        cache: {
            expiresIn: Utils.oneDay
        }
    }
});

exports.methods.push({
    name: 'github.styleGuide',
    method: function (callback) {

        var options = Hoek.applyToDefaults(internals.requestOptions, {
            headers: {
                accept: 'application/vnd.github.3.html'
            }
        });

        return Utils.download('https://api.github.com/repos/hapijs/contrib/contents/Style.md', options, callback);
    },
    options: {
        cache: {
            expiresIn: Utils.oneDay
        }
    }
});

exports.methods.push({
    name: 'github.guidelines',
    method: function (callback) {

        var options = Hoek.applyToDefaults(internals.requestOptions, {
            headers: {
                accept: 'application/vnd.github.3.html'
            }
        });

        return Utils.download('https://api.github.com/repos/hapijs/contrib/contents/Guidelines.md', options, callback);
    },
    options: {
        cache: {
            expiresIn: Utils.oneDay
        }
    }
});

exports.methods.push({
    name: 'github.latestUpdate',
    method: function (request, callback) {

        var latestCommit = request.pre.commits[0];
        var latestIssue = request.pre.issues[0];
        var latest = {};

        if (latestCommit && !latestIssue || (latestCommit && latestIssue && new Date(latestCommit.commit.committer.date).getTime() > new Date(latestIssue.updated_at).getTime())) {
            latest.title = latestCommit.commit.message;
            latest.updated = latestCommit.commit.committer.date;
            latest.url = latestCommit.html_url;
        } else if (latestIssue) {
            latest.title = latestIssue.title;
            latest.updated = latestIssue.updated_at;
            latest.url = latestIssue.html_url;
        }

        callback(null, latest);
    },
    options: {
        cache: {
            expiresIn: Utils.fifteenMinutes
        },
        generateKey: function () {

            return 'latestUpdate';
        }
    }
});

exports.methods.push({
    name: 'github.repos',
    method: function (callback) {

        return Utils.download('https://api.github.com/orgs/hapijs/repos', internals.requestOptions, callback);
    },
    options: {
        cache: {
            expiresIn: Utils.oneDay
        }
    }
});

exports.methods.push({
    name: 'github.tags',
    method: function (callback) {

        return Utils.download('https://api.github.com/repos/hapijs/hapi/tags', internals.requestOptions, callback);
    },
    options: {
        cache: {
            expiresIn: Utils.fifteenMinutes
        }
    }
});

exports.methods.push({
    name: 'github.reference',
    method: function (ref, callback) {

        var options = Hoek.applyToDefaults(internals.requestOptions, {
            headers: {
                accept: 'application/vnd.github.3.html'
            }
        });

        var path;
        if (Semver.lt(ref, '7.0.0')) {
            path = 'https://api.github.com/repos/hapijs/hapi/contents/docs/Reference.md?ref=v' + ref;
        }
        else {
            path = 'https://api.github.com/repos/hapijs/hapi/contents/API.md?ref=v' + ref;
        }

        return Utils.download(path, options, callback);
    },
    options: {
        cache: {
            expiresIn: Utils.oneYear
        }
    }
});

exports.methods.push({
    name: 'github.newContributorIssues',
    method: function (request, callback) {

        var params = Querystring.encode({
            labels: 'new contributor'
        });

        var repos = request.pre.repos.filter(function (repo) {

            return repo.open_issues > 0;
        }).map(function (repo) {

            return repo.name;
        });

        var newContributorIssues = [];

        Async.eachLimit(repos, 10, function (repo, cb) {

            Utils.download('https://api.github.com/repos/hapijs/' + repo + '/issues?' + params, internals.requestOptions, function (err, issues) {

                if (err) {
                    return cb(err);
                }

                issues = issues.map(function (issue) {

                    issue.repo = repo;
                    return issue;
                });

                newContributorIssues = newContributorIssues.concat(issues);
                cb();
            });
        }, function (err) {

            if (err) {
                return next(err);
            }

            callback(null, newContributorIssues);
        });
    },
    options: {
        cache: {
            expiresIn: Utils.fifteenMinutes
        },
        generateKey: function () {

            return 'newContributorIssues';
        }
    }
});

exports.methods.push({
    name: 'github.helpWantedIssues',
    method: function (request, callback) {

        var params = Querystring.encode({
            labels: 'help wanted'
        });

        var repos = request.pre.repos.filter(function (repo) {

            return repo.open_issues > 0;
        }).map(function (repo) {

            return repo.name;
        });

        var helpWantedIssues = [];

        Async.eachLimit(repos, 10, function (repo, cb) {

            Utils.download('https://api.github.com/repos/hapijs/' + repo + '/issues?' + params, internals.requestOptions, function (err, issues) {

                if (err) {
                    return cb(err);
                }

                issues = issues.map(function (issue) {

                    issue.repo = repo;
                    return issue;
                });

                helpWantedIssues = helpWantedIssues.concat(issues);
                cb();
            });
        }, function (err) {

            if (err) {
                return next(err);
            }

            callback(null, helpWantedIssues);
        });
    },
    options: {
        cache: {
            expiresIn: Utils.fifteenMinutes
        },
        generateKey: function () {

            return 'helpWantedIssues';
        }
    }
});
<commit_msg>Only return merged PRs from github.pullRequests<commit_after>var Async = require('async');
var Config = require('getconfig');
var Hoek = require('hoek');
var Utils = require('./utils');
var Querystring = require('querystring');
var Semver = require('semver');

var internals = {};

internals.requestOptions = {
    headers: {
        'user-agent': 'hapijs.com',
        'authorization': 'token ' + Config.githubToken
    },
    json: true
};

exports.methods = [];

exports.methods.push({
    name: 'github.commits',
    method: function (callback) {

        return Utils.download('https://api.github.com/repos/hapijs/hapi/commits', internals.requestOptions, callback);
    },
    options: {
        cache: {
            expiresIn: Utils.fifteenMinutes
        }
    }
});

exports.methods.push({
    name: 'github.issues',
    method: function (callback) {

        var weekAgo = new Date();
        weekAgo.setDate(weekAgo.getDate() - 7);

        var params = Querystring.encode({
            sort: 'created',
            state: 'closed',
            since: weekAgo.toISOString()
        });

        return Utils.download('https://api.github.com/repos/hapijs/hapi/issues?' + params, internals.requestOptions, function (err, issues) {

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

            issues = issues.filter(function (issue) {

                return !issue.hasOwnProperty('pull_request');
            });

            callback(null, issues);
        });
    },
    options: {
        cache: {
            expiresIn: Utils.fifteenMinutes
        }
    }
});

exports.methods.push({
    name: 'github.pullRequests',
    method: function (callback) {

        var weekAgo = new Date();
        weekAgo.setDate(weekAgo.getDate() - 7);

        var params = Querystring.encode({
            sort: 'created',
            direction: 'desc',
            state: 'closed',
            since: weekAgo.toISOString()
        });

        return Utils.download('https://api.github.com/repos/hapijs/hapi/pulls?' + params, internals.requestOptions, (err, payload) => {

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

            callback(null, payload.filter((p) => p.merged_at));
        });
    },
    options: {
        cache: {
            expiresIn: Utils.fifteenMinutes
        }
    }
});

exports.methods.push({
    name: 'github.governance',
    method: function (callback) {

        var options = Hoek.applyToDefaults(internals.requestOptions, {
            headers: {
                accept: 'application/vnd.github.3.html'
            }
        });

        return Utils.download('https://api.github.com/repos/hapijs/contrib/contents/Governance.md', options, callback);
    },
    options: {
        cache: {
            expiresIn: Utils.oneDay
        }
    }
});

exports.methods.push({
    name: 'github.styleGuide',
    method: function (callback) {

        var options = Hoek.applyToDefaults(internals.requestOptions, {
            headers: {
                accept: 'application/vnd.github.3.html'
            }
        });

        return Utils.download('https://api.github.com/repos/hapijs/contrib/contents/Style.md', options, callback);
    },
    options: {
        cache: {
            expiresIn: Utils.oneDay
        }
    }
});

exports.methods.push({
    name: 'github.guidelines',
    method: function (callback) {

        var options = Hoek.applyToDefaults(internals.requestOptions, {
            headers: {
                accept: 'application/vnd.github.3.html'
            }
        });

        return Utils.download('https://api.github.com/repos/hapijs/contrib/contents/Guidelines.md', options, callback);
    },
    options: {
        cache: {
            expiresIn: Utils.oneDay
        }
    }
});

exports.methods.push({
    name: 'github.latestUpdate',
    method: function (request, callback) {

        var latestCommit = request.pre.commits[0];
        var latestIssue = request.pre.issues[0];
        var latest = {};

        if (latestCommit && !latestIssue || (latestCommit && latestIssue && new Date(latestCommit.commit.committer.date).getTime() > new Date(latestIssue.updated_at).getTime())) {
            latest.title = latestCommit.commit.message;
            latest.updated = latestCommit.commit.committer.date;
            latest.url = latestCommit.html_url;
        } else if (latestIssue) {
            latest.title = latestIssue.title;
            latest.updated = latestIssue.updated_at;
            latest.url = latestIssue.html_url;
        }

        callback(null, latest);
    },
    options: {
        cache: {
            expiresIn: Utils.fifteenMinutes
        },
        generateKey: function () {

            return 'latestUpdate';
        }
    }
});

exports.methods.push({
    name: 'github.repos',
    method: function (callback) {

        return Utils.download('https://api.github.com/orgs/hapijs/repos', internals.requestOptions, callback);
    },
    options: {
        cache: {
            expiresIn: Utils.oneDay
        }
    }
});

exports.methods.push({
    name: 'github.tags',
    method: function (callback) {

        return Utils.download('https://api.github.com/repos/hapijs/hapi/tags', internals.requestOptions, callback);
    },
    options: {
        cache: {
            expiresIn: Utils.fifteenMinutes
        }
    }
});

exports.methods.push({
    name: 'github.reference',
    method: function (ref, callback) {

        var options = Hoek.applyToDefaults(internals.requestOptions, {
            headers: {
                accept: 'application/vnd.github.3.html'
            }
        });

        var path;
        if (Semver.lt(ref, '7.0.0')) {
            path = 'https://api.github.com/repos/hapijs/hapi/contents/docs/Reference.md?ref=v' + ref;
        }
        else {
            path = 'https://api.github.com/repos/hapijs/hapi/contents/API.md?ref=v' + ref;
        }

        return Utils.download(path, options, callback);
    },
    options: {
        cache: {
            expiresIn: Utils.oneYear
        }
    }
});

exports.methods.push({
    name: 'github.newContributorIssues',
    method: function (request, callback) {

        var params = Querystring.encode({
            labels: 'new contributor'
        });

        var repos = request.pre.repos.filter(function (repo) {

            return repo.open_issues > 0;
        }).map(function (repo) {

            return repo.name;
        });

        var newContributorIssues = [];

        Async.eachLimit(repos, 10, function (repo, cb) {

            Utils.download('https://api.github.com/repos/hapijs/' + repo + '/issues?' + params, internals.requestOptions, function (err, issues) {

                if (err) {
                    return cb(err);
                }

                issues = issues.map(function (issue) {

                    issue.repo = repo;
                    return issue;
                });

                newContributorIssues = newContributorIssues.concat(issues);
                cb();
            });
        }, function (err) {

            if (err) {
                return next(err);
            }

            callback(null, newContributorIssues);
        });
    },
    options: {
        cache: {
            expiresIn: Utils.fifteenMinutes
        },
        generateKey: function () {

            return 'newContributorIssues';
        }
    }
});

exports.methods.push({
    name: 'github.helpWantedIssues',
    method: function (request, callback) {

        var params = Querystring.encode({
            labels: 'help wanted'
        });

        var repos = request.pre.repos.filter(function (repo) {

            return repo.open_issues > 0;
        }).map(function (repo) {

            return repo.name;
        });

        var helpWantedIssues = [];

        Async.eachLimit(repos, 10, function (repo, cb) {

            Utils.download('https://api.github.com/repos/hapijs/' + repo + '/issues?' + params, internals.requestOptions, function (err, issues) {

                if (err) {
                    return cb(err);
                }

                issues = issues.map(function (issue) {

                    issue.repo = repo;
                    return issue;
                });

                helpWantedIssues = helpWantedIssues.concat(issues);
                cb();
            });
        }, function (err) {

            if (err) {
                return next(err);
            }

            callback(null, helpWantedIssues);
        });
    },
    options: {
        cache: {
            expiresIn: Utils.fifteenMinutes
        },
        generateKey: function () {

            return 'helpWantedIssues';
        }
    }
});
<|endoftext|>


<commit_before>var Github = require('github'),
	_ = require('lodash'),
	P = require('bluebird');

/**
 * @scope Client
 */
var authenticate = function() {
	this.ghClient.authenticate({
		type: 'oauth',
		token: this.token
	});
};

var Client = module.exports = function(token) {
	this.token = token;
	this.ghClient = new Github({
		version: '3.0.0',
		protocol: 'https'
	});
};

Client.prototype.getPullRequests = function(repo, state) {
	var repoInfo = repo.split('/');
	var requestArgs = {
		user: repoInfo[0],
		repo: repoInfo[1],
		state: state
	};
	authenticate.call(this);
	return P.fromCallback(this.ghClient.pullRequests.getAll.bind(this.ghClient, requestArgs));
};

Client.prototype.getLabels = function(repo, prNumber) {
	var repoInfo = repo.split('/');
	var issueArgs = {
		user: repoInfo[0],
		repo: repoInfo[1],
		number: prNumber
	};
	authenticate.call(this);
	return P.fromCallback(this.ghClient.issues.getRepoIssue.bind(this.ghClient, issueArgs)).then(function(issue) {
		return issue.labels.map(function(label) {
			return label.name;
		});
	});
};

var appendLabels = function(user, repo, number, appendLabels) {
	authenticate.call(this);
	return P.fromCallback(this.ghClient.issues.edit.bind(this.ghClient, {
		user: user,
		repo: repo,
		number: number,
		labels: appendLabels || []
	}));
};

Client.prototype.setLabels = function(repo, prNumber, labels) {
	var repoInfo = repo.split('/');
	console.log(repoInfo);
	return this.getLabels(repo, prNumber)
		.then(function(issueLabels) {
			return appendLabels.call(this, repoInfo[0], repoInfo[1], prNumber, _.union(issueLabels, labels));
		}.bind(this));
};

Client.prototype.setClient = function(client) {
	this.ghClient = client;
};
<commit_msg>Remove debugging code.<commit_after>var Github = require('github'),
	_ = require('lodash'),
	P = require('bluebird');

/**
 * @scope Client
 */
var authenticate = function() {
	this.ghClient.authenticate({
		type: 'oauth',
		token: this.token
	});
};

var Client = module.exports = function(token) {
	this.token = token;
	this.ghClient = new Github({
		version: '3.0.0',
		protocol: 'https'
	});
};

Client.prototype.getPullRequests = function(repo, state) {
	var repoInfo = repo.split('/');
	var requestArgs = {
		user: repoInfo[0],
		repo: repoInfo[1],
		state: state
	};
	authenticate.call(this);
	return P.fromCallback(this.ghClient.pullRequests.getAll.bind(this.ghClient, requestArgs));
};

Client.prototype.getLabels = function(repo, prNumber) {
	var repoInfo = repo.split('/');
	var issueArgs = {
		user: repoInfo[0],
		repo: repoInfo[1],
		number: prNumber
	};
	authenticate.call(this);
	return P.fromCallback(this.ghClient.issues.getRepoIssue.bind(this.ghClient, issueArgs)).then(function(issue) {
		return issue.labels.map(function(label) {
			return label.name;
		});
	});
};

var appendLabels = function(user, repo, number, appendLabels) {
	authenticate.call(this);
	return P.fromCallback(this.ghClient.issues.edit.bind(this.ghClient, {
		user: user,
		repo: repo,
		number: number,
		labels: appendLabels || []
	}));
};

Client.prototype.setLabels = function(repo, prNumber, labels) {
	var repoInfo = repo.split('/');
	return this.getLabels(repo, prNumber)
		.then(function(issueLabels) {
			return appendLabels.call(this, repoInfo[0], repoInfo[1], prNumber, _.union(issueLabels, labels));
		}.bind(this));
};

Client.prototype.setClient = function(client) {
	this.ghClient = client;
};
<|endoftext|>


<commit_before>var Hook = require('hook.io').Hook,
    util = require('util'),
    async = require('async'),
    GitHubApi = require('github'),
    request = require('request');

/**
* @@TODO
*
* - incorporate hook.io-markdown and remove markdown code
* - README
* - abstract the readme-finder portion so it can find any file in a repo and return the raw version
* - make attaching the readme an optional piece of functionality
*/

var GithubHook = exports.GithubHook = function GithubHook(options) {

  var self = this;
  Hook.call(this, options);

  this.configReady = false;

  self.on('hook::ready', function () {
    if (!!options.configFilePath && options.configFilePath.length) {
      self.config.use('file', { file: options.configFilePath });
      self.config.load(function (err, contents) {
        if (err) {
          // @@TODO
          throw new Error(err);
        }

        self.configReady = true;

        // call it now
        self.getAllItems();

        // and call it later
        self.on('getAllItems', self.getAllItems.bind(self));
        self.on('*::getAllItems', self.getAllItems.bind(self));
      });
    }
  });
};

//
// Inherit from `hookio.Hook`
//
util.inherits(GithubHook, Hook);

GithubHook.prototype.findReadme = function (user, repo, cb) {
  var self = this;
  async.waterfall(
    [ self.findMasterBranchSHA.bind(this, user, repo),
      self.findReadmeBlobsInTree.bind(this, user, repo),
      self.findReadmeFilesOfPreferredFormats.bind(this),
      self.decodeReadmeBase64.bind(this, user, repo),
      self.parseToGithubHookFlavoredMarkdown.bind(this, user, repo),
      self.addStylesheetsAndHTMLLayout.bind(this)
    ], cb);
}

GithubHook.prototype.addStylesheetsAndHTMLLayout = function (html, cb) {
  html = '
' + html + '
';

  var css = require('fs').readFileSync(__dirname + '/github.css');
  html = '' + html + '';
  cb(null, html);
}

GithubHook.prototype.parseToGithubHookFlavoredMarkdown = function (user, repo, md, cb) {
  var ghm = require('github-flavored-markdown');
  var rendered = ghm.parse(md, [user, repo].join('/'));
  cb(null, rendered);
}

GithubHook.prototype.decodeReadmeBase64 = function (user, repo, readmeFilename, cb) {
  request('https://raw.github.com/' + user + '/' + repo + '/master/' + readmeFilename, function (err, resp, body) {
    body = body || ' ';
    return cb(null, body);
  });
  /*var githubApi = new GitHubApi({ version: "3.0.0" });
  githubApi.gitdata.getBlob(
    { user: user,
      repo: repo,
      sha: readmeSHA },
    function (err, result) {
      if (result.encoding == 'base64') {
        var decoded = new Buffer(result.content.length);
        decoded.write(result.content, 0, result.content.length, 'base64');
        decoded = decoded.toString('ascii'); // remove null bytes that are everywhere
        //decoded = decoded.replace(0x00, ' ') + '\0';
        console.log(decoded);
        return cb(null, decoded);
      }
      else {
        return cb(null, result.content);
      }
    });*/
}

GithubHook.prototype.findReadmeFilesOfPreferredFormats = function (blobs, cb) {
  if (!blobs)
    return cb(null, null);

  function checkForFileExtension(ext, cb) {
    async.detect(
      blobs,
      function (blob, fcb) {
        fcb(blob.path.toLowerCase().indexOf(ext) !== -1);
      },
      function (result) {
        if (result)
          result = result.path; //sha;
        cb(null, result);
      });
  }

  var preferredFormats = [ '.md', '.markdown', '.html', '.txt' ];
  async.map(
    preferredFormats,
    function (fmt, mcp) {
      var fn = checkForFileExtension.bind(this, fmt);
      fn.fmt = fmt;
      mcp(null, fn);
    },
    function (err, mapped) {
      async.detectSeries(
        mapped,
        function (fn, dcb) {
          fn(function (err, readmeSHA) {
            fn.readmeSHA = readmeSHA;
            dcb(!err && readmeSHA);
          });
        },
        function (result) {
          if (result && result.readmeSHA)
            cb(null, result.readmeSHA);
          else
            cb(null, null);
        });
    });

}

GithubHook.prototype.findReadmeBlobsInTree = function (user, repo, treeSHA, cb) {
  var githubApi = new GitHubApi({ version: "3.0.0" });
  githubApi.gitdata.getTree(
    { user: user,
      repo: repo,
      sha: treeSHA },
    function (err, result) {
      if (err) return cb(err);

      async.filter(
        result.tree,
        function (tree, fcb) {
          fcb(tree.path.toUpperCase().indexOf('README') !== -1);
        },
        function (results) {
          if (results.length > 0)
            return cb(null, results);
          else
            return cb(null, null);
        });
    });
}

GithubHook.prototype.findMasterBranchSHA = function (user, repo, cb) {
  var githubApi = new GitHubApi({ version: "3.0.0" });
  githubApi.repos.getBranches(
    { user: user,
      repo: repo },
    function (err, result) {
      if (err) return cb(err);

      async.filter(
        result,
        function (branch, fcb) {
          return fcb(branch.name == 'master');
        },
        function (results) {
          if (results.length > 0) {
            return cb(null, results[0].commit.sha);
          }
        });
    });
}

GithubHook.prototype.getAllItems = function () {
  var self = this;

  var watched = self.config.get('watched');

  async.forEach(
    watched,
    function (item, forCb) {
      var githubApi = new GitHubApi({ version: "3.0.0" });

      if (item.subtype == 'repo') {
        githubApi.repos.get(
          { user: item.user,
            repo: item.repo },
          function (err, result) {
            self.findReadme(item.user, item.repo, function (err, readmeText) {
              result.readmeText = readmeText;
              self.emit('repo', result);
            });
          });

        return forCb();
      }
      return forCb();
    },
    function (err) {
      if (err) {
        throw new Error(err);
      }
    });
}

<commit_msg>Should still attempt to move forward even though there's no config file specified<commit_after>var Hook = require('hook.io').Hook,
    util = require('util'),
    async = require('async'),
    GitHubApi = require('github'),
    request = require('request');

/**
* @@TODO
*
* - incorporate hook.io-markdown and remove markdown code
* - README
* - abstract the readme-finder portion so it can find any file in a repo and return the raw version
* - make attaching the readme an optional piece of functionality
*/

var GithubHook = exports.GithubHook = function GithubHook(options) {

  var self = this;
  Hook.call(this, options);

  this.configReady = false;

  self.on('hook::ready', function () {
    self.config.use('file', { file: options.configFilePath || './config.json' });
    self.config.load(function (err, contents) {
      if (err) {
        // @@TODO
        throw new Error(err);
      }

      self.configReady = true;

      // call it now
      self.getAllItems();

      // and call it later
      self.on('getAllItems', self.getAllItems.bind(self));
      self.on('*::getAllItems', self.getAllItems.bind(self));
    });
  });
};

//
// Inherit from `hookio.Hook`
//
util.inherits(GithubHook, Hook);

GithubHook.prototype.findReadme = function (user, repo, cb) {
  var self = this;
  async.waterfall(
    [ self.findMasterBranchSHA.bind(this, user, repo),
      self.findReadmeBlobsInTree.bind(this, user, repo),
      self.findReadmeFilesOfPreferredFormats.bind(this),
      self.decodeReadmeBase64.bind(this, user, repo),
      self.parseToGithubHookFlavoredMarkdown.bind(this, user, repo),
      self.addStylesheetsAndHTMLLayout.bind(this)
    ], cb);
}

GithubHook.prototype.addStylesheetsAndHTMLLayout = function (html, cb) {
  html = '
' + html + '
';

  var css = require('fs').readFileSync(__dirname + '/github.css');
  html = '' + html + '';
  cb(null, html);
}

GithubHook.prototype.parseToGithubHookFlavoredMarkdown = function (user, repo, md, cb) {
  var ghm = require('github-flavored-markdown');
  var rendered = ghm.parse(md, [user, repo].join('/'));
  cb(null, rendered);
}

GithubHook.prototype.decodeReadmeBase64 = function (user, repo, readmeFilename, cb) {
  request('https://raw.github.com/' + user + '/' + repo + '/master/' + readmeFilename, function (err, resp, body) {
    body = body || ' ';
    return cb(null, body);
  });
  /*var githubApi = new GitHubApi({ version: "3.0.0" });
  githubApi.gitdata.getBlob(
    { user: user,
      repo: repo,
      sha: readmeSHA },
    function (err, result) {
      if (result.encoding == 'base64') {
        var decoded = new Buffer(result.content.length);
        decoded.write(result.content, 0, result.content.length, 'base64');
        decoded = decoded.toString('ascii'); // remove null bytes that are everywhere
        //decoded = decoded.replace(0x00, ' ') + '\0';
        console.log(decoded);
        return cb(null, decoded);
      }
      else {
        return cb(null, result.content);
      }
    });*/
}

GithubHook.prototype.findReadmeFilesOfPreferredFormats = function (blobs, cb) {
  if (!blobs)
    return cb(null, null);

  function checkForFileExtension(ext, cb) {
    async.detect(
      blobs,
      function (blob, fcb) {
        fcb(blob.path.toLowerCase().indexOf(ext) !== -1);
      },
      function (result) {
        if (result)
          result = result.path; //sha;
        cb(null, result);
      });
  }

  var preferredFormats = [ '.md', '.markdown', '.html', '.txt' ];
  async.map(
    preferredFormats,
    function (fmt, mcp) {
      var fn = checkForFileExtension.bind(this, fmt);
      fn.fmt = fmt;
      mcp(null, fn);
    },
    function (err, mapped) {
      async.detectSeries(
        mapped,
        function (fn, dcb) {
          fn(function (err, readmeSHA) {
            fn.readmeSHA = readmeSHA;
            dcb(!err && readmeSHA);
          });
        },
        function (result) {
          if (result && result.readmeSHA)
            cb(null, result.readmeSHA);
          else
            cb(null, null);
        });
    });

}

GithubHook.prototype.findReadmeBlobsInTree = function (user, repo, treeSHA, cb) {
  var githubApi = new GitHubApi({ version: "3.0.0" });
  githubApi.gitdata.getTree(
    { user: user,
      repo: repo,
      sha: treeSHA },
    function (err, result) {
      if (err) return cb(err);

      async.filter(
        result.tree,
        function (tree, fcb) {
          fcb(tree.path.toUpperCase().indexOf('README') !== -1);
        },
        function (results) {
          if (results.length > 0)
            return cb(null, results);
          else
            return cb(null, null);
        });
    });
}

GithubHook.prototype.findMasterBranchSHA = function (user, repo, cb) {
  var githubApi = new GitHubApi({ version: "3.0.0" });
  githubApi.repos.getBranches(
    { user: user,
      repo: repo },
    function (err, result) {
      if (err) return cb(err);

      async.filter(
        result,
        function (branch, fcb) {
          return fcb(branch.name == 'master');
        },
        function (results) {
          if (results.length > 0) {
            return cb(null, results[0].commit.sha);
          }
        });
    });
}

GithubHook.prototype.getAllItems = function () {
  var self = this;

  var watched = self.config.get('watched');

  async.forEach(
    watched,
    function (item, forCb) {
      var githubApi = new GitHubApi({ version: "3.0.0" });

      if (item.subtype == 'repo') {
        githubApi.repos.get(
          { user: item.user,
            repo: item.repo },
          function (err, result) {
            self.findReadme(item.user, item.repo, function (err, readmeText) {
              result.readmeText = readmeText;
              self.emit('repo', result);
            });
          });

        return forCb();
      }
      return forCb();
    },
    function (err) {
      if (err) {
        throw new Error(err);
      }
    });
}

<|endoftext|>


<commit_before>Router = new I18NRouter({autoStart: true});<commit_msg>Removed useless startup option<commit_after>Router = new I18NRouter;<|endoftext|>


<commit_before>var utils = require("utils-pkg");

/**
 * Parses options of the package
 *
 * @param  {Object} options The object options provided
 * @return {Object}         The parsed object options
 */
module.exports.parseOptions = (options) => {
	if(options == null){
		throw new Error("Options is undefined");
	}

	else if(!utils.isObject(options)){
		throw new Error("Options parameter must be an object");
	}

	else{
		var values = {};

		// Iterate for each default option from the module
		for(prop in module.parent.options.defaults){
			var property = module.parent.options.defaults[prop];

			values[prop] = options.defaults ? options.defaults[prop] : property;
		}

		return {
			values: values
		};
	}
};<commit_msg>ADDED: parsing logic for "allow-headers"<commit_after>var utils = require("utils-pkg");

/**
 * Parses options of the package
 *
 * @param  {Object} options The object options provided
 * @return {Object}         The parsed object options
 */
module.exports.parseOptions = (options) => {
	if(options == null){
		throw new Error("Options is undefined");
	}

	else if(!utils.isObject(options)){
		throw new Error("Options parameter must be an object");
	}

	else{
		var values = {};

		// Iterate for each default option from the module
		for(prop in module.parent.options.defaults){
			var property = module.parent.options.defaults[prop];

			// Check for allow-headers option
			if(prop == "allow-headers" && property != null){
				property = parseAllowHeader(property, prop);
			}

			values[prop] = options.defaults ? options.defaults[prop] : property;
		}

		return {
			values: values
		};
	}
};

function parseAllowHeader(value, name){
	// Throw error if value is not array or string
	if(value && (!utils.isArray(value) || !utils.isString(value))){
		throw new Error(`Default Header for "${name}" must be Array or String`);
	}

	// In case when no error was threw, check if value is array
	// Set all values to UpperCase and join the values into a string
	else if(utils.isArray(value)){
		for(i = 0; i < value.length; i++){
			value[i] = value[i].toUpperCase();
		}

		value = value.join(", ");
	}

	// When value is string, make sure it's in UpperCase
	else{
		value = value.toUpperCase();
	}

	return value;
}<|endoftext|>


<commit_before>/**
 * Copyright (c) 2012, Twitter Inc. and other contributors
 * Released under the MIT License
 */

var jsonml = require('jsonml');

var reNumber = /^[\.\+\-]?[\d\.]+$/,
    reInvalidDec = /(?:\.\d*){2,}/,
    reDec = /\./,
    reLineBreak = /[\n\r]+/g,
    reLastBreak = /\n$/,

    TAB = '\t',
    NEWLINE = '\n';

function parseNumber(s) {
  if (typeof s !== 'string' || !reNumber.test(s) || reInvalidDec.test(s)) {
    return s;
  }

  return reDec.test(s) ? parseFloat(s, 10) : parseInt(s, 10);
}

function xmlToObj(xml) {
  var obj = {},

      rec = function xmlToObjRecursion(a, o) {
        var val, newObj, i,
            len = a.length;

        if (len === 2) {
          if (typeof a[1] !== 'object') {
            o[a[0]] = parseNumber(a[1]);
          } else {
            o[a[0]] = {};
            rec(a[1], o[a[0]]);
          }
        } else if (len > 2) {
          if (o[a[0]]) {
            if (!(o[a[0]] instanceof Array)) {
              val = o[a[0]];
              o[a[0]] = [val];
            }
            newObj = {};
            o[a[0]].push(newObj);
          } else {
            o[a[0]] = {};
          }
          for (i = 1, len = a.length; i < len; i += 1) {
            rec(a[i], newObj || o[a[0]]);
          }
        }
      };

  rec(jsonml.parse(xml), obj);

  return obj;
}

function svToObj(delimiter, headers, sv) {
  var data,
      start = 0,
      obj = {};

  delimiter = delimiter || ',';

  if (!sv) {
    return {};
  }

  // keep line breaks consistent as "\n" and remove the very last one
  data = sv.replace(reLineBreak, '\n').replace(reLastBreak, '').split('\n');

  if (!headers) {
    headers = data[0].split(delimiter);
    start = 1;
  }

  // edge case: when response provides headers, 1st 2 rows should be ignored
  if (data[0].split(delimiter)[3] === 'IP Address') {
    start = 2;
  }

  headers.forEach(function headersEach(header) {
    obj[header] = [];
  });

  data.slice(start).forEach(function dataEach(row) {
    row.split(delimiter).forEach(function rowEach(value, index) {
      if (headers[index]) {
        obj[headers[index]].push(parseNumber(value));
      }
    });
  });

  return obj;
}

// Net log has a buggy end of file, attempt to fix
function netLogParser(data) {
  data = data || '{}';
  if (data.slice(data.length - 3) === ',\r\n') {
    data = data.slice(0, data.length - 3) + ']}';
  }

  return JSON.parse(data);
}

// Convert image (binary) into data URI (string)
function dataURI(data) {
  return new Buffer(data || '', 'binary').toString('base64');
}

// Convert script objects into formatted string
function scriptToString(data) {
  var script = [];

  data.forEach(function dataEach(step) {
    var key, value;

    if (typeof step === 'string') {
      script.push(step);
    } else if (typeof step === 'object') {
      key = [Object.keys(step)[0]];
      value = step[key];
      if (value !== undefined && value !== null && value !== '') {
        key = key.concat(value);
      }
      script.push(key.join(TAB));
    }
  });

  return script.join(NEWLINE);
}

module.exports = {
  xmlToObj: xmlToObj,
  csvToObj: svToObj.bind(null, ',', false),
  tsvToObj: svToObj.bind(null, '\t'),
  netLogParser: netLogParser,
  scriptToString: scriptToString
};
<commit_msg>exposed method<commit_after>/**
 * Copyright (c) 2012, Twitter Inc. and other contributors
 * Released under the MIT License
 */

var jsonml = require('jsonml');

var reNumber = /^[\.\+\-]?[\d\.]+$/,
    reInvalidDec = /(?:\.\d*){2,}/,
    reDec = /\./,
    reLineBreak = /[\n\r]+/g,
    reLastBreak = /\n$/,

    TAB = '\t',
    NEWLINE = '\n';

function parseNumber(s) {
  if (typeof s !== 'string' || !reNumber.test(s) || reInvalidDec.test(s)) {
    return s;
  }

  return reDec.test(s) ? parseFloat(s, 10) : parseInt(s, 10);
}

function xmlToObj(xml) {
  var obj = {},

      rec = function xmlToObjRecursion(a, o) {
        var val, newObj, i,
            len = a.length;

        if (len === 2) {
          if (typeof a[1] !== 'object') {
            o[a[0]] = parseNumber(a[1]);
          } else {
            o[a[0]] = {};
            rec(a[1], o[a[0]]);
          }
        } else if (len > 2) {
          if (o[a[0]]) {
            if (!(o[a[0]] instanceof Array)) {
              val = o[a[0]];
              o[a[0]] = [val];
            }
            newObj = {};
            o[a[0]].push(newObj);
          } else {
            o[a[0]] = {};
          }
          for (i = 1, len = a.length; i < len; i += 1) {
            rec(a[i], newObj || o[a[0]]);
          }
        }
      };

  rec(jsonml.parse(xml), obj);

  return obj;
}

function svToObj(delimiter, headers, sv) {
  var data,
      start = 0,
      obj = {};

  delimiter = delimiter || ',';

  if (!sv) {
    return {};
  }

  // keep line breaks consistent as "\n" and remove the very last one
  data = sv.replace(reLineBreak, '\n').replace(reLastBreak, '').split('\n');

  if (!headers) {
    headers = data[0].split(delimiter);
    start = 1;
  }

  // edge case: when response provides headers, 1st 2 rows should be ignored
  if (data[0].split(delimiter)[3] === 'IP Address') {
    start = 2;
  }

  headers.forEach(function headersEach(header) {
    obj[header] = [];
  });

  data.slice(start).forEach(function dataEach(row) {
    row.split(delimiter).forEach(function rowEach(value, index) {
      if (headers[index]) {
        obj[headers[index]].push(parseNumber(value));
      }
    });
  });

  return obj;
}

// Net log has a buggy end of file, attempt to fix
function netLogParser(data) {
  data = data || '{}';
  if (data.slice(data.length - 3) === ',\r\n') {
    data = data.slice(0, data.length - 3) + ']}';
  }

  return JSON.parse(data);
}

// Convert image (binary) into data URI (string)
function dataURI(data) {
  return new Buffer(data || '', 'binary').toString('base64');
}

// Convert script objects into formatted string
function scriptToString(data) {
  var script = [];

  data.forEach(function dataEach(step) {
    var key, value;

    if (typeof step === 'string') {
      script.push(step);
    } else if (typeof step === 'object') {
      key = [Object.keys(step)[0]];
      value = step[key];
      if (value !== undefined && value !== null && value !== '') {
        key = key.concat(value);
      }
      script.push(key.join(TAB));
    }
  });

  return script.join(NEWLINE);
}

module.exports = {
  xmlToObj: xmlToObj,
  csvToObj: svToObj.bind(null, ',', false),
  tsvToObj: svToObj.bind(null, '\t'),
  netLogParser: netLogParser,
  scriptToString: scriptToString,
  dataURI: dataURI
};
<|endoftext|>


<commit_before>'use strict';

/*!
 * imager
 * Copyright(c) 2014 Madhusudhan Srinivasa <madhums8@gmail.com>
 * MIT Licensed
 */

/**
 * Module dependencies.
 */

var fs = require('fs');
var gm = require('graphicsmagick-stream');
var mime = require('mime');
var co = require('co');
var pkgcloud = require('pkgcloud');
var debug = require('debug')('imager');

/**
 * Expose
 */

module.exports = Imager;

/**
 * Imager
 *
 * @param {Object} variants
 * @param {Object} storage
 * @api public
 */

function Imager (variants, storage) {
  this.client = pkgcloud.storage.createClient(storage);
  this.variants = variants;
  this.storage = storage;
}

/**
 * upload
 *
 * @param {Array|String} files
 * @@param {String} variant
 * @param {Function} cb
 * @api public
 */

Imager.prototype.upload = function (files, variant, fn) {
  var self = this;

  if (typeof files === 'string') {
    files = [files];
  }

  var presets = self.variants[variant];
  presets = Object.keys(presets).map(function (key, index) {
    presets[key].__name = key;
    return presets[key];
  });

  co(function *() {
    // modified files having the same object structure
    var _files = yield files.map(info);
    var arr = [];

    _files.forEach(function (file) {
      presets.forEach(function (preset) {
        arr.push({ file: file, preset: preset });
      });
    });

    try {
      var uploaded = yield arr.map(upload.bind(self));
      fn(null, uploaded);
    } catch (err) {
      fn(err);
    }
  })();
};

/**
 * upload
 *
 * @param {Object} file
 * @api private
 */

function upload (obj) {
  var storage = this.storage;
  var client = this.client;
  var preset = obj.preset;
  var file = obj.file;
  var filename = preset.rename && preset.rename(file, preset.__name);

  return function (fn) {
    var _convert = gm(preset);
    var _upload = client.upload({
      container: storage.container,
      remote: filename || (preset.__name + '_' + file.name)
    }, done);

    function done (err, uploaded, res) {
      if (err) return fn(err);
      // Pass the uploaded image url
      fn(err, res.request.href);
    }

    // Convert and upload
    fs.createReadStream(file.path)
      .pipe(_convert())
      .pipe(_upload);
  };
}

/**
 * info
 *
 * @param {Object} file
 * @return {Object}
 * @api private
 */

function *info (file) {
  return {
    size: typeof(file) === 'string'
      ? (yield stat(file)).size
      : file.size,
    type: typeof(file) === 'string'
      ? mime.lookup(file)
      : file.type || file.mimetype || file.headers['content-type'],
    name: typeof(file) === 'string'
      ? file.split('/')[file.split('/').length - 1]
      : file.name,
    path: typeof(file) === 'string'
      ? file
      : file.path
  };
}

/**
 * stat
 *
 * @param {String} path
 * @return {Function}
 * @api private
 */

function stat (path) {
  return function (done) {
    fs.stat(path, done);
  }
}
<commit_msg>maintain container name in an instance variable<commit_after>'use strict';

/*!
 * imager
 * Copyright(c) 2014 Madhusudhan Srinivasa <madhums8@gmail.com>
 * MIT Licensed
 */

/**
 * Module dependencies.
 */

var fs = require('fs');
var gm = require('graphicsmagick-stream');
var mime = require('mime');
var co = require('co');
var pkgcloud = require('pkgcloud');
var debug = require('debug')('imager');

/**
 * Expose
 */

module.exports = Imager;

/**
 * Imager
 *
 * @param {Object} variants
 * @param {Object} storage
 * @api public
 */

function Imager (variants, storage) {
  this.client = pkgcloud.storage.createClient(storage);
  this.variants = variants;
  this.container = storage.container;
}

/**
 * upload
 *
 * @param {Array|String} files
 * @@param {String} variant
 * @param {Function} cb
 * @api public
 */

Imager.prototype.upload = function (files, variant, fn) {
  var self = this;

  if (typeof files === 'string') {
    files = [files];
  }

  var presets = self.variants[variant];
  presets = Object.keys(presets).map(function (key, index) {
    presets[key].__name = key;
    return presets[key];
  });

  co(function *() {
    // modified files having the same object structure
    var _files = yield files.map(info);
    var arr = [];

    _files.forEach(function (file) {
      presets.forEach(function (preset) {
        arr.push({ file: file, preset: preset });
      });
    });

    try {
      var uploaded = yield arr.map(upload.bind(self));
      fn(null, uploaded);
    } catch (err) {
      fn(err);
    }
  })();
};

/**
 * upload
 *
 * @param {Object} file
 * @api private
 */

function upload (obj) {
  var container = this.container;
  var client = this.client;
  var preset = obj.preset;
  var file = obj.file;
  var filename = preset.rename && preset.rename(file, preset.__name);

  return function (fn) {
    var _convert = gm(preset);
    var _upload = client.upload({
      container: container,
      remote: filename || (preset.__name + '_' + file.name)
    }, done);

    function done (err, uploaded, res) {
      if (err) return fn(err);
      // uploaded image url
      fn(err, res.request.href);
    }

    // convert and upload
    fs.createReadStream(file.path)
      .pipe(_convert())
      .pipe(_upload);
  };
}

/**
 * info
 *
 * @param {Object} file
 * @return {Object}
 * @api private
 */

function *info (file) {
  return {
    size: typeof(file) === 'string'
      ? (yield stat(file)).size
      : file.size,
    type: typeof(file) === 'string'
      ? mime.lookup(file)
      : file.type || file.mimetype || file.headers['content-type'],
    name: typeof(file) === 'string'
      ? file.split('/')[file.split('/').length - 1]
      : file.name,
    path: typeof(file) === 'string'
      ? file
      : file.path
  };
}

/**
 * stat
 *
 * @param {String} path
 * @return {Function}
 * @api private
 */

function stat (path) {
  return function (done) {
    fs.stat(path, done);
  }
}
<|endoftext|>