<commit_before>import Ember from 'ember';
import FdEditformControl from '../objects/fd-editform-control';
import FdEditformGroup from '../objects/fd-editform-group';
import FdEditformRow from '../objects/fd-editform-row';
import FdEditformTab from '../objects/fd-editform-tab';
import FdEditformTabgroup from '../objects/fd-editform-tabgroup';
import { Query } from 'ember-flexberry-data';
const { Builder, FilterOperator } = Query;

export default Ember.Route.extend({

  currentProjectContext: Ember.inject.service('fd-current-project-context'),

  model: function(params) {
    let stageId = this.get('currentProjectContext').getCurrentStage();
    let _this = this;
    let modelHash = {
      editform: undefined,
      dataobject: undefined,
      typemap: undefined,
      enums: undefined,
      types: undefined
    };

    return new Ember.RSVP.Promise(function (resolve, reject) {
      // TODO: Replace promises to use fd-preload-stage-metadata and store.peekRecord().
      // Load «editform».
      let loadClassesPromise = new Ember.RSVP.Promise(function (resolveLoadClasses, rejectLoadClasses) {
        let predicateEditformId = new Query.SimplePredicate('id', FilterOperator.Eq, params.id);

        let builderEditform = new  Builder(_this.store, 'fd-dev-class').
        select('id,name,caption,description,formViews,formViews.view,formViews.view.class,formViews.view.class.id,formViews.view.definition').
        where(predicateEditformId);

        _this.store.query('fd-dev-class', builderEditform.build()).then((result) => {
          let editform = result.objectAt(0);
          modelHash.editform = editform;
          return editform;
        }, rejectLoadClasses).then((editform) => {
          // Load dataobject «implementation».
          let dataobjectId = editform.get('formViews').objectAt(0).get('view.class.id'); // TODO: Check array.
          let predicateDataobjectId = new Query.SimplePredicate('id', FilterOperator.Eq, dataobjectId);

          let builderDataobject = new  Builder(_this.store, 'fd-dev-class').
          select('id,name,caption,description').
          where(predicateDataobjectId);

          _this.store.query('fd-dev-class', builderDataobject.build()).then((resultDataobject) => {
            modelHash.dataobject = resultDataobject.objectAt(0);
            resolveLoadClasses(modelHash);
          }, rejectLoadClasses);
        }, reject);
      });

      // Stage with type map.
      let predicateId = new Query.SimplePredicate('id', FilterOperator.Eq, stageId);

      let builderStage = new  Builder(_this.store, 'fd-dev-stage').
      select('id,typeMapCSStr').
      where(predicateId);

      let loadTypemapPromise = _this.store.query('fd-dev-stage', builderStage.build()).then((result) => {
        let stage = result.objectAt(0);
        modelHash.typemap = stage.get('typeMapCSStr');
        return modelHash;
      }, reject);

      let predicateStageId = new Query.SimplePredicate('stage.id', FilterOperator.Eq, stageId);

      // Enums
      let predicateEnumerationStereorype = new Query.SimplePredicate('stereotype', FilterOperator.Eq, '«enumeration»');
      let predicateEnumeration = new Query.ComplexPredicate(Query.Condition.And, predicateStageId, predicateEnumerationStereorype);

      let builderEnumeration = new  Builder(_this.store, 'fd-dev-class').
      select('id,name,caption,description,stereotype,stage.id').
      where(predicateEnumeration);

      let promiseEnumeration = _this.store.query('fd-dev-class', builderEnumeration.build()).then((result) => {
        modelHash.enums = result;
        return modelHash;
      }, reject);

      // Type
      let predicateTypeStereorype = new Query.SimplePredicate('stereotype', FilterOperator.Eq, '«type»');
      let predicateType = new Query.ComplexPredicate(Query.Condition.And, predicateStageId, predicateTypeStereorype);

      let builderType = new  Builder(_this.store, 'fd-dev-class').
      select('id,name,caption,description,stereotype,stage.id').
      where(predicateType);

      let promiseType = _this.store.query('fd-dev-class', builderType.build()).then((result) => {
        modelHash.types = result;
        return modelHash;
      }, reject);

      Ember.RSVP.all([loadClassesPromise, loadTypemapPromise, promiseEnumeration, promiseType]).then(() => {
        let controlTree = Ember.A();

        let definition = modelHash.editform.get('formViews.firstObject.view.definition');
        for (let i = 0; i < definition.length; i++) {
          let propertyDefinition = definition[i];
          if (!propertyDefinition.visible) {
            continue;
          }

          _this._locateControl(controlTree, propertyDefinition, propertyDefinition.path);
        }

        modelHash.controls = controlTree;
        resolve(modelHash);
      });
    });
  },

  /**
      Locate control by path.

      @method _locateControl
      @param {Object} controlTree Controls tree.
      @param {FdDefinition} propertyDefinition Property definition from view.
      @param {String} path Property path from view.
      @return {Object} Modified controlTree with placed control.
  */
  _locateControl: function (controlTree, propertyDefinition, path) {
    if (!path || path === '') {
      let row  = FdEditformRow.create({ controls: Ember.A(), columnsCount: 0 });

      if (controlTree.rows) {
        controlTree.rows.pushObject(row);
      } else {
        controlTree.pushObject(row);
      }

      this._locateControlInRow(row, propertyDefinition);

      return controlTree;
    }

    if (path.charAt(0) === '|') {
      return this._locateTabs(controlTree, propertyDefinition, path);
    }

    if (path.charAt(0) === '-') {
      return this._locateGroup(controlTree, propertyDefinition, path);
    }

    if (path.charAt(0) === '#') {
      return this._locateColumn(controlTree, propertyDefinition, path);
    }

    // TODO: Show error and fix it.
  },

  /**
      Locate control in row by path.

      @method _locateControlInRow
      @param {FdEditformRow} row Row for control placement.
      @param {FdDefinition} propertyDefinition Property definition from view.
      @return {Object} Modified controlTree with placed control.
  */
  _locateControlInRow: function (row, propertyDefinition) {
    // TODO: вычислить type контрола из метаданных атрибута или FormControl и width из path.
    let control = FdEditformControl.create({ caption: propertyDefinition.name, type: 'string', width: '100*' });

    row.controls.pushObject(control);
    row.columnsCount++;

    return row;
  },

  /**
      Locate tabs for control.

      @method _locateTabs
      @param {Object} controlTree Controls tree.
      @param {FdDefinition} propertyDefinition Property definition from view.
      @param {String} path Property path from view.
      @return {Object} Modified controlTree with placed tabs.
  */
  _locateTabs: function(controlTree, propertyDefinition, path) {
    let pathLength = path.length;
    let splitterIndex = path.indexOf('\\');
    let tabCaptionEndIndex = splitterIndex > -1 ? splitterIndex : pathLength;

    let tabCaption = path.slice(1, tabCaptionEndIndex);

    let row;
    let tabGroup;
    let tab;
    let rowsCollection;

    if (controlTree.rows) {
      rowsCollection = controlTree.rows;
    } else {
      rowsCollection = controlTree;
    }

    for (let i = 0; i < rowsCollection.length; i++) {
      let rowInCollection = rowsCollection[i];
      if (rowInCollection instanceof FdEditformRow) {
        for (let j = 0; j < rowInCollection.controls.length; j++) {
          let controlInRow = rowInCollection.controls[j];
          if (controlInRow instanceof FdEditformTabgroup) {
            row = rowInCollection;
            tabGroup = controlInRow;
            for (let k = 0; k < controlInRow.tabs.length; k++) {
              let tabInTabgroup = controlInRow.tabs[k];
              if (tabInTabgroup.caption === tabCaption) {
                tab = tabInTabgroup;
              }
            }
          }
        }
      }
    }

    if (!row) {
      row  = FdEditformRow.create({ controls: Ember.A(), columnsCount: 0 });

      if (controlTree.rows) {
        controlTree.rows.pushObject(row);
      } else {
        controlTree.pushObject(row);
      }
    }

    if (!tabGroup) {
      tabGroup  = FdEditformTabgroup.create({ tabs: Ember.A(), width: '100*' });
      row.controls.pushObject(tabGroup);
    }

    if (!tab) {
      tab  = FdEditformTab.create({ rows: Ember.A(), caption: tabCaption });
      tabGroup.tabs.pushObject(tab);
    }

    let nextPath = path.slice(tabCaptionEndIndex + 1, pathLength);

    return this._locateControl(tab, propertyDefinition, nextPath);
  },

  /**
      Locate group for control.

      @method _locateGroup
      @param {Object} controlTree Controls tree.
      @param {FdDefinition} propertyDefinition Property definition from view.
      @param {String} path Property path from view.
      @return {Object} Modified controlTree with placed group.
  */
  _locateGroup: function(controlTree, propertyDefinition, path) {
    let pathLength = path.length;
    let splitterIndex = path.indexOf('\\');
    let groupCaptionEndIndex = splitterIndex > -1 ? splitterIndex : pathLength;

    let groupCaption = path.slice(1, groupCaptionEndIndex);

    let row;
    let group;
    let rowsCollection;

    if (controlTree.rows) {
      rowsCollection = controlTree.rows;
    } else {
      rowsCollection = controlTree;
    }

    for (let i = 0; i < rowsCollection.length; i++) {
      let rowInCollection = rowsCollection[i];
      if (rowInCollection instanceof FdEditformRow) {
        for (let j = 0; j < rowInCollection.controls.length; j++) {
          let controlInRow = rowInCollection.controls[j];
          if (controlInRow instanceof FdEditformGroup && controlInRow.caption === groupCaption) {
            row = rowInCollection;
            group = controlInRow;
          }
        }
      }
    }

    if (!row) {
      row  = FdEditformRow.create({ controls: Ember.A(), columnsCount: 0 });

      if (controlTree.rows) {
        controlTree.rows.pushObject(row);
      } else {
        controlTree.pushObject(row);
      }
    }

    if (!group) {
      group  = FdEditformGroup.create({ rows: Ember.A(), width: '100*', caption: groupCaption });
      row.controls.pushObject(group);
    }

    let nextPath = path.slice(groupCaptionEndIndex + 1, pathLength);

    return this._locateControl(group, propertyDefinition, nextPath);
  },

  /**
      Locate column for control.

      @method _locateColumn
      @param {Object} controlTree Controls tree.
      @param {FdDefinition} propertyDefinition Property definition from view.
      @param {String} path Property path from view.
      @return {Object} Modified controlTree with placed column.
  */
  _locateColumn: function(controlTree, propertyDefinition, path) {
    let pathLength = path.length;
    let splitterIndex = path.indexOf('\\');
    let columnDefinitionEndIndex = splitterIndex > -1 ? splitterIndex : pathLength;

    let columnDefinition = path.slice(1, columnDefinitionEndIndex);

    let braceIndex = columnDefinition.indexOf('(');

    if (braceIndex === -1) {
      braceIndex = columnDefinition.length;
    }

    let columnIndex = parseInt(columnDefinition.slice(0, braceIndex));

    let rowsCollection;

    if (controlTree.rows) {
      rowsCollection = controlTree.rows;
    } else {
      rowsCollection = controlTree;
    }

    let row = rowsCollection.get('lastObject');

    // Current columns count in row must be match column index else it will be another row.
    if (row && row.columnsCount + 1 !== columnIndex) {
      row = undefined;
    }

    if (!row) {
      row  = FdEditformRow.create({ controls: Ember.A(), columnsCount: 0 });

      if (controlTree.rows) {
        controlTree.rows.pushObject(row);
      } else {
        controlTree.pushObject(row);
      }
    }

    let nextPath = path.slice(columnDefinitionEndIndex + 1, pathLength);

    if (nextPath) {
      // TODO: may be another group or tabs there?
      return this._locateControl(row, propertyDefinition, nextPath);
    } else {
      return this._locateControlInRow(row, propertyDefinition);
    }
  }
});
<commit_msg>Fix code review<commit_after>import Ember from 'ember';
import FdEditformControl from '../objects/fd-editform-control';
import FdEditformGroup from '../objects/fd-editform-group';
import FdEditformRow from '../objects/fd-editform-row';
import FdEditformTab from '../objects/fd-editform-tab';
import FdEditformTabgroup from '../objects/fd-editform-tabgroup';
import { Query } from 'ember-flexberry-data';
const { Builder, FilterOperator } = Query;

export default Ember.Route.extend({

  currentProjectContext: Ember.inject.service('fd-current-project-context'),

  model: function(params) {
    let stageId = this.get('currentProjectContext').getCurrentStage();
    let _this = this;
    let modelHash = {
      editform: undefined,
      dataobject: undefined,
      typemap: undefined,
      enums: undefined,
      types: undefined
    };

    return new Ember.RSVP.Promise(function (resolve, reject) {
      // TODO: Replace promises to use fd-preload-stage-metadata and store.peekRecord().
      // Load «editform».
      let loadClassesPromise = new Ember.RSVP.Promise(function (resolveLoadClasses, rejectLoadClasses) {
        let predicateEditformId = new Query.SimplePredicate('id', FilterOperator.Eq, params.id);

        let builderEditform = new  Builder(_this.store, 'fd-dev-class').
        select('id,name,caption,description,formViews,formViews.view,formViews.view.class,formViews.view.class.id,formViews.view.definition').
        where(predicateEditformId);

        _this.store.query('fd-dev-class', builderEditform.build()).then((result) => {
          let editform = result.objectAt(0);
          modelHash.editform = editform;
          return editform;
        }, rejectLoadClasses).then((editform) => {
          // Load dataobject «implementation».
          let dataobjectId = editform.get('formViews').objectAt(0).get('view.class.id'); // TODO: Check array.
          let predicateDataobjectId = new Query.SimplePredicate('id', FilterOperator.Eq, dataobjectId);

          let builderDataobject = new  Builder(_this.store, 'fd-dev-class').
          select('id,name,caption,description').
          where(predicateDataobjectId);

          _this.store.query('fd-dev-class', builderDataobject.build()).then((resultDataobject) => {
            modelHash.dataobject = resultDataobject.objectAt(0);
            resolveLoadClasses(modelHash);
          }, rejectLoadClasses);
        }, reject);
      });

      // Stage with type map.
      let predicateId = new Query.SimplePredicate('id', FilterOperator.Eq, stageId);

      let builderStage = new  Builder(_this.store, 'fd-dev-stage').
      select('id,typeMapCSStr').
      where(predicateId);

      let loadTypemapPromise = _this.store.query('fd-dev-stage', builderStage.build()).then((result) => {
        let stage = result.objectAt(0);
        modelHash.typemap = stage.get('typeMapCSStr');
        return modelHash;
      }, reject);

      let predicateStageId = new Query.SimplePredicate('stage.id', FilterOperator.Eq, stageId);

      // Enums
      let predicateEnumerationStereorype = new Query.SimplePredicate('stereotype', FilterOperator.Eq, '«enumeration»');
      let predicateEnumeration = new Query.ComplexPredicate(Query.Condition.And, predicateStageId, predicateEnumerationStereorype);

      let builderEnumeration = new  Builder(_this.store, 'fd-dev-class').
      select('id,name,caption,description,stereotype,stage.id').
      where(predicateEnumeration);

      let promiseEnumeration = _this.store.query('fd-dev-class', builderEnumeration.build()).then((result) => {
        modelHash.enums = result;
        return modelHash;
      }, reject);

      // Type
      let predicateTypeStereorype = new Query.SimplePredicate('stereotype', FilterOperator.Eq, '«type»');
      let predicateType = new Query.ComplexPredicate(Query.Condition.And, predicateStageId, predicateTypeStereorype);

      let builderType = new  Builder(_this.store, 'fd-dev-class').
      select('id,name,caption,description,stereotype,stage.id').
      where(predicateType);

      let promiseType = _this.store.query('fd-dev-class', builderType.build()).then((result) => {
        modelHash.types = result;
        return modelHash;
      }, reject);

      Ember.RSVP.all([loadClassesPromise, loadTypemapPromise, promiseEnumeration, promiseType]).then(() => {
        let controlTree = Ember.A();

        let definition = modelHash.editform.get('formViews.firstObject.view.definition');
        for (let i = 0; i < definition.length; i++) {
          let propertyDefinition = definition[i];
          if (!propertyDefinition.visible) {
            continue;
          }

          _this._locateControl(controlTree, propertyDefinition, propertyDefinition.path);
        }

        modelHash.controls = controlTree;
        resolve(modelHash);
      });
    });
  },

  /**
      Locate control by path.

      @method _locateControl
      @param {Object} controlTree Controls tree.
      @param {FdDefinition} propertyDefinition Property definition from view.
      @param {String} path Property path from view.
      @return {Object} Modified controlTree with placed control.
  */
  _locateControl: function (controlTree, propertyDefinition, path) {
    if (!path || path === '') {
      let row  = FdEditformRow.create({ controls: Ember.A(), columnsCount: 0 });

      if (controlTree.get('rows')) {
        controlTree.get('rows').pushObject(row);
      } else {
        controlTree.pushObject(row);
      }

      this._locateControlInRow(row, propertyDefinition);

      return controlTree;
    }

    if (path.charAt(0) === '|') {
      return this._locateTabs(controlTree, propertyDefinition, path);
    }

    if (path.charAt(0) === '-') {
      return this._locateGroup(controlTree, propertyDefinition, path);
    }

    if (path.charAt(0) === '#') {
      return this._locateColumn(controlTree, propertyDefinition, path);
    }

    // TODO: Show error and fix it.
  },

  /**
      Locate control in row by path.

      @method _locateControlInRow
      @param {FdEditformRow} row Row for control placement.
      @param {FdDefinition} propertyDefinition Property definition from view.
      @return {Object} Modified controlTree with placed control.
  */
  _locateControlInRow: function (row, propertyDefinition) {
    // TODO: вычислить type контрола из метаданных атрибута или FormControl и width из path.
    let control = FdEditformControl.create({ caption: propertyDefinition.caption || propertyDefinition.name, type: 'string', width: '100*' });

    row.get('controls').pushObject(control);
    row.set('columnsCount', row.get('columnsCount') + 1);

    return row;
  },

  /**
      Locate tabs for control.

      @method _locateTabs
      @param {Object} controlTree Controls tree.
      @param {FdDefinition} propertyDefinition Property definition from view.
      @param {String} path Property path from view.
      @return {Object} Modified controlTree with placed tabs.
  */
  _locateTabs: function(controlTree, propertyDefinition, path) {
    let pathLength = path.length;
    let splitterIndex = path.indexOf('\\');
    let tabCaptionEndIndex = splitterIndex > -1 ? splitterIndex : pathLength;

    let tabCaption = path.slice(1, tabCaptionEndIndex);

    let row;
    let tabGroup;
    let tab;
    let rowsCollection;

    if (controlTree.get('rows')) {
      rowsCollection = controlTree.get('rows');
    } else {
      rowsCollection = controlTree;
    }

    for (let i = 0; i < rowsCollection.get('length'); i++) {
      let rowInCollection = rowsCollection[i];
      if (rowInCollection instanceof FdEditformRow) {
        for (let j = 0; j < rowInCollection.get('controls.length'); j++) {
          let controlInRow = rowInCollection.controls[j];
          if (controlInRow instanceof FdEditformTabgroup) {
            row = rowInCollection;
            tabGroup = controlInRow;
            for (let k = 0; k < controlInRow.get('tabs.length'); k++) {
              let tabInTabgroup = controlInRow.tabs[k];
              if (tabInTabgroup.caption === tabCaption) {
                tab = tabInTabgroup;
              }
            }
          }
        }
      }
    }

    if (!row) {
      row  = FdEditformRow.create({ controls: Ember.A(), columnsCount: 0 });

      if (controlTree.get('rows')) {
        controlTree.get('rows').pushObject(row);
      } else {
        controlTree.pushObject(row);
      }
    }

    if (!tabGroup) {
      tabGroup  = FdEditformTabgroup.create({ tabs: Ember.A(), width: '100*' });
      row.get('controls').pushObject(tabGroup);
    }

    if (!tab) {
      tab  = FdEditformTab.create({ rows: Ember.A(), caption: tabCaption });
      tabGroup.get('tabs').pushObject(tab);
    }

    let nextPath = path.slice(tabCaptionEndIndex + 1, pathLength);

    return this._locateControl(tab, propertyDefinition, nextPath);
  },

  /**
      Locate group for control.

      @method _locateGroup
      @param {Object} controlTree Controls tree.
      @param {FdDefinition} propertyDefinition Property definition from view.
      @param {String} path Property path from view.
      @return {Object} Modified controlTree with placed group.
  */
  _locateGroup: function(controlTree, propertyDefinition, path) {
    let pathLength = path.length;
    let splitterIndex = path.indexOf('\\');
    let groupCaptionEndIndex = splitterIndex > -1 ? splitterIndex : pathLength;

    let groupCaption = path.slice(1, groupCaptionEndIndex);

    let row;
    let group;
    let rowsCollection;

    if (controlTree.get('rows')) {
      rowsCollection = controlTree.get('rows');
    } else {
      rowsCollection = controlTree;
    }

    for (let i = 0; i < rowsCollection.get('length'); i++) {
      let rowInCollection = rowsCollection[i];
      if (rowInCollection instanceof FdEditformRow) {
        for (let j = 0; j < rowInCollection.get('controls.length'); j++) {
          let controlInRow = rowInCollection.controls[j];
          if (controlInRow instanceof FdEditformGroup && controlInRow.get('caption') === groupCaption) {
            row = rowInCollection;
            group = controlInRow;
          }
        }
      }
    }

    if (!row) {
      row  = FdEditformRow.create({ controls: Ember.A(), columnsCount: 0 });

      if (controlTree.get('rows')) {
        controlTree.get('rows').pushObject(row);
      } else {
        controlTree.pushObject(row);
      }
    }

    if (!group) {
      group  = FdEditformGroup.create({ rows: Ember.A(), width: '100*', caption: groupCaption });
      row.get('controls').pushObject(group);
    }

    let nextPath = path.slice(groupCaptionEndIndex + 1, pathLength);

    return this._locateControl(group, propertyDefinition, nextPath);
  },

  /**
      Locate column for control.

      @method _locateColumn
      @param {Object} controlTree Controls tree.
      @param {FdDefinition} propertyDefinition Property definition from view.
      @param {String} path Property path from view.
      @return {Object} Modified controlTree with placed column.
  */
  _locateColumn: function(controlTree, propertyDefinition, path) {
    let pathLength = path.length;
    let splitterIndex = path.indexOf('\\');
    let columnDefinitionEndIndex = splitterIndex > -1 ? splitterIndex : pathLength;

    let columnDefinition = path.slice(1, columnDefinitionEndIndex);

    let braceIndex = columnDefinition.indexOf('(');

    if (braceIndex === -1) {
      braceIndex = columnDefinition.length;
    }

    let columnIndex = parseInt(columnDefinition.slice(0, braceIndex));

    let rowsCollection;

    if (controlTree.get('rows')) {
      rowsCollection = controlTree.get('rows');
    } else {
      rowsCollection = controlTree;
    }

    let row = rowsCollection.get('lastObject');

    // Current columns count in row must be match column index else it will be another row.
    if (row && row.get('columnsCount') + 1 !== columnIndex) {
      row = undefined;
    }

    if (!row) {
      row  = FdEditformRow.create({ controls: Ember.A(), columnsCount: 0 });

      if (controlTree.get('rows')) {
        controlTree.get('rows').pushObject(row);
      } else {
        controlTree.pushObject(row);
      }
    }

    let nextPath = path.slice(columnDefinitionEndIndex + 1, pathLength);

    if (nextPath) {
      // TODO: may be another group or tabs there?
      return this._locateControl(row, propertyDefinition, nextPath);
    } else {
      return this._locateControlInRow(row, propertyDefinition);
    }
  }
});
<|endoftext|>


<commit_before>'use strict';

var Auth = require('./Auth');
var Util = require('./Util');
var gcloud = require('gcloud');

function Datastore(repoName) {
  this.name = repoName;
  this.namespace = Util.makeBucketName(repoName);
  this.dataset = gcloud.datastore.dataset(Auth);
}

// Write out what happened
Datastore.prototype.saveInitialData = function(runs, rawBuildRequest, buildData, cb) {
  if (!this.buildId) {
    cb('Must set Build ID!');
  } else {
    var key = this.dataset.key({ namespace: this.namespace, path: [ 'build', String(this.buildId) ]});
    var dataToStore = Util.cleanDatastoreContents({ buildData: buildData, runs: runs, rawBuildRequest: rawBuildRequest });
    var entity = { key: key, data: dataToStore };
    this.dataset.save(entity, cb);
  }
};

Datastore.prototype.getNextBuildNumber = function(cb) {
  var me = this;
  var key = this.dataset.key({ namespace: this.namespace, path: [ 'buildId' ] });
  this.dataset.runInTransaction(function(transaction, done) {
    var query = me.dataset.createQuery(me.namespace, key.path);
    transaction.runQuery(query, function(err, entities) {
      if (err) {
        cb(err);
      } else {
        var entity;
        if (entities.length) {
          entity = entities[0];
          entity.data.value++;
        } else {
          entity = { key: key, data: { value: 1 }};
        }
        transaction.save(entity);
        me.buildId = entity.data.value;
        done();
      }
    });
  }, function(err) {
    cb(err, me.buildId);
  });
};

Datastore.prototype.getBuildType = function(type, cb) {
  var query = this.dataset.createQuery(this.namespace, ['build']).limit(50);

  this.dataset.runQuery(query, function(err, entities) {
    if (err) {
      cb(err);
    } else {
      var builds = entities.filter(function(entity) {
        return entity.data.buildData.kind === type;
      });
      cb(null, builds.map(function(build) {
        return build.data;
      }));
    }
  });
};

Datastore.prototype.getSomePushBuilds = function(cb) {
  this.getBuildType('push', cb);
};

Datastore.prototype.getSomePRBuilds = function(cb) {
  this.getBuildType('pull_request', cb);
};

Datastore.prototype.getABuild = function(buildId, cb) {
  this.dataset.get({ namespace: this.namespace, path: ['build', String(buildId) ] }, function(err, build) {
    if (err) {
      cb(err);
    } else if (build) {
      cb(null, build.data);
    } else {
      cb('Build ' + buildId + ' does not exist');
    }
  });
};

Datastore.prototype.updateRunState = function(buildId, buildNumber, newState, cb) {
  var key = this.dataset.key({ namespace: this.namespace, path: [ 'build', buildId ]});
  var me = this;
  this.dataset.runInTransaction(function(transaction, done) {
    transaction.get(key, function(err, entity) {
      if (err) {
        cb(err);
      } else {
        entity.data.runs.forEach(function(run) {
          if (run.buildNumber === parseInt(buildNumber, 10)) {
            run.state = newState;
            run.updated = new Date().getTime();
          }
        });
        transaction.update(entity);
        done();
      }
    });
  }, function(err) {
    me.retryHandler(me.updateRunState, 'tries', [ buildId, buildNumber, newState, cb ], err);
  });
};

// Update overall build state
Datastore.prototype.updateOverallState = function(buildId, newState, totalRunTime, cb) {
  var me = this;
  var key = this.dataset.key({ namespace: this.namespace, path: [ 'build', buildId ]});
  this.dataset.runInTransaction(function(transaction, done) {
    transaction.get(key, function(err, entity) {
      if (err) {
        cb(err);
      } else {
        entity.data.buildData.state = newState;
        entity.data.buildData.totalRunTime = totalRunTime;
        transaction.update(entity);
        done();
      }
    });
  }, function(err) {
    me.retryHandler(me.updateOverallState, 'utries', [ buildId, newState, cb ], err);
  });
};

// Get overall build time
Datastore.prototype.getTotalRunTime = function(buildId, cb) {
  this.getABuild(buildId, function(err, build) {
    if (build.buildData.state === 'running') {
      if (err) {
        cb(err);
      } else {
        var totalTime = build.runs.reduce(function(timeSoFar, run) {
          var updated = run.updated;
          if (!updated) {
            // run hasn't hit first update yet
            updated = new Date().getTime();
          }
          return timeSoFar + (updated - run.created);
        }, 0);
        cb(null, totalTime);
      }
    } else {
      cb(null, build.buildData.totalRunTime);
    }
 });
};

// set 'state' and 'totalTime' for build
Datastore.prototype.updateBuildState = function(buildId, cb) {
};

Datastore.prototype.retryHandler = function(funcToCall, retryCountProperty, args, err) {
  var me = this;
  var cb = args[args.length - 1];
  if (err) {
    if (!me[retryCountProperty]) {
      me[retryCountProperty] = 0;
    }
    if (err.code === 409 && me.utries < 10) {
      // message: 'too much contention on these datastore entities. please try again.',
      // sleep for a second & try again
      me[retryCountProperty]++;
      var sleep = Math.floor(Math.random() * 5) + 1;
      console.log('409 - going around again after %s seconds', sleep);
      setTimeout(function() {
        funcToCall.apply(me, args);
      }, 1000 * sleep);
    } else {
      if (me[retryCountProperty] > 0) {
        console.log('Too many tries - failing');
        me[retryCountProperty] = 0;
      }
      cb(err);
    }
  } else {
    cb();
  }
};

module.exports = Datastore;
<commit_msg>update build state when getting builds<commit_after>'use strict';

var Auth = require('./Auth');
var Util = require('./Util');
var gcloud = require('gcloud');
var Q = require('Q');

function Datastore(repoName) {
  this.name = repoName;
  this.namespace = Util.makeBucketName(repoName);
  this.dataset = gcloud.datastore.dataset(Auth);
}

// Write out what happened
Datastore.prototype.saveInitialData = function(runs, rawBuildRequest, buildData, cb) {
  if (!this.buildId) {
    cb('Must set Build ID!');
  } else {
    var key = this.dataset.key({ namespace: this.namespace, path: [ 'build', String(this.buildId) ]});
    var dataToStore = Util.cleanDatastoreContents({ buildData: buildData, runs: runs, rawBuildRequest: rawBuildRequest });
    var entity = { key: key, data: dataToStore };
    this.dataset.save(entity, cb);
  }
};

Datastore.prototype.getNextBuildNumber = function(cb) {
  var me = this;
  var key = this.dataset.key({ namespace: this.namespace, path: [ 'buildId' ] });
  this.dataset.runInTransaction(function(transaction, done) {
    var query = me.dataset.createQuery(me.namespace, key.path);
    transaction.runQuery(query, function(err, entities) {
      if (err) {
        cb(err);
      } else {
        var entity;
        if (entities.length) {
          entity = entities[0];
          entity.data.value++;
        } else {
          entity = { key: key, data: { value: 1 }};
        }
        transaction.save(entity);
        me.buildId = entity.data.value;
        done();
      }
    });
  }, function(err) {
    cb(err, me.buildId);
  });
};

Datastore.prototype.getBuildType = function(type, cb) {
  var me = this;
  var query = this.dataset.createQuery(this.namespace, ['build']).limit(50);

  this.dataset.runQuery(query, function(err, entities) {
    if (err) {
      cb(err);
    } else {
      // Filter out only the builds we're interested in
      var builds = entities.filter(function(entity) {
        return entity.data.buildData.kind === type;
      });

      // Determine their build state
      var promises = builds.map(function(build) {
        return Q.ninvoke(me, 'determineBuildState', build.data);
      });

      // When that's done return the builds
      Q.allSettled(promises).then(function(/*results*/) {
        // TODO(trostler): look at 'results' to ensure nothing went haywire
        cb(null, builds.map(function(build) {
          return build.data;
        }));
      });
    }
  });
};

Datastore.prototype.getSomePushBuilds = function(cb) {
  this.getBuildType('push', cb);
};

Datastore.prototype.getSomePRBuilds = function(cb) {
  this.getBuildType('pull_request', cb);
};

Datastore.prototype.getABuild = function(buildId, cb) {
  this.dataset.get({ namespace: this.namespace, path: ['build', String(buildId) ] }, function(err, build) {
    if (err) {
      cb(err);
    } else if (build) {
      cb(null, build.data);
    } else {
      cb('Build ' + buildId + ' does not exist');
    }
  });
};

Datastore.prototype.updateRunState = function(buildId, buildNumber, newState, cb) {
  var key = this.dataset.key({ namespace: this.namespace, path: [ 'build', buildId ]});
  var me = this;
  this.dataset.runInTransaction(function(transaction, done) {
    transaction.get(key, function(err, entity) {
      if (err) {
        cb(err);
      } else {
        entity.data.runs.forEach(function(run) {
          if (run.buildNumber === parseInt(buildNumber, 10)) {
            run.state = newState;
            run.updated = new Date().getTime();
          }
        });
        transaction.update(entity);
        done();
      }
    });
  }, function(err) {
    me.retryHandler(me.updateRunState, 'tries', [ buildId, buildNumber, newState, cb ], err);
  });
};

// Update overall build state
Datastore.prototype.updateOverallState = function(buildId, newState, totalRunTime, cb) {
  var me = this;
  var key = this.dataset.key({ namespace: this.namespace, path: [ 'build', buildId ]});
  this.dataset.runInTransaction(function(transaction, done) {
    transaction.get(key, function(err, entity) {
      if (err) {
        cb(err);
      } else {
        entity.data.buildData.state = newState;
        entity.data.buildData.totalRunTime = totalRunTime;
        transaction.update(entity);
        done();
      }
    });
  }, function(err) {
    me.retryHandler(me.updateOverallState, 'utries', [ buildId, newState, cb ], err);
  });
};

// Get overall build time
Datastore.prototype.getTotalRunTime = function(buildId, cb) {
  this.getABuild(buildId, function(err, build) {
    if (build.buildData.state === 'running') {
      if (err) {
        cb(err);
      } else {
        var totalTime = build.runs.reduce(function(timeSoFar, run) {
          var updated = run.updated;
          if (!updated) {
            // run hasn't hit first update yet
            updated = new Date().getTime();
          }
          return timeSoFar + (updated - run.created);
        }, 0);
        cb(null, totalTime);
      }
    } else {
      cb(null, build.buildData.totalRunTime);
    }
 });
};

Datastore.prototype.retryHandler = function(funcToCall, retryCountProperty, args, err) {
  var me = this;
  var cb = args[args.length - 1];
  if (err) {
    if (!me[retryCountProperty]) {
      me[retryCountProperty] = 0;
    }
    if (err.code === 409 && me.utries < 10) {
      // message: 'too much contention on these datastore entities. please try again.',
      // sleep for a second & try again
      me[retryCountProperty]++;
      var sleep = Math.floor(Math.random() * 5) + 1;
      console.log('409 - going around again after %s seconds', sleep);
      setTimeout(function() {
        funcToCall.apply(me, args);
      }, 1000 * sleep);
    } else {
      if (me[retryCountProperty] > 0) {
        console.log('Too many tries - failing');
        me[retryCountProperty] = 0;
      }
      cb(err);
    }
  } else {
    cb();
  }
};

Datastore.prototype.determineBuildState = function(build, cb) {
  if (build.buildData.state === 'running') {
    // Now figure it out!
    var failed = false;
    var errored = false;
    var running = false;
    var totalRunTime = 0;
    // individual buildNumber states:
    build.runs.forEach(function(result) {

      // First add to total build time
      var runTime = 0;
      if (result.updated) {
        runTime = result.updated - result.created;
      } else {
        runTime = new Date().getTime() - result.created;
      }
      totalRunTime += runTime;

      // 'building', 'running', 'exited', 'timeout', 'passed', 'error', 'fail'
      if (!result.ignoreFailure) {
        if (result.state === 'fail') {
          failed = true;
        } else if (result.state === 'error') {
          errored = true;
        } else if (result.state === 'timeout' || result.state === 'exited') {
          failed = true;
        } else if (result.state === 'building' || result.state === 'running') {
          running = true;
        }
      }
    });

    var passed = false;
    if (!failed && !errored && !running) {
      passed = true;
    } else if (failed && errored) {
      // fail wins!  Need to have a single value for the overall build state
      failed = false;
    }

    // Only update overall build when all builds are done
    var newState = failed ? 'failed' : (errored ? 'errored' : (passed ? 'passed' : 'running' ));

    // Just stick these values here for the case that we don't persist the values
    build.buildData.state = newState;
    build.buildData.totalRunTime = totalRunTime;

    if (!running) {
      // If this build is done then persis the build state and total time
      this.updateOverallState(build.buildData.id, newState, totalRunTime, function(uoserr) {
        cb(uoserr, newState, totalRunTime);
      });
    } else {
      // Otherwise just return the values
      cb(null, newState, totalRunTime);
    }
  } else {
    cb(null, build.buildData.state, build.buildData.totalRunTime);
  }
};

module.exports = Datastore;
<|endoftext|>


<commit_before>(function () {
  "use strict";

  angular
    .module('mnHttp', ["mnPendingQueryKeeper"])
    .factory('mnHttpInterceptor', mnHttpFactory)
    .config(function ($httpProvider) {
      $httpProvider.interceptors.push('mnHttpInterceptor');
    });

  function mnHttpFactory(mnPendingQueryKeeper, $q, $httpParamSerializerJQLike, $timeout) {
    var myHttpInterceptor = {
      request: request,
      response: response,
      responseError: responseError
    };

    return myHttpInterceptor;

    function request(config) {
      if (config.url.indexOf(".html") !== -1 || config.doNotIntercept) {
        return config;
      } else {
        return intercept(config);
      }
    }
    function intercept(config) {
      var pendingQuery = {
        config: _.clone(config)
      };
      var mnHttpConfig = config.mnHttp || {};
      delete config.mnHttp;
      if (config.method.toLowerCase() === "post" && mnHttpConfig.cancelPrevious) {
        var queryInFly = mnPendingQueryKeeper.getQueryInFly(config);
        queryInFly && queryInFly.canceler();
      }
      var canceler = $q.defer();
      var timeoutID;
      var timeout = config.timeout;
      var isCleared;

      function clear() {
        if (isCleared) {
          return;
        }
        isCleared = true;
        timeoutID && $timeout.cancel(timeoutID);
        mnPendingQueryKeeper.removeQueryInFly(pendingQuery);
      }

      function cancel(reason) {
        return function () {
          canceler.resolve(reason);
          clear();
        };
      }

      switch (config.method.toLowerCase()) {
        case 'post':
        case 'put':
          config.headers = config.headers || {};
          if (!mnHttpConfig.isNotForm) {
            config.headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';
            if (!angular.isString(config.data)) {
              config.data = $httpParamSerializerJQLike(config.data);
            }
          }
        break;
      }

      config.timeout = canceler.promise;
      config.clear = clear;

      pendingQuery.canceler = cancel("cancelled");
      pendingQuery.group = mnHttpConfig.group;
      mnPendingQueryKeeper.push(pendingQuery);

      if (timeout) {
        timeoutID = $timeout(cancel("timeout"), timeout);
      }
      return config;
    }

    function clearOnResponse(response) {
      if (response.config.clear && angular.isFunction(response.config.clear)) {
        response.config.clear();
        delete response.config.clear;
      }
    }

    function response(response) {
      clearOnResponse(response);
      return response;
    }
    function responseError(response) {
      clearOnResponse(response);
      return $q.reject(response);
    }
  }

})();
<commit_msg>spock-ui: MB-21064: encode semicolon in post requests<commit_after>(function () {
  "use strict";

  angular
    .module('mnHttp', ["mnPendingQueryKeeper"])
    .factory('mnHttpInterceptor', mnHttpFactory)
    .config(function ($httpProvider) {
      $httpProvider.interceptors.push('mnHttpInterceptor');
    });

  function mnHttpFactory(mnPendingQueryKeeper, $q, $httpParamSerializerJQLike, $timeout) {
    var myHttpInterceptor = {
      request: request,
      response: response,
      responseError: responseError
    };

    return myHttpInterceptor;

    function request(config) {
      if (config.url.indexOf(".html") !== -1 || config.doNotIntercept) {
        return config;
      } else {
        return intercept(config);
      }
    }
    function intercept(config) {
      var pendingQuery = {
        config: _.clone(config)
      };
      var mnHttpConfig = config.mnHttp || {};
      delete config.mnHttp;
      if (config.method.toLowerCase() === "post" && mnHttpConfig.cancelPrevious) {
        var queryInFly = mnPendingQueryKeeper.getQueryInFly(config);
        queryInFly && queryInFly.canceler();
      }
      var canceler = $q.defer();
      var timeoutID;
      var timeout = config.timeout;
      var isCleared;

      function clear() {
        if (isCleared) {
          return;
        }
        isCleared = true;
        timeoutID && $timeout.cancel(timeoutID);
        mnPendingQueryKeeper.removeQueryInFly(pendingQuery);
      }

      function cancel(reason) {
        return function () {
          canceler.resolve(reason);
          clear();
        };
      }

      switch (config.method.toLowerCase()) {
        case 'post':
        case 'put':
          config.headers = config.headers || {};
          if (!mnHttpConfig.isNotForm) {
            config.headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';
            if (!angular.isString(config.data)) {
              //Angular uses it's own method for encoding uri component which called
              //encodeUriQuery. They need a custom method because encodeURIComponent
              //is too aggressive and encodes stuff that doesn't have to be encoded per
              //http://tools.ietf.org/html/rfc3986. However semicolon is important symbol
              //for mochiweb, so we should encode it.
              config.data = $httpParamSerializerJQLike(config.data).replace(/;/gi, '%3B');
            }
          }
        break;
      }

      config.timeout = canceler.promise;
      config.clear = clear;

      pendingQuery.canceler = cancel("cancelled");
      pendingQuery.group = mnHttpConfig.group;
      mnPendingQueryKeeper.push(pendingQuery);

      if (timeout) {
        timeoutID = $timeout(cancel("timeout"), timeout);
      }
      return config;
    }

    function clearOnResponse(response) {
      if (response.config.clear && angular.isFunction(response.config.clear)) {
        response.config.clear();
        delete response.config.clear;
      }
    }

    function response(response) {
      clearOnResponse(response);
      return response;
    }
    function responseError(response) {
      clearOnResponse(response);
      return $q.reject(response);
    }
  }

})();
<|endoftext|>


<commit_before>var express = require('express');
var cors = require('cors');
var bodyParser = require('body-parser');
var nano = require('nano')('http://localhost:5984');
var todo = nano.db.use('todo');

var app = express();

app.use(cors());
app.use(bodyParser.json());

app.get('/', function(req, res, next) {
  console.log('get triggered');
  var results = [];
  todo.view('todos', 'all_todos', function(err, body) {
    for (var row of body.rows) {
      results.push(row.value);
    }
    res.json(results);
  });
});

app.post('/', function(req, res, next) {
  console.log('post triggered');
  var task = {title: req.body.title, completed: false};
  todo.insert(task, function(err, body) {
    if (err) {
      console.log(err);
    }
    task._id = body.id;
    task._rev = body.rev;
    // assign a url based on id and commit back to database
    task.url = 'http://localhost:3000/' + body.id;
    todo.insert(task, function(err, body) {
      res.json(task);
    });
  });
});

app.delete('/', function(req, res, next) {
  console.log('delete triggered');
  todo.view('todos', 'all_todos', function(err, body) {
    if (body.rows.length !== 0) {
      body.rows.forEach(function(curr, index, array) {
        todo.destroy(curr.value._id, curr.value._rev, function(err, body) {
          if (index === array.length - 1) {
            res.json([]);
          }
        });
      });
    } else {
      res.json([]);
    }
  });
});

app.get('/:url', function(req, res, next) {
  todo.get(req.params.url, function(err, body) {
    console.log(body);
    res.json(body);
  });
});

app.patch('/:url', function(req, res, next) {
  todo.get(req.params.url, function(err, body) {
    if (req.body.title) {
      body.title  = req.body.title;
    }
    if (req.body.completed) {
      body.completed  = req.body.completed;
    }
    todo.insert(body, function(err, update) {
      res.json(body);
    });
  });
});

app.delete('/:url', function(req, res, next) {
  todo.get(req.params.url, function(err, body) {
    todo.destroy(body._id, body._rev, function(err, body) {
      res.json([]);
    });
  });
});

app.listen(3000, function() {
  console.log('Cors enabled server listening on port 3000');
});
<commit_msg>A todo now has an order (14/16)<commit_after>var express = require('express');
var cors = require('cors');
var bodyParser = require('body-parser');
var nano = require('nano')('http://localhost:5984');
var todo = nano.db.use('todo');

var app = express();

app.use(cors());
app.use(bodyParser.json());

app.get('/', function(req, res, next) {
  console.log('get triggered');
  var results = [];
  todo.view('todos', 'all_todos', function(err, body) {
    for (var row of body.rows) {
      results.push(row.value);
    }
    res.json(results);
  });
});

app.post('/', function(req, res, next) {
  console.log('post triggered');
  var task = {title: req.body.title, completed: false, order: req.body.order};
  todo.insert(task, function(err, body) {
    if (err) {
      console.log(err);
    }
    task._id = body.id;
    task._rev = body.rev;
    // assign a url based on id and commit back to database
    task.url = 'http://localhost:3000/' + body.id;
    todo.insert(task, function(err, body) {
      res.json(task);
    });
  });
});

app.delete('/', function(req, res, next) {
  console.log('delete triggered');
  todo.view('todos', 'all_todos', function(err, body) {
    if (body.rows.length !== 0) {
      body.rows.forEach(function(curr, index, array) {
        todo.destroy(curr.value._id, curr.value._rev, function(err, body) {
          if (index === array.length - 1) {
            res.json([]);
          }
        });
      });
    } else {
      res.json([]);
    }
  });
});

app.get('/:url', function(req, res, next) {
  todo.get(req.params.url, function(err, body) {
    console.log(body);
    res.json(body);
  });
});

app.patch('/:url', function(req, res, next) {
  todo.get(req.params.url, function(err, body) {
    if (req.body.title) {
      body.title  = req.body.title;
    }
    if (req.body.completed) {
      body.completed  = req.body.completed;
    }
    todo.insert(body, function(err, update) {
      res.json(body);
    });
  });
});

app.delete('/:url', function(req, res, next) {
  todo.get(req.params.url, function(err, body) {
    todo.destroy(body._id, body._rev, function(err, body) {
      res.json([]);
    });
  });
});

app.listen(3000, function() {
  console.log('Cors enabled server listening on port 3000');
});
<|endoftext|>


<commit_before>let React = require('react')

class BlockType {

  constructor({ component, menuItems, label, types, id, private }) {
    if (typeof component === 'object') {
      component = React.createClass(component)
    }

    this.id        = id
    this.label     = label
    this.types     = types || []
    this.component = component
    this.menuItems = menuItems
    this.private   = private
  }

  valueOf() {
    return this.id
  }

}

module.exports = BlockType
<commit_msg>[update] propagate change to block type<commit_after>let React = require('react')

class BlockType {

  constructor({ component, menuItems, label, types, id, childOnly }) {
    if (typeof component === 'object') {
      component = React.createClass(component)
    }

    this.id        = id
    this.label     = label
    this.types     = types || []
    this.component = component
    this.menuItems = menuItems
    this.childOnly = childOnly
  }

  valueOf() {
    return this.id
  }

}

module.exports = BlockType
<|endoftext|>


<commit_before>var express = require('express');
var router = express.Router();
var account = require('../models/account');
var rbac = require('mongoose-rbac');
var role = rbac.Role;
var torii = require('../conf/torii.conf.js').torii;

// admin root
router.get('/', function(req, res){
  res.render('adminHome', {
    logged: req.user,
    toriiTitle: torii.conf.core.title,
    welcomeSubtitle: torii.conf.core.welcomeSubtitle,
    welcomeTitle: torii.conf.core.welcomeTitle,
    welcomeMessage: torii.conf.core.welcomeMessage
  });
});

// user - list
router.get('/user/list', function(req, res){
  res.render('adminUserList',{
    logged: req.user,
    toriiTitle: torii.conf.core.title
  });
});

// user - new
router.get('/user/new', function(req, res){
  role.find({}, function(req, res){
    res.render('adminUserNew',{
      toriiTitle: torii.conf.core.title,
      logged: req.user,
      roles: roles
    });
  });
});

// user - edit
router.get('/user/:userid/edit', function(req, res){
  account.findById(req.params.userid, '_id username role isAdmin isDev name surname', function(err, user){
    if(err){
      res.send(err);
      return;
    }

    user._id = user._id.toHexString();

    role.find({}, function(err, roles){
      if(err){
        res.send(err);
        return;
      }

      res.render('adminUserEdit',{
        toriiTitle: torii.conf.core.title,
        logged: req.user,
        user: user,
        roles: roles
      });
    });
  });
});

// action - list
router.get('/action/list', function(req, res){
  res.render('adminActionList', {
    toriiTitle: torii.conf.core.title,
    logged: req.user
  });
});

// action - new
router.get('/action/new', function(req, res){
  res.render('adminActionNew', {
    toriiTitle: torii.conf.core.title,
    logged: req.user
  });
});

// action - edit
router.get('/action/:action_id/edit', function(req, res){
  res.render('adminActionEdit', {
    toriiTitle: torii.conf.core.title,
    logged: req.user
  });
});

// role - new
router.get('/role/new', function(req, res){
  res.render('adminRoleNew',{
    toriiTitle: torii.conf.core.title,
    logged: req.user
  });
});

// role - list
router.get('/role/list', function(req, res){
  res.render('adminRoleList',{
    toriiTitle: torii.conf.core.title,
    logged: req.user
  });
});

// role - edit
router.get('/role/:role_id/edit', function(req, res){
  role.findById(req.params.role_id, function(err, role){
    if(err){
      res.send(err);
      return;
    }

    res.render('adminRoleEdit', {
      toriiTitle: torii.conf.core.title,
      logged: req.user,
      req: req,
      role: role
    });
  });
});

// collections list
router.get('/collections', function(req, res){
  res.render('adminCollectionList', {
    toriiTitle: torii.conf.core.title,
    req: req,
    logged: req.user
  });
});

// collection new
router.get('/collection/new', function(req, res){
  res.render('adminCollectionNew', {
    toriiTitle: torii.conf.core.title,
    req: req,
    logged: req.user
  });
});

// document - list
router.get('/:collection_name/documents', function(req, res){
  req.user.can('backend-read', req.params.collection_name, function(err,can){
    if(err){
      res.send(err);
      return;
    }

    if(can || req.user.isDev){
      res.render('adminDocumentList', {
        toriiTitle: torii.conf.core.title,
        req: req,
        logged: req.user
      });
    }else{
      res.send(401, 'user are not allowed');
    }

  });
});

// document - new
router.get('/:collection_name/new', function(req, res){
  req.user.can('backend-write', req.params.collection_name, function(err, can){
    if(err){
      res.send(err);
      return;
    }

    if(can || req.user.isDev){
      res.render('adminDocumentNew',{
        toriiTitle: torii.conf.core.title,
        req: req,
        logged: req.user
      });
    }else{
      res.send(401, 'user not allowed');
    }
  });
});

// document - import
router.get('/:collection_name/import', function(req, res){
  req.user.can('backend-write', req.params.collection_name, function(err, can){
    if(err){
      res.send(err);
      return;
    }

    if(can || req.user.isDev){
      res.send('adminDocumentImportCSv', {
        toriiTitle: torii.conf.core.title,
        req: req,
        logged: req.user
      });
    }else{
      res.send(401, 'user not allowed');
      return;
    }
  });
});

// document - edit
router.get('/:collection_name/:document_id/edit', function(req, res){
  req.user.can('backend-write', req.params.collection_name, function(err, can){
    if(err){
      res.send(err);
      return;
    }

    if(can || req.user.isDev){
      res.render('adminDocumentEdit',{
        toriiTitle: torii.conf.core.title,
        req: req,
        logged: req.user
      });
    }else{
      res.send(401, 'user not allowed');
    }
  });
});

module.exports = router;
<commit_msg>fix bug<commit_after>var express = require('express');
var router = express.Router();
var account = require('../models/account');
var rbac = require('mongoose-rbac');
var role = rbac.Role;
var torii = require('../conf/torii.conf.js').torii;

// admin root
router.get('/', function(req, res){
  res.render('adminHome', {
    logged: req.user,
    toriiTitle: torii.conf.core.title,
    welcomeSubtitle: torii.conf.core.welcomeSubtitle,
    welcomeTitle: torii.conf.core.welcomeTitle,
    welcomeMessage: torii.conf.core.welcomeMessage
  });
});

// user - list
router.get('/user/list', function(req, res){
  res.render('adminUserList',{
    logged: req.user,
    toriiTitle: torii.conf.core.title
  });
});

// user - new
router.get('/user/new', function(req, res){
  role.find({}, function(err, roles){
    res.render('adminUserNew',{
      toriiTitle: torii.conf.core.title,
      logged: req.user,
      roles: roles
    });
  });
});

// user - edit
router.get('/user/:userid/edit', function(req, res){
  account.findById(req.params.userid, '_id username role isAdmin isDev name surname', function(err, user){
    if(err){
      res.send(err);
      return;
    }

    user._id = user._id.toHexString();

    role.find({}, function(err, roles){
      if(err){
        res.send(err);
        return;
      }

      res.render('adminUserEdit',{
        toriiTitle: torii.conf.core.title,
        logged: req.user,
        user: user,
        roles: roles
      });
    });
  });
});

// action - list
router.get('/action/list', function(req, res){
  res.render('adminActionList', {
    toriiTitle: torii.conf.core.title,
    logged: req.user
  });
});

// action - new
router.get('/action/new', function(req, res){
  res.render('adminActionNew', {
    toriiTitle: torii.conf.core.title,
    logged: req.user
  });
});

// action - edit
router.get('/action/:action_id/edit', function(req, res){
  res.render('adminActionEdit', {
    toriiTitle: torii.conf.core.title,
    logged: req.user
  });
});

// role - new
router.get('/role/new', function(req, res){
  res.render('adminRoleNew',{
    toriiTitle: torii.conf.core.title,
    logged: req.user
  });
});

// role - list
router.get('/role/list', function(req, res){
  res.render('adminRoleList',{
    toriiTitle: torii.conf.core.title,
    logged: req.user
  });
});

// role - edit
router.get('/role/:role_id/edit', function(req, res){
  role.findById(req.params.role_id, function(err, role){
    if(err){
      res.send(err);
      return;
    }

    res.render('adminRoleEdit', {
      toriiTitle: torii.conf.core.title,
      logged: req.user,
      req: req,
      role: role
    });
  });
});

// collections list
router.get('/collections', function(req, res){
  res.render('adminCollectionList', {
    toriiTitle: torii.conf.core.title,
    req: req,
    logged: req.user
  });
});

// collection new
router.get('/collection/new', function(req, res){
  res.render('adminCollectionNew', {
    toriiTitle: torii.conf.core.title,
    req: req,
    logged: req.user
  });
});

// document - list
router.get('/:collection_name/documents', function(req, res){
  req.user.can('backend-read', req.params.collection_name, function(err,can){
    if(err){
      res.send(err);
      return;
    }

    if(can || req.user.isDev){
      res.render('adminDocumentList', {
        toriiTitle: torii.conf.core.title,
        req: req,
        logged: req.user
      });
    }else{
      res.send(401, 'user are not allowed');
    }

  });
});

// document - new
router.get('/:collection_name/new', function(req, res){
  req.user.can('backend-write', req.params.collection_name, function(err, can){
    if(err){
      res.send(err);
      return;
    }

    if(can || req.user.isDev){
      res.render('adminDocumentNew',{
        toriiTitle: torii.conf.core.title,
        req: req,
        logged: req.user
      });
    }else{
      res.send(401, 'user not allowed');
    }
  });
});

// document - import
router.get('/:collection_name/import', function(req, res){
  req.user.can('backend-write', req.params.collection_name, function(err, can){
    if(err){
      res.send(err);
      return;
    }

    if(can || req.user.isDev){
      res.send('adminDocumentImportCSv', {
        toriiTitle: torii.conf.core.title,
        req: req,
        logged: req.user
      });
    }else{
      res.send(401, 'user not allowed');
      return;
    }
  });
});

// document - edit
router.get('/:collection_name/:document_id/edit', function(req, res){
  req.user.can('backend-write', req.params.collection_name, function(err, can){
    if(err){
      res.send(err);
      return;
    }

    if(can || req.user.isDev){
      res.render('adminDocumentEdit',{
        toriiTitle: torii.conf.core.title,
        req: req,
        logged: req.user
      });
    }else{
      res.send(401, 'user not allowed');
    }
  });
});

module.exports = router;
<|endoftext|>


<commit_before>/************************************************************************************
** The MIT License (MIT)
**
** Copyright (c) 2015 Serg "EXL" Koles
**
** 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.
************************************************************************************/

var TelegramBot = require('node-telegram-bot-api');
var FileSystem = require('fs');

var token = getTokenAccess();
var catchPhrases = getCatchPhrases();

var botOptions = {
    polling: true
};

var bot = new TelegramBot(token, botOptions);

var globalCountOfMessagesWithDigest = 0;
var globalUserNameIs;

var globalStackListDigestMessages = [ ];

bot.getMe().then(function (me)
{
    console.log('Hello! My name is %s!', me.first_name);
    console.log('My id is %s.', me.id);
    console.log('And my username is @%s.', me.username);
});

bot.on('text', function(msg)
{
    // Set main variables
    var messageChatId = msg.chat.id;
    var messageText = msg.text;
    var messageDate = msg.date;
    globalUserNameIs = msg.from.username;

    // DEBUG SECTION
    // console.log(msg);
    // END DEBUG SECTION

    // DIGEST TAG
    if (messageText.indexOf('#digest') >= 0) {
        globalCountOfMessagesWithDigest++;
        var normalMessage = normalizeMessage(messageText);
        if (!(isBlank(normalMessage))) {
            var messageInfoStruct = {
                's_chatID': messageChatId,
                's_date': messageDate,
                's_message': normalMessage,
                's_username': globalUserNameIs
            };

            globalStackListDigestMessages.push(messageInfoStruct);

            // Send message by bot.
            sendMessageByBot(messageChatId,
                             catchPhrases.digestTag[getRandomInt(0, 5)]);
        }
    }

    // DIGEST COMMAND
    if (messageText === '/digest' || messageText === '/Digest') {
        // Digest delay.
        // 45 sec for debug.
        // 43 200 for 12-hours.
        // 86 400 for 24-hours.
        // 172 800 for 48-hours.
        var hourDelay = 86400;

        var bSendDigest = false;

        if (globalStackListDigestMessages.length > 0) {
            // Delete all obsolete digest messages from globalStackListDigestMessages
            bSendDigest = deleteObsoleteDigestMessages(messageDate - hourDelay);
        }

        // Generate Bot Answer
        if (bSendDigest) {
            var botAnswer = '';
            var endLineString = ';\n';
            var stackSize = globalStackListDigestMessages.length;

            // Count of digest messages from one chat.
            var countOfDigestMessagesByChat = getCountDigestMessagesOfChat(messageChatId);

            // Append answer string.
            // botAnswer += 'Hola amigos!\nThere is 24-hour digest of this chat:\n';
            for (var i = 0; i < stackSize; ++i) {
                if (globalStackListDigestMessages[i].s_chatID === messageChatId) {
                    botAnswer += catchPhrases.digestMarker + globalStackListDigestMessages[i].s_message + endLineString;
                }
            }

            // Delete last new line and semicolon characters (;\n).
            botAnswer = botAnswer.substring(0, botAnswer.length - 2);

            // Add dot to end of line.
            if (botAnswer.substr(botAnswer.length - 1) !== '.') {
                botAnswer += '.';
            }

            // Check countOfDigestMessagesByChat.
            if (countOfDigestMessagesByChat > 0) {
                // Send botAnswer to chat with catchPhrases chunks.
                sendMessageByBot(messageChatId, getDigestReportHeader() + botAnswer);
            } else {
                sendNoDigestMessages(messageChatId);
            }
        } else {
            sendNoDigestMessages(messageChatId);
        }
    }

    // DEBUG SECTION
    // CLEARSTACK COMMAND
    if (messageText === '/stackClear') {
        if (getAdminRights()) {
            globalStackListDigestMessages = [ ];
            sendMessageByBot(messageChatId,
                             catchPhrases.debugCommandMessages[1]);
        } else {
            sendMessageByBot(messageChatId,
                             catchPhrases.debugCommandMessages[0]);
        }
    }

    // HELLO COMMAND
    if (messageText === '/hello') {
        if (getAdminRights()) {
            sendMessageByBot(messageChatId,
                             catchPhrases.helloCommand[getRandomInt(0, 5)]);
        }
    }

    // DIGESTCOUNT COMMAND
    if (messageText === '/digestCount') {
        if (getAdminRights()) {
            sendMessageByBot(messageChatId,
                             catchPhrases.debugCommandMessages[4] + globalCountOfMessagesWithDigest);
        }
    }

    // STACK COMMAND
    if (messageText === '/stack') {
        if (getAdminRights()) {
            var stack = '\n';
            var sizeOfStack = globalStackListDigestMessages.length;
            if (sizeOfStack > 0) {
                for (var j = 0; j < sizeOfStack; ++j) {
                    stack += globalStackListDigestMessages[j].s_chatID + ' ';
                    stack += globalStackListDigestMessages[j].s_username + ' ';
                    stack += globalStackListDigestMessages[j].s_date + ' ';
                    stack += globalStackListDigestMessages[j].s_message + '\n';
                }
                sendMessageByBot(messageChatId,
                                 catchPhrases.debugCommandMessages[3] + stack);
            } else {
                sendMessageByBot(messageChatId,
                                 catchPhrases.debugCommandMessages[2]);
            }
        } else {
            sendMessageByBot(messageChatId,
                             catchPhrases.debugCommandMessages[0]);
        }
    }
    // END DEBUG SECTION
});

function getAdminRights()
{
    return globalUserNameIs === 'exlmoto';
}

function getDigestReportHeader()
{
    return catchPhrases.digestCommandHello[getRandomInt(0, 5)]
            + '\n'
            + catchPhrases.digestCommandHeader[getRandomInt(0, 5)]
            + '\n';
}

function sendNoDigestMessages(aChatId)
{
    sendMessageByBot(aChatId, catchPhrases.digestCommandNoMessages[getRandomInt(0, 5)]);
}

function sendMessageByBot(aChatId, aMessage)
{
    // Replace '%username%' by userName.
    var readyMessage = aMessage.replace('%username%', '@' + globalUserNameIs);
    bot.sendMessage(aChatId, readyMessage, { caption: 'I\'m a cute bot!' });
}

function getRandomInt(aMin, aMax)
{
    return Math.floor(Math.random() * (aMax - aMin + 1)) + aMin;
}

function getCountDigestMessagesOfChat(aChatId)
{
    var stackSize = globalStackListDigestMessages.length;
    var countOfMessages = 0;
    for (var i = 0; i < stackSize; ++i) {
        if (globalStackListDigestMessages[i].s_chatID === aChatId) {
            countOfMessages++;
        }
    }
    return countOfMessages;
}

function deleteObsoleteDigestMessages(aObsoleteDate)
{
    var stackSize = globalStackListDigestMessages.length;

    var position = 0;
    for (var i = 0; i < stackSize; ++i) {
        if (globalStackListDigestMessages[i].s_date < aObsoleteDate) {
            position++;
        }
    }

    // All stack digest messages are obsolete.
    // Drop stack.
    if (position == stackSize) {
        globalStackListDigestMessages = [ ];
        return false;
    }

    // All stack digest messages are relevant.
    // Print them.
    if (position == 0) {
        return true;
    }

    // Replace current digest stack by sliced.
    globalStackListDigestMessages = globalStackListDigestMessages.slice(position);

    // Return true if stack not empty
    return stackSize > 0;
}

function normalizeMessage(aMessage)
{
    var normalMessage = '';

    if (!isEmpty(aMessage)) {
        // Delete #digest tag from message
        normalMessage = aMessage.replace('#digest', '');

        // Delete %username% variable
        if (!(isBlank(normalMessage))) {
            normalMessage = normalMessage.replace('%username%', '');
        }

        // Ttrim all trailing spaces
        if (!(isBlank(normalMessage))) {
            normalMessage = normalMessage.trim();
        }

        // Replace multiple spaces with a single space
        if (!(isBlank(normalMessage))) {
            normalMessage = normalMessage.replace(/\s\s+/g, ' ');
        }

        // Capitalize the first letter of message
        if (!(isBlank(normalMessage))) {
            normalMessage = capitalizeFirstLetterOfString(normalMessage);
        }
    }
    return normalMessage;
}

function capitalizeFirstLetterOfString(aString)
{
    return aString.charAt(0).toUpperCase() + aString.slice(1);
}

function isEmpty(aString)
{
    return (!aString || 0 === aString.length);
}

function isBlank(aString)
{
    return (!aString || /^\s*$/.test(aString));
}

function getTokenAccess()
{
    var parsedJsonFromFile = getJSONFileFromFileSystem('BOT_TOKEN_ACCESS.json');
    var token = parsedJsonFromFile.botTokenAccess;

    if (token === 'PLEASE_WRITE_YOU_TOKEN_HERE') {
        console.error('Error: Token is empty!\nPlease write your token in \'BOT_TOKEN_ACCESS.json\' file.')
        process.exit(1);
        return false;
    }

    return token;
}

function getCatchPhrases()
{
    return getJSONFileFromFileSystem('CatchPhrases.json');
}

function getJSONFileFromFileSystem(aFileName)
{
    var dotSlashName = './' + aFileName
    return JSON.parse(FileSystem.readFileSync(dotSlashName, 'utf-8'));
}

function getCountOfMessageWithDigest()
{
    return 'Count of digest messages is ' + globalCountOfMessagesWithDigest;
}
<commit_msg>Add rouble command<commit_after>/************************************************************************************
** The MIT License (MIT)
**
** Copyright (c) 2015 Serg "EXL" Koles
**
** 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.
************************************************************************************/

var TelegramBot = require('node-telegram-bot-api');
var FileSystem = require('fs');
var Http = require("http");

var token = getTokenAccess();
var catchPhrases = getCatchPhrases();

var httpOptions = {
    host: "www.cbr.ru",
    port: 80,
    path: "/scripts/XML_daily.asp?"
};

var botOptions = {
    polling: true
};

var bot = new TelegramBot(token, botOptions);

var globalCountOfMessagesWithDigest = 0;
var globalUserNameIs;

var globalStackListDigestMessages = [ ];

// CURRENCY SECTION
var xmlContent = "";
var globalUsdCurrencyValue = 0.0;
var globalCurrencyList = {
    'USD': 0.0,
    'EUR': 0.0,
    'UAH': 0.0,
    'KZT': 0.0,
    'BYR': 0.0
};
initilizeCurrencyListAndGetUsdValue();
// END CURRENCY SECTION

// CURRENCY SECTION
function removeTags(aString)
{
    return aString.replace(/(<([^>]+)>)/ig, '');
}

function getLineFromXml(aStart, aString)
{
    var textSize = aString.length;
    var targetString = '';
    for (var i = aStart; i < textSize; ++i) {
        if (aString[i] === '\n') {
            break;
        }
        targetString += aString[i];
    }

    return removeTags(targetString.trim());
}

function getStringBelow(aStart, aBelow, aString)
{
    var textSize = aString.length;
    var countOfLineEndings = 0;
    var getLineWith = 0;

    for (var i = aStart; i < textSize; ++i) {
        if (countOfLineEndings === aBelow) {
            getLineWith = i;
            break;
        }
        if (aString[i] === '\n') {
            countOfLineEndings++;
        }
    }

    return getLineFromXml(getLineWith, aString);
}

function replaceCommasByDots(aString)
{
    return aString.replace(',', '.');
}

function getCurrentValue(aCurrency, aString)
{
    var nominal = parseFloat(replaceCommasByDots(getStringBelow(aString.indexOf(aCurrency), 1, aString)));
    var value = parseFloat(replaceCommasByDots(getStringBelow(aString.indexOf(aCurrency), 3, aString)));

    return (value / nominal).toFixed(4);
}

function shittyParseXML(aAllXml)
{
    if (isEmpty(aAllXml)) {
        globalCurrencyList.USD = 'Error';
        globalCurrencyList.EUR = 'Error';
        globalCurrencyList.UAH = 'Error';
        globalCurrencyList.KZT = 'Error';
        globalCurrencyList.BYR = 'Error';
    }

    globalCurrencyList.USD = getCurrentValue('USD', aAllXml);
    globalCurrencyList.EUR = getCurrentValue('EUR', aAllXml);
    globalCurrencyList.UAH = getCurrentValue('UAH', aAllXml);
    globalCurrencyList.KZT = getCurrentValue('KZT', aAllXml);
    globalCurrencyList.BYR = getCurrentValue('BYR', aAllXml);

    globalUsdCurrencyValue = globalCurrencyList.USD;
}

function updateGlobalCurrencyList()
{
    var request = Http.request(httpOptions, function(aRes) {
        aRes.setEncoding("utf8");
        aRes.on("data", function(aChunk) {
            xmlContent += aChunk;
        });

        console.log('Req');

        aRes.on("end", function() {
            shittyParseXML(xmlContent);
        });
    });
    request.end();
}

function initilizeCurrencyListAndGetUsdValue()
{
    updateGlobalCurrencyList();
}
// END CURRENCY SECTION

bot.getMe().then(function (me)
{
    console.log('Hello! My name is %s!', me.first_name);
    console.log('My id is %s.', me.id);
    console.log('And my username is @%s.', me.username);
});

bot.on('text', function(msg)
{
    // Set main variables
    var messageChatId = msg.chat.id;
    var messageText = msg.text;
    var messageDate = msg.date;
    globalUserNameIs = msg.from.username;

    // DEBUG SECTION
    // console.log(msg);
    // END DEBUG SECTION

    // DIGEST TAG
    if (messageText.indexOf('#digest') >= 0) {
        globalCountOfMessagesWithDigest++;
        var normalMessage = normalizeMessage(messageText);
        if (!(isBlank(normalMessage))) {
            var messageInfoStruct = {
                's_chatID': messageChatId,
                's_date': messageDate,
                's_message': normalMessage,
                's_username': globalUserNameIs
            };

            globalStackListDigestMessages.push(messageInfoStruct);

            // Send message by bot.
            sendMessageByBot(messageChatId,
                             catchPhrases.digestTag[getRandomInt(0, 5)]);
        }
    }

    // DIGEST COMMAND
    if (messageText === '/digest' || messageText === '/Digest') {
        // Digest delay.
        // 45 sec for debug.
        // 43 200 for 12-hours.
        // 86 400 for 24-hours.
        // 172 800 for 48-hours.
        var hourDelay = 86400;

        var bSendDigest = false;

        if (globalStackListDigestMessages.length > 0) {
            // Delete all obsolete digest messages from globalStackListDigestMessages
            bSendDigest = deleteObsoleteDigestMessages(messageDate - hourDelay);
        }

        // Generate Bot Answer
        if (bSendDigest) {
            var botAnswer = '';
            var endLineString = ';\n';
            var stackSize = globalStackListDigestMessages.length;

            // Count of digest messages from one chat.
            var countOfDigestMessagesByChat = getCountDigestMessagesOfChat(messageChatId);

            // Append answer string.
            // botAnswer += 'Hola amigos!\nThere is 24-hour digest of this chat:\n';
            for (var i = 0; i < stackSize; ++i) {
                if (globalStackListDigestMessages[i].s_chatID === messageChatId) {
                    botAnswer += catchPhrases.digestMarker + globalStackListDigestMessages[i].s_message + endLineString;
                }
            }

            // Delete last new line and semicolon characters (;\n).
            botAnswer = botAnswer.substring(0, botAnswer.length - 2);

            // Add dot to end of line.
            if (botAnswer.substr(botAnswer.length - 1) !== '.') {
                botAnswer += '.';
            }

            // Check countOfDigestMessagesByChat.
            if (countOfDigestMessagesByChat > 0) {
                // Send botAnswer to chat with catchPhrases chunks.
                sendMessageByBot(messageChatId, getDigestReportHeader() + botAnswer);
            } else {
                sendNoDigestMessages(messageChatId);
            }
        } else {
            sendNoDigestMessages(messageChatId);
        }
    }

    // RUBLE COMMAND
    if (messageText === '/rouble') {
        var lastUSDValue = globalUsdCurrencyValue;
        updateGlobalCurrencyList();

        console.log(globalCurrencyList);
    }

    // DEBUG SECTION
    // CLEARSTACK COMMAND
    if (messageText === '/stackClear') {
        if (getAdminRights()) {
            globalStackListDigestMessages = [ ];
            sendMessageByBot(messageChatId,
                             catchPhrases.debugCommandMessages[1]);
        } else {
            sendMessageByBot(messageChatId,
                             catchPhrases.debugCommandMessages[0]);
        }
    }

    // HELLO COMMAND
    if (messageText === '/hello') {
        if (getAdminRights()) {
            sendMessageByBot(messageChatId,
                             catchPhrases.helloCommand[getRandomInt(0, 5)]);
        }
    }

    // DIGESTCOUNT COMMAND
    if (messageText === '/digestCount') {
        if (getAdminRights()) {
            sendMessageByBot(messageChatId,
                             catchPhrases.debugCommandMessages[4] + globalCountOfMessagesWithDigest);
        }
    }

    // STACK COMMAND
    if (messageText === '/stack') {
        if (getAdminRights()) {
            var stack = '\n';
            var sizeOfStack = globalStackListDigestMessages.length;
            if (sizeOfStack > 0) {
                for (var j = 0; j < sizeOfStack; ++j) {
                    stack += globalStackListDigestMessages[j].s_chatID + ' ';
                    stack += globalStackListDigestMessages[j].s_username + ' ';
                    stack += globalStackListDigestMessages[j].s_date + ' ';
                    stack += globalStackListDigestMessages[j].s_message + '\n';
                }
                sendMessageByBot(messageChatId,
                                 catchPhrases.debugCommandMessages[3] + stack);
            } else {
                sendMessageByBot(messageChatId,
                                 catchPhrases.debugCommandMessages[2]);
            }
        } else {
            sendMessageByBot(messageChatId,
                             catchPhrases.debugCommandMessages[0]);
        }
    }
    // END DEBUG SECTION
});

function getAdminRights()
{
    return globalUserNameIs === 'exlmoto';
}

function getDigestReportHeader()
{
    return catchPhrases.digestCommandHello[getRandomInt(0, 5)]
            + '\n'
            + catchPhrases.digestCommandHeader[getRandomInt(0, 5)]
            + '\n';
}

function sendNoDigestMessages(aChatId)
{
    sendMessageByBot(aChatId, catchPhrases.digestCommandNoMessages[getRandomInt(0, 5)]);
}

function sendMessageByBot(aChatId, aMessage)
{
    // Replace '%username%' by userName.
    var readyMessage = aMessage.replace('%username%', '@' + globalUserNameIs);
    bot.sendMessage(aChatId, readyMessage, { caption: 'I\'m a cute bot!' });
}

function getRandomInt(aMin, aMax)
{
    return Math.floor(Math.random() * (aMax - aMin + 1)) + aMin;
}

function getCountDigestMessagesOfChat(aChatId)
{
    var stackSize = globalStackListDigestMessages.length;
    var countOfMessages = 0;
    for (var i = 0; i < stackSize; ++i) {
        if (globalStackListDigestMessages[i].s_chatID === aChatId) {
            countOfMessages++;
        }
    }
    return countOfMessages;
}

function deleteObsoleteDigestMessages(aObsoleteDate)
{
    var stackSize = globalStackListDigestMessages.length;

    var position = 0;
    for (var i = 0; i < stackSize; ++i) {
        if (globalStackListDigestMessages[i].s_date < aObsoleteDate) {
            position++;
        }
    }

    // All stack digest messages are obsolete.
    // Drop stack.
    if (position == stackSize) {
        globalStackListDigestMessages = [ ];
        return false;
    }

    // All stack digest messages are relevant.
    // Print them.
    if (position == 0) {
        return true;
    }

    // Replace current digest stack by sliced.
    globalStackListDigestMessages = globalStackListDigestMessages.slice(position);

    // Return true if stack not empty
    return stackSize > 0;
}

function normalizeMessage(aMessage)
{
    var normalMessage = '';

    if (!isEmpty(aMessage)) {
        // Delete #digest tag from message
        normalMessage = aMessage.replace('#digest', '');

        // Delete %username% variable
        if (!(isBlank(normalMessage))) {
            normalMessage = normalMessage.replace('%username%', '');
        }

        // Ttrim all trailing spaces
        if (!(isBlank(normalMessage))) {
            normalMessage = normalMessage.trim();
        }

        // Replace multiple spaces with a single space
        if (!(isBlank(normalMessage))) {
            normalMessage = normalMessage.replace(/\s\s+/g, ' ');
        }

        // Capitalize the first letter of message
        if (!(isBlank(normalMessage))) {
            normalMessage = capitalizeFirstLetterOfString(normalMessage);
        }
    }
    return normalMessage;
}

function capitalizeFirstLetterOfString(aString)
{
    return aString.charAt(0).toUpperCase() + aString.slice(1);
}

function isEmpty(aString)
{
    return (!aString || 0 === aString.length);
}

function isBlank(aString)
{
    return (!aString || /^\s*$/.test(aString));
}

function getTokenAccess()
{
    var parsedJsonFromFile = getJSONFileFromFileSystem('BOT_TOKEN_ACCESS.json');
    var token = parsedJsonFromFile.botTokenAccess;

    if (token === 'PLEASE_WRITE_YOU_TOKEN_HERE') {
        console.error('Error: Token is empty!\nPlease write your token in \'BOT_TOKEN_ACCESS.json\' file.')
        process.exit(1);
        return false;
    }

    return token;
}

function getCatchPhrases()
{
    return getJSONFileFromFileSystem('CatchPhrases.json');
}

function getJSONFileFromFileSystem(aFileName)
{
    var dotSlashName = './' + aFileName
    return JSON.parse(FileSystem.readFileSync(dotSlashName, 'utf-8'));
}

function getCountOfMessageWithDigest()
{
    return 'Count of digest messages is ' + globalCountOfMessagesWithDigest;
}
<|endoftext|>


<commit_before>var express = require('express');
var router = express.Router();

/*
 * GET bill_list.
 */
router.get('/bill_list', function(req, res) {
    var db = req.db;
    var collection = db.get('bill_list');
    collection.find({},{},function(e,docs){
        res.json(docs);
    });
});

/*
 * POST to adduser.
 */
router.post('/add_bill', function(req, res) {
    var db = req.db;
    var collection = db.get('bill_list'); // get collection
    collection.insert(req.body, function(err, result){
        res.send(
            (err === null) ? { msg: '' } : { msg: err }
        );
    });

    // db.collection('collectionName').insert({req.data}, function (err, doc) {
    //        //rest of code
    // });
});

module.exports = router;
<commit_msg>Remove unneccessary comments<commit_after>var express = require('express');
var router = express.Router();

/*
 * GET bill_list.
 */
router.get('/bill_list', function(req, res) {
    var db = req.db;
    var collection = db.get('bill_list');
    collection.find({},{},function(e,docs){
        res.json(docs);
    });
});

/*
 * POST to add_bill.
 */
router.post('/add_bill', function(req, res) {
    var db = req.db;
    var collection = db.get('bill_list'); // get collection
    collection.insert(req.body, function(err, result){
        res.send(
            (err === null) ? { msg: '' } : { msg: err }
        );
    });
});

module.exports = router;
<|endoftext|>


<commit_before>var TelegramBot = require('node-telegram-bot-api');
var FileSystem = require("fs");

var token = getTokenAccess();

var botOptions = {
    polling: true
};

var bot = new TelegramBot(token, botOptions);

var globalCountOfMessagesWithDigest = 0;
var globalUserNameIs;

var globalStackListDigestMessages = [ ];

bot.getMe().then(function (me) {
    console.log('Hello! My name is %s!', me.first_name);
    console.log('My id is %s.', me.id);
    console.log('And my username is @%s.', me.username);
});

bot.on('text', function(msg) {
    // Set main variables
    var messageChatId = msg.chat.id;
    var messageText = msg.text;
    var messageDate = msg.date;
    globalUserNameIs = msg.from.username;

    // DEBUG SECTION
    console.log(msg);
    // END DEBUG SECTION

    if (messageText.indexOf('#digest') >= 0) {
        globalCountOfMessagesWithDigest++;
        console.log('Message before normalization:' + messageText)
        var normalMessage = normalizeMessage(messageText);
        console.log('Message after normalization:' + normalMessage)
        if (!(isBlank(normalMessage))) {
            var messageInfoStruct = {
                's_chatID': messageChatId,
                's_date': messageDate,
                's_message': messageText,
                's_username': globalUserNameIs
            };

            globalStackListDigestMessages.push(messageInfoStruct);

            // TODO: sending message by bot
        }
    }

    console.log("Stack view")
    console.log(globalStackListDigestMessages)

    //    if (msg.text === '/digest' || msg.text === '/Digest') {
    //        console.log('Digest command received, sending digest stack...');
    //        bot.sendMessage(messageChatId,
    //                        getCountOfMessageWithDigest(),
    //                        { caption: "I'm a bot!" });
    //    }

    //    console.log(globalCountOfMessagesWithDigest);
});

function normalizeMessage(aMessage) {
    var normalMessage = '';

    if (!isEmpty(aMessage)) {
        // Delete #digest tag from message
        normalMessage = aMessage.replace('#digest', '');

        // Ttrim all trailing spaces
        if (!(isBlank(normalMessage))) {
            normalMessage = normalMessage.trim();
        }

        // Replace multiple spaces with a single space
        if (!(isBlank(normalMessage))) {
            normalMessage = normalMessage.replace(/\s\s+/g, ' ');
        }

        // Capitalize the first letter of message
        if (!(isBlank(normalMessage))) {
            normalMessage = capitalizeFirstLetterOfString(normalMessage);
        }
    }
    return normalMessage;
}

function capitalizeFirstLetterOfString(aString) {
    return aString.charAt(0).toUpperCase() + aString.slice(1);
}

function isEmpty(aString) {
    return (!aString || 0 === aString.length);
}

function isBlank(aString) {
    return (!aString || /^\s*$/.test(aString));
}

function getTokenAccess() {
    var parsedJsonFromFile = getJSONFileFromFileSystem('BOT_TOKEN_ACCESS.json');
    var token = parsedJsonFromFile.botTokenAccess;

    if (token === 'PLEASE_WRITE_YOU_TOKEN_HERE') {
        console.error('Error: Token is empty!\nPlease write your token in \'BOT_TOKEN_ACCESS.json\' file.')
        process.exit(1);
        return false;
    }

    return token;
}

function getJSONFileFromFileSystem(aFileName) {
    var dotSlashName = './' + aFileName
    return JSON.parse(FileSystem.readFileSync(dotSlashName, 'utf-8'));
}

function getCountOfMessageWithDigest() {
    return 'Count of digest messages is ' + globalCountOfMessagesWithDigest;
}
<commit_msg>Test /digest command<commit_after>var TelegramBot = require('node-telegram-bot-api');
var FileSystem = require('fs');

var token = getTokenAccess();

var botOptions = {
    polling: true
};

var bot = new TelegramBot(token, botOptions);

var globalCountOfMessagesWithDigest = 0;
var globalUserNameIs;

var globalStackListDigestMessages = [ ];

bot.getMe().then(function (me)
{
    console.log('Hello! My name is %s!', me.first_name);
    console.log('My id is %s.', me.id);
    console.log('And my username is @%s.', me.username);
});

bot.on('text', function(msg)
{
    // Set main variables
    var messageChatId = msg.chat.id;
    var messageText = msg.text;
    var messageDate = msg.date;
    globalUserNameIs = msg.from.username;

    // DEBUG SECTION
    console.log(msg);
    // END DEBUG SECTION

    if (messageText.indexOf('#digest') >= 0) {
        globalCountOfMessagesWithDigest++;
        var normalMessage = normalizeMessage(messageText);
        if (!(isBlank(normalMessage))) {
            var messageInfoStruct = {
                's_chatID': messageChatId,
                's_date': messageDate,
                's_message': normalMessage,
                's_username': globalUserNameIs
            };

            globalStackListDigestMessages.push(messageInfoStruct);

            // TODO: sending message by bot
        }
    }

    if (messageText === '/digest' || messageText === '/Digest') {
        var bSendDigest = false;

        // TODO: Delay table here
        var hourDelay = 50000;

        if (globalStackListDigestMessages.length > 0) {
            // Delete all obsolete digest messages from globalStackListDigestMessages
            bSendDigest = deleteObsoleteDigestMessages(messageDate - hourDelay);
        }

        // Generate Bot Answer
        if (bSendDigest) {
            var botAnswer = '';
            var endLineString = ';\n';
            var stackSize = globalStackListDigestMessages.length;

            // Count of digest messages from one chat.
            var countOfDigestMessagesByChat = getCountDigestMessagesOfChat(messageChatId);

            // Append answer string.
            botAnswer += 'Hola amigos!\nThere is 24-hour digest of this chat:\n';
            for (var i = 0; i < stackSize; ++i) {
                if (globalStackListDigestMessages[i].s_chatID === messageChatId) {
                    botAnswer += globalStackListDigestMessages[i].s_message + endLineString;
                }
            }

            // Delete last new line and semicolon characters (;\n).
            botAnswer = botAnswer.substring(0, str.length - 1);

            // Add dot to end of line.
            botAnswer += '.';

            // Check countOfDigestMessagesByChat
            if (countOfDigestMessagesByChat > 0) {
                // TODO: send botAnswer
                console.log(botAnswer);
            } else {
                // TODO: no messages
            }
        } else {
            // TODO: send no message to chat
        }
    }

    console.log('Stack view')
    console.log(globalStackListDigestMessages)

    //    if (msg.text === '/digest' || msg.text === '/Digest') {
    //        console.log('Digest command received, sending digest stack...');
    //        bot.sendMessage(messageChatId,
    //                        getCountOfMessageWithDigest(),
    //                        { caption: "I'm a bot!" });
    //    }

    // TODO: /stackCount command
    //    console.log(globalCountOfMessagesWithDigest);
});

function getCountDigestMessagesOfChat(aChatId) {
    var stackSize = globalStackListDigestMessages.length;
    var countOfMessages = 0;
    for (var i = 0; i < stackSize; ++i) {
        if (globalStackListDigestMessages[i].s_chatID === aChatId) {
            countOfMessages++;
        }
    }
    return countOfMessages;
}

function deleteObsoleteDigestMessages(aObsoleteDate)
{
    var stackSize = globalStackListDigestMessages.length;

    var position = 0;
    for (var i = 0; i < stackSize; ++i) {
        if (globalStackListDigestMessages[i].s_date < aObsoleteDate) {
            position++;
        }
    }

    // All stack digest messages are obsolete.
    // Drop stack.
    if (position == stackSize) {
        globalStackListDigestMessages = [ ];
        return false;
    }

    // All stack digest messages are relevant.
    // Print them.
    if (position == 0) {
        return true;
    }

    // Replace current digest stack by sliced.
    globalStackListDigestMessages = globalStackListDigestMessages.slice(position);

    // Return true if stack not empty
    return stackSize > 0;
}

function normalizeMessage(aMessage)
{
    var normalMessage = '';

    if (!isEmpty(aMessage)) {
        // Delete #digest tag from message
        normalMessage = aMessage.replace('#digest', '');

        // Ttrim all trailing spaces
        if (!(isBlank(normalMessage))) {
            normalMessage = normalMessage.trim();
        }

        // Replace multiple spaces with a single space
        if (!(isBlank(normalMessage))) {
            normalMessage = normalMessage.replace(/\s\s+/g, ' ');
        }

        // Capitalize the first letter of message
        if (!(isBlank(normalMessage))) {
            normalMessage = capitalizeFirstLetterOfString(normalMessage);
        }
    }
    return normalMessage;
}

function capitalizeFirstLetterOfString(aString)
{
    return aString.charAt(0).toUpperCase() + aString.slice(1);
}

function isEmpty(aString)
{
    return (!aString || 0 === aString.length);
}

function isBlank(aString)
{
    return (!aString || /^\s*$/.test(aString));
}

function getTokenAccess()
{
    var parsedJsonFromFile = getJSONFileFromFileSystem('BOT_TOKEN_ACCESS.json');
    var token = parsedJsonFromFile.botTokenAccess;

    if (token === 'PLEASE_WRITE_YOU_TOKEN_HERE') {
        console.error('Error: Token is empty!\nPlease write your token in \'BOT_TOKEN_ACCESS.json\' file.')
        process.exit(1);
        return false;
    }

    return token;
}

function getJSONFileFromFileSystem(aFileName)
{
    var dotSlashName = './' + aFileName
    return JSON.parse(FileSystem.readFileSync(dotSlashName, 'utf-8'));
}

function getCountOfMessageWithDigest()
{
    return 'Count of digest messages is ' + globalCountOfMessagesWithDigest;
}
<|endoftext|>