<commit_before>Moves = new Mongo.Collection("moves");

Scores = new Mongo.Collection("scores")

Rounds = new Mongo.Collection("rounds")

if (Meteor.isClient) {

  Template.body.helpers({
    // moves: [
    // {'user': 1},
    // {'user': 2},
    // ]
    moves_1: function() {
      return moves_1 = Moves.find({user: '1'}, {sort: {createdAt: -1}, limit: 1})
    },
    moves_2: function() {
      return Moves.find({user: '2'}, {sort: {createdAt: -1}, limit: 1});
    },
    user_1_score: function() {
      return Scores.findOne({_id: '1'}).score;
    }

  });

  Template.body.events({
    "click #add-event": function (event){

      Moves.insert({
        _id: '1',
        move: 'rock',
        user: '1',
        createdAt: new Date()
      })
    },
    "click #start-game": function(event){
      console.log('game starts!')
      resetScores()
    },
    "click #start-round": function(event){
      console.log('round starts!')
      // initiate countdown, remove all current moves from db.
      var round = Rounds.insert({
        createdAt: new Date(),
        status: 'pending',
      })

      // start animation
      start()

      // Open round for input
      Rounds.update({_id: round}, {$set: {status: 'open'}})
      console.log(Rounds.find({}, {sort: {createdAt: -1}, limit: 1}).fetch()[0]['status'])
    },
    "click #end-round": function(event){
      // close round, assess round results.

      user_1_move = Moves.findOne({user: '1'})
      user_2_move = Moves.findOne({user: '2'})

      // Add a point to winning player,
      var user = Scores.findOne({_id: '1'})
      Scores.update({_id: '1'}, {$set: {score: user.score + 1}})

      // Delete old moves.
      Moves.remove({_id: '1'});
      Moves.remove({_id: '2'});

      // Set round to be closed.
      var open_rounds = Rounds.find({status: 'open'}, {sort: {createdAt: -1}, limit: 1})
      round_id = open_rounds.fetch()[0]._id
      Rounds.update({_id: round_id}, {$set: {status: 'closed'}})

      console.log(Rounds.find({}, {sort: {createdAt: -1}, limit: 1}).fetch()[0]['status'])
    }

  })
}

if (Meteor.isServer) {

  // Global API configuration
  var Api = new Restivus({
    useDefaultAuth: true,
    prettyJson: true
  });

  // Generates: GET, POST on /api/items and GET, PUT, DELETE on
  // /api/moves/:id for the Moves collection
  Api.addCollection(Moves, {
    routeOptions: {
      authRequired: false
    },
    endpoints: {
      post: {
        authRequired: false,
        action: function () {

          var params
          if (this.bodyParams.hasOwnProperty('user')) {
            params = this.bodyParams;
          } else {
            params = this.queryParams;
          }
          var currentRound = Rounds.find({}, {sort: {createdAt: -1}, limit: 1}).fetch()[0]
          console.log(typeof currentRound)
          if (typeof currentRound === 'object' && currentRound['status'] == 'open') {
            var a = Moves.insert({
              _id: params.user,
              user: params.user,
              move: params.move,
              createdAt: new Date()
            })
            return {"status": 'success', "data": a}
          } else {
            return {'status': "failure", 'reason': 'round is not open.'}
          }
        }
      },
    }
  });

  function resetScores() {

    Scores.update({_id: '1'}, {$set: {score: 0}})
    Scores.update({_id: '2'}, {$set: {score: 0}})
  }

  Meteor.startup(function () {
    // code to run on server at startup
    Moves.remove({});
    Scores.remove({});
    Rounds.remove({});

    Scores.insert({_id:'1', user: '1', score: 0})
    Scores.insert({_id:'2', user: '2', score: 0})
    resetScores()
  });
}

<commit_msg>Refactored out methods, added end round logic<commit_after>Moves = new Mongo.Collection("moves");

Scores = new Mongo.Collection("scores")

Rounds = new Mongo.Collection("rounds")

if (Meteor.isClient) {

  Template.body.helpers({
    // moves: [
    // {'user': 1},
    // {'user': 2},
    // ]
    moves_1: function() {
      return moves_1 = Moves.find({user: '1'}, {sort: {createdAt: -1}, limit: 1})
    },
    moves_2: function() {
      return Moves.find({user: '2'}, {sort: {createdAt: -1}, limit: 1});
    },
    user_1_score: function() {
      return Scores.findOne({_id: '1'}).score;
    }

  });

  Template.body.events({
    "click #add-event": function (event){

      Moves.insert({
        _id: '1',
        move: 'rock',
        user: '1',
        createdAt: new Date()
      })
    },
    "click #start-game": function(event){
      console.log('game starts!')
      resetScores()
    },
    "click #start-round": function(event){
      console.log('round starts!')
      // initiate countdown, remove all current moves from db.
      var round = Rounds.insert({
        createdAt: new Date(),
        status: 'pending',
      })

      // start animation
      start()

      // Open round for input
      Rounds.update({_id: round}, {$set: {status: 'open'}})
      console.log(Rounds.find({}, {sort: {createdAt: -1}, limit: 1}).fetch()[0]['status'])
    },
    "click #end-round": endRound
  })
}

function endRound() {
  // close round, assess round results.

  user_1_move = Moves.findOne({user: '1'})
  user_2_move = Moves.findOne({user: '2'})

  // Add a point to winning player,
  var user = Scores.findOne({_id: '1'})
  Scores.update({_id: '1'}, {$set: {score: user.score + 1}})

  // Delete old moves.
  Moves.remove({_id: '1'});
  Moves.remove({_id: '2'});

  // Set round to be closed.
  var open_rounds = Rounds.find({status: 'open'}, {sort: {createdAt: -1}, limit: 1})
  round_id = open_rounds.fetch()[0]._id
  Rounds.update({_id: round_id}, {$set: {status: 'closed'}})

  console.log(Rounds.find({}, {sort: {createdAt: -1}, limit: 1}).fetch()[0]['status'])
}

if (Meteor.isServer) {

  // Global API configuration
  var Api = new Restivus({
    useDefaultAuth: true,
    prettyJson: true
  });

  // Generates: GET, POST on /api/items and GET, PUT, DELETE on
  // /api/moves/:id for the Moves collection
  Api.addCollection(Moves, {
    routeOptions: {
      authRequired: false
    },
    endpoints: {
      post: {
        authRequired: false,
        action: onPost,
      },
    }
  });

  function onPost() {
    var params;
    if (this.bodyParams.hasOwnProperty('user')) {
      params = this.bodyParams;
    } else {
      params = this.queryParams;
    }

    var currentRound = Rounds.find({}, {sort: {createdAt: -1}, limit: 1}).fetch()[0];
    console.log(typeof currentRound);

    if (typeof currentRound === 'object' && currentRound['status'] == 'open') {
      var a = Moves.insert({
        _id: params.user,
        user: params.user,
        move: params.move,
        createdAt: new Date()
      });
      if (Moves.findOne({_id: '1'}) && Moves.findOne({_id: '2'})) {
        endRound();
      }
      return {"status": 'success', "data": a}
    } else {
      return {'status': "failure", 'reason': 'round is not open.'}
    }
  }

  function resetScores() {

    Scores.update({_id: '1'}, {$set: {score: 0}})
    Scores.update({_id: '2'}, {$set: {score: 0}})
  }

  Meteor.startup(function () {
    // code to run on server at startup
    Moves.remove({});
    Scores.remove({});
    Rounds.remove({});

    Scores.insert({_id:'1', user: '1', score: 0})
    Scores.insert({_id:'2', user: '2', score: 0})
    resetScores()
  });
}

<|endoftext|>


<commit_before>var async = require('async');
var fs = require('fs');
var path = require('path');
var remote = require('remote');
var app = remote.require('app');

Installer = {};

Installer.CURRENT_VERSION = app.getVersion();
Installer.BASE_URL = 'https://s3.amazonaws.com/kite-installer/';

Installer.isUpToDate = function () {
  return !!Installs.findOne({version: Installer.CURRENT_VERSION});
};

/**
 * Install steps. A step is a function that accepts a function (err) callback and returns once that step is complete.keys:
 * - run: Function that runs the installation step and calls the callback with an error if failed.
 * - pastMessage: Message to show after step completion
 * - message: Message to show while step is running
 * - imperativeMessage: Message to show before running
 */
