<commit_before>import { all, call, put, select, takeEvery } from 'redux-saga/effects';
import { showNotification } from 'controllers/notification';
import { NOTIFICATION_TYPES } from 'controllers/notification/constants';
import { redirect } from 'redux-first-router';
import { URLS } from 'common/urls';
import { fetchDataAction } from 'controllers/fetch';
import { activeProjectSelector, userIdSelector } from 'controllers/user';
import { hideModalAction } from 'controllers/modal';
import { fetch, setStorageItem } from 'common/utils';
import {
  PROJECT_DASHBOARD_ITEM_PAGE,
  PROJECT_DASHBOARD_PAGE,
  activeDashboardIdSelector,
  pageSelector,
  projectIdSelector,
} from 'controllers/pages';
import {
  ADD_DASHBOARD,
  CHANGE_VISIBILITY_TYPE,
  DASHBOARDS_VISIBILITY_TYPE_STORAGE_KEY,
  FETCH_DASHBOARD,
  FETCH_DASHBOARDS,
  NAMESPACE,
  REMOVE_DASHBOARD,
  UPDATE_DASHBOARD,
  UPDATE_DASHBOARD_WIDGETS,
  REMOVE_DASHBOARD_SUCCESS,
} from './constants';
import { querySelector } from './selectors';
import {
  addDashboardSuccessAction,
  deleteDashboardSuccessAction,
  updateDashboardItemSuccessAction,
} from './actionCreators';

function* fetchDashboards({ payload: params }) {
  const activeProject = yield select(activeProjectSelector);
  const query = yield select(querySelector);

  yield put(
    fetchDataAction(NAMESPACE)(URLS.dashboards(activeProject), {
      params: {
        ...query,
        ...params,
      },
    }),
  );
}

function* fetchDashboard() {
  const activeProject = yield select(activeProjectSelector);
  const activeDashboardId = yield select(activeDashboardIdSelector);
  const dashboard = yield call(fetch, URLS.dashboard(activeProject, activeDashboardId));

  yield put(updateDashboardItemSuccessAction(dashboard));
}

function* addDashboard({ payload: dashboard }) {
  const activeProject = yield select(activeProjectSelector);
  const owner = yield select(userIdSelector);
  const { id } = yield call(fetch, URLS.dashboards(activeProject), {
    method: 'post',
    data: dashboard,
  });

  yield put(addDashboardSuccessAction({ id, owner, ...dashboard }));
  yield put(
    showNotification({
      messageId: 'addDashboardSuccess',
      type: NOTIFICATION_TYPES.SUCCESS,
    }),
  );
  yield put(hideModalAction());
  yield put({
    type: PROJECT_DASHBOARD_ITEM_PAGE,
    payload: { projectId: activeProject, dashboardId: id },
  });
}

function* updateDashboard({ payload: dashboard }) {
  const activeProject = yield select(activeProjectSelector);
  const { name, description, share, id } = dashboard;

  yield call(fetch, URLS.dashboard(activeProject, id), {
    method: 'put',
    data: { name, description, share },
  });
  yield put(updateDashboardItemSuccessAction(dashboard));
}

function* updateDashboardWidgets({ payload: dashboard }) {
  const activeProject = yield select(activeProjectSelector);

  yield call(fetch, URLS.dashboard(activeProject, dashboard.id), {
    method: 'put',
    data: {
      updateWidgets: dashboard.widgets,
    },
  });
  yield put(updateDashboardItemSuccessAction(dashboard));
}

function* removeDashboard({ payload: id }) {
  const activeProject = yield select(activeProjectSelector);

  yield call(fetch, URLS.dashboard(activeProject, id), {
    method: 'delete',
  });
  yield put(deleteDashboardSuccessAction(id));
}

function* redirectAfterDelete({ payload: dashboardId }) {
  const activePage = yield select(pageSelector);
  if (activePage === PROJECT_DASHBOARD_ITEM_PAGE) {
    const activeDashboardId = yield select(activeDashboardIdSelector);
    if (activeDashboardId === dashboardId) {
      const activeProject = yield select(projectIdSelector);
      yield put(hideModalAction());
      yield put(
        redirect({
          type: PROJECT_DASHBOARD_PAGE,
          payload: { projectId: activeProject },
        }),
      );
    }
  }
}

function changeVisibilityType({ payload: visibilityType }) {
  setStorageItem(DASHBOARDS_VISIBILITY_TYPE_STORAGE_KEY, visibilityType);
}

export function* dashboardSagas() {
  yield all([
    yield takeEvery(FETCH_DASHBOARDS, fetchDashboards),
    yield takeEvery(FETCH_DASHBOARD, fetchDashboard),
    yield takeEvery(ADD_DASHBOARD, addDashboard),
    yield takeEvery(UPDATE_DASHBOARD, updateDashboard),
    yield takeEvery(UPDATE_DASHBOARD_WIDGETS, updateDashboardWidgets),
    yield takeEvery(REMOVE_DASHBOARD, removeDashboard),
    yield takeEvery(CHANGE_VISIBILITY_TYPE, changeVisibilityType),
    yield takeEvery(REMOVE_DASHBOARD_SUCCESS, redirectAfterDelete),
  ]);
}
<commit_msg>EPMRPP-39594 Fix update dashboard request<commit_after>import { all, call, put, select, takeEvery } from 'redux-saga/effects';
import { showNotification } from 'controllers/notification';
import { NOTIFICATION_TYPES } from 'controllers/notification/constants';
import { redirect } from 'redux-first-router';
import { URLS } from 'common/urls';
import { fetchDataAction } from 'controllers/fetch';
import { activeProjectSelector, userIdSelector } from 'controllers/user';
import { hideModalAction } from 'controllers/modal';
import { fetch, setStorageItem } from 'common/utils';
import {
  PROJECT_DASHBOARD_ITEM_PAGE,
  PROJECT_DASHBOARD_PAGE,
  activeDashboardIdSelector,
  pageSelector,
  projectIdSelector,
} from 'controllers/pages';
import {
  ADD_DASHBOARD,
  CHANGE_VISIBILITY_TYPE,
  DASHBOARDS_VISIBILITY_TYPE_STORAGE_KEY,
  FETCH_DASHBOARD,
  FETCH_DASHBOARDS,
  NAMESPACE,
  REMOVE_DASHBOARD,
  UPDATE_DASHBOARD,
  UPDATE_DASHBOARD_WIDGETS,
  REMOVE_DASHBOARD_SUCCESS,
} from './constants';
import { querySelector } from './selectors';
import {
  addDashboardSuccessAction,
  deleteDashboardSuccessAction,
  updateDashboardItemSuccessAction,
} from './actionCreators';

function* fetchDashboards({ payload: params }) {
  const activeProject = yield select(activeProjectSelector);
  const query = yield select(querySelector);

  yield put(
    fetchDataAction(NAMESPACE)(URLS.dashboards(activeProject), {
      params: {
        ...query,
        ...params,
      },
    }),
  );
}

function* fetchDashboard() {
  const activeProject = yield select(activeProjectSelector);
  const activeDashboardId = yield select(activeDashboardIdSelector);
  const dashboard = yield call(fetch, URLS.dashboard(activeProject, activeDashboardId));

  yield put(updateDashboardItemSuccessAction(dashboard));
}

function* addDashboard({ payload: dashboard }) {
  const activeProject = yield select(activeProjectSelector);
  const owner = yield select(userIdSelector);
  const { id } = yield call(fetch, URLS.dashboards(activeProject), {
    method: 'post',
    data: dashboard,
  });

  yield put(addDashboardSuccessAction({ id, owner, ...dashboard }));
  yield put(
    showNotification({
      messageId: 'addDashboardSuccess',
      type: NOTIFICATION_TYPES.SUCCESS,
    }),
  );
  yield put(hideModalAction());
  yield put({
    type: PROJECT_DASHBOARD_ITEM_PAGE,
    payload: { projectId: activeProject, dashboardId: id },
  });
}

function* updateDashboard({ payload: dashboard }) {
  const activeProject = yield select(activeProjectSelector);
  const { name, description, share, id } = dashboard;

  yield call(fetch, URLS.dashboard(activeProject, id), {
    method: 'put',
    data: { name, description, share },
  });
  yield put(updateDashboardItemSuccessAction(dashboard));
}

function* updateDashboardWidgets({ payload: dashboard }) {
  const activeProject = yield select(activeProjectSelector);

  yield call(fetch, URLS.dashboard(activeProject, dashboard.id), {
    method: 'put',
    data: {
      name: dashboard.name,
      updateWidgets: dashboard.widgets,
    },
  });
  yield put(updateDashboardItemSuccessAction(dashboard));
}

function* removeDashboard({ payload: id }) {
  const activeProject = yield select(activeProjectSelector);

  yield call(fetch, URLS.dashboard(activeProject, id), {
    method: 'delete',
  });
  yield put(deleteDashboardSuccessAction(id));
}

function* redirectAfterDelete({ payload: dashboardId }) {
  const activePage = yield select(pageSelector);
  if (activePage === PROJECT_DASHBOARD_ITEM_PAGE) {
    const activeDashboardId = yield select(activeDashboardIdSelector);
    if (activeDashboardId === dashboardId) {
      const activeProject = yield select(projectIdSelector);
      yield put(hideModalAction());
      yield put(
        redirect({
          type: PROJECT_DASHBOARD_PAGE,
          payload: { projectId: activeProject },
        }),
      );
    }
  }
}

function changeVisibilityType({ payload: visibilityType }) {
  setStorageItem(DASHBOARDS_VISIBILITY_TYPE_STORAGE_KEY, visibilityType);
}

export function* dashboardSagas() {
  yield all([
    yield takeEvery(FETCH_DASHBOARDS, fetchDashboards),
    yield takeEvery(FETCH_DASHBOARD, fetchDashboard),
    yield takeEvery(ADD_DASHBOARD, addDashboard),
    yield takeEvery(UPDATE_DASHBOARD, updateDashboard),
    yield takeEvery(UPDATE_DASHBOARD_WIDGETS, updateDashboardWidgets),
    yield takeEvery(REMOVE_DASHBOARD, removeDashboard),
    yield takeEvery(CHANGE_VISIBILITY_TYPE, changeVisibilityType),
    yield takeEvery(REMOVE_DASHBOARD_SUCCESS, redirectAfterDelete),
  ]);
}
<|endoftext|>


<commit_before>'use strict';

var _         = require('lodash');
var d3        = require('d3');
var moment    = require('moment');
var React     = require('react');

var browser   = require('util/browser');
var colors    = require('colors');
var data      = require('util/data');
var format    = require('util/format');
var hoverLine = require('component/chart/behavior/hover-line');
var label     = require('component/chart/renderer/label');

var DEFAULTS = {
	margin  : {
		top    : 12,
		right  : 0,
		bottom : 12,
		left   : 0
	},
	scale      : d3.scale.linear,
	seriesName : _.property('name'),
	x          : _.property('x'),
	xFormat    : format.timeAxis,
	y          : _.property('y'),
	yFormat    : d3.format(',d')
};

function LineChart() {}

