<commit_before>var apply_default, check_search_term, dataset_info, group_info, make_default, open_window, populate_dataset, populate_group, populate_species, populate_type, process_json, redo_dropdown;
process_json = function(data) {
  window.jdata = data;
  populate_species();
  if ($('#type').length > 0) { //This is to determine if it's the index page or the submit_trait page (which only has species and group selection and no make default option)
    return apply_default();
  }
};
$.ajax('/api/v_pre1/gen_dropdown', {
  dataType: 'json',
  success: process_json
});

populate_species = function() {
  var species_list;
  species_list = this.jdata.species;
  redo_dropdown($('#species'), species_list);
  return populate_group();
};
window.populate_species = populate_species;
populate_group = function() {
  var group_list, species;
  console.log("in populate group");
  species = $('#species').val();
  group_list = this.jdata.groups[species];
  for (_i = 0, _len = group_list.length; _i < (_len - 1); _i++) {
     if (group_list[_i][0] == "BXD300"){
         group_list.splice(_i, 1)
     }
  }
  redo_dropdown($('#group'), group_list);
  if ($('#type').length > 0) { //This is to determine if it's the index page or the submit_trait page (which only has species and group selection and no make default option)
    return populate_type();
  }
};
window.populate_group = populate_group;
populate_type = function() {
  var group, species, type_list;
  console.log("in populate type");
  species = $('#species').val();
  group = $('#group').val();
  type_list = this.jdata.types[species][group];
  redo_dropdown($('#type'), type_list);
  return populate_dataset();
};
window.populate_type = populate_type;
populate_dataset = function() {
  var dataset_list, group, species, type;
  console.log("in populate dataset");
  species = $('#species').val();
  group = $('#group').val();
  type = $('#type').val();
  console.log("sgt:", species, group, type);
  dataset_list = this.jdata.datasets[species][group][type];
  console.log("pop_dataset:", dataset_list);
  return redo_dropdown($('#dataset'), dataset_list);
};
window.populate_dataset = populate_dataset;
redo_dropdown = function(dropdown, items) {
  var item, _i, _len, _results;
  console.log("in redo:", dropdown, items);
  dropdown.empty();
  _results = [];

  if (dropdown.attr('id') == "group"){
    group_family_list = [];
    for (_i = 0, _len = items.length; _i < _len; _i++) {
      item = items[_i];
      group_family = item[2].toString().split(":")[1]
      group_family_list.push([item[0], item[1], group_family])
    }

    current_family = ""
    this_opt_group = null
    for (_i = 0, _len = group_family_list.length; _i < _len; _i++) {
      item = group_family_list[_i];
      console.log("THE ITEM:", item)
      if (item[2] != "None" && current_family == ""){
        current_family = item[2]
        this_opt_group = $("<optgroup label=\"" + item[2] + "\">")
        this_opt_group.append($("<option />").val(item[0]).text(item[1]));
      } else if (current_family != "" && item[2] == current_family){
        this_opt_group.append($("<option />").val(item[0]).text(item[1]));
      } else if (current_family != "" && item[2] != current_family && item[2] != "None"){
        current_family = item[2]
        _results.push(dropdown.append(this_opt_group))
        this_opt_group = $("<optgroup label=\"" + current_family + "\">")
        this_opt_group.append($("<option />").val(item[0]).text(item[1]));
      } else if (current_family != "" && this_opt_group != null && item[2] == "None"){
        _results.push(dropdown.append(this_opt_group))
        current_family = ""
        _results.push(dropdown.append($("<option />").val(item[0]).text(item[1])));
      } else {
        _results.push(dropdown.append($("<option />").val(item[0]).text(item[1])));
      }
    }
  } else {
    for (_i = 0, _len = items.length; _i < _len; _i++) {
      item = items[_i];
      if (item.length > 2){
        _results.push(dropdown.append($("<option data-id=\""+item[0]+"\" />").val(item[1]).text(item[2])));
      } else {
        _results.push(dropdown.append($("<option />").val(item[0]).text(item[1])));
      }
    }
  }
  return _results;
};
$('#species').change((function(_this) {
  return function() {
    return populate_group();
  };
})(this));
$('#group').change((function(_this) {
  return function() {
    if ($('#type').length > 0) { //This is to determine if it's the index page or the submit_trait page (which only has species and group selection and no make default option)
      return populate_type();
    }
    else {
      return false
    }
  };
})(this));
$('#type').change((function(_this) {
  return function() {
    return populate_dataset();
  };
})(this));
open_window = function(url, name) {
  var options;
  options = "menubar=yes,toolbar=yes,titlebar=yes,location=yes,resizable=yes,status=yes,scrollbars=yes,directories=yes,width=900";
  return open(url, name, options).focus();
};
group_info = function() {
  var group, species, url;
  species = $('#species').val();
  group = $('#group').val();
  url = "/" + species + "Cross.html#" + group;
  return open_window(url, "Group Info");
};
$('#group_info').click(group_info);
dataset_info = function() {
  var dataset, url;
  accession_id = $('#dataset option:selected').data("id");
  if (accession_id != "None") {
    url = "http://genenetwork.org/webqtl/main.py?FormID=sharinginfo&GN_AccessionId=" + accession_id;
  } else {
    name = $('#dataset option:selected').val();
    url = "http://genenetwork.org/webqtl/main.py?FormID=sharinginfo&InfoPageName=" + name;
  }
  return open_window(url, "Dataset Info");
};
$('#dataset_info').click(dataset_info);
make_default = function() {
  var holder, item, jholder, _i, _len, _ref;
  alert("The current settings are now your default.")
  holder = {};
  _ref = ['species', 'group', 'type', 'dataset'];
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
    item = _ref[_i];
    holder[item] = $("#" + item).val();
  }
  jholder = JSON.stringify(holder);
  return $.cookie('search_defaults', jholder, {
    expires: 365
  });
};
apply_default = function() {
  var defaults, item, populate_function, _i, _len, _ref, _results;
  defaults = $.cookie('search_defaults');
  if (defaults) {
    defaults = $.parseJSON(defaults);
  } else {
    defaults = {
      species: "mouse",
      group: "BXD",
      type: "Hippocampus mRNA",
      dataset: "HC_M2_0606_P"
    };
  }

  _ref = [['species', 'group'], ['group', 'type'], ['type', 'dataset'], ['dataset', null]];
  _results = [];
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
    item = _ref[_i];
    $("#" + item[0]).val(defaults[item[0]]);
    if (item[1]) {
      populate_function = "populate_" + item[1];
      console.log("Calling:", populate_function);
      _results.push(window[populate_function]());
    } else {
      _results.push(void 0);
    }
  }
  return _results;
};
check_search_term = function() {
  var or_search_term, and_search_term;
  or_search_term = $('#or_search').val();
  and_search_term = $('#and_search').val();
  console.log("or_search_term:", or_search_term);
  console.log("and_search_term:", and_search_term);
  if (or_search_term === "" && and_search_term === "") {
    alert("Please enter one or more search terms or search equations.");
    return false;
  }
};
$("#make_default").click(make_default);
$("#btsearch").click(check_search_term);
<commit_msg>Change needed to get info pages to work when there's no accession id<commit_after>var apply_default, check_search_term, dataset_info, group_info, make_default, open_window, populate_dataset, populate_group, populate_species, populate_type, process_json, redo_dropdown;
process_json = function(data) {
  window.jdata = data;
  populate_species();
  if ($('#type').length > 0) { //This is to determine if it's the index page or the submit_trait page (which only has species and group selection and no make default option)
    return apply_default();
  }
};
$.ajax('/api/v_pre1/gen_dropdown', {
  dataType: 'json',
  success: process_json
});

populate_species = function() {
  var species_list;
  species_list = this.jdata.species;
  redo_dropdown($('#species'), species_list);
  return populate_group();
};
window.populate_species = populate_species;
populate_group = function() {
  var group_list, species;
  console.log("in populate group");
  species = $('#species').val();
  group_list = this.jdata.groups[species];
  for (_i = 0, _len = group_list.length; _i < (_len - 1); _i++) {
     if (group_list[_i][0] == "BXD300"){
         group_list.splice(_i, 1)
     }
  }
  redo_dropdown($('#group'), group_list);
  if ($('#type').length > 0) { //This is to determine if it's the index page or the submit_trait page (which only has species and group selection and no make default option)
    return populate_type();
  }
};
window.populate_group = populate_group;
populate_type = function() {
  var group, species, type_list;
  console.log("in populate type");
  species = $('#species').val();
  group = $('#group').val();
  type_list = this.jdata.types[species][group];
  redo_dropdown($('#type'), type_list);
  return populate_dataset();
};
window.populate_type = populate_type;
populate_dataset = function() {
  var dataset_list, group, species, type;
  console.log("in populate dataset");
  species = $('#species').val();
  group = $('#group').val();
  type = $('#type').val();
  console.log("sgt:", species, group, type);
  dataset_list = this.jdata.datasets[species][group][type];
  console.log("pop_dataset:", dataset_list);
  return redo_dropdown($('#dataset'), dataset_list);
};
window.populate_dataset = populate_dataset;
redo_dropdown = function(dropdown, items) {
  var item, _i, _len, _results;
  console.log("in redo:", dropdown, items);
  dropdown.empty();
  _results = [];

  if (dropdown.attr('id') == "group"){
    group_family_list = [];
    for (_i = 0, _len = items.length; _i < _len; _i++) {
      item = items[_i];
      group_family = item[2].toString().split(":")[1]
      group_family_list.push([item[0], item[1], group_family])
    }

    current_family = ""
    this_opt_group = null
    for (_i = 0, _len = group_family_list.length; _i < _len; _i++) {
      item = group_family_list[_i];
      console.log("THE ITEM:", item)
      if (item[2] != "None" && current_family == ""){
        current_family = item[2]
        this_opt_group = $("<optgroup label=\"" + item[2] + "\">")
        this_opt_group.append($("<option />").val(item[0]).text(item[1]));
      } else if (current_family != "" && item[2] == current_family){
        this_opt_group.append($("<option />").val(item[0]).text(item[1]));
      } else if (current_family != "" && item[2] != current_family && item[2] != "None"){
        current_family = item[2]
        _results.push(dropdown.append(this_opt_group))
        this_opt_group = $("<optgroup label=\"" + current_family + "\">")
        this_opt_group.append($("<option />").val(item[0]).text(item[1]));
      } else if (current_family != "" && this_opt_group != null && item[2] == "None"){
        _results.push(dropdown.append(this_opt_group))
        current_family = ""
        _results.push(dropdown.append($("<option />").val(item[0]).text(item[1])));
      } else {
        _results.push(dropdown.append($("<option />").val(item[0]).text(item[1])));
      }
    }
  } else {
    for (_i = 0, _len = items.length; _i < _len; _i++) {
      item = items[_i];
      if (item.length > 2){
        _results.push(dropdown.append($("<option data-id=\""+item[0]+"\" />").val(item[1]).text(item[2])));
      } else {
        _results.push(dropdown.append($("<option />").val(item[0]).text(item[1])));
      }
    }
  }
  return _results;
};
$('#species').change((function(_this) {
  return function() {
    return populate_group();
  };
})(this));
$('#group').change((function(_this) {
  return function() {
    if ($('#type').length > 0) { //This is to determine if it's the index page or the submit_trait page (which only has species and group selection and no make default option)
      return populate_type();
    }
    else {
      return false
    }
  };
})(this));
$('#type').change((function(_this) {
  return function() {
    return populate_dataset();
  };
})(this));
open_window = function(url, name) {
  var options;
  options = "menubar=yes,toolbar=yes,titlebar=yes,location=yes,resizable=yes,status=yes,scrollbars=yes,directories=yes,width=900";
  return open(url, name, options).focus();
};
group_info = function() {
  var group, species, url;
  species = $('#species').val();
  group = $('#group').val();
  url = "/" + species + "Cross.html#" + group;
  return open_window(url, "Group Info");
};
$('#group_info').click(group_info);
dataset_info = function() {
  var dataset, url;
  accession_id = $('#dataset option:selected').data("id");
  name = $('#dataset option:selected').val();
  if (accession_id != "None") {
    url = "http://genenetwork.org/webqtl/main.py?FormID=sharinginfo&GN_AccessionId=" + accession_id + "&InfoPageName=" + name;
  } else {
    url = "http://genenetwork.org/webqtl/main.py?FormID=sharinginfo&InfoPageName=" + name;
  }
  return open_window(url, "Dataset Info");
};
$('#dataset_info').click(dataset_info);
make_default = function() {
  var holder, item, jholder, _i, _len, _ref;
  alert("The current settings are now your default.")
  holder = {};
  _ref = ['species', 'group', 'type', 'dataset'];
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
    item = _ref[_i];
    holder[item] = $("#" + item).val();
  }
  jholder = JSON.stringify(holder);
  return $.cookie('search_defaults', jholder, {
    expires: 365
  });
};
apply_default = function() {
  var defaults, item, populate_function, _i, _len, _ref, _results;
  defaults = $.cookie('search_defaults');
  if (defaults) {
    defaults = $.parseJSON(defaults);
  } else {
    defaults = {
      species: "mouse",
      group: "BXD",
      type: "Hippocampus mRNA",
      dataset: "HC_M2_0606_P"
    };
  }

  _ref = [['species', 'group'], ['group', 'type'], ['type', 'dataset'], ['dataset', null]];
  _results = [];
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
    item = _ref[_i];
    $("#" + item[0]).val(defaults[item[0]]);
    if (item[1]) {
      populate_function = "populate_" + item[1];
      console.log("Calling:", populate_function);
      _results.push(window[populate_function]());
    } else {
      _results.push(void 0);
    }
  }
  return _results;
};
check_search_term = function() {
  var or_search_term, and_search_term;
  or_search_term = $('#or_search').val();
  and_search_term = $('#and_search').val();
  console.log("or_search_term:", or_search_term);
  console.log("and_search_term:", and_search_term);
  if (or_search_term === "" && and_search_term === "") {
    alert("Please enter one or more search terms or search equations.");
    return false;
  }
};
$("#make_default").click(make_default);
$("#btsearch").click(check_search_term);
<|endoftext|>


<commit_before>genotower.naturalSelector = {

    scoreFitness : function () {

        return genotower.path.getLength();
    },

    evolve : function () {
        var bestScore = genotower.naturalSelector.scoreFitness();

        console.log(genotower.naturalSelector.scoreFitness());
        genotower.path.toggleWaypoints(false);
        genotower.maze.mutate();

        if (bestScore > genotower.naturalSelector.scoreFitness()) {
            genotower.maze.discardMutations();
        }
        genotower.path.toggleWaypoints(true);

        genotower.config.MONSTER_COUNT === 0 ?
                setTimeout(genotower.naturalSelector.evolve, 1) :
                genotower.hoarde.charge();
    },
};

<commit_msg>Removed a comma I accidentally added last commit.<commit_after>genotower.naturalSelector = {

    scoreFitness : function () {

        return genotower.path.getLength();
    },

    evolve : function () {
        var bestScore = genotower.naturalSelector.scoreFitness();

        console.log(genotower.naturalSelector.scoreFitness());
        genotower.path.toggleWaypoints(false);
        genotower.maze.mutate();

        if (bestScore > genotower.naturalSelector.scoreFitness()) {
            genotower.maze.discardMutations();
        }
        genotower.path.toggleWaypoints(true);

        genotower.config.MONSTER_COUNT === 0 ?
                setTimeout(genotower.naturalSelector.evolve, 1) :
                genotower.hoarde.charge();
    }
};

<|endoftext|>


<commit_before>import React from 'react'
import api from 'api'
import { Heading, Label, Input, Text, cx } from '@hackclub/design-system'
import { withFormik } from 'formik'
import yup from 'yup'
import storage from 'storage'
import fetch from 'unfetch'

const StyledInput = Input.extend`
  text-align: inherit;
  background: ${props => props.color};
  color: ${props => cx(props.bg)};
  border: none;
  :focus {
    box-shadow: none !important;
  }
  ::placeholder {
    text-align: inherit;
    color: ${props => cx(props.bg)};
    opacity: 0.5;
  }
`

const InnerForm = ({
  values,
  errors,
  touched,
  handleChange,
  handleBlur,
  handleSubmit,
  isSubmitting,
  userType,
  color,
  bg,
  status,
  inputProps = {},
  textProps = {}
}) => (
  <form onSubmit={handleSubmit}>
    <Label className="email" id="email" mb={0} {...textProps}>
      <Text mb={2} color={color}>
        Enter your email
      </Text>
      <StyledInput
        name="email"
        placeholder="Email address"
        color={color}
        bg={bg}
        value={values.email}
        onChange={e => {
          e.target.value = e.target.value.trim()
          handleChange(e)
        }}
        onBlur={handleBlur}
        disabled={isSubmitting}
        autoComplete="off"
        autoFocus
        {...inputProps}
      />
    </Label>
    {errors.email && (
      <Text
        f={1}
        mt={2}
        align={textProps.align || 'center'}
        children={errors.email || ''}
      />
    )}
  </form>
)

const EmailLoginForm = withFormik({
  mapPropsToValues: ({ email }) => ({ email: email || '' }),
  enableReinitialize: true,
  validateOnChange: false,
  validationSchema: yup.object().shape({
    email: yup.string().email('That doesn’t look like a valid email.')
  }),
  handleSubmit: (data, { props, setSubmitting }) => {
    if (!data.email) {
      setSubmitting(false)
      return null
    }
    api
      .post('v1/users/auth', { data })
      .then(user => {
        storage.set('userId', user.id)
        storage.set('userEmail', user.email)
        setSubmitting(false)
        props.submitCallback({ userId: user.id, email: user.email })
      })
      .catch(e => {
        console.error(e)
        setSubmitting(false)
      })
  },
  displayName: 'EmailLoginForm'
})(InnerForm)

export default EmailLoginForm
<commit_msg>Use API helper for auth components<commit_after>import React from 'react'
import api from 'api'
import { Heading, Label, Input, Text, cx } from '@hackclub/design-system'
import { withFormik } from 'formik'
import yup from 'yup'
import storage from 'storage'
import fetch from 'unfetch'

const StyledInput = Input.extend`
  text-align: inherit;
  background: ${props => props.color};
  color: ${props => cx(props.bg)};
  border: none;
  :focus {
    box-shadow: none !important;
  }
  ::placeholder {
    text-align: inherit;
    color: ${props => cx(props.bg)};
    opacity: 0.5;
  }
`

const InnerForm = ({
  values,
  errors,
  touched,
  handleChange,
  handleBlur,
  handleSubmit,
  isSubmitting,
  userType,
  color,
  bg,
  status,
  inputProps = {},
  textProps = {}
}) => (
  <form onSubmit={handleSubmit}>
    <Label className="email" id="email" mb={0} {...textProps}>
      <Text mb={2} color={color}>
        Enter your email
      </Text>
      <StyledInput
        name="email"
        placeholder="Email address"
        color={color}
        bg={bg}
        value={values.email}
        onChange={e => {
          e.target.value = e.target.value.trim()
          handleChange(e)
        }}
        onBlur={handleBlur}
        disabled={isSubmitting}
        autoComplete="off"
        autoFocus
        {...inputProps}
      />
    </Label>
    {errors.email && (
      <Text
        f={1}
        mt={2}
        align={textProps.align || 'center'}
        children={errors.email || ''}
      />
    )}
  </form>
)

const EmailLoginForm = withFormik({
  mapPropsToValues: ({ email }) => ({ email: email || '' }),
  enableReinitialize: true,
  validateOnChange: false,
  validationSchema: yup.object().shape({
    email: yup.string().email('That doesn’t look like a valid email.')
  }),
  handleSubmit: (data, { props, setSubmitting }) => {
    if (!data.email) {
      setSubmitting(false)
      return null
    }
    api.post('v1/users/auth', { data })
       .then(user => {
         storage.set('userId', user.id)
         storage.set('userEmail', user.email)
         setSubmitting(false)
         props.submitCallback({ userId: user.id, email: user.email })
       })
       .catch(e => {
         console.error(e)
         setSubmitting(false)
       })
  },
  displayName: 'EmailLoginForm'
})(InnerForm)

export default EmailLoginForm
<|endoftext|>


<commit_before>var UI = require('ui');
var Util = require('Util');
var MailActionsList = require('MailActionsList');

var MailMessageCard = function(account, message, messagesList) {
  this.card = new UI.Card({
    title: Util.getMessageFromHeader(message),
    subtitle: Util.getMessageSubjectHeader(message),
    body: Util.decodeHTML(message.snippet),
    scrollable: true
  });

  this.card.on('click', 'select', function() {
    new MailActionsList(account, message, messagesList, this);
  }.bind(this));

  this.card.on('longClick', 'select', function() {
    new MailActionsList(account, message, messagesList, this);
  }.bind(this));

  this.card.show();
};

module.exports = MailMessageCard;
<commit_msg>Shrink message card<commit_after>var UI = require('ui');
var Util = require('Util');
var MailActionsList = require('MailActionsList');

var MailMessageCard = function(account, message, messagesList) {
  console.log(JSON.stringify(message));
  this.card = new UI.Card({
    subtitle: Util.getMessageSubjectHeader(message),
    body: Util.getMessageFromHeader(message) + '\n\n' + Util.decodeHTML(message.snippet),
    scrollable: true,
    style: 'small'
  });

  this.card.on('click', 'select', function() {
    new MailActionsList(account, message, messagesList, this);
  }.bind(this));

  this.card.on('longClick', 'select', function() {
    new MailActionsList(account, message, messagesList, this);
  }.bind(this));

  this.card.show();
};

module.exports = MailMessageCard;
<|endoftext|>


<commit_before>import * as fs from 'fs';
import restify from 'restify';
import {dialog} from 'electron';
import sudo from 'electron-sudo';
import {replace, splitAt} from 'ramda';
import YAML from 'yamljs';

import {setupRoutes} from './routes';
import {serverMessageReceive, CHANNEL} from './messageHandler';

// generic directories
const HOSTS = '/etc/hosts';
const SCRIPTS_DIRECTORY = replace(/\ /g, '\\ ', `${__dirname}`);

// certificates setup
const keyFile = `${__dirname}/../ssl/certs/server/privkey.pem`;
const csrFile = `${__dirname}/../ssl/certs/server/fullchain.pem`;

// scripts
const REDIRECT_CONNECTOR_SCRIPT = `sh  "${SCRIPTS_DIRECTORY}"/../ssl/redirectConnector.sh`;
const CREATE_KEYS_SCRIPT = `sh  "${SCRIPTS_DIRECTORY}"/../ssl/createKeys.sh`;

// running sudo commands options
const SUDO_OPTIONS = {
    name: 'Connector',
    process: {
        options: {
            env: {'VAR': 'VALUE'}
        },
        on: (ps) => {
            ps.stdout.on('data', function() {});
            setTimeout(function() {
                ps.kill();
            }, 50000);
        }
    }
};

const errorMessageBox = (error) => {
    const shortenedMessage = splitAt(500, error.toString())[0];
    return {
        type: 'info',
        buttons: ['OK'],
        message: 'Yikes, an error occurred while setting up' +
            'HTTPS. Create an issue at ' +
            'https://github.com/plotly/plotly-database-connector/issues' +
            'and paste a screen shot of this error message:' +
            `${shortenedMessage}`
    };
};

// accept requests from these domains
export const CONNECTOR_URL = 'connector.plot.ly';
const acceptRequestsFrom = YAML.load(`${__dirname}/acceptedDomains.yaml`);
const addAcceptedDomain = (domain) => {
    acceptRequestsFrom.domains.push(`https://${domain}`);
};

// dialog message to create a https server and ask for password
const httpsMessage = 'Welcome to the Plotly Database Connector! ' +
'To get started we\'ll need your administrator password to set up encrypted ' +
'HTTPS on this app. Behind the scenes we will be running the openssl command ' +
'to generate a self-signed HTTPS certificate.';
let messageShown = false;
const showSudoMessage = (sequelizeManager, OPTIONS) => {
    if (!messageShown) {
        messageShown = true;
        if (OPTIONS.headless) {
            sequelizeManager.log(httpsMessage, 1);
        } else {
            dialog.showMessageBox(
                {type: 'info', buttons: ['OK'], message: httpsMessage}
            );
        }
    }
};

// Check if HTTPS has been setup or not yet
export function findSelfSignedCert() {
    try {
        // try reading certs
        fs.accessSync(keyFile, fs.F_OK);
        fs.accessSync(csrFile, fs.F_OK);
    } catch (e) {
        return false;
    }
    return true;
}

// make available for general scope
let httpServer;
let httpsServer;

export const newOnPremSession = (
    domain, responseTools
) => {
    addAcceptedDomain(domain);
    if (httpServer) {
        httpServer.close();
        setupHTTP(responseTools);
    } else {
        httpsServer.close();
        setupHTTPS(responseTools);
    }
};

// sets up the server itself, called by setupHTTPS() function
const setupSecureRestifyServer = (responseTools) => {

    const {sequelizeManager, OPTIONS} = responseTools;

    const httpsOptions = {
        key: fs.readFileSync(keyFile),
        certificate: fs.readFileSync(csrFile)
    };

    sequelizeManager.log('Closing HTTP server.', 1);
    if (httpServer) {
        httpServer.close();
    }
    httpServer = null;

    httpsServer = restify.createServer(httpsOptions);
    /*
     * parsed content will always be available in req.query,
     * additionally params are merged into req.params
     */
    httpsServer.use(restify.queryParser());
    httpsServer.use(restify.bodyParser({ mapParams: true }));
    httpsServer.use(restify.CORS({
        origins: acceptRequestsFrom.domains,
        credentials: false,
        headers: ['Access-Control-Allow-Origin']
    })).listen(OPTIONS.port);

    /*
     * https://github.com/restify/node-restify/issues/664
     * Handle all OPTIONS requests to a deadend (Allows CORS to work them out)
     */
    httpsServer.opts( /.*/, (req, res) => res.send(204));

    setupRoutes(httpsServer, serverMessageReceive(responseTools));

};

// http

export function setupHTTP(responseTools) {

    httpServer = restify.createServer();
    httpServer.use(restify.queryParser());
    httpServer.use(restify.bodyParser({ mapParams: true }));
    httpServer.use(restify.CORS({
        origins: ['*'],
        credentials: false,
        headers: ['Access-Control-Allow-Origin']
    })).listen(responseTools.OPTIONS.port);
    responseTools.sequelizeManager.log(
        `Listening on port ${responseTools.OPTIONS.port}`, 1
    );
    setupRoutes(httpServer, serverMessageReceive(responseTools));

}

/*
 * Run a couple scripts to generate a self-signed cert
 * and then run the https server.
 * These scripts require sudo and prompt for an admin password
 */

export function setupHTTPS(responseTools) {

    const {sequelizeManager, mainWindow, OPTIONS} = responseTools;
    const log = (args) => sequelizeManager.log(args);

    // 1 - redirect CONNECTOR_URL to localhost
    try {
        log(`checking if ${CONNECTOR_URL} is in /etc/hosts`, 1);
        fs.readFile(HOSTS, function (err, data) {
            if (data.indexOf(CONNECTOR_URL) < 0) {

                showSudoMessage(sequelizeManager, OPTIONS);
                log(`${CONNECTOR_URL} is not in /etc/hosts.`, 1);
                log(`Writing ${CONNECTOR_URL} to /etc/hosts.`, 1);
                sudo.exec(REDIRECT_CONNECTOR_SCRIPT,
                    SUDO_OPTIONS, function(error) {
                    if (error) {
                        dialog.showMessageBox(errorMessageBox(error));
                        log(error, 0);
                    } else {
                        log(`${CONNECTOR_URL} is now redirected to local.`, 1);
                    }
                });
            } else {
                log(`${CONNECTOR_URL} is already in /etc/hosts`, 1);
            }
        });
    } catch (error) {
        log(error, 0);
    }

    // 2 - setup HTTPS server with self signed certs
    try {
        log('Checking if HTTPS certificate and key files already exist', 1);
        // try reading certs
        fs.accessSync(keyFile, fs.F_OK);
        fs.accessSync(csrFile, fs.F_OK);
        log('Certificate and key files already exist.', 1);
        setupSecureRestifyServer(responseTools);
        mainWindow.webContents.send(CHANNEL, {hasSelfSignedCert: true});

    } catch (e) {
        // if error returned, certs do not exist -- let's create them
        log('Certificate and key files do not exist.', 1);
        log('Genearting certificate and key files.', 1);
        showSudoMessage(sequelizeManager, OPTIONS);
        sudo.exec(CREATE_KEYS_SCRIPT, SUDO_OPTIONS,
            function(error) {
                if (error) {
                    dialog.showMessageBox(errorMessageBox(error));
                    log(error, 0);
                } else {
                    log('New key and certificate generated', 1);
                    mainWindow.webContents.send(CHANNEL, {
                        hasSelfSignedCert: true
                    });
                    // setup server with those keys
                    setupSecureRestifyServer(responseTools);
                }
        });

    }
}
<commit_msg>use process.env.PORT if it exists for heroku<commit_after>import * as fs from 'fs';
import restify from 'restify';
import {dialog} from 'electron';
import sudo from 'electron-sudo';
import {replace, splitAt} from 'ramda';
import YAML from 'yamljs';

import {setupRoutes} from './routes';
import {serverMessageReceive, CHANNEL} from './messageHandler';

// generic directories
const HOSTS = '/etc/hosts';
const SCRIPTS_DIRECTORY = replace(/\ /g, '\\ ', `${__dirname}`);

// certificates setup
const keyFile = `${__dirname}/../ssl/certs/server/privkey.pem`;
const csrFile = `${__dirname}/../ssl/certs/server/fullchain.pem`;

// scripts
const REDIRECT_CONNECTOR_SCRIPT = `sh  "${SCRIPTS_DIRECTORY}"/../ssl/redirectConnector.sh`;
const CREATE_KEYS_SCRIPT = `sh  "${SCRIPTS_DIRECTORY}"/../ssl/createKeys.sh`;

// running sudo commands options
const SUDO_OPTIONS = {
    name: 'Connector',
    process: {
        options: {
            env: {'VAR': 'VALUE'}
        },
        on: (ps) => {
            ps.stdout.on('data', function() {});
            setTimeout(function() {
                ps.kill();
            }, 50000);
        }
    }
};

const errorMessageBox = (error) => {
    const shortenedMessage = splitAt(500, error.toString())[0];
    return {
        type: 'info',
        buttons: ['OK'],
        message: 'Yikes, an error occurred while setting up' +
            'HTTPS. Create an issue at ' +
            'https://github.com/plotly/plotly-database-connector/issues' +
            'and paste a screen shot of this error message:' +
            `${shortenedMessage}`
    };
};

// accept requests from these domains
export const CONNECTOR_URL = 'connector.plot.ly';
const acceptRequestsFrom = YAML.load(`${__dirname}/acceptedDomains.yaml`);
const addAcceptedDomain = (domain) => {
    acceptRequestsFrom.domains.push(`https://${domain}`);
};

// dialog message to create a https server and ask for password
const httpsMessage = 'Welcome to the Plotly Database Connector! ' +
'To get started we\'ll need your administrator password to set up encrypted ' +
'HTTPS on this app. Behind the scenes we will be running the openssl command ' +
'to generate a self-signed HTTPS certificate.';
let messageShown = false;
const showSudoMessage = (sequelizeManager, OPTIONS) => {
    if (!messageShown) {
        messageShown = true;
        if (OPTIONS.headless) {
            sequelizeManager.log(httpsMessage, 1);
        } else {
            dialog.showMessageBox(
                {type: 'info', buttons: ['OK'], message: httpsMessage}
            );
        }
    }
};

// Check if HTTPS has been setup or not yet
export function findSelfSignedCert() {
    try {
        // try reading certs
        fs.accessSync(keyFile, fs.F_OK);
        fs.accessSync(csrFile, fs.F_OK);
    } catch (e) {
        return false;
    }
    return true;
}

// make available for general scope
let httpServer;
let httpsServer;

export const newOnPremSession = (
    domain, responseTools
) => {
    addAcceptedDomain(domain);
    if (httpServer) {
        httpServer.close();
        setupHTTP(responseTools);
    } else {
        httpsServer.close();
        setupHTTPS(responseTools);
    }
};

// sets up the server itself, called by setupHTTPS() function
const setupSecureRestifyServer = (responseTools) => {

    const {sequelizeManager, OPTIONS} = responseTools;

    const httpsOptions = {
        key: fs.readFileSync(keyFile),
        certificate: fs.readFileSync(csrFile)
    };

    sequelizeManager.log('Closing HTTP server.', 1);
    if (httpServer) {
        httpServer.close();
    }
    httpServer = null;

    httpsServer = restify.createServer(httpsOptions);
    /*
     * parsed content will always be available in req.query,
     * additionally params are merged into req.params
     */
    httpsServer.use(restify.queryParser());
    httpsServer.use(restify.bodyParser({ mapParams: true }));
    httpsServer.use(restify.CORS({
        origins: acceptRequestsFrom.domains,
        credentials: false,
        headers: ['Access-Control-Allow-Origin']
    })).listen(process.env.PORT || OPTIONS.port);

    /*
     * https://github.com/restify/node-restify/issues/664
     * Handle all OPTIONS requests to a deadend (Allows CORS to work them out)
     */
    httpsServer.opts( /.*/, (req, res) => res.send(204));

    setupRoutes(httpsServer, serverMessageReceive(responseTools));

};

// http

export function setupHTTP(responseTools) {

    httpServer = restify.createServer();
    httpServer.use(restify.queryParser());
    httpServer.use(restify.bodyParser({ mapParams: true }));
    httpServer.use(restify.CORS({
        origins: ['*'],
        credentials: false,
        headers: ['Access-Control-Allow-Origin']
    })).listen(process.env.PORT || responseTools.OPTIONS.port);
    responseTools.sequelizeManager.log(
        `Listening on port ${process.env.PORT || responseTools.OPTIONS.port}`, 1
    );
    setupRoutes(httpServer, serverMessageReceive(responseTools));

}

/*
 * Run a couple scripts to generate a self-signed cert
 * and then run the https server.
 * These scripts require sudo and prompt for an admin password
 */

export function setupHTTPS(responseTools) {

    const {sequelizeManager, mainWindow, OPTIONS} = responseTools;
    const log = (args) => sequelizeManager.log(args);

    // 1 - redirect CONNECTOR_URL to localhost
    try {
        log(`checking if ${CONNECTOR_URL} is in /etc/hosts`, 1);
        fs.readFile(HOSTS, function (err, data) {
            if (data.indexOf(CONNECTOR_URL) < 0) {

                showSudoMessage(sequelizeManager, OPTIONS);
                log(`${CONNECTOR_URL} is not in /etc/hosts.`, 1);
                log(`Writing ${CONNECTOR_URL} to /etc/hosts.`, 1);
                sudo.exec(REDIRECT_CONNECTOR_SCRIPT,
                    SUDO_OPTIONS, function(error) {
                    if (error) {
                        dialog.showMessageBox(errorMessageBox(error));
                        log(error, 0);
                    } else {
                        log(`${CONNECTOR_URL} is now redirected to local.`, 1);
                    }
                });
            } else {
                log(`${CONNECTOR_URL} is already in /etc/hosts`, 1);
            }
        });
    } catch (error) {
        log(error, 0);
    }

    // 2 - setup HTTPS server with self signed certs
    try {
        log('Checking if HTTPS certificate and key files already exist', 1);
        // try reading certs
        fs.accessSync(keyFile, fs.F_OK);
        fs.accessSync(csrFile, fs.F_OK);
        log('Certificate and key files already exist.', 1);
        setupSecureRestifyServer(responseTools);
        mainWindow.webContents.send(CHANNEL, {hasSelfSignedCert: true});

    } catch (e) {
        // if error returned, certs do not exist -- let's create them
        log('Certificate and key files do not exist.', 1);
        log('Genearting certificate and key files.', 1);
        showSudoMessage(sequelizeManager, OPTIONS);
        sudo.exec(CREATE_KEYS_SCRIPT, SUDO_OPTIONS,
            function(error) {
                if (error) {
                    dialog.showMessageBox(errorMessageBox(error));
                    log(error, 0);
                } else {
                    log('New key and certificate generated', 1);
                    mainWindow.webContents.send(CHANNEL, {
                        hasSelfSignedCert: true
                    });
                    // setup server with those keys
                    setupSecureRestifyServer(responseTools);
                }
        });

    }
}
<|endoftext|>


<commit_before>/*eslint-env node*/
'use strict';

var chai  = require('chai');
var chaiAsPromised = require("chai-as-promised");
chai.use(chaiAsPromised);

var assert = chai.assert;
var RSVP = require('rsvp');

describe('s3 plugin', function() {
  var subject;
  var mockUi;
  var context;

  before(function() {
    subject = require('../index');
  });

  beforeEach(function() {
    mockUi = {
      verbose: true,
      messages: [],
      write: function() {},
      writeLine: function(message) {
        this.messages.push(message);
      }
    };

    context = {
      distDir: process.cwd() + '/tests/fixtures/dist',
      distFiles: ['app.css', 'app.js'],
      ui: mockUi,
      uploadClient: {
        upload: function(/* options */) {
          return RSVP.resolve(['app.css', 'app.js']);
        }
      },
      config: {
        s3: {
          accessKeyId: 'aaaa',
          secretAccessKey: 'bbbb',
          sessionToken: 'eeee',
          bucket: 'cccc',
          region: 'dddd',
          profile: 'ffff',
          filePattern: '*.{css,js}',
          acl: 'authenticated-read',
          prefix: '',
          proxy: 'http://user:password@internal.proxy.com',
          distDir: function(context) {
            return context.distDir;
          },
          distFiles: function(context) {
            return context.distFiles || [];
          },
          gzippedFiles: function(context) {
            return context.gzippedFiles || []; // e.g. from ember-cli-deploy-gzip
          },
          manifestPath: function(context) {
            return context.manifestPath; // e.g. from ember-cli-deploy-manifest
          },
          uploadClient: function(context) {
            return context.uploadClient; // if you want to provide your own upload client to be used instead of one from this addon
          },
          s3Client: function(context) {
            return context.s3Client; // if you want to provide your own s3 client to be used instead of one from aws-sdk
          }
        }
      }
    };
  });

  it('has a name', function() {
    var plugin = subject.createDeployPlugin({
      name: 's3'
    });

    assert.equal(plugin.name, 's3');
  });

  it('implements the correct hooks', function() {
    var plugin = subject.createDeployPlugin({
      name: 's3'
    });

    assert.typeOf(plugin.configure, 'function');
    assert.typeOf(plugin.upload, 'function');
  });

  describe('configure hook', function() {
    it('does not throw if config is ok', function() {
      var plugin = subject.createDeployPlugin({
        name: 's3'
      });
      plugin.beforeHook(context);
      plugin.configure(context);
      assert.ok(true); // it didn't throw
    });

    it('throws if config is not valid', function() {
      var plugin = subject.createDeployPlugin({
        name: 's3'
      });

      context.config.s3 = {};

      plugin.beforeHook(context);
      assert.throws(function(){
        plugin.configure(context);
      });
    });

    it('warns about missing optional config', function() {
      delete context.config.s3.filePattern;
      delete context.config.s3.prefix;

      var plugin = subject.createDeployPlugin({
        name: 's3'
      });
      plugin.beforeHook(context);
      plugin.configure(context);
      var messages = mockUi.messages.reduce(function(previous, current) {
        if (/- Missing config:\s.*, using default:\s/.test(current)) {
          previous.push(current);
        }

        return previous;
      }, []);

      assert.equal(messages.length, 6);
    });

    describe('required config', function() {
      it('warns about missing bucket', function() {
        delete context.config.s3.bucket;

        var plugin = subject.createDeployPlugin({
          name: 's3'
        });
        plugin.beforeHook(context);
        assert.throws(function(/* error */){
          plugin.configure(context);
        });
        var messages = mockUi.messages.reduce(function(previous, current) {
          if (/- Missing required config: `bucket`/.test(current)) {
            previous.push(current);
          }

          return previous;
        }, []);

        assert.equal(messages.length, 1);
      });

      it('warns about missing region', function() {
        delete context.config.s3.region;

        var plugin = subject.createDeployPlugin({
          name: 's3'
        });
        plugin.beforeHook(context);
        assert.throws(function(/* error */){
          plugin.configure(context);
        });
        var messages = mockUi.messages.reduce(function(previous, current) {
          if (/- Missing required config: `region`/.test(current)) {
            previous.push(current);
          }

          return previous;
        }, []);

        assert.equal(messages.length, 1);
      });
    });

    it('adds default config to the config object', function() {
      delete context.config.s3.filePattern;
      delete context.config.s3.prefix;
      delete context.config.s3.cacheControl;
      delete context.config.s3.expires;

      assert.isUndefined(context.config.s3.filePattern);
      assert.isUndefined(context.config.s3.prefix);
      assert.isUndefined(context.config.s3.cacheControl);
      assert.isUndefined(context.config.s3.expires);

      var plugin = subject.createDeployPlugin({
        name: 's3'
      });
      plugin.beforeHook(context);
      plugin.configure(context);

      assert.equal(context.config.s3.filePattern, '**/*.{js,css,png,gif,ico,jpg,map,xml,txt,svg,swf,eot,ttf,woff,woff2,otf}');
      assert.equal(context.config.s3.prefix, '');
      assert.equal(context.config.s3.cacheControl, 'max-age=63072000, public');
      assert.equal(new Date(context.config.s3.expires).getTime(), new Date('Tue, 01 Jan 2030 00:00:00 GMT').getTime());
    });
  });

  describe('#upload hook', function() {
    it('prints the begin message', function() {
      var plugin = subject.createDeployPlugin({
        name: 's3'
      });

      plugin.beforeHook(context);
      return assert.isFulfilled(plugin.upload(context))
        .then(function() {
          assert.equal(mockUi.messages.length, 2);
          assert.match(mockUi.messages[0], /preparing to upload to S3 bucket `cccc`/);
        });
    });

    it('prints success message when files successully uploaded', function() {
      var plugin = subject.createDeployPlugin({
        name: 's3'
      });

      plugin.beforeHook(context);
      return assert.isFulfilled(plugin.upload(context))
        .then(function() {
          assert.equal(mockUi.messages.length, 2);

          var messages = mockUi.messages.reduce(function(previous, current) {
            if (/- uploaded 2 files ok/.test(current)) {
              previous.push(current);
            }

            return previous;
          }, []);

          assert.equal(messages.length, 1);
        });
    });

    it('prints an error message if the upload errors', function() {
      var plugin = subject.createDeployPlugin({
        name: 's3'
      });

      context.uploadClient = {
        upload: function(/* opts */) {
          return RSVP.reject(new Error('something bad went wrong'));
        }
      };

      plugin.beforeHook(context);
      return assert.isRejected(plugin.upload(context))
        .then(function() {
          assert.equal(mockUi.messages.length, 3);
          assert.match(mockUi.messages[1], /- Error: something bad went wrong/);
        });
    });

    it('calls proxy agent if a proxy is specified', function() {
      var plugin = subject.createDeployPlugin({
        name: 's3'
      });

      var assertionCount = 0
      context.proxyAgent = function(/* proxy */) {
        assertionCount++;
      };

      plugin.beforeHook(context);
      plugin.configure(context);

      assert.isFulfilled(plugin.upload(context)).then(function(){
        assert.equal(assertionCount, 1);
      });
    });

    it('sets the appropriate header if the file is inclued in gzippedFiles list', function(done) {
      var plugin = subject.createDeployPlugin({
        name: 's3'
      });

      context.gzippedFiles = ['app.css'];
      var assertionCount = 0;
      context.uploadClient = null;
      context.s3Client = {
        putObject: function(params, cb) {
          if (params.Key === 'app.css') {
            assert.equal(params.ContentEncoding, 'gzip');
            assertionCount++;
          } else {
            assert.isUndefined(params.ContentEncoding);
            assertionCount++;
          }
          cb();
        },
        getObject: function(params, cb){
          cb(new Error("File not found"));
        }
      };

      plugin.beforeHook(context);
      assert.isFulfilled(plugin.upload(context)).then(function(){
        assert.equal(assertionCount, 2);
        done();
      }).catch(function(reason){
        done(reason);
      });
    });
  });
});
<commit_msg>Fix failing test<commit_after>/*eslint-env node*/
'use strict';

var chai  = require('chai');
var chaiAsPromised = require("chai-as-promised");
chai.use(chaiAsPromised);

var assert = chai.assert;
var RSVP = require('rsvp');

describe('s3 plugin', function() {
  var subject;
  var mockUi;
  var context;

  before(function() {
    subject = require('../index');
  });

  beforeEach(function() {
    mockUi = {
      verbose: true,
      messages: [],
      write: function() {},
      writeLine: function(message) {
        this.messages.push(message);
      }
    };

    context = {
      distDir: process.cwd() + '/tests/fixtures/dist',
      distFiles: ['app.css', 'app.js'],
      ui: mockUi,
      uploadClient: {
        upload: function(/* options */) {
          return RSVP.resolve(['app.css', 'app.js']);
        }
      },
      config: {
        s3: {
          accessKeyId: 'aaaa',
          secretAccessKey: 'bbbb',
          sessionToken: 'eeee',
          bucket: 'cccc',
          region: 'dddd',
          profile: 'ffff',
          filePattern: '*.{css,js}',
          acl: 'authenticated-read',
          prefix: '',
          proxy: 'http://user:password@internal.proxy.com',
          distDir: function(context) {
            return context.distDir;
          },
          distFiles: function(context) {
            return context.distFiles || [];
          },
          gzippedFiles: function(context) {
            return context.gzippedFiles || []; // e.g. from ember-cli-deploy-gzip
          },
          manifestPath: function(context) {
            return context.manifestPath; // e.g. from ember-cli-deploy-manifest
          },
          uploadClient: function(context) {
            return context.uploadClient; // if you want to provide your own upload client to be used instead of one from this addon
          },
          s3Client: function(context) {
            return context.s3Client; // if you want to provide your own s3 client to be used instead of one from aws-sdk
          }
        }
      }
    };
  });

  it('has a name', function() {
    var plugin = subject.createDeployPlugin({
      name: 's3'
    });

    assert.equal(plugin.name, 's3');
  });

  it('implements the correct hooks', function() {
    var plugin = subject.createDeployPlugin({
      name: 's3'
    });

    assert.typeOf(plugin.configure, 'function');
    assert.typeOf(plugin.upload, 'function');
  });

  describe('configure hook', function() {
    it('does not throw if config is ok', function() {
      var plugin = subject.createDeployPlugin({
        name: 's3'
      });
      plugin.beforeHook(context);
      plugin.configure(context);
      assert.ok(true); // it didn't throw
    });

    it('throws if config is not valid', function() {
      var plugin = subject.createDeployPlugin({
        name: 's3'
      });

      context.config.s3 = {};

      plugin.beforeHook(context);
      assert.throws(function(){
        plugin.configure(context);
      });
    });

    it('warns about missing optional config', function() {
      delete context.config.s3.filePattern;
      delete context.config.s3.prefix;

      var plugin = subject.createDeployPlugin({
        name: 's3'
      });
      plugin.beforeHook(context);
      plugin.configure(context);
      var messages = mockUi.messages.reduce(function(previous, current) {
        if (/- Missing config:\s.*, using default:\s/.test(current)) {
          previous.push(current);
        }

        return previous;
      }, []);

      assert.equal(messages.length, 7);
    });

    describe('required config', function() {
      it('warns about missing bucket', function() {
        delete context.config.s3.bucket;

        var plugin = subject.createDeployPlugin({
          name: 's3'
        });
        plugin.beforeHook(context);
        assert.throws(function(/* error */){
          plugin.configure(context);
        });
        var messages = mockUi.messages.reduce(function(previous, current) {
          if (/- Missing required config: `bucket`/.test(current)) {
            previous.push(current);
          }

          return previous;
        }, []);

        assert.equal(messages.length, 1);
      });

      it('warns about missing region', function() {
        delete context.config.s3.region;

        var plugin = subject.createDeployPlugin({
          name: 's3'
        });
        plugin.beforeHook(context);
        assert.throws(function(/* error */){
          plugin.configure(context);
        });
        var messages = mockUi.messages.reduce(function(previous, current) {
          if (/- Missing required config: `region`/.test(current)) {
            previous.push(current);
          }

          return previous;
        }, []);

        assert.equal(messages.length, 1);
      });
    });

    it('adds default config to the config object', function() {
      delete context.config.s3.filePattern;
      delete context.config.s3.prefix;
      delete context.config.s3.cacheControl;
      delete context.config.s3.expires;

      assert.isUndefined(context.config.s3.filePattern);
      assert.isUndefined(context.config.s3.prefix);
      assert.isUndefined(context.config.s3.cacheControl);
      assert.isUndefined(context.config.s3.expires);

      var plugin = subject.createDeployPlugin({
        name: 's3'
      });
      plugin.beforeHook(context);
      plugin.configure(context);

      assert.equal(context.config.s3.filePattern, '**/*.{js,css,png,gif,ico,jpg,map,xml,txt,svg,swf,eot,ttf,woff,woff2,otf}');
      assert.equal(context.config.s3.prefix, '');
      assert.equal(context.config.s3.cacheControl, 'max-age=63072000, public');
      assert.equal(new Date(context.config.s3.expires).getTime(), new Date('Tue, 01 Jan 2030 00:00:00 GMT').getTime());
    });
  });

  describe('#upload hook', function() {
    it('prints the begin message', function() {
      var plugin = subject.createDeployPlugin({
        name: 's3'
      });

      plugin.beforeHook(context);
      return assert.isFulfilled(plugin.upload(context))
        .then(function() {
          assert.equal(mockUi.messages.length, 2);
          assert.match(mockUi.messages[0], /preparing to upload to S3 bucket `cccc`/);
        });
    });

    it('prints success message when files successully uploaded', function() {
      var plugin = subject.createDeployPlugin({
        name: 's3'
      });

      plugin.beforeHook(context);
      return assert.isFulfilled(plugin.upload(context))
        .then(function() {
          assert.equal(mockUi.messages.length, 2);

          var messages = mockUi.messages.reduce(function(previous, current) {
            if (/- uploaded 2 files ok/.test(current)) {
              previous.push(current);
            }

            return previous;
          }, []);

          assert.equal(messages.length, 1);
        });
    });

    it('prints an error message if the upload errors', function() {
      var plugin = subject.createDeployPlugin({
        name: 's3'
      });

      context.uploadClient = {
        upload: function(/* opts */) {
          return RSVP.reject(new Error('something bad went wrong'));
        }
      };

      plugin.beforeHook(context);
      return assert.isRejected(plugin.upload(context))
        .then(function() {
          assert.equal(mockUi.messages.length, 3);
          assert.match(mockUi.messages[1], /- Error: something bad went wrong/);
        });
    });

    it('calls proxy agent if a proxy is specified', function() {
      var plugin = subject.createDeployPlugin({
        name: 's3'
      });

      var assertionCount = 0
      context.proxyAgent = function(/* proxy */) {
        assertionCount++;
      };

      plugin.beforeHook(context);
      plugin.configure(context);

      assert.isFulfilled(plugin.upload(context)).then(function(){
        assert.equal(assertionCount, 1);
      });
    });

    it('sets the appropriate header if the file is inclued in gzippedFiles list', function(done) {
      var plugin = subject.createDeployPlugin({
        name: 's3'
      });

      context.gzippedFiles = ['app.css'];
      var assertionCount = 0;
      context.uploadClient = null;
      context.s3Client = {
        putObject: function(params, cb) {
          if (params.Key === 'app.css') {
            assert.equal(params.ContentEncoding, 'gzip');
            assertionCount++;
          } else {
            assert.isUndefined(params.ContentEncoding);
            assertionCount++;
          }
          cb();
        },
        getObject: function(params, cb){
          cb(new Error("File not found"));
        }
      };

      plugin.beforeHook(context);
      assert.isFulfilled(plugin.upload(context)).then(function(){
        assert.equal(assertionCount, 2);
        done();
      }).catch(function(reason){
        done(reason);
      });
    });
  });
});
<|endoftext|>


<commit_before>// This file is provided 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.

require.paths.unshift("../lib");

var Riak = require('riak-node')
  assert = require('assert');

var db = new Riak.Client({host: '127.0.0.1', port: 8098, debug: false}),
  bucket = 'riak-js-random-bucket',
  doc = "test",
  doc_json = "test-json",
  content = "this is a test",
  content_json = { a: 1, b: "test", c: false };

db.save(bucket, doc, content, {returnbody: true})(function(response, meta) {
  assert.ok(response);
  assert.notEqual(204, meta.statusCode);

  db.get(bucket, doc)(function(response2) {
    assert.equal(response2, content);
    db.remove(bucket, doc)(function() {
      db.get(bucket, doc)(null, function(r, meta3) {
        assert.equal(404, meta3.statusCode);
      });
    });
  });
});

db.save(bucket, doc_json, content_json)(function(response, meta) {
  assert.equal(204, meta.statusCode);
  db.get(bucket, doc_json)(function(response2, meta2) {
    // check objects and meta (headers)
    // deepEqual response
  });
});

// wait 2 seconds and delete all documents from the test bucket no matter what
var nothing = function() {};

var func = function() { db.get(bucket)(function(resp) {
    resp.keys.forEach(function(key) {
     db.remove(bucket, key)();
    });
  });
}

setTimeout(func, 2000);<commit_msg>update testcase<commit_after>// This file is provided 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.

require.paths.unshift("../lib");

var Riak = require('riak-node')
  assert = require('assert'),
  sys = require('sys');

var db = new Riak.Client({host: '127.0.0.1', port: 8098, debug: false}),
  bucket = 'riak-js-random-bucket',
  doc = "test",
  doc_json = "test-json",
  content = "this is a test",
  content_json = { a: 1, b: "test", c: false },
  content_json_2 = { a: 1, b: "test", c: true };

db.save(bucket, doc, content, {returnbody: true})(function(response, meta) {
  assert.ok(response);
  assert.notEqual(204, meta.statusCode);

  db.get(bucket, doc)(function(response2) {
    assert.equal(response2, content);
    db.remove(bucket, doc)(function() {
      db.get(bucket, doc)(null, function(r, meta3) {
        assert.equal(404, meta3.statusCode);
      });
    });
  });
});

db.save(bucket, doc_json, content_json)(function(response, meta) {
  assert.equal(204, meta.statusCode);
  db.get(bucket, doc_json)(function(response2, meta2) {
    assert.deepEqual(response2, content_json);
    db.save(bucket, doc_json, content_json_2)(function() {
      db.get(bucket, doc_json)(function(response3) {
        assert.deepEqual(response3, content_json_2);
      })
    })
    // check objects and meta (headers)
    // deepEqual response
  });
});

// wait 2 seconds and delete all documents from the test bucket no matter what
var nothing = function() {};

var func = function() { db.get(bucket)(function(resp) {
    resp.keys.forEach(function(key) {
     db.remove(bucket, key)();
    });
  });
}

setTimeout(func, 2000);<|endoftext|>


<commit_before>/**
Gather from the nearest source.
@param {Creep} creep
*/
function gatherFromClosestSource(creep) {
  var sources = creep.room.find(FIND_SOURCES);
  if (creep.harvest(sources[0]) == ERR_NOT_IN_RANGE) {
    creep.moveTo(sources[0], {
      visualizePathStyle: {
        stroke: '#ffaa00'
      }
    });
  }
}

/**
Drop off energy at the closest structure that is not full of energy.
@param {Creep} creep
*/
function dropOffEnergyAtClosestStructure(creep) {
  var targets = creep.room.find(FIND_STRUCTURES, {
    filter: (structure) => {
      return (structure.structureType == STRUCTURE_EXTENSION ||
          structure.structureType == STRUCTURE_SPAWN ||
          structure.structureType == STRUCTURE_TOWER) &&
        structure.energy < structure.energyCapacity;
    }
  });
  if (targets.length > 0) {
    if (creep.transfer(targets[0], RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
      creep.moveTo(targets[0], {
        visualizePathStyle: {
          stroke: '#ffffff'
        }
      });
    }
  }
}

/**
Find the biggest dropped pile of energy in the room and pick it up.
@param {Creep} creep
*/
function pickupBiggestEnergyPile(creep) {
  let droppedResources = creep.room.find(FIND_DROPPED_RESOURCES, {
    filter: {
      resourceType: RESOURCE_ENERGY
    }
  });
  if (droppedResources.length) {
    //determine which pile of resources is biggest
    let biggestResource = droppedResources[0];
    if (droppedResources.length > 1) {
      for (let i = 1; i < droppedResources.length; i++) {
        if (droppedResources[i].amount > biggestResource.amount) {
          biggestResource = droppedResources[i];
        }
      }
    }
    if (creep.pickup(biggestResource) == ERR_NOT_IN_RANGE) {
      creep.moveTo(biggestResource, {
        visualizePathStyle: {
          stroke: '#ffaa00'
        }
      });
    }
  }
}

/**
Upgrade this rooms controller.
@param {Creep} creep
*/
function upgradeRoomController(creep) {
  creep.upgradeController(creep.room.controller);
  if (!creep.pos.isNearTo(creep.room.controller)) {
    creep.moveTo(creep.room.controller, {
      visualizePathStyle: {
        stroke: '#ffffff'
      }
    });
  }
}

/**
Retrieve energy from an upgrader container. If one is not found,
retrieve energy from spawn.
@param {Creep} creep
*/
function retrieveEnergyForUpgrading(creep) {
  let energyStorages = creep.room.find(FIND_MY_STRUCTURES, {
    filter: {
      structureType: STRUCTURE_SPAWN
    }
  });
  if (creep.withdraw(energyStorages[0], RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
    creep.moveTo(energyStorages[0], {
      visualizePathStyle: {
        stroke: '#ffaa00'
      }
    });
  }
}

module.exports = {
  gatherFromClosestSource,
  dropOffEnergyAtClosestStructure,
  pickupBiggestEnergyPile,
  upgradeRoomController,
  retrieveEnergyForUpgrading
};
<commit_msg>Added logic to dropOffEnergyAtClosestStructure for dropping off energy at containers. Added logic to retrieveEnergyForUpgrading() for taking energy from the upgrader container first, if it exists.<commit_after>/**
Gather from the nearest source.
@param {Creep} creep
*/
function gatherFromClosestSource(creep) {
  var sources = creep.room.find(FIND_SOURCES);
  if (creep.harvest(sources[0]) == ERR_NOT_IN_RANGE) {
    creep.moveTo(sources[0], {
      visualizePathStyle: {
        stroke: '#ffaa00'
      }
    });
  }
}

/**
Drop off energy at the closest structure that is not full of energy.
@param {Creep} creep
*/
function dropOffEnergyAtClosestStructure(creep) {
  var targets = creep.room.find(FIND_STRUCTURES, {
    filter: (structure) => {
      return (structure.structureType == STRUCTURE_EXTENSION ||
          structure.structureType == STRUCTURE_SPAWN ||
          structure.structureType == STRUCTURE_TOWER ||
          structure.structureType == STRUCTURE_CONTAINER) &&
        structure.energy < structure.energyCapacity ||
        (structure.store && structure.store[RESOURCE_ENERGY] < structure.storeCapacity);
    }
  });
  console.log(JSON.stringify(targets));
  if (targets.length > 0) {
    if (creep.transfer(targets[0], RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
      creep.moveTo(targets[0], {
        visualizePathStyle: {
          stroke: '#ffffff'
        }
      });
    }
  }
}

/**
Find the biggest dropped pile of energy in the room and pick it up.
@param {Creep} creep
*/
function pickupBiggestEnergyPile(creep) {
  let droppedResources = creep.room.find(FIND_DROPPED_RESOURCES, {
    filter: {
      resourceType: RESOURCE_ENERGY
    }
  });
  if (droppedResources.length) {
    //determine which pile of resources is biggest
    let biggestResource = droppedResources[0];
    if (droppedResources.length > 1) {
      for (let i = 1; i < droppedResources.length; i++) {
        if (droppedResources[i].amount > biggestResource.amount) {
          biggestResource = droppedResources[i];
        }
      }
    }
    if (creep.pickup(biggestResource) == ERR_NOT_IN_RANGE) {
      creep.moveTo(biggestResource, {
        visualizePathStyle: {
          stroke: '#ffaa00'
        }
      });
    }
  }
}

/**
Upgrade this rooms controller.
@param {Creep} creep
*/
function upgradeRoomController(creep) {
  creep.upgradeController(creep.room.controller);
  if (!creep.pos.isNearTo(creep.room.controller)) {
    creep.moveTo(creep.room.controller, {
      visualizePathStyle: {
        stroke: '#ffffff'
      }
    });
  }
}

/**
Retrieve energy from an upgrader container. If one is not found,
retrieve energy from spawn.
@param {Creep} creep
*/
function retrieveEnergyForUpgrading(creep) {
  //check for upContainer first
  let upContainerFlagPos = Memory.flags[creep.room.name + " upContainer"];
  let lookResults = creep.room.lookForAt(LOOK_STRUCTURES,
    upContainerFlagPos.x,
    upContainerFlagPos.y);

  if (lookResults.length) {
    let upContainer = lookResults[0];
    if (creep.withdraw(upContainer, RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
      creep.moveTo(upContainer, {
        visualizePathStyle: {
          stroke: '#ffaa00'
        }
      });
    }
  } else {
    //if not found, check for spawn and retrieve from there.
    let spawns = creep.room.find(FIND_MY_STRUCTURES, {
      filter: {
        structureType: STRUCTURE_SPAWN
      }
    });
    if (creep.withdraw(spawns[0], RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
      creep.moveTo(spawns[0], {
        visualizePathStyle: {
          stroke: '#ffaa00'
        }
      });
    }
  }
}

module.exports = {
  gatherFromClosestSource,
  dropOffEnergyAtClosestStructure,
  pickupBiggestEnergyPile,
  upgradeRoomController,
  retrieveEnergyForUpgrading
};
<|endoftext|>


<commit_before>/**
 * Marionette Routing
 *
 * Copyright © 2015-2016 Luiz Américo Pereira Câmara. All rights reserved.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE.txt file in the root directory of this source tree.
 */

import _ from 'underscore'
import Radio from 'backbone.radio'
import cherrytree from 'cherrytree'
import Route from './route'

let mnRouteMap = Object.create(null)
export const routerChannel = Radio.channel('router')
let router

export function createRouter(options) {
  if (router) {
    throw new Error('Instance of router already created')
  }
  return router = Route.prototype.$router = cherrytree(options)
}

export function destroyRouter(instance) {
  router = null
  Route.prototype.$router = null
  mnRouteMap = Object.create(null)
  instance.destroy()
}

export function getMnRoutes(routes) {
  return routes.map(function (route) {
    return mnRouteMap[route.name]
  })
}

routerChannel.reply('transitionTo', function () {
  return router.transitionTo.apply(router, arguments)
})

routerChannel.reply('isActive', function () {
  return router.isActive.apply(router, arguments)
})

routerChannel.reply('generate', function () {
  return router.generate.apply(router, arguments)
})

routerChannel.reply('goBack', function () {
  //in wait of a better implementation
  history.back();
})

function getChangingIndex(prevRoutes, currentRoutes){
  var index, prev, current;
  const count = Math.max(prevRoutes.length, currentRoutes.length)
  for (index = 0; index < count; index++) {
    prev = prevRoutes[index]
    current = currentRoutes[index]
    if (!(prev && current) || (prev.name !== current.name) || !_.isEqual(prev.params, current.params)) {
      break
    }
  }
  return index
}

function findRouteConfig(routeName, index, routes) {
  let parentRoutes = routes.slice(0, index).reverse().map(function (route) {
    return mnRouteMap[route.name]
  })
  let config
  parentRoutes.some(function (route) {
    let childRoutes = _.result(route, 'childRoutes')
    config = childRoutes && childRoutes[routeName]
    if (_.isFunction(config) && !(config.prototype instanceof Route)) {
      config = config.call(route)
    }
    return config
  })
  return config
}

function createRouteInstance(options, config) {
  if (options.prototype instanceof Route) {
    return new options()
  }
  let routeOptions = _.extend({}, options.routeOptions, _.pick(options, ['viewClass', 'viewOptions']))
  if (options.routeClass) {
    return new options.routeClass(routeOptions, config)
  } else if (options.viewClass || options.abstract) {
    return new Route(routeOptions, config)
  }
}

function createMnRoute(route, index, routes) {
  let instanceConfig = {
    name: route.name,
    path: route.path,
    options: _.clone(route.options)
  }
  let instance = createRouteInstance(route.options, instanceConfig)
  if (!instance) {
    let routeConfig = findRouteConfig(route.name, index, routes)
    return Promise.resolve(routeConfig).then(function (options) {
      return options && createRouteInstance(options, instanceConfig)
    })
  }
  return instance
}

function getParentRegion(routes, route) {
  var region, parent
  let routeIndex = routes.indexOf(route) - 1
  while (routeIndex >= 0) {
    parent = routes[routeIndex]
    if (parent.view && parent.$config.options.outlet !== false) {
      region = parent.getOutlet()
      if (region) {
        return region
      } else {
        throw new Error(`No outlet region defined in ${parent.$config.name} route`)
      }
    }
    routeIndex--
  }
  if (!router.rootRegion) {
    throw new Error('No root outlet region defined')
  }
  return router.rootRegion
}

export function middleware(transition) {

  routerChannel.trigger('before:transition', transition)

  if (transition.isCancelled) return ;

  let prevRoutes = transition.prev.routes
  let changingIndex = getChangingIndex(prevRoutes, transition.routes)
  var routeIndex, routeInstance, deactivated = []

  //deactivate previous routes
  for (routeIndex = prevRoutes.length - 1; routeIndex >= changingIndex; routeIndex--) {
    routeInstance = mnRouteMap[prevRoutes[routeIndex].name]
    if (routeInstance) {
      deactivated.push(routeInstance)
    }
  }

  if (deactivated.some(function (route) {
      routerChannel.trigger('before:deactivate', transition, route)
      return transition.isCancelled
    })) return

  if (deactivated.some(function (route) {
      route.deactivate(transition)
      routerChannel.trigger('deactivate', transition, route)
      return transition.isCancelled
    })) return

  //build route tree and creating instances if necessary
  let mnRoutes = transition.mnRoutes = []

  let promise = transition.routes.reduce(function (acc, route, i, routes) {
    return acc.then(function (res) {
      let instance = mnRouteMap[route.name]
      if (instance) {
        res.push(instance)
        return res
      } else {
        instance = createMnRoute(route, i, routes)
        return Promise.resolve(instance).then(function (mnRoute) {
          if (!mnRoute) {
            throw new Error(`Unable to create route ${route.name}: routeClass or viewClass must be defined`)
          }
          mnRouteMap[route.name] = mnRoute
          res.push(mnRoute)
          return res
        })
      }
    });
  }, Promise.resolve(mnRoutes));

  //activate routes in order
  let activated

  promise = promise.then(function () {
    activated = mnRoutes.slice(changingIndex)
    return activated.reduce(function (prevPromise, mnRoute) {
      routerChannel.trigger('before:activate', transition, mnRoute)
      return prevPromise.then(function () {
        if (!transition.isCancelled) {
          return Promise.resolve(mnRoute.activate(transition)).then(function () {
            if (!transition.isCancelled) {
              routerChannel.trigger('activate', transition, mnRoute)
            }
          })
        }
        return Promise.resolve()
      })
    }, Promise.resolve())
  })

  transition.then(function () {
    router.state.mnRoutes = mnRoutes
    routerChannel.trigger('transition', transition)
  }).catch(function (err) {
    if (err.type !== 'TransitionCancelled' && err.type !== 'TransitionRedirected') {
      routerChannel.trigger('transition:error', transition, err)
    }
  })

  //render views
  return promise.then(function () {
    if (transition.isCancelled) return ;
    //ensure at least the target (last) route is rendered
    if (!activated.length && mnRoutes.length) {
      activated.push(mnRoutes[mnRoutes.length - 1])
    }

    let renderQueue = activated.reduce(function (memo, mnRoute) {
      if (mnRoute.viewClass) {
        if (memo.length && memo[memo.length - 1].$config.options.outlet === false) {
          memo.pop()
        }
        memo.push(mnRoute)
      }
      return memo
    }, [])

    renderQueue.forEach(function (mnRoute) {
      let parentRegion = getParentRegion(mnRoutes, mnRoute)
      mnRoute.renderView(parentRegion, transition)
    })
  })
}<commit_msg>Do not create dummy Route class for abstract routes<commit_after>/**
 * Marionette Routing
 *
 * Copyright © 2015-2016 Luiz Américo Pereira Câmara. All rights reserved.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE.txt file in the root directory of this source tree.
 */

import _ from 'underscore'
import Radio from 'backbone.radio'
import cherrytree from 'cherrytree'
import Route from './route'

let mnRouteMap = Object.create(null)
export const routerChannel = Radio.channel('router')
let router

export function createRouter(options) {
  if (router) {
    throw new Error('Instance of router already created')
  }
  return router = Route.prototype.$router = cherrytree(options)
}

export function destroyRouter(instance) {
  router = null
  Route.prototype.$router = null
  mnRouteMap = Object.create(null)
  instance.destroy()
}

export function getMnRoutes(routes) {
  return routes.map(function (route) {
    return mnRouteMap[route.name]
  })
}

routerChannel.reply('transitionTo', function () {
  return router.transitionTo.apply(router, arguments)
})

routerChannel.reply('isActive', function () {
  return router.isActive.apply(router, arguments)
})

routerChannel.reply('generate', function () {
  return router.generate.apply(router, arguments)
})

routerChannel.reply('goBack', function () {
  //in wait of a better implementation
  history.back();
})

function getChangingIndex(prevRoutes, currentRoutes){
  var index, prev, current;
  const count = Math.max(prevRoutes.length, currentRoutes.length)
  for (index = 0; index < count; index++) {
    prev = prevRoutes[index]
    current = currentRoutes[index]
    if (!(prev && current) || (prev.name !== current.name) || !_.isEqual(prev.params, current.params)) {
      break
    }
  }
  return index
}

function findRouteConfig(routeName, index, routes) {
  let parentRoutes = routes.slice(0, index).reverse().map(function (route) {
    return mnRouteMap[route.name]
  })
  let config
  parentRoutes.some(function (route) {
    let childRoutes = _.result(route, 'childRoutes')
    config = childRoutes && childRoutes[routeName]
    if (_.isFunction(config) && !(config.prototype instanceof Route)) {
      config = config.call(route)
    }
    return config
  })
  return config
}

function createRouteInstance(options, config) {
  if (options.prototype instanceof Route) {
    return new options()
  }
  let routeOptions = _.extend({}, options.routeOptions, _.pick(options, ['viewClass', 'viewOptions']))
  if (options.routeClass) {
    return new options.routeClass(routeOptions, config)
  } else if (options.viewClass) {
    return new Route(routeOptions, config)
  }
}

function createMnRoute(route, index, routes) {
  let instanceConfig = {
    name: route.name,
    path: route.path,
    options: _.clone(route.options)
  }
  let instance = createRouteInstance(route.options, instanceConfig)
  if (!instance) {
    let routeConfig = findRouteConfig(route.name, index, routes)
    return Promise.resolve(routeConfig).then(function (options) {
      return options && createRouteInstance(options, instanceConfig)
    })
  }
  return instance
}

function getParentRegion(routes, route) {
  var region, parent
  let routeIndex = routes.indexOf(route) - 1
  while (routeIndex >= 0) {
    parent = routes[routeIndex]
    if (parent.view && parent.$config.options.outlet !== false) {
      region = parent.getOutlet()
      if (region) {
        return region
      } else {
        throw new Error(`No outlet region defined in ${parent.$config.name} route`)
      }
    }
    routeIndex--
  }
  if (!router.rootRegion) {
    throw new Error('No root outlet region defined')
  }
  return router.rootRegion
}

export function middleware(transition) {

  routerChannel.trigger('before:transition', transition)

  if (transition.isCancelled) return ;

  let prevRoutes = transition.prev.routes
  let changingIndex = getChangingIndex(prevRoutes, transition.routes)
  var routeIndex, routeInstance, deactivated = []

  //deactivate previous routes
  for (routeIndex = prevRoutes.length - 1; routeIndex >= changingIndex; routeIndex--) {
    routeInstance = mnRouteMap[prevRoutes[routeIndex].name]
    if (routeInstance) {
      deactivated.push(routeInstance)
    }
  }

  if (deactivated.some(function (route) {
      routerChannel.trigger('before:deactivate', transition, route)
      return transition.isCancelled
    })) return

  if (deactivated.some(function (route) {
      route.deactivate(transition)
      routerChannel.trigger('deactivate', transition, route)
      return transition.isCancelled
    })) return

  //build route tree and creating instances if necessary
  let mnRoutes = transition.mnRoutes = []

  let promise = transition.routes.reduce(function (acc, route, i, routes) {
    return acc.then(function (res) {
      let instance = mnRouteMap[route.name]
      if (instance) {
        res.push(instance)
        return res
      } else {
        instance = createMnRoute(route, i, routes)
        return Promise.resolve(instance).then(function (mnRoute) {
          if (!mnRoute) {
            throw new Error(`Unable to create route ${route.name}: routeClass or viewClass must be defined`)
          }
          mnRouteMap[route.name] = mnRoute
          res.push(mnRoute)
          return res
        })
      }
    });
  }, Promise.resolve(mnRoutes));

  //activate routes in order
  let activated

  promise = promise.then(function () {
    activated = mnRoutes.slice(changingIndex)
    return activated.reduce(function (prevPromise, mnRoute) {
      routerChannel.trigger('before:activate', transition, mnRoute)
      return prevPromise.then(function () {
        if (!transition.isCancelled) {
          return Promise.resolve(mnRoute.activate(transition)).then(function () {
            if (!transition.isCancelled) {
              routerChannel.trigger('activate', transition, mnRoute)
            }
          })
        }
        return Promise.resolve()
      })
    }, Promise.resolve())
  })

  transition.then(function () {
    router.state.mnRoutes = mnRoutes
    routerChannel.trigger('transition', transition)
  }).catch(function (err) {
    if (err.type !== 'TransitionCancelled' && err.type !== 'TransitionRedirected') {
      routerChannel.trigger('transition:error', transition, err)
    }
  })

  //render views
  return promise.then(function () {
    if (transition.isCancelled) return ;
    //ensure at least the target (last) route is rendered
    if (!activated.length && mnRoutes.length) {
      activated.push(mnRoutes[mnRoutes.length - 1])
    }

    let renderQueue = activated.reduce(function (memo, mnRoute) {
      if (mnRoute.viewClass) {
        if (memo.length && memo[memo.length - 1].$config.options.outlet === false) {
          memo.pop()
        }
        memo.push(mnRoute)
      }
      return memo
    }, [])

    renderQueue.forEach(function (mnRoute) {
      let parentRegion = getParentRegion(mnRoutes, mnRoute)
      mnRoute.renderView(parentRegion, transition)
    })
  })
}<|endoftext|>


<commit_before>var remoteUrl = "http://52.10.162.213/";
var localUrl = "http://127.0.0.1:8000/";
var baseUrl = localUrl;
var user = { userName : "", userId : "", age : "" };

var myHRData;

// Load the Visualization API library and the piechart library.
google.load('visualization', '1.0', {'packages':['corechart']});
// google.setOnLoadCallback(drawAllHRDataChart);

function drawAllHRDataChart () {
     // Create the data table.
      var data = new google.visualization.DataTable();
      data.addColumn('string', 'Topping');
      data.addColumn('number', 'Slices');
      data.addRows([
        ['Mushrooms', 3],
        ['Onions', 1],
        ['Olives', 1],
        ['Zucchini', 1],
        ['Pepperoni', 2]
      ]);

      // Set chart options
      var options = {'title':'How Much Pizza I Ate Last Night',
                     'width':400,
                     'height':300};

      // Instantiate and draw our chart, passing in some options.
      var chart = new google.visualization.PieChart(document.getElementById('chart_div'));
      chart.draw(data, options);
}

function showTile(tileName) {
  $("#tileContent").css("display", "none");
  $(".jumbotron").css("display", "none");

  switch (tileName) {
    case  "sleep":
      showSleepTile();
      break;
    case "fitness":
      showFitnessTile();
      break;
    case "calories":
      showCaloriesTile()
      break;
    case "intensity":
      showIntensityTile();
      break;
    case "otherUsers":
      showOtherUsersTile();
      break;
    case "myData":
      showMyDataTile();
      break;
  }
}

function createUser () {
  $('#newUserModal').modal();
}

function showMyDataTile() {
  //allow for manual entry

  //do a get call to load some amount of the data
  var myDataUrl = baseUrl + "dataSet/entries/28/" + user.userId;

  $.ajax({
    type: "GET",
    url: myDataUrl
  }).done(function(result) {
    console.log("got some data");
    myHRData = result;
    drawAHRGraph("#myDataChart", "#myHRDataTable", "My Heart Rate", myHRData);
  }).fail(function(error){
    console.log("could not get myData");
    console.log(error);
  });

  var toAppend = "<button onclick='goToHomePage()'>❰ Home</button>";
  toAppend += "
My Health Data
";
  toAppend += '<button type="submit" style="margin-left: 70%;" class="btn btn-success" data-toggle="modal" data-target="#manualDataEntryModal">Enter New Data</button>';
  toAppend += '

<button type="button" onclick="showMyHRDataGraph()" id="myHRDataGraphBtn" class="btn active btn-default">Graph</button><button type="button" onclick="showMyHRDataTable()" id="myHRDataTableBtn" class="btn btn-default">Table</button>
'
  toAppend += '

';
  toAppend += "

"

  $("#tileDetail").empty().append(toAppend);
}

function showMyHRDataTable() {
  $("#myHRDataTableBtn").addClass("active")
  $("#myHRDataGraphBtn").removeClass("active")

  drawATable("#myHRDataTable", "#myDataChart", myHRData);
}

function showMyHRDataGraph() {
  $("#myHRDataTableBtn").removeClass("active")
  $("#myHRDataGraphBtn").addClass("active")

  drawAHRGraph("#myDataChart", "#myHRDataTable", "My Heart Rate", myHRData);
}

function drawATable(activate, deactivate, dataSource) {
  $(deactivate).css("display", "none");
  $(activate).css("display", "inline");

  var toAppend = "
";
  toAppend += '
';
  toAppend += '

Date	Heart Rate (bpm)

';
  toAppend += '
';

  var json = dataSource;

  for (i = 0; i < json.length; i++) {
    var date = dateCleaner(json[i]["date_time"]);
    var value = json[i]["value"];
    toAppend += '
' + date + '	' + value + '
'
  }

  toAppend += "

";
  $(activate).empty().append(toAppend);
}

function drawAHRGraph(activate, deactivate, title, dataSource) {
  $(activate).css("display", "inline");
  $(deactivate).css("display", "none");

  var data = new google.visualization.DataTable();

  data.addColumn('string', 'Date');
  data.addColumn('number', 'HR (bpm)');

  var json = dataSource;

  for (i = 0; i < json.length; i++) {
    var date = dateCleaner(json[i]["date_time"]);
    var value = json[i]["value"];
    data.addRows([
      [date, value]
    ]);
  }

  var options = {'title': title, 'width':800, 'height':500};

  //call draw() again for the chart
  var chart = new google.visualization.ColumnChart($(activate)[0]);
  chart.draw(data, options);
}

function showSleepTile() {
  var toAppend = "<button onclick='goToHomePage()'>❰ Home</button>";
  toAppend += "

Sleep Tile Stuff
";

  $("#tileDetail").empty().append(toAppend);
}

function showFitnessTile() {
  //var fitnessUrl = baseUrl + "fitness/" + user.userId;
  var fitnessUrl = baseUrl + "test";
  var fitnessData = {};

  $.ajax({
    type: "GET",
    url: fitnessUrl,
    data: fitnessData
  }).done(function(result) {
    //want to get things like target HR and baseline HR

    console.log(result);

  });

      var toAppend = "<button onclick='goToHomePage()'>❰ Home</button>";
    // toAppend += "

Baseline Heart Rate: " + userFitness.baselineHR + "

Target Heart Rate: " + userFitness.targetHR + "
"
    toAppend += "

Fitness Tile Stuff
";

    $("#tileDetail").empty().append(toAppend);

}

function showCaloriesTile() {
  var toAppend = "<button onclick='goToHomePage()'>❰ Home</button>";
  toAppend += "

Metabolism Tile Stuff
";
  $("#tileDetail").empty().append(toAppend);
}

function showIntensityTile() {
  var lowTargetHR = 50;
  var highTargetHR = 175;
  var maxHR = 200;

  var targetHRRangeUrl = baseUrl + "targetHR";
  var targetAge = { targetAge : user.age };

  $.ajax({
    type: "GET",
    url: targetHRRangeUrl,
    data: targetAge
  }).done(function(result) {
    console.log("got some data");

    lowTargetHR = result["low"];
    highTargetHR = result["high"];
    maxHR = result["max"];

  }).fail(function(error){
    console.log("could not get all user data");
    console.log(error);
  });

  var toAppend = "<button onclick='goToHomePage()'>❰ Home</button>";
  toAppend += "

Target Exercise Intensities
";
  toAppend += "

Lower Heart Rate Target: " + lowTargetHR + " bpm
";
  toAppend += "

Upper Heart Rate Target: " + highTargetHR + " bpm
";
  toAppend += "

Max Heart Rate: " + maxHR + " bpm
";
  toAppend += "

";

  $("#tileDetail").empty().append(toAppend);

  showExerciseIntensityTable();
}

function showExerciseIntensityTable() {
  //create table

  var toAppend = "
";
  toAppend += '
';
  toAppend += '

Intensity	Heart Rate Range

';
  toAppend += '
';

  for (i = 0; i < 5; i++) {
    toAppend += '
' + i + '	' + i + '
'
  }

  toAppend += "

";
  $("#exerciseIntensityRangeTbl").empty().append(toAppend);
}

function showOtherUsersTile() {

  //do a get call to load data about all the users
  var allDataUrl = baseUrl + "dataSet/entries/"

  $.ajax({
    type: "GET",
    url: allDataUrl
  }).done(function(result) {
    console.log("got some data")
    allHRData = result;
    drawAHRGraph("#allHRDataGraph", "#allHRDataTable", "All Heart Rate Data", allHRData);
  }).fail(function(error){
    console.log("could not get all user data")
    console.log(error)
  });

  var toAppend = "<button onclick='goToHomePage()'>❰ Home</button>";
  toAppend += "

All Heartful Users' Data
";
  toAppend += '

<button type="button" onclick="showAllHRDataGraph()" id="allHRDataGraphBtn" class="btn active btn-default">Graph</button><button type="button" onclick="showAllHRDataTable()" id="allHRDataTableBtn" class="btn btn-default">Table</button>
'
  toAppend += "

"
  toAppend += "

"

  $("#tileDetail").empty().append(toAppend);
}

function showAllHRDataTable() {
  $("#allHRDataTableBtn").addClass("active")
  $("#allHRDataGraphBtn").removeClass("active")

  drawATable("#allHRDataTable", "#allHRDataGraph", allHRData);
}

function showAllHRDataGraph() {
  $("#allHRDataGraphBtn").addClass("active")
  $("#allHRDataTableBtn").removeClass("active")

  drawAHRGraph("#allHRDataGraph", "#allHRDataTable", "All Heart Rate Data", allHRData);
}

function goToHomePage() {
  $("#tileContent").css("display", "inherit");
  $(".jumbotron").css("display", "inherit");
  $("#tileDetail").empty();
}

//TODO: Doesn't seem to work!  The /dataSet url accepts the example data on github documentation, but not user entered data -- detail not found
function submitManualData() {
  var hr = $("#manualEntryHR").val();
  var date = $("#manualEntryDate").val();
  var type = $("#manualEntryType").val();
  var id = 28;

  var json = { "googleid" : id, "type" : type, "heartrate_values" : [{ "value" : hr, "unit" : "bpm", "date_time" : date }] };
  var manualDataUrl = baseUrl + "dataSet";

  $.ajax({
    type: "POST",
    url: manualDataUrl,
    data: json
  }).done(function(result) {
      $("#manualEntryHR").val("");
      $("#manualEntryDate").val("2009-07-24 21:45:34-07");
      $("#manualEntryTag").val("sitting");
      $("#manualDataEntryModal").toggle();
  }).fail(function(result) {
    console.log("failed to upload data manually")
  });
}

function signinCallback(authResult) {
  if (authResult['status']['signed_in']) {
      gapi.client.load('plus','v1', function() {
          var request = gapi.client.plus.people.get({
             'userId': 'me'
          });
          request.execute(function(resp) {
            user.userName = resp.displayName;
            user.userId = resp.result.id;
            console.log(user.userName + " " + user.userId);

            //hide sign in button and show name instead
            $("#googleSignInButton").css("display", "none");
            $("#userName").append("
" + user.userName + "
");
          });
      });
  } else {
      console.log('Sign-in state: ' + authResult['error']);
  }
}

function dateCleaner(date) {
  var cleanDate = new Date(date);
  return "" + (cleanDate.getMonth() + 1) + "/" + cleanDate.getDate() + "/" + cleanDate.getFullYear();
}<commit_msg>Code clean up<commit_after>var remoteUrl = "http://52.10.162.213/";
var localUrl = "http://127.0.0.1:8000/";
var baseUrl = localUrl;
var user = { userName : "", userId : "", age : "" };

var myHRData;

// Load the Visualization API library and the piechart library.
google.load('visualization', '1.0', {'packages':['corechart']});

function showTile(tileName) {
  $("#tileContent").css("display", "none");
  $(".jumbotron").css("display", "none");

  switch (tileName) {
    case  "sleep":
      showSleepTile();
      break;
    case "fitness":
      showFitnessTile();
      break;
    case "calories":
      showCaloriesTile()
      break;
    case "intensity":
      showIntensityTile();
      break;
    case "otherUsers":
      showOtherUsersTile();
      break;
    case "myData":
      showMyDataTile();
      break;
  }
}

function createUser () {
  $('#newUserModal').modal();
}

function showMyDataTile() {
  //allow for manual entry

  //do a get call to load some amount of the data
  var myDataUrl = baseUrl + "dataSet/entries/28/" + user.userId;

  $.ajax({
    type: "GET",
    url: myDataUrl
  }).done(function(result) {
    console.log("got some data");
    myHRData = result;
    drawAHRGraph("#myDataChart", "#myHRDataTable", "My Heart Rate", myHRData);
  }).fail(function(error){
    console.log("could not get myData");
    console.log(error);
  });

  var toAppend = "<button onclick='goToHomePage()'>❰ Home</button>";
  toAppend += "
My Health Data
";
  toAppend += '<button type="submit" style="margin-left: 70%;" class="btn btn-success" data-toggle="modal" data-target="#manualDataEntryModal">Enter New Data</button>';
  toAppend += '

<button type="button" onclick="showMyHRDataGraph()" id="myHRDataGraphBtn" class="btn active btn-default">Graph</button><button type="button" onclick="showMyHRDataTable()" id="myHRDataTableBtn" class="btn btn-default">Table</button>
'
  toAppend += '

';
  toAppend += "

"

  $("#tileDetail").empty().append(toAppend);
}

function showMyHRDataTable() {
  $("#myHRDataTableBtn").addClass("active")
  $("#myHRDataGraphBtn").removeClass("active")

  drawATable("#myHRDataTable", "#myDataChart", myHRData);
}

function showMyHRDataGraph() {
  $("#myHRDataTableBtn").removeClass("active")
  $("#myHRDataGraphBtn").addClass("active")

  drawAHRGraph("#myDataChart", "#myHRDataTable", "My Heart Rate", myHRData);
}

function drawATable(activate, deactivate, dataSource) {
  $(deactivate).css("display", "none");
  $(activate).css("display", "inline");

  var toAppend = "
";
  toAppend += '
';
  toAppend += '

Date	Heart Rate (bpm)

';
  toAppend += '
';

  var json = dataSource;

  for (i = 0; i < json.length; i++) {
    var date = dateCleaner(json[i]["date_time"]);
    var value = json[i]["value"];
    toAppend += '
' + date + '	' + value + '
'
  }

  toAppend += "

";
  $(activate).empty().append(toAppend);
}

function drawAHRGraph(activate, deactivate, title, dataSource) {
  $(activate).css("display", "inline");
  $(deactivate).css("display", "none");

  var data = new google.visualization.DataTable();

  data.addColumn('string', 'Date');
  data.addColumn('number', 'HR (bpm)');

  var json = dataSource;

  for (i = 0; i < json.length; i++) {
    var date = dateCleaner(json[i]["date_time"]);
    var value = json[i]["value"];
    data.addRows([
      [date, value]
    ]);
  }

  var options = {'title': title, 'width':800, 'height':500};

  //call draw() again for the chart
  var chart = new google.visualization.ColumnChart($(activate)[0]);
  chart.draw(data, options);
}

function showSleepTile() {
  var toAppend = "<button onclick='goToHomePage()'>❰ Home</button>";
  toAppend += "

Sleep Tile Stuff
";

  $("#tileDetail").empty().append(toAppend);
}

function showFitnessTile() {
  //var fitnessUrl = baseUrl + "fitness/" + user.userId;
  var fitnessUrl = baseUrl + "test";
  var fitnessData = {};

  $.ajax({
    type: "GET",
    url: fitnessUrl,
    data: fitnessData
  }).done(function(result) {
    //want to get things like target HR and baseline HR

    console.log(result);

  });

      var toAppend = "<button onclick='goToHomePage()'>❰ Home</button>";
    // toAppend += "

Baseline Heart Rate: " + userFitness.baselineHR + "

Target Heart Rate: " + userFitness.targetHR + "
"
    toAppend += "

Fitness Tile Stuff
";

    $("#tileDetail").empty().append(toAppend);

}

function showCaloriesTile() {
  var toAppend = "<button onclick='goToHomePage()'>❰ Home</button>";
  toAppend += "

Metabolism Tile Stuff
";
  $("#tileDetail").empty().append(toAppend);
}

function showIntensityTile() {
  var lowTargetHR = 50;
  var highTargetHR = 175;
  var maxHR = 200;

  var targetHRRangeUrl = baseUrl + "targetHR";
  var targetAge = { targetAge : user.age };

  $.ajax({
    type: "GET",
    url: targetHRRangeUrl,
    data: targetAge
  }).done(function(result) {
    console.log("got some data");

    lowTargetHR = result["low"];
    highTargetHR = result["high"];
    maxHR = result["max"];

  }).fail(function(error){
    console.log("could not get all user data");
    console.log(error);
  });

  var toAppend = "<button onclick='goToHomePage()'>❰ Home</button>";
  toAppend += "

Target Exercise Intensities
";
  toAppend += "

Lower Heart Rate Target: " + lowTargetHR + " bpm
";
  toAppend += "

Upper Heart Rate Target: " + highTargetHR + " bpm
";
  toAppend += "

Max Heart Rate: " + maxHR + " bpm
";
  toAppend += "

";

  $("#tileDetail").empty().append(toAppend);

  showExerciseIntensityTable();
}

function showExerciseIntensityTable() {
  //create table

  var toAppend = "
";
  toAppend += '
';
  toAppend += '

Intensity	Heart Rate Range

';
  toAppend += '
';

  for (i = 0; i < 5; i++) {
    toAppend += '
' + i + '	' + i + '
'
  }

  toAppend += "

";
  $("#exerciseIntensityRangeTbl").empty().append(toAppend);
}

function showOtherUsersTile() {

  //do a get call to load data about all the users
  var allDataUrl = baseUrl + "dataSet/entries/"

  $.ajax({
    type: "GET",
    url: allDataUrl
  }).done(function(result) {
    console.log("got some data")
    allHRData = result;
    drawAHRGraph("#allHRDataGraph", "#allHRDataTable", "All Heart Rate Data", allHRData);
  }).fail(function(error){
    console.log("could not get all user data")
    console.log(error)
  });

  var toAppend = "<button onclick='goToHomePage()'>❰ Home</button>";
  toAppend += "

All Heartful Users' Data
";
  toAppend += '

<button type="button" onclick="showAllHRDataGraph()" id="allHRDataGraphBtn" class="btn active btn-default">Graph</button><button type="button" onclick="showAllHRDataTable()" id="allHRDataTableBtn" class="btn btn-default">Table</button>
'
  toAppend += "

"
  toAppend += "

"

  $("#tileDetail").empty().append(toAppend);
}

function showAllHRDataTable() {
  $("#allHRDataTableBtn").addClass("active")
  $("#allHRDataGraphBtn").removeClass("active")

  drawATable("#allHRDataTable", "#allHRDataGraph", allHRData);
}

function showAllHRDataGraph() {
  $("#allHRDataGraphBtn").addClass("active")
  $("#allHRDataTableBtn").removeClass("active")

  drawAHRGraph("#allHRDataGraph", "#allHRDataTable", "All Heart Rate Data", allHRData);
}

function goToHomePage() {
  $("#tileContent").css("display", "inherit");
  $(".jumbotron").css("display", "inherit");
  $("#tileDetail").empty();
}

//TODO: Doesn't seem to work!  The /dataSet url accepts the example data on github documentation, but not user entered data -- detail not found
function submitManualData() {
  var hr = $("#manualEntryHR").val();
  var date = $("#manualEntryDate").val();
  var type = $("#manualEntryType").val();
  var id = 28;

  var json = { "googleid" : id, "type" : type, "heartrate_values" : [{ "value" : hr, "unit" : "bpm", "date_time" : date }] };
  var manualDataUrl = baseUrl + "dataSet";

  $.ajax({
    type: "POST",
    url: manualDataUrl,
    data: json
  }).done(function(result) {
      $("#manualEntryHR").val("");
      $("#manualEntryDate").val("2009-07-24 21:45:34-07");
      $("#manualEntryTag").val("sitting");
      $("#manualDataEntryModal").toggle();
  }).fail(function(result) {
    console.log("failed to upload data manually")
  });
}

function signinCallback(authResult) {
  if (authResult['status']['signed_in']) {
      gapi.client.load('plus','v1', function() {
          var request = gapi.client.plus.people.get({
             'userId': 'me'
          });
          request.execute(function(resp) {
            user.userName = resp.displayName;
            user.userId = resp.result.id;
            console.log(user.userName + " " + user.userId);

            //hide sign in button and show name instead
            $("#googleSignInButton").css("display", "none");
            $("#userName").append("
" + user.userName + "
");
          });
      });
  } else {
      console.log('Sign-in state: ' + authResult['error']);
  }
}

function dateCleaner(date) {
  var cleanDate = new Date(date);
  return "" + (cleanDate.getMonth() + 1) + "/" + cleanDate.getDate() + "/" + cleanDate.getFullYear();
}<|endoftext|>