Node.js scheduling system powered by Redis Keyspace Notifications
@param options {Object}
@constructor
198315
function(options){
  var _this = this;

  this.handlers = {};

  if(!options){
    options = {};
  }

  if(!options.redis){
    options.redis = {};
  }

  this.options = {
    id: options.id || shortId.generate(),
    autoConfig: options.autoConfig ||  false,
    dataExpiry: options.dataExpiry || 30,
    redis: {
      port: options.redis.port || 6379,
      host: options.redis.host || '127.0.0.1',
      redis: options.redis.options || {}
    }
  };

  //Create redis clients
  this.redisSub = redis.createClient(this.options.redis.port, this.options.redis.host, this.options.redis.options);
  this.redis = redis.createClient(this.options.redis.port, this.options.redis.host, this.options.redis.options);
  this.redisInstant = redis.createClient(this.options.redis.port, this.options.redis.host, this.options.redis.options);

  //Attempt auto config
  if(this.options.autoConfig){
    var config = '';
    this.redis.config("GET", "notify-keyspace-events", function(err, data){
      if(data){
        config = data[1];
      }
      if(config.indexOf('E') == -1){
        config += 'E'
      }
      if(config.indexOf('x') == -1){
        config += 'x'
      }
      _this.redis.config("SET", "notify-keyspace-events", config)
    });
  }

  //Listen to key expiry notifications and handle events
  var expiryListener = new RedisEvent(this.redisSub, 'expired', /redular:(.+):(.+):(.+)/);
  expiryListener.defineHandler(function(key){
    var clientId = key[1];
    var eventName = key[2];
    var eventId = key[3];

    _this.redis.get('redular-data:' + clientId + ':' + eventName + ':' + eventId, function(err, data){
      if(data){
        data = JSON.parse(data);
      }
      if(clientId == _this.options.id || clientId == 'global'){
        _this.handleEvent(eventName, data);
      }
    });
  });

  //Listen to instant events and handle them
  this.redisInstant.subscribe('redular:instant');
  this.redisInstant.on('message', function(channel, message){
    try{
      var parsedMessage = JSON.parse(message);
    } catch (e){
      throw e;
    }
    if(parsedMessage.client == _this.options.id || parsedMessage.client == 'global') {
      _this.handleEvent(parsedMessage.event, parsedMessage.data);
    }
  });

}
1364824
function Cron (pattern, options, fn) {
		var self = this;
		
		// Optional "new" keyword
		if( !(this instanceof Cron) ) {
			return new Cron(pattern, options, fn);
		}

		self.pattern = new CronPattern(pattern);

		self.schedulerDefaults = {
			stopAt:     Infinity,
			maxRuns:    Infinity,
			kill:       false
		};

		// Make options optional
		if( typeof options === "function" ) {
			fn = options;
			options = {};
		}

		// Store and validate options
		self.opts = self.validateOpts(options || {});

		// Determine what to return, default is self
		if( fn === void 0 ) {
			// Normal initialization, return self
			return self;

		} else {
			// Shorthand schedule requested, return job
			return this.schedule(options, fn);

		}

	}
