<commit_before>/**!
 * Copyright(c) ali-sdk and other contributors.
 * MIT Licensed
 *
 * Authors:
 *   dead_horse <dead_horse@qq.com>
 *   fengmk2 <m@fengmk2.com> (http://fengmk2.com)
 */

'use strict';

/**
 * Module dependencies.
 */

const co = require('co');
const defer = require('co-defer');
const Base = require('sdk-base');
const util = require('util');
const ready = require('get-ready');
const currentIP = require('address').ip();
const RR = 'roundRobin';
const MS = 'masterSlave';

module.exports = function (oss) {
  function Client(options) {
    if (!(this instanceof Client)) {
      return new Client(options);
    }

    if (!options || !Array.isArray(options.cluster)) {
      throw new Error('require options.cluster to be an array');
    }

    Base.call(this);

    this.clients = [];
    this.availables = {};

    for (let i = 0; i < options.cluster.length; i++) {
      let opt = options.cluster[i];
      opt.timeout = opt.timeout || options.timeout;
      this.clients.push(oss(opt));
      this.availables[i] = true;
    }

    this.schedule = options.schedule || RR;
    this.index = 0;

    const heartbeatInterval = options.heartbeatInterval || 10000;
    this._checkAvailableLock = false;
    this._timerId = defer.setInterval(this._checkAvailable.bind(this), heartbeatInterval);
    this._init();
  }

  util.inherits(Client, Base);
  const proto = Client.prototype;
  ready.mixin(proto);

  const GET_METHODS = [
    'head',
    'get',
    'getStream',
    'list',
  ];

  const PUT_METHODS = [
    'put',
    'putStream',
    'delete',
    'deleteMulti',
    'copy',
    'putMeta',
  ];

  GET_METHODS.forEach(function (method) {
    proto[method] = function* () {
      const args = Array.prototype.slice.call(arguments);
      let client = this.chooseAvailable();
      let lastError;
      try {
        return yield client[method].apply(client, args);
      } catch (err) {
        if (err.status && err.status >= 200 && err.status < 500) {
          // 200 ~ 499 belong to normal response, don't try again
          throw err;
        }
        // < 200 || >= 500 need to retry from other cluser node
        lastError = err;
      }

      for (let i = 0; i < this.clients.length; i++) {
        let c = this.clients[i];
        if (c === client) {
          continue;
        }
        try {
          return yield c[method].apply(client, args);
        } catch (err){
          if (err.status && err.status >= 200 && err.status < 500) {
            // 200 ~ 499 belong to normal response, don't try again
            throw err;
          }
          // < 200 || >= 500 need to retry from other cluser node
          lastError = err;
        }
      }

      lastError.message += ' (all clients are down)';
      throw lastError;
    };
  });

  // must cluster node write success
  PUT_METHODS.forEach(function (method) {
    proto[method] = function* () {
      let args = Array.prototype.slice.call(arguments);
      let res = yield this.clients.map(function (client) {
        return client[method].apply(client, args);
      });
      return res[0];
    };
  });

  proto.signatureUrl = function (/* name */) {
    const args = Array.prototype.slice.call(arguments);
    let client = this.chooseAvailable();
    return client.signatureUrl.apply(client, args);
  };

  proto._init = function() {
    const that = this;
    co(function*() {
      yield that._checkAvailable(true);
      that.ready(true);
    }).catch(function(err) {
      that.emit('error', err);
    });
  };

  proto._checkAvailable = function*(first) {
    const name = '._ali-oss/check.status.' + currentIP + '.txt';
    if (first) {
      // only start will try to write the file
      yield this.put(name, new Buffer('check available started at ' + Date()));
    }

    if (this._checkAvailableLock) {
      return;
    }
    this._checkAvailableLock = true;
    let downStatusFiles = [];
    for (let i = 0; i < this.clients.length; i++) {
      let client = this.clients[i];
      // check 3 times
      let available = yield this._checkStatus(client, name);
      if (!available) {
        // check again
        available = yield this._checkStatus(client, name);
      }
      if (!available) {
        // check again
        available = yield this._checkStatus(client, name);
        if (!available) {
          downStatusFiles.push(client._objectUrl(name));
        }
      }
      this.availables[i] = available;
    }
    this._checkAvailableLock = false;

    if (downStatusFiles.length > 0) {
      const err = new Error(downStatusFiles.length + ' data node down, please check status file: ' + downStatusFiles.join(', '));
      err.name = 'CheckAvailableError';
      this.emit('error', err);
    }
  };

  proto._checkStatus = function*(client, name) {
    let available = true;
    try {
      yield client.head(name);
    } catch (err) {
      // 404 will be available too
      if (!err.status || err.status >= 500 || err.status < 200) {
        available = false;
      }
    }
    return available;
  };

  proto.chooseAvailable = function() {
    if (this.schedule === MS) {
      for (let i = 0; i < this.clients.length; i++) {
        if (this.availables[i]) {
          return this.clients[i];
        }
      }
      // all down, try to use this first one
      return this.clients[0];
    }

    // RR
    let n = this.clients.length;
    while (n > 0) {
      let i = this._nextRRIndex();
      if (this.availables[i]) {
        return this.clients[i];
      }
      n--;
    }
    // all down, try to use this first one
    return this.clients[0];
  };

  proto._nextRRIndex = function() {
    let index = this.index++;
    if (this.index >= this.clients.length) {
      this.index = 0;
    }
    return index;
  };

  proto.close = function() {
    clearInterval(this._timerId);
    this._timerId = null;
  };

  return Client;
};
<commit_msg>fix(cluster): simplify cluster config<commit_after>/**!
 * Copyright(c) ali-sdk and other contributors.
 * MIT Licensed
 *
 * Authors:
 *   dead_horse <dead_horse@qq.com>
 *   fengmk2 <m@fengmk2.com> (http://fengmk2.com)
 */

'use strict';

/**
 * Module dependencies.
 */

const co = require('co');
const defer = require('co-defer');
const Base = require('sdk-base');
const util = require('util');
const ready = require('get-ready');
const copy = require('copy-to');
const currentIP = require('address').ip();

const RR = 'roundRobin';
const MS = 'masterSlave';
module.exports = function (oss) {
  function Client(options) {
    if (!(this instanceof Client)) {
      return new Client(options);
    }

    if (!options || !Array.isArray(options.cluster)) {
      throw new Error('require options.cluster to be an array');
    }

    Base.call(this);

    this.clients = [];
    this.availables = {};

    for (let i = 0; i < options.cluster.length; i++) {
      let opt = options.cluster[i];
      copy(options).pick('timeout', 'agent', 'urllib').to(opt);
      this.clients.push(oss(opt));
      this.availables[i] = true;
    }

    this.schedule = options.schedule || RR;
    this.index = 0;

    const heartbeatInterval = options.heartbeatInterval || 10000;
    this._checkAvailableLock = false;
    this._timerId = defer.setInterval(this._checkAvailable.bind(this), heartbeatInterval);
    this._init();
  }

  util.inherits(Client, Base);
  const proto = Client.prototype;
  ready.mixin(proto);

  const GET_METHODS = [
    'head',
    'get',
    'getStream',
    'list',
  ];

  const PUT_METHODS = [
    'put',
    'putStream',
    'delete',
    'deleteMulti',
    'copy',
    'putMeta',
  ];

  GET_METHODS.forEach(function (method) {
    proto[method] = function* () {
      const args = Array.prototype.slice.call(arguments);
      let client = this.chooseAvailable();
      let lastError;
      try {
        return yield client[method].apply(client, args);
      } catch (err) {
        if (err.status && err.status >= 200 && err.status < 500) {
          // 200 ~ 499 belong to normal response, don't try again
          throw err;
        }
        // < 200 || >= 500 need to retry from other cluser node
        lastError = err;
      }

      for (let i = 0; i < this.clients.length; i++) {
        let c = this.clients[i];
        if (c === client) {
          continue;
        }
        try {
          return yield c[method].apply(client, args);
        } catch (err){
          if (err.status && err.status >= 200 && err.status < 500) {
            // 200 ~ 499 belong to normal response, don't try again
            throw err;
          }
          // < 200 || >= 500 need to retry from other cluser node
          lastError = err;
        }
      }

      lastError.message += ' (all clients are down)';
      throw lastError;
    };
  });

  // must cluster node write success
  PUT_METHODS.forEach(function (method) {
    proto[method] = function* () {
      let args = Array.prototype.slice.call(arguments);
      let res = yield this.clients.map(function (client) {
        return client[method].apply(client, args);
      });
      return res[0];
    };
  });

  proto.signatureUrl = function (/* name */) {
    const args = Array.prototype.slice.call(arguments);
    let client = this.chooseAvailable();
    return client.signatureUrl.apply(client, args);
  };

  proto._init = function() {
    const that = this;
    co(function*() {
      yield that._checkAvailable(true);
      that.ready(true);
    }).catch(function(err) {
      that.emit('error', err);
    });
  };

  proto._checkAvailable = function*(first) {
    const name = '._ali-oss/check.status.' + currentIP + '.txt';
    if (first) {
      // only start will try to write the file
      yield this.put(name, new Buffer('check available started at ' + Date()));
    }

    if (this._checkAvailableLock) {
      return;
    }
    this._checkAvailableLock = true;
    let downStatusFiles = [];
    for (let i = 0; i < this.clients.length; i++) {
      let client = this.clients[i];
      // check 3 times
      let available = yield this._checkStatus(client, name);
      if (!available) {
        // check again
        available = yield this._checkStatus(client, name);
      }
      if (!available) {
        // check again
        available = yield this._checkStatus(client, name);
        if (!available) {
          downStatusFiles.push(client._objectUrl(name));
        }
      }
      this.availables[i] = available;
    }
    this._checkAvailableLock = false;

    if (downStatusFiles.length > 0) {
      const err = new Error(downStatusFiles.length + ' data node down, please check status file: ' + downStatusFiles.join(', '));
      err.name = 'CheckAvailableError';
      this.emit('error', err);
    }
  };

  proto._checkStatus = function*(client, name) {
    let available = true;
    try {
      yield client.head(name);
    } catch (err) {
      // 404 will be available too
      if (!err.status || err.status >= 500 || err.status < 200) {
        available = false;
      }
    }
    return available;
  };

  proto.chooseAvailable = function() {
    if (this.schedule === MS) {
      for (let i = 0; i < this.clients.length; i++) {
        if (this.availables[i]) {
          return this.clients[i];
        }
      }
      // all down, try to use this first one
      return this.clients[0];
    }

    // RR
    let n = this.clients.length;
    while (n > 0) {
      let i = this._nextRRIndex();
      if (this.availables[i]) {
        return this.clients[i];
      }
      n--;
    }
    // all down, try to use this first one
    return this.clients[0];
  };

  proto._nextRRIndex = function() {
    let index = this.index++;
    if (this.index >= this.clients.length) {
      this.index = 0;
    }
    return index;
  };

  proto.close = function() {
    clearInterval(this._timerId);
    this._timerId = null;
  };

  return Client;
};
<|endoftext|>