Installer.steps = [
  {
    run: function (callback, progressCallback) {
      var installed = VirtualBox.installed();
      if (!installed) {
        Util.downloadFile(Installer.BASE_URL + VirtualBox.INSTALLER_FILENAME, path.join(Util.getResourceDir(), VirtualBox.INSTALLER_FILENAME), VirtualBox.INSTALLER_CHECKSUM, function (err) {
          if (err) {callback(err); return;}
          VirtualBox.install(function (err) {
            if (!VirtualBox.installed()) {
              callback('VirtualBox could not be installed. The installation either failed or was cancelled. Please try closing all VirtualBox instances and try again.');
            } else {
              callback(err);
            }
          });
        }, function (progress) {
          progressCallback(progress);
        });
      } else {
        // Version 4.3.12 is required.
        VirtualBox.version(function (err, installedVersion) {
          if (err) {callback(err); return;}
          if (Util.compareVersions(installedVersion, VirtualBox.REQUIRED_VERSION) < 0) {
            // Download a newer version of Virtualbox
            Util.downloadFile(Installer.BASE_URL + VirtualBox.INSTALLER_FILENAME, path.join(Util.getResourceDir(), VirtualBox.INSTALLER_FILENAME), VirtualBox.INSTALLER_CHECKSUM, function (err) {
              if (err) {callback(err); return;}
              VirtualBox.install(function (err) {
                if (err) {callback(err); return;}
                VirtualBox.version(function (err, installedVersion) {
                  if (err) {callback(err); return;}
                  if (Util.compareVersions(installedVersion, VirtualBox.REQUIRED_VERSION) < 0) {
                    callback('VirtualBox could not be installed. The installation either failed or was cancelled. Please try closing all VirtualBox instances and try again.');
                  } else {
                    callback(err);
                  }
                });
              }, function (progress) {
                progressCallback(progress);
              });
            });
          } else {
            callback();
          }
        });
      }
    },
    pastMessage: 'VirtualBox installed',
    message: 'Downloading & Installing VirtualBox',
    futureMessage: 'Download & Install VirtualBox if necessary'
  },

  // Initialize Boot2Docker if necessary.
  {
    run: function (callback) {
      Boot2Docker.exists(function (err, exists) {
        if (err) { callback(err); return; }
        if (!exists) {
          var vmFilesPath = path.join(Util.getHomePath(), 'VirtualBox\ VMs', 'kitematic-vm');
          if (fs.existsSync(vmFilesPath)) {
            Util.deleteFolder(vmFilesPath);
          }
          Boot2Docker.init(function (err) {
            callback(err);
          });
        } else {
          if (!Boot2Docker.sshKeyExists()) {
            callback('Boot2Docker SSH key doesn\'t exist. Fix by deleting the existing Boot2Docker VM and re-run the installer. This usually occurs because an old version of Boot2Docker is installed.');
          } else {
            Boot2Docker.stop(function(err) {
              Boot2Docker.upgrade(function (err) {
                callback(err);
              });
            });
          }
        }
      });
    },
    pastMessage: 'Setup the Kitematic VM (if required)',
    message: 'Setting up the Kitematic VM',
    futureMessage: 'Set up the Kitematic VM(if required)'
  },

  {
    run: function (callback) {
      VirtualBox.addCustomHostAdapter('kitematic-vm', function (err, ifname) {
        callback(err);
      });
    },
    pastMessage: 'Added custom host adapter to the Kitematic VM',
    message: 'Adding custom host adapter to the Kitematic VM',
    futureMessage: 'Add custom host adapter to the Kitematic VM'
  },

  // Start the Kitematic VM
  {
    run: function (callback) {
      Boot2Docker.state(function (err, state) {
        if (err) { callback(err); return; }
        if (state !== 'running') {
          console.log('starting');
          Boot2Docker.start(function (err) {
            callback(err);
          });
        } else {
          Boot2Docker.setIp('eth2', Boot2Docker.REQUIRED_IP, function(err) {
            callback(err);
          });
        }
      });
    },
    pastMessage: 'Started the Kitematic VM',
    message: 'Starting the Kitematic VM',
    futureMessage: 'Start the Kitematic VM'
  },

  {
    run: function (callback) {
      VirtualBox.setupRouting('kitematic-vm', function (err, ifname) {
        callback(err);
      });
    },
    pastMessage: 'Container routing set up',
    message: 'Setting up container routing (root required)',
    futureMessage: 'Set up container routing to VM (root required)'
  },

  // Set up the default Kitematic images
  {
    run: function (callback, progressCallback) {
      Util.downloadFile(Installer.BASE_URL + Docker.DEFAULT_IMAGES_FILENAME, path.join(Util.getResourceDir(), Docker.DEFAULT_IMAGES_FILENAME), Docker.DEFAULT_IMAGES_CHECKSUM, function (err) {
        Docker.reloadDefaultContainers(function (err) {
          callback(err);
        });
      }, function (progress) {
        progressCallback(progress);
      });
    },
    pastMessage: 'Set up the default Kitematic images.',
    message: 'Setting up the default Kitematic images...',
    subMessage: '(This may take a few minutes)',
    futureMessage: 'Set up the default Kitematic images'
  }
];

Installer.run = function (callback) {
  var currentStep = 0;
  Session.set('currentInstallStep', currentStep);
  Session.set('numberOfInstallSteps', this.steps.length);
  async.eachSeries(this.steps, function (step, callback) {
    console.log('Performing step ' + currentStep);
    Session.set('currentInstallStepProgress', 0);
    step.run(function (err) {
      if (err) {
        callback(err);
      } else {
        currentStep += 1;
        Session.set('currentInstallStep', currentStep);
        callback();
      }
    }, function (progress) {
      Session.set('currentInstallStepProgress', progress);
    });
  }, function (err) {
    if (err) {
      // if any of the steps fail
      console.log('Kitematic setup failed at step ' + currentStep);
      console.log(err);
      Session.set('failedStep', currentStep);
      Session.set('failedError', err);
      callback(err);
    } else {
      // Setup Finished
      console.log('Setup finished.');
      callback();
    }
  });
};
<commit_msg>Correct typo in installer text<commit_after>var async = require('async');
var fs = require('fs');
var path = require('path');
var remote = require('remote');
var app = remote.require('app');

Installer = {};

Installer.CURRENT_VERSION = app.getVersion();
Installer.BASE_URL = 'https://s3.amazonaws.com/kite-installer/';

Installer.isUpToDate = function () {
  return !!Installs.findOne({version: Installer.CURRENT_VERSION});
};

/**
 * Install steps. A step is a function that accepts a function (err) callback and returns once that step is complete.keys:
 * - run: Function that runs the installation step and calls the callback with an error if failed.
 * - pastMessage: Message to show after step completion
 * - message: Message to show while step is running
 * - imperativeMessage: Message to show before running
 */
Installer.steps = [
  {
    run: function (callback, progressCallback) {
      var installed = VirtualBox.installed();
      if (!installed) {
        Util.downloadFile(Installer.BASE_URL + VirtualBox.INSTALLER_FILENAME, path.join(Util.getResourceDir(), VirtualBox.INSTALLER_FILENAME), VirtualBox.INSTALLER_CHECKSUM, function (err) {
          if (err) {callback(err); return;}
          VirtualBox.install(function (err) {
            if (!VirtualBox.installed()) {
              callback('VirtualBox could not be installed. The installation either failed or was cancelled. Please try closing all VirtualBox instances and try again.');
            } else {
              callback(err);
            }
          });
        }, function (progress) {
          progressCallback(progress);
        });
      } else {
        // Version 4.3.12 is required.
        VirtualBox.version(function (err, installedVersion) {
          if (err) {callback(err); return;}
          if (Util.compareVersions(installedVersion, VirtualBox.REQUIRED_VERSION) < 0) {
            // Download a newer version of Virtualbox
            Util.downloadFile(Installer.BASE_URL + VirtualBox.INSTALLER_FILENAME, path.join(Util.getResourceDir(), VirtualBox.INSTALLER_FILENAME), VirtualBox.INSTALLER_CHECKSUM, function (err) {
              if (err) {callback(err); return;}
              VirtualBox.install(function (err) {
                if (err) {callback(err); return;}
                VirtualBox.version(function (err, installedVersion) {
                  if (err) {callback(err); return;}
                  if (Util.compareVersions(installedVersion, VirtualBox.REQUIRED_VERSION) < 0) {
                    callback('VirtualBox could not be installed. The installation either failed or was cancelled. Please try closing all VirtualBox instances and try again.');
                  } else {
                    callback(err);
                  }
                });
              }, function (progress) {
                progressCallback(progress);
              });
            });
          } else {
            callback();
          }
        });
      }
    },
    pastMessage: 'VirtualBox installed',
    message: 'Downloading & Installing VirtualBox',
    futureMessage: 'Download & Install VirtualBox if necessary'
  },

  // Initialize Boot2Docker if necessary.
  {
    run: function (callback) {
      Boot2Docker.exists(function (err, exists) {
        if (err) { callback(err); return; }
        if (!exists) {
          var vmFilesPath = path.join(Util.getHomePath(), 'VirtualBox\ VMs', 'kitematic-vm');
          if (fs.existsSync(vmFilesPath)) {
            Util.deleteFolder(vmFilesPath);
          }
          Boot2Docker.init(function (err) {
            callback(err);
          });
        } else {
          if (!Boot2Docker.sshKeyExists()) {
            callback('Boot2Docker SSH key doesn\'t exist. Fix by deleting the existing Boot2Docker VM and re-run the installer. This usually occurs because an old version of Boot2Docker is installed.');
          } else {
            Boot2Docker.stop(function(err) {
              Boot2Docker.upgrade(function (err) {
                callback(err);
              });
            });
          }
        }
      });
    },
    pastMessage: 'Setup the Kitematic VM (if required)',
    message: 'Setting up the Kitematic VM',
    futureMessage: 'Set up the Kitematic VM (if required)'
  },

  {
    run: function (callback) {
      VirtualBox.addCustomHostAdapter('kitematic-vm', function (err, ifname) {
        callback(err);
      });
    },
    pastMessage: 'Added custom host adapter to the Kitematic VM',
    message: 'Adding custom host adapter to the Kitematic VM',
    futureMessage: 'Add custom host adapter to the Kitematic VM'
  },

  // Start the Kitematic VM
  {
    run: function (callback) {
      Boot2Docker.state(function (err, state) {
        if (err) { callback(err); return; }
        if (state !== 'running') {
          console.log('starting');
          Boot2Docker.start(function (err) {
            callback(err);
          });
        } else {
          Boot2Docker.setIp('eth2', Boot2Docker.REQUIRED_IP, function(err) {
            callback(err);
          });
        }
      });
    },
    pastMessage: 'Started the Kitematic VM',
    message: 'Starting the Kitematic VM',
    futureMessage: 'Start the Kitematic VM'
  },

  {
    run: function (callback) {
      VirtualBox.setupRouting('kitematic-vm', function (err, ifname) {
        callback(err);
      });
    },
    pastMessage: 'Container routing set up',
    message: 'Setting up container routing (root required)',
    futureMessage: 'Set up container routing to VM (root required)'
  },

  // Set up the default Kitematic images
  {
    run: function (callback, progressCallback) {
      Util.downloadFile(Installer.BASE_URL + Docker.DEFAULT_IMAGES_FILENAME, path.join(Util.getResourceDir(), Docker.DEFAULT_IMAGES_FILENAME), Docker.DEFAULT_IMAGES_CHECKSUM, function (err) {
        Docker.reloadDefaultContainers(function (err) {
          callback(err);
        });
      }, function (progress) {
        progressCallback(progress);
      });
    },
    pastMessage: 'Set up the default Kitematic images.',
    message: 'Setting up the default Kitematic images...',
    subMessage: '(This may take a few minutes)',
    futureMessage: 'Set up the default Kitematic images'
  }
];

Installer.run = function (callback) {
  var currentStep = 0;
  Session.set('currentInstallStep', currentStep);
  Session.set('numberOfInstallSteps', this.steps.length);
  async.eachSeries(this.steps, function (step, callback) {
    console.log('Performing step ' + currentStep);
    Session.set('currentInstallStepProgress', 0);
    step.run(function (err) {
      if (err) {
        callback(err);
      } else {
        currentStep += 1;
        Session.set('currentInstallStep', currentStep);
        callback();
      }
    }, function (progress) {
      Session.set('currentInstallStepProgress', progress);
    });
  }, function (err) {
    if (err) {
      // if any of the steps fail
      console.log('Kitematic setup failed at step ' + currentStep);
      console.log(err);
      Session.set('failedStep', currentStep);
      Session.set('failedError', err);
      callback(err);
    } else {
      // Setup Finished
      console.log('Setup finished.');
      callback();
    }
  });
};
<|endoftext|>


<commit_before>var db = require(__dirname + "/database.js"),
    md5 = require(__dirname + "/md5.js"),
    utils = require(__dirname + "/utils.js"),
    datetime = require(__dirname + "/datetime.js"),
    errorcodes = require(__dirname + "/errorcodes.js").errorcodes;