1113412
function $$core$$ToDateTimeOptions (options, required, defaults) {
        // 1. If options is undefined, then let options be null, else let options be
        //    ToObject(options).
        if (options === undefined)
            options = null;

        else {
            // (#12) options needs to be a Record, but it also needs to inherit properties
            var opt2 = $$core$$toObject(options);
            options = new $$core$$Record();

            for (var k in opt2)
                options[k] = opt2[k];
        }

        var
        // 2. Let create be the standard built-in function object defined in ES5, 15.2.3.5.
            create = $$core$$objCreate,

        // 3. Let options be the result of calling the [[Call]] internal method of create with
        //    undefined as the this value and an argument list containing the single item
        //    options.
            options = create(options),

        // 4. Let needDefaults be true.
            needDefaults = true;

        // 5. If required is "date" or "any", then
        if (required === 'date' || required === 'any') {
            // a. For each of the property names "weekday", "year", "month", "day":
                // i. If the result of calling the [[Get]] internal method of options with the
                //    property name is not undefined, then let needDefaults be false.
            if (options.weekday !== undefined || options.year !== undefined
                    || options.month !== undefined || options.day !== undefined)
                needDefaults = false;
        }

        // 6. If required is "time" or "any", then
        if (required === 'time' || required === 'any') {
            // a. For each of the property names "hour", "minute", "second":
                // i. If the result of calling the [[Get]] internal method of options with the
                //    property name is not undefined, then let needDefaults be false.
            if (options.hour !== undefined || options.minute !== undefined || options.second !== undefined)
                    needDefaults = false;
        }

        // 7. If needDefaults is true and defaults is either "date" or "all", then
        if (needDefaults && (defaults === 'date' || defaults === 'all'))
            // a. For each of the property names "year", "month", "day":
                // i. Call the [[DefineOwnProperty]] internal method of options with the
                //    property name, Property Descriptor {[[Value]]: "numeric", [[Writable]]:
                //    true, [[Enumerable]]: true, [[Configurable]]: true}, and false.
            options.year = options.month = options.day = 'numeric';

        // 8. If needDefaults is true and defaults is either "time" or "all", then
        if (needDefaults && (defaults === 'time' || defaults === 'all'))
            // a. For each of the property names "hour", "minute", "second":
                // i. Call the [[DefineOwnProperty]] internal method of options with the
                //    property name, Property Descriptor {[[Value]]: "numeric", [[Writable]]:
                //    true, [[Enumerable]]: true, [[Configurable]]: true}, and false.
            options.hour = options.minute = options.second = 'numeric';

        // 9. Return options.
        return options;
    }
741284
function RedisIssueDao(client) {
	this.client = client;
	this.prefix = "omega:";

	console.log('storing issues in: redis://' + this.client.host + ':' + this.client.port + '/' + this.prefix);
}
1017463
function RedisStore(options) {
  if (!(this instanceof RedisStore)) {
    return new RedisStore(options);
  }
  var self = this,
      type,
      autoCast,
      delimiter = ':',
      client,
      pw,
      db;
  if (!options) {
    options = {};
  }
  // Set the delimiter property
  type = typeof options.delimiter;
  if ((type === 'string' && options.delimiter) || type === 'number') {
    delimiter = options.delimiter;
  }
  Object.defineProperty(this, 'delimiter', {
    value: delimiter,
    writable: false
  });
  // Set the automatic cast property
  autoCast = options.autoCast !== false;
  Object.defineProperty(this, 'autoCast', {
    value: autoCast,
    writable: false
  });
  // Create the Redis connection
  if (options.client) {
    client = options.client;
  } else {
    client = redis.createClient(options.port, options.host, options.options);
    pw = options.pw || options.pass || options.password;
    db = options.db || options.database;
    if (typeof db !== 'number') {
      if (typeof db === 'string') {
        db = parseInt(db, 10);
      }
    }
    if (db && typeof db !== 'number') {
      db = parseInt(db, 10);
    }
    if (!(typeof db === 'number' && !isNaN(db))) {
      db = null;
    }
    if (pw) {
      client.auth(pw, function() {
        if (typeof db === 'number' && !isNaN(db)) {
          client.select(db);
        }
      });
    } else if (typeof db === 'number' && !isNaN(db)) {
      client.select(db);
    }
  }
  Object.defineProperty(this, 'client', {
    value: client,
    writable: false
  });
  EventEmitter.call(this);
  ['ready', 'connect', 'end'].forEach(function(name) {
    client.on(name, function() {
      self.emit(name);
    });
  });
  client.on('error', function(error) {
    self.emit('error', error);
  });
}
1195894
function Scheduler(async) {
		this._async = async;
		this._running = false;

		this._queue = this;
		this._queueLen = 0;
		this._afterQueue = {};
		this._afterQueueLen = 0;

		var self = this;
		this.drain = function() {
			self._drain();
		};
	}
