Example #1
0
            _.each(schema, function (properties, index)
            {
                var realProperties = properties.index ? schema[properties.index] : properties;
                var realIndex = properties.index ? properties.index : index;

                if (options.all !== true && properties.type != 'object' && properties.type != 'array' &&
                    ((properties.invisible || (properties.toObject == 'never' && options.nevers !== false)
                    || (properties.toObject == 'changed' && (options.changed === false || !self.tracking.hasChanged(realIndex)))
                    || (properties.type == 'alias' && !options.alias === false)
                    || (properties.toObject == 'hasValue' &&
                        ((_.isUndefined(self[index]) && options.undefineds === false) ||
                        (_.isNull(self[index]) && options.nulls == false) ||
                        options.hasValues === false))
                    || (properties.toObject == 'always' && options.always === false)
                    || (properties.toObject == 'hasValue' && ((_.isNull(self[index]) && !options.nulls === false) || options.hasValues === false))) ))
                {
                    return;
                }

                // Fetch value from self[index] to route through getter.
                var value = self[index];
                if ((_.isNull(value) && !options.includeNull) || (_.isUndefined(value) && !options.includeUndefined))
                    return;

                // If value does not need to be cloned, place in index.
                if ((value === undefined || value === null)
                || properties.type !== 'object' && properties.type !== 'array' && properties.type !== 'date')
                {
                    getObj[index] = value;
                    // Clone Object
                } else if (properties.type === 'object')
                {
                    // Call toObject() method if defined (this allows us to return primitive objects instead of SchemaObjects).
                    if (_.isFunction(value.toObject))
                    {
                        getObj[index] = value.toObject(options);
                        // If is non-SchemaType object, shallow clone so that properties modification don't have an affect on the original object.
                    } else if (_.isObject(value))
                    {
                        getObj[index] = _.clone(value);
                    }

                    // Clone Array
                } else if (properties.type === 'array')
                {
                    // Built in method to clone array to native type
                    getObj[index] = value.toArray();

                    // Clone Date object.
                } else if (properties.type === 'date')
                {
                    // https://github.com/documentcloud/underscore/pull/863
                    // _.clone doesn't work on Date object.
                    getObj[index] = new Date(value.getTime());
                }
            });
Example #2
0
exports.sexp = function(obj) {
    if (_.isNull(obj) || _.isUndefined(obj)) {
        return 'nil';
    } else if (obj.toSexp) {
        return obj.toSexp();
    } else if (obj.lispType) {
        switch (obj.lispType) {
        case 'string': return exports.string(obj);
        case 'symbol': return exports.symbol(obj);
        case 'keyword': return exports.keyword(obj);
        case 'list': return exports.list(obj);
        case 'vector': return exports.vector(obj);
        } 
        throw new Error("Unrecognized lispType: " + util.inspect(obj.lispType));
    } else if (_.isString(obj)) {
        return exports.string(obj);
    } else if (_.isArray(obj))  {
        return exports.list(obj);
    } else if (_.isBoolean(obj)) {
        return exports.bool(obj);
    } else if (_.isNumber(obj)) {
        return exports.number(obj);
    } else {
        return exports.alist(obj);
    }
};
Example #3
0
	isHangoutPending: function() {
		if(_.isNull(this.get("hangout-pending"))) {
			return false;
		} else {
			return true;
		}
	},
Example #4
0
 client.saveMulti(postData, function(response){
   assert(!_.isUndefined(response));
   assert(!_.isUndefined(response.foobar));
   assert(_.isObject(response.foobar.error));
   assert(_.isNull(response.foobar.data));
   done();
 });
Example #5
0
 client.deleteMulti(['foobar'], function(response){
   assert(!_.isUndefined(response));
   assert(!_.isUndefined(response.foobar));
   assert(_.isObject(response.foobar.error));
   assert(_.isNull(response.foobar.data));
   done();
 });