var leaderboards = module.exports = {

    /**
     * Lists scores from a leaderboard table
     * @param options:  table, url, highest, mode, page, perpage, filters ass. array, friendslist,
     * @param callback function (error, errorcode, numscores, scores)
     */
    list: function(options, callback) {

        // defaults
        options.page = options.page || 1;
        options.perpage = options.perpage || 20;
        options.highest = options.lowest !== true;

        var query = {
            filter: {
                publickey: options.publickey,
                table: options.table
            },
            limit: options.perpage,
            skip: (options.page - 1) * options.perpage,
            sort: {}
        };

        // per-source website or device scores, websites
		// get truncated to domain.com
        if(options.source) {
            query.filter.source = options.source.indexOf("://") > -1 ? utils.baseurl(options.source) : options.source;
        }

        if(options.filters && Object.keys(options.filters).length > 0) {
            query.filter.fields = {};
            for(var x in options.filters) {
                query.filter.fields[x] = options.filters[x];
            }
        }

        // filtering for playerids
        var playerids = options.friendslist || [];

        if(options.playerid && !options.excludeplayerid) {
            playerids.push(options.playerid);
        }

		if(playerids.length > 1) {
            query.filter.playerid = { $in: playerids };
        } else if(playerids.length == 1) {
            query.filter.playerid = playerids[0];
        }

        // date mode
        options.mode = (options.mode || "alltime").toLowerCase();

        switch(options.mode) {
            case "today":
                query.filter.date = {"$gte": datetime.now - (24 * 60 * 60)};
                break;

           case "last7days":
               query.filter.date = {"$gte": (datetime.now - (7 * 24 * 60 * 60))};
                break;

            case "last30days":
                query.filter.date = {"$gte": (datetime.now - (30 * 24 * 60 * 60))};
                break;
        }

        // sorting
        if(options.mode == "newest") {
            query.sort = "-date";
        } else {
            query.sort = options.highest ? "-points" : "points";
        }

        // the scores
        db.LeaderboardScore.find(query.filter).sort(query.sort).limit(query.limit).skip(query.skip).exec(function(error, scores){

            if(error) {
                callback("unable to load scores: " + error + " (api.leaderboards.list:99)", errorcodes.GeneralError);
                return;
            }

            db.LeaderboardScore.count(query.filter, function(error, numscores) {

                if(error) {
                    callback("unable to count scores: " + error + " (api.leaderboards.list:104)", errorcodes.GeneralError);
                    return;
                }

                scores = scores || [];
                callback(null, errorcodes.NoError, numscores, clean(scores, query.skip + 1));
            });
        });
    },

    /**
     * Saves a score
     * @param options: url, name, points, auth, playerid, table, highest, allowduplicates, customfields ass. array
     * @param callback function(error, errorcode)
     */
    save: function(options, callback) {

        if(!options.playername) {
            callback("no name (" + options.playername + ")", errorcodes.InvalidName);
            return;
        }

        if(!options.table) {
            callback("no table name (" + options.table + ")", errorcodes.InvalidLeaderboardId);
            return;
        }

        if(options.source ) {
            options.source = utils.baseurl(options.source);
        }

        options.highest = options.lowest !== true;

        // small cleanup
        var score = {};

        // fields that aren't relevant to our score
        var exclude = ["allowduplicates", "highest", "lowest", "numfields", "section", "action",
                        "ip", "date", "url", "rank", "points", "page", "perpage", "global", "filters", "debug"];

        for(var x in options) {
            if(exclude.indexOf(x) > -1) {
                continue;
            }
            score[x] = options[x];
        }

        score.hash = md5([options.publickey, options.ip, options.table, options.playername,
                          options.playerid, options.highest, options.source].join("."));
        score.points = options.points;

        // check bans

        // insert
        if(options.allowduplicates === true) {
            var mscore = new db.LeaderboardScore(score);
            return mscore.save(function(error, item) {
                if(error) {
                    return callback("unable to insert score: " + error + " (api.leaderboards.save:166)", errorcodes.GeneralError);
                }

                return callback(null, errorcodes.NoError, item._id, item);
            });
        }

        // check for duplicates, by default we will assume highest unless lowest is explicitly specified
        var sort = options.highest ? "-score" : "score",
            query = {
                hash: score.hash
            };

        db.LeaderboardScore.findOne(query).sort(sort).exec(function(error, dupe) {
            if(error) {
                return callback("unable to check dupes: " + error + " (api.leaderboards.save:212)", errorcodes.GeneralError);
            }

            // no duplicates
            if(!dupe) {
                var mscore = new db.LeaderboardScore(score);
                return mscore.save(function(error) {

                    if(error) {
                        return callback("unable to insert score: " + error + " (api.leaderboards.save:212)", errorcodes.GeneralError);
                    }

                    return callback(null, errorcodes.NoError);
                });
            }

            // check if the new score is higher or lower
            if((dupe.points > score.points && options.highest) || (dupe.points < score.points && !options.highest)) {
                callback(null, errorcodes.NotBestScore);
                return;
            }

            db.LeaderboardScore.update( { _id: dupe._id }, { points: score.points, date: score.date, fields: score.fields }, { upsert: false }, function(error, item) {
                if(error) {
                    callback("unable to update score: " + error + " (api.leaderboards.save:240)", errorcodes.GeneralError);
                    return;
                }

                callback(null, errorcodes.NoError, item._id, item);
            });
        });
    },

    saveAndList: function(options, callback) {
        leaderboards.save(options, function(error, errorcode, insertedid, insertedscore) {
            if(error) {
                return callback(error + " (api.leaderboards.saveAndList:232)", errorcode);
            }

            var query = {
                table: options.table
            };

            if(options.excludeplayerid !== true && options.playerid) {
                query.playerid = options.playerid;
            }

            if(options.fields && Object.keys(options.fields).length > 0) {
                query.fields = options.fields;
            }

            if(options.hasOwnProperty("global")) {
                query.global = options.global;
            }

            if(options.hasOwnProperty("source")) {
                query.source = options.source;
            }

            // find the offset
            rank(query, options.highest, options.points, function(error, errorcode, before) {
                if(error) {
                    return callback(error + " (api.leaderboards.saveAndList:240)", errorcode);
                }
                // prepare our query for listing
                query.publickey = options.publickey;
                query.perpage = options.perpage;
                query.page = Math.floor(before / options.perpage) + 1;
                query.highest = options.lowest !== true;
                query.lowest = !query.highest;
                delete(query.points);
                leaderboards.list(query, function(error, errorcode, numscores, scores) {

                        if(scores && scores.length) {
                        for(var i=0, len=scores.length; i<len; i++) {
                            if(scores[i].points == options.points &&
                               scores[i].playerid == query.playerid &&
                               scores[i].playerid == query.playername &&
                               scores[i].playerid == query.source) {
                                   scores[i].submitted = true;
                                   break;
                               }
                        }
                    }

                    return callback(error, errorcode, numscores, scores);
                });
            });
        });
    }
};

/**
 * Strips unnceessary data and tidies a score object
 */
function clean(scores, baserank) {
    var i, len, x, score,
        results = [];

    for(i=0, len=scores.length; i<len; i++) {
        score = scores[i].toObject();

        for(x in score) {
            if(typeof(score[x]) == "string") {
                score[x] = utils.unescape(score[x]);
            }
        }

        for(x in score.fields) {
            if(typeof(score.fields[x]) == "string") {
                score.fields[x] = utils.unescape(score.fields[x]);
            }
        }

        score.rank = baserank + i;
        score.scoreid = score._id.toString();
		score.rdate = utils.friendlyDate(utils.fromTimestamp(score.date));
        delete score._id;
        delete score.__v;
        delete score.hash;
        results.push(score);
    }
    return results;
}

// indexes provide a way to skip expensive mongodb count operations by tracking
// the rank position of points for specific leaderboard queries

var indexlist = [];
var index = {};/*
    hash: {
        hash: hash,
        query: query,
        highest: highest,
        scores: [ { points: 1000, scores: 7 }, { points: 989, scores: 1}],
        remove: [ { points: 1000, 3 } ],
        lastupdated: timestamp,
        lastused: timestamp
}*/

/*
 * Gets the rank of the provided points based on its query either from an existing
 * index, or manually while it creates a new index
 */
function rank(query, highest, points, callback) {

    var hash = md5(JSON.stringify(query) + "." + highest),
        newscore = { points: points, scores: 1, before: 0 },
        ind = index[hash];

    if(ind) {

        ind.lastused = datetime.now;
        if(ind.removeHash[points]) {
            return callback(null, errorcodes.NoError, ind.removeHash[points].before);
        }

        addToIndex(index, highest, newscore, function(o) {
            return callback(null, newscore.before);
        });
    }

    // set up our new index and chek against the database
    index[hash] = {
        key: hash,
        query: query,
        highest: highest,
        scores: [newscore],
        remove: [newscore],
        removeHash: {},
        lastupdated: 0,
        lastused: datetime.now
    };

    indexlist.push(index[hash]);
    indexlist.sort(function(a, b) { // todo: this could be better
        return a.lastupdated < b.lastupdated ? 1 : -1;
    });

    query.points = highest ? { $gte: points } : { $lte: points };
    db.LeaderboardScore.count(query, function(error, numscores) {
        return callback(error, error ? errorcodes.GeneralError : errorcodes.NoError, numscores);
    });
}

// asynchronously puts a new score in an index
function addToIndex(index, highest, newscore, callback) {
    var ai, i, len,
        found = false;

    function nextBlock() {
        len = i + 1000;
        if(len >= index.scores.length) {
            len = index.scores.length;
        }

        if(i >= len) {
            return callback(newscore);
        }

        for(i=i; i<len; i++) {
            ai = index.scores[i];

            // update the scores after us to have one more 'before'
            if(found) {
                ai.before++;
                continue;
            }

            // count the number of scores higher or lower depending on setting
            found = (highest && ai.points > newscore.points) || (!highest && ai.points < newscore.points);

            if(!found) {
                newscore.before += ai.scores;
                continue;
            }

            // insert our new score
            index.scores.splice(i, 0, newscore);
            index.remove.push(newscore);
            index.removeHash[newscore.points] = newscore;
       }

       return setTimeout(nextBlock, 100);
    }

    nextBlock();
}