298540
function saveNotifications(options) {
            const defaults = {
                    dismissible: true,
                    location: 'bottom',
                    status: 'alert',
                    id: ObjectId.generate()
                },
                overrides = {
                    seen: false,
                    addedAt: moment().toDate()
                },
                notificationsToCheck = options.data.notifications;
            let addedNotifications = [];

            return _private.fetchAllNotifications()
                .then((allNotifications) => {
                    notificationsToCheck.forEach((notification) => {
                        const isDuplicate = allNotifications.find((n) => {
                            return n.id === notification.id;
                        });

                        if (!isDuplicate) {
                            addedNotifications.push(merge({}, defaults, notification, overrides));
                        }
                    });

                    const hasReleaseNotification = notificationsToCheck.find((notification) => {
                        return !notification.custom;
                    });

                    // CASE: remove any existing release notifications if a new release notification comes in
                    if (hasReleaseNotification) {
                        remove(allNotifications, (el) => {
                            return !el.custom;
                        });
                    }

                    // CASE: nothing to add, skip
                    if (!addedNotifications.length) {
                        return Promise.resolve();
                    }

                    const addedReleaseNotifications = addedNotifications.filter((notification) => {
                        return !notification.custom;
                    });

                    // CASE: only latest release notification
                    if (addedReleaseNotifications.length > 1) {
                        addedNotifications = addedNotifications.filter((notification) => {
                            return notification.custom;
                        });
                        addedNotifications.push(orderBy(addedReleaseNotifications, 'created_at', 'desc')[0]);
                    }

                    return SettingsAPI.edit({
                        settings: [{
                            key: 'notifications',
                            value: allNotifications.concat(addedNotifications)
                        }]
                    }, internalContext);
                })
                .then(() => {
                    return _private.publicResponse(addedNotifications);
                });
        }
571996
function PushManager(node, options) {

        /**
         * ### PushManager.node
         *
         * Reference to a nodegame-client instance
         */
        this.node = node;

        /**
         * ### PushManager.timer
         *
         * The timer object that will fire the checking of clients
         *
         * The timer will be created only if needed.
         *
         * @see PushManager.startTimer
         */
        this.timer = null;

        /**
         * ### PushManager.offsetWaitTime
         *
         * Time that is always added to the timer value of
         *
         * @see PushManager.startTimer
         */
        this.offsetWaitTime = PushManager.offsetWaitTime;

        /**
         * ### PushManager.replyWaitTime
         *
         * Time to wait to get a reply from a pushed client
         *
         * @see PushManager.pushGame
         */
        this.replyWaitTime = PushManager.replyWaitTime;

        /**
         * ### PushManager.checkPushWaitTime
         *
         * Time to wait to check if a pushed client updated its state
         *
         * @see PushManager.pushGame
         */
        this.checkPushWaitTime = PushManager.checkPushWaitTime;

        this.init(options);
    }