<commit_before>module.exports = collect

function collect (stream) {
  if (stream._collected) return

  stream._collected = true
  stream.pause()

  stream.on("data", save)
  stream.on("end", save)
  var buf = []
  function save (b) {
    if (typeof b === "string") b = new Buffer(b)
    if (Buffer.isBuffer(b) && !b.length) return
    buf.push(b)
  }

  stream.on("entry", saveEntry)
  var entryBuffer = []
  function saveEntry (e) {
    collect(e)
    entryBuffer.push(e)
  }

  stream.on("proxy", proxyPause)
  function proxyPause (p) {
    p.pause()
  }

  // replace the pipe method with a new version that will
  // unlock the buffered stuff.
  stream.pipe = (function (orig) { return function (dest) {
    if (!dest) {
      stream.pipe = orig
      stream.removeListener("entry", saveEntry)
      stream.removeListener("data", save)
      stream.removeListener("end", save)
      stream.resume()
      return
    }

    // let the entries flow through one at a time.
    // Once they're all done, then we can resume completely.
    var e = 0
    ;(function unblockEntry () {
      var entry = entryBuffer[e++]
      if (!entry) return resume()
      entry.on("end", unblockEntry)
      dest.addEntry(entry)
    })()

    function resume () {
      buf.forEach(function (b) {
        if (b) dest.write(b)
        else dest.end()
      })

      stream.removeListener("entry", saveEntry)
      stream.removeListener("data", save)
      stream.removeListener("end", save)

      stream.pipe = orig
      stream.pipe(dest)
      stream.resume()
    }

    return dest
  }})(stream.pipe)
}
<commit_msg>Replay events if no pipe dest provided<commit_after>module.exports = collect

function collect (stream) {
  if (stream._collected) return

  stream._collected = true
  stream.pause()

  stream.on("data", save)
  stream.on("end", save)
  var buf = []
  function save (b) {
    if (typeof b === "string") b = new Buffer(b)
    if (Buffer.isBuffer(b) && !b.length) return
    buf.push(b)
  }

  stream.on("entry", saveEntry)
  var entryBuffer = []
  function saveEntry (e) {
    collect(e)
    entryBuffer.push(e)
  }

  stream.on("proxy", proxyPause)
  function proxyPause (p) {
    p.pause()
  }

  // replace the pipe method with a new version that will
  // unlock the buffered stuff.  if you just call .pipe()
  // without a destination, then it'll re-play the events.
  stream.pipe = (function (orig) { return function (dest) {

    // let the entries flow through one at a time.
    // Once they're all done, then we can resume completely.
    var e = 0
    ;(function unblockEntry () {
      var entry = entryBuffer[e++]
      if (!entry) return resume()
      entry.on("end", unblockEntry)
      if (dest) dest.addEntry(entry)
      else stream.emit("entry", entry)
    })()

    if (!dest) {
      stream.pipe = orig
      stream.removeListener("entry", saveEntry)
      stream.removeListener("data", save)
      stream.removeListener("end", save)
      buf.forEach(function (b) {
        if (b) stream.emit("data", b)
        else stream.emit("end")
      })
      stream.resume()
      return
    }

    function resume () {
      buf.forEach(function (b) {
        if (b) dest.write(b)
        else dest.end()
      })

      stream.removeListener("entry", saveEntry)
      stream.removeListener("data", save)
      stream.removeListener("end", save)

      stream.pipe = orig
      stream.pipe(dest)
      stream.resume()
    }

    return dest
  }})(stream.pipe)
}
<|endoftext|>


<commit_before>'use strict';

var each = require('p-each-series');
var algoliasearch = require('algoliasearch');
var crypto = require('crypto');

var INDEXED_LAYOUTS = 'page';

var CONSOLE_DEFAULTS = {
  dryRun: false,
  flush: false,
  chunkSize: 50,
  layouts: INDEXED_LAYOUTS
};

var INDEXED_PROPERTIES = [
  'title',
  'date',
  'updated',
  'slug',
  'excerpt',
  'permalink',
  'layout'
];

var INDEXED_LAYOUTS = [
  'page'
];

function computeSha1(text) {
  return crypto.createHash('sha1').update(text, 'utf8').digest('hex');
}

function pick(object, properties) {
  return properties.reduce(function(filteredObj, prop) {
    filteredObj[prop] = object[prop];
    return filteredObj;
  }, {});
}

function chunk(array, chunkSize) {
  var batches = [];

  while (array.length > 0) {
    batches.push(array.splice(0, chunkSize));
  }

  return batches;
}

module.exports = function(args, callback) {
  var hexo = this;
  var config = Object.assign({}, hexo.config.algolia);
  var indexName = config.indexName;
  var applicationID = config.applicationID;
  var apiKey = String(process.env.HEXO_ALGOLIA_INDEXING_KEY || '');
  var options = Object.assign({}, CONSOLE_DEFAULTS, args || {});
  var pageLayouts = options.layouts.split(',');
  var client;
  var index;

  Promise.resolve(apiKey)
    .then(function(){
      if (!apiKey) {
        hexo.log.error('[hexo-algolia] Please set an `HEXO_ALGOLIA_INDEXING_KEY` environment variable to enable content indexing.');
        hexo.log.error('>> Read %s for more informations.', 'https://npmjs.com/hexo-algolia#api-key');
        process.exit(1);
      }

      if (!indexName) {
        hexo.log.error('[hexo-algolia] Please provide an Algolia index name in your hexo _config.yml file.');
        hexo.log.error('>> Read %s for more informations.', 'https://npmjs.com/hexo-algolia#public-facing-search-options');
        process.exit(1);
      }

      client = algoliasearch(applicationID, apiKey);
      index = client.initIndex(indexName);
    })
    .then(function(){
      hexo.log.info('[hexo-algolia] Testing HEXO_ALGOLIA_INDEXING_KEY permissions.');

      return client.getApiKey(apiKey)
        .catch(function(err){
          hexo.log.error('[hexo-algolia] %s', err.message);
          hexo.log.error('>> You might have used an Admin Key or an invalid Key.');
          hexo.log.error('>> Read %s for more informations.', 'https://npmjs.com/hexo-algolia#security-concerns');
          process.exit(1);
        });
    })
    .then(function() {
      return hexo.load();
    })
    .then(function() {
      var posts = hexo.database.model('Post').find({ published: true });

      return posts.toArray();
    })
    .then(function(publishedPosts) {
      var pages = hexo.database.model('Page').find({
        layout: { '$in': pageLayouts }
      });

      return publishedPosts.concat(pages.toArray());
    })
    .then(function(publishedPagesAndPosts) {
      return publishedPagesAndPosts.map(function(data) {
        var storedPost = pick(data, INDEXED_PROPERTIES);

        storedPost.objectID = computeSha1(data.path);
        storedPost.date_as_int = Date.parse(data.date) / 1000;
        storedPost.updated_as_int = Date.parse(data.updated) / 1000;
        storedPost.permalink = storedPost.permalink.replace(/\/index.html$/, '/');

        if (Array.isArray(data.categories)) {
          storedPost.categories = data.categories.map(function(item) {
            return pick(item, ['name', 'path']);
          });
        }

        if (Array.isArray(data.tags)) {
          storedPost.tags = data.tags.map(function(item) {
            return pick(item, ['name', 'path']);
          });
        }

        storedPost.author = data.author || config.author;

        return storedPost;
      });
    })
    .then(function(publishedPagesAndPosts) {
      hexo.log.info(
        '[hexo-algolia] %d pages and posts to index.',
        publishedPagesAndPosts.length
      );

      return publishedPagesAndPosts.map(function toAlgoliaBatchActions(post) {
        return {
          action: 'updateObject',
          indexName: indexName,
          body: post
        };
      });
    })
    .then(function(actions) {
      if (options.dryRun) {
        hexo.log.info('[hexo-algolia] Skipping due to --dry-run option');
        return;
      }

      return Promise.resolve(options.flush)
        .then(function(flush) {
          if (flush) {
            hexo.log.info('[hexo-algolia] Clearing index...');
            return index.clearIndex();
          }
        })
        .then(function() {
          var chunks = chunk(actions, options.chunkSize);

          return each(chunks, function(chunk, i) {
            hexo.log.info(
              '[hexo-algolia] Indexing chunk %d of %d (%d items each)',
              i + 1,
              chunks.length,
              options.chunkSize
            );

            return client
              .batch(chunk)
              .catch(function(err){
                hexo.log.error('[hexo-algolia] %s', err.message);
              });
          });
        })

        .then(function() {
          hexo.log.info('[hexo-algolia] Indexing done.');
        });
    })
    .catch(callback);
};
<commit_msg>feat: index the `image` property<commit_after>'use strict';

var each = require('p-each-series');
var algoliasearch = require('algoliasearch');
var crypto = require('crypto');

var INDEXED_LAYOUTS = 'page';

var CONSOLE_DEFAULTS = {
  dryRun: false,
  flush: false,
  chunkSize: 50,
  layouts: INDEXED_LAYOUTS
};