// keep our indexes up to date
function refreshIndexes() {

    if (!indexlist.length) {
        return setTimeout(refreshIndexes, 1000);
    }

    var first = indexlist.shift();

    // dispose of indexes not used in the last 10 minutes
    if(first.lastused < datetime.now - 600) {
        index[first.hash] = null;
        delete(index[first.hash]);
        first = null;
        return refreshIndexes();
    }

    indexlist.push(first);

    // wait at least 30 seconds between updates
    if(datetime.now - first.lastcheck < 30) {
        return setTimeout(refreshIndexes, 1000);
    }

    // remove any scores we locally added
    var i, len, rem;

    for(i=0, len=first.remove.length; i<len; i++) {
       rem = first.remove[i];
       first.removeHash[rem.points] -= rem.scores;
    }

    // update the index
    first.query.date = { $gt: first.lastupdated };
    first.lastupdated = datetime.now;
    db.LeaderboardScore.find(first.query).sort(first.highest ? "-points" : "points").select("points date").exec(function(error, scores) {

        if(error) {
            return setTimeout(refreshIndexes, 1000);
        }

        if(!scores.length) {
            return setTimeout(refreshIndexes, 1000);
        }

        // add the new data
        var i, len, score;
        for(i=0, len=scores.length; i<len; i++)  {
            score = scores[i];

            var newscore = { points: score.points, scores: 1, before: 0 };
            addToIndex(first, first.highest, newscore);

            if(score.date > first.lastupdated) {
                first.lastupdated = score.date;
            }
        }

        return setTimeout(refreshIndexes, 1000);
    });
}

refreshIndexes();<commit_msg>Fix submitted = true<commit_after>var db = require(__dirname + "/database.js"),
    md5 = require(__dirname + "/md5.js"),
    utils = require(__dirname + "/utils.js"),
    datetime = require(__dirname + "/datetime.js"),
    errorcodes = require(__dirname + "/errorcodes.js").errorcodes;

var leaderboards = module.exports = {

    /**
     * Lists scores from a leaderboard table
     * @param options:  table, url, highest, mode, page, perpage, filters ass. array, friendslist,
     * @param callback function (error, errorcode, numscores, scores)
     */
    list: function(options, callback) {

        // defaults
        options.page = options.page || 1;
        options.perpage = options.perpage || 20;
        options.highest = options.lowest !== true;

        var query = {
            filter: {
                publickey: options.publickey,
                table: options.table
            },
            limit: options.perpage,
            skip: (options.page - 1) * options.perpage,
            sort: {}
        };

        // per-source website or device scores, websites
		// get truncated to domain.com
        if(options.source) {
            query.filter.source = options.source.indexOf("://") > -1 ? utils.baseurl(options.source) : options.source;
        }

        if(options.filters && Object.keys(options.filters).length > 0) {
            query.filter.fields = {};
            for(var x in options.filters) {
                query.filter.fields[x] = options.filters[x];
            }
        }

        // filtering for playerids
        var playerids = options.friendslist || [];

        if(options.playerid && !options.excludeplayerid) {
            playerids.push(options.playerid);
        }

		if(playerids.length > 1) {
            query.filter.playerid = { $in: playerids };
        } else if(playerids.length == 1) {
            query.filter.playerid = playerids[0];
        }

        // date mode
        options.mode = (options.mode || "alltime").toLowerCase();

        switch(options.mode) {
            case "today":
                query.filter.date = {"$gte": datetime.now - (24 * 60 * 60)};
                break;

           case "last7days":
               query.filter.date = {"$gte": (datetime.now - (7 * 24 * 60 * 60))};
                break;

            case "last30days":
                query.filter.date = {"$gte": (datetime.now - (30 * 24 * 60 * 60))};
                break;
        }

        // sorting
        if(options.mode == "newest") {
            query.sort = "-date";
        } else {
            query.sort = options.highest ? "-points" : "points";
        }

        // the scores
        db.LeaderboardScore.find(query.filter).sort(query.sort).limit(query.limit).skip(query.skip).exec(function(error, scores){

            if(error) {
                callback("unable to load scores: " + error + " (api.leaderboards.list:99)", errorcodes.GeneralError);
                return;
            }

            db.LeaderboardScore.count(query.filter, function(error, numscores) {

                if(error) {
                    callback("unable to count scores: " + error + " (api.leaderboards.list:104)", errorcodes.GeneralError);
                    return;
                }

                scores = scores || [];
                callback(null, errorcodes.NoError, numscores, clean(scores, query.skip + 1));
            });
        });
    },

    /**
     * Saves a score
     * @param options: url, name, points, auth, playerid, table, highest, allowduplicates, customfields ass. array
     * @param callback function(error, errorcode)
     */
    save: function(options, callback) {

        if(!options.playername) {
            callback("no name (" + options.playername + ")", errorcodes.InvalidName);
            return;
        }

        if(!options.table) {
            callback("no table name (" + options.table + ")", errorcodes.InvalidLeaderboardId);
            return;
        }

        if(options.source ) {
            options.source = utils.baseurl(options.source);
        }

        options.highest = options.lowest !== true;

        // small cleanup
        var score = {};

        // fields that aren't relevant to our score
        var exclude = ["allowduplicates", "highest", "lowest", "numfields", "section", "action",
                        "ip", "date", "url", "rank", "points", "page", "perpage", "global", "filters", "debug"];

        for(var x in options) {
            if(exclude.indexOf(x) > -1) {
                continue;
            }
            score[x] = options[x];
        }

        score.hash = md5([options.publickey, options.ip, options.table, options.playername,
                          options.playerid, options.highest, options.source].join("."));
        score.points = options.points;

        // check bans

        // insert
        if(options.allowduplicates === true) {
            var mscore = new db.LeaderboardScore(score);
            return mscore.save(function(error, item) {
                if(error) {
                    return callback("unable to insert score: " + error + " (api.leaderboards.save:166)", errorcodes.GeneralError);
                }

                return callback(null, errorcodes.NoError, item._id, item);
            });
        }

        // check for duplicates, by default we will assume highest unless lowest is explicitly specified
        var sort = options.highest ? "-score" : "score",
            query = {
                hash: score.hash
            };

        db.LeaderboardScore.findOne(query).sort(sort).exec(function(error, dupe) {
            if(error) {
                return callback("unable to check dupes: " + error + " (api.leaderboards.save:212)", errorcodes.GeneralError);
            }

            // no duplicates
            if(!dupe) {
                var mscore = new db.LeaderboardScore(score);
                return mscore.save(function(error) {

                    if(error) {
                        return callback("unable to insert score: " + error + " (api.leaderboards.save:212)", errorcodes.GeneralError);
                    }

                    return callback(null, errorcodes.NoError);
                });
            }

            // check if the new score is higher or lower
            if((dupe.points > score.points && options.highest) || (dupe.points < score.points && !options.highest)) {
                callback(null, errorcodes.NotBestScore);
                return;
            }

            db.LeaderboardScore.update( { _id: dupe._id }, { points: score.points, date: score.date, fields: score.fields }, { upsert: false }, function(error, item) {
                if(error) {
                    callback("unable to update score: " + error + " (api.leaderboards.save:240)", errorcodes.GeneralError);
                    return;
                }

                callback(null, errorcodes.NoError, item._id, item);
            });
        });
    },

    saveAndList: function(options, callback) {
        leaderboards.save(options, function(error, errorcode, insertedid, insertedscore) {
            if(error) {
                return callback(error + " (api.leaderboards.saveAndList:232)", errorcode);
            }

            var query = {
                table: options.table
            };

            if(options.excludeplayerid !== true && options.playerid) {
                query.playerid = options.playerid;
            }

            if(options.fields && Object.keys(options.fields).length > 0) {
                query.fields = options.fields;
            }

            if(options.hasOwnProperty("global")) {
                query.global = options.global;
            }

            if(options.hasOwnProperty("source")) {
                query.source = options.source;
            }

            // find the offset
            rank(query, options.highest, options.points, function(error, errorcode, before) {
                if(error) {
                    return callback(error + " (api.leaderboards.saveAndList:240)", errorcode);
                }
                // prepare our query for listing
                query.publickey = options.publickey;
                query.perpage = options.perpage;
                query.page = Math.floor(before / options.perpage) + 1;
                query.highest = options.lowest !== true;
                query.lowest = !query.highest;
                delete(query.points);
                leaderboards.list(query, function(error, errorcode, numscores, scores) {

                        if(scores && scores.length) {
                        for(var i=0, len=scores.length; i<len; i++) {
                            if(scores[i].points == options.points &&
                               scores[i].playerid == options.playerid &&
                               scores[i].playername == options.playername &&
                               scores[i].source == options.source) {
                                   scores[i].submitted = true;
                                   break;
                               }
                        }
                    }

                    return callback(error, errorcode, numscores, scores);
                });
            });
        });
    }
};

/**
 * Strips unnceessary data and tidies a score object
 */
function clean(scores, baserank) {
    var i, len, x, score,
        results = [];

    for(i=0, len=scores.length; i<len; i++) {
        score = scores[i].toObject();

        for(x in score) {
            if(typeof(score[x]) == "string") {
                score[x] = utils.unescape(score[x]);
            }
        }

        for(x in score.fields) {
            if(typeof(score.fields[x]) == "string") {
                score.fields[x] = utils.unescape(score.fields[x]);
            }
        }

        score.rank = baserank + i;
        score.scoreid = score._id.toString();
		score.rdate = utils.friendlyDate(utils.fromTimestamp(score.date));
        delete score._id;
        delete score.__v;
        delete score.hash;
        results.push(score);
    }
    return results;
}

// indexes provide a way to skip expensive mongodb count operations by tracking
// the rank position of points for specific leaderboard queries

var indexlist = [];
var index = {};/*
    hash: {
        hash: hash,
        query: query,
        highest: highest,
        scores: [ { points: 1000, scores: 7 }, { points: 989, scores: 1}],
        remove: [ { points: 1000, 3 } ],
        lastupdated: timestamp,
        lastused: timestamp
}*/

/*
 * Gets the rank of the provided points based on its query either from an existing
 * index, or manually while it creates a new index
 */
function rank(query, highest, points, callback) {

    var hash = md5(JSON.stringify(query) + "." + highest),
        newscore = { points: points, scores: 1, before: 0 },
        ind = index[hash];

    if(ind) {

        ind.lastused = datetime.now;
        if(ind.removeHash[points]) {
            return callback(null, errorcodes.NoError, ind.removeHash[points].before);
        }

        addToIndex(index, highest, newscore, function(o) {
            return callback(null, newscore.before);
        });
    }

    // set up our new index and chek against the database
    index[hash] = {
        key: hash,
        query: query,
        highest: highest,
        scores: [newscore],
        remove: [newscore],
        removeHash: {},
        lastupdated: 0,
        lastused: datetime.now
    };

    indexlist.push(index[hash]);
    indexlist.sort(function(a, b) { // todo: this could be better
        return a.lastupdated < b.lastupdated ? 1 : -1;
    });

    query.points = highest ? { $gte: points } : { $lte: points };
    db.LeaderboardScore.count(query, function(error, numscores) {
        return callback(error, error ? errorcodes.GeneralError : errorcodes.NoError, numscores);
    });
}