_.extend(LineChart.prototype, {
	defaults : DEFAULTS,

	update : function (series, options) {
		options = _.assign(this._options, options);

		var margin = options.margin

	  var svg    = this._svg;
	  var width  = this._width - margin.left - margin.right;
	  var height = this._height - margin.top - margin.bottom;

	  var color = options.colors;

	  if (!_.isFunction(color)) {
	  	var colorScale = d3.scale.ordinal()
	  		.domain(_.map(series, options.seriesName))
	  		.range(colors);

	  	color = _.flow(options.seriesName, colorScale);
	  }

	  var domain = _.isFunction(options.domain) ?
	  	options.domain(series) :
	  	d3.extent(_(series)
	  		.map(options.values)
	  		.flatten()
	  		.map(options.x)
	  		.value());

	  var xScale = d3.time.scale()
	  	.domain(domain)
	  	.range([0, width]);

	  var range = _.isFunction(options.range) ?
	  	options.range(series) :
	  	d3.extent(_(series)
	  			.map(options.values)
	  			.flatten()
	  			.map(options.y)
	  			.value());

	  range[0] = Math.min(range[0], 0);

	  var yScale = options.scale()
	  	.domain(range)
	  	.range([height, 0]);

	  var x = _.flow(options.x, xScale);
	  var y = _.flow(options.y, yScale);

	  // Set up the hover interaction
	  svg.attr('class', 'line')
	  	.call(hoverLine()
				.width(width)
				.height(height)
				.top(-margin.top)
				.xFormat(options.xFormat)
				.yFormat(options.yFormat)
				.x(options.x)
				.y(options.y)
				.xScale(xScale)
				.yScale(yScale)
				.value(options.y)
				.seriesName(_.property('seriesName'))
				.sort(true)
				.datapoints(_(series).map(function (s) {
						// Set the series name on each datapoint for easy retrieval
						return _.map(options.values(s), _.partial(_.set, _, 'seriesName', options.seriesName(s)));
					})
					.flatten()
					.value()
				)
			);

	  var g = svg.select('.data')
	    .selectAll('.series')
	    .data(series, options.seriesName);

	  g.enter()
	    .append('g')
	    .attr('class', 'series');

	  g.style({
	    'fill'   : color,
	    'stroke' : color
	  });

	  g.exit().remove();

	  var path = g.selectAll('path')
	    .data(function (d) { return [options.values(d)]; });

	  path.enter().append('path');

	  path.transition()
	    .duration(500)
	    .attr('d', d3.svg.line().x(x).y(y))

	  var point = g.selectAll('circle')
	    .data(options.values);

	  point.enter()
	    .append('circle')
	    .attr({
	      'cx' : x,
	      'cy' : y,
	      'r'  : 0
	    });

	  point.transition()
	    .duration(500)
	    .attr({
	      'cx' : x,
	      'cy' : y,
	      'r'  : 3
	    });

	  point.exit()
	    .transition()
	    .duration(500)
	    .attr('r', 0)
	    .remove();

	  var labels = _(series)
	    .map(function (d) {
	      var last = _.max(options.values(d), options.x);
	      var v    = options.y(last);

	      return {
	        text    : options.seriesName(d) + ' ' + v,
	        x       : x(last),
	        y       : y(last),
	        defined : _.isFinite(v)
	      };
	    })
	    .filter('defined')
	    .sortBy('y')
	    .value();

	  svg.select('.annotation')
	    .selectAll('.series.label')
	    .data(labels)
	    .call(label()
	      .addClass('series')
	      .width(width)
	      .height(height)
	      .align(false));

	  var gx = svg.select('.x.axis')
	    .call(d3.svg.axis()
	      .tickFormat(options.xFormat)
	      .outerTickSize(0)
	      .ticks(4)
	      .scale(xScale)
	      .orient('bottom'));

	  // Prevent labels from overflowing the left and right edges of the SVG
	  var svgBox = svg.node().getBoundingClientRect();
	  gx.selectAll('text')
	   .attr('dx', function () {
	     var bbox = this.getBoundingClientRect();
	     var dx = null;

	     if (bbox.right > svgBox.right) {
	       dx = svgBox.right - bbox.right;
	     }

	     if (bbox.left < svgBox.left) {
	       dx = svgBox.left - bbox.left;
	     }

	     return dx;
	   });

	  var gy = svg.select('.y.axis')
	    .call(d3.svg.axis()
	      .tickFormat(options.yFormat)
	      .tickSize(width)
	      .ticks(3)
	      .scale(yScale)
	      .orient('right'));

	  gy.selectAll('text')
	    .attr({
				'x'  : 4,
				'dy' : -4
	    });

	  gy.selectAll('g').classed('minor', function (d) {
	    return d !== range[0];
	  });
	}
});

module.exports = LineChart;
<commit_msg>Format the label in the line charts<commit_after>'use strict';

var _         = require('lodash');
var d3        = require('d3');
var moment    = require('moment');
var React     = require('react');

var browser   = require('util/browser');
var colors    = require('colors');
var data      = require('util/data');
var format    = require('util/format');
var hoverLine = require('component/chart/behavior/hover-line');
var label     = require('component/chart/renderer/label');

var DEFAULTS = {
	margin  : {
		top    : 12,
		right  : 0,
		bottom : 12,
		left   : 0
	},
	scale      : d3.scale.linear,
	seriesName : _.property('name'),
	x          : _.property('x'),
	xFormat    : format.timeAxis,
	y          : _.property('y'),
	yFormat    : d3.format(',d')
};

function LineChart() {}

_.extend(LineChart.prototype, {
	defaults : DEFAULTS,

	update : function (series, options) {
		options = _.assign(this._options, options);

		var margin = options.margin

	  var svg    = this._svg;
	  var width  = this._width - margin.left - margin.right;
	  var height = this._height - margin.top - margin.bottom;

	  var color = options.colors;

	  if (!_.isFunction(color)) {
	  	var colorScale = d3.scale.ordinal()
	  		.domain(_.map(series, options.seriesName))
	  		.range(colors);

	  	color = _.flow(options.seriesName, colorScale);
	  }

	  var domain = _.isFunction(options.domain) ?
	  	options.domain(series) :
	  	d3.extent(_(series)
	  		.map(options.values)
	  		.flatten()
	  		.map(options.x)
	  		.value());

	  var xScale = d3.time.scale()
	  	.domain(domain)
	  	.range([0, width]);

	  var range = _.isFunction(options.range) ?
	  	options.range(series) :
	  	d3.extent(_(series)
	  			.map(options.values)
	  			.flatten()
	  			.map(options.y)
	  			.value());

	  range[0] = Math.min(range[0], 0);

	  var yScale = options.scale()
	  	.domain(range)
	  	.range([height, 0]);

	  var x = _.flow(options.x, xScale);
	  var y = _.flow(options.y, yScale);

	  // Set up the hover interaction
	  svg.attr('class', 'line')
	  	.call(hoverLine()
				.width(width)
				.height(height)
				.xFormat(options.xFormat)
				.yFormat(options.yFormat)
				.x(options.x)
				.y(options.y)
				.xScale(xScale)
				.yScale(yScale)
				.value(options.y)
				.seriesName(_.property('seriesName'))
				.sort(true)
				.datapoints(_(series).map(function (s) {
						// Set the series name on each datapoint for easy retrieval
						return _.map(options.values(s), _.partial(_.set, _, 'seriesName', options.seriesName(s)));
					})
					.flatten()
					.value()
				)
			);

	  var g = svg.select('.data')
	    .selectAll('.series')
	    .data(series, options.seriesName);

	  g.enter()
	    .append('g')
	    .attr('class', 'series');

	  g.style({
	    'fill'   : color,
	    'stroke' : color
	  });

	  g.exit().remove();

	  var path = g.selectAll('path')
	    .data(function (d) { return [options.values(d)]; });

	  path.enter().append('path');

	  path.transition()
	    .duration(500)
	    .attr('d', d3.svg.line().x(x).y(y))

	  var point = g.selectAll('circle')
	    .data(options.values);

	  point.enter()
	    .append('circle')
	    .attr({
	      'cx' : x,
	      'cy' : y,
	      'r'  : 0
	    });

	  point.transition()
	    .duration(500)
	    .attr({
	      'cx' : x,
	      'cy' : y,
	      'r'  : 3
	    });

	  point.exit()
	    .transition()
	    .duration(500)
	    .attr('r', 0)
	    .remove();

	  var labels = _(series)
	    .map(function (d) {
	      var last = _.max(options.values(d), options.x);
	      var v    = options.y(last);

	      return {
	        text    : options.seriesName(d) + ' ' + options.yFormat(v),
	        x       : x(last),
	        y       : y(last),
	        defined : _.isFinite(v)
	      };
	    })
	    .filter('defined')
	    .sortBy('y')
	    .value();

	  svg.select('.annotation')
	    .selectAll('.series.label')
	    .data(labels)
	    .call(label()
	      .addClass('series')
	      .width(width)
	      .height(height)
	      .align(false));

	  var gx = svg.select('.x.axis')
	    .call(d3.svg.axis()
	      .tickFormat(options.xFormat)
	      .outerTickSize(0)
	      .ticks(4)
	      .scale(xScale)
	      .orient('bottom'));

	  // Prevent labels from overflowing the left and right edges of the SVG
	  var svgBox = svg.node().getBoundingClientRect();
	  gx.selectAll('text')
	   .attr('dx', function () {
	     var bbox = this.getBoundingClientRect();
	     var dx = null;

	     if (bbox.right > svgBox.right) {
	       dx = svgBox.right - bbox.right;
	     }

	     if (bbox.left < svgBox.left) {
	       dx = svgBox.left - bbox.left;
	     }

	     return dx;
	   });

	  var gy = svg.select('.y.axis')
	    .call(d3.svg.axis()
	      .tickFormat(options.yFormat)
	      .tickSize(width)
	      .ticks(3)
	      .scale(yScale)
	      .orient('right'));

	  gy.selectAll('text')
	    .attr({
				'x'  : 4,
				'dy' : -4
	    });

	  gy.selectAll('g').classed('minor', function (d) {
	    return d !== range[0];
	  });
	}
});

module.exports = LineChart;
<|endoftext|>


<commit_before>/**
 * All content on this website (including text, images, source
 * code and any other original works), unless otherwise noted,
 * is licensed under a Creative Commons License.
 *
 * http://creativecommons.org/licenses/by-nc-sa/2.5/
 *
 * Copyright (C) Open-Xchange Inc., 2011
 * Mail: info@open-xchange.com
 *
 * @author Viktor Pracht <viktor.pracht@open-xchange.com>
 */

var fs = require('fs');
var http = require('http');
var https = require('https');
var path = require('path');
var url = require('url');

var nopt = require('nopt');

nopt.invalidHandler = function (key, val) {
    var messages = {
        port: 'Invalid port number: ',
        server: 'Invalid server URL: ',
        zoneinfo: 'Invalid tzdata path: '
    };
    console.error((messages[key] || 'Invalid option: ' + key + '=') + val);
    usage(1);
};

var options = nopt({
    help: Boolean,
    manifests: [path, Array],
    port: Number,
    server: url,
    verbose: ['local', 'remote', 'proxy', 'all', Array],
    zoneinfo: path
}, {
    h: '--help',
    m: '--manifests',
    p: '--port',
    s: '--server',
    v: '--verbose',
    z: '--zoneinfo'
}, process.argv, 2);

var verbose = options.verbose.reduce(function (opt, val) {
    if (val === 'all') {
        opt.local = opt.remote = opt.proxy = true;
    } else {
        opt[val] = true;
    }
    return opt;
}, {});

if (options.help) usage(0);

function usage(exitCode) {
    (exitCode ? console.error : console.log)(
        'Usage: appserver [OPTION]... [PATH]...\n\n' +
        '  -h,      --help           print this help message and exit\n' +
        '  -m PATH, --manifests=PATH add manifests from the specified path (default:\n' +
        '                            the "manifests" subdirectory of every file path)\n' +
        '  -p PORT, --port=PORT      listen on PORT (default: 8337)\n' +
        '  -s URL,  --server=URL     use an existing server as fallback\n' +
        '  -v TYPE, --verbose=TYPE   print more information depending on TYPE:\n' +
        '                            local: local files, remote: remote files,\n' +
        '                            proxy: forwarded URLs, all: shortcut for all three\n' +
        '  -z PATH, --zoneinfo=PATH  use timezone data from the specified path\n' +
        '                            (default: /usr/share/zoneinfo/)\n\n' +
        'Files are searched in each PATH in order and requested from the server if not\n' +
        'found. If no paths are specified, the default is /var/www/appsuite/.');
    process.exit(exitCode);
}