Example #6
0
 url: function() {
     if(_.isNull(this.event) || _.isUndefined(this.event)) {
         return "session/permalink";
     } else {
         return this.event.url() + "/sessions";
     }
 }
Example #7
0
	email: function(string, match) {
		if(_.isNull(mc)) {
			winston.error("No mandrill client initialized, rejecting email.");
			return;
		}

		if(this.subscribers.length==0) {
			winston.error("No subscribers specified, rejecting email.");
			return;
		}

		var to = _.map(this.subscribers, function(sub) {
			return {email: sub};
		});

		// send the actual email.
		var message = {
			"text": string,
			"to": to,
			"subject": string.split("\n")[0],
			"preserve_recipient": false,
			"track_clicks": false,
			"from_email": "*****@*****.**",
			"from_name": "Dota 2 Results"
		};

		mc.messages.send({message:message}, function(result) {
			winston.info("Email sent, result: " + JSON.stringify(result));
		},
		function(e) {
			winston.warning("Error sending email: " + e.name + ": " + e.message);
		});
	},
 passport.deserializeUser(_.bind(function(id, done) {
     var user = this.db.users.get(id);
     if(_.isNull(user)) {
         logger.error("Tried to deserialize a user that did not exist; user:"******" does not exist."));
     } else {
         done(null, user);
     }
 }, this));
	initialize: function(args) {
		client_models.Session.prototype.initialize.call(this, args)
        _.bindAll(this, "onHangoutStarted", "onHangoutStopped")

		// make sure not to overwrite the built-in session-key
		// if we've loaded one through the db.
		if(_.isNull(this.get("session-key"))) {
			var shasum = crypto.createHash('sha256');
			shasum.update(this.get("id") + "");
			shasum.update(new Date().getTime() + "");
			this.set("session-key", shasum.digest('hex'));
		}

		// these listeners are for responding to messages from connected, currently
		// live hangouts. 

		// this particular event triggers when the server makes a change to this 
		// session's hangoutConnected field. It could be changing it in either direction,
		// so we need to disambiguate between starting and stopping by checking
		// the previous state.
		this.on("change:hangoutConnected", _.bind(function() {
			if(this.get("hangoutConnected")) {
                this.onHangoutStarted();
			} else {
                this.onHangoutStopped();
			}
		}, this));
        
        // now check to see if the hangout is already connected when we
        // initialize the serversession. This happens in situations where the
        // server crashes while hangouts are running, and the sockets
        // re-connect.
		if(this.get("hangoutConnected")) {
			logger.debug("server-models triggering hangout-started on load.");

            // this is an annoying hack. it turns out that
            // ServerSession.collection isn't set, because in the
            // initialization process sessions are created before they're
            // assigned to events.  This means that if we try to do a broadcast
            // (the second line of hangout-started event above) it will fail.
            // Instead, we wait until the collection is assigned to do this.
            // (this is triggered manually in Event.addSession, because
            // backbone doesn't seem to fire this event on its own)

            // if it's a permalink session, just start immediately. No need to
            // do the collection hack.
			if(this.get("isPermalinkSession")) {
				this.onHangoutStarted();
			} else {
				this.on("change:collection", _.bind(function() {
                    this.onHangoutStarted
				}, this));
			}
		}
    },
Example #10
0
			client.get(string, function(err, results) {
				if (err) callback(err)
			
				if (_.isNull(results))
				callback(err, [])
			//	client.get("1", function(err, results) {
			//		callback(err, Array.apply(null, Array(results.slice(0,-1).split(",").length)).map(function () { return 0}))
			//	})
				else
				callback(err, _.map(results.slice(0,-1).split(","), parseFloat))
			})