// asynchronously puts a new score in an index
function addToIndex(index, highest, newscore, callback) {
    var ai, i, len,
        found = false;

    function nextBlock() {
        len = i + 1000;
        if(len >= index.scores.length) {
            len = index.scores.length;
        }

        if(i >= len) {
            return callback(newscore);
        }

        for(i=i; i<len; i++) {
            ai = index.scores[i];

            // update the scores after us to have one more 'before'
            if(found) {
                ai.before++;
                continue;
            }

            // count the number of scores higher or lower depending on setting
            found = (highest && ai.points > newscore.points) || (!highest && ai.points < newscore.points);

            if(!found) {
                newscore.before += ai.scores;
                continue;
            }

            // insert our new score
            index.scores.splice(i, 0, newscore);
            index.remove.push(newscore);
            index.removeHash[newscore.points] = newscore;
       }

       return setTimeout(nextBlock, 100);
    }

    nextBlock();
}

// keep our indexes up to date
function refreshIndexes() {

    if (!indexlist.length) {
        return setTimeout(refreshIndexes, 1000);
    }

    var first = indexlist.shift();

    // dispose of indexes not used in the last 10 minutes
    if(first.lastused < datetime.now - 600) {
        index[first.hash] = null;
        delete(index[first.hash]);
        first = null;
        return refreshIndexes();
    }

    indexlist.push(first);

    // wait at least 30 seconds between updates
    if(datetime.now - first.lastcheck < 30) {
        return setTimeout(refreshIndexes, 1000);
    }

    // remove any scores we locally added
    var i, len, rem;

    for(i=0, len=first.remove.length; i<len; i++) {
       rem = first.remove[i];
       first.removeHash[rem.points] -= rem.scores;
    }

    // update the index
    first.query.date = { $gt: first.lastupdated };
    first.lastupdated = datetime.now;
    db.LeaderboardScore.find(first.query).sort(first.highest ? "-points" : "points").select("points date").exec(function(error, scores) {

        if(error) {
            return setTimeout(refreshIndexes, 1000);
        }

        if(!scores.length) {
            return setTimeout(refreshIndexes, 1000);
        }

        // add the new data
        var i, len, score;
        for(i=0, len=scores.length; i<len; i++)  {
            score = scores[i];

            var newscore = { points: score.points, scores: 1, before: 0 };
            addToIndex(first, first.highest, newscore);

            if(score.date > first.lastupdated) {
                first.lastupdated = score.date;
            }
        }

        return setTimeout(refreshIndexes, 1000);
    });
}

refreshIndexes();
<|endoftext|>


<commit_before>/*©agpl*************************************************************************
*                                                                              *
* This file is part of FRIEND UNIFYING PLATFORM.                               *
* Copyright (c) Friend Software Labs AS. All rights reserved.                  *
*                                                                              *
* Licensed under the Source EULA. Please refer to the copy of the GNU Affero   *
* General Public License, found in the file license_agpl.txt.                  *
*                                                                              *
*****************************************************************************©*/

Application.run = function( msg, iface )
{
	var nd = new Library( 'system.library' );
	nd.execute( 'file/makedir', { path: 'Home:Notes' } );

	var w = new View( {
		'title'     : 'Notes',
		'width'     : 1290,
		'height'    : 800,
		'min-width' : 700,
		'min-height': 400
	} );

	this.mainView = w;

	w.onClose = function( closeWindow )
	{
		/*if( !w.saved )
		{
			Confirm( 'Are you sure?', 'By closing the application you may lose unsaved data.', function( res )
			{
				if( res.data )
				{
					Application.quit();
				}
				else
				{
					closeWindow( false );
				}
			} );
		}*/
		Application.quit();
		return false;
	}

	w.setMenuItems( [
		{
			name: i18n( 'menu_file' ),
			items: [
				{
					name: i18n( 'menu_new' ),
					command: 'new'
				},
				{
					name: i18n( 'menu_load' ),
					command: 'load'
				},
				{
					name: i18n( 'menu_save' ),
					command: 'save'
				},
				{
					name: i18n( 'menu_save_as' ),
					command: 'save_as'
				},
				{
					name: i18n( 'menu_print' ),
					command: 'print'
				},
				/*{
					name: i18n( 'menu_print_remote' ),
					command: 'print_remote'
				},*/
				{
					name: i18n( 'menu_quit' ),
					command: 'quit'
				}
			]
		},
		{
			name: i18n( 'menu_document' ),
			items: [
				{
					name: i18n( 'menu_insert_image' ),
					command: 'insertimage'
				},
				{
					name: i18n( 'menu_convert_images_inline' ),
					command: 'makeinlineimages'
				}
			]
		},
		{
			name: i18n( 'menu_preferences' ),
			items: [
				{
					name: i18n( 'menu_preferences' ),
					command: 'showprefs'
				}/*,
				{
					name: i18n( 'menu_vr_features' ),
					command: 'togglevr'
				}*/
			]
		}
	] );

	var f = new File( 'Progdir:Templates/maingui.html' );
	f.replacements = {
		'i18n_search' : i18n('i18n_search'),
		'i18n_find'   : i18n('i18n_find'),
		'i18n_select' : i18n('i18n_select')
	};
	f.onLoad = function( data )
	{
		w.setContent( data, function()
		{
			// Open by path
			if( msg.args && typeof( msg.args ) != 'undefined' )
			{
				//console.log( 'What happens: ', msg.args );
				w.sendMessage( { command: 'loadfiles', files: [ { Path: msg.args } ] } );
			}
			else if( Application.sessionObject && Application.sessionObject.content )
			{
				if( Application.sessionObject.currentDocument )
				{
					w.sendMessage( { command: 'loadfiles', files: [ { Path: Application.sessionObject.currentDocument } ] } );
					return;
				}

				var msng = {
					command: 'newdocument',
					content: Application.sessionObject.content,
					scrollTop: Application.sessionObject.scrollTop,
					browserPath: 'Home:Notes/'
				};
				w.sendMessage( msng );

				if( Application.sessionObject.currentDocument )
				{
					Application.wholeFilename = Application.sessionObject.currentDocument;
				}

				if( Application.sessionObject.currentDocument )
				{
					Application.wholeFilename = Application.sessionObject.currentDocument;
					this.setCorrectTitle();
				}
			}
			else
			{
				w.sendMessage( {
					command: 'newdocument',
					content: '',
					browserPath: 'Home:Notes/'
				} );
			}
		} );
	}
	f.load();

	/*var noti = new View( { title: 'Notice', width: 300, height: 300 } );
	var cf = new File( 'Progdir:Templates/notice.html' );
	cf.onLoad = function( data )
	{
		noti.setContent( data );
	}
	cf.load();*/
}

// Return the current state of the application
Application.sessionStateGet = function()
{
	if( this.sessionObject && this.sessionObject.content )
	{
		return JSON.stringify( {
			currentDocument: this.wholeFilename,
			content: this.sessionObject.content,
			scrollTop: this.sessionObject.scrollTop
		} );
	}
	return JSON.stringify( { content: '', scrollTop: 0 } );
}

Application.handleKeys = function( k, e )
{
	if( e.ctrlKey )
	{
		if( k == 79 )
		{
			this.load();
			return true;
		}
		else if( k == 83 )
		{
			this.save();
			return true;
		}
		// n (doesn't work, find a different key)
		else if( k == 78 )
		{
			this.newFile();
			return true;
		}
		else if( k == 81 )
		{
			this.quit();
			return true;
		}
		// CTRL + I
		else if( k == 73 )
		{
			this.closeFile();
			return true;
		}
		//console.log( k );
	}
	return false;
}

// Toggle VR gui features
Application.toggleVR = function()
{

}

Application.newDocument = function()
{
	this.sessionObject = {};
	this.wholeFilename = '';
	this.mainView.setFlag( 'title', 'Notes' );
	this.mainView.sendMessage( {
		command: 'newdocument'
	} );
}

// Prints a file
Application.print = function()
{
	if( !Application.wholeFilename )
	{
		Alert( i18n( 'i18n_print_alert' ), i18n( 'i18n_not_saved_cant_print' ) );
		return;
	}
	/*if( this.printDialog ) return;
	var w = new View( {
		title: 'Print preview',
		width: 700,
		height: 800
	} );
	this.printDialog = w;
	*/
	Application.mainView.sendMessage( {
		command: 'print',
		path: Application.wholeFilename
	} );
}

// Loads a file
Application.load = function()
{
	if( this.fileDialog ) return;

	var flags = {
		multiSelect: false,
		suffix: 'html',
		triggerFunction: function( arr )
		{
			if( arr )
			{
				Application.mainView.sendMessage( {
					command: 'loadfiles',
					files: arr
				} );
				Application.wholeFilename = arr[0].Path;
				Application.mainView.setFlag( 'title', 'Notes - ' + Application.wholeFilename );
			}
			Application.fileDialog = false;
		},
		path: false,
		mainView: this.mainView,
		type: 'load',
		suffix: [ 'html', 'htm' ]
	};

	var f = new Filedialog( flags );
	this.fileDialog = f;
}

Application.saveAs = function()
{
	this.prevFilename = this.wholeFilename;
	this.wholeFilename = false;
	this.save( 'saveas' );
}

// Saves current file
Application.save = function( mode )
{
	if( this.wholeFilename )
	{
		Application.mainView.sendMessage( {
			command: 'savefile',
			path: Application.wholeFilename
		} );
	}
	else
	{
		var flags = {
			type: 'save',
			triggerFunction: function( fname )
			{
				if( !fname || !fname.length )
				{
					if( Application.prevFilename )
					{
						Application.wholeFilename = Application.prevFilename;
						Application.prevFilename = false;
					}
					return;
				}

				if( fname.indexOf( '.' ) < 0 )
					fname += '.html';
				Application.mainView.sendMessage( {
					command: 'savefile',
					path: fname
				} );
				Application.wholeFilename = fname;
				Application.mainView.setFlag( 'title', 'Notes - ' + fname );
			},
			mainView: this.mainView,
			title: mode == 'saveas' ? i18n( 'i18n_save_as' ) : i18n( 'i18n_save' ),
			suffix: [ 'html', 'htm' ]
		};

		var f = new Filedialog( flags );
	}
}

Application.insertImage = function( file )
{
	this.mainView.sendMessage( {
		command: 'insertimage',
		path: file
	} );
}

Application.showPrefs = function()
{
	if( this.pwin )
	{
		return this.pwin.activate();
	}
	this.pwin = new View( {
		title: i18n('i18n_preferences'),
		width: 800,
		height: 500,
		id: 'authorprefswin'
	} );

	this.pwin.onClose = function()
	{
		Application.pwin = false;
	}

	var f = new File( 'Progdir:Templates/preferences.html' );
	f.onLoad = function( data )
	{
		Application.pwin.setContent( data );
	}
	f.i18n();
	f.load();
}

function sanitizeFilename( data )
{
	if( !data ) return '';
	var filename = data.split( ':' )[1];
	if( filename.indexOf( '/' ) > 0 )
		filename = filename.split( '/' ).pop();
	filename = filename.split( '.' );
	filename.pop();
	filename = filename.join( '.' );
	return filename;
}