var INDEXED_PROPERTIES = [
  'title',
  'date',
  'updated',
  'slug',
  'excerpt',
  'permalink',
  'layout',
  'image'
];

function computeSha1(text) {
  return crypto.createHash('sha1').update(text, 'utf8').digest('hex');
}

function pick(object, properties) {
  return properties.reduce(function(filteredObj, prop) {
    filteredObj[prop] = object[prop];
    return filteredObj;
  }, {});
}

function chunk(array, chunkSize) {
  var batches = [];

  while (array.length > 0) {
    batches.push(array.splice(0, chunkSize));
  }

  return batches;
}

module.exports = function(args, callback) {
  var hexo = this;
  var config = Object.assign({}, hexo.config.algolia);
  var indexName = config.indexName;
  var applicationID = config.applicationID;
  var apiKey = String(process.env.HEXO_ALGOLIA_INDEXING_KEY || '');
  var options = Object.assign({}, CONSOLE_DEFAULTS, args || {});
  var pageLayouts = options.layouts.split(',');
  var client;
  var index;

  Promise.resolve(apiKey)
    .then(function(){
      if (!apiKey) {
        hexo.log.error('[hexo-algolia] Please set an `HEXO_ALGOLIA_INDEXING_KEY` environment variable to enable content indexing.');
        hexo.log.error('>> Read %s for more informations.', 'https://npmjs.com/hexo-algolia#api-key');
        process.exit(1);
      }

      if (!indexName) {
        hexo.log.error('[hexo-algolia] Please provide an Algolia index name in your hexo _config.yml file.');
        hexo.log.error('>> Read %s for more informations.', 'https://npmjs.com/hexo-algolia#public-facing-search-options');
        process.exit(1);
      }

      client = algoliasearch(applicationID, apiKey);
      index = client.initIndex(indexName);
    })
    .then(function(){
      hexo.log.info('[hexo-algolia] Testing HEXO_ALGOLIA_INDEXING_KEY permissions.');

      return client.getApiKey(apiKey)
        .catch(function(err){
          hexo.log.error('[hexo-algolia] %s', err.message);
          hexo.log.error('>> You might have used an Admin Key or an invalid Key.');
          hexo.log.error('>> Read %s for more informations.', 'https://npmjs.com/hexo-algolia#security-concerns');
          process.exit(1);
        });
    })
    .then(function() {
      return hexo.load();
    })
    .then(function() {
      var posts = hexo.database.model('Post').find({ published: true });

      return posts.toArray();
    })
    .then(function(publishedPosts) {
      var pages = hexo.database.model('Page').find({
        layout: { '$in': pageLayouts }
      });

      return publishedPosts.concat(pages.toArray());
    })
    .then(function(publishedPagesAndPosts) {
      return publishedPagesAndPosts.map(function(data) {
        var storedPost = pick(data, INDEXED_PROPERTIES);

        storedPost.objectID = computeSha1(data.path);
        storedPost.date_as_int = Date.parse(data.date) / 1000;
        storedPost.updated_as_int = Date.parse(data.updated) / 1000;
        storedPost.permalink = storedPost.permalink.replace(/\/index.html$/, '/');

        if (Array.isArray(data.categories)) {
          storedPost.categories = data.categories.map(function(item) {
            return pick(item, ['name', 'path']);
          });
        }

        if (Array.isArray(data.tags)) {
          storedPost.tags = data.tags.map(function(item) {
            return pick(item, ['name', 'path']);
          });
        }

        storedPost.author = data.author || config.author;

        return storedPost;
      });
    })
    .then(function(publishedPagesAndPosts) {
      hexo.log.info(
        '[hexo-algolia] %d pages and posts to index.',
        publishedPagesAndPosts.length
      );

      return publishedPagesAndPosts.map(function toAlgoliaBatchActions(post) {
        return {
          action: 'updateObject',
          indexName: indexName,
          body: post
        };
      });
    })
    .then(function(actions) {
      if (options.dryRun) {
        hexo.log.info('[hexo-algolia] Skipping due to --dry-run option');
        return;
      }

      return Promise.resolve(options.flush)
        .then(function(flush) {
          if (flush) {
            hexo.log.info('[hexo-algolia] Clearing index...');
            return index.clearIndex();
          }
        })
        .then(function() {
          var chunks = chunk(actions, options.chunkSize);

          return each(chunks, function(chunk, i) {
            hexo.log.info(
              '[hexo-algolia] Indexing chunk %d of %d (%d items each)',
              i + 1,
              chunks.length,
              options.chunkSize
            );

            return client
              .batch(chunk)
              .catch(function(err){
                hexo.log.error('[hexo-algolia] %s', err.message);
              });
          });
        })

        .then(function() {
          hexo.log.info('[hexo-algolia] Indexing done.');
        });
    })
    .catch(callback);
};
<|endoftext|>


<commit_before>"use strict"

var cfg        = require('config'),
    log4js     = require('log4js'),

// logs

log4js.configure(cfg.get('log.log4jsConfigs'));

var log = log4js.getLogger(cfg.get('log.appName'));
log.setLevel(cfg.get('log.level'));

// Hourly callout rate for OOH shifts
var calloutHourlyRate = 50;

function GetDiffs (params, callback) {

  var emails = params.email
     ,cals   = params.calendar
     ,oohs   = params.timesheet;

  var notSynced = [];

  // Split out the OOH shifts first
  var total = emails.length
  for (var i = 0; i < total; i++) {

    var email        = emails[i]
       ,emailDate    = email.date
       ,emailPayType = email.payType;

    log.debug('Comparison event: %s (%s)', emailPayType, emailDate)

    var synced = false;

    // Treat the various pay categories
    switch (emailPayType) {

      case "OOH" : {

        log.debug('Payment is for OOH')

        for (var j = 0; j < oohs.length; j++) {

          var ooh        = oohs[j]
             ,oohDate    = ooh.date
             ,oohHours   = ooh.hours
             ,emailHours = (email.amount/calloutHourlyRate)

          log.trace('+--> Comparing with OOH on %s for %s hours', oohDate, oohHours);

          if (emailDate == oohDate
            && emailHours == oohHours
          ) {
            log.debug('Match found for OOH shift on %s for %s hours', oohDate, oohHours)
            emails.splice(i,1)
            i--
            total--
            oohs.splice(j,1)
            synced = true
            break
          }

        }

        break;
      }

      case "L1" :
      case "L2" : {

        log.debug('Payment is for Calendar')

        // Look for an entry in the calendar array with
        // the same details
        for (var j = 0; j < cals.length; j++) {

          var cal        = cals[j]
             ,calDate    = cal.date
             ,calPayType = cal.payType;

          log.trace('+--> Comparing with Cal on %s for %s shift', calPayType, calDate)

          if (emailDate == calDate && emailPayType == calPayType) {
            log.debug('Match found for Calendar %s shift on %s', calPayType, calDate)
            emails.splice(i,1)
            i--
            total--
            cals.splice(j,1)
            synced = true
            break
          }
        }

        break;
      }

      default : {

        // Unrecognized entry
        var errMsg = 'Comparison error: Unrecognized entry type: ' + emailPayType;
        log.error(errMsg);
        callback(new Error(errMsg))
        return null
      }
    }

    if (!synced) {
      var d = new Date(email.date);
      notSynced.push({
        source:  "Email",
        payType: email.payType,
        date:    d.toDateString(),
      })
    }

  }

  /*
   * Finally, go through the ooh and cal objects.
   * Any leftovers here are ones that didn't match.
   */

  for (var i = 0; i < oohs.length; i++) {

    var d = new Date(oohs[i].date);
    notSynced.push({
      source:  "Timesheet",
      payType: oohs[i].payType,
      date:    d.toDateString(),
    })

  }

  for (var i = 0; i < cals.length; i++) {

    var d = new Date(cals[i].date);
    notSynced.push({
      source:  "Calendar",
      payType: cals[i].payType,
      date:    d.toDateString(),
    })

  }

  if (notSynced.length == 0) {
    log.info('All in sync')
  } else {
    log.info('Not synced:\n%s', JSON.stringify(notSynced))
  }

  callback(null,notSynced);
}

// export the class
exports.getDiffs = GetDiffs;
<commit_msg>Removing unneccesary dependency on dateformat<commit_after>"use strict"

var cfg        = require('config'),
    log4js     = require('log4js')

// logs

log4js.configure(cfg.get('log.log4jsConfigs'));

var log = log4js.getLogger(cfg.get('log.appName'));
log.setLevel(cfg.get('log.level'));

// Hourly callout rate for OOH shifts
var calloutHourlyRate = 50;