573411
function(keys){

  console.log('\nInitializing keys in Redis...\n')

  keys.forEach(function(el,i){

    client.get(el.key, function(e,d){

      if(e) {
        console.log("Error trying to get %s ", el.key)
        return console.error(e)
      }

      // checking for falsey values only is a bad idea
      if(typeof d === 'undefined'){

        console.log("Not OK trying to get %s ", el.key)

        client.set(el.key, el.initialValue, function(e,d){
          if(e) {
            console.log("Error trying to set %s ", el.key)
            return console.error(e)
          }
          if(d !== 'OK') {
            console.log("Not OK trying to set %s ", el.key)
            return console.warn(el.key + " was not set.")
          }
          if(d === 'OK') {
            console.log("OK setting %s ", el.key)
            client.get(el.key, function(e,d){
             console.log(d) 
            })
          }

        }) // end set.
      }

      console.log("The value for key %s is %s", el.key.yellow, d.green)

    }) // end get

  })
}
66856
function SSH(options) {
	this.options = options || {};
	console.assert(this.options.hostname, "Hostname required!");

	this.debug = !!options.debug;
	this.listener = new Listener({
		debug: options.debug
	});
}
962732
function startAllConnections() {
  try {
    myUtils.validateConfig();
  }
  catch(e) {
    console.error(e.message);
    process.exit(2);
  }

  // redefine keys method before connections are started
  if (config.get('redis.useScan')) {
    console.log('Using scan instead of keys');
    Object.defineProperty(Redis.prototype, 'keys', {
      value: function(pattern, cb) {
        let keys = [];
        let that = this;
        let scanCB = function(err, res) {
          if (err) {
            if (typeof cb === 'function') cb(err);
            else {
              console.log('ERROR in redefined "keys" function to use "scan" instead without callback: ' + JSON.stringify(err));
            }
          }
          else {
            let count = res[0], curKeys = res[1];
            console.log("scanning: " + count + ": " + curKeys.length);
            keys = keys.concat(curKeys);
            if (Number(count) === 0) {
              if (typeof cb === 'function') cb(null, keys);
              else {
                console.log('ERROR in redefined "keys" function to use "scan" instead - no callback given!');
              }
            }
            else {
              that.scan(count, 'MATCH', pattern, 'COUNT', config.get('redis.scanCount'), scanCB);
            }
          }
        };
        return this.scan(0, 'MATCH', pattern, 'COUNT', config.get('redis.scanCount'), scanCB);
      }
    });
  }

  // first default connections from config object
  // second connection from cli params (redis-host, redis-port, ...)
  startDefaultConnections(config.connections, function (err) {
    if (err) {
      console.log(err);
      process.exit();
    }
    let db = parseInt(args['redis-db']);
    if (isNaN(db)) {
        db = 0;
    }

    let client;
    if (args['sentinel-host'] || args['sentinels'] || args['redis-host'] || args['redis-port'] || args['redis-socket'] || args['redis-password']) {
      let newDefault = {
        "label": config.get('redis.defaultLabel'),
        "dbIndex": db,
        "password": args['redis-password'] || '',
        "connectionName": config.get('redis.connectionName')
      };

      if (args['redis-socket']) {
        newDefault.path = args['redis-socket'];
      }
      else {
        newDefault.host = args['redis-host'] || "localhost";
        newDefault.port = args['redis-port'] || "6379";
        newDefault.sentinel_name = args['sentinel-name'];
        if (args['sentinels']) {
          newDefault.sentinels = myUtils.parseRedisSentinel('--sentinels', args['sentinels']);
        }
        else if (args['sentinel-host']) {
          newDefault.sentinels = myUtils.parseRedisSentinel( '--sentinel-host or --sentinel-port',
            args['sentinel-host'] + ':' + args['sentinel-port']);
        }
      }

      if (args['redis-tls']) {
        newDefault.tls = {};
      }

      if (!myUtils.containsConnection(config.connections, newDefault)) {
        client = myUtils.createRedisClient(newDefault);
        redisConnections.push(client);
        config.connections.push(newDefault);
        if (!config.get('noSave')) {
          myUtils.saveConnections(config,function (err) {
            if (err) {
              console.log("Problem saving connection config.");
              console.error(err);
            }
          });
        }
        setUpConnection(client, db);
      }
    } else if (config.connections.length === 0) {
      // fallback to localhost if nothing else configured
      client = myUtils.createRedisClient({label: config.get('redis.defaultLabel')});
      redisConnections.push(client);
      setUpConnection(client, db);
    }

    return startWebApp();
  });

  // wait a bit before starting browser to let http server start
  if (args['open']) {
    setTimeout(function() {
      let address = '127.0.0.1';
      if (config.get('server.address') !== '0.0.0.0' && config.get('server.address') !== '::') {
        address = config.get('server.address');
      }
      require('opener')('http://' + address + ':' + config.get('server.port'));
    }, 1000);
  }
}
1169077
function(namespace, ressource, args, options) {
            var d = Q.defer();
            var namespace_configs = _.extend({}, Resources.namespaces[namespace] || {}, options || {});
            var loader = namespace_configs.loader || namespace;
            
            if (Resources.loaders[loader] == null) {
                logging.error("Loader doesn't exists ", loader, "namespace=",namespace);
                d.reject();
                return d.promise;
            }
            Resources.loaders[loader](ressource, d, args, namespace_configs);
            return d.promise;
        }