Application.setCorrectTitle = function()
{
	if( this.currentViewMode == 'files' )
	{
		var cand = '';
		if( this.browserPath )
		{
			cand = this.browserPath;
			if( cand.indexOf( '/' ) > 0 )
			{
				cand = cand.split( '/' );
				cand.pop();
				cand = cand.join( '/' );
				if( cand.indexOf( '/' ) > 0 )
				{
					cand = cand.split( '/' ).pop();
				}
				else
				{
					cand = cand.split( ':' ).pop();
				}
				if( cand == 'Notes' )
					cand = i18n( 'i18n_uncategorized' );
			}
			else
			{
				cand = i18n( 'i18n_uncategorized' );
			}
		}
		else
		{
			cand = i18n( 'i18n_uncategorized' );
		}
		Application.mainView.setFlag( 'title', 'Notes - ' + cand );
	}
	else if( this.currentViewMode == 'root' )
	{
		Application.mainView.setFlag( 'title', 'Notes - ' + i18n( 'i18n_categories' ) );
	}
	else
	{
		Application.mainView.setFlag( 'title', 'Notes - ' + sanitizeFilename( Application.wholeFilename ) );
	}
}

Application.receiveMessage = function( msg )
{
	if( !msg.command ) return;
	switch( msg.command )
	{
		case 'updateViewMode':
			this.currentViewMode = msg.mode;
			if( isMobile )
			{
				var mode = msg.mode;
				if( mode == 'notes' || mode == 'files' )
				{
					var v = this.mainView;
					v.showBackButton( true, function()
					{
						v.sendMessage( { command: 'mobilebackbutton' } );
					} );
				}
				else
				{
					this.mainView.showBackButton( false );
				}
			}
			this.browserPath = msg.browserPath;
			this.setCorrectTitle();
			break;
		case 'setfilename':
			this.wholeFilename = msg.data;
			this.setCorrectTitle();
			break;
		case 'newdocument':
			this.wholeFilename = '';
			break;
		case 'applystyle':
			this.mainView.sendMessage( msg );
			break;
		case 'togglevr':
			this.toggleVR();
			break;
		case 'closeprefs':
			this.pwin.close();
			this.pwin = false;
			break;
		case 'currentfile':
			this.fileName = msg.filename;
			this.path = msg.path;
			this.wholeFilename = msg.path + msg.filename;
			this.setCorrectTitle();
			break;
		case 'openfile':
			this.load();
			break;
		case 'keydown':
			this.handleKeys( msg.key, { ctrlKey: msg.ctrlKey } );
			break;
		case 'quit':
			this.quit();
			break;
		case 'new':
			this.newDocument();
			break;
		case 'print':
			var p = new Printdialog( {
				path: this.wholeFilename
			} );
			//this.mainView.sendMessage( { command: 'print_iframe' } );
			break;
		case 'print_remote':
			this.print();
			break;
		case 'remembercontent':
			this.sessionObject.content = msg.data;
			this.sessionObject.scrollTop = msg.scrollTop;
			if( msg.path )
			{
				this.wholeFilename = msg.path;
				this.setCorrectTitle();
			}
			break;
		case 'syncload':
			if( msg.filename )
			{
				this.wholeFilename = msg.filename;
				this.setCorrectTitle();
			}
			break;
		case 'load':
			this.load();
			break;
		case 'save':
			this.save();
			break;
		case 'save_as':
			this.saveAs();
			break;
		// Make sure we can activate window
		case 'activate':
			this.mainView.activate();
			break;
		// Show preferences
		case 'showprefs':
			this.showPrefs();
			break;
		case 'makeinlineimages':
			this.mainView.sendMessage( msg );
			break;
		case 'insertimage':
			var f = new Filedialog( this.mainView, function( items )
			{
				for( var a = 0; a < items.length; a++ )
				{
					Application.insertImage( items[a].Path );
				}
			}, 'Mountlist:', 'load' );
			break;
	}
}

<commit_msg>Just doing debugging.<commit_after>/*©agpl*************************************************************************
*                                                                              *
* This file is part of FRIEND UNIFYING PLATFORM.                               *
* Copyright (c) Friend Software Labs AS. All rights reserved.                  *
*                                                                              *
* Licensed under the Source EULA. Please refer to the copy of the GNU Affero   *
* General Public License, found in the file license_agpl.txt.                  *
*                                                                              *
*****************************************************************************©*/

Application.run = function( msg, iface )
{
	var nd = new Library( 'system.library' );
	nd.execute( 'file/makedir', { path: 'Home:Notes' } );

	var w = new View( {
		'title'     : 'Notes',
		'width'     : 1290,
		'height'    : 800,
		'min-width' : 700,
		'min-height': 400
	} );

	this.mainView = w;

	w.onClose = function( closeWindow )
	{
		Application.quit();
		return false;
	}

	// Set up the main menu items ----------------------------------------------
	w.setMenuItems( [
		{
			name: i18n( 'menu_file' ),
			items: [
				{
					name: i18n( 'menu_new' ),
					command: 'new'
				},
				{
					name: i18n( 'menu_load' ),
					command: 'load'
				},
				{
					name: i18n( 'menu_save' ),
					command: 'save'
				},
				{
					name: i18n( 'menu_save_as' ),
					command: 'save_as'
				},
				{
					name: i18n( 'menu_print' ),
					command: 'print'
				},
				{
					name: i18n( 'menu_quit' ),
					command: 'quit'
				}
			]
		},
		{
			name: i18n( 'menu_document' ),
			items: [
				{
					name: i18n( 'menu_insert_image' ),
					command: 'insertimage'
				},
				{
					name: i18n( 'menu_convert_images_inline' ),
					command: 'makeinlineimages'
				}
			]
		},
		{
			name: i18n( 'menu_preferences' ),
			items: [
				{
					name: i18n( 'menu_preferences' ),
					command: 'showprefs'
				}
			]
		}
	] );

	var f = new File( 'Progdir:Templates/maingui.html' );
	f.replacements = {
		'i18n_search' : i18n('i18n_search'),
		'i18n_find'   : i18n('i18n_find'),
		'i18n_select' : i18n('i18n_select')
	};
	f.onLoad = function( data )
	{
		w.setContent( data, function()
		{
			// Open by path
			if( msg.args && typeof( msg.args ) != 'undefined' )
			{
				console.log( 'What happens: ', msg.args );
				w.sendMessage( { command: 'loadfiles', files: [ { Path: msg.args } ] } );
			}
			else if( Application.sessionObject && Application.sessionObject.content )
			{
				if( Application.sessionObject.currentDocument )
				{
					console.log( 'Loading from session object.' );
					w.sendMessage( { command: 'loadfiles', files: [ { Path: Application.sessionObject.currentDocument } ] } );
					return;
				}

				console.log( 'Making a new document.' );

				var msng = {
					command: 'newdocument',
					content: Application.sessionObject.content,
					scrollTop: Application.sessionObject.scrollTop,
					browserPath: 'Home:Notes/'
				};
				w.sendMessage( msng );

				if( Application.sessionObject.currentDocument )
				{
					Application.wholeFilename = Application.sessionObject.currentDocument;
				}

				if( Application.sessionObject.currentDocument )
				{
					Application.wholeFilename = Application.sessionObject.currentDocument;
					this.setCorrectTitle();
				}
			}
			else
			{
				w.sendMessage( {
					command: 'newdocument',
					content: '',
					browserPath: 'Home:Notes/'
				} );
			}
		} );
	}
	f.load();

	/*var noti = new View( { title: 'Notice', width: 300, height: 300 } );
	var cf = new File( 'Progdir:Templates/notice.html' );
	cf.onLoad = function( data )
	{
		noti.setContent( data );
	}
	cf.load();*/
}

// Return the current state of the application
Application.sessionStateGet = function()
{
	if( this.sessionObject && this.sessionObject.content )
	{
		return JSON.stringify( {
			currentDocument: this.wholeFilename,
			content: this.sessionObject.content,
			scrollTop: this.sessionObject.scrollTop
		} );
	}
	return JSON.stringify( { content: '', scrollTop: 0 } );
}

Application.handleKeys = function( k, e )
{
	if( e.ctrlKey )
	{
		if( k == 79 )
		{
			this.load();
			return true;
		}
		else if( k == 83 )
		{
			this.save();
			return true;
		}
		// n (doesn't work, find a different key)
		else if( k == 78 )
		{
			this.newFile();
			return true;
		}
		else if( k == 81 )
		{
			this.quit();
			return true;
		}
		// CTRL + I
		else if( k == 73 )
		{
			this.closeFile();
			return true;
		}
		//console.log( k );
	}
	return false;
}

// Toggle VR gui features
Application.toggleVR = function()
{

}

Application.newDocument = function()
{
	this.sessionObject = {};
	this.wholeFilename = '';
	this.mainView.setFlag( 'title', 'Notes' );
	this.mainView.sendMessage( {
		command: 'newdocument'
	} );
}

// Prints a file
Application.print = function()
{
	if( !Application.wholeFilename )
	{
		Alert( i18n( 'i18n_print_alert' ), i18n( 'i18n_not_saved_cant_print' ) );
		return;
	}
	/*if( this.printDialog ) return;
	var w = new View( {
		title: 'Print preview',
		width: 700,
		height: 800
	} );
	this.printDialog = w;
	*/
	Application.mainView.sendMessage( {
		command: 'print',
		path: Application.wholeFilename
	} );
}

// Loads a file
Application.load = function()
{
	if( this.fileDialog ) return;

	var flags = {
		multiSelect: false,
		suffix: 'html',
		triggerFunction: function( arr )
		{
			if( arr )
			{
				Application.mainView.sendMessage( {
					command: 'loadfiles',
					files: arr
				} );
				Application.wholeFilename = arr[0].Path;
				Application.mainView.setFlag( 'title', 'Notes - ' + Application.wholeFilename );
			}
			Application.fileDialog = false;
		},
		path: false,
		mainView: this.mainView,
		type: 'load',
		suffix: [ 'html', 'htm' ]
	};

	var f = new Filedialog( flags );
	this.fileDialog = f;
}

Application.saveAs = function()
{
	this.prevFilename = this.wholeFilename;
	this.wholeFilename = false;
	this.save( 'saveas' );
}

// Saves current file
Application.save = function( mode )
{
	if( this.wholeFilename )
	{
		Application.mainView.sendMessage( {
			command: 'savefile',
			path: Application.wholeFilename
		} );
	}
	else
	{
		var flags = {
			type: 'save',
			triggerFunction: function( fname )
			{
				if( !fname || !fname.length )
				{
					if( Application.prevFilename )
					{
						Application.wholeFilename = Application.prevFilename;
						Application.prevFilename = false;
					}
					return;
				}

				if( fname.indexOf( '.' ) < 0 )
					fname += '.html';
				Application.mainView.sendMessage( {
					command: 'savefile',
					path: fname
				} );
				Application.wholeFilename = fname;
				Application.mainView.setFlag( 'title', 'Notes - ' + fname );
			},
			mainView: this.mainView,
			title: mode == 'saveas' ? i18n( 'i18n_save_as' ) : i18n( 'i18n_save' ),
			suffix: [ 'html', 'htm' ]
		};

		var f = new Filedialog( flags );
	}
}