Example #11
0
 setTimeout(function() {
     if(!_.isNull(this.game)) {
         if(this.game.found.length > 0) {
             var winner = _.invert(this.game.scores)[_.max(this.game.scores)];
             event.reply('GAME OVER. THE WINNER IS ' + winner.toUpperCase() + ' WITH ' + this.game.scores[winner]);
             event.reply(this.game.solutions.length - this.game.found.length + ' solutions remained.'); 
         } else {
             event.reply('NO SOLUTIONS FOUND. YOU ARE ALL RUBBISH.');
         }
         this.game = null;
     }
 }.bind(this), 40000);
Example #12
0
Action.isMatch = function(info, action){

  action = Action.is(action) ? action : new Action(action)
  log('checking [%s]', action.name);

  var p = action.pattern;

  //info为空则视为不匹配
  if(_.isNull(info)){
    warn('info is null');
    return false;
  }

  //为空则视为通过匹配
  if(_.isNull(p) || _.isUndefined(p)){
    warn('pattern is null');
    return true;
  }

  //pattern为函数则直接使用
  if(_.isFunction(p)) return p.call(action, info);

  //非函数,则仅对文本消息支持正则式匹配
  if(info.type == 'text' && !_.isNull(info.text)){
    //正则式
    var regex = _.isRegExp(p) ? p : Utils.str2Regex(p);
    if(regex){
      //正则匹配, 把匹配组赋值给info.query
      info.query = info.text.match(regex);
      log('pattern is regex: %s', info.query);
      return info.query !== null ;
    }else{
      return info.text.indexOf(p) !== -1
    }
  }

  log('[%s] not match.', action.name);
  return false;
};
Example #13
0
    setHangoutUrl: function(url, user, hangoutId) {
        // User parameter is only used for logging.
        if(_.isNull(this.get("hangout-url"))) {
            this.set("hangout-url", url);
            this.set("hangout-id", hangoutId);

            // if we have a valid hangout url set, mark it as not pending anymore.
            var wasUnfarmed = this.get("hangout-pending");
            this.set("hangout-pending", null);

            // let anyone who was waiting for a hangout url from this session know
            // that we have a valid one now.
            this.trigger("hangout-url", url);

            // If no one is in this hangout, set a timeout to invalidate our
            // hangout URL if no one joins.
            if (this.getNumConnectedParticipants() == 0) {
                setTimeout(function() {
                    if (this.getNumConnectedParticipants() == 0) {
                        this.logAnalytics({action: "invalidate hangout url", url: url});
                        if (this.getNumConnectedParticipants() == 0) {
                            this.set("hangout-url", null);
                            this.set("hangout-id", null);
                        }
                    }
                }.bind(this), this.HANGOUT_CONNECTION_TIMEOUT);
            }
            this.logAnalytics({action: "set hangout url",
                               url: url,
                               wasUnfarmed: wasUnfarmed,
                               user: user});
        } else {
            // If someone tries to overwrite an active hangout URL with a
            // different one, return false, so we can warn them what the
            // correct URL is.
            if (this.get("hangout-url") != url) {
                this.logAnalytics({
                    action: "double-set hangout url denied",
                    attemptedUrl: url,
                    attemptedId: hangoutId,
                    existing: this.get("hangout-url"),
                    user: user
                })
                // XXX: Logging this as error to try to debug this in production.
                logger.error("Double-set hangout url", _.extend({
                    attemptedUrl: url}, this.toJSON()));
                return false;
            }
        }
        return true;
    },
