<commit_before>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var App = require('app');
var date = require('utils/date/date');

App.MainAdminStackUpgradeHistoryView = App.TableView.extend(App.TableServerViewMixin, {

  controllerBinding: 'App.router.mainAdminStackUpgradeHistoryController',

  templateName: require('templates/main/admin/stack_upgrade/upgrade_history'),

  summary: [],

  isReady: false,

  categories: [
    Em.Object.create({
      labelKey: 'admin.stackVersions.upgradeHistory.filter.all',
      value: 'ALL',
      isSelected: true
    }),
    Em.Object.create({
      labelKey: 'admin.stackVersions.upgradeHistory.filter.upgrade',
      value: 'UPGRADE',
      isSelected: false
    }),
    Em.Object.create({
      labelKey: 'admin.stackVersions.upgradeHistory.filter.downgrade',
      value: 'DOWNGRADE',
      isSelected: false
    }),
    Em.Object.create({
      labelKey: 'admin.stackVersions.upgradeHistory.filter.successful.upgrade',
      value: 'UPGRADE_COMPLETED',
      isSelected: false
    }),
    Em.Object.create({
      labelKey: 'admin.stackVersions.upgradeHistory.filter.aborted.upgrade',
      value: 'UPGRADE_ABORTED',
      isSelected: false
    }),
    Em.Object.create({
      labelKey: 'admin.stackVersions.upgradeHistory.filter.failed.upgrade',
      value: 'UPGRADE_FAILED',
      isSelected: false
    }),
    Em.Object.create({
      labelKey: 'admin.stackVersions.upgradeHistory.filter.successful.downgrade',
      value: 'DOWNGRADE_COMPLETED',
      isSelected: false
    }),
    Em.Object.create({
      labelKey: 'admin.stackVersions.upgradeHistory.filter.aborted.downgrade',
      value: 'DOWNGRADE_ABORTED',
      isSelected: false
    }),
    Em.Object.create({
      labelKey: 'admin.stackVersions.upgradeHistory.filter.failed.downgrade',
      value: 'DOWNGRADE_FAILED',
      isSelected: false
    })
  ],
  upgradeMethods: [
    Em.Object.create({
      displayName: Em.I18n.t('common.rolling'),
      type: 'ROLLING'
    }),
    Em.Object.create({
      displayName: Em.I18n.t('common.express'),
      type: 'NON_ROLLING'
    }),
    Em.Object.create({
      displayName: Em.I18n.t('common.hostOrdered'),
      type: 'HOST_ORDERED'
    })
  ],

  /**
   * @type {object}
   */
  selectedCategory: Em.computed.findBy('categories', 'isSelected', true),

  filteredCount: function () {
    var filteredContent = this.get('filteredContent').toArray();
    return filteredContent.length;
  }.property('filteredContent'),

  /**
   * displaying content filtered by upgrade type and upgrade status.
   */
  filteredContent: function () {
    var filterValue = 'ALL';
    var category = this.get('selectedCategory');
    if (category) {
      filterValue = category.get('value');
    }
    return this.filterBy(filterValue).reverse();
  }.property('selectedCategory'),

  /**
   * sort and slice recieved content by pagination parameters
   */
  pageContent: function () {
    var content = this.get('filteredContent').toArray();
    content = this.processForDisplay(content);
    content = content.slice(this.get('startIndex') - 1, this.get('endIndex'));
    return content;
  }.property('filteredContent', 'startIndex', 'endIndex'),

  processForDisplay: function (content) {
    var processedContent = [];

    content.forEach(function (item) {
      var direction = item.get('direction') === 'UPGRADE' ? Em.I18n.t('common.upgrade') : Em.I18n.t('common.downgrade');
      var method = this.get('upgradeMethods').findProperty('type', item.get('upgradeType'));
      item.setProperties({
        directionLabel: direction,
        upgradeTypeLabel: method ? method.get('displayName') : method,
        startTimeLabel: date.startTime(item.get('startTime')),
        endTimeLabel: date.startTime(item.get('endTime')),
        duration: date.durationSummary(item.get('startTime'), item.get('endTime'))
      });
      processedContent.push(item);
    }, this);
    return processedContent;
  },

  paginationLeftClass: function () {
    if (this.get("startIndex") > 1) {
      return "paginate_previous";
    }
    return "paginate_disabled_previous";
  }.property("startIndex", 'filteredCount'),

  /**
   * Determines how display "next"-link - as link or text
   * @type {string}
   */
  paginationRightClass: function () {
    if (this.get("endIndex") < this.get("filteredCount")) {
      return "paginate_next";
    }
    return "paginate_disabled_next";
  }.property("endIndex", 'filteredCount'),

  /**
   * Show previous-page if user not in the first page
   * @method previousPage
   */
  previousPage: function () {
    if (this.get('paginationLeftClass') === 'paginate_previous') {
      this._super();
    }
  },

  /**
   * Show next-page if user not in the last page
   * @method nextPage
   */
  nextPage: function () {
    if (this.get('paginationRightClass') === 'paginate_next') {
      this._super();
    }
  },

  willInsertElement: function () {
    var self = this;
    this.get('controller').loadStackUpgradeHistoryToModel().done(function () {
      self.populateUpgradeHistorySummary();
    });
  },

  didInsertElement: function () {
    this.observesCategories();
  },

  observesCategories: function () {
    this.get('categories').forEach(function (category) {
      var label = Em.I18n.t(category.labelKey).format(this.filterBy(category.value).length);
      category.set('label', label)
    }, this);
  }.observes('isReady'),

  filterBy: function (filterValue) {
    if ('ALL' == filterValue) {
      var all_records = App.StackUpgradeHistory.find();
      return all_records.toArray();
    } else {
      var tokens = filterValue.split('_');
      var direction_token = null;
      var status_token = null;

      if (tokens.length == 1) {
        direction_token = tokens[0]
      } else if (tokens.length > 1) {
        direction_token = tokens[0];
        status_token = tokens[1];
      }

      var result = [];
      App.StackUpgradeHistory.find().forEach(function (item) {
        var direction = item.get('direction');
        if (direction == direction_token) {
          if (status_token != null) {
            //only for the given status
            var status = item.get('requestStatus');
            if (status == status_token) {
              result.push(item)
            }
          } else {
            //regardless status
            result.push(item)
          }
        }
      }, this);
      return result
    }
  },

  selectCategory: function (event) {
    this.get('categories').filterProperty('isSelected').setEach('isSelected', false);
    event.context.set('isSelected', true);
  },

  populateUpgradeHistorySummary: function () {
    this.set('isReady', false);
    var result = [
      Em.Object.create({
        direction: 'UPGRADE',
        label: Em.I18n.t('common.upgrade'),
        hasSuccess: false,
        success: 0,
        hasAbort: false,
        abort: 0
      }),
      Em.Object.create({
        direction: 'DOWNGRADE',
        label: Em.I18n.t('common.downgrade'),
        hasSuccess: false,
        success: 0,
        hasAbort: false,
        abort: 0
      })
    ];

    App.StackUpgradeHistory.find().forEach(function (item) {
      var direction = item.get('direction');
      var status = item.get('requestStatus');
      if ('UPGRADE' == direction) {
        if ('COMPLETED' == status) {
          result[0].set('success', result[0].get('success') + 1);
        } else if ('ABORTED' == status) {
          result[0].set('abort', result[0].get('abort') + 1);
        }
      } else if ('DOWNGRADE' == direction) {
        if ('COMPLETED' == status) {
          result[1].set('success', result[1].get('success') + 1);
        } else if ('ABORTED' == status) {
          result[1].set('abort', result[1].get('abort') + 1);
        }
      }
    }, this);

    result[0].set('hasSuccess', result[0].get('success') > 0);
    result[1].set('hasSuccess', result[1].get('success') > 0);
    result[0].set('hasAbort', result[0].get('abort') > 0);
    result[1].set('hasAbort', result[1].get('abort') > 0);

    this.set('summary', result);
    this.set('isReady', true);
  },

  showUpgradeHistoryRecord: function (event) {
    var record = event.context;
    var direction = App.format.normalizeName(record.get('direction'));
    var type = this.get('upgradeMethods').findProperty('type', record.get('upgradeType'));
    var displayName = type ? type.get('displayName') : record.get('upgradeType');

    this.get('controller').set('currentUpgradeRecord', record);

    App.ModalPopup.show({
      classNames: ['wizard-modal-wrapper'],
      modalDialogClasses: ['modal-xlg'],
      header: Em.I18n.t('admin.stackVersions.upgradeHistory.record.title').format(displayName, direction, record.get('fromVersion')),
      bodyClass: App.MainAdminStackUpgradeHistoryDetailsView,
      primary: Em.I18n.t('common.dismiss'),
      secondary: null,
      didInsertElement: function () {
        this._super();
        this.fitHeight();
        this.fitInnerHeight();
      },
      fitInnerHeight: function () {
        var block = this.$().find('#modal > .modal-body');
        var scrollable = this.$().find('#modal .scrollable-block');
        scrollable.css('max-height', Number(block.css('max-height').slice(0, -2)) - block.height());
        block.css('max-height', 'none');
      },
    });
  },
});
<commit_msg>AMBARI-19348 - Version number is incorrect when upgrade wizard is opened from Upgrade History (rzang)<commit_after>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var App = require('app');
var date = require('utils/date/date');