var prefixes = options.argv.remain.map(function (s) {
    return path.resolve(s);
});
if (!prefixes.length) prefixes =  ['/var/www/appsuite/'];
var manifests = options.manifests || append(prefixes, 'manifests/');
manifests.reverse();
prefixes = append(prefixes, 'apps/');

function append(array, suffix) {
    return array.map(function(prefix) {
        return path.join(prefix, suffix);
    });
}

var tzModule = 'io.ox/core/date/tz/zoneinfo/';
var tzPath = options.zoneinfo || '/usr/share/zoneinfo/';
if (tzPath.slice(-1) !== '/') tzPath += '/';
tzPath = [tzPath];

var appsLoadPath = '/api/apps/load/';
var manifestsPath = '/api/apps/manifests';

if (options.server) {
    if (options.server.slice(-1) != '/') options.server += '/';
    var server = url.parse(options.server);
    if (server.protocol !== 'http:' && server.protocol !== 'https:') {
        console.error('Server must be an HTTP(S) URL');
        usage(1);
    }
    var protocol = server.protocol === 'https:' ? https : http;
    appsLoadPath = server.pathname + appsLoadPath.slice(1);
    manifestsPath = server.pathname + manifestsPath.slice(1);
}

var escapes = {
    '\x00': '\\x00', '\x01': '\\x01', '\x02': '\\x02', '\x03': '\\x03',
    '\x04': '\\x04', '\x05': '\\x05', '\x06': '\\x06', '\x07': '\\x07',
    '\b': '\\b', '\t': '\\t', '\n': '\\n', '\v': '\\v', '\f': '\\f',
    '\r': '\\r', '\x0e': '\\x0e', '\x0f': '\\x0f', '\x10': '\\x10',
    '\x11': '\\x11', '\x12': '\\x12', '\x13': '\\x13', '\x14': '\\x14',
    '\x15': '\\x15', '\x16': '\\x16', '\x17': '\\x17', '\x18': '\\x18',
    '\x19': '\\x19', '\x1a': '\\x1a', '\x1b': '\\x1b', '\x1c': '\\x1c',
    '\x1d': '\\x1d', '\x1e': '\\x1e', '\x1f': '\\x1f', "'": "\\'",
    '\\': '\\\\', '\u2028': '\\u2028', '\u2029': '\\u2029'
};

function escape(s) {
    return s.replace(/[\x00-\x1f'\\\u2028\u2029]/g, function(c) {
        return escapes[c];
    });
}

function httpDate(d) {
    function pad(n) { return n < 10 ? '0' + n : String(n); }
    return [
        ['Sun,', 'Mon,', 'Tue,', 'Wed,', 'Thu,', 'Fri,', 'Sat,'][d.getUTCDay()],
        pad(d.getUTCDate()),
        ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
         'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'][d.getUTCMonth()],
        d.getUTCFullYear(),
        [pad(d.getUTCHours()),
         pad(d.getUTCMinutes()),
         pad(d.getUTCSeconds())].join(':'),
        'GMT'
    ].join(' ');
}

http.createServer(function (request, response) {
    var URL = url.parse(request.url, true);
    if (request.method === 'GET') {
        if (URL.pathname.slice(0, appsLoadPath.length) === appsLoadPath) {
            return load(request, response);
        } else if (URL.pathname === manifestsPath &&
                   URL.query.action === 'config')
        {
            return injectManifests(request, response);
        }
    }
    return proxy(request, response);
}).listen(options.port || 8337);

function load(request, response) {

    // parse request URL
    var list = url.parse(request.url).pathname.split(',');
    var version = list.shift();

    // find local files, request unknown files from server
    var files = [], remoteCounter = 0;
    for (var i in list) {
        var m = /^(?:\/(text|raw);)?([\w\/+-]+(?:\.[\w\/+-]+)*)$/.exec(list[i]);
        if (!m) {
            files.push(invalid(list[i]));
            continue;
        }
        if (m[2].slice(0, tzModule.length) === tzModule) {
            var paths = tzPath;
            var name = m[2].slice(tzModule.length);
        } else {
            var paths = prefixes;
            var name = m[2];
        }
        for (var j = 0; j < paths.length; j++) {
            var filename = path.join(paths[j], name);
            if (path.existsSync(filename) && fs.statSync(filename).isFile()) {
                break;
            }
        }
        files.push(j >= paths.length ? remote(filename, list[i], m[2]) :
                   !m[1]             ? module(filename, list[i]) :
                   m[1] === 'raw'    ? raw(filename, list[i]) :
                                       text(filename, list[i]));
    }
    if (!remoteCounter) complete();

    // invalid module name
    function invalid(fullName) {
        return function () {
            console.log('Invalid module name: ' + fullName);
            response.write("console.log('Invalid module name: \"" +
                           escape(fullName) + "\"');\n");
        };
    }

    // remote file
    function remote(filename, fullName, name) {
        if (!options.server) {
            return function() {
                console.log('Could not read', filename);
                response.write(
                    "define('" + escape(fullName) + "', function () {\n" +
                    "  if (ox.debug) console.log(\"Could not read '" +
                        escape(name) + "'\");\n" +
                    "  throw new Error(\"Could not read '" +
                        escape(name) + "'\");\n" +
                    "});\n");
            };
        }
        remoteCounter++;
        var chunks = [];
        var URL = url.resolve(options.server, version + ',' + fullName);
        protocol.get(url.parse(URL), ok).on('error', error);
        return function () {
            if (verbose.remote) console.log(URL);
            for (var i = 0; i < chunks.length; i++) response.write(chunks[i]);
        };
        function ok(res) {
            if (res.statusCode === 200) {
                res.on('data', chunk).on('end', end);
            } else {
                res.resume();
                console.log('HTTP error ' + res.statusCode + ' for ' + URL);
                chunk("console.log('HTTP error " + res.statusCode + "');\n");
                end();
            }
        }
        function error(e) {
            console.log('Server error for ' + URL + ' : ' + e.message);
            chunk("console.log('Server error: " + e.message + "');\n");
            end();
        }
        function chunk(data) { chunks.push(data); }
        function end() { if (!--remoteCounter) complete(); }
    }

    // normal RequireJS module
    function module(filename, fullName) {
        return function () {
            if (verbose.local) console.log(filename);
            response.write(fs.readFileSync(filename));
        };
    }

    // raw data as string (e.g. timezones)
    function raw(filename, fullName) {
        return function () {
            if (verbose.local) console.log(filename);
            var data = fs.readFileSync(filename), s = [];
            for (var j = 0; j < data.length; j++) s.push(data[j]);
            s = String.fromCharCode.apply(String, s);
            response.write("define('" + escape(fullName) + "','" + escape(s) +
                "');\n");
        };
    }

    // text file as a string (e.g. CSS)
    function text(filename, fullName) {
        return function () {
            if (verbose.local) console.log(filename);
            var s = fs.readFileSync(filename, 'utf8');
            response.write("define('" + escape(fullName) + "','" + escape(s) +
                "');\n");
        };
    }

    // send reply
    function complete() {

        // set headers
        response.setHeader('Content-Type', 'text/javascript;charset=UTF-8');
        response.setHeader('Expires', '0');

        // send data
        for (var i = 0; i < files.length; i++) files[i]();

        // all done
        response.end();
        if (verbose.local || verbose.remote) console.log();
    }
}

function lock() {
    var counter = 1, cb;
    var L = function (f) {
        counter++;
        return function () {
            var retval = f.apply(this, arguments);
            if (!--counter) cb();
            return retval;
        };
    };
    L.done = function (callback) {
        cb = callback;
        if (!--counter) cb();
    };
    return L;
};

function injectManifests(request, response) {
    if (!options.server) {
        console.error('Manifests require --server');
        response.writeHead(501, 'Manifests require --server',
            { 'Content-Type': 'text/plain' });
        response.end('Manifests require --server');
        return;
    }
    var URL = url.resolve(options.server, request.url);
    var opt = url.parse(URL, true);
    opt.headers = request.headers;
    opt.headers.host = opt.host;
    delete opt.headers['accept-encoding'];
    protocol.request(opt, function (res) {
        if (res.statusCode !== 200) {
            response.writeHead(res.statusCode, res.headers);
            res.pipe(response);
            return;
        }
        var reply = [], map = {}, L = lock();
        res.on('data', data).on('end', end);
        function data(chunk) { reply.push(chunk); }
        function end() {
            reply = JSON.parse(reply.join(''));
            if (reply.error) {
                response.end(JSON.stringify(reply, null, 4));
                return;
            }
            var list = reply.data.manifests;
            for (var i in list) map[list[i].path] = list[i];
            manifests.forEach(readDir);
            L.done(sendReply);
        }
        function readDir(dir) {
            fs.readdir(dir, L(function (err, files) {
                if (err) return console.error(err.message);
                files.forEach(function (file) {
                    file = path.join(dir, file);
                    if (verbose.local) console.log(file);
                    fs.readFile(file, 'utf8', L(addManifest));
                });
            }));
        }
        function addManifest(err, manifest) {
            if (err) return console.error(err.message);
            manifest = Function('return (' + manifest + ')')();
            if (!(manifest instanceof Array)) manifest = [manifest];
            for (var i in manifest) map[manifest[i].path] = manifest[i];
        }
        function sendReply() {
            var list = reply.data.manifests = [];
            for (var i in map) {
                if (opt.query.session || /signin/.test(map[i].namespace)) {
                    list.push(map[i]);
                }
            }
            response.end(JSON.stringify(reply, null, 4));
            if (verbose.local) console.log();
        }
    }).end();
}

function proxy(request, response) {
    if (!options.server) {
        console.log('No --server specified to forward', request.url);
        response.writeHead(501, 'No --server specified',
            { 'Content-Type': 'text/plain' });
        response.end('No --server specified');
        return;
    }
    var URL = url.resolve(options.server, request.url);
    if (verbose.proxy) console.log(URL);
    var opt = url.parse(URL);
    opt.method = request.method;
    opt.headers = request.headers;
    opt.headers.host = opt.host;
    request.pipe(protocol.request(opt, function (res) {
        var cookies = res.headers['set-cookie'];
        if (cookies) {
            if (typeof cookies === 'string') cookies = [cookies];
            res.headers['set-cookie'] = cookies.map(function (s) {
                return s.replace(/;\s*secure/i, '');
            });
        }
        response.writeHead(res.statusCode, res.headers);
        res.pipe(response);
    }));
}
<commit_msg>Fixed crash without -v flags<commit_after>/**
 * All content on this website (including text, images, source
 * code and any other original works), unless otherwise noted,
 * is licensed under a Creative Commons License.
 *
 * http://creativecommons.org/licenses/by-nc-sa/2.5/
 *
 * Copyright (C) Open-Xchange Inc., 2011
 * Mail: info@open-xchange.com
 *
 * @author Viktor Pracht <viktor.pracht@open-xchange.com>
 */

var fs = require('fs');
var http = require('http');
var https = require('https');
var path = require('path');
var url = require('url');

var nopt = require('nopt');

nopt.invalidHandler = function (key, val) {
    var messages = {
        port: 'Invalid port number: ',
        server: 'Invalid server URL: ',
        zoneinfo: 'Invalid tzdata path: '
    };
    console.error((messages[key] || 'Invalid option: ' + key + '=') + val);
    usage(1);
};

var options = nopt({
    help: Boolean,
    manifests: [path, Array],
    port: Number,
    server: url,
    verbose: ['local', 'remote', 'proxy', 'all', Array],
    zoneinfo: path
}, {
    h: '--help',
    m: '--manifests',
    p: '--port',
    s: '--server',
    v: '--verbose',
    z: '--zoneinfo'
}, process.argv, 2);

var verbose = (options.verbose || []).reduce(function (opt, val) {
    if (val === 'all') {
        opt.local = opt.remote = opt.proxy = true;
    } else {
        opt[val] = true;
    }
    return opt;
}, {});

if (options.help) usage(0);

function usage(exitCode) {
    (exitCode ? console.error : console.log)(
        'Usage: appserver [OPTION]... [PATH]...\n\n' +
        '  -h,      --help           print this help message and exit\n' +
        '  -m PATH, --manifests=PATH add manifests from the specified path (default:\n' +
        '                            the "manifests" subdirectory of every file path)\n' +
        '  -p PORT, --port=PORT      listen on PORT (default: 8337)\n' +
        '  -s URL,  --server=URL     use an existing server as fallback\n' +
        '  -v TYPE, --verbose=TYPE   print more information depending on TYPE:\n' +
        '                            local: local files, remote: remote files,\n' +
        '                            proxy: forwarded URLs, all: shortcut for all three\n' +
        '  -z PATH, --zoneinfo=PATH  use timezone data from the specified path\n' +
        '                            (default: /usr/share/zoneinfo/)\n\n' +
        'Files are searched in each PATH in order and requested from the server if not\n' +
        'found. If no paths are specified, the default is /var/www/appsuite/.');
    process.exit(exitCode);
}

var prefixes = options.argv.remain.map(function (s) {
    return path.resolve(s);
});
if (!prefixes.length) prefixes =  ['/var/www/appsuite/'];
var manifests = options.manifests || append(prefixes, 'manifests/');
manifests.reverse();
prefixes = append(prefixes, 'apps/');

function append(array, suffix) {
    return array.map(function(prefix) {
        return path.join(prefix, suffix);
    });
}

var tzModule = 'io.ox/core/date/tz/zoneinfo/';
var tzPath = options.zoneinfo || '/usr/share/zoneinfo/';
if (tzPath.slice(-1) !== '/') tzPath += '/';
tzPath = [tzPath];

var appsLoadPath = '/api/apps/load/';
var manifestsPath = '/api/apps/manifests';

if (options.server) {
    if (options.server.slice(-1) != '/') options.server += '/';
    var server = url.parse(options.server);
    if (server.protocol !== 'http:' && server.protocol !== 'https:') {
        console.error('Server must be an HTTP(S) URL');
        usage(1);
    }
    var protocol = server.protocol === 'https:' ? https : http;
    appsLoadPath = server.pathname + appsLoadPath.slice(1);
    manifestsPath = server.pathname + manifestsPath.slice(1);
}

var escapes = {
    '\x00': '\\x00', '\x01': '\\x01', '\x02': '\\x02', '\x03': '\\x03',
    '\x04': '\\x04', '\x05': '\\x05', '\x06': '\\x06', '\x07': '\\x07',
    '\b': '\\b', '\t': '\\t', '\n': '\\n', '\v': '\\v', '\f': '\\f',
    '\r': '\\r', '\x0e': '\\x0e', '\x0f': '\\x0f', '\x10': '\\x10',
    '\x11': '\\x11', '\x12': '\\x12', '\x13': '\\x13', '\x14': '\\x14',
    '\x15': '\\x15', '\x16': '\\x16', '\x17': '\\x17', '\x18': '\\x18',
    '\x19': '\\x19', '\x1a': '\\x1a', '\x1b': '\\x1b', '\x1c': '\\x1c',
    '\x1d': '\\x1d', '\x1e': '\\x1e', '\x1f': '\\x1f', "'": "\\'",
    '\\': '\\\\', '\u2028': '\\u2028', '\u2029': '\\u2029'
};

function escape(s) {
    return s.replace(/[\x00-\x1f'\\\u2028\u2029]/g, function(c) {
        return escapes[c];
    });
}

function httpDate(d) {
    function pad(n) { return n < 10 ? '0' + n : String(n); }
    return [
        ['Sun,', 'Mon,', 'Tue,', 'Wed,', 'Thu,', 'Fri,', 'Sat,'][d.getUTCDay()],
        pad(d.getUTCDate()),
        ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
         'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'][d.getUTCMonth()],
        d.getUTCFullYear(),
        [pad(d.getUTCHours()),
         pad(d.getUTCMinutes()),
         pad(d.getUTCSeconds())].join(':'),
        'GMT'
    ].join(' ');
}

http.createServer(function (request, response) {
    var URL = url.parse(request.url, true);
    if (request.method === 'GET') {
        if (URL.pathname.slice(0, appsLoadPath.length) === appsLoadPath) {
            return load(request, response);
        } else if (URL.pathname === manifestsPath &&
                   URL.query.action === 'config')
        {
            return injectManifests(request, response);
        }
    }
    return proxy(request, response);
}).listen(options.port || 8337);

function load(request, response) {

    // parse request URL
    var list = url.parse(request.url).pathname.split(',');
    var version = list.shift();

    // find local files, request unknown files from server
    var files = [], remoteCounter = 0;
    for (var i in list) {
        var m = /^(?:\/(text|raw);)?([\w\/+-]+(?:\.[\w\/+-]+)*)$/.exec(list[i]);
        if (!m) {
            files.push(invalid(list[i]));
            continue;
        }
        if (m[2].slice(0, tzModule.length) === tzModule) {
            var paths = tzPath;
            var name = m[2].slice(tzModule.length);
        } else {
            var paths = prefixes;
            var name = m[2];
        }
        for (var j = 0; j < paths.length; j++) {
            var filename = path.join(paths[j], name);
            if (path.existsSync(filename) && fs.statSync(filename).isFile()) {
                break;
            }
        }
        files.push(j >= paths.length ? remote(filename, list[i], m[2]) :
                   !m[1]             ? module(filename, list[i]) :
                   m[1] === 'raw'    ? raw(filename, list[i]) :
                                       text(filename, list[i]));
    }
    if (!remoteCounter) complete();

    // invalid module name
    function invalid(fullName) {
        return function () {
            console.log('Invalid module name: ' + fullName);
            response.write("console.log('Invalid module name: \"" +
                           escape(fullName) + "\"');\n");
        };
    }

    // remote file
    function remote(filename, fullName, name) {
        if (!options.server) {
            return function() {
                console.log('Could not read', filename);
                response.write(
                    "define('" + escape(fullName) + "', function () {\n" +
                    "  if (ox.debug) console.log(\"Could not read '" +
                        escape(name) + "'\");\n" +
                    "  throw new Error(\"Could not read '" +
                        escape(name) + "'\");\n" +
                    "});\n");
            };
        }
        remoteCounter++;
        var chunks = [];
        var URL = url.resolve(options.server, version + ',' + fullName);
        protocol.get(url.parse(URL), ok).on('error', error);
        return function () {
            if (verbose.remote) console.log(URL);
            for (var i = 0; i < chunks.length; i++) response.write(chunks[i]);
        };
        function ok(res) {
            if (res.statusCode === 200) {
                res.on('data', chunk).on('end', end);
            } else {
                res.resume();
                console.log('HTTP error ' + res.statusCode + ' for ' + URL);
                chunk("console.log('HTTP error " + res.statusCode + "');\n");
                end();
            }
        }
        function error(e) {
            console.log('Server error for ' + URL + ' : ' + e.message);
            chunk("console.log('Server error: " + e.message + "');\n");
            end();
        }
        function chunk(data) { chunks.push(data); }
        function end() { if (!--remoteCounter) complete(); }
    }

    // normal RequireJS module
    function module(filename, fullName) {
        return function () {
            if (verbose.local) console.log(filename);
            response.write(fs.readFileSync(filename));
        };
    }

    // raw data as string (e.g. timezones)
    function raw(filename, fullName) {
        return function () {
            if (verbose.local) console.log(filename);
            var data = fs.readFileSync(filename), s = [];
            for (var j = 0; j < data.length; j++) s.push(data[j]);
            s = String.fromCharCode.apply(String, s);
            response.write("define('" + escape(fullName) + "','" + escape(s) +
                "');\n");
        };
    }

    // text file as a string (e.g. CSS)
    function text(filename, fullName) {
        return function () {
            if (verbose.local) console.log(filename);
            var s = fs.readFileSync(filename, 'utf8');
            response.write("define('" + escape(fullName) + "','" + escape(s) +
                "');\n");
        };
    }

    // send reply
    function complete() {

        // set headers
        response.setHeader('Content-Type', 'text/javascript;charset=UTF-8');
        response.setHeader('Expires', '0');

        // send data
        for (var i = 0; i < files.length; i++) files[i]();

        // all done
        response.end();
        if (verbose.local || verbose.remote) console.log();
    }
}

function lock() {
    var counter = 1, cb;
    var L = function (f) {
        counter++;
        return function () {
            var retval = f.apply(this, arguments);
            if (!--counter) cb();
            return retval;
        };
    };
    L.done = function (callback) {
        cb = callback;
        if (!--counter) cb();
    };
    return L;
};

function injectManifests(request, response) {
    if (!options.server) {
        console.error('Manifests require --server');
        response.writeHead(501, 'Manifests require --server',
            { 'Content-Type': 'text/plain' });
        response.end('Manifests require --server');
        return;
    }
    var URL = url.resolve(options.server, request.url);
    var opt = url.parse(URL, true);
    opt.headers = request.headers;
    opt.headers.host = opt.host;
    delete opt.headers['accept-encoding'];
    protocol.request(opt, function (res) {
        if (res.statusCode !== 200) {
            response.writeHead(res.statusCode, res.headers);
            res.pipe(response);
            return;
        }
        var reply = [], map = {}, L = lock();
        res.on('data', data).on('end', end);
        function data(chunk) { reply.push(chunk); }
        function end() {
            reply = JSON.parse(reply.join(''));
            if (reply.error) {
                response.end(JSON.stringify(reply, null, 4));
                return;
            }
            var list = reply.data.manifests;
            for (var i in list) map[list[i].path] = list[i];
            manifests.forEach(readDir);
            L.done(sendReply);
        }
        function readDir(dir) {
            fs.readdir(dir, L(function (err, files) {
                if (err) return console.error(err.message);
                files.forEach(function (file) {
                    file = path.join(dir, file);
                    if (verbose.local) console.log(file);
                    fs.readFile(file, 'utf8', L(addManifest));
                });
            }));
        }
        function addManifest(err, manifest) {
            if (err) return console.error(err.message);
            manifest = Function('return (' + manifest + ')')();
            if (!(manifest instanceof Array)) manifest = [manifest];
            for (var i in manifest) map[manifest[i].path] = manifest[i];
        }
        function sendReply() {
            var list = reply.data.manifests = [];
            for (var i in map) {
                if (opt.query.session || /signin/.test(map[i].namespace)) {
                    list.push(map[i]);
                }
            }
            response.end(JSON.stringify(reply, null, 4));
            if (verbose.local) console.log();
        }
    }).end();
}

function proxy(request, response) {
    if (!options.server) {
        console.log('No --server specified to forward', request.url);
        response.writeHead(501, 'No --server specified',
            { 'Content-Type': 'text/plain' });
        response.end('No --server specified');
        return;
    }
    var URL = url.resolve(options.server, request.url);
    if (verbose.proxy) console.log(URL);
    var opt = url.parse(URL);
    opt.method = request.method;
    opt.headers = request.headers;
    opt.headers.host = opt.host;
    request.pipe(protocol.request(opt, function (res) {
        var cookies = res.headers['set-cookie'];
        if (cookies) {
            if (typeof cookies === 'string') cookies = [cookies];
            res.headers['set-cookie'] = cookies.map(function (s) {
                return s.replace(/;\s*secure/i, '');
            });
        }
        response.writeHead(res.statusCode, res.headers);
        res.pipe(response);
    }));
}
<|endoftext|>


<commit_before>import faker from 'nomad-ui/mirage/faker';
import { provide } from './utils';

// Realistically, resource reservations have a low cardinality
const CPU_RESERVATIONS = [250, 500, 1000, 2000, 2500, 4000];
const MEMORY_RESERVATIONS = [256, 512, 1024, 2048, 4096, 8192];
const DISK_RESERVATIONS = [200, 500, 1000, 2000, 5000, 10000, 100000];
const IOPS_RESERVATIONS = [100000, 250000, 500000, 1000000, 10000000, 20000000];

// There is also a good chance that certain resource restrictions are unbounded
IOPS_RESERVATIONS.push(...Array(1000).fill(0));
DISK_RESERVATIONS.push(...Array(500).fill(0));

const NETWORK_MODES = ['bridge', 'host'];

export const DATACENTERS = provide(
  15,
  (n, i) => `${faker.address.countryCode().toLowerCase()}${i}`
);

export const HOSTS = provide(100, () => {
  const ip = faker.random.boolean() ? faker.internet.ip() : `[${faker.internet.ipv6()}]`;
  return `${ip}:${faker.random.number({ min: 4000, max: 4999 })}`;
});

export const STORAGE_PROVIDERS = ['ebs', 'zfs', 'nfs', 'cow', 'moo'];

export function generateResources(options = {}) {
  return {
    CPU: faker.helpers.randomize(CPU_RESERVATIONS),
    MemoryMB: faker.helpers.randomize(MEMORY_RESERVATIONS),
    DiskMB: faker.helpers.randomize(DISK_RESERVATIONS),
    IOPS: faker.helpers.randomize(IOPS_RESERVATIONS),
    Networks: generateNetworks(options.networks),
    Ports: generatePorts(options.networks),
  };
}

export function generateNetworks(options = {}) {
  return Array(faker.random.number({ min: 1, max: 3 }))
    .fill(null)
    .map(() => ({
      Device: `eth${faker.random.number({ max: 5 })}`,
      CIDR: '',
      IP: faker.internet.ip(),
      MBits: 10,
      Mode: faker.helpers.randomize(NETWORK_MODES),
      ReservedPorts: Array(
        faker.random.number({
          min: options.minPorts != null ? options.minPorts : 0,
          max: options.maxPorts != null ? options.maxPorts : 2,
        })
      )
        .fill(null)
        .map(() => ({
          Label: faker.hacker.noun(),
          Value: faker.random.number({ min: 5000, max: 60000 }),
          To: faker.random.number({ min: 5000, max: 60000 }),
        })),
      DynamicPorts: Array(
        faker.random.number({
          min: options.minPorts != null ? options.minPorts : 0,
          max: options.maxPorts != null ? options.maxPorts : 2,
        })
      )
        .fill(null)
        .map(() => ({
          Label: faker.hacker.noun(),
          Value: faker.random.number({ min: 5000, max: 60000 }),
          To: faker.random.number({ min: 5000, max: 60000 }),
        })),
    }));
}

export function generatePorts(options = {}) {
  return Array(faker.random.number({
    min: options.minPorts != null ? options.minPorts : 0,
    max: options.maxPorts != null ? options.maxPorts : 2
  }))
    .fill(null)
    .map(() => ({
      Label: faker.hacker.noun(),
      Value: faker.random.number({ min: 5000, max: 60000 }),
      To: faker.random.number({ min: 5000, max: 60000 }),
      HostIP: faker.random.boolean() ? faker.internet.ip() : faker.internet.ipv6(),
    }))
}<commit_msg>Parameterize generateResources to enable property overrides<commit_after>import faker from 'nomad-ui/mirage/faker';
import { provide } from './utils';

// Realistically, resource reservations have a low cardinality
const CPU_RESERVATIONS = [250, 500, 1000, 2000, 2500, 4000];
const MEMORY_RESERVATIONS = [256, 512, 1024, 2048, 4096, 8192];
const DISK_RESERVATIONS = [200, 500, 1000, 2000, 5000, 10000, 100000];
const IOPS_RESERVATIONS = [100000, 250000, 500000, 1000000, 10000000, 20000000];

// There is also a good chance that certain resource restrictions are unbounded
IOPS_RESERVATIONS.push(...Array(1000).fill(0));
DISK_RESERVATIONS.push(...Array(500).fill(0));

const NETWORK_MODES = ['bridge', 'host'];

export const DATACENTERS = provide(
  15,
  (n, i) => `${faker.address.countryCode().toLowerCase()}${i}`
);

export const HOSTS = provide(100, () => {
  const ip = faker.random.boolean() ? faker.internet.ip() : `[${faker.internet.ipv6()}]`;
  return `${ip}:${faker.random.number({ min: 4000, max: 4999 })}`;
});

export const STORAGE_PROVIDERS = ['ebs', 'zfs', 'nfs', 'cow', 'moo'];

export function generateResources(options = {}) {
  return {
    CPU: options.CPU || faker.helpers.randomize(CPU_RESERVATIONS),
    MemoryMB: options.MemoryMB || faker.helpers.randomize(MEMORY_RESERVATIONS),
    DiskMB: options.DiskMB || faker.helpers.randomize(DISK_RESERVATIONS),
    IOPS: options.IOPS || faker.helpers.randomize(IOPS_RESERVATIONS),
    Networks: generateNetworks(options.networks),
    Ports: generatePorts(options.networks),
  };
}

export function generateNetworks(options = {}) {
  return Array(faker.random.number({ min: 1, max: 3 }))
    .fill(null)
    .map(() => ({
      Device: `eth${faker.random.number({ max: 5 })}`,
      CIDR: '',
      IP: faker.internet.ip(),
      MBits: 10,
      Mode: faker.helpers.randomize(NETWORK_MODES),
      ReservedPorts: Array(
        faker.random.number({
          min: options.minPorts != null ? options.minPorts : 0,
          max: options.maxPorts != null ? options.maxPorts : 2,
        })
      )
        .fill(null)
        .map(() => ({
          Label: faker.hacker.noun(),
          Value: faker.random.number({ min: 5000, max: 60000 }),
          To: faker.random.number({ min: 5000, max: 60000 }),
        })),
      DynamicPorts: Array(
        faker.random.number({
          min: options.minPorts != null ? options.minPorts : 0,
          max: options.maxPorts != null ? options.maxPorts : 2,
        })
      )
        .fill(null)
        .map(() => ({
          Label: faker.hacker.noun(),
          Value: faker.random.number({ min: 5000, max: 60000 }),
          To: faker.random.number({ min: 5000, max: 60000 }),
        })),
    }));
}

export function generatePorts(options = {}) {
  return Array(
    faker.random.number({
      min: options.minPorts != null ? options.minPorts : 0,
      max: options.maxPorts != null ? options.maxPorts : 2,
    })
  )
    .fill(null)
    .map(() => ({
      Label: faker.hacker.noun(),
      Value: faker.random.number({ min: 5000, max: 60000 }),
      To: faker.random.number({ min: 5000, max: 60000 }),
      HostIP: faker.random.boolean() ? faker.internet.ip() : faker.internet.ipv6(),
    }));
}
<|endoftext|>


<commit_before>const AppSettings = require('../AppSettings');
const GoogleAnalytics = require('react-native-google-analytics-bridge');

GoogleAnalytics.setTrackerId(AppSettings.GOOGLE_ANALYTICS_ID);

/**
 * A module containing logging helper functions
 * @module util/logger
 */
module.exports = {

	/**
	 * Send a log message to the console
	 * @function
	 * @param {string} msg The message to log
	 */
	log(msg) {
		console.log(msg);
	},

	/**
	 * Send an error message to the console
	 * If debugging is enabled, the message is sent as an error (e.g. stderr)
	 * @function
	 * @param {string} msg The error message to log
	 */
	error(msg) {
		if (AppSettings.DEBUG_ENABLED) {
			console.error(msg);
		} else {
			console.log(msg);
		}
	},

	/**
	 * Sends a log message to Google Analytics as well as the local console
	 * @function
	 * @param {string} msg The message to to log
	 */
	ga(msg) {
		this.log(msg);
		GoogleAnalytics.trackScreenView(msg);
	},

};
<commit_msg>google analytics bridge upgrade<commit_after>import { GOOGLE_ANALYTICS_ID, DEBUG_ENABLED } from '../AppSettings';
import { GoogleAnalyticsTracker } from 'react-native-google-analytics-bridge';

let tracker = new GoogleAnalyticsTracker(GOOGLE_ANALYTICS_ID);

/**
 * A module containing logging helper functions
 * @module util/logger
 */
module.exports = {

	/**
	 * Send a log message to the console
	 * @function
	 * @param {string} msg The message to log
	 */
	log(msg) {
		console.log(msg);
	},

	/**
	 * Send an error message to the console
	 * If debugging is enabled, the message is sent as an error (e.g. stderr)
	 * @function
	 * @param {string} msg The error message to log
	 */
	error(msg) {
		if (DEBUG_ENABLED) {
			console.error(msg);
		} else {
			console.log(msg);
		}
	},

	/**
	 * Sends a log message to Google Analytics as well as the local console
	 * @function
	 * @param {string} msg The message to to log
	 */
	ga(msg) {
		this.log(msg);
		tracker.trackScreenView(msg);
	},

};
<|endoftext|>


<commit_before>import firebase from 'app/fire'

export const getCard = (storyBranchId, cardId, handleCurrentStoryChange) => {
  firebase.database().ref(`storyBranch/${storyBranchId}`).once('value', snap => {
    const storyBranch = snap.val()
    return handleCurrentStoryChange(storyBranchId, storyBranch)
  })
  .then(() => {
    firebase.database().ref(`storyCard/${cardId}`).once('value', snap => {
      console.log('set val after empty')
      this.setState({cards: [...this.state.cards, snap.val()]})
    })
  })
}
<commit_msg>delete useless utils<commit_after><|endoftext|>


<commit_before>'use strict';

angular.module('myApp.view1', ['ngRoute', 'ngFileUpload'])
  .config(['$routeProvider', function($routeProvider) {
    $routeProvider.when('/view1', {
      templateUrl: 'view1/view1.html',
      controller: 'View1Ctrl'
    })
    .when('/view2', {
      templateUrl: 'view2/view2.html',
      controller: 'View2Ctrl'
    });
  }])

.controller('View1Ctrl', function($scope, $q, fileReader, pdfReader, cvModel, jobDescriptionModel, cvEvaluator, $location) {
    $scope.fileNames = "";
    $scope.jobDescript = "";
  $scope.$watch('file', function () {
    if ($scope.file != null) {
      $scope.files = [$scope.file];
    }
  });

  $scope.$on("fileProgress", function(e, progress) {
    $scope.progress = (progress.loaded / progress.total) * 100;
  });

  var processFiles = function (files) {
    $scope.fileNames = "";
    if (files && files.length) {
      var promises = [];
      for (var i = 0; i < files.length; i++) {
        $scope.fileNames += files[i].name + "\n";
        $scope.showProgressBar = true;

        var readPdf = fileReader.readAsDataUrl(files[i], $scope)
          .then(function(pdf) {
            return getAllTextFromPdf(pdf).then(function(allTextFromPdf) {
              return allTextFromPdf;
            });
          });
        promises.push(readPdf);
      }
      return $q.all(promises).then(function(allCvParsed) {
        console.log("all cv parsed promise", allCvParsed);
        return allCvParsed;
      });
    }
  };

  function getAllTextFromPdf(pdf) {
    return pdfReader.getAllTextFromPdf(pdf).then(function(result) {
      console.log("final array of string", result);
     cvModel.save(result);
    });
  };

  var processJobDesc = function(jobDesc) {
    var deferred = $q.defer();
    jobDescriptionModel.save(jobDesc);
    deferred.resolve();
    return deferred.promise;
  };

  $scope.doProcess = function () {
    var processJobDescPromise = processJobDesc($scope.jobDescript);
    var processFilesPromise = processFiles($scope.files);
    $q.all([processJobDescPromise, processFilesPromise]).then(function(jobDescAndFiles) {
      console.log("THS IS THE END", jobDescAndFiles);
      var allParsedCvs = jobDescAndFiles[1];
      cvEvaluator.evaluateCV();
      $location.url("/view2");
    });
  };
});<commit_msg>View1 Controller: remove routing config since it's already in app.js<commit_after>'use strict';

angular.module('myApp.view1', ['ngRoute', 'ngFileUpload'])

.controller('View1Ctrl', function($scope, $q, fileReader, pdfReader, cvModel, jobDescriptionModel, cvEvaluator, $location) {
    $scope.fileNames = "";
    $scope.jobDescript = "";
  $scope.$watch('file', function () {
    if ($scope.file != null) {
      $scope.files = [$scope.file];
    }
  });

  $scope.$on("fileProgress", function(e, progress) {
    $scope.progress = (progress.loaded / progress.total) * 100;
  });

  var processFiles = function (files) {
    $scope.fileNames = "";
    if (files && files.length) {
      var promises = [];
      for (var i = 0; i < files.length; i++) {
        $scope.fileNames += files[i].name + "\n";
        $scope.showProgressBar = true;

        var readPdf = fileReader.readAsDataUrl(files[i], $scope)
          .then(function(pdf) {
            return getAllTextFromPdf(pdf).then(function(allTextFromPdf) {
              return allTextFromPdf;
            });
          });
        promises.push(readPdf);
      }
      return $q.all(promises).then(function(allCvParsed) {
        console.log("all cv parsed promise", allCvParsed);
        return allCvParsed;
      });
    }
  };

  function getAllTextFromPdf(pdf) {
    return pdfReader.getAllTextFromPdf(pdf).then(function(result) {
      console.log("final array of string", result);
     cvModel.save(result);
    });
  };

  var processJobDesc = function(jobDesc) {
    var deferred = $q.defer();
    jobDescriptionModel.save(jobDesc);
    deferred.resolve();
    return deferred.promise;
  };

  $scope.doProcess = function () {
    var processJobDescPromise = processJobDesc($scope.jobDescript);
    var processFilesPromise = processFiles($scope.files);
    $q.all([processJobDescPromise, processFilesPromise]).then(function(jobDescAndFiles) {
      console.log("THS IS THE END", jobDescAndFiles);
      var allParsedCvs = jobDescAndFiles[1];
      cvEvaluator.evaluateCV();
      $location.url("/view2");
    });
  };
});<|endoftext|>


<commit_before>'use strict';

function randrange(minimum, maximum) {
    return Math.floor(Math.random() * (maximum - minimum + 1)) + minimum;
}

function randLab(lower, upper) {
    var labMean = (lower + upper) / 2;
    var labRange = upper - lower;
    var randLab = 0;
    if (randrange(0, 10) <= 5) {
        randLab = labMean + Math.random() * labRange / 2;
    } else {
        randLab = labMean - Math.random() * labRange / 2;
    }
    return randLab
}

angular.module('myApp.view2', ['ngRoute'])

    .config(['$routeProvider', function ($routeProvider) {
        $routeProvider.when('/view2', {
            templateUrl: 'view2/view2.html',
            controller: 'View2Ctrl'
        });
    }])
    .directive("mathjaxBind", function () {
        return {
            restrict: "A",
            controller: ["$scope", "$element", "$attrs", function ($scope, $element, $attrs) {
                $scope.$watch($attrs.mathjaxBind, function (value) {
                    $element.text(value == undefined ? "" : value);
                    MathJax.Hub.Queue(["Typeset", MathJax.Hub, $element[0]]);
                });
            }]
        };
    })

    .controller('View2Ctrl', function ($scope, LatexService, GentVariableService, CreatePatient, PopulationParams) {
        var constants = GentVariableService.C_unknown();
        console.log(constants);
        /* (C, C0, k, t )*/
        $scope.firstorder = LatexService.firstOrderElimination(constants.C, constants.C0, constants.k, 't');
        /* (C, C0, k, t )*/
        $scope.firstorderslope = LatexService.firstOrderSlope(2, 10, "k", "t");
        $scope.adultpatient = CreatePatient.adult();

        /* age, weight, creatinine, gender */
        $scope.gentParams = PopulationParams.aminoglycoside(47, 70, 1.1, 'female');
    })

    .service('LatexService', function () {
        this.firstOrderElimination = function (C, C0, k, t) {
            if (!angular.isNumber(C)) {
                C = "C";
            }
            if (!angular.isNumber(C0)) {
                C0 = "C_0";
            }
            if (!angular.isNumber(k)) {
                k = "k_{el}";
            }
            if (!angular.isNumber(t)) {
                t = "t";
            }
            return "\\[ " + C + "=" + C0 + "\\cdot e^{-" + k + "\\cdot " + t + "} \\]";

        };
        this.firstOrderSlope = function (C, C0, k, t) {
            if (!angular.isNumber(C)) {
                C = "C";
            }
            if (!angular.isNumber(C0)) {
                C0 = "C_0";
            }
            if (!angular.isNumber(k)) {
                k = "k_{el}";
            }
            if (!angular.isNumber(t)) {
                t = "t";
            }
            return "\\[-" + k + " = {\\frac{{\\ln " + C + " - \\ln " + C0 + "}}{\\Delta " + t + "}} \\]";
        };
    })

    .service('GentVariableService', function () {
        this.C_unknown = function () {
            var RandomC = Math.floor((Math.random() * 4) + 1);
            var RandomC0 = Math.floor((Math.random() * 8) + RandomC);
            var RandomHalfLife = Math.floor((Math.random() * 5) + 1);
            var RandomK = Math.round(0.693 / RandomHalfLife * 1000) / 1000;
            var RandomT = Math.floor((Math.random() * 10) + 1);
            var C = RandomC0 * (Math.exp(-1 * RandomK * RandomT));
            C = Math.round(C * 10) / 10;
            return {
                C: C,
                C0: RandomC0,
                k: RandomK,
                t: RandomT
            };
        };
    })

    .service('PopulationParams', function () {
        this.aminoglycoside = function (age, weight, Scr, gender) {
            var ClCr = (140 - age) * weight / 72 / Scr;
            if (gender == 'female') {
                ClCr = 0.85 * ClCr;
            }
            ClCr = Math.round(ClCr);

            var Vd = randLab((0.21 * weight), (0.27 * weight));
            Vd = Math.round(Vd * 10) / 10;

            var kel = 0.00285 * ClCr + 0.015;
            kel = randLab((kel * 0.8), (kel * 1.2));
            kel = Math.round(kel * 1000) / 1000;

            var halflife = 0.693 / kel;
            halflife = Math.round(halflife * 10) / 10;
            return {
                kel: kel,
                Vd: Vd,
                halflife: halflife,
                ClCr: ClCr
            };
        };
    })

    .service('CreatePatient', function () {

        /* Comes up with a random lab value within a range */

        this.adult = function () {
            if (randrange(0, 10) < 5) {
                var gender = 'male';
                var height = randLab(65, 75);
                var weight = 50 + 2.3 * (height - 60);
            } else {
                var gender = 'female';
                var height = randLab(62, 72);
                var weight = 45.5 + 2.3 * (height - 60);
            }
            height = Math.round(height * 10) / 10;
            weight = randLab(weight * 0.9, weight * 1.1);
            weight = Math.round(weight);

            var age = randrange(18, 85);

            var races = [
                "white",
                "African-American",
                "Asian",
                "Hispanic"
            ];
            var race = races[randrange(0, (races.length - 1))];

            /* Renal Function */
            var creatinine = 0.9;
            var renalfailurerisk = randrange(0, 10);
            if (renalfailurerisk <= 5) {
                creatinine = Math.floor(creatinine * randrange(25, 75) / 5) / 10;
            }
            else if (renalfailurerisk > 5 && renalfailurerisk < 8) {
                creatinine = Math.floor(creatinine * randrange(10, 30)) / 10;
            }
            else if (renalfailurerisk >= 8) {
                creatinine = Math.floor(creatinine * randrange(10, 100)) / 10;
            }
            var BUN = Math.floor(9.5 * creatinine);

            /* Background Normal Labs */
            var Na = Math.floor(randLab(136, 146));
            var K = Math.floor(randLab(3.5, 5.1) * 10) / 10;
            var Cl = Math.floor(randLab(98, 108));
            var C02 = Math.floor(randLab(18, 30));
            var glucose = Math.floor(randLab(74, 106));

            return {
                gender: gender,
                age: age,
                race: race,
                creatinine: creatinine,
                BUN: BUN,
                Na: Na,
                K: K,
                Cl: Cl,
                C02: C02,
                glucose: glucose,
                height: height,
                weight: weight
            };
        };
    });

<commit_msg>Pharmacokinetic params for randomly generated patient<commit_after>'use strict';

function randrange(minimum, maximum) {
    return Math.floor(Math.random() * (maximum - minimum + 1)) + minimum;
}

function randLab(lower, upper) {
    var labMean = (lower + upper) / 2;
    var labRange = upper - lower;
    var randLab = 0;
    if (randrange(0, 10) <= 5) {
        randLab = labMean + Math.random() * labRange / 2;
    } else {
        randLab = labMean - Math.random() * labRange / 2;
    }
    return randLab
}

angular.module('myApp.view2', ['ngRoute'])

    .config(['$routeProvider', function ($routeProvider) {
        $routeProvider.when('/view2', {
            templateUrl: 'view2/view2.html',
            controller: 'View2Ctrl'
        });
    }])
    .directive("mathjaxBind", function () {
        return {
            restrict: "A",
            controller: ["$scope", "$element", "$attrs", function ($scope, $element, $attrs) {
                $scope.$watch($attrs.mathjaxBind, function (value) {
                    $element.text(value == undefined ? "" : value);
                    MathJax.Hub.Queue(["Typeset", MathJax.Hub, $element[0]]);
                });
            }]
        };
    })

    .controller('View2Ctrl', function ($scope, LatexService, GentVariableService, CreatePatient, PopulationParams) {
        var constants = GentVariableService.C_unknown();
        console.log(constants);
        /* (C, C0, k, t )*/
        $scope.firstorder = LatexService.firstOrderElimination(constants.C, constants.C0, constants.k, 't');
        /* (C, C0, k, t )*/
        $scope.firstorderslope = LatexService.firstOrderSlope(2, 10, "k", "t");
        $scope.adultpatient = CreatePatient.adult();

        /* age, weight, creatinine, gender */
        $scope.gentParams = PopulationParams.aminoglycoside($scope.adultpatient.age, $scope.adultpatient.weight, $scope.adultpatient.creatinine, $scope.adultpatient.gender);
    })

    .service('LatexService', function () {
        this.firstOrderElimination = function (C, C0, k, t) {
            if (!angular.isNumber(C)) {
                C = "C";
            }
            if (!angular.isNumber(C0)) {
                C0 = "C_0";
            }
            if (!angular.isNumber(k)) {
                k = "k_{el}";
            }
            if (!angular.isNumber(t)) {
                t = "t";
            }
            return "\\[ " + C + "=" + C0 + "\\cdot e^{-" + k + "\\cdot " + t + "} \\]";

        };
        this.firstOrderSlope = function (C, C0, k, t) {
            if (!angular.isNumber(C)) {
                C = "C";
            }
            if (!angular.isNumber(C0)) {
                C0 = "C_0";
            }
            if (!angular.isNumber(k)) {
                k = "k_{el}";
            }
            if (!angular.isNumber(t)) {
                t = "t";
            }
            return "\\[-" + k + " = {\\frac{{\\ln " + C + " - \\ln " + C0 + "}}{\\Delta " + t + "}} \\]";
        };
    })

    .service('GentVariableService', function () {
        this.C_unknown = function () {
            var RandomC = Math.floor((Math.random() * 4) + 1);
            var RandomC0 = Math.floor((Math.random() * 8) + RandomC);
            var RandomHalfLife = Math.floor((Math.random() * 5) + 1);
            var RandomK = Math.round(0.693 / RandomHalfLife * 1000) / 1000;
            var RandomT = Math.floor((Math.random() * 10) + 1);
            var C = RandomC0 * (Math.exp(-1 * RandomK * RandomT));
            C = Math.round(C * 10) / 10;
            return {
                C: C,
                C0: RandomC0,
                k: RandomK,
                t: RandomT
            };
        };
    })

    .service('PopulationParams', function () {
        this.aminoglycoside = function (age, weight, Scr, gender) {
            var ClCr = (140 - age) * weight / 72 / Scr;
            if (gender == 'female') {
                ClCr = 0.85 * ClCr;
            }
            ClCr = Math.round(ClCr);

            var Vd = randLab((0.21 * weight), (0.27 * weight));
            Vd = Math.round(Vd * 10) / 10;

            var kel = 0.00285 * ClCr + 0.015;
            kel = randLab((kel * 0.8), (kel * 1.2));
            kel = Math.round(kel * 1000) / 1000;

            var halflife = 0.693 / kel;
            halflife = Math.round(halflife * 10) / 10;
            return {
                kel: kel,
                Vd: Vd,
                halflife: halflife,
                ClCr: ClCr
            };
        };
    })

    .service('CreatePatient', function () {

        /* Comes up with a random lab value within a range */

        this.adult = function () {
            if (randrange(0, 10) < 5) {
                var gender = 'male';
                var height = randLab(65, 75);
                var weight = 50 + 2.3 * (height - 60);
            } else {
                var gender = 'female';
                var height = randLab(62, 72);
                var weight = 45.5 + 2.3 * (height - 60);
            }
            height = Math.round(height * 10) / 10;
            weight = randLab(weight * 0.9, weight * 1.1);
            weight = Math.round(weight);

            var age = randrange(18, 85);

            var races = [
                "white",
                "African-American",
                "Asian",
                "Hispanic"
            ];
            var race = races[randrange(0, (races.length - 1))];

            /* Renal Function */
            var creatinine = 0.9;
            var renalfailurerisk = randrange(0, 10);
            if (renalfailurerisk <= 5) {
                creatinine = Math.floor(creatinine * randrange(25, 75) / 5) / 10;
            }
            else if (renalfailurerisk > 5 && renalfailurerisk < 8) {
                creatinine = Math.floor(creatinine * randrange(10, 30)) / 10;
            }
            else if (renalfailurerisk >= 8) {
                creatinine = Math.floor(creatinine * randrange(10, 100)) / 10;
            }
            var BUN = Math.floor(9.5 * creatinine);

            /* Background Normal Labs */
            var Na = Math.floor(randLab(136, 146));
            var K = Math.floor(randLab(3.5, 5.1) * 10) / 10;
            var Cl = Math.floor(randLab(98, 108));
            var C02 = Math.floor(randLab(18, 30));
            var glucose = Math.floor(randLab(74, 106));

            return {
                gender: gender,
                age: age,
                race: race,
                creatinine: creatinine,
                BUN: BUN,
                Na: Na,
                K: K,
                Cl: Cl,
                C02: C02,
                glucose: glucose,
                height: height,
                weight: weight
            };
        };
    });

<|endoftext|>


<commit_before>const fs = require('fs');
const path = require('path');
const Badge = require('../models/badge')("DATABASE");
const Image = require('../models/image')("DATABASE");
const async = require('async');

const openbadger = require('../lib/openbadger');
const middleware = require('../middleware');

const studioPath = 'images/studio/';

function getBadgeById(badgeId, category, callback) {
  if (category === 'draft' || category === 'template') {
    Badge.getOne({ id: badgeId }, { relationships: true }, function(err, row) {
     callback(err, { badge: row } );
   });
  }
  else {
    openbadger.getBadge({ slug: badgeId }, function(err, data) {
      if (err)
        return callback(err);

      data = openbadger.toBadgekitBadge(data);

      callback(err, { badge: data });
    });
  }
}

exports.home = function home (req, res, next) {
  const badgeId = req.params.badgeId;
  const category = req.query.category || 'draft';

  getBadgeById(badgeId, category, function(err, data) {
    if (err)
      return res.send(500, err);

    data.category = category;

    res.render('badge/home.html', data);
  });
};

exports.edit = function edit (req, res, next) {
  const badgeId = req.params.badgeId;
  const section = req.query.section || 'visual';
  const category = req.query.category || 'draft';

  async.parallel([
    function(callback) {
      getBadgeById(badgeId, category, function(err, data) {
        if (err)
          return callback(err);

        data.section = section;
        data.category = category;

        callback(null, data);
      });
    },
    function(callback) {
      fs.readdir(path.join(__dirname, '../static', studioPath, 'shapes'), function(err, files) {
        if (err)
          callback(err);

        var shapes = files.map(function(file) {
          return { id: file,
                   image: res.locals.static(path.join(studioPath, 'shapes', file)) };
        });

        callback(null, shapes);
      });
    }],
    function(err, results) {
      if (err)
        res.send(500, err);

      var data = results[0];
      data.shapes = results[1];

      res.render('badge/edit.html', data);
    }
  );
};

exports.getBackgrounds = function getBackgrounds(req, res, next) {
  fs.readdir(path.join(__dirname, '../static', studioPath, 'backgrounds'), function(err, files) {
    if (err)
      res.send(500, err);

    var backgrounds = files.map(function(file) {
      return { id: file,
               image: res.locals.static(path.join(studioPath, 'backgrounds', file)) };
    });

    res.send(200, { backgrounds: backgrounds });
  });
};

exports.getTexts = function getTexts(req, res, next) {
  fs.readdir(path.join(__dirname, '../static', studioPath, 'texts'), function(err, files) {
    if (err)
      res.send(500, err);

    var texts = files.map(function(file) {
      return { id: file,
               image: res.locals.static(path.join(studioPath, 'texts', file)) };
    });

    res.send(200, { texts: texts });
  });
};

exports.getIcons = function getIcons(req, res, next) {
  fs.readdir(path.join(__dirname, '../static', studioPath, 'icons'), function(err, files) {
    if (err)
      res.send(500, err);

    var icons = files.map(function(file) {
      return { id: file,
               image: res.locals.static(path.join(studioPath, 'icons', file)) };
    });

    res.send(200, { icons: icons });
  });
};

exports.getColors = function getColors(req, res, next) {
  fs.readdir(path.join(__dirname, '../static', studioPath, 'colors'), function(err, files) {
    if (err)
      res.send(500, err);

    var colors = files.map(function(file) {
      return { id: file,
               image: res.locals.static(path.join(studioPath, 'colors', file)) };
    });

    res.send(200, { colors: colors });
  });
};

function saveBadge(req, callback) {
  const timeValue = parseInt(req.body.timeValue, 10);
  const limitNumber = parseInt(req.body.limitNumber, 10);
  const numCriteria = parseInt(req.body.numCriteria, 10);

  const query = {
    id: req.body.badgeId,
    name: req.body.name,
    description: req.body.description,
    tags: req.body.tags,
    issuerUrl: req.body.issuerUrl,
    earnerDescription: req.body.earnerDescription,
    consumerDescription: req.body.consumerDescription,
    rubricUrl: req.body.rubricUrl,
    timeValue: timeValue > 0 ? timeValue : 0,
    timeUnits: req.body.timeUnits,
    limit: req.body.limit == 'limit' ? (limitNumber > 0 ? limitNumber : 0) : 0,
    unique: req.body.unique == 'unique' ? 1 : 0,
    multiClaimCode: req.body.multiClaimCode,
  };

  Badge.put(query, function (err, result) {
    if (err)
      return callback(err);

    Badge.getOne({ id: result.row.id }, function(err, badgeRow) {
      if (err)
        return callback(err);

      async.parallel([
        function(innerCallback) {
          const criteria = req.body.criteria.slice(0,numCriteria).map(function(criterion) {
            return {
              id: criterion.id || null,
              description: criterion.description,
              required: criterion.required == 'on' ? 1 : 0,
              note: criterion.note
            };
          });

          badgeRow.setCriteria(criteria, function(err) {
            return innerCallback(err);
          });
        },
        function(innerCallback) {
          if (req.files) {
            var path = req.files.uploadImage.path;
            var type = req.files.uploadImage.type;

            if (req.files.studioImage) {
              path = req.files.studioImage.path;
              type = req.files.studioImage.type;
            }

            // Need to determine acceptable mime types... this is just accepting everything right now.
            fs.readFile(path, function(err, data) {
              if (err)
                return innerCallback(err);

              const imageQuery = {
                id: badgeRow.imageId,
                mimetype: type,
                data: data
              };

              Image.put(imageQuery, function(err, imageResult) {
                if (err)
                  return innerCallback(err);

                if (badgeRow.imageId === null) {
                  Badge.update({ id: badgeRow.id, imageId: imageResult.insertId }, function(err, result) {
                    return innerCallback(err);
                  });
                }
                else {
                  return innerCallback(null);
                }
              });
            });
          }
          else {
            return innerCallback(null);
          }
        }],
        function(err) {
          callback(err, badgeRow);
        }
      );
    });
  });
};

exports.save = function save (req, res, next) {
  saveBadge(req, function(err, row) {
    if (err)
      return res.send(500, err);

    return middleware.redirect('badge.edit', { badgeId: req.body.badgeId }, 302)(req, res, next);
  });
};

exports.archive = function archive (req, res, next) {
  const badgeId = req.params.badgeId;
  openbadger.getBadge({ slug: badgeId }, function(err, badge) {
    if (err)
      return res.send(500, err);

    badge.archived = true;

    openbadger.updateBadge(badge, function(err) {
      if (err)
        return res.send(500, err);

      return res.send(200);
    });
  });
};

exports.publish = function publish (req, res, next) {
  const badgeId = req.params.badgeId;

  saveBadge(req, function(err, row) {
    if (err)
      return res.send(500, err);

    Badge.getOne({ id: badgeId }, { relationships: true }, function(err, row) {
      if (err)
        return res.send(500, err);

      var badge = openbadger.toOpenbadgerBadge(row);
      openbadger.createBadge(badge, function(err) {
        if (err)
          return res.send(500, err);

        Badge.update({ id: badgeId, published: true }, function(err, result) {
          if (err)
            return res.send(500, err);

          return res.send(200, { location: res.locals.url('directory') + '?category=published' });
        });
      });
    });
  });
};

exports.copy = function copy (req, res, next) {
  const badgeId = req.params.badgeId;
  openbadger.getBadge({ slug: badgeId }, function(err, badge) {
    if (err)
      return res.send(500, err);

    badge = openbadger.toBadgekitBadge(badge);
    delete badge.id;
    Badge.put(badge, function (err, result) {
      if (err)
        return res.send(500, err);

      return res.send(200, { location: res.locals.url('directory') + '?category=draft' })
    });
  });
};

exports.image = function image (req, res, next) {
  const badgeId = req.params.badgeId;

  Badge.getOne({ id: badgeId }, { relationships: true }, function(err, row) {
    if (err)
      return res.send(500, err);

    if (row) {
      if (row.image.id !== null) {
        res.type(row.image.mimetype);
        return res.send(row.image.data);
      }
      else {
        res.sendfile(path.join(__dirname, '../static/images/default-badge.png'));
      }
    }
    else {
      res.send(404);
    }
  });
};

exports.renderIssueByEmail = function renderIssueByEmail (req, res, next) {
  const badgeId = req.params.badgeId;

  openbadger.getBadge({ slug: badgeId }, function(err, data) {
    if (err)
      return res.send(500, err);

    data = openbadger.toBadgekitBadge(data);
    res.render('badge/issue-by-email.html', { badge: data });
  });
};

exports.issueByEmail = function issueByEmail (req, res, next) {
  const query = {
    learner: {
      email: req.body.email
    },
    badge: req.body.badgeId
  };

  // This API endpoint isn't yet implemented, and likely "query" will have to be changed when it is
  openbadger.grantBadgeAward(req.body.badgeId, query, function(err, data) {
    //suppressing errors for now, as this will always result in an error at the moment
    //if (err)
    //  return res.send(500, err);

    return middleware.redirect('directory', 302)(req, res, next);
  });

};

exports.renderIssueByClaimCode = function renderIssueByClaimCode (req, res, next) {
  const badgeId = req.params.badgeId;

  openbadger.getBadge({ slug: badgeId }, function(err, data) {
    if (err)
      return res.send(500, err);

    data = openbadger.toBadgekitBadge(data);
    res.render('badge/issue-by-claim-code.html', { badge: data });
  });
};

exports.issueByClaimCode = function issueByClaimCode (req, res, next) {
  // openbadger does not yet support generation of claim codes via its API
  return middleware.redirect('directory', 302)(req, res, next);
};
<commit_msg>Removing test code<commit_after>const fs = require('fs');
const path = require('path');
const Badge = require('../models/badge')("DATABASE");
const Image = require('../models/image')("DATABASE");
const async = require('async');

const openbadger = require('../lib/openbadger');
const middleware = require('../middleware');

const studioPath = 'images/studio/';

function getBadgeById(badgeId, category, callback) {
  if (category === 'draft' || category === 'template') {
    Badge.getOne({ id: badgeId }, { relationships: true }, function(err, row) {
     callback(err, { badge: row } );
   });
  }
  else {
    openbadger.getBadge({ slug: badgeId }, function(err, data) {
      if (err)
        return callback(err);

      data = openbadger.toBadgekitBadge(data);

      callback(err, { badge: data });
    });
  }
}

exports.home = function home (req, res, next) {
  const badgeId = req.params.badgeId;
  const category = req.query.category || 'draft';

  getBadgeById(badgeId, category, function(err, data) {
    if (err)
      return res.send(500, err);

    data.category = category;

    res.render('badge/home.html', data);
  });
};

exports.edit = function edit (req, res, next) {
  const badgeId = req.params.badgeId;
  const section = req.query.section || 'description';
  const category = req.query.category || 'draft';

  async.parallel([
    function(callback) {
      getBadgeById(badgeId, category, function(err, data) {
        if (err)
          return callback(err);

        data.section = section;
        data.category = category;

        callback(null, data);
      });
    },
    function(callback) {
      fs.readdir(path.join(__dirname, '../static', studioPath, 'shapes'), function(err, files) {
        if (err)
          callback(err);

        var shapes = files.map(function(file) {
          return { id: file,
                   image: res.locals.static(path.join(studioPath, 'shapes', file)) };
        });

        callback(null, shapes);
      });
    }],
    function(err, results) {
      if (err)
        res.send(500, err);

      var data = results[0];
      data.shapes = results[1];

      res.render('badge/edit.html', data);
    }
  );
};

exports.getBackgrounds = function getBackgrounds(req, res, next) {
  fs.readdir(path.join(__dirname, '../static', studioPath, 'backgrounds'), function(err, files) {
    if (err)
      res.send(500, err);

    var backgrounds = files.map(function(file) {
      return { id: file,
               image: res.locals.static(path.join(studioPath, 'backgrounds', file)) };
    });

    res.send(200, { backgrounds: backgrounds });
  });
};

exports.getTexts = function getTexts(req, res, next) {
  fs.readdir(path.join(__dirname, '../static', studioPath, 'texts'), function(err, files) {
    if (err)
      res.send(500, err);

    var texts = files.map(function(file) {
      return { id: file,
               image: res.locals.static(path.join(studioPath, 'texts', file)) };
    });

    res.send(200, { texts: texts });
  });
};

exports.getIcons = function getIcons(req, res, next) {
  fs.readdir(path.join(__dirname, '../static', studioPath, 'icons'), function(err, files) {
    if (err)
      res.send(500, err);

    var icons = files.map(function(file) {
      return { id: file,
               image: res.locals.static(path.join(studioPath, 'icons', file)) };
    });

    res.send(200, { icons: icons });
  });
};

exports.getColors = function getColors(req, res, next) {
  fs.readdir(path.join(__dirname, '../static', studioPath, 'colors'), function(err, files) {
    if (err)
      res.send(500, err);

    var colors = files.map(function(file) {
      return { id: file,
               image: res.locals.static(path.join(studioPath, 'colors', file)) };
    });

    res.send(200, { colors: colors });
  });
};

function saveBadge(req, callback) {
  const timeValue = parseInt(req.body.timeValue, 10);
  const limitNumber = parseInt(req.body.limitNumber, 10);
  const numCriteria = parseInt(req.body.numCriteria, 10);

  const query = {
    id: req.body.badgeId,
    name: req.body.name,
    description: req.body.description,
    tags: req.body.tags,
    issuerUrl: req.body.issuerUrl,
    earnerDescription: req.body.earnerDescription,
    consumerDescription: req.body.consumerDescription,
    rubricUrl: req.body.rubricUrl,
    timeValue: timeValue > 0 ? timeValue : 0,
    timeUnits: req.body.timeUnits,
    limit: req.body.limit == 'limit' ? (limitNumber > 0 ? limitNumber : 0) : 0,
    unique: req.body.unique == 'unique' ? 1 : 0,
    multiClaimCode: req.body.multiClaimCode,
  };

  Badge.put(query, function (err, result) {
    if (err)
      return callback(err);

    Badge.getOne({ id: result.row.id }, function(err, badgeRow) {
      if (err)
        return callback(err);

      async.parallel([
        function(innerCallback) {
          const criteria = req.body.criteria.slice(0,numCriteria).map(function(criterion) {
            return {
              id: criterion.id || null,
              description: criterion.description,
              required: criterion.required == 'on' ? 1 : 0,
              note: criterion.note
            };
          });

          badgeRow.setCriteria(criteria, function(err) {
            return innerCallback(err);
          });
        },
        function(innerCallback) {
          if (req.files) {
            var path = req.files.uploadImage.path;
            var type = req.files.uploadImage.type;

            if (req.files.studioImage) {
              path = req.files.studioImage.path;
              type = req.files.studioImage.type;
            }

            // Need to determine acceptable mime types... this is just accepting everything right now.
            fs.readFile(path, function(err, data) {
              if (err)
                return innerCallback(err);

              const imageQuery = {
                id: badgeRow.imageId,
                mimetype: type,
                data: data
              };

              Image.put(imageQuery, function(err, imageResult) {
                if (err)
                  return innerCallback(err);

                if (badgeRow.imageId === null) {
                  Badge.update({ id: badgeRow.id, imageId: imageResult.insertId }, function(err, result) {
                    return innerCallback(err);
                  });
                }
                else {
                  return innerCallback(null);
                }
              });
            });
          }
          else {
            return innerCallback(null);
          }
        }],
        function(err) {
          callback(err, badgeRow);
        }
      );
    });
  });
};

exports.save = function save (req, res, next) {
  saveBadge(req, function(err, row) {
    if (err)
      return res.send(500, err);

    return middleware.redirect('badge.edit', { badgeId: req.body.badgeId }, 302)(req, res, next);
  });
};

exports.archive = function archive (req, res, next) {
  const badgeId = req.params.badgeId;
  openbadger.getBadge({ slug: badgeId }, function(err, badge) {
    if (err)
      return res.send(500, err);

    badge.archived = true;

    openbadger.updateBadge(badge, function(err) {
      if (err)
        return res.send(500, err);

      return res.send(200);
    });
  });
};

exports.publish = function publish (req, res, next) {
  const badgeId = req.params.badgeId;

  saveBadge(req, function(err, row) {
    if (err)
      return res.send(500, err);

    Badge.getOne({ id: badgeId }, { relationships: true }, function(err, row) {
      if (err)
        return res.send(500, err);

      var badge = openbadger.toOpenbadgerBadge(row);
      openbadger.createBadge(badge, function(err) {
        if (err)
          return res.send(500, err);

        Badge.update({ id: badgeId, published: true }, function(err, result) {
          if (err)
            return res.send(500, err);

          return res.send(200, { location: res.locals.url('directory') + '?category=published' });
        });
      });
    });
  });
};

exports.copy = function copy (req, res, next) {
  const badgeId = req.params.badgeId;
  openbadger.getBadge({ slug: badgeId }, function(err, badge) {
    if (err)
      return res.send(500, err);

    badge = openbadger.toBadgekitBadge(badge);
    delete badge.id;
    Badge.put(badge, function (err, result) {
      if (err)
        return res.send(500, err);

      return res.send(200, { location: res.locals.url('directory') + '?category=draft' })
    });
  });
};

exports.image = function image (req, res, next) {
  const badgeId = req.params.badgeId;

  Badge.getOne({ id: badgeId }, { relationships: true }, function(err, row) {
    if (err)
      return res.send(500, err);

    if (row) {
      if (row.image.id !== null) {
        res.type(row.image.mimetype);
        return res.send(row.image.data);
      }
      else {
        res.sendfile(path.join(__dirname, '../static/images/default-badge.png'));
      }
    }
    else {
      res.send(404);
    }
  });
};

exports.renderIssueByEmail = function renderIssueByEmail (req, res, next) {
  const badgeId = req.params.badgeId;

  openbadger.getBadge({ slug: badgeId }, function(err, data) {
    if (err)
      return res.send(500, err);

    data = openbadger.toBadgekitBadge(data);
    res.render('badge/issue-by-email.html', { badge: data });
  });
};

exports.issueByEmail = function issueByEmail (req, res, next) {
  const query = {
    learner: {
      email: req.body.email
    },
    badge: req.body.badgeId
  };

  // This API endpoint isn't yet implemented, and likely "query" will have to be changed when it is
  openbadger.grantBadgeAward(req.body.badgeId, query, function(err, data) {
    //suppressing errors for now, as this will always result in an error at the moment
    //if (err)
    //  return res.send(500, err);

    return middleware.redirect('directory', 302)(req, res, next);
  });

};

exports.renderIssueByClaimCode = function renderIssueByClaimCode (req, res, next) {
  const badgeId = req.params.badgeId;

  openbadger.getBadge({ slug: badgeId }, function(err, data) {
    if (err)
      return res.send(500, err);

    data = openbadger.toBadgekitBadge(data);
    res.render('badge/issue-by-claim-code.html', { badge: data });
  });
};

exports.issueByClaimCode = function issueByClaimCode (req, res, next) {
  // openbadger does not yet support generation of claim codes via its API
  return middleware.redirect('directory', 302)(req, res, next);
};
<|endoftext|>