Example #14
0
Rule.isMatch = function(info, rule){
  rule = Rule.is(rule) ? rule : new Rule(rule);
  log('checking [%s]', rule.name);

  var p = rule.pattern;

  //info为空则视为不匹配
  if(_.isNull(info)){
    warn('info is null');
    return false;
  }

  //为空则视为通过匹配
  if(_.isNull(p) || _.isUndefined(p)){
    warn('pattern is null');
    return true;
  }

  //pattern为函数则直接使用
  if(_.isFunction(p)) return p.call(rule, info);

  //非函数,则仅对文本消息支持正则式匹配
  if(info.type == 'text' && !_.isNull(info.text)){
    //正则式
    var regex = _.isRegExp(p) ? p : utils.str2Regex(p);
    if(regex){
      //正则匹配, 把匹配组赋值给 info.param
      info.query = info.param = info.text.match(regex);
      log('pattern is regex: %s', info.param);
      return info.param !== null ;
    }else{
      return info.text.indexOf(p) !== -1;
    }
  }

  log('[%s] not match.', rule.name);
  return false;
};
Example #15
0
			this.redis.hgetall("global:delayed_matches", _.bind(function(err, reply) {
				if(!err) {
					if(!_.isNull(reply) && reply.length==0) {
						winston.info("No delayed matches found.");
					}
					_.each(reply, _.bind(function(match, match_id) {
						// push it onto matchIdsToTweet
						winston.info("Pushing delayed matches onto list: " + match);
						this.matchesToTweet.push(JSON.parse(match));
					}, this));
				} else {
					winston.warn("Error loading delayed matches from cache: " + err);
				}
			}, this));
Example #16
0
    initialize: function(args) {
        client_models.Session.prototype.initialize.call(this, args)
        _.bindAll(this, "onHangoutStarted", "onHangoutStopped")

        // Set up a hash to maintain timeouts for joinng users.
        this.joiningTimeouts = {};

        // make sure not to overwrite the built-in session-key
        // if we've loaded one through the db.
        if(_.isNull(this.get("session-key"))) {
            var shasum = crypto.createHash('sha256');
            shasum.update(this.get("id") + "");
            shasum.update(new Date().getTime() + "");
            this.set("session-key", shasum.digest('hex'));
        }
    },
Example #17
0
    this.listener = function(event) {
        if(!_.isNull(this.game) && this.game.channel === event.channel.name) {
            if(_.include(this.game.solutions, event.message) && !_.include(this.game.found, event.message)) {
                if(!_.has(this.game.scores, event.user)) this.game.scores[event.user] = 0;
                this.game.scores[event.user]++;
                this.game.found.push(event.message);
                event.reply(event.user + ': ' + event.message.toUpperCase() + ' IS CORRECT. ' + 
                    this.game.found.length + '/' + this.game.solutions.length + ' WORDS FOUND');

                if(this.game.found.length === this.game.solutions.length) {
                    var winner = _.invert(this.game.scores)[_.max(this.game.scores)];
                    event.reply('ALL WORDS FOUND. THE WINNER IS ' + winner.toUpperCase() + ' WITH ' + this.game.scores[winner]);
                    this.game = null;
                }
            }
        }
    }.bind(this);
Example #18
0
Action.exec = function(info, action, cb){
  action = Action.is(action) ? action : new Action(action)

  log('action [%s] exec', action.name);

  var fn = action.handler;
  
  //为空则跳过
  if(_.isNull(fn) || _.isUndefined(fn)){
    warn('handler is null')
    return cb();
  }

  //为数组则直接返回随机的一个子元素
  if( _.isArray(fn) && fn.length>=1){
    log('handler is array: [%s], choose one', fn)
    fn = fn[_.random(0,fn.length-1)];
  }

  //为字符串则直接返回
  if( _.isString(fn)){
    log('handler is string: [%s]', fn)
    if(info.query){
      fn = Utils.formatStr(fn, info.query)
      log('replace with capture group: %s -> %s', info.query, fn)
    }
    return cb(null, fn);
  }

  //为函数时
  if(_.isFunction(fn)){
    fn = fn || action
    log('handler is function, length=%d', fn.length)
    //只定义了一个参数时直接调用, 否则通过回调
    if(fn.length <= 2){
      //返回false则执行下一个action
      return cb(null, fn(info, action)); 
    }else{
      return fn(info, action, cb);
    }
  }

  log('handler is nth, %s', action)
  return cb();
};
	isHangoutPending: function() {
		if(_.isNull(this.get("hangout-pending"))) {
			return false;
		} else {
            // check and see how long it's been since we marked it pending. If
            // it's been more than HANGOUT_CREATION_TIMEOUT seconds, give up
            // and let this person be the new designee. If someone DOES
            // actually complete the process after this, then we're sort of in
            // trouble because they'll be floating, and their app will attempt
            // to set the url.

			// obj has (optionally) "userId" and definitely has "time"
			var obj = this.get("hangout-pending");

			if((new Date().getTime() - obj.time) > HANGOUT_CREATION_TIMEOUT) {
                this.logAnalytics({action: "unfarmed start timeout"});
				this.set("hangout-pending", null);
				return false;
			}
			return true;
		}
	},