App.MainAdminStackUpgradeHistoryView = App.TableView.extend(App.TableServerViewMixin, {

  controllerBinding: 'App.router.mainAdminStackUpgradeHistoryController',

  templateName: require('templates/main/admin/stack_upgrade/upgrade_history'),

  summary: [],

  isReady: false,

  categories: [
    Em.Object.create({
      labelKey: 'admin.stackVersions.upgradeHistory.filter.all',
      value: 'ALL',
      isSelected: true
    }),
    Em.Object.create({
      labelKey: 'admin.stackVersions.upgradeHistory.filter.upgrade',
      value: 'UPGRADE',
      isSelected: false
    }),
    Em.Object.create({
      labelKey: 'admin.stackVersions.upgradeHistory.filter.downgrade',
      value: 'DOWNGRADE',
      isSelected: false
    }),
    Em.Object.create({
      labelKey: 'admin.stackVersions.upgradeHistory.filter.successful.upgrade',
      value: 'UPGRADE_COMPLETED',
      isSelected: false
    }),
    Em.Object.create({
      labelKey: 'admin.stackVersions.upgradeHistory.filter.aborted.upgrade',
      value: 'UPGRADE_ABORTED',
      isSelected: false
    }),
    Em.Object.create({
      labelKey: 'admin.stackVersions.upgradeHistory.filter.failed.upgrade',
      value: 'UPGRADE_FAILED',
      isSelected: false
    }),
    Em.Object.create({
      labelKey: 'admin.stackVersions.upgradeHistory.filter.successful.downgrade',
      value: 'DOWNGRADE_COMPLETED',
      isSelected: false
    }),
    Em.Object.create({
      labelKey: 'admin.stackVersions.upgradeHistory.filter.aborted.downgrade',
      value: 'DOWNGRADE_ABORTED',
      isSelected: false
    }),
    Em.Object.create({
      labelKey: 'admin.stackVersions.upgradeHistory.filter.failed.downgrade',
      value: 'DOWNGRADE_FAILED',
      isSelected: false
    })
  ],
  upgradeMethods: [
    Em.Object.create({
      displayName: Em.I18n.t('common.rolling'),
      type: 'ROLLING'
    }),
    Em.Object.create({
      displayName: Em.I18n.t('common.express'),
      type: 'NON_ROLLING'
    }),
    Em.Object.create({
      displayName: Em.I18n.t('common.hostOrdered'),
      type: 'HOST_ORDERED'
    })
  ],

  /**
   * @type {object}
   */
  selectedCategory: Em.computed.findBy('categories', 'isSelected', true),

  filteredCount: function () {
    var filteredContent = this.get('filteredContent').toArray();
    return filteredContent.length;
  }.property('filteredContent'),

  /**
   * displaying content filtered by upgrade type and upgrade status.
   */
  filteredContent: function () {
    var filterValue = 'ALL';
    var category = this.get('selectedCategory');
    if (category) {
      filterValue = category.get('value');
    }
    return this.filterBy(filterValue).reverse();
  }.property('selectedCategory'),

  /**
   * sort and slice recieved content by pagination parameters
   */
  pageContent: function () {
    var content = this.get('filteredContent').toArray();
    content = this.processForDisplay(content);
    content = content.slice(this.get('startIndex') - 1, this.get('endIndex'));
    return content;
  }.property('filteredContent', 'startIndex', 'endIndex'),

  processForDisplay: function (content) {
    var processedContent = [];

    content.forEach(function (item) {
      var direction = item.get('direction') === 'UPGRADE' ? Em.I18n.t('common.upgrade') : Em.I18n.t('common.downgrade');
      var method = this.get('upgradeMethods').findProperty('type', item.get('upgradeType'));
      item.setProperties({
        directionLabel: direction,
        upgradeTypeLabel: method ? method.get('displayName') : method,
        startTimeLabel: date.startTime(item.get('startTime')),
        endTimeLabel: date.startTime(item.get('endTime')),
        duration: date.durationSummary(item.get('startTime'), item.get('endTime'))
      });
      processedContent.push(item);
    }, this);
    return processedContent;
  },

  paginationLeftClass: function () {
    if (this.get("startIndex") > 1) {
      return "paginate_previous";
    }
    return "paginate_disabled_previous";
  }.property("startIndex", 'filteredCount'),

  /**
   * Determines how display "next"-link - as link or text
   * @type {string}
   */
  paginationRightClass: function () {
    if (this.get("endIndex") < this.get("filteredCount")) {
      return "paginate_next";
    }
    return "paginate_disabled_next";
  }.property("endIndex", 'filteredCount'),

  /**
   * Show previous-page if user not in the first page
   * @method previousPage
   */
  previousPage: function () {
    if (this.get('paginationLeftClass') === 'paginate_previous') {
      this._super();
    }
  },

  /**
   * Show next-page if user not in the last page
   * @method nextPage
   */
  nextPage: function () {
    if (this.get('paginationRightClass') === 'paginate_next') {
      this._super();
    }
  },

  willInsertElement: function () {
    var self = this;
    this.get('controller').loadStackUpgradeHistoryToModel().done(function () {
      self.populateUpgradeHistorySummary();
    });
  },

  didInsertElement: function () {
    this.observesCategories();
  },

  observesCategories: function () {
    this.get('categories').forEach(function (category) {
      var label = Em.I18n.t(category.labelKey).format(this.filterBy(category.value).length);
      category.set('label', label)
    }, this);
  }.observes('isReady'),

  filterBy: function (filterValue) {
    if ('ALL' == filterValue) {
      var all_records = App.StackUpgradeHistory.find();
      return all_records.toArray();
    } else {
      var tokens = filterValue.split('_');
      var direction_token = null;
      var status_token = null;

      if (tokens.length == 1) {
        direction_token = tokens[0]
      } else if (tokens.length > 1) {
        direction_token = tokens[0];
        status_token = tokens[1];
      }

      var result = [];
      App.StackUpgradeHistory.find().forEach(function (item) {
        var direction = item.get('direction');
        if (direction == direction_token) {
          if (status_token != null) {
            //only for the given status
            var status = item.get('requestStatus');
            if (status == status_token) {
              result.push(item)
            }
          } else {
            //regardless status
            result.push(item)
          }
        }
      }, this);
      return result
    }
  },

  selectCategory: function (event) {
    this.get('categories').filterProperty('isSelected').setEach('isSelected', false);
    event.context.set('isSelected', true);
  },

  populateUpgradeHistorySummary: function () {
    this.set('isReady', false);
    var result = [
      Em.Object.create({
        direction: 'UPGRADE',
        label: Em.I18n.t('common.upgrade'),
        hasSuccess: false,
        success: 0,
        hasAbort: false,
        abort: 0
      }),
      Em.Object.create({
        direction: 'DOWNGRADE',
        label: Em.I18n.t('common.downgrade'),
        hasSuccess: false,
        success: 0,
        hasAbort: false,
        abort: 0
      })
    ];

    App.StackUpgradeHistory.find().forEach(function (item) {
      var direction = item.get('direction');
      var status = item.get('requestStatus');
      if ('UPGRADE' == direction) {
        if ('COMPLETED' == status) {
          result[0].set('success', result[0].get('success') + 1);
        } else if ('ABORTED' == status) {
          result[0].set('abort', result[0].get('abort') + 1);
        }
      } else if ('DOWNGRADE' == direction) {
        if ('COMPLETED' == status) {
          result[1].set('success', result[1].get('success') + 1);
        } else if ('ABORTED' == status) {
          result[1].set('abort', result[1].get('abort') + 1);
        }
      }
    }, this);

    result[0].set('hasSuccess', result[0].get('success') > 0);
    result[1].set('hasSuccess', result[1].get('success') > 0);
    result[0].set('hasAbort', result[0].get('abort') > 0);
    result[1].set('hasAbort', result[1].get('abort') > 0);

    this.set('summary', result);
    this.set('isReady', true);
  },

  showUpgradeHistoryRecord: function (event) {
    var record = event.context;
    var direction = App.format.normalizeName(record.get('direction'));
    var toVersion = record.get('toVersion');
    var type = this.get('upgradeMethods').findProperty('type', record.get('upgradeType'));
    var displayName = type ? type.get('displayName') : record.get('upgradeType');

    this.get('controller').set('currentUpgradeRecord', record);

    App.ModalPopup.show({
      classNames: ['wizard-modal-wrapper'],
      modalDialogClasses: ['modal-xlg'],
      header: Em.I18n.t('admin.stackVersions.upgradeHistory.record.title').format(displayName, direction, toVersion),
      bodyClass: App.MainAdminStackUpgradeHistoryDetailsView,
      primary: Em.I18n.t('common.dismiss'),
      secondary: null,
      didInsertElement: function () {
        this._super();
        this.fitHeight();
        this.fitInnerHeight();
      },
      fitInnerHeight: function () {
        var block = this.$().find('#modal > .modal-body');
        var scrollable = this.$().find('#modal .scrollable-block');
        scrollable.css('max-height', Number(block.css('max-height').slice(0, -2)) - block.height());
        block.css('max-height', 'none');
      },
    });
  },
});
<|endoftext|>


<commit_before>import React from 'react'
import { Navbar, Nav, NavItem } from 'react-bootstrap'
import { LinkContainer, IndexLinkContainer } from 'react-router-bootstrap'
import classes from './Header.scss'

export const Header = () => (

Karaoke Forever

    <Navbar>

        <IndexLinkContainer to='/' activeClassName={classes.activeRoute}>
          <NavItem>Home</NavItem>
        </IndexLinkContainer>
        <LinkContainer to='/library' activeClassName={classes.activeRoute}>
          <NavItem>Library</NavItem>
        </LinkContainer>
        <LinkContainer to='/counter' activeClassName={classes.activeRoute}>
          <NavItem>Counter</NavItem>
        </LinkContainer>
        <LinkContainer to='/player' activeClassName={classes.activeRoute}>
          <NavItem>Player</NavItem>
        </LinkContainer>
        <LinkContainer to='/account' activeClassName={classes.activeRoute}>
          <NavItem>Account</NavItem>
        </LinkContainer>

    </Navbar>

)

export default Header
<commit_msg>IndexLinkContainer won't set dynamic className on NavItems so rip this out for now<commit_after>import React from 'react'
import { Navbar, Nav, NavItem } from 'react-bootstrap'
import { LinkContainer, IndexLinkContainer } from 'react-router-bootstrap'
// import classes from './Header.scss'
import classes from './Header.css'

export const Header = () => (
  <Navbar staticTop={true}>

      <IndexLinkContainer to='/'>
        <NavItem className={classes.noCollapse}>Home</NavItem>
      </IndexLinkContainer>
      <LinkContainer to='/library'>
        <NavItem className={classes.noCollapse}>Library</NavItem>
      </LinkContainer>
      <LinkContainer to='/counter'>
        <NavItem className={classes.noCollapse}>Counter</NavItem>
      </LinkContainer>
      <LinkContainer to='/player'>
        <NavItem className={classes.noCollapse}>Player</NavItem>
      </LinkContainer>
      <LinkContainer to='/account'>
        <NavItem className={classes.noCollapse}>Account</NavItem>
      </LinkContainer>

  </Navbar>
)

export default Header
<|endoftext|>


<commit_before>import moment from 'moment';
import {config} from './';

export class ReviewsStats {
  constructor(reviews, period) {
    this.startDate = period[0].format('YYYY-MM-DD');
    if (moment(config.startDate).isAfter(this.startDate)) {
      this.startDate = config.startDate;
    }
    this.endDate = period[1].format('YYYY-MM-DD');
    this.totalEarned = 0;
    this.totalAssigned = 0;
    // Create stats for each project type reviewed
    this.projects = {};
    reviews.forEach((review) => {
      this.countReview(review);
    });
    Object.keys(this.projects).forEach((id) => {
      const project = this.projects[id];
      // Set the average turnaround time for each project
      project.avgTurnaroundTime = project.totalTurnaroundTime / project.totalAssigned;
    });

    // Find the average daily earnings

    // Checks if the endTime is today or in the future. If yes it calculates
    // the number of days considering the endDate as the current time. If not,
    // it uses the endTime provided by the user.
    const endIsToday = moment.utc().diff(this.endDate, 'days', true) < 1;
    if (endIsToday) {
      this.numberOfDays = moment.utc().diff(moment.utc(this.startDate), 'days', true);
    } else {
      // Increase 1 to account the last day, since it considers that `endDate` starts at 00:00
      this.numberOfDays = moment(this.endDate).diff(this.startDate, 'days') + 1;
    }
    this.dailyAverage = this.numberOfDays ? this.totalEarned / this.numberOfDays : this.totalEarned;
  }

  countReview(review) {
    const id = review.project_id;
    const price = parseInt(review.price, 10);
    const assignedAt = moment(review.assigned_at);
    const completedAt = moment(review.completed_at);
    const turnaroundTime = completedAt.diff(assignedAt);

    // If the report does not yet contain an entry for the project type, create
    // the entry and try counting the review again.
    if (!Object.prototype.hasOwnProperty.call(this.projects, id)) {
      this.projects[id] = {
        id,
        name: review.project.name,
        passed: 0,
        failed: 0,
        ungradeable: 0,
        earned: 0,
        totalTurnaroundTime: 0,
        totalAssigned: 0,
      };
      this.countReview(review);
    } else {
      this.projects[id][review.result] += 1;
      this.projects[id].earned += price;
      this.projects[id].totalTurnaroundTime += turnaroundTime;
      this.projects[id].totalAssigned += 1;
      this.totalEarned += price;
      this.totalAssigned += 1;
    }
  }
}
<commit_msg>Us Moment's isSame to check if endDaate is Today<commit_after>import moment from 'moment';
import {config} from './';

export class ReviewsStats {
  constructor(reviews, period) {
    this.startDate = period[0].format('YYYY-MM-DD');
    if (moment(config.startDate).isAfter(this.startDate)) {
      this.startDate = config.startDate;
    }
    this.endDate = period[1].format('YYYY-MM-DD');
    this.totalEarned = 0;
    this.totalAssigned = 0;
    // Create stats for each project type reviewed
    this.projects = {};
    reviews.forEach((review) => {
      this.countReview(review);
    });
    Object.keys(this.projects).forEach((id) => {
      const project = this.projects[id];
      // Set the average turnaround time for each project
      project.avgTurnaroundTime = project.totalTurnaroundTime / project.totalAssigned;
    });

    // Find the average daily earnings

    // Checks if the endTime is today. If yes, it calculate the number of days
    // from startDate up to now.
    const endIsToday = moment.utc().isSame(this.endDate, 'day');
    if (endIsToday) {
      this.numberOfDays = moment.utc().diff(moment.utc(this.startDate), 'days', true);
    } else {
      // Increase 1 to account the last day, since it considers that `endDate` starts at 00:00
      this.numberOfDays = moment(this.endDate).diff(this.startDate, 'days') + 1;
    }
    this.dailyAverage = this.numberOfDays ? this.totalEarned / this.numberOfDays : this.totalEarned;
  }

  countReview(review) {
    const id = review.project_id;
    const price = parseInt(review.price, 10);
    const assignedAt = moment(review.assigned_at);
    const completedAt = moment(review.completed_at);
    const turnaroundTime = completedAt.diff(assignedAt);

    // If the report does not yet contain an entry for the project type, create
    // the entry and try counting the review again.
    if (!Object.prototype.hasOwnProperty.call(this.projects, id)) {
      this.projects[id] = {
        id,
        name: review.project.name,
        passed: 0,
        failed: 0,
        ungradeable: 0,
        earned: 0,
        totalTurnaroundTime: 0,
        totalAssigned: 0,
      };
      this.countReview(review);
    } else {
      this.projects[id][review.result] += 1;
      this.projects[id].earned += price;
      this.projects[id].totalTurnaroundTime += turnaroundTime;
      this.projects[id].totalAssigned += 1;
      this.totalEarned += price;
      this.totalAssigned += 1;
    }
  }
}
<|endoftext|>


<commit_before>const { isFunction, validateSiblings, validateChild, getLatestFromNames, loadCurrentValue, saveCurrentValue } = require("../../util/ruleUtil");
const { CONTENT, CLEAN, TRANSFORM, FUNCTION, DEFAULT, TYPE, STRING, PROPERTIES, OPTIONAL, CAST_TO, MATCH, VALIDATE, MIN, MAX, NUMBER, ARRAY, OBJECT, BOOLEAN } = require("../../constant");

const depth = 1;
const config = {
	body: {
		siblings: [
			{ name: PROPERTIES },
			{ name: TRANSFORM },
			{ name: OPTIONAL },
			{ name: VALIDATE },
			{ name: CONTENT },
			{ name: CLEAN },
			{ name: TYPE },
		],
		children: { types: [BOOLEAN, STRING, NUMBER, FUNCTION, ARRAY, OBJECT] },
	},
	userInput: {
		siblings: [
			{ name: OPTIONAL },
			{ name: TYPE },
			{ name: CAST_TO },
			{ name: MATCH },
			{ name: VALIDATE },
			{ name: TRANSFORM },
			{ name: MIN },
			{ name: MAX },
			{ name: PROPERTIES },
		],
		children: { types: [BOOLEAN, STRING, NUMBER, FUNCTION, ARRAY, OBJECT] },
	},
};

module.exports = {
	name: DEFAULT,
	priority: 10,
	validate,
	execute,
	config,
};

function execute({ rule, data }) {
	return new Promise(async (resolve, reject) => {
		loadCurrentValue(data);
		if (data.current.value === undefined) {
			if (isFunction(rule.current)) {
				try {
					data.current.value = await rule.current.value(rule.current.value);
				} catch (error) {
					return reject(error);
				}
			} else {
				data.current.value = rule.current.value;
			}
		}
		saveCurrentValue(data);
		resolve(true);
	});
}

function validate({ current, parents, ruleConfig }) {
	const { siblings, children } = getLatestFromNames(config, parents, depth, DEFAULT);
	validateSiblings({ siblings, current, parents, ruleConfig });
	const child = current;
	validateChild({ child, children, parents, current, ruleConfig });
	return true;
}
<commit_msg>Add support for default at same level of content<commit_after>const { isFunction, validateSiblings, validateChild, getLatestFromNames, loadCurrentValue, saveCurrentValue } = require("../../util/ruleUtil");
const { CONTENT, CLEAN, TRANSFORM, FUNCTION, DEFAULT, TYPE, STRING, PROPERTIES, OPTIONAL, CAST_TO, MATCH, VALIDATE, MIN, MAX, NUMBER, ARRAY, OBJECT, BOOLEAN } = require("../../constant");

const depth = 1;
const config = {
	body: {
		siblings: [
			{ name: PROPERTIES },
			{ name: TRANSFORM },
			{ name: OPTIONAL },
			{ name: VALIDATE },
			{ name: CONTENT },
			{ name: CLEAN },
			{ name: TYPE },
		],
		children: { types: [BOOLEAN, STRING, NUMBER, FUNCTION, ARRAY, OBJECT] },
	},
	userInput: {
		siblings: [
			{ name: OPTIONAL },
			{ name: TYPE },
			{ name: CAST_TO },
			{ name: MATCH },
			{ name: VALIDATE },
			{ name: TRANSFORM },
			{ name: MIN },
			{ name: MAX },
			{ name: PROPERTIES },
			{ name: CONTENT },
		],
		children: { types: [BOOLEAN, STRING, NUMBER, FUNCTION, ARRAY, OBJECT] },
	},
};

module.exports = {
	name: DEFAULT,
	priority: 10,
	validate,
	execute,
	config,
};

function execute({ rule, data }) {
	return new Promise(async (resolve, reject) => {
		loadCurrentValue(data);
		if (data.current.value === undefined) {
			if (isFunction(rule.current)) {
				try {
					data.current.value = await rule.current.value(rule.current.value);
				} catch (error) {
					return reject(error);
				}
			} else {
				data.current.value = rule.current.value;
			}
		}
		saveCurrentValue(data);
		resolve(true);
	});
}

function validate({ current, parents, ruleConfig }) {
	const { siblings, children } = getLatestFromNames(config, parents, depth, DEFAULT);
	validateSiblings({ siblings, current, parents, ruleConfig });
	const child = current;
	validateChild({ child, children, parents, current, ruleConfig });
	return true;
}
<|endoftext|>


<commit_before>$(document).ready(function () {
    var agreements = $('

');
    var cookiesLink = 'Cookies';
    var FAQLink = 'FAQ';
    var acceptBtn = 'I agree';
    var paragraph = 'This site use &nbsp' + cookiesLink + '&nbsp ' +
        'to store information on your computer.' +
        'Please read our &nbsp' + FAQLink + '&nbsp&nbsp' + ' section.' + acceptBtn;
    agreements.append(paragraph);
    $('#fake-header').append(agreements);

    //CLICK LISTENER AGREEMENTS
    $('#accept-agreements').click(function () {
        $('#agreements').remove();
    });

    //CLICK LISTENER LOGIN
    $('#login-btn').click(function () {
        var formStatus = '<input id="form-status" type="hidden" name="status" value="submitted"/>';
        var loginForm = $('#login-form');
        loginForm.append(formStatus);

        if ($('#form-status').val() === 'submitted') {
            loginForm.submit();
        }
    });

    //MODAL LISTENER
    $("#modal_trigger").leanModal({top : 120, overlay : 0.6, closeButton: ".modal_close" });
});<commit_msg>Change theme added<commit_after>$(document).ready(function () {
    var agreements = $('

');
    var cookiesLink = 'Cookies';
    var FAQLink = 'FAQ';
    var acceptBtn = 'I agree';
    var paragraph = 'This site use &nbsp' + cookiesLink + '&nbsp ' +
        'to store information on your computer.' +
        'Please read our &nbsp' + FAQLink + '&nbsp&nbsp' + ' section.' + acceptBtn;
    agreements.append(paragraph);
    $('#fake-header').append(agreements);

    //CLICK LISTENER AGREEMENTS
    $('#accept-agreements').click(function () {
        $('#agreements').remove();
    });

    //CLICK LISTENER LOGIN
    $('#login-btn').click(function () {
        var formStatus = '<input id="form-status" type="hidden" name="status" value="submitted"/>';
        var loginForm = $('#login-form');
        loginForm.append(formStatus);

        if ($('#form-status').val() === 'submitted') {
            loginForm.submit();
        }
    });

    //MODAL LISTENER
    $("#modal_trigger").leanModal({top : 120, overlay : 0.6, closeButton: ".modal_close" });

    //CHANGE CSS
    function changeCSS(cssFile, cssLinkIndex) {

        var oldlink = document.getElementsByTagName("link").item(cssLinkIndex);

        var newlink = document.createElement("link");
        newlink.setAttribute("rel", "stylesheet");
        newlink.setAttribute("type", "text/css");
        newlink.setAttribute("href", cssFile);

        document.getElementsByTagName("head").item(0).replaceChild(newlink, oldlink);
    }

    $('#theme-choose').change(function() {
        var element = $('#theme-choose');

        if (element.val() == 'dark') {
            changeCSS('assets/styles/dark.css', 0);
        } else if (element.val() == 'white') {
            changeCSS('assets/styles/white.css', 0);
        } else {
            changeCSS('assets/styles/main.css', 0);
        }
    })
});<|endoftext|>


<commit_before>'use strict';

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

const Exchange = require ('./base/Exchange');
const { ExchangeError, InsufficientFunds, InvalidOrder, AuthenticationError, PermissionDenied, InvalidNonce, OrderNotFound, DDoSProtection } = require ('./base/errors');

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

module.exports = class btcbox extends Exchange {
    describe () {
        return this.deepExtend (super.describe (), {
            'id': 'btcbox',
            'name': 'BtcBox',
            'countries': 'JP',
            'rateLimit': 1000,
            'version': 'v1',
            'has': {
                'CORS': false,
            },
            'urls': {
                'logo': 'https://user-images.githubusercontent.com/1294454/31275803-4df755a8-aaa1-11e7-9abb-11ec2fad9f2d.jpg',
                'api': 'https://www.btcbox.co.jp/api',
                'www': 'https://www.btcbox.co.jp/',
                'doc': 'https://www.btcbox.co.jp/help/asm',
            },
            'api': {
                'public': {
                    'get': [
                        'depth',
                        'orders',
                        'ticker',
                        'allticker',
                    ],
                },
                'private': {
                    'post': [
                        'balance',
                        'trade_add',
                        'trade_cancel',
                        'trade_list',
                        'trade_view',
                        'wallet',
                    ],
                },
            },
            'markets': {
                'BTC/JPY': { 'id': 'BTC/JPY', 'symbol': 'BTC/JPY', 'base': 'BTC', 'quote': 'JPY' },
            },
            'exceptions': {
                '104': AuthenticationError,
                '105': PermissionDenied,
                '106': InvalidNonce,
                '107': InvalidOrder,
                '200': InsufficientFunds,
                '201': InvalidOrder,
                '202': InvalidOrder,
                '203': OrderNotFound,
                '402': DDoSProtection,
            },
        });
    }

    async fetchBalance (params = {}) {
        await this.loadMarkets ();
        let balances = await this.privatePostBalance ();
        let result = { 'info': balances };
        let currencies = Object.keys (this.currencies);
        for (let i = 0; i < currencies.length; i++) {
            let currency = currencies[i];
            let lowercase = currency.toLowerCase ();
            if (lowercase === 'dash')
                lowercase = 'drk';
            let account = this.account ();
            let free = lowercase + '_balance';
            let used = lowercase + '_lock';
            if (free in balances)
                account['free'] = parseFloat (balances[free]);
            if (used in balances)
                account['used'] = parseFloat (balances[used]);
            account['total'] = this.sum (account['free'], account['used']);
            result[currency] = account;
        }
        return this.parseBalance (result);
    }

    async fetchOrderBook (symbol, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let request = {};
        let numSymbols = this.symbols.length;
        if (numSymbols > 1)
            request['coin'] = market['id'];
        let orderbook = await this.publicGetDepth (this.extend (request, params));
        let result = this.parseOrderBook (orderbook);
        result['asks'] = this.sortBy (result['asks'], 0);
        return result;
    }

    parseTicker (ticker, market = undefined) {
        let timestamp = this.milliseconds ();
        let symbol = undefined;
        if (market)
            symbol = market['symbol'];
        return {
            'symbol': symbol,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'high': this.safeFloat (ticker, 'high'),
            'low': this.safeFloat (ticker, 'low'),
            'bid': this.safeFloat (ticker, 'buy'),
            'ask': this.safeFloat (ticker, 'sell'),
            'vwap': undefined,
            'open': undefined,
            'close': undefined,
            'first': undefined,
            'last': this.safeFloat (ticker, 'last'),
            'change': undefined,
            'percentage': undefined,
            'average': undefined,
            'baseVolume': this.safeFloat (ticker, 'vol'),
            'quoteVolume': this.safeFloat (ticker, 'volume'),
            'info': ticker,
        };
    }

    async fetchTickers (symbols = undefined, params = {}) {
        await this.loadMarkets ();
        let tickers = await this.publicGetAllticker (params);
        let ids = Object.keys (tickers);
        let result = {};
        for (let i = 0; i < ids.length; i++) {
            let id = ids[i];
            let market = this.markets_by_id[id];
            let symbol = market['symbol'];
            let ticker = tickers[id];
            result[symbol] = this.parseTicker (ticker, market);
        }
        return result;
    }

    async fetchTicker (symbol, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let request = {};
        let numSymbols = this.symbols.length;
        if (numSymbols > 1)
            request['coin'] = market['id'];
        let ticker = await this.publicGetTicker (this.extend (request, params));
        return this.parseTicker (ticker, market);
    }

    parseTrade (trade, market) {
        let timestamp = parseInt (trade['date']) * 1000;
        return {
            'info': trade,
            'id': trade['tid'],
            'order': undefined,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'symbol': market['symbol'],
            'type': undefined,
            'side': trade['type'],
            'price': trade['price'],
            'amount': trade['amount'],
        };
    }

    async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let request = {};
        let numSymbols = this.symbols.length;
        if (numSymbols > 1)
            request['coin'] = market['id'];
        let response = await this.publicGetOrders (this.extend (request, params));
        return this.parseTrades (response, market, since, limit);
    }

    async createOrder (symbol, type, side, amount, price = undefined, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let request = {
            'amount': amount,
            'price': price,
            'type': side,
        };
        let numSymbols = this.symbols.length;
        if (numSymbols > 1)
            request['coin'] = market['id'];
        let response = await this.privatePostTradeAdd (this.extend (request, params));
        return {
            'info': response,
            'id': response['id'],
        };
    }

    async cancelOrder (id, symbol = undefined, params = {}) {
        await this.loadMarkets ();
        return await this.privatePostTradeCancel (this.extend ({
            'id': id,
        }, params));
    }

    parseOrder (order) {
        // {"id":11,"datetime":"2014-10-21 10:47:20","type":"sell","price":42000,"amount_original":1.2,"amount_outstanding":1.2,"status":"closed","trades":[]}
        const id = this.safeString (order, 'id');
        const timestamp = this.parse8601 (order['datetime']);
        const amount = this.safeFloat (order, 'amount_original');
        const remaining = this.safeFloat (order, 'amount_outstanding');
        let filled = undefined;
        if (typeof amount !== 'undefined')
            if (typeof remaining !== 'undefined')
                filled = amount - remaining;
        const price = this.safeFloat (order, 'price');
        let cost = undefined;
        if (typeof price !== 'undefined')
            if (typeof filled !== 'undefined')
                cost = filled * price;
        const statuses = {
            // TODO: complete list
            'closed': 'closed',
            'cancelled': 'canceled',
        };
        let status = undefined;
        if (order['status'] in statuses)
            status = statuses[order['status']];
        let trades = undefined; // todo: this.parseTrades (order['trades']);
        return {
            'id': id,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'amount': amount,
            'remaining': remaining,
            'filled': filled,
            'side': order['type'],
            'type': undefined,
            'status': status,
            'symbol': undefined,
            'price': price,
            'cost': cost,
            'trades': trades,
            'fee': undefined,
            'info': order,
        };
    }

    async fetchOrder (id, symbol = undefined, params = {}) {
        await this.loadMarkets ();
        let response = await this.privatePostTradeView (this.extend ({
            'id': id,
        }, params));
        return this.parseOrder (response);
    }

    async fetchOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let response = await this.privatePostTradeList (this.extend ({
            'type': 'all', // 'open' or 'all'
        }, params));
        return this.parseOrders (response);
    }

    async fetchOpenOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let response = await this.privatePostTradeList (this.extend ({
            'type': 'open', // 'open' or 'all'
        }, params));
        return this.parseOrders (response);
    }

    sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        let url = this.urls['api'] + '/' + this.version + '/' + path;
        if (api === 'public') {
            if (Object.keys (params).length)
                url += '?' + this.urlencode (params);
        } else {
            this.checkRequiredCredentials ();
            let nonce = this.nonce ().toString ();
            let query = this.extend ({
                'key': this.apiKey,
                'nonce': nonce,
            }, params);
            let request = this.urlencode (query);
            let secret = this.hash (this.encode (this.secret));
            query['signature'] = this.hmac (this.encode (request), this.encode (secret));
            body = this.urlencode (query);
            headers = {
                'Content-Type': 'application/x-www-form-urlencoded',
            };
        }
        return { 'url': url, 'method': method, 'body': body, 'headers': headers };
    }

    handleErrors (httpCode, reason, url, method, headers, body) {
        // typical error response: {"result":false,"code":"401"}
        if (httpCode >= 400)
            return; // resort to defaultErrorHandler
        if (body[0] !== '{')
            return; // not json, resort to defaultErrorHandler
        const response = JSON.parse (body);
        const result = this.safeValue (response, 'result');
        if (typeof result === 'undefined' || result === true)
            return; // either public API (no error codes expected) or success
        const errorCode = this.safeValue (response, 'code');
        const feedback = this.id + ' ' + this.json (response);
        const exceptions = this.exceptions;
        if (errorCode in exceptions)
            throw new exceptions[errorCode] (feedback);
        throw new ExchangeError (feedback); // unknown message
    }
};
<commit_msg>btcbox fetchTicker consistency<commit_after>'use strict';

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

const Exchange = require ('./base/Exchange');
const { ExchangeError, InsufficientFunds, InvalidOrder, AuthenticationError, PermissionDenied, InvalidNonce, OrderNotFound, DDoSProtection } = require ('./base/errors');

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

module.exports = class btcbox extends Exchange {
    describe () {
        return this.deepExtend (super.describe (), {
            'id': 'btcbox',
            'name': 'BtcBox',
            'countries': 'JP',
            'rateLimit': 1000,
            'version': 'v1',
            'has': {
                'CORS': false,
            },
            'urls': {
                'logo': 'https://user-images.githubusercontent.com/1294454/31275803-4df755a8-aaa1-11e7-9abb-11ec2fad9f2d.jpg',
                'api': 'https://www.btcbox.co.jp/api',
                'www': 'https://www.btcbox.co.jp/',
                'doc': 'https://www.btcbox.co.jp/help/asm',
            },
            'api': {
                'public': {
                    'get': [
                        'depth',
                        'orders',
                        'ticker',
                        'allticker',
                    ],
                },
                'private': {
                    'post': [
                        'balance',
                        'trade_add',
                        'trade_cancel',
                        'trade_list',
                        'trade_view',
                        'wallet',
                    ],
                },
            },
            'markets': {
                'BTC/JPY': { 'id': 'BTC/JPY', 'symbol': 'BTC/JPY', 'base': 'BTC', 'quote': 'JPY' },
            },
            'exceptions': {
                '104': AuthenticationError,
                '105': PermissionDenied,
                '106': InvalidNonce,
                '107': InvalidOrder,
                '200': InsufficientFunds,
                '201': InvalidOrder,
                '202': InvalidOrder,
                '203': OrderNotFound,
                '402': DDoSProtection,
            },
        });
    }

    async fetchBalance (params = {}) {
        await this.loadMarkets ();
        let balances = await this.privatePostBalance ();
        let result = { 'info': balances };
        let currencies = Object.keys (this.currencies);
        for (let i = 0; i < currencies.length; i++) {
            let currency = currencies[i];
            let lowercase = currency.toLowerCase ();
            if (lowercase === 'dash')
                lowercase = 'drk';
            let account = this.account ();
            let free = lowercase + '_balance';
            let used = lowercase + '_lock';
            if (free in balances)
                account['free'] = parseFloat (balances[free]);
            if (used in balances)
                account['used'] = parseFloat (balances[used]);
            account['total'] = this.sum (account['free'], account['used']);
            result[currency] = account;
        }
        return this.parseBalance (result);
    }

    async fetchOrderBook (symbol, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let request = {};
        let numSymbols = this.symbols.length;
        if (numSymbols > 1)
            request['coin'] = market['id'];
        let orderbook = await this.publicGetDepth (this.extend (request, params));
        let result = this.parseOrderBook (orderbook);
        result['asks'] = this.sortBy (result['asks'], 0);
        return result;
    }

    parseTicker (ticker, market = undefined) {
        let timestamp = this.milliseconds ();
        let symbol = undefined;
        if (market)
            symbol = market['symbol'];
        let last = this.safeFloat (ticker, 'last');
        return {
            'symbol': symbol,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'high': this.safeFloat (ticker, 'high'),
            'low': this.safeFloat (ticker, 'low'),
            'bid': this.safeFloat (ticker, 'buy'),
            'bidVolume': undefined,
            'ask': this.safeFloat (ticker, 'sell'),
            'askVolume': undefined,
            'vwap': undefined,
            'open': undefined,
            'close': last,
            'last': last,
            'previousClose': undefined,
            'change': undefined,
            'percentage': undefined,
            'average': undefined,
            'baseVolume': this.safeFloat (ticker, 'vol'),
            'quoteVolume': this.safeFloat (ticker, 'volume'),
            'info': ticker,
        };
    }

    async fetchTickers (symbols = undefined, params = {}) {
        await this.loadMarkets ();
        let tickers = await this.publicGetAllticker (params);
        let ids = Object.keys (tickers);
        let result = {};
        for (let i = 0; i < ids.length; i++) {
            let id = ids[i];
            let market = this.markets_by_id[id];
            let symbol = market['symbol'];
            let ticker = tickers[id];
            result[symbol] = this.parseTicker (ticker, market);
        }
        return result;
    }

    async fetchTicker (symbol, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let request = {};
        let numSymbols = this.symbols.length;
        if (numSymbols > 1)
            request['coin'] = market['id'];
        let ticker = await this.publicGetTicker (this.extend (request, params));
        return this.parseTicker (ticker, market);
    }

    parseTrade (trade, market) {
        let timestamp = parseInt (trade['date']) * 1000;
        return {
            'info': trade,
            'id': trade['tid'],
            'order': undefined,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'symbol': market['symbol'],
            'type': undefined,
            'side': trade['type'],
            'price': trade['price'],
            'amount': trade['amount'],
        };
    }

    async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let request = {};
        let numSymbols = this.symbols.length;
        if (numSymbols > 1)
            request['coin'] = market['id'];
        let response = await this.publicGetOrders (this.extend (request, params));
        return this.parseTrades (response, market, since, limit);
    }

    async createOrder (symbol, type, side, amount, price = undefined, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let request = {
            'amount': amount,
            'price': price,
            'type': side,
        };
        let numSymbols = this.symbols.length;
        if (numSymbols > 1)
            request['coin'] = market['id'];
        let response = await this.privatePostTradeAdd (this.extend (request, params));
        return {
            'info': response,
            'id': response['id'],
        };
    }

    async cancelOrder (id, symbol = undefined, params = {}) {
        await this.loadMarkets ();
        return await this.privatePostTradeCancel (this.extend ({
            'id': id,
        }, params));
    }

    parseOrder (order) {
        // {"id":11,"datetime":"2014-10-21 10:47:20","type":"sell","price":42000,"amount_original":1.2,"amount_outstanding":1.2,"status":"closed","trades":[]}
        const id = this.safeString (order, 'id');
        const timestamp = this.parse8601 (order['datetime']);
        const amount = this.safeFloat (order, 'amount_original');
        const remaining = this.safeFloat (order, 'amount_outstanding');
        let filled = undefined;
        if (typeof amount !== 'undefined')
            if (typeof remaining !== 'undefined')
                filled = amount - remaining;
        const price = this.safeFloat (order, 'price');
        let cost = undefined;
        if (typeof price !== 'undefined')
            if (typeof filled !== 'undefined')
                cost = filled * price;
        const statuses = {
            // TODO: complete list
            'closed': 'closed',
            'cancelled': 'canceled',
        };
        let status = undefined;
        if (order['status'] in statuses)
            status = statuses[order['status']];
        let trades = undefined; // todo: this.parseTrades (order['trades']);
        return {
            'id': id,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'amount': amount,
            'remaining': remaining,
            'filled': filled,
            'side': order['type'],
            'type': undefined,
            'status': status,
            'symbol': undefined,
            'price': price,
            'cost': cost,
            'trades': trades,
            'fee': undefined,
            'info': order,
        };
    }

    async fetchOrder (id, symbol = undefined, params = {}) {
        await this.loadMarkets ();
        let response = await this.privatePostTradeView (this.extend ({
            'id': id,
        }, params));
        return this.parseOrder (response);
    }

    async fetchOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let response = await this.privatePostTradeList (this.extend ({
            'type': 'all', // 'open' or 'all'
        }, params));
        return this.parseOrders (response);
    }

    async fetchOpenOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let response = await this.privatePostTradeList (this.extend ({
            'type': 'open', // 'open' or 'all'
        }, params));
        return this.parseOrders (response);
    }

    sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        let url = this.urls['api'] + '/' + this.version + '/' + path;
        if (api === 'public') {
            if (Object.keys (params).length)
                url += '?' + this.urlencode (params);
        } else {
            this.checkRequiredCredentials ();
            let nonce = this.nonce ().toString ();
            let query = this.extend ({
                'key': this.apiKey,
                'nonce': nonce,
            }, params);
            let request = this.urlencode (query);
            let secret = this.hash (this.encode (this.secret));
            query['signature'] = this.hmac (this.encode (request), this.encode (secret));
            body = this.urlencode (query);
            headers = {
                'Content-Type': 'application/x-www-form-urlencoded',
            };
        }
        return { 'url': url, 'method': method, 'body': body, 'headers': headers };
    }

    handleErrors (httpCode, reason, url, method, headers, body) {
        // typical error response: {"result":false,"code":"401"}
        if (httpCode >= 400)
            return; // resort to defaultErrorHandler
        if (body[0] !== '{')
            return; // not json, resort to defaultErrorHandler
        const response = JSON.parse (body);
        const result = this.safeValue (response, 'result');
        if (typeof result === 'undefined' || result === true)
            return; // either public API (no error codes expected) or success
        const errorCode = this.safeValue (response, 'code');
        const feedback = this.id + ' ' + this.json (response);
        const exceptions = this.exceptions;
        if (errorCode in exceptions)
            throw new exceptions[errorCode] (feedback);
        throw new ExchangeError (feedback); // unknown message
    }
};
<|endoftext|>


<commit_before>const refresh = require('./lib/refresh');
const bot = require('./bot.js');
const settings = require('./../settings.json');
const modules = require('./modules.js');
const Message = require('./../orm/Message')
const commands = require('./commands');
const request = require('request-promise-native');
let lock = false;
bot.on('error', (err) => {
    /**
     * Catch errors here
     */
    console.log("Stack Trace: " + err.stack);
})
process.on('unhandledRejection', (err) => {
    console.log("UNHANDLED REJECTION AT " + err.stack);
    if (err.toString().includes('Request to use token, but token was unavailable to the client'))
        process.exit();//restart
});
process.on('uncaughtException', (err) => console.log("UNHANDLED EXCEPTION AT " + err.stack));
bot.on('message', (message) => {
    /**
     * if locked, reject everything except dm
     */

    new Message({
        messageID: message.id,
        channel: message.channel.id
    }).save();
    if (message.author.bot) return;
    if (lock) {
        if (!settings.owners.includes(message.author.id))
            //  if (message.channel.guild)
            return;//not DM
    }
    /**
     * Listen to messages and convert into params
     */
    if (message.content.startsWith(settings.identifier)) {
        /**Extracting params */
        let params = message.content.substring(settings.identifier.length).trim();
        params = params.split(settings.delimiter || ' ');
        let cmd = params.shift().trim();
        commands.execute(cmd.toLowerCase(), params, message)
    }
    else if (message.isMentioned(bot.user)) {
        /**remove mentions and then get params */
        let params = message.cleancontent.trim().replace(bot.user.toString(), "").trim();
        params = params.split(settings.delimiter || ' ');
        let cmd = params.shift.trim();
        commands.execute(cmd.toLowerCase(), params, message)
    }
    else {
        //ignore because normal message
    }
});
bot.on('lock', () => { lock = true; });
bot.on('unlock', () => { lock = false; });
bot.on("guildMemberAdd", async function (member) {
    var user = member.user;
    if (member.guild.id === "184536578654339072") {
        if (member.user.bot) return console.log(member.user.tag + " is a bot who joined " + member.guild.name)
        user.send("Welcome to the Revive Network");
        if (! await refresh(user)) {
            await member.addRole(bot.guilds.get("184536578654339072").roles.get("317854639431221248"));
            const ma = await bot.channels.get("317859245309689856").send(user.toString() + "Type `accept` to continue. You will be kicked if you don't type `accept` within 10 minutes");
            ma.delete();
            // Await !vote messages
            const filter = (message) => {
                if (message.author.id === member.user.id)
                {
                    message.delete();
                    if (message.content.toLowerCase().includes("accept") && message.member.roles.get("317854639431221248")) {
                        message.member.removeRole("317854639431221248");
                        return message;
                    }
                }
            }
            // Errors: ['time'] treats ending because of the time limit as an error
            bot.channels.get("317859245309689856").awaitMessages(filter, { max: 1, time: 600000, errors: ['time'] })
                .then(collected => {
                    if (collected.size < 1) {
                        member.kick();
                    }
                    return collected;
                })

        }
    }
});/**
bot.on('disconnect', function(event) {
    if (event.code === 0) return console.error(event);
    process.exit();//force restart
});*/

bot.on('ready', () => {
    console.log("ReviveBot Ready");
});
bot.on("guildMemberUpdate", async function (member, newMem) {
    let user = member.user;
    if (member.guild && (member.guild.id === "184536578654339072")) {
        let oldMem = member;
        if (!oldMem.roles.has("273105185566359562") && newMem.roles.has("273105185566359562")) return;
        if (!oldMem.roles.has("275317218911322112") && newMem.roles.has("275317218911322112")) return;
        if ((!oldMem.roles.has("184684916833779712") && newMem.roles.has("184684916833779712")) || (!oldMem.roles.has("200849956796497920") && newMem.roles.has("200849956796497920")) || (!oldMem.roles.has("184676864630063104") && newMem.roles.has("184676864630063104")) || (!oldMem.roles.has("286646245198528523") && newMem.roles.has("286646245198528523"))) {
            await request('http://revive-bot-discord.revive.systems/v0/discord/reverse_link/' + user.id);
        }
    }
});
<commit_msg>Update listen.js<commit_after>const refresh = require('./lib/refresh');
const bot = require('./bot.js');
const settings = require('./../settings.json');
const modules = require('./modules.js');
const Message = require('./../orm/Message')
const commands = require('./commands');
const request = require('request-promise-native');
let lock = false;
bot.on('error', (err) => {
    /**
     * Catch errors here
     */
    console.log("Stack Trace: " + err.stack);
})
process.on('unhandledRejection', (err) => {
    console.log("UNHANDLED REJECTION AT " + err.stack);
    if (err.toString().includes('Request to use token, but token was unavailable to the client'))
        process.exit();//restart
});
process.on('uncaughtException', (err) => console.log("UNHANDLED EXCEPTION AT " + err.stack));
bot.on('message', (message) => {
    /**
     * if locked, reject everything except dm
     */

    new Message({
        messageID: message.id,
        channel: message.channel.id
    }).save();
    if (message.author.bot) return;
    if (lock) {
        if (!settings.owners.includes(message.author.id))
            //  if (message.channel.guild)
            return;//not DM
    }
    /**
     * Listen to messages and convert into params
     */
    if (message.content.startsWith(settings.identifier)) {
        /**Extracting params */
        let params = message.content.substring(settings.identifier.length).trim();
        params = params.split(settings.delimiter || ' ');
        let cmd = params.shift().trim();
        commands.execute(cmd.toLowerCase(), params, message)
    }
    else if (message.isMentioned(bot.user)) {
        /**remove mentions and then get params */
        let params = message.cleancontent.trim().replace(bot.user.toString(), "").trim();
        params = params.split(settings.delimiter || ' ');
        let cmd = params.shift.trim();
        commands.execute(cmd.toLowerCase(), params, message)
    }
    else {
        //ignore because normal message
    }
});
bot.on('lock', () => { lock = true; });
bot.on('unlock', () => { lock = false; });
bot.on("guildMemberAdd", async function (member) {
    var user = member.user;
    if (member.guild.id === "184536578654339072") {
        if (member.user.bot) return console.log(member.user.tag + " is a bot who joined " + member.guild.name)
        user.send("Welcome to the Revive Network");
        if (! await refresh(user)) {
            await member.addRole(bot.guilds.get("184536578654339072").roles.get("317854639431221248"));
            const ma = await bot.channels.get("317859245309689856").send(user.toString() + "Type `accept` to continue. You will be kicked if you don't type `accept` within 10 minutes");
            ma.delete();
            // Await !vote messages
            const filter = (message) => {
                if (message.author.id === member.user.id)
                {
                    message.delete();
                    if (message.content.toLowerCase().includes("accept") && message.member.roles.get("317854639431221248")) {
                        message.member.removeRole("317854639431221248");
                        return message;
                    }
                }
            }
            // Errors: ['time'] treats ending because of the time limit as an error
            bot.channels.get("317859245309689856").awaitMessages(filter, { max: 1, time: 600000, errors: ['time'] })
                .then(collected => {
                    if (collected.size < 1  && !message.member.roles.get("317854639431221248")) {
                        member.kick();
                    }
                    return collected;
                })

        }
    }
});/**
bot.on('disconnect', function(event) {
    if (event.code === 0) return console.error(event);
    process.exit();//force restart
});*/

bot.on('ready', () => {
    console.log("ReviveBot Ready");
});
bot.on("guildMemberUpdate", async function (member, newMem) {
    let user = member.user;
    if (member.guild && (member.guild.id === "184536578654339072")) {
        let oldMem = member;
        if (!oldMem.roles.has("273105185566359562") && newMem.roles.has("273105185566359562")) return;
        if (!oldMem.roles.has("275317218911322112") && newMem.roles.has("275317218911322112")) return;
        if ((!oldMem.roles.has("184684916833779712") && newMem.roles.has("184684916833779712")) || (!oldMem.roles.has("200849956796497920") && newMem.roles.has("200849956796497920")) || (!oldMem.roles.has("184676864630063104") && newMem.roles.has("184676864630063104")) || (!oldMem.roles.has("286646245198528523") && newMem.roles.has("286646245198528523"))) {
            await request('http://revive-bot-discord.revive.systems/v0/discord/reverse_link/' + user.id);
        }
    }
});
<|endoftext|>


<commit_before>import rp from 'request-promise'
import _ from 'lodash'
import Moment from 'moment'

import config from '../config'
import constants from '../constants'
import botHelper from '../helpers'
import apiService from '../services/ppbotApi'

const PAGE_TOKEN = process.env.MESSENGER_PAGE_TOKEN

export function authenticate (req, res) {
  if (req.query['hub.mode'] === 'subscribe' && req.query['hub.verify_token'] === 'ppbot-messenger_ot') {
      res.status(200).send(req.query['hub.challenge'])
    } else {
      res.sendStatus(403)
    }
}

export function receiveMessage (req, res) {
  const data = req.body

  if (data.object === 'page') {
    data.entry.forEach(entry => {
      const pageId = entry.pageId
      const timeOfEvent = entry.time

      entry.messaging.forEach(event => {
        if (event.message) {
          receivedMessage(event)
        } else {
          console.log('Unknown event', event)
        }
      })
    })

    res.sendStatus(200)
  }
}

function receivedMessage(event) {
  const senderID = event.sender.id
  try {
    processMessage({senderID, message: event.message.text})
  } catch (error) {
    sendTextMessage({ recipientId: senderID, text: "Erro ao processar mensagem! :( Tente novamente em alguns instantes." })
  }
}

function processMessage ({ senderID, message }) {
  sendTyping(senderID)

  if (_.upperCase(message) === config.help_command) {
    sendTextMessage({ recipientId: senderID, text: config.help_text })
  } else if(_.includes(constants.GREETINGS, _.chain(message.replace(constants.MARKS_REGULAR_EXPRESSION, '')).upperCase().replace('Á', 'A').value())) {
    sendTextMessage({ recipientId: senderID, text: "Oi! Envie 'Ajuda' para detalhes de como ficar por dentro da programação do Maior e Melhor São João do Mundo :D" })
  } else if (_.includes(constants.THANKS, _.chain(message.replace(constants.MARKS_REGULAR_EXPRESSION, '')).upperCase())) {
    sendTextMessage({ recipientId: senderID, text: "Por nada! ;)" })
  } else {
    let dates = []

    try {
      dates = botHelper.getDateFromMessage(message)
    } catch (error) {
      console.log(error)
      if (error.name === 'InvalidStringException') {
        sendTextMessage({ recipientId: senderID, text: "Ops! Mensagem inválida. Envie 'Ajuda' para mais detalhes de como utilizar o Bot! :)" })
      } else {
        sendTextMessage({ recipientId: senderID, text: "Ops! Data inválida. O Maior e Melhor São João do Mundo vai de 02 de junho a 02 de julho de 2017! :)" })
      }
      return
    }

    apiService.getShows()
    .then(shows => {
      const filteredShows = botHelper.filterShows({ shows, dates })
      if (!_.isEmpty(filteredShows)) {
        sendReply({ recipientId: senderID, shows: filteredShows })
      } else {
        sendTextMessage({ recipientId: senderID, text: "Nenhum show encontrado para o dia desejado" })
      }
    })
    .catch(err => {
      console.log(err)
      sendTextMessage({ recipientId: senderID, text: "Erro ao processar mensagem! :( Tente novamente em alguns instantes." })
    })
  }
}

function sendTextMessage({recipientId, text}) {
  var messageData = {
    recipient: {
      id: recipientId
    },
    message: {
      text
    }
  }

  callSendAPI(messageData)
}

function sendReply ({ recipientId, shows }) {
  _.forIn(shows, (value, key) => {
    const data = createMessage(value)
    const messageData = {
      recipient: {
        id: recipientId
      },
      message: {
        attachment: {
          type: "template",
          payload: {
            template_type: "generic",
            elements: data
          }
        }
      }
    }

    callSendAPI(messageData)
  })
}

function sendTyping (senderId) {
  rp({
    uri: 'https://graph.facebook.com/v2.6/me/messages',
    qs: { access_token: PAGE_TOKEN },
    method: 'POST',
    json: {
      recipient: {
        id: senderId
      },
      sender_action: 'typing_on'
    }
  })
  .then((response, body) => {
    if (response.statusCode == 200) {
      var recipientId = body.recipient_id
      var messageId = body.message_id

      console.log("Successfully sent typing message with id %s to recipient %s", messageId, recipientId)
    }
  })
  .catch(err => {
    console.error("Unable to send message.")
    console.error(err)
  })
}

function callSendAPI(messageData) {
  rp({
    uri: 'https://graph.facebook.com/v2.6/me/messages',
    qs: { access_token: PAGE_TOKEN },
    method: 'POST',
    json: messageData
  })
  .then((response, body) => {
    if (response.statusCode == 200) {
      var recipientId = body.recipient_id
      var messageId = body.message_id

      console.log("Successfully sent generic message with id %s to recipient %s", messageId, recipientId)
    }
  })
  .catch(err => {
    console.error("Unable to send message.")
    console.error(err)
  })
}

function createMessage (shows) {
  let result = []
  _.forEach(shows, s => {
    result.push({
      title: s.name,
      subtitle: Moment(s.date).format('DD [de] MMMM - dddd'),
      image_url: s.imgUrl,
      buttons: [
        {
          type: "web_url",
          url: s.videoUrl,
          title: "Ver vídeo"
        }
      ]
    })
  })
  return result
}<commit_msg>Changing thanks to uppercase - value<commit_after>import rp from 'request-promise'
import _ from 'lodash'
import Moment from 'moment'

import config from '../config'
import constants from '../constants'
import botHelper from '../helpers'
import apiService from '../services/ppbotApi'

const PAGE_TOKEN = process.env.MESSENGER_PAGE_TOKEN

export function authenticate (req, res) {
  if (req.query['hub.mode'] === 'subscribe' && req.query['hub.verify_token'] === 'ppbot-messenger_ot') {
      res.status(200).send(req.query['hub.challenge'])
    } else {
      res.sendStatus(403)
    }
}

export function receiveMessage (req, res) {
  const data = req.body

  if (data.object === 'page') {
    data.entry.forEach(entry => {
      const pageId = entry.pageId
      const timeOfEvent = entry.time

      entry.messaging.forEach(event => {
        if (event.message) {
          receivedMessage(event)
        } else {
          console.log('Unknown event', event)
        }
      })
    })

    res.sendStatus(200)
  }
}

function receivedMessage(event) {
  const senderID = event.sender.id
  try {
    processMessage({senderID, message: event.message.text})
  } catch (error) {
    sendTextMessage({ recipientId: senderID, text: "Erro ao processar mensagem! :( Tente novamente em alguns instantes." })
  }
}

function processMessage ({ senderID, message }) {
  sendTyping(senderID)

  if (_.upperCase(message) === config.help_command) {
    sendTextMessage({ recipientId: senderID, text: config.help_text })
  } else if(_.includes(constants.GREETINGS, _.chain(message.replace(constants.MARKS_REGULAR_EXPRESSION, '')).upperCase().replace('Á', 'A').value())) {
    sendTextMessage({ recipientId: senderID, text: "Oi! Envie 'Ajuda' para detalhes de como ficar por dentro da programação do Maior e Melhor São João do Mundo :D" })
  } else if (_.includes(constants.THANKS, _.chain(message.replace(constants.MARKS_REGULAR_EXPRESSION, '')).upperCase().value())) {
    sendTextMessage({ recipientId: senderID, text: "Por nada! ;)" })
  } else {
    let dates = []

    try {
      dates = botHelper.getDateFromMessage(message)
    } catch (error) {
      console.log(error)
      if (error.name === 'InvalidStringException') {
        sendTextMessage({ recipientId: senderID, text: "Ops! Mensagem inválida. Envie 'Ajuda' para mais detalhes de como utilizar o Bot! :)" })
      } else {
        sendTextMessage({ recipientId: senderID, text: "Ops! Data inválida. O Maior e Melhor São João do Mundo vai de 02 de junho a 02 de julho de 2017! :)" })
      }
      return
    }

    apiService.getShows()
    .then(shows => {
      const filteredShows = botHelper.filterShows({ shows, dates })
      if (!_.isEmpty(filteredShows)) {
        sendReply({ recipientId: senderID, shows: filteredShows })
      } else {
        sendTextMessage({ recipientId: senderID, text: "Nenhum show encontrado para o dia desejado" })
      }
    })
    .catch(err => {
      console.log(err)
      sendTextMessage({ recipientId: senderID, text: "Erro ao processar mensagem! :( Tente novamente em alguns instantes." })
    })
  }
}

function sendTextMessage({recipientId, text}) {
  var messageData = {
    recipient: {
      id: recipientId
    },
    message: {
      text
    }
  }

  callSendAPI(messageData)
}

function sendReply ({ recipientId, shows }) {
  _.forIn(shows, (value, key) => {
    const data = createMessage(value)
    const messageData = {
      recipient: {
        id: recipientId
      },
      message: {
        attachment: {
          type: "template",
          payload: {
            template_type: "generic",
            elements: data
          }
        }
      }
    }

    callSendAPI(messageData)
  })
}

function sendTyping (senderId) {
  rp({
    uri: 'https://graph.facebook.com/v2.6/me/messages',
    qs: { access_token: PAGE_TOKEN },
    method: 'POST',
    json: {
      recipient: {
        id: senderId
      },
      sender_action: 'typing_on'
    }
  })
  .then((response, body) => {
    if (response.statusCode == 200) {
      var recipientId = body.recipient_id
      var messageId = body.message_id

      console.log("Successfully sent typing message with id %s to recipient %s", messageId, recipientId)
    }
  })
  .catch(err => {
    console.error("Unable to send message.")
    console.error(err)
  })
}

function callSendAPI(messageData) {
  rp({
    uri: 'https://graph.facebook.com/v2.6/me/messages',
    qs: { access_token: PAGE_TOKEN },
    method: 'POST',
    json: messageData
  })
  .then((response, body) => {
    if (response.statusCode == 200) {
      var recipientId = body.recipient_id
      var messageId = body.message_id

      console.log("Successfully sent generic message with id %s to recipient %s", messageId, recipientId)
    }
  })
  .catch(err => {
    console.error("Unable to send message.")
    console.error(err)
  })
}

function createMessage (shows) {
  let result = []
  _.forEach(shows, s => {
    result.push({
      title: s.name,
      subtitle: Moment(s.date).format('DD [de] MMMM - dddd'),
      image_url: s.imgUrl,
      buttons: [
        {
          type: "web_url",
          url: s.videoUrl,
          title: "Ver vídeo"
        }
      ]
    })
  })
  return result
}<|endoftext|>


<commit_before>const assert = require("assert");
const CommandRunner = require("../commandrunner");
const MemoryLogger = require("../memorylogger");
const fs = require("fs-extra");

describe("truffle unbox", () => {
  let config;
  const logger = new MemoryLogger();

  beforeEach("set up config for logger", () => {
    config = { working_directory: `${process.cwd()}/test/sources/unbox` };
    config.logger = logger;
  });

  afterEach("clear working_directory", () => {
    fs.emptyDirSync(`${process.cwd()}/test/sources/unbox`);
  });

  describe("when run without arguments", () => {
    it("unboxes truffle-init-default", done => {
      CommandRunner.run("unbox --force", config, () => {
        assert(
          fs.pathExistsSync(
            `${process.cwd()}/test/sources/unbox/contracts/ConvertLib.sol`
          )
        );
        assert(
          fs.pathExistsSync(
            `${process.cwd()}/test/sources/unbox/contracts/Migrations.sol`
          )
        );
        assert(
          fs.pathExistsSync(
            `${process.cwd()}/test/sources/unbox/contracts/MetaCoin.sol`
          )
        );
        done();
      });
    }).timeout(20000);
  });

  describe("when run with arguments", () => {
    describe("valid input", () => {
      afterEach("clear working_directory", () => {
        fs.emptyDirSync(`${process.cwd()}/test/sources/unbox`);
      });

      describe("full url", () => {
        it("unboxes successfully", done => {
          CommandRunner.run(
            "unbox https://github.com/truffle-box/bare-box",
            config,
            () => {
              const output = logger.contents();
              assert(output.includes("Unbox successful."));
              done();
            }
          );
        }).timeout(20000);
      });

      describe("full url + branch", () => {
        it("unboxes successfully", done => {
          CommandRunner.run(
            "unbox https://github.com/truffle-box/bare-box#truffle-test-branch",
            config,
            () => {
              const output = logger.contents();
              assert(output.includes("Unbox successful."));
              done();
            }
          );
        }).timeout(20000);
      });

      describe("full url + branch + relativePath", () => {
        it("unboxes successfully", done => {
          CommandRunner.run(
            "unbox https://github.com/truffle-box/bare-box#truffle-test-branch:path/to/subDir --force",
            config,
            () => {
              const output = logger.contents();
              assert(output.includes("Unbox successful."));
              done();
            }
          );
        }).timeout(20000);
      });

      describe("origin/master", () => {
        it("unboxes successfully", done => {
          CommandRunner.run("unbox truffle-box/bare-box", config, () => {
            const output = logger.contents();
            assert(output.includes("Unbox successful."));
            done();
          });
        }).timeout(20000);
      });

      describe("origin/master#branch", () => {
        it("unboxes successfully", done => {
          CommandRunner.run(
            "unbox truffle-box/bare-box#truffle-test-branch",
            config,
            () => {
              const output = logger.contents();
              assert(output.includes("Unbox successful."));
              done();
            }
          );
        }).timeout(20000);
      });

      describe("origin/master#branch:relativePath", () => {
        it("unboxes successfully", done => {
          CommandRunner.run(
            "unbox truffle-box/bare-box#truffle-test-branch:path/to/subDir --force",
            config,
            () => {
              const output = logger.contents();
              assert(output.includes("Unbox successful."));
              done();
            }
          );
        }).timeout(20000);
      });

      describe("official truffle box", () => {
        it("unboxes successfully", done => {
          CommandRunner.run("unbox bare", config, () => {
            const output = logger.contents();
            assert(output.includes("Unbox successful."));
            done();
          });
        }).timeout(20000);
      });

      describe("official truffle box + branch", () => {
        it("unboxes successfully", done => {
          CommandRunner.run("unbox bare#truffle-test-branch", config, () => {
            const output = logger.contents();
            assert(output.includes("Unbox successful."));
            done();
          });
        }).timeout(20000);
      });

      describe("official truffle box + branch + relativePath", () => {
        it("unboxes successfully", done => {
          CommandRunner.run(
            "unbox bare#truffle-test-branch:path/to/subDir --force",
            config,
            () => {
              const output = logger.contents();
              assert(output.includes("Unbox successful."));
              done();
            }
          );
        }).timeout(20000);
      });

      describe("git@ ssh", () => {
        it("unboxes successfully", done => {
          CommandRunner.run(
            "unbox git@github.com:truffle-box/bare-box",
            config,
            () => {
              const output = logger.contents();
              assert(output.includes("Unbox successful."));
              done();
            }
          );
        }).timeout(20000);
      });

      describe("with an invalid git@ ssh", () => {
        it("logs an error", done => {
          CommandRunner.run(
            "unbox git@github.com:truffle-box/bare-boxer",
            config,
            () => {
              const output = logger.contents();
              assert(output.includes("doesn't exist."));
              done();
            }
          );
        }).timeout(20000);
      });

      describe("git@ ssh + branch", () => {
        it("unboxes successfully", done => {
          CommandRunner.run(
            "unbox git@github.com:truffle-box/bare-box#truffle-test-branch",
            config,
            () => {
              const output = logger.contents();
              assert(output.includes("Unbox successful."));
              done();
            }
          );
        }).timeout(20000);
      });

      describe("git@ ssh + branch + relativePath", () => {
        it("unboxes successfully", done => {
          CommandRunner.run(
            "unbox git@github.com:truffle-box/bare-box#truffle-test-branch:path/to/subDir --force",
            config,
            () => {
              const output = logger.contents();
              assert(output.includes("Unbox successful."));
              done();
            }
          );
        }).timeout(20000);
      });
    });

    describe("with invalid input", () => {
      afterEach("clear working_directory", () => {
        fs.emptyDirSync(`${process.cwd()}/test/sources/unbox`);
      });

      describe("invalid full url", () => {
        it("throws an error", done => {
          CommandRunner.run(
            "unbox https://github.com/truffle-box/bare-boxing",
            config,
            () => {
              const output = logger.contents();
              assert(output.includes("doesn't exist."));
              done();
            }
          );
        }).timeout(20000);
      });

      describe("invalid origin/master", () => {
        it("throws an error", done => {
          CommandRunner.run("unbox truffle-box/bare-boxer", config, () => {
            const output = logger.contents();
            assert(output.includes("doesn't exist."));
            done();
          });
        }).timeout(20000);
      });

      describe("invalid official truffle box", () => {
        it("throws an error", done => {
          CommandRunner.run("unbox barer", config, () => {
            const output = logger.contents();
            assert(output.includes("doesn't exist."));
            done();
          });
        }).timeout(20000);
      });

      describe("invalid git@ ssh", () => {
        it("throws an error", done => {
          CommandRunner.run(
            "unbox git@github.com:truffle-box/bare-boxer",
            config,
            () => {
              const output = logger.contents();
              assert(output.includes("doesn't exist."));
              done();
            }
          );
        }).timeout(20000);
      });

      describe("absolutePaths", () => {
        it("throws an error", done => {
          CommandRunner.run("unbox bare:/path/to/subDir", config, () => {
            const output = logger.contents();
            assert(output.includes("not allowed!"));
            done();
          });
        }).timeout(20000);
      });

      describe("invalid box format", () => {
        it("throws an error", done => {
          CommandRunner.run("unbox /bare/", config, () => {
            const output = logger.contents();
            assert(output.includes("invalid format"));
            done();
          });
        }).timeout(20000);
      });
    });
  });
});
<commit_msg>Add some messages to clarify errors<commit_after>const assert = require("assert");
const CommandRunner = require("../commandrunner");
const MemoryLogger = require("../memorylogger");
const fs = require("fs-extra");

describe("truffle unbox", () => {
  let config;
  const logger = new MemoryLogger();

  beforeEach("set up config for logger", () => {
    config = { working_directory: `${process.cwd()}/test/sources/unbox` };
    config.logger = logger;
  });

  afterEach("clear working_directory", () => {
    fs.emptyDirSync(`${process.cwd()}/test/sources/unbox`);
  });

  describe("when run without arguments", () => {
    it("unboxes truffle-init-default", done => {
      CommandRunner.run("unbox --force", config, () => {
        assert(
          fs.pathExistsSync(
            `${process.cwd()}/test/sources/unbox/contracts/ConvertLib.sol`
          ),
          "ConvertLib.sol does not exist"
        );
        assert(
          fs.pathExistsSync(
            `${process.cwd()}/test/sources/unbox/contracts/Migrations.sol`
          ),
          "Migrations.sol does not exist"
        );
        assert(
          fs.pathExistsSync(
            `${process.cwd()}/test/sources/unbox/contracts/MetaCoin.sol`
          ),
          "MetaCoin.sol does not exist"
        );
        done();
      });
    }).timeout(20000);
  });

  describe("when run with arguments", () => {
    describe("valid input", () => {
      afterEach("clear working_directory", () => {
        fs.emptyDirSync(`${process.cwd()}/test/sources/unbox`);
      });

      describe("full url", () => {
        it("unboxes successfully", done => {
          CommandRunner.run(
            "unbox https://github.com/truffle-box/bare-box",
            config,
            () => {
              const output = logger.contents();
              assert(output.includes("Unbox successful."));
              done();
            }
          );
        }).timeout(20000);
      });

      describe("full url + branch", () => {
        it("unboxes successfully", done => {
          CommandRunner.run(
            "unbox https://github.com/truffle-box/bare-box#truffle-test-branch",
            config,
            () => {
              const output = logger.contents();
              assert(output.includes("Unbox successful."));
              done();
            }
          );
        }).timeout(20000);
      });

      describe("full url + branch + relativePath", () => {
        it("unboxes successfully", done => {
          CommandRunner.run(
            "unbox https://github.com/truffle-box/bare-box#truffle-test-branch:path/to/subDir --force",
            config,
            () => {
              const output = logger.contents();
              assert(output.includes("Unbox successful."));
              done();
            }
          );
        }).timeout(20000);
      });

      describe("origin/master", () => {
        it("unboxes successfully", done => {
          CommandRunner.run("unbox truffle-box/bare-box", config, () => {
            const output = logger.contents();
            assert(output.includes("Unbox successful."));
            done();
          });
        }).timeout(20000);
      });

      describe("origin/master#branch", () => {
        it("unboxes successfully", done => {
          CommandRunner.run(
            "unbox truffle-box/bare-box#truffle-test-branch",
            config,
            () => {
              const output = logger.contents();
              assert(output.includes("Unbox successful."));
              done();
            }
          );
        }).timeout(20000);
      });

      describe("origin/master#branch:relativePath", () => {
        it("unboxes successfully", done => {
          CommandRunner.run(
            "unbox truffle-box/bare-box#truffle-test-branch:path/to/subDir --force",
            config,
            () => {
              const output = logger.contents();
              assert(output.includes("Unbox successful."));
              done();
            }
          );
        }).timeout(20000);
      });

      describe("official truffle box", () => {
        it("unboxes successfully", done => {
          CommandRunner.run("unbox bare", config, () => {
            const output = logger.contents();
            assert(output.includes("Unbox successful."));
            done();
          });
        }).timeout(20000);
      });

      describe("official truffle box + branch", () => {
        it("unboxes successfully", done => {
          CommandRunner.run("unbox bare#truffle-test-branch", config, () => {
            const output = logger.contents();
            assert(output.includes("Unbox successful."));
            done();
          });
        }).timeout(20000);
      });

      describe("official truffle box + branch + relativePath", () => {
        it("unboxes successfully", done => {
          CommandRunner.run(
            "unbox bare#truffle-test-branch:path/to/subDir --force",
            config,
            () => {
              const output = logger.contents();
              assert(output.includes("Unbox successful."));
              done();
            }
          );
        }).timeout(20000);
      });

      describe("git@ ssh", () => {
        it("unboxes successfully", done => {
          CommandRunner.run(
            "unbox git@github.com:truffle-box/bare-box",
            config,
            () => {
              const output = logger.contents();
              assert(output.includes("Unbox successful."));
              done();
            }
          );
        }).timeout(20000);
      });

      describe("with an invalid git@ ssh", () => {
        it("logs an error", done => {
          CommandRunner.run(
            "unbox git@github.com:truffle-box/bare-boxer",
            config,
            () => {
              const output = logger.contents();
              assert(output.includes("doesn't exist."));
              done();
            }
          );
        }).timeout(20000);
      });

      describe("git@ ssh + branch", () => {
        it("unboxes successfully", done => {
          CommandRunner.run(
            "unbox git@github.com:truffle-box/bare-box#truffle-test-branch",
            config,
            () => {
              const output = logger.contents();
              assert(output.includes("Unbox successful."));
              done();
            }
          );
        }).timeout(20000);
      });

      describe("git@ ssh + branch + relativePath", () => {
        it("unboxes successfully", done => {
          CommandRunner.run(
            "unbox git@github.com:truffle-box/bare-box#truffle-test-branch:path/to/subDir --force",
            config,
            () => {
              const output = logger.contents();
              assert(output.includes("Unbox successful."));
              done();
            }
          );
        }).timeout(20000);
      });
    });

    describe("with invalid input", () => {
      afterEach("clear working_directory", () => {
        fs.emptyDirSync(`${process.cwd()}/test/sources/unbox`);
      });

      describe("invalid full url", () => {
        it("throws an error", done => {
          CommandRunner.run(
            "unbox https://github.com/truffle-box/bare-boxing",
            config,
            () => {
              const output = logger.contents();
              assert(output.includes("doesn't exist."));
              done();
            }
          );
        }).timeout(20000);
      });

      describe("invalid origin/master", () => {
        it("throws an error", done => {
          CommandRunner.run("unbox truffle-box/bare-boxer", config, () => {
            const output = logger.contents();
            assert(output.includes("doesn't exist."));
            done();
          });
        }).timeout(20000);
      });

      describe("invalid official truffle box", () => {
        it("throws an error", done => {
          CommandRunner.run("unbox barer", config, () => {
            const output = logger.contents();
            assert(output.includes("doesn't exist."));
            done();
          });
        }).timeout(20000);
      });

      describe("invalid git@ ssh", () => {
        it("throws an error", done => {
          CommandRunner.run(
            "unbox git@github.com:truffle-box/bare-boxer",
            config,
            () => {
              const output = logger.contents();
              assert(output.includes("doesn't exist."));
              done();
            }
          );
        }).timeout(20000);
      });

      describe("absolutePaths", () => {
        it("throws an error", done => {
          CommandRunner.run("unbox bare:/path/to/subDir", config, () => {
            const output = logger.contents();
            assert(output.includes("not allowed!"));
            done();
          });
        }).timeout(20000);
      });

      describe("invalid box format", () => {
        it("throws an error", done => {
          CommandRunner.run("unbox /bare/", config, () => {
            const output = logger.contents();
            assert(output.includes("invalid format"));
            done();
          });
        }).timeout(20000);
      });
    });
  });
});
<|endoftext|>


<commit_before>/*//////////////////////////////// ABOUT \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*\

	1401.js is the 'server startup' code, called directly from the gulpfile
	in runServer(). It is invoked in a separate node instance, so it can be
	killed and restarted independently of the gulp build process.

	For unmodified 1401A1 instances, you won't have to change this unless
	you want to add new features.

	To add new features, create your own version of 1401.js (name
	it something else) that does a call to server.setServerInitHook( hook )
	BEFORE calling startServer(). The hook function will recieve an instance
	of the express app, which can be modified BEFORE app.listen() is invoked.
	You can add your own routes, etc, then.

\*\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ * //////////////////////////////////////*/

	var server = require('./1401-server');

///////////////////////////////////////////////////////////////////////////////

	server.startServer();

///////////////////////////////////////////////////////////////////////////////
/** RETURN MODULE DEFINITION *************************************************/
	module.exports.setServerInitHook = server.setServerInitHook;
<commit_msg>bg-plae-compatibility: The 1401.js startup script can now be modified to add additional server features without having to create a new file and changing the gulpfile.<commit_after>/*//////////////////////////////// ABOUT \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*\

	1401.js is the 'server startup' code, called directly from the gulpfile
	in runServer(). It is invoked in a separate node instance, so it can be
	killed and restarted independently of the gulp build process.

	For unmodified 1401A1 instances, you won't have to change this unless
	you want to add new features.

	To add new features, append additional modules and write a function that
	initializes them via the server.setServerInitHook() call. This function
	receives an instance of Express app before app.listen() is called.

\*\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ * //////////////////////////////////////*/

	var server = require('./1401-server');

/// START SERVER //////////////////////////////////////////////////////////////

	server.setServerInitHook ( function ( app ) {
		// your additional ExpressJS app initialization goes here
	});
	server.startServer();

///////////////////////////////////////////////////////////////////////////////
<|endoftext|>