function GetDiffs (params, callback) {

  var emails = params.email
     ,cals   = params.calendar
     ,oohs   = params.timesheet;

  var notSynced = [];

  // Split out the OOH shifts first
  var total = emails.length
  for (var i = 0; i < total; i++) {

    var email        = emails[i]
       ,emailDate    = email.date
       ,emailPayType = email.payType;

    log.debug('Comparison event: %s (%s)', emailPayType, emailDate)

    var synced = false;

    // Treat the various pay categories
    switch (emailPayType) {

      case "OOH" : {

        log.debug('Payment is for OOH')

        for (var j = 0; j < oohs.length; j++) {

          var ooh        = oohs[j]
             ,oohDate    = ooh.date
             ,oohHours   = ooh.hours
             ,emailHours = (email.amount/calloutHourlyRate)

          log.trace('+--> Comparing with OOH on %s for %s hours', oohDate, oohHours);

          if (emailDate == oohDate
            && emailHours == oohHours
          ) {
            log.debug('Match found for OOH shift on %s for %s hours', oohDate, oohHours)
            emails.splice(i,1)
            i--
            total--
            oohs.splice(j,1)
            synced = true
            break
          }

        }

        break;
      }

      case "L1" :
      case "L2" : {

        log.debug('Payment is for Calendar')

        // Look for an entry in the calendar array with
        // the same details
        for (var j = 0; j < cals.length; j++) {

          var cal        = cals[j]
             ,calDate    = cal.date
             ,calPayType = cal.payType;

          log.trace('+--> Comparing with Cal on %s for %s shift', calPayType, calDate)

          if (emailDate == calDate && emailPayType == calPayType) {
            log.debug('Match found for Calendar %s shift on %s', calPayType, calDate)
            emails.splice(i,1)
            i--
            total--
            cals.splice(j,1)
            synced = true
            break
          }
        }

        break;
      }

      default : {

        // Unrecognized entry
        var errMsg = 'Comparison error: Unrecognized entry type: ' + emailPayType;
        log.error(errMsg);
        callback(new Error(errMsg))
        return null
      }
    }

    if (!synced) {
      var d = new Date(email.date);
      notSynced.push({
        source:  "Email",
        payType: email.payType,
        date:    d.toDateString(),
      })
    }

  }

  /*
   * Finally, go through the ooh and cal objects.
   * Any leftovers here are ones that didn't match.
   */

  for (var i = 0; i < oohs.length; i++) {

    var d = new Date(oohs[i].date);
    notSynced.push({
      source:  "Timesheet",
      payType: oohs[i].payType,
      date:    d.toDateString(),
    })

  }

  for (var i = 0; i < cals.length; i++) {

    var d = new Date(cals[i].date);
    notSynced.push({
      source:  "Calendar",
      payType: cals[i].payType,
      date:    d.toDateString(),
    })

  }

  if (notSynced.length == 0) {
    log.info('All in sync')
  } else {
    log.info('Not synced:\n%s', JSON.stringify(notSynced))
  }

  callback(null,notSynced);
}

// export the class
exports.getDiffs = GetDiffs;
<|endoftext|>


<commit_before>(function () {
if (typeof(window) === 'undefined') {
    var nearley = require('../lib/nearley.js');
} else {
    var nearley = window.nearley;
}

function Compile(structure, opts) {
    var unique = uniquer();

    var outputRules = [];
    var body = []; // @directives list

    function buildProcessedRule(ruleName, rule) {
        var tokens = [];

        rule.tokens.forEach(function(token) {
            if (token.literal) {
                var str = token.literal;
                if (str.length > 1) {
                    var rules = str.split("").map(function(d) {
                        return {
                            literal: d
                        };
                    });

                    var newname = unique(ruleName + "$string");
                    buildProcessedRule(newname, {
                        tokens: rules,
                        postprocess: joiner
                    });
                    tokens.push(newname);
                } else if (str.length === 1) {
                    tokens.push({
                        literal: str
                    });
                }
            } else if (token.subexpression) {
                var data = token.subexpression;
                var name = unique(ruleName + "$subexpression");
                structure.push({"name": name, "rules": data});
                tokens.push(name);
            } else if (token.ebnf) {
                var data = token.ebnf;
                var modifier = token.modifier;
                var name = unique(ruleName + "$ebnf");

                switch (modifier) {
                    case ":+":
                        structure.push({
                            name: name,
                            rules: [{
                                tokens: [data],
                            }, {
                                tokens: [data, name],
                                postprocess: arrconcat
                            }]
                        });
                        tokens.push(name);
                        break;
                    case ":*":
                        structure.push({
                            name: name,
                            rules: [{
                                tokens: [],
                            }, {
                                tokens: [data, name],
                                postprocess: arrconcat
                            }]
                        });
                        tokens.push(name);
                        break;
                    case ":?":
                        structure.push({
                            name: name,
                            rules: [{
                                tokens: [data],
                                postprocess: "id"
                            }, {
                                tokens: [],
                                postprocess: "function(d) {return null;}"
                            }]
                        });
                        tokens.push(name);
                        break;
                }
            } else if (typeof token === 'string') {
                if (token !== 'null') tokens.push(token);
            } else if (token instanceof RegExp) {
                tokens.push(token);
            } else {
                throw new Error("Should never get here");
            }
        });

        var out = new nearley.Rule(
            ruleName,
            tokens,
            (opts.nojs ? null : rule.postprocess)
        );

        outputRules.push(out);
    }

    var firstName;

    for (var i = 0; i < structure.length; i++) {
        var productionRule = structure[i];
        if (productionRule.body) {
            // This isn't a rule, it's an @directive.
            if (!opts.nojs) body.push(productionRule.body);
        } else {
            var rules = productionRule.rules;
            if (!firstName) firstName = productionRule.name;
            rules.forEach(function(rule) {
                buildProcessedRule(productionRule.name, rule);
            });
        }
    }

    return {
        rules: outputRules,
        body: body,
        start: firstName
    };
}

function uniquer() {
    var uns = {};
    return unique;
    function unique(name) {
        var un = uns[name] = (uns[name] || 0) + 1;
        return name + '$' + un;
    }
}

function arrconcat(d) {
    return [d[0]].concat(d[1]);
}

function joiner(d) {
    return d.join('');
}

if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
    module.exports = Compile;
} else {
    window.Compile = Compile;
}
})();
<commit_msg>lib/compile: re-order for change clarity<commit_after>(function () {
if (typeof(window) === 'undefined') {
    var nearley = require('../lib/nearley.js');
} else {
    var nearley = window.nearley;
}

function Compile(structure, opts) {
    var unique = uniquer();

    var outputRules = [];
    var body = []; // @directives list
    var firstName;

    for (var i = 0; i < structure.length; i++) {
        var productionRule = structure[i];
        if (productionRule.body) {
            // This isn't a rule, it's an @directive.
            if (!opts.nojs) body.push(productionRule.body);
        } else {
            var rules = productionRule.rules;
            if (!firstName) firstName = productionRule.name;
            rules.forEach(function(rule) {
                buildProcessedRule(productionRule.name, rule);
            });
        }
    }

    return {
        rules: outputRules,
        body: body,
        start: firstName
    };

    function buildProcessedRule(ruleName, rule) {
        var tokens = [];

        rule.tokens.forEach(function(token) {
            if (token.literal) {
                var str = token.literal;
                if (str.length > 1) {
                    var rules = str.split("").map(function(d) {
                        return {
                            literal: d
                        };
                    });

                    var newname = unique(ruleName + "$string");
                    buildProcessedRule(newname, {
                        tokens: rules,
                        postprocess: joiner
                    });
                    tokens.push(newname);
                } else if (str.length === 1) {
                    tokens.push({
                        literal: str
                    });
                }
            } else if (token.subexpression) {
                var data = token.subexpression;
                var name = unique(ruleName + "$subexpression");
                structure.push({"name": name, "rules": data});
                tokens.push(name);
            } else if (token.ebnf) {
                var data = token.ebnf;
                var modifier = token.modifier;
                var name = unique(ruleName + "$ebnf");

                switch (modifier) {
                    case ":+":
                        structure.push({
                            name: name,
                            rules: [{
                                tokens: [data],
                            }, {
                                tokens: [data, name],
                                postprocess: arrconcat
                            }]
                        });
                        tokens.push(name);
                        break;
                    case ":*":
                        structure.push({
                            name: name,
                            rules: [{
                                tokens: [],
                            }, {
                                tokens: [data, name],
                                postprocess: arrconcat
                            }]
                        });
                        tokens.push(name);
                        break;
                    case ":?":
                        structure.push({
                            name: name,
                            rules: [{
                                tokens: [data],
                                postprocess: "id"
                            }, {
                                tokens: [],
                                postprocess: "function(d) {return null;}"
                            }]
                        });
                        tokens.push(name);
                        break;
                }
            } else if (typeof token === 'string') {
                if (token !== 'null') tokens.push(token);
            } else if (token instanceof RegExp) {
                tokens.push(token);
            } else {
                throw new Error("Should never get here");
            }
        });

        var out = new nearley.Rule(
            ruleName,
            tokens,
            (opts.nojs ? null : rule.postprocess)
        );

        outputRules.push(out);
    }
}

function uniquer() {
    var uns = {};
    return unique;
    function unique(name) {
        var un = uns[name] = (uns[name] || 0) + 1;
        return name + '$' + un;
    }
}

function arrconcat(d) {
    return [d[0]].concat(d[1]);
}

function joiner(d) {
    return d.join('');
}

if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
    module.exports = Compile;
} else {
    window.Compile = Compile;
}
})();
<|endoftext|>


<commit_before>/*
 * This file is part of EspruinoHub, a Bluetooth-MQTT bridge for
 * Puck.js/Espruino JavaScript Microcontrollers
 *
 * Copyright (C) 2016 Gordon Williams <gw@pur3.co.uk>
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * ----------------------------------------------------------------------------
 *  Connect to BLE devices
 * ----------------------------------------------------------------------------
 */
var util = require('./util');
var discovery = require('./discovery');
var queue = [];

var MAX_CONNECTIONS = 4;
var connections = [];

function log(x) {
  console.log("<Connect> "+x);
}

function Connection(device, callback) {
  connections.push(this);
  var connection = this;
  connection.device = device;
  log("Connecting...");
  device.connect(function (error) {
    if (error) {
      log("Error Connecting: "+error.toString());
      connection.device = undefined;
      connection.close();
      callback("Error Connecting: "+error.toString());
      serviceQueue();
    } else {
      log("Connected.");
      callback(null);
    }
  });
}
Connection.prototype.getCharacteristic = function(serviceUUID, characteristicUUID, callback) {
  log("Getting Service...");
  var timeout = setTimeout(function() {
    timeout = undefined;
    log("Timed out getting services.");
    callback("Timed out getting services.");
  }, 4000);
  var matchedService = undefined;
  job.device.discoverServices([serviceUUID], function(error, services) { // do explicit search for known service
    if (services != undefined && services.length) {
      log("found service: " + matchedService.uuid, "getting Characteristic....");
      var matchedService = services[0];
      var characteristic = undefined;
      matchedService.discoverCharacteristics([characteristicUUID], function(error, characteristics) { // do explicit search for known characteristic
        if (timeout) clearTimeout(timeout);
        if (characteristics != undefined && characteristics.length) {
          log("found characteristic: " + characteristic.uuid);
          callback(null, characteristics[0]);
        } else {
          callback("Characteristic "+characteristicUUID+" not found");
        }
      });
    } else {
      if (timeout) clearTimeout(timeout);
      callback("Service "+serviceUUID+" not found");
    }
  });
}