587034
function RedisPool(opts) {

    if (!(this instanceof RedisPool)) {
        return new RedisPool(opts);
    }

    EventEmitter.call(this);

    opts = opts || {};
    var defaults = {
        host: '127.0.0.1',
        port: '6379',
        max: 50,
        idleTimeoutMillis: 10000,
        reapIntervalMillis: 1000,
        noReadyCheck: false,
        returnToHead: false,
        unwatchOnRelease: true,
        name: 'default',
        log: false,
        slowPool: {
            log: false,
            elapsedThreshold: 25
        },
        emitter: {
            statusInterval: 60000
        },
        commands: []
    };

    this.options = _.defaults(opts, defaults);
    this.pools = {};
    this.elapsedThreshold = this.options.slowPool.elapsedThreshold;

    // add custom Redis commands
    if (this.options.commands && this.options.commands.length) {
        this.options.commands.forEach(function(newCommand) {
            redis.add_command(newCommand);
        });
    }

    var self = this;
    setInterval(function() {
        Object.keys(self.pools).forEach(function(poolKey) {
            var pool = self.pools[poolKey];
            self.emit('status', {
                name: self.options.name,
                db: poolKey,
                count: pool.getPoolSize(),
                unused: pool.availableObjectsCount(),
                waiting:  pool.waitingClientsCount()
            });
        });
    }, this.options.emitter.statusInterval);
}
1327475
function(options) {
      if (any(hook('running'), haveStopped)) return this
      if (options) extend(this.options, options)
      this.start = Number(new Date)
      each(this.suites, function(suite) { JSpec.runSuite(suite) })
      return this
    }