Application.insertImage = function( file )
{
	this.mainView.sendMessage( {
		command: 'insertimage',
		path: file
	} );
}

Application.showPrefs = function()
{
	if( this.pwin )
	{
		return this.pwin.activate();
	}
	this.pwin = new View( {
		title: i18n('i18n_preferences'),
		width: 800,
		height: 500,
		id: 'authorprefswin'
	} );

	this.pwin.onClose = function()
	{
		Application.pwin = false;
	}

	var f = new File( 'Progdir:Templates/preferences.html' );
	f.onLoad = function( data )
	{
		Application.pwin.setContent( data );
	}
	f.i18n();
	f.load();
}

function sanitizeFilename( data )
{
	if( !data ) return '';
	var filename = data.split( ':' )[1];
	if( filename.indexOf( '/' ) > 0 )
		filename = filename.split( '/' ).pop();
	filename = filename.split( '.' );
	filename.pop();
	filename = filename.join( '.' );
	return filename;
}

Application.setCorrectTitle = function()
{
	if( this.currentViewMode == 'files' )
	{
		var cand = '';
		if( this.browserPath )
		{
			cand = this.browserPath;
			if( cand.indexOf( '/' ) > 0 )
			{
				cand = cand.split( '/' );
				cand.pop();
				cand = cand.join( '/' );
				if( cand.indexOf( '/' ) > 0 )
				{
					cand = cand.split( '/' ).pop();
				}
				else
				{
					cand = cand.split( ':' ).pop();
				}
				if( cand == 'Notes' )
					cand = i18n( 'i18n_uncategorized' );
			}
			else
			{
				cand = i18n( 'i18n_uncategorized' );
			}
		}
		else
		{
			cand = i18n( 'i18n_uncategorized' );
		}
		Application.mainView.setFlag( 'title', 'Notes - ' + cand );
	}
	else if( this.currentViewMode == 'root' )
	{
		Application.mainView.setFlag( 'title', 'Notes - ' + i18n( 'i18n_categories' ) );
	}
	else
	{
		Application.mainView.setFlag( 'title', 'Notes - ' + sanitizeFilename( Application.wholeFilename ) );
	}
}

Application.receiveMessage = function( msg )
{
	if( !msg.command ) return;
	switch( msg.command )
	{
		case 'updateViewMode':
			this.currentViewMode = msg.mode;
			if( isMobile )
			{
				var mode = msg.mode;
				if( mode == 'notes' || mode == 'files' )
				{
					var v = this.mainView;
					v.showBackButton( true, function()
					{
						v.sendMessage( { command: 'mobilebackbutton' } );
					} );
				}
				else
				{
					this.mainView.showBackButton( false );
				}
			}
			this.browserPath = msg.browserPath;
			this.setCorrectTitle();
			break;
		case 'setfilename':
			this.wholeFilename = msg.data;
			this.setCorrectTitle();
			break;
		case 'newdocument':
			this.wholeFilename = '';
			break;
		case 'applystyle':
			this.mainView.sendMessage( msg );
			break;
		case 'togglevr':
			this.toggleVR();
			break;
		case 'closeprefs':
			this.pwin.close();
			this.pwin = false;
			break;
		case 'currentfile':
			this.fileName = msg.filename;
			this.path = msg.path;
			this.wholeFilename = msg.path + msg.filename;
			this.setCorrectTitle();
			break;
		case 'openfile':
			this.load();
			break;
		case 'keydown':
			this.handleKeys( msg.key, { ctrlKey: msg.ctrlKey } );
			break;
		case 'quit':
			this.quit();
			break;
		case 'new':
			this.newDocument();
			break;
		case 'print':
			var p = new Printdialog( {
				path: this.wholeFilename
			} );
			//this.mainView.sendMessage( { command: 'print_iframe' } );
			break;
		case 'print_remote':
			this.print();
			break;
		case 'remembercontent':
			this.sessionObject.content = msg.data;
			this.sessionObject.scrollTop = msg.scrollTop;
			if( msg.path )
			{
				this.wholeFilename = msg.path;
				this.setCorrectTitle();
			}
			break;
		case 'syncload':
			if( msg.filename )
			{
				this.wholeFilename = msg.filename;
				this.setCorrectTitle();
			}
			break;
		case 'load':
			this.load();
			break;
		case 'save':
			this.save();
			break;
		case 'save_as':
			this.saveAs();
			break;
		// Make sure we can activate window
		case 'activate':
			this.mainView.activate();
			break;
		// Show preferences
		case 'showprefs':
			this.showPrefs();
			break;
		case 'makeinlineimages':
			this.mainView.sendMessage( msg );
			break;
		case 'insertimage':
			var f = new Filedialog( this.mainView, function( items )
			{
				for( var a = 0; a < items.length; a++ )
				{
					Application.insertImage( items[a].Path );
				}
			}, 'Mountlist:', 'load' );
			break;
	}
}

<|endoftext|>


<commit_before>var taskList = function taskList (spec) {
  spec = spec || {};

  var that = {

    name: spec.name || 'Task List',

    tasks: spec.tasks || [],

    add: function add (task) {
      var newlen = that.tasks.push(task);
      localStorage.setItem(that.name, JSON.stringify(that.tasks));
      return (newlen - 1); // index of new entry
    },

    remove: function remove (taskId) {
      var removed = that.tasks.splice(taskId, 1);
      localStorage.setItem(that.name, JSON.stringify(that.tasks));
      return (removed.length > 0) ? true: false;
    },

    get: function get (taskId) {
      return that.tasks[taskId];
    },

    getAll: function getAll (taskId) {
      return that.tasks;
    },

    getName: function getName () {
      return that.name;
    },

    find: function find (task) {
      return that.tasks.indexOf(task);
    },

    search: function search (pattern, flags) {
      flags = flags || 'i';
      if (typeof pattern === 'string') {
        pattern = new RegExp(pattern, flags);
      }
      if (! pattern instanceof RegExp) {
        return [];
      } else {
        return that.tasks.filter(function (task) { return pattern.test(task); });
      }
    }
  },
  localItems = localStorage.getItem(that.name),
  tmpTasks;

  if (localItems) {
    tmpTasks = JSON.parse(localItems);
    if (tmpTasks instanceof Array) {
      that.tasks.concat(tmpTasks);
    }
  }

  console.log('found',spec.tasks.length,'tasks');

  if (typeof Array.prototype.forEach === 'function') {
    // real browser, or IE >=9
    console.log('using Array.prototype.forEach');
    that.forEach = function forEach (fn) {
      that.tasks.forEach(fn);
    };
  } else {
    // last resort - fake it
    console.log('using local forEach');
    that.forEach = function forEach (fn) {
      var len = that.tasks.length,
          i = 0;

      if (typeof fn !== 'function') {
        throw new TypeError();
      }

      for (; i < len; i++) {
        fn.call(void 0, that.tasks[i], i, that.tasks);
      }
    };
  }

  return that;
};

<commit_msg>removed console logging<commit_after>var taskList = function taskList (spec) {
  spec = spec || {};

  var that = {

    name: spec.name || 'Task List',

    tasks: spec.tasks || [],

    add: function add (task) {
      var newlen = that.tasks.push(task);
      localStorage.setItem(that.name, JSON.stringify(that.tasks));
      return (newlen - 1); // index of new entry
    },

    remove: function remove (taskId) {
      var removed = that.tasks.splice(taskId, 1);
      localStorage.setItem(that.name, JSON.stringify(that.tasks));
      return (removed.length > 0) ? true: false;
    },

    get: function get (taskId) {
      return that.tasks[taskId];
    },

    getAll: function getAll (taskId) {
      return that.tasks;
    },

    getName: function getName () {
      return that.name;
    },

    find: function find (task) {
      return that.tasks.indexOf(task);
    },

    search: function search (pattern, flags) {
      flags = flags || 'i';
      if (typeof pattern === 'string') {
        pattern = new RegExp(pattern, flags);
      }
      if (! pattern instanceof RegExp) {
        return [];
      } else {
        return that.tasks.filter(function (task) { return pattern.test(task); });
      }
    }
  },
  localItems = localStorage.getItem(that.name),
  tmpTasks;

  if (localItems) {
    tmpTasks = JSON.parse(localItems);
    if (tmpTasks instanceof Array) {
      that.tasks.concat(tmpTasks);
    }
  }

  if (typeof Array.prototype.forEach === 'function') {
    // real browser, or IE >=9
    that.forEach = function forEach (fn) {
      that.tasks.forEach(fn);
    };
  } else {
    // last resort - fake it
    that.forEach = function forEach (fn) {
      var len = that.tasks.length,
          i = 0;

      if (typeof fn !== 'function') {
        throw new TypeError();
      }

      for (; i < len; i++) {
        fn.call(void 0, that.tasks[i], i, that.tasks);
      }
    };
  }

  return that;
};

<|endoftext|>


<commit_before>import React, {PropTypes} from 'react'
import {connect} from 'react-redux'
import {bindActionCreators} from 'redux'
import {getKapacitor} from 'src/shared/apis'
import * as kapacitorActionCreators from '../actions/view'
import KapacitorRules from 'src/kapacitor/components/KapacitorRules'

const {
  arrayOf,
  func,
  shape,
  string,
} = PropTypes

export const KapacitorRulesPage = React.createClass({
  propTypes: {
    source: shape({
      id: string.isRequired,
      links: shape({
        proxy: string.isRequired,
        self: string.isRequired,
        kapacitors: string.isRequired,
      }),
    }),
    rules: arrayOf(shape({
      name: string.isRequired,
      trigger: string.isRequired,
      message: string.isRequired,
      alerts: arrayOf(string.isRequired).isRequired,
    })).isRequired,
    actions: shape({
      fetchRules: func.isRequired,
      deleteRule: func.isRequired,
      updateRuleStatus: func.isRequired,
    }).isRequired,
    addFlashMessage: func,
  },

  getInitialState() {
    return {
      hasKapacitor: false,
      loading: true,
      fooRule: 'HAI',
    };
  },

  componentDidMount() {
    getKapacitor(this.props.source).then((kapacitor) => {
      if (kapacitor) {
        this.props.actions.fetchRules(kapacitor);
      }
      this.setState({loading: false, hasKapacitor: !!kapacitor});
    });
  },

  handleDeleteRule(rule) {
    const {actions} = this.props;
    actions.deleteRule(rule);
  },

  handleRuleStatus(rule) {
    const {actions} = this.props
    const status = rule.status === 'enabled' ? 'disabled' : 'enabled'

    actions.updateRuleStatus(rule, status)
    actions.updateRuleStatusSuccess(rule.id, status)
  },

  render() {
    const {source, rules} = this.props
    const {hasKapacitor, loading} = this.state

    return (
      <KapacitorRules
        source={source}
        rules={rules}
        hasKapacitor={hasKapacitor}
        loading={loading}
        onDelete={this.handleDeleteRule}
        onChangeRuleStatus={this.handleRuleStatus}
      />
    )
  },
});

function mapStateToProps(state) {
  return {
    rules: Object.values(state.rules),
  };
}

function mapDispatchToProps(dispatch) {
  return {
    actions: bindActionCreators(kapacitorActionCreators, dispatch),
  };
}

export default connect(mapStateToProps, mapDispatchToProps)(KapacitorRulesPage);
<commit_msg>Update container to extend Component<commit_after>import React, {PropTypes, Component} from 'react'
import {connect} from 'react-redux'
import {bindActionCreators} from 'redux'
import {getKapacitor} from 'src/shared/apis'
import * as kapacitorActionCreators from '../actions/view'
import KapacitorRules from 'src/kapacitor/components/KapacitorRules'

class KapacitorRulesPage extends Component {
  constructor(props) {
    super(props);
    this.state = {
      hasKapacitor: false,
      loading: true,
    }

    this.handleDeleteRule = this.handleDeleteRule.bind(this)
    this.handleRuleStatus = this.handleRuleStatus.bind(this)
  }

  componentDidMount() {
    getKapacitor(this.props.source).then((kapacitor) => {
      if (kapacitor) {
        this.props.actions.fetchRules(kapacitor);
      }
      this.setState({loading: false, hasKapacitor: !!kapacitor});
    });
  }

  handleDeleteRule(rule) {
    const {actions} = this.props
    actions.deleteRule(rule)
  }

  handleRuleStatus(rule) {
    const {actions} = this.props
    const status = rule.status === 'enabled' ? 'disabled' : 'enabled'

    actions.updateRuleStatus(rule, status)
    actions.updateRuleStatusSuccess(rule.id, status)
  }

  render() {
    const {source, rules} = this.props
    const {hasKapacitor, loading} = this.state

    return (
      <KapacitorRules
        source={source}
        rules={rules}
        hasKapacitor={hasKapacitor}
        loading={loading}
        onDelete={this.handleDeleteRule}
        onChangeRuleStatus={this.handleRuleStatus}
      />
    )
  }
}

const {
  arrayOf,
  func,
  shape,
  string,
} = PropTypes

KapacitorRulesPage.propTypes = {
  source: shape({
    id: string.isRequired,
    links: shape({
      proxy: string.isRequired,
      self: string.isRequired,
      kapacitors: string.isRequired,
    }),
  }),
  rules: arrayOf(shape({
    name: string.isRequired,
    trigger: string.isRequired,
    message: string.isRequired,
    alerts: arrayOf(string.isRequired).isRequired,
  })).isRequired,
  actions: shape({
    fetchRules: func.isRequired,
    deleteRule: func.isRequired,
    updateRuleStatus: func.isRequired,
  }).isRequired,
  addFlashMessage: func,
}

const mapStateToProps = (state) => {
  return {
    rules: Object.values(state.rules),
  }
}

const mapDispatchToProps = (dispatch) => {
  return {
    actions: bindActionCreators(kapacitorActionCreators, dispatch),
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(KapacitorRulesPage)
<|endoftext|>


<commit_before>var systemError = require( '../utils' ).systemError;

exports.MongooseDataManager = function ( model ) {
    return {
        create: function ( data, callback ) {
            model.create( data, function ( err, result ) {
                if ( err ) {
                    return callback( systemError( err ) );
                }
                return callback( null, result );
            } );
        },
        list: function ( data, callback ) {
            model.find( data, function ( err, results ) {
                if ( err ) {
                    return callback( systemError( err ) );
                }
                return callback( null, results );
            } );
        },
        read: function ( id, callback ) {
            model.findById( id, function ( err, result ) {
                if ( err ) {
                    return callback( systemError( err ) );
                }
                return callback( null, result );
            } );
        },
        update: function ( id, update, callback ) {
            model.findByIdAndUpdate( id, update, function ( err, result ) {
                if ( err ) {
                    return callback( systemError( err ) );
                }
                return callback( null, result );
            } );
        },
        delete: function ( id, callback ) {
            model.findByIdAndRemove( id, function ( err, result ) {
                if ( err ) {
                    return callback( systemError( err ) );
                }
                return callback( null, {} );
            } );
        }
    };
};
<commit_msg>Add optional fields argument to list and read<commit_after>var systemError = require( '../utils' ).systemError;

exports.MongooseDataManager = function ( model ) {
    return {
        create: function ( data, callback ) {
            model.create( data, function ( err, result ) {
                if ( err ) {
                    return callback( systemError( err ) );
                }
                return callback( null, result );
            } );
        },
        list: function ( data, fields, callback ) {
            var query = model.find( data );

            if ( arguments.length === 2 ) {
                callback = fields;
            } else {
                query.select( fields );
            }

            query.exec( function ( err, results ) {
                if ( err ) {
                    return callback( systemError( err ) );
                }
                return callback( null, results );
            } );
        },
        read: function ( id, fields, callback ) {
            var query = model.findById( id );

            if ( arguments.length === 2 ) {
                callback = fields;
            } else {
                query.select( fields );
            }

            query.exec( function ( err, result ) {
                if ( err ) {
                    return callback( systemError( err ) );
                }
                return callback( null, result );
            } );
        },
        update: function ( id, update, callback ) {
            model.findByIdAndUpdate( id, update, function ( err, result ) {
                if ( err ) {
                    return callback( systemError( err ) );
                }
                return callback( null, result );
            } );
        },
        delete: function ( id, callback ) {
            model.findByIdAndRemove( id, function ( err, result ) {
                if ( err ) {
                    return callback( systemError( err ) );
                }
                return callback( null, {} );
            } );
        }
    };
};
<|endoftext|>


<commit_before>define("ace/snippets/ftl",["require","exports","module"], function(require, exports, module) {
"use strict";

exports.snippetText =undefined;
exports.scope = "ftl";

});
<commit_msg>Update public/libs/bower_components/ace-builds/src/snippets/ftl.js<commit_after><|endoftext|>


<commit_before>// Add your blacklisted sites to this array. Subdomain and TLD are optional and flexible.
// Should probably be kept in sync with https://github.com/premgane/agolo-twitterbot/blob/master/server.py
var BLACKLIST = [
  'github',
  'agolo.com',
  'youtube',
  'youtu.be',
  'atlassian.net',
  'spotify.com',
  'twitter.com',
  'mail.google',
  'google.com'
  'imgur.com',
  'bit.ly',
  'tinyurl',
  'vine',
  'dropbox',
  'slack',
  'notion.so',
  'zoom.us',
  'appear.in'
];

/** Convert the array to an object and export it **/

var empty = {};

// Adapted from: https://egghead.io/lessons/javascript-introducing-reduce-reducing-an-array-into-an-object
var reducer = function(aggregate, element) {
  aggregate[element] = 1;
  return aggregate;
}

module.exports = BLACKLIST.reduce(reducer, empty);
<commit_msg>add comma to fix blacklist<commit_after>// Add your blacklisted sites to this array. Subdomain and TLD are optional and flexible.
// Should probably be kept in sync with https://github.com/premgane/agolo-twitterbot/blob/master/server.py
var BLACKLIST = [
  'github',
  'agolo.com',
  'youtube',
  'youtu.be',
  'atlassian.net',
  'spotify.com',
  'twitter.com',
  'mail.google',
  'google.com',
  'imgur.com',
  'bit.ly',
  'tinyurl',
  'vine',
  'dropbox',
  'slack',
  'notion.so',
  'zoom.us',
  'appear.in'
];

/** Convert the array to an object and export it **/

var empty = {};

// Adapted from: https://egghead.io/lessons/javascript-introducing-reduce-reducing-an-array-into-an-object
var reducer = function(aggregate, element) {
  aggregate[element] = 1;
  return aggregate;
}

module.exports = BLACKLIST.reduce(reducer, empty);
<|endoftext|>


<commit_before>// Copyright (c) 2015 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

'use strict';

var PermissionsCache = require('../hyperbahn/permissions_cache.js');
var allocCluster = require('./lib/alloc-cluster.js');

allocCluster.test('permissionsCache: counts service request counts', {
    numPeers: 2
}, function t(cluster, assert) {
    var server = cluster.channels[0];
    var client = cluster.channels[1];

    var cache = new PermissionsCache({
        channel: server,
        logger: null
    });

    server.makeSubChannel({
        serviceName: 'server'
    }).register('echo', function echo(req, res, h, b) {
        res.headers.as = 'raw';
        res.sendOk(h, b);
    });

    var clientChan = client.makeSubChannel({
        serviceName: 'server',
        peers: [server.hostPort]
    });

    clientChan.request({
        serviceName: 'server',
        hasNoParent: true,
        headers: {
            cn: 'client',
            as: 'raw'
        }
    }).send('echo', 'a', 'b', onResponse);

    function onResponse(err, res, arg2, arg3) {
        assert.ifError(err);
        assert.ok(cache.lru.keys().indexOf('client_server') >= 0);
        assert.end();
        cache.clearBuckets();
    }
});
<commit_msg>shortcut permissions cache test in the case of response error<commit_after>// Copyright (c) 2015 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

'use strict';

var PermissionsCache = require('../hyperbahn/permissions_cache.js');
var allocCluster = require('./lib/alloc-cluster.js');

allocCluster.test('permissionsCache: counts service request counts', {
    numPeers: 2
}, function t(cluster, assert) {
    var server = cluster.channels[0];
    var client = cluster.channels[1];

    var cache = new PermissionsCache({
        channel: server,
        logger: null
    });

    server.makeSubChannel({
        serviceName: 'server'
    }).register('echo', function echo(req, res, h, b) {
        res.headers.as = 'raw';
        res.sendOk(h, b);
    });

    var clientChan = client.makeSubChannel({
        serviceName: 'server',
        peers: [server.hostPort]
    });

    clientChan.request({
        serviceName: 'server',
        hasNoParent: true,
        headers: {
            cn: 'client',
            as: 'raw'
        }
    }).send('echo', 'a', 'b', onResponse);

    function onResponse(err, res, arg2, arg3) {
        if (err) {
            return assert.end(err);
        }

        assert.ok(cache.lru.keys().indexOf('client_server') >= 0);
        assert.end();
        cache.clearBuckets();
    }
});
<|endoftext|>