Connection.prototype.close = function() {
  if (this.device) {
    try {
      this.device.disconnect();
      log("Disconnected");
    } catch (e) {
      log("Disconnect error: "+e);
    }
    this.device = undefined;
  }
  var i = connections.indexOf(this);
  if (i>=0) connections.splice(i,1);
  serviceQueue();
};

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------

// Repeated write to characteristic
function writeToCharacteristic(characteristic, message, callback) { // added function to write longer strings
  if (message.length) {
    var data = message.slice(0, 20);
    message = message.slice(20);
    characteristic.write(data, false, function() {
      log("wrote data: " + data.length + " bytes");
      writeToCharacteristic(characteristic, message);
    });
  } else if (callback) callback();
}

function serviceQueue() {
  if (!queue.length) {
    discovery.restartScan();
    return;
  }
  var job = queue.shift();
  discovery.stopScan();
  setTimeout(job, 1000);
}

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------

/* Write to the given device */
exports.write = function(device, service, characteristic, data) {
  queue.push(function(){
    var connection = new Connection(device, function(err) {
      if (err) return;
      connection.getCharacteristic(util.uuid2noble(service),
                                   util.uuid2noble(characteristic),
       function(err,char) {
         if (err) return;
         writeToCharacteristic(char, util.obj2buf(data), function() {
             log("Written. Disconnecting.");
             connection.close();
           });
       });
    });
  });
  serviceQueue();
};

/* Read from the given device */
exports.read = function(device, service, characteristic, callback) {
  queue.push(function(){
    var connection = new Connection(device, function(err) {
      if (err) return;
      connection.getCharacteristic(util.uuid2noble(service),
                                   util.uuid2noble(characteristic),
       function(err,char) {
         if (err) return;
         characteristic.read(function(error, data) {
           log("Read. Disconnecting.");
           connection.close();
           if (callback) callback(data.toString());
         });
       });
    });
  });
  serviceQueue();
};
<commit_msg>write and read now working<commit_after>/*
 * This file is part of EspruinoHub, a Bluetooth-MQTT bridge for
 * Puck.js/Espruino JavaScript Microcontrollers
 *
 * Copyright (C) 2016 Gordon Williams <gw@pur3.co.uk>
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * ----------------------------------------------------------------------------
 *  Connect to BLE devices
 * ----------------------------------------------------------------------------
 */
var util = require('./util');
var discovery = require('./discovery');
var queue = [];

var MAX_CONNECTIONS = 4;
var connections = [];

function log(x) {
  console.log("<Connect> "+x);
}

function Connection(device, callback) {
  connections.push(this);
  var connection = this;
  connection.device = device;
  log("Connecting...");
  device.connect(function (error) {
    if (error) {
      log("Error Connecting: "+error.toString());
      connection.device = undefined;
      connection.close();
      callback("Error Connecting: "+error.toString());
      serviceQueue();
    } else {
      log("Connected.");
      callback(null);
    }
  });
}
Connection.prototype.getCharacteristic = function(serviceUUID, characteristicUUID, callback) {
  log("Getting Service...");
  var timeout = setTimeout(function() {
    timeout = undefined;
    log("Timed out getting services.");
    callback("Timed out getting services.");
  }, 4000);
  var matchedService = undefined;
  this.device.discoverServices([serviceUUID], function(error, services) { // do explicit search for known service
    if (services != undefined && services.length) {
      var matchedService = services[0];
      log("found service: " + matchedService.uuid, "getting Characteristic....");
      var characteristic = undefined;
      matchedService.discoverCharacteristics([characteristicUUID], function(error, characteristics) { // do explicit search for known characteristic
        if (timeout) clearTimeout(timeout);
        if (characteristics != undefined && characteristics.length) {
          log("found characteristic: " + characteristics[0].uuid);
          callback(null, characteristics[0]);
        } else {
          callback("Characteristic "+characteristicUUID+" not found");
        }
      });
    } else {
      if (timeout) clearTimeout(timeout);
      callback("Service "+serviceUUID+" not found");
    }
  });
}

Connection.prototype.close = function() {
  if (this.device) {
    try {
      this.device.disconnect();
      log("Disconnected");
    } catch (e) {
      log("Disconnect error: "+e);
    }
    this.device = undefined;
  }
  var i = connections.indexOf(this);
  if (i>=0) connections.splice(i,1);
  serviceQueue();
};

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------

// Repeated write to characteristic
function writeToCharacteristic(characteristic, message, callback) { // added function to write longer strings
  if (message.length) {
    var data = message.slice(0, 20);
    message = message.slice(20);
    characteristic.write(data, false, function() {
      log("wrote data: " + data.length + " bytes");
      writeToCharacteristic(characteristic, message, callback);
    });
  } else if (callback) callback();
}

function serviceQueue() {
  if (!queue.length) {
    discovery.restartScan();
    return;
  }
  var job = queue.shift();
  discovery.stopScan();
  setTimeout(job, 1000);
}

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------

/* Write to the given device */
exports.write = function(device, service, characteristic, data) {
  queue.push(function(){
    var connection = new Connection(device, function(err) {
      if (err) return;
      connection.getCharacteristic(util.uuid2noble(service),
                                   util.uuid2noble(characteristic),
       function(err,char) {
         if (err) return;
         writeToCharacteristic(char, util.obj2buf(data), function() {
             log("Written. Disconnecting.");
             connection.close();
           });
       });
    });
  });
  serviceQueue();
};

/* Read from the given device */
exports.read = function(device, service, characteristic, callback) {
  queue.push(function(){
    var connection = new Connection(device, function(err) {
      if (err) return;
      connection.getCharacteristic(util.uuid2noble(service),
                                   util.uuid2noble(characteristic),
       function(err,char) {
         if (err) return;
         char.read(function(error, data) {
           log("Read. Disconnecting.");
           connection.close();
           if (callback) callback(data.toString());
         });
       });
    });
  });
  serviceQueue();
};
<|endoftext|>


<commit_before>
/**
 * Module dependencies.
 */

var sprintf = require('printf');
var sum = require('sum-component');
var path = require('path');
var basename = path.basename;
var isatty = process.stdout.isTTY;

/**
 * Expose `Console`.
 */

module.exports = Console;

/**
 * Initialize a new `Console` reporter.
 *
 * - `direct` show direct links
 * - `progressOnly` show aggregate progress only
 *
 * @param {Stream} stream
 * @param {Object} options
 * @api public
 */

function Console(stream, options) {
  this.y = 0;
  this.items = [];
  this.stream = stream;
  this.direct = options.direct;
  this.progressOnly = options.progressOnly;
  if (this.progressOnly) stream.on('item', this.aggregate.bind(this))
  else stream.on('item', this.progress.bind(this));
  stream.on('save', this.onsave.bind(this));
  stream.on('end', this.onend.bind(this));
  this.setup();
}

/**
 * Setup.
 *
 * @api private
 */

Console.prototype.setup = function(){
  if (isatty) console.log();
  clear();
  hideCursor();
  process.on('uncaughtException', showCursor);
  process.on('uncaughtException', fatal);
  process.on('exit', showCursor);
  process.on('SIGINT', showCursor);
  process.on('SIGINT', clear);
  process.on('SIGINT', process.exit.bind(null, 1));
};

/**
 * Item aggregate progress.
 *
 * @api private
 */

Console.prototype.aggregate = function(item){
  var self = this;
  this.items.push(item);
  item.progress = 0;
  item.on('progress', function(e){
    item.progress = e.percent;
    self.update();
  });
};

/**
 * Update aggregate progress.
 *
 * @api private
 */

Console.prototype.update = function(){
  var len = this.items.length;
  var percent = sum(this.items, 'progress') / len | 0;
  move(0, 3);
  log(len + ' items', percent + '%');
};

/**
 * Item progress reporting.
 *
 * @api private
 */

Console.prototype.progress = function(item){
  var y = this.y++;
  var direct = this.direct;
  var stream = this.stream;

  if (isatty) {
    process.nextTick(function(){
      move(0, 2 + y);
      log(ctx(item), '0%');
    });

    item.on('progress', function(e){
      var n = e.percent | 0;
      move(0, 2 + y);
      log(ctx(item), n + '%');
    });
  }

  item.on('end', function(){
    move(0, 2 + y);

    if (direct) {
      log(ctx(item), item.remote_url);
    } else {
      log(ctx(item), item.url);
    }
  });
};

/**
 * Output collection link on save.
 *
 * @api private
 */

Console.prototype.onsave = function(){
  move(0, 2 + this.y);
  log('stream', this.stream.url);
};

/**
 * Add padding on end.
 *
 * @api private
 */

Console.prototype.onend = function(){
  move(0, 3 + this.y);
  if (isatty) console.log();
};

/**
 * Fatal error.
 */

function fatal(err) {
  console.log();
  console.error(err.stack.replace(/^/gm, '  '));
  console.log();
  process.exit(1);
}

/**
 * Clear the term.
 */

function clear() {
  if (!isatty) return;
  process.stdout.write('\033[0m\033[1J');
  process.stdout.write('\033[J');
}

/**
 * Hide the cursor.
 */

function hideCursor(){
  if (!isatty) return;
  process.stdout.write('\033[?25l');
}

/**
 * Show the cursor.
 */

function showCursor(){
  if (!isatty) return;
  process.stdout.write('\033[?25h');
}

/**
 * Move to (x, y).
 */

function move(x, y) {
  if (!isatty) return;
  x = Math.round(x);
  y = Math.round(y);
  process.stdout.write('\033[' + y + ';' + x + 'H');
}

/**
 * Truncate `str`.
 */

function truncate(str) {
  var w = 20;
  if (str.length < w) return str;
  return str.slice(0, w) + '…';
}

/**
 * Log `key` / `str`.
 */

function log(key, str) {
  if (isatty) {
    process.stdout.write(sprintf('\033[36m%25s\033[0m : \033[90m%s\033[m\n', key, str));
  } else {
    process.stdout.write(sprintf('%s : %s\n', key, str));
  }
}

/**
 * Context string for `item`.
 */

function ctx(item) {
  return truncate(item._file
    ? basename(item.filename || item._file)
    : item._url);
}
<commit_msg>fix --direct support<commit_after>
/**
 * Module dependencies.
 */

var sprintf = require('printf');
var sum = require('sum-component');
var path = require('path');
var basename = path.basename;
var isatty = process.stdout.isTTY;

/**
 * Expose `Console`.
 */

module.exports = Console;

/**
 * Initialize a new `Console` reporter.
 *
 * - `direct` show direct links
 * - `progressOnly` show aggregate progress only
 *
 * @param {Stream} stream
 * @param {Object} options
 * @api public
 */

function Console(stream, options) {
  this.y = 0;
  this.items = [];
  this.stream = stream;
  this.direct = options.direct;
  this.progressOnly = options.progressOnly;
  if (this.progressOnly) stream.on('item', this.aggregate.bind(this))
  else stream.on('item', this.progress.bind(this));
  stream.on('save', this.onsave.bind(this));
  stream.on('end', this.onend.bind(this));
  this.setup();
}

/**
 * Setup.
 *
 * @api private
 */

Console.prototype.setup = function(){
  if (isatty) console.log();
  clear();
  hideCursor();
  process.on('uncaughtException', showCursor);
  process.on('uncaughtException', fatal);
  process.on('exit', showCursor);
  process.on('SIGINT', showCursor);
  process.on('SIGINT', clear);
  process.on('SIGINT', process.exit.bind(null, 1));
};

/**
 * Item aggregate progress.
 *
 * @api private
 */

Console.prototype.aggregate = function(item){
  var self = this;
  this.items.push(item);
  item.progress = 0;
  item.on('progress', function(e){
    item.progress = e.percent;
    self.update();
  });
};

/**
 * Update aggregate progress.
 *
 * @api private
 */

Console.prototype.update = function(){
  var len = this.items.length;
  var percent = sum(this.items, 'progress') / len | 0;
  move(0, 3);
  log(len + ' items', percent + '%');
};

/**
 * Item progress reporting.
 *
 * @api private
 */

Console.prototype.progress = function(item){
  var y = this.y++;
  var direct = this.direct;
  var stream = this.stream;

  if (isatty) {
    process.nextTick(function(){
      move(0, 2 + y);
      log(ctx(item), '0%');
    });

    item.on('progress', function(e){
      var n = e.percent | 0;
      move(0, 2 + y);
      log(ctx(item), n + '%');
    });
  }

  item.on('end', function(){
    move(0, 2 + y);

    if (direct) {
      log(ctx(item), item.direct_url);
    } else {
      log(ctx(item), item.url);
    }
  });
};

/**
 * Output collection link on save.
 *
 * @api private
 */

Console.prototype.onsave = function(){
  move(0, 2 + this.y);
  log('stream', this.stream.url);
};

/**
 * Add padding on end.
 *
 * @api private
 */

Console.prototype.onend = function(){
  move(0, 3 + this.y);
  if (isatty) console.log();
};

/**
 * Fatal error.
 */

function fatal(err) {
  console.log();
  console.error(err.stack.replace(/^/gm, '  '));
  console.log();
  process.exit(1);
}

/**
 * Clear the term.
 */

function clear() {
  if (!isatty) return;
  process.stdout.write('\033[0m\033[1J');
  process.stdout.write('\033[J');
}

/**
 * Hide the cursor.
 */

function hideCursor(){
  if (!isatty) return;
  process.stdout.write('\033[?25l');
}

/**
 * Show the cursor.
 */

function showCursor(){
  if (!isatty) return;
  process.stdout.write('\033[?25h');
}

/**
 * Move to (x, y).
 */

function move(x, y) {
  if (!isatty) return;
  x = Math.round(x);
  y = Math.round(y);
  process.stdout.write('\033[' + y + ';' + x + 'H');
}

/**
 * Truncate `str`.
 */

function truncate(str) {
  var w = 20;
  if (str.length < w) return str;
  return str.slice(0, w) + '…';
}

/**
 * Log `key` / `str`.
 */

function log(key, str) {
  if (isatty) {
    process.stdout.write(sprintf('\033[36m%25s\033[0m : \033[90m%s\033[m\n', key, str));
  } else {
    process.stdout.write(sprintf('%s : %s\n', key, str));
  }
}

/**
 * Context string for `item`.
 */

function ctx(item) {
  return truncate(item._file
    ? basename(item.filename || item._file)
    : item._url);
}
<|endoftext|>


<commit_before>var bunyan = require('bunyan'),
	chalk = require('chalk'),
	util = require('util'),
	_ = require('lodash'),
	events = require('events'),
	Logger = require('./logger'),
	EventEmitter = events.EventEmitter,
	grey = chalk.grey,
	green = chalk.green,
	cyan = chalk.cyan,
	red = chalk.red,
	yellow = chalk.yellow,
	dash = grey.bold('|'),
	defaultChalkEnabled = chalk.enabled,
	defaultColorizeArg;

util.inherits(ConsoleLogger, events.EventEmitter);

/**
 * Console logging functionality
 *
 * @param {Object} options - options
 */
function ConsoleLogger(options) {
	EventEmitter.call(this);
	this.options = options || {};
	// allow use to customize if they want the label or not
	this.prefix = this.options.prefix === undefined ? true : this.options.prefix;
	this.showcr = this.options.showcr === undefined ? true : this.options.showcr;
	this.showtab = this.options.showtab === undefined ? true : this.options.showtab;
	this.colorize = this.options.colorize === undefined ? checkColorize() : this.options.colorize;
	chalk.enabled = !!this.colorize;
	this.remapLevels();
}

/**
 * Check colorization
 */
function checkColorize() {
	if (defaultColorizeArg !== undefined) {
		return defaultColorizeArg;
	}
	// default is to only colorize if we have a TTY and not running on TTY
	defaultColorizeArg = process.stdout.isTTY && !process.env.TRAVIS;
	for (var c = 1; c < process.argv.length; c++) {
		var arg = process.argv[c];
		if (arg === '--colorize' || arg === '--color' || arg === '--colors') {
			defaultColorizeArg = true;
			break;
		} else if (arg === '--no-colors' || arg === '--no-color') {
			defaultColorizeArg = false;
			break;
		}
	}
	return defaultColorizeArg;
}

const	CR_NC = '↩',
		CR = chalk.blue.bold(CR_NC),
		TAB_NC = '↠',
		TAB = chalk.blue.bold(TAB_NC);

/**
 * Remap levels
 */
ConsoleLogger.prototype.remapLevels = function remapLevels() {
	this.LevelMapping = {};
	this.LevelMapping[bunyan.TRACE] = {prefix: grey('TRACE '), color:grey, prefixNoColor: 'TRACE '};
	this.LevelMapping[bunyan.DEBUG] = {prefix: grey.bold('DEBUG '), color: cyan, prefixNoColor: 'DEBUG '};
	this.LevelMapping[bunyan.INFO] = {prefix: green('INFO  '), prefixNoColor: 'INFO  '};
	this.LevelMapping[bunyan.WARN] = {prefix: yellow('WARN  '), prefixNoColor: 'WARN  '};
	this.LevelMapping[bunyan.ERROR] = {prefix: red('ERROR '), prefixNoColor: 'ERROR '};
	this.LevelMapping[bunyan.FATAL] = {prefix: red.underline('FATAL') + ' ', color:red, prefixNoColor: 'FATAL '};
};

/**
 * called to write a formatted set of args (as an array) to
 * console.log. allows subclasses to override after formatting
 * has been applied
 *
 * @param  {Object} args - args
 */
ConsoleLogger.prototype.writeFormatted = function (args) {
	console.log.apply(console, args);
};

/**
 * Write
 *
 * @param  {Object} record - record
 */
ConsoleLogger.prototype.write = function (record) {
	if (!record.ignore) {

		// this should only happen during unit testing
		if (defaultColorizeArg === undefined) {
			this.colorize = checkColorize();
		}

		var level = this.LevelMapping[record.level],
			color = this.colorize,
			args = [];

		if (this.prefix) {
			args.push(color ? level.prefix : level.prefixNoColor);
			args.push(color ? dash : '|');
		}
		var msg = record.msg;
		if (!msg || msg === ' ') {
			// this is the case where you send in an object as the only argument
			var fields = _.omit(record, 'name', 'prefix', 'showtab', 'showcr', 'hostname', 'pid', 'level', 'msg', 'time', 'v', 'problemLogName');
			if (_.isEmpty(fields)) {
				msg = '';
			} else {
				msg = util.inspect(fields, {colors:true});
			}
		}
		if (this.showcr && msg.indexOf('\n') > 0) {
			var lines = msg.split(/\n/),
				cr = color ? CR : CR_NC;
			msg = lines.join(cr + '\n') + (lines.length > 1 ? cr : '');
		}
		if (this.showtab && msg.indexOf('\t') > 0) {
			var tlines = msg.split(/\t/),
				tab = color ? TAB : TAB_NC;
			msg = tlines.join('\t' + tab);
		}
		if (color) {
			args.push(level.color && level.color(msg) || msg);
		} else {
			args.push(Logger.stripColors(msg));
		}
		this.writeFormatted(args);
	}
	return true;
};

/**
 * End
 */
ConsoleLogger.prototype.end = function () {
	if (arguments.length > 0) {
		this.write.apply(this, Array.prototype.slice.call(arguments));
	}
	this.destroySoon();
};

/**
 * Destroy
 */
ConsoleLogger.prototype.destroy = function () {
	this.emit('close');
};

/**
 * Destroy soon
 */
ConsoleLogger.prototype.destroySoon = function () {
	this.destroy();
};

/**
 * Reset colorization
 */
ConsoleLogger.resetColorize = function () {
	defaultColorizeArg = undefined;
	chalk.enabled = chalk.supportsColor;
};

module.exports = ConsoleLogger;
<commit_msg>change tab to space after const<commit_after>var bunyan = require('bunyan'),
	chalk = require('chalk'),
	util = require('util'),
	_ = require('lodash'),
	events = require('events'),
	Logger = require('./logger'),
	EventEmitter = events.EventEmitter,
	grey = chalk.grey,
	green = chalk.green,
	cyan = chalk.cyan,
	red = chalk.red,
	yellow = chalk.yellow,
	dash = grey.bold('|'),
	defaultChalkEnabled = chalk.enabled,
	defaultColorizeArg;

util.inherits(ConsoleLogger, events.EventEmitter);

/**
 * Console logging functionality
 *
 * @param {Object} options - options
 */
function ConsoleLogger(options) {
	EventEmitter.call(this);
	this.options = options || {};
	// allow use to customize if they want the label or not
	this.prefix = this.options.prefix === undefined ? true : this.options.prefix;
	this.showcr = this.options.showcr === undefined ? true : this.options.showcr;
	this.showtab = this.options.showtab === undefined ? true : this.options.showtab;
	this.colorize = this.options.colorize === undefined ? checkColorize() : this.options.colorize;
	chalk.enabled = !!this.colorize;
	this.remapLevels();
}

/**
 * Check colorization
 */
function checkColorize() {
	if (defaultColorizeArg !== undefined) {
		return defaultColorizeArg;
	}
	// default is to only colorize if we have a TTY and not running on TTY
	defaultColorizeArg = process.stdout.isTTY && !process.env.TRAVIS;
	for (var c = 1; c < process.argv.length; c++) {
		var arg = process.argv[c];
		if (arg === '--colorize' || arg === '--color' || arg === '--colors') {
			defaultColorizeArg = true;
			break;
		} else if (arg === '--no-colors' || arg === '--no-color') {
			defaultColorizeArg = false;
			break;
		}
	}
	return defaultColorizeArg;
}

const CR_NC = '↩',
	CR = chalk.blue.bold(CR_NC),
	TAB_NC = '↠',
	TAB = chalk.blue.bold(TAB_NC);

/**
 * Remap levels
 */
ConsoleLogger.prototype.remapLevels = function remapLevels() {
	this.LevelMapping = {};
	this.LevelMapping[bunyan.TRACE] = {prefix: grey('TRACE '), color:grey, prefixNoColor: 'TRACE '};
	this.LevelMapping[bunyan.DEBUG] = {prefix: grey.bold('DEBUG '), color: cyan, prefixNoColor: 'DEBUG '};
	this.LevelMapping[bunyan.INFO] = {prefix: green('INFO  '), prefixNoColor: 'INFO  '};
	this.LevelMapping[bunyan.WARN] = {prefix: yellow('WARN  '), prefixNoColor: 'WARN  '};
	this.LevelMapping[bunyan.ERROR] = {prefix: red('ERROR '), prefixNoColor: 'ERROR '};
	this.LevelMapping[bunyan.FATAL] = {prefix: red.underline('FATAL') + ' ', color:red, prefixNoColor: 'FATAL '};
};

/**
 * called to write a formatted set of args (as an array) to
 * console.log. allows subclasses to override after formatting
 * has been applied
 *
 * @param  {Object} args - args
 */
ConsoleLogger.prototype.writeFormatted = function (args) {
	console.log.apply(console, args);
};

/**
 * Write
 *
 * @param  {Object} record - record
 */
ConsoleLogger.prototype.write = function (record) {
	if (!record.ignore) {

		// this should only happen during unit testing
		if (defaultColorizeArg === undefined) {
			this.colorize = checkColorize();
		}

		var level = this.LevelMapping[record.level],
			color = this.colorize,
			args = [];

		if (this.prefix) {
			args.push(color ? level.prefix : level.prefixNoColor);
			args.push(color ? dash : '|');
		}
		var msg = record.msg;
		if (!msg || msg === ' ') {
			// this is the case where you send in an object as the only argument
			var fields = _.omit(record, 'name', 'prefix', 'showtab', 'showcr', 'hostname', 'pid', 'level', 'msg', 'time', 'v', 'problemLogName');
			if (_.isEmpty(fields)) {
				msg = '';
			} else {
				msg = util.inspect(fields, {colors:true});
			}
		}
		if (this.showcr && msg.indexOf('\n') > 0) {
			var lines = msg.split(/\n/),
				cr = color ? CR : CR_NC;
			msg = lines.join(cr + '\n') + (lines.length > 1 ? cr : '');
		}
		if (this.showtab && msg.indexOf('\t') > 0) {
			var tlines = msg.split(/\t/),
				tab = color ? TAB : TAB_NC;
			msg = tlines.join('\t' + tab);
		}
		if (color) {
			args.push(level.color && level.color(msg) || msg);
		} else {
			args.push(Logger.stripColors(msg));
		}
		this.writeFormatted(args);
	}
	return true;
};

/**
 * End
 */
ConsoleLogger.prototype.end = function () {
	if (arguments.length > 0) {
		this.write.apply(this, Array.prototype.slice.call(arguments));
	}
	this.destroySoon();
};

/**
 * Destroy
 */
ConsoleLogger.prototype.destroy = function () {
	this.emit('close');
};

/**
 * Destroy soon
 */
ConsoleLogger.prototype.destroySoon = function () {
	this.destroy();
};

/**
 * Reset colorization
 */
ConsoleLogger.resetColorize = function () {
	defaultColorizeArg = undefined;
	chalk.enabled = chalk.supportsColor;
};

module.exports = ConsoleLogger;
<|endoftext|>


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

var mediaTypeRe = /^\s*([^;]+)/i;

function getMediaType( contentType ) {
    return contentType.match( mediaTypeRe )[0].toLowerCase();
}

function getMediaTypeFromSpecReq( specReq ) {
    if( specReq && specReq.headers ) {
        for( var i = 0; i < specReq.headers.length; i++ ) {
            if(/content\-type/i.test( specReq.headers[i].name )) {
                return getMediaType( specReq.headers[i].value );
            }
        }
    }
    return null;
}

function getMediaTypeFromHttpReq( httpReq ) {
    if( 'content-type' in httpReq.headers ) {
        return getMediaType( httpReq.headers['content-type'] );
    }
    return null;
}

function isBodyEqual( httpReq, specReq, contentType ) {
    if (!specReq && !httpReq.body){
        return true;
    }

    if (/json/i.test(contentType)){
        return lodash.isEqual(JSON.parse(httpReq.body), JSON.parse(specReq.body));
    } else {
        return httpReq.body === specReq.body;
    }
}

function hasHeaders( httpReq, specReq ){
    if (!specReq || !specReq.headers){
        return true;
    }

    for(var i=0,length=specReq.headers.length;i<length;i++){
        var header=specReq.headers[i];

        if(!httpReq.headers.hasOwnProperty(header.name) || httpReq.headers[header.name] !== header.value){
            return false;
        }
    }

    return true;
}

exports.matches = function( httpReq, specReq ) {
    var httpMediaType = getMediaTypeFromHttpReq( httpReq );
    var specMediaType = getMediaTypeFromSpecReq( specReq );
    if ( httpMediaType === specMediaType ) {
        if ( !hasHeaders(httpReq ,specReq ) ){
            console.warn('Skip. Different headers');
            return false;
        }

        if ( isBodyEqual(httpReq, specReq, httpMediaType ) ) {
            return true;
        } else {
            console.warn('Skip. Different body');
            return false;
        }

    } else {
        console.warn('Skip. Different content-types ', httpMediaType, " !== ", specMediaType );
        return false;
    }

};
<commit_msg>change for loop to every method and logging via console to custom logger method<commit_after>var lodash = require('lodash');

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

var mediaTypeRe = /^\s*([^;]+)/i;

function getMediaType( contentType ) {
    return contentType.match( mediaTypeRe )[0].toLowerCase();
}

function getMediaTypeFromSpecReq( specReq ) {
    if( specReq && specReq.headers ) {
        for( var i = 0; i < specReq.headers.length; i++ ) {
            if(/content\-type/i.test( specReq.headers[i].name )) {
                return getMediaType( specReq.headers[i].value );
            }
        }
    }
    return null;
}

function getMediaTypeFromHttpReq( httpReq ) {
    if( 'content-type' in httpReq.headers ) {
        return getMediaType( httpReq.headers['content-type'] );
    }
    return null;
}

function isBodyEqual( httpReq, specReq, contentType ) {
    if (!specReq && !httpReq.body){
        return true;
    }

    if (/json/i.test(contentType)){
        return lodash.isEqual(JSON.parse(httpReq.body), JSON.parse(specReq.body));
    } else {
        return httpReq.body === specReq.body;
    }
}

function hasHeaders( httpReq, specReq ){
    if (!specReq || !specReq.headers){
        return true;
    }

    function containsHeader( header ){
        if(!httpReq.headers.hasOwnProperty( header.name ) || httpReq.headers[header.name] !== header.value){
            return false;
        }

        return true;
    }

    return specReq.headers.every(containsHeader);

}

exports.matches = function( httpReq, specReq ) {
    var httpMediaType = getMediaTypeFromHttpReq( httpReq );
    var specMediaType = getMediaTypeFromSpecReq( specReq );
    if ( httpMediaType === specMediaType ) {
        if ( !hasHeaders( httpReq, specReq ) ){
            logger.log('[WARN]'.red, 'Skip. Different headers');
            return false;
        }

        if ( isBodyEqual( httpReq, specReq, httpMediaType ) ) {
            return true;
        } else {
            logger.log('[WARN]'.red, 'Skip. Different body');
            return false;
        }

    } else {
        logger.log('[WARN]'.red, 'Skip. Different content-types ', httpMediaType, " !== ", specMediaType );
        return false;
    }

};
<|endoftext|>


<commit_before>var videoSystem = angular.module("VideoSystem", ['ngRoute']);

videoSystem.config(['$routeProvider', function ($routeProvider) {
	$routeProvider
		.when('/home', {
			templateUrl : 'homeView/home.html',
			controller : 'homeView'
		})
		.when('/upload', {
			templateUrl : 'uploadVideo/upload.html',
			controller : 'uploadController'
		})
		.otherwise({
			redirectTo : '/home'
		})
}]);

videoSystem.service('$videoFile', function () {
	var listOfVideos = [];

	var addVideo = function(newVideo) {
		listOfVideos.push(newVideo);
	};

	var getVideo = function(){
		return listOfVideos;
	};

	addVideo({
		title : 'Course introduction',
		pictureUrl : 'data:image/jpeg;base64,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',
		length : '3:32',
		category : 'IT',
		subscribers : 3,
		date : new Date(2014, 12, 15),
		haveSubtitles : false,
		comments : [
			{
				username: 'Pesho Peshev',
				content: 'Congratulations Nakov',
				date: new Date(2014, 12, 15, 12, 30, 0),
				likes: 3,
				websiteUrl: 'http://pesho.com/'
			}
		]
	});

	return {
		addVideo: addVideo,
		getVideo: getVideo
	};
});

<commit_msg>remove service<commit_after>var videoSystem = angular.module("VideoSystem", ['ngRoute']);

videoSystem.config(['$routeProvider', function ($routeProvider) {
	$routeProvider
		.when('/home', {
			templateUrl : 'homeView/home.html',
			controller : 'homeView'
		})
		.when('/upload', {
			templateUrl : 'uploadVideo/upload.html',
			controller : 'uploadController'
		})
		.otherwise({
			redirectTo : '/home'
		})
}]);

<|endoftext|>


<commit_before>/**
 * Contexts wrap the entire Littlest architecture through a single entry point.
 * This solves a few challenges at once:
 *
 * - Debugging is made easier because all internal traffic can be viewed in
 *   one place.
 * - De- and Rehydration of state can be accomplished at once.
 * - Both behaviour and state can be made individual by layering individual
 *   concerns on an existing Context, creating a new Context.
 */
var util = require('util');
var dispatcher = require('littlest-dispatcher');

/**
 * Creates a new instance of Context with the provided `options`.
 *
 * @param {Object} options
 */
function Context(options) {
  if (!(this instanceof Context)) {
    return new Context(options);
  }

  options = options || {};

  this.logger = this.logger || options.logger || null;

  this.dispatcher = dispatcher.createDispatcher({ logger: this.logger });
  this.actions = {};
  this.stores = {};

  this._cloneSteps = options._cloneSteps || [];
}
Context.createContext = Context;

/**
 * Creates and returns a new Context inheriting all Actions and Stores from
 * this parent Context. Requests and state updates made within the child
 * Context will be confined to the child, adn lost whenever the child is
 * destroyed.
 *
 * If provided, `options` will override any options this Context would
 * otherwise have provided (or not) to the child.
 */
Context.prototype.getChild = function getChild(options) {
  var opts = {};

  util._extend(opts, this);
  util._extend(opts, options);

  var context = new Context(opts);

  context._cloneFrom(this);

  return context;
};

/**
 * Creates a new, named Action associated with this Context. Modules may
 * perform the Action through this Context, and the Context will be made
 * available as `this` within the function body.
 *
 * Returns the Context for cascading.
 */
Context.prototype.createAction = function createAction(name, fn) {
  function step(parent) {
    this.actions[name] = this.dispatcher.createAction(name, fn);
    return this.actions[name];
  }

  return this._addAndRunStep(step);
};

/**
 * Performs the named Action, passing in `params` as the first and only
 * argument to the originally-defined function.
 */
Context.prototype.performAction = function performAction(name, params) {
  return this.actions[name].call(this, params);
};

/**
 * Creates a new, named Store associated with this Context. Modules may access
 * the Store through this Context, and the Store can subscribe to updates
 * through the Context's shared Dispatcher.
 *
 * Returns the Context for cascading.
 */
Context.prototype.createStore = function createStore(name, props) {
  function step(parent) {
    var ctx = this;

    ctx.stores[name] = ctx.dispatcher.createStore(parent && parent.stores[name].toObject() || props);

    // TODO(schoon) - Find a better way to persist event handlers to child
    // Contexts.
    ctx.stores[name].handle = function handle(eventName, fn) {
      return ctx._addAndRunStep(function () {
        return dispatcher.Store.prototype.handle.call(this.stores[name], eventName, fn);
      });
    };

    return ctx.stores[name];
  }

  return this._addAndRunStep(step);
};

/**
 * Gets the named Store.
 */
Context.prototype.getStore = function getStore(name) {
  return this.stores[name];
};

/**
 * Serializes the Context and all associated Stores as JSON.
 */
Context.prototype.toJSON = function toJSON() {
  return {
    stores: this.stores
  };
};

/**
 * Deserializes the passed-in Object into the Context and its associated Stores.
 */
Context.prototype.fromObject = function fromObject(obj) {
  var self = this;

  if (!obj || !obj.stores) {
    return;
  }

  Object.keys(self.stores)
    .forEach(function (key) {
      self.stores[key].fromObject(obj.stores[key]);
    });
};

/**
 * Internal helper to add `step` functions to run when setting up a child
 * Context.
 */
Context.prototype._addAndRunStep = function _addAndRunStep(step) {
  this._cloneSteps.push(step);
  return step.call(this);
};

/**
 * Internal helper to set up a child Context from the steps in the parent.
 */
Context.prototype._cloneFrom = function _cloneFrom(parent) {
  var self = this;

  self._cloneSteps.forEach(function (step) {
    step.call(self, parent);
  });

  return self;
};

/*!
 * Export `Context`.
 */
module.exports = Context;
<commit_msg>Context: Better error for missing Actions.<commit_after>/**
 * Contexts wrap the entire Littlest architecture through a single entry point.
 * This solves a few challenges at once:
 *
 * - Debugging is made easier because all internal traffic can be viewed in
 *   one place.
 * - De- and Rehydration of state can be accomplished at once.
 * - Both behaviour and state can be made individual by layering individual
 *   concerns on an existing Context, creating a new Context.
 */
var util = require('util');
var dispatcher = require('littlest-dispatcher');
var when = require('when');

/**
 * Creates a new instance of Context with the provided `options`.
 *
 * @param {Object} options
 */
function Context(options) {
  if (!(this instanceof Context)) {
    return new Context(options);
  }

  options = options || {};

  this.logger = this.logger || options.logger || null;

  this.dispatcher = dispatcher.createDispatcher({ logger: this.logger });
  this.actions = {};
  this.stores = {};

  this._cloneSteps = options._cloneSteps || [];
}
Context.createContext = Context;

/**
 * Creates and returns a new Context inheriting all Actions and Stores from
 * this parent Context. Requests and state updates made within the child
 * Context will be confined to the child, adn lost whenever the child is
 * destroyed.
 *
 * If provided, `options` will override any options this Context would
 * otherwise have provided (or not) to the child.
 */
Context.prototype.getChild = function getChild(options) {
  var opts = {};

  util._extend(opts, this);
  util._extend(opts, options);

  var context = new Context(opts);

  context._cloneFrom(this);

  return context;
};

/**
 * Creates a new, named Action associated with this Context. Modules may
 * perform the Action through this Context, and the Context will be made
 * available as `this` within the function body.
 *
 * Returns the Context for cascading.
 */
Context.prototype.createAction = function createAction(name, fn) {
  function step(parent) {
    this.actions[name] = this.dispatcher.createAction(name, fn);
    return this.actions[name];
  }

  return this._addAndRunStep(step);
};

/**
 * Performs the named Action, passing in `params` as the first and only
 * argument to the originally-defined function.
 */
Context.prototype.performAction = function performAction(name, params) {
  var fn = this.actions[name];

  if (!fn) {
    return when.reject(new Error('Could not find action \'' + name + '\''));
  }

  return fn.call(this, params);
};

/**
 * Creates a new, named Store associated with this Context. Modules may access
 * the Store through this Context, and the Store can subscribe to updates
 * through the Context's shared Dispatcher.
 *
 * Returns the Context for cascading.
 */
Context.prototype.createStore = function createStore(name, props) {
  function step(parent) {
    var ctx = this;

    ctx.stores[name] = ctx.dispatcher.createStore(parent && parent.stores[name].toObject() || props);

    // TODO(schoon) - Find a better way to persist event handlers to child
    // Contexts.
    ctx.stores[name].handle = function handle(eventName, fn) {
      return ctx._addAndRunStep(function () {
        return dispatcher.Store.prototype.handle.call(this.stores[name], eventName, fn);
      });
    };

    return ctx.stores[name];
  }

  return this._addAndRunStep(step);
};

/**
 * Gets the named Store.
 */
Context.prototype.getStore = function getStore(name) {
  return this.stores[name];
};

/**
 * Serializes the Context and all associated Stores as JSON.
 */
Context.prototype.toJSON = function toJSON() {
  return {
    stores: this.stores
  };
};

/**
 * Deserializes the passed-in Object into the Context and its associated Stores.
 */
Context.prototype.fromObject = function fromObject(obj) {
  var self = this;

  if (!obj || !obj.stores) {
    return;
  }

  Object.keys(self.stores)
    .forEach(function (key) {
      self.stores[key].fromObject(obj.stores[key]);
    });
};

/**
 * Internal helper to add `step` functions to run when setting up a child
 * Context.
 */
Context.prototype._addAndRunStep = function _addAndRunStep(step) {
  this._cloneSteps.push(step);
  return step.call(this);
};

/**
 * Internal helper to set up a child Context from the steps in the parent.
 */
Context.prototype._cloneFrom = function _cloneFrom(parent) {
  var self = this;

  self._cloneSteps.forEach(function (step) {
    step.call(self, parent);
  });

  return self;
};

/*!
 * Export `Context`.
 */
module.exports = Context;
<|endoftext|>