665516
function(schedule, useSeconds) {
    var textParts = [];

    // A later.js schedules contains no member for time units where an asterisk is used,
    // but schedules that means the same (e.g 0/1 is essentially the same as *) are
    // returned with populated members.
    // Remove all members that are fully populated to reduce complexity of code
    removeFromSchedule( schedule, 'M', 12 );
    removeFromSchedule( schedule, 'D', 31 );
    removeFromSchedule( schedule, 'd', 7 );
    removeFromSchedule( schedule, 'h', 24 );
    removeFromSchedule( schedule, 'm', 60 );
    removeFromSchedule( schedule, 's', 60 );

    var everySecond = useSeconds && schedule['s'] === undefined,
        everyMinute = schedule['m'] === undefined,
        everyHour = schedule['h'] === undefined
        everyWeekday = schedule['d'] === undefined
        everyDayInMonth = schedule['D'] === undefined,
        everyMonth = schedule['M'] === undefined;

    var oneOrTwoSecondsPerMinute = schedule['s'] && schedule['s'].length <= 2;
    var oneOrTwoMinutesPerHour = schedule['m'] && schedule['m'].length <= 2;
    var oneOrTwoHoursPerDay = schedule['h'] && schedule['h'].length <= 2;
    var onlySpecificDaysOfMonth = schedule['D'] && schedule['D'].length !== 31;
    if ( oneOrTwoHoursPerDay && oneOrTwoMinutesPerHour && oneOrTwoSecondsPerMinute ) {
      // If there are only one or two specified values for
      // hour or minute, print them in HH:MM format, or HH:MM:ss if seconds are used
      // If seconds are not used, later.js returns one element for the seconds (set to zero)

      var hm = [];
      var m = moment();
      for (var i=0; i < schedule['h'].length; i++) {
        for (var j=0; j < schedule['m'].length; j++) {
          for (var k=0; k < schedule['s'].length; k++) {
            m.hour(schedule['h'][i]);
            m.minute(schedule['m'][j]);
            m.second(schedule['s'][k]);
            hm.push(m.format( useSeconds ? 'HH:mm:ss' : 'HH:mm'));
          }
        }
      }
      if (hm.length < 2) {
        textParts.push( hm[0] );
      } else {
        var last_val = hm.pop();
        textParts.push( hm.join(', ') + ' and ' + last_val );
      }
      if (everyWeekday && everyDayInMonth) {
        textParts.push('every day');
      }

    } else {
      var seconds = getSecondsTextParts(schedule['s']);
      var minutes = getMinutesTextParts(schedule['m']);
      var beginning = '';
      var end = '';

      textParts.push('Every');

      // Otherwise, list out every specified hour/minute value.
      var hasSpecificSeconds = schedule['s'] && (
          schedule['s'].length > 1 && schedule['s'].length < 60 ||
          schedule['s'].length === 1 && schedule['s'][0] !== 0 );
      if(hasSpecificSeconds) {
        beginning = seconds.beginning;
        end = seconds.text;
      }

      if(schedule['h']) { // runs only at specific hours
        if( hasSpecificSeconds ) {
          end += ' on the ';
        }
        if (schedule['m']) { // and only at specific minutes
          var hours = numberList(schedule['h']) + ' hour';
          if( !hasSpecificSeconds && isOnTheHour(schedule['m']) ) {
            textParts = [ 'On the' ];
            end += hours;
          } else {
            beginning = minutes.beginning;
            end += minutes.text + ' past the ' + hours;
          }
        } else { // specific hours, but every minute
          end += 'minute of ' + numberList(schedule['h']) + ' hour';
        }
      } else if(schedule['m']) { // every hour, but specific minutes
        beginning = minutes.beginning;
        end += minutes.text;
        if( !isOnTheHour(schedule['m']) && ( onlySpecificDaysOfMonth || schedule['d'] || schedule['M'] ) ) {
          end += ' past every hour';
        }
      } else if( !schedule['s'] && !schedule['m'] ) {
        beginning = seconds.beginning;
      } else if( !useSeconds || !hasSpecificSeconds) { // cronspec has "*" for both hour and minute
        beginning += minutes.beginning;
      }
      textParts.push(beginning);
      textParts.push(end);
    }

    if (onlySpecificDaysOfMonth) { // runs only on specific day(s) of month
      textParts.push('on the ' + numberList(schedule['D']));
      if (!schedule['M']) {
        textParts.push('of every month');
      }
    }

    if (schedule['d']) { // runs only on specific day(s) of week
      if (schedule['D']) {
        // if both day fields are specified, cron uses both; superuser.com/a/348372
        textParts.push('and every');
      } else {
        textParts.push('on');
      }
      textParts.push(dateList(schedule['d'], 'dow'));
    }

    if (schedule['M']) {
      if( schedule['M'].length === 12 ) {
        textParts.push('day of every month');
      } else {
        // runs only in specific months; put this output last
        textParts.push('in ' + dateList(schedule['M'], 'mon'));
      }
    }

    return textParts.filter(function(p) { return p; }).join(' ');
  }
476310
function Queue(options) {
  var self = this;

  typeforce({
    path: 'String',
    process: 'Function',
    throttle: 'Number',
    leveldown: 'Function'
  }, options);

  EventEmitter.call(this);

  this._options = extend(true, {}, options);
  this._process = options.process;
  this._throttle = options.throttle;
  this._strikes = ('strikes' in options) ? options.strikes : false;
  this._blockOnFail = options.blockOnFail;

  this._q = [];
  this._db = levelQuery(levelup(options.path, {
    db: options.leveldown,
    valueEncoding: 'json'
  }));

  this._db.query.use(jsonQueryEngine());

  indices.forEach(function(i) {
    self._db.ensureIndex(i);
  });

  this._deleting = {};
  promisifyDB(this._db);
  promisifyDB(this._db, 'query', { type: 'readable' })

  this._setupCount();
  this._load()
    .then(function() {
      if (options.autostart) self.start();
    });
}
1050517
function RedisProjectDao(client) {
	this.client = client;
	this.prefix = "omega:";

	console.log('storing projects in: redis://' + this.client.host + ':' + this.client.port + '/' + this.prefix);
}