Example #20
0
			Fs.exists(self.Config.actualPath+ self.Config.responses_dir + oMethod.sClass + '.js', function(isExists){
				var $responseClass= null;
				
				
				aMethod = oRequest.method.split('.');
				if (aMethod.length == 1){
					oMethod.sClass = self.Config.Default_Class;
					oMethod.sMethod = aMethod[0];
				} else {
					oMethod.sClass = aMethod[0];
					oMethod.sMethod = aMethod[1];
				}
				
				try{				
					if (!isExists){
						throw new exceptions.RPC_CLASS_NOT_FOUND({class: oMethod.sClass});
					}else{
						
						$responseClass = require(self.Config.actualPath+ self.Config.responses_dir + oMethod.sClass);
						if (u.isNull($responseClass) || u.isUndefined(oMethod.sClass)) throw new exceptions.RPC_CLASS_NOT_FOUND({class: oMethod.sClass, id:oRequest.id});
						
						$responseClass = new $responseClass[oMethod.sClass];
						
					}
					
					if (u.isUndefined($responseClass[oMethod.sMethod])) throw new exceptions.RPC_METHOD_NOT_FOUND({method: oMethod.sMethod});
					
					self.done($responseClass[oMethod.sMethod](oRequest.params), oRequest);
				}catch(err){
					
					self.fail(err, oRequest);
				}
				
				
				
				self.complete();
			});
Example #21
0
File: kick.js Project: reality/dbot
      dbot.api.nickserv.getUserHost(server, quietee, function (host) {
        // Add host record entry
        if (host) {
          this.hosts[server][quietee] = host;

          if (!_.isUndefined(duration) && !_.isNull(duration)) {
            duration = duration.trim();
            var msTimeout = new Date(new Date().getTime() + (parseFloat(duration) * 60000));
            if (_.has(dbot.modules, 'remind')) {
              msTimeout = dbot.api.remind.parseTime(duration);
              if (!msTimeout) {
                return callback('Invalid time. Remember you must give e.g. 5m now.');
              }
              duration = duration.replace(/([\d]+)d/, '$1 years').replace(/([\d]+)d/, '$1 days').replace(/([\d]+)h/, '$1 hours ').replace(/([\d]+)m/, '$1 minutes ').replace(/([\d]+)s/, '$1 seconds').trim();
            } else {
              duration += ' minutes';
            }

            var vStatus = dbot.instance.connections[server].channels[channel].nicks[quietee].voice;
            dbot.api.timers.addTimeout(msTimeout, function () {
              if (_.has(this.hosts[server], quietee)) {
                if (_.include(this.config.quietBans, channel)) {
                  this.api.unban(server, this.hosts[server][quietee], channel);
                  this.api.voice(server, quietee, channel);
                } else {
                  this.api.unquiet(server, this.hosts[server][quietee], channel);
                }

                dbot.api.users.resolveUser(server, dbot.config.name, function (err, user) {
                  dbot.api.report.notify('unquiet', server, user, channel,
                    dbot.t('unquiet_notify', {
                      'unquieter': dbot.config.name,
                      'quietee': quietee
                    }), false, quietee);
                });
              }
            }
              .bind(this));
            callback(dbot.t('tquieted', {
                'quietee': quietee,
                'minutes': duration
              }));
            dbot.api.report.notify('quiet', server, quieter.primaryNick, channel,
              dbot.t('tquiet_notify', {
                'minutes': duration,
                'quieter': quieter.primaryNick,
                'quietee': quietee,
                'reason': reason
              }), false, quietee);
          } else {
            callback(dbot.t('quieted', {
                'quietee': quietee
              }));
            dbot.api.report.notify('quiet', server, quieter.primaryNick, channel,
              dbot.t('quiet_notify', {
                'quieter': quieter.primaryNick,
                'quietee': quietee,
                'reason': reason
              }), false, quietee);
          }

          this.api.devoice(server, quietee, channel);

          if (_.include(this.config.quietBans, channel)) {
            this.api.ban(server, this.hosts[server][quietee], channel);
          } else {
            this.api.quiet(server, host, channel);
          }

          if (reason.indexOf('#warn') !== -1) {
            dbot.api.warning.warn(server, quieter, quietee,
              'Quieted in ' + channel + ' for ' + reason, channel,
              function () {});
          }
        } else {
          event.reply(dbot.t('no_user', {
              'user': quietee
            }));
        }
      }
Example #22
0
	handleFinishedMatch: function(match, matchMetadata) {
		// winston.info(JSON.stringify(match));
		// winston.info(JSON.stringify(matchMetadata));
		// okay, now lets look up the detailed lobby info.
		var lobbyInfo = this.states.getLobbyByTeamAndLeague(
			[match.radiant_team_id, match.dire_team_id], match.leagueid);

		// make the lobbyInfo available to processMatchDetails if possible. 
		try {
			var results = this.processMatchDetails(match, matchMetadata, lobbyInfo);
		} catch (e) {
			winston.info(JSON.stringify(match));
			this.removeMatchFromQueue(matchMetadata);
			winston.warn("Error processing match: " + e);
			winston.warn(new Error().stack);
			return;
		}

		// drop out, but mark this match as processed.
		if(!this.isValidMatch(results)) {
			this.removeMatchFromQueue(match);
			return;
		}

		winston.info(JSON.stringify(results));

		// In this new regime, don't tweet based on the blacklist, follow new logics:
		// 1. If it's a tier 3 league, tweet it.
		// 2. If it's a tier 1 league, blacklist it.
		// 3. Otherwise, blacklist it UNLESS it's in the WHITELIST.

		var leagueTier = matchMetadata.league_tier;

		if(leagueTier==3) {
			useAltTweet = false;
			winston.info("FOUND TIER 3 GAME - MAIN");
		} else if (leagueTier==1) {
			useAltTweet = true;
			winston.info("FOUND TIER 1 GAME - ALT");
		} else {
			// if the leagueId is in whitelisted league ids, then DON'T altTweet
			useAltTweet = !_.contains(this.whitelistedLeagueIds, match.leagueid);
			winston.info("FOUND TIER 2 GAME; USE ALT? " + useAltTweet);
		}

		// write out the match data anyway so we can manually build files if we have to
		fs.writeFileSync("games/match_" + match.match_id + ".json", JSON.stringify(results));

		if(lobbyInfo) {
			var success = boxscores.generate(lobbyInfo, results, _.bind(function(base64image) {
				// this method is called only on success. this is a little wonky for sure, but
				// that's just the way it is.


				winston.info("generation successful: (base64) " + base64image.length);
				// if boxscores fails to generate, it represents some sort of major
				// missing data like no tower data or no gold history data.
				// (over time I'll make this more tight; expect at least one gold
				// event every 2-3 minutes for the duration of the game so we can 
				// plausibly feel like we've captured the whole thing and it's worth
				// an image.

				// clean out the lobby data regardless; if we successfully generated,
				// then we don't need it anymore. If we didn't, it was sort of bad
				// data to begin with so clean it out. We'll rely on redis expiring
				// the data on bot restart.
				this.states.removeLobby(lobbyInfo.lastSnapshot.lobby_id);


				// this really should be abstracted; the logic is identical but for historical debugging
				// reasons they're separate.
				if(isSilent || isDemo) {
					winston.info("Skipping media tweet. Alt? " + useAltTweet);
				} else {
					var account = useAltTweet ? this.twitterAlt : this.twitter;
					winston.info("TWEET MEDIA: " + results.shortMessage + " (to alt? " + useAltTweet + ")");
					this._tweetMedia(account, results.shortMessage, matchMetadata, base64image);
				}
			}, this));

			if(!success) {
				// this wasn't necessarily happening otherwise.
				this.states.removeLobby(lobbyInfo.lastSnapshot.lobby_id);

				// we need to tweet normally, without an image.
				if(!useAltTweet) {
					winston.info("TWEET (generate failed): " + results.message);
					this.tweet(results.message, matchMetadata);
				} else {
					winston.info("TWEET.ALT (generate failed): " + results.message);
					this.altTweet(results.message, matchMetadata);
				}
			}
		} else {
			// we're going to decline to tweet without lobby info and see how that goes.
			winston.warn("Not tweeting because lobby info was missing: " + results.message);

			// as far as I can tell this happens largely beacuse it's a double tweet and an
			// earlier tweet attempt flushed that particular lobbyId so it's not present
			// when the second tweet attempt 

			// do non-media tweets
			if(!useAltTweet) {
				winston.info("NO TWEET (missing lobby info): " + results.message);
				// this.tweet(results.message, matchMetadata);
			} else {
				winston.info("NO TWEET.ALT (missing lobby info): " + results.message);
				// this.altTweet(results.message, matchMetadata);
			}			
		}

		// I'm not totally sure why this doesn't delay until we get an ack from
		// the twitter api. That would probably be smarter. But whatever.
		// now remove the match_id from matchIdsToTweet
		this.removeMatchFromQueue(matchMetadata);

		// update the listing if there were series wins.
		// do this late in the process in case there were errors.
		if(!_.isNull(results.teams[0].series_wins)) {
			this.activeSeriesIds[results.seriesStatus.series_id] = results.seriesStatus;
			winston.info("In handleFinishedMatch, save series status. Result: " + JSON.stringify(this.activeSeriesIds));
			// cache the series data so it survives a restart.
			this.saveSeries();
		}
		this.cleanupActiveSeries();
	},
Example #23
0
    getState: function() {
        // There are five parameters that contribute to the state:
        // `hangout-start-time`, `hangout-url`, `hangout-pending`,
        // `hangout-stop-request-time`, and `connectedParticipants`.  However, there
        // are only two fully valid and two limbo combinations of these:
        // valid:
        //  "started", "stopped"
        // limbo:
        //  "pending", "stopping"
        //
        // "started": {
        //     "hangout-start-time": <int>,
        //     "hangout-url": <string>,
        //     "hangout-pending": null,
        //     "hangout-stop-request-time": null,
        //     "connectedParticipants": [list of length more than 0],
        // }
        // "stopped": {
        //     "hangout-start-time": null,
        //     "hangout-url": null,
        //     "hangout-pending": null,
        //     "hangout-stop-request-time": null,
        //     "connectedParticipants": []
        // }
        // "pending": {
        //     "hangout-start-time": null,
        //     "hangout-url": null,
        //     "hangout-pending": null,
        //     "hangout-stop-request-time": null,
        //     "connectedParticipants": []
        // }
        // "stopping": {
        //     "hangout-start-time": <int>,
        //     "hangout-url": <string>,
        //     "hangout-pending": null,
        //     "hangout-stop-request-time": <timestamp integer>,
        //     "connectedParticipants": []
        // }
        //
        // Any other combination of values -- a hangout-url with zero
        // participants, a hangout-start-time with no hangout-url, etc. is an
        // error condition.

        var pending = !_.isNull(this.get("hangout-pending"));
        var pendingStale = pending && (
            (new Date().getTime() - this.get("hangout-pending").time) > this.HANGOUT_CREATION_TIMEOUT
        );
        var stopping = !_.isNull(this.get("hangout-stop-request-time"));
        var stoppingStale = stopping && (
            (new Date().getTime() - this.get("hangout-stop-request-time")) > this.HANGOUT_LEAVE_STOP_TIMEOUT
        );
        var hasUrl = _.isString(this.get("hangout-url"));
        var hasStartTime = _.isNumber(this.get("hangout-start-time"));
        var hasParticipants = this.getNumConnectedParticipants();

        //
        // Valid states
        //
        if (!pending && hasUrl && hasStartTime && hasParticipants && !stopping) {
            return "started";
        }
        if (!pending && !hasUrl && !hasStartTime && !hasParticipants && !stopping) {
            return "stopped";
        }
        if (pending && !pendingStale && !hasUrl && !hasStartTime && !hasParticipants && !stopping) {
            return "pending";
        }
        if (!pending && hasUrl && hasStartTime && !hasParticipants && stopping && !stoppingStale) {
            return "stopping";
        }

        //
        // Problem states
        //
        var problems = [];
        if (pendingStale) { problems.push("pending overdue"); }
        if (stoppingStale) { problems.push("stopping overdue"); }
        if (pending) { problems.push("uncleared pending"); }
        if (stopping) { problems.push("uncleared stopping"); }
        if (hasParticipants) {
            if (!hasUrl) { problems.push("no url"); }
            if (!hasStartTime) { problems.push("no start time"); }
        } else {
            if (hasUrl) { problems.push("stale url"); }
            if (hasStartTime) { problems.push("unstopped"); }
        }
        return problems.join("; ");
    },
Example #24
0
var clone = {name:'moe', b:[1,2,3]};
console.log(moe==clone);//false
console.log(_.isEqual(moe, clone));//true
//判断对象类型以下都为空
console.log(_.isEmpty({})); //如果object里没包含任何东西,将返回true
console.log(_.isArray([1,2,3]));
console.log(_.isObject({}));
console.log((function(){ return _.isArguments(arguments); })(1, 2, 3));
console.log(_.isFunction(console.log));
console.log(_.isString("moe"));
console.log(_.isNumber(8.4 * 5));
console.log(_.isFinite(-101));
console.log(_.isBoolean(true));
console.log(_.isDate(new Date()));
console.log(_.isNaN(NaN));
console.log(_.isNull(null));
console.log(_.isUndefined(undefined));

// invert _.invert(object)
// 返回一个object的副本,并且里面的键和值是对调的,要使之有效,必须确保object里所有的值都是唯一的且可以序列号成字符串
console.log(_.invert({a:'b', c:'d', e:'f'})); // { b: 'a', d: 'c', f: 'e' }

// pairs _.pairs(object)
// 把一个对象转换成一个[key, value]形式的数组
console.log(_.pairs({one:1, two:2, three: 3})); // [ [ 'one', 1 ], [ 'two', 2 ], [ 'three', 3 ] ]

// values _.values(object)
// 获取object对象的所有属性值
console.log(_.values({one:1, two:2, three:3})); // [ 1, 2, 3 ]

// keys _.keys(object)
Example #25
0
	isLive: function() {
        var curTime = new Date().getTime();
        var test = !_.isNull(this.get("start")) && curTime >= this.get("start") && _.isNull(this.get("end"));
        return test;
    },
Example #26
0
	isConnected: function() {
		return !_.isUndefined(this.get("sock")) && !_.isNull(this.get("sock"));
	},
Example #27
0
 return _.filter(builds, function(b){
     return !_.isNull(b) && !_.isUndefined(b); });
Example #28
0
 var _isDefined = function(obj) {
     return !_.isUndefined(obj) && !_.isNull(obj);
 };
Example #29
0
		results = _.filter(results, function(num){ return !_.isNull(num) });