<commit_before>var _ = require('lodash'),
	fs = require('fs');

var SwaggerManager = function(options) {

	options = options || {};

	var swaggerHooks = options.swaggerHooks || {};

	var apiDocsCache = {};

	var getRoutesGroupedByName = function(routes) {
			var filteredRoutes = _.filter(routes, function(route) {
				if (route.settings.plugins && route.settings.plugins[options.pluginName]) {
					return (route.settings.plugins[options.pluginName].swagger === undefined || route.settings.plugins[options.pluginName].swagger === true);
				}
				return false;
			});
			return _.groupBy(filteredRoutes, function(route) {
				if (swaggerHooks.routeNameGroup){
					return swaggerHooks.routeNameGroup(route);
				}
				var groupName = route.path;
				if (groupName.lastIndexOf('}') === groupName.length - 1) {
					groupName = groupName.substring(0, groupName.lastIndexOf('/'));
				}
				return groupName.substr(1).replace(/\{/g, '_').replace(/\}/g, '_');
			});
		},

		getRoutesGroupedByPath = function(routes) {
			return _.groupBy(routes, function(item) {
				return item.path;
			});
		},

		getApplicationVersion = function() {
			var executingFile = process.argv[1];
			var packageLoc = findPackageJson(executingFile.replace(/\/[^\/]+?$/g, ''));

			if (packageLoc) {
				return require(packageLoc).version;
			}
			return 'unknown';
		},

		findPackageJson = function(startingDirectory) {
			if (!startingDirectory) {
				return false;
			}
			if (fs.existsSync(startingDirectory + '/package.json')) {
				return startingDirectory + '/package.json';
			}
			return findPackageJson(startingDirectory.replace(/\/[^\/]+?$/g, ''));
		},

		getSwaggerParams = function(route, type, operationNickname) {
			var params = [], prop, param;
			if (swaggerParamTypeMap[type] &&
				route.settings.plugins &&
				route.settings.plugins[options.pluginName] &&
				route.settings.plugins[options.pluginName][type]) {
				var schema = route.settings.plugins[options.pluginName][type];

				if (type === 'payload') {
					// keep an eye on https://github.com/wordnik/swagger-ui/issues/72
					// looks like there might be change as far as body params go

					if (!route.settings.payload || !route.settings.payload.allow || route.settings.payload.allow.indexOf('application/json') >= 0) {
						param = {
							paramType: swaggerParamTypeMap[type],
							name: 'body',
							description: schema.description,
							type: operationNickname ? operationNickname + '_body' : schema.type,
							required: true
						};
						params.push(param);
					}
					else {
						for (prop in schema.properties) {
							if (schema.properties.hasOwnProperty(prop)) {
								var formParam = {
									paramType: 'form',
									name: prop,
									description: schema.properties[prop].description,
									type: schema.properties[prop].type,
									required: (schema.required && schema.required.indexOf(prop) >= 0)
								};
								params.push(formParam);
							}
						}
					}
				}
				else {
					for (prop in schema.properties) {
						if (schema.properties.hasOwnProperty(prop)) {
							param = {
								paramType: swaggerParamTypeMap[type],
								name: prop,
								description: schema.properties[prop].description,
								type: schema.properties[prop].type,
								required: (schema.required && schema.required.indexOf(prop) >= 0)
							};
							if (schema.properties[prop].hasOwnProperty('minimum')) {
								param.minimum = (schema.properties[prop].exclusiveMinimum) ? schema.properties[prop].minimum + 1 : schema.properties[prop].minimum;
							}
							if (schema.properties[prop].hasOwnProperty('maximum')) {
								param.maximum = schema.properties[prop].maximum;
							}
							if (schema.properties[prop].hasOwnProperty('enum')) {
								param.enum = schema.properties[prop].enum;
							}
							params.push(param);
						}
					}
				}
			}

			if (swaggerHooks.params){
				swaggerHooks.params(params, route, type);
			}

			return params;
		},

		getSwaggerOperationForRoute = function(route, resourceType, path) {
			var pathParts = path.split('/'),
				regex = /^\{.+\}$/,
				lastPart = pathParts.pop(),
				resourceId = (regex.test(lastPart)) ? lastPart : null,
				resourceName = (!resourceId) ? lastPart : pathParts.pop(),
				nickname = (!resourceId) ? resourceName : resourceName + '_by_' + resourceId.replace(/[\{\}]*/g, ''),
				operation = {
					method: route.method,
					summary: route.settings.description,
					notes: route.settings.notes,
					tags: route.settings.tags,
					type: 'void',
					nickname: route.method + '_' + nickname,
					parameters: []
				},
				schema,
				plugins = route.settings.plugins;

			if (plugins &&
				plugins[options.pluginName] &&
				plugins[options.pluginName].response){

				if (plugins[options.pluginName].response.schema){
					schema = plugins[options.pluginName].response.schema;

					if (schema.type === 'object') {
						operation.type = operation.nickname + '_response';
					}
					else if (schema.type === 'array') {
						operation.type = schema.type;
						operation.items = { '$ref': operation.nickname + '_response' };
					}
					else {
						operation.type = schema.type;
						operation.description = schema.description;
						operation.defaultValue = schema.defaultValue;
					}
				}

				if (plugins[options.pluginName].response.messages){
					operation.responseMessages = plugins[options.pluginName].response.messages;
				}
			}

			operation.parameters = operation.parameters.concat(getSwaggerParams(route, 'path'));

			operation.parameters = operation.parameters.concat(getSwaggerParams(route, 'query'));

			operation.parameters = operation.parameters.concat(getSwaggerParams(route, 'payload', operation.nickname));

			operation.parameters = operation.parameters.concat(getSwaggerParams(route, 'headers'));

			//TODO: warn if more than 1 param with the same name

			if (swaggerHooks.operation){
				swaggerHooks.operation(operation, route, resourceType, path);
			}

			return operation;
		},

		getModelForRoute = function(route, modelKind, modelGetter){
			var plugins = route.settings.plugins;
			var model;
			if (plugins && plugins[options.pluginName] &&
				plugins[options.pluginName][modelKind] && modelGetter()) {
				model = _.cloneDeep(modelGetter());

				if (model.type === 'array') {
					model = _.cloneDeep(model.items);
				}
				else if (model.type !== 'object') {
					return null;
				}
			}

			return model;
		},

		getRequestModelForRoute = function(route){
			return getModelForRoute(route, 'payload', function(){
				return route.settings.plugins[options.pluginName].payload;
			});
		},

		getResponseModelForRoute = function(route) {
			return getModelForRoute(route, 'response', function(){
				return route.settings.plugins[options.pluginName].response.schema;
			});
		},

		generateNestedModels = function (model, models, prefix, parent){
			if (!model.properties){
				return;
			}

			parent = parent || '';

			Object.keys(model.properties).forEach(function(prop){
				if (model.properties[prop].properties ||
				 	model.properties[prop].type === 'object' ||
				 	(Array.isArray(model.properties[prop].type) &&
				 	model.properties[prop].type.indexOf('object') >= 0)){
					models[prefix + prop] = _.cloneDeep(model.properties[prop]);

					generateNestedModels(model.properties[prop], models, prefix, parent + prop + '.');

					model.properties[prop] = { $ref: prefix + prop};
				}
			});
		},

		swaggerParamTypeMap = {
			path: 'path',
			query: 'query',
			payload: 'body',
			headers: 'header'
		},
		defaultResourceListingModel = {
			apiVersion: options.apiVersion || getApplicationVersion().split('.')[0],
			swaggerVersion: '1.2',
			apis: []
		},
		defaultApiDeclaration = {
			apiVersion: options.apiVersion || getApplicationVersion().split('.')[0],
			swaggerVersion: '1.2',
			basePath: '',
			resourcePath: '',
			produces: null,
			apis: null
		};

	this.isValidApi = function(routes, apiName) {
		var routesByGroupNames = getRoutesGroupedByName(routes);
		return routesByGroupNames.hasOwnProperty(apiName);
	};

	this.getResourceListingModel = function(routes) {
		var routesByGroupNames = getRoutesGroupedByName(routes),
			resourceListingModel = _.cloneDeep(defaultResourceListingModel);

		resourceListingModel.apis = [];
		Object.keys(routesByGroupNames).forEach(function(item) {
			resourceListingModel.apis.push({ path: '/' + item });
		});

		return resourceListingModel;
	};

	this.getApiDeclarationModel = function(routes, apiName) {
		var cached = apiDocsCache[apiName];
		if (cached){
			return cached;
		}

		var routesByGroupNames = getRoutesGroupedByName(routes),
			routesByPath = getRoutesGroupedByPath(routesByGroupNames[apiName]),
			apiObj = _.cloneDeep(defaultApiDeclaration);

		apiObj.apis = [];
		apiObj.basePath = options.baseUrl;
		apiObj.resourcePath = '/' + apiName;
		apiObj.produces = options.responseContentTypes;
		apiObj.consumes = _.chain(routesByPath)
							.map(function(val) { return val; })
							.flatten()
							.map(function(route) {
								var defaults = ['application/json', 'application/x-www-form-urlencoded'];
								if (route.settings.payload && route.settings.payload.parse) {
									return (route.settings.payload.allow) ? route.settings.payload.allow : defaults;
								}
								return null;
							})
							.flatten()
							.uniq()
							.compact()
							.value();

		var models = {};

		for (var prop in routesByPath) {
			if (routesByPath.hasOwnProperty(prop)) {
				var api = {
					path: prop,
					operations: []
				};

				routesByPath[prop].forEach(function(route) {
					var operation = getSwaggerOperationForRoute(route, apiName, prop);
					api.operations.push(operation);

					var responseModel = getResponseModelForRoute(route);

					if (responseModel) {
						models[operation.nickname + '_response'] = responseModel;
						generateNestedModels(responseModel, models, operation.nickname + '_response_');
					}

					var requestModel = getRequestModelForRoute(route);

					if (requestModel) {
						models[operation.nickname + '_body'] = requestModel;
						generateNestedModels(requestModel, models, operation.nickname + '_body_');
					}
				});

				apiObj.apis.push(api);
			}
		}

		if (swaggerHooks.models){
			swaggerHooks.models(models);
		}

		apiObj.models = models;

		apiDocsCache[apiName] = apiObj;

		return apiObj;
	};

};

module.exports = SwaggerManager;<commit_msg>Add 'consumes' attribute in a per operation basis<commit_after>var _ = require('lodash'),
	fs = require('fs');

var SwaggerManager = function(options) {

	options = options || {};

	var swaggerHooks = options.swaggerHooks || {};

	var apiDocsCache = {};

	var consumesDefaults = ['application/json', 'application/x-www-form-urlencoded'];

	var getRoutesGroupedByName = function(routes) {
			var filteredRoutes = _.filter(routes, function(route) {
				if (route.settings.plugins && route.settings.plugins[options.pluginName]) {
					return (route.settings.plugins[options.pluginName].swagger === undefined || route.settings.plugins[options.pluginName].swagger === true);
				}
				return false;
			});
			return _.groupBy(filteredRoutes, function(route) {
				if (swaggerHooks.routeNameGroup){
					return swaggerHooks.routeNameGroup(route);
				}
				var groupName = route.path;
				if (groupName.lastIndexOf('}') === groupName.length - 1) {
					groupName = groupName.substring(0, groupName.lastIndexOf('/'));
				}
				return groupName.substr(1).replace(/\{/g, '_').replace(/\}/g, '_');
			});
		},

		getRoutesGroupedByPath = function(routes) {
			return _.groupBy(routes, function(item) {
				return item.path;
			});
		},

		getApplicationVersion = function() {
			var executingFile = process.argv[1];
			var packageLoc = findPackageJson(executingFile.replace(/\/[^\/]+?$/g, ''));

			if (packageLoc) {
				return require(packageLoc).version;
			}
			return 'unknown';
		},

		findPackageJson = function(startingDirectory) {
			if (!startingDirectory) {
				return false;
			}
			if (fs.existsSync(startingDirectory + '/package.json')) {
				return startingDirectory + '/package.json';
			}
			return findPackageJson(startingDirectory.replace(/\/[^\/]+?$/g, ''));
		},

		getSwaggerParams = function(route, type, operationNickname) {
			var params = [], prop, param;
			if (swaggerParamTypeMap[type] &&
				route.settings.plugins &&
				route.settings.plugins[options.pluginName] &&
				route.settings.plugins[options.pluginName][type]) {
				var schema = route.settings.plugins[options.pluginName][type];

				if (type === 'payload') {
					// keep an eye on https://github.com/wordnik/swagger-ui/issues/72
					// looks like there might be change as far as body params go

					if (!route.settings.payload || !route.settings.payload.allow || route.settings.payload.allow.indexOf('application/json') >= 0) {
						param = {
							paramType: swaggerParamTypeMap[type],
							name: 'body',
							description: schema.description,
							type: operationNickname ? operationNickname + '_body' : schema.type,
							required: true
						};
						params.push(param);
					}
					else {
						for (prop in schema.properties) {
							if (schema.properties.hasOwnProperty(prop)) {
								var formParam = {
									paramType: 'form',
									name: prop,
									description: schema.properties[prop].description,
									type: schema.properties[prop].type,
									required: (schema.required && schema.required.indexOf(prop) >= 0)
								};
								params.push(formParam);
							}
						}
					}
				}
				else {
					for (prop in schema.properties) {
						if (schema.properties.hasOwnProperty(prop)) {
							param = {
								paramType: swaggerParamTypeMap[type],
								name: prop,
								description: schema.properties[prop].description,
								type: schema.properties[prop].type,
								required: (schema.required && schema.required.indexOf(prop) >= 0)
							};
							if (schema.properties[prop].hasOwnProperty('minimum')) {
								param.minimum = (schema.properties[prop].exclusiveMinimum) ? schema.properties[prop].minimum + 1 : schema.properties[prop].minimum;
							}
							if (schema.properties[prop].hasOwnProperty('maximum')) {
								param.maximum = schema.properties[prop].maximum;
							}
							if (schema.properties[prop].hasOwnProperty('enum')) {
								param.enum = schema.properties[prop].enum;
							}
							params.push(param);
						}
					}
				}
			}

			if (swaggerHooks.params){
				swaggerHooks.params(params, route, type);
			}

			return params;
		},

		getSwaggerOperationForRoute = function(route, resourceType, path) {
			var pathParts = path.split('/'),
				regex = /^\{.+\}$/,
				lastPart = pathParts.pop(),
				resourceId = (regex.test(lastPart)) ? lastPart : null,
				resourceName = (!resourceId) ? lastPart : pathParts.pop(),
				nickname = (!resourceId) ? resourceName : resourceName + '_by_' + resourceId.replace(/[\{\}]*/g, ''),
				operation = {
					method: route.method,
					summary: route.settings.description,
					notes: route.settings.notes,
					tags: route.settings.tags,
					type: 'void',
					nickname: route.method + '_' + nickname,
					parameters: []
				},
				schema,
				plugins = route.settings.plugins;

			if (plugins &&
				plugins[options.pluginName] &&
				plugins[options.pluginName].response){

				if (plugins[options.pluginName].response.schema){
					schema = plugins[options.pluginName].response.schema;

					if (schema.type === 'object') {
						operation.type = operation.nickname + '_response';
					}
					else if (schema.type === 'array') {
						operation.type = schema.type;
						operation.items = { '$ref': operation.nickname + '_response' };
					}
					else {
						operation.type = schema.type;
						operation.description = schema.description;
						operation.defaultValue = schema.defaultValue;
					}
				}

				if (plugins[options.pluginName].response.messages){
					operation.responseMessages = plugins[options.pluginName].response.messages;
				}
			}

			operation.parameters = operation.parameters.concat(getSwaggerParams(route, 'path'));

			operation.parameters = operation.parameters.concat(getSwaggerParams(route, 'query'));

			var payloadParameters = getSwaggerParams(route, 'payload', operation.nickname);
			operation.parameters = operation.parameters.concat(payloadParameters);

			operation.parameters = operation.parameters.concat(getSwaggerParams(route, 'headers'));

			setOperationConsumes(payloadParameters, route, operation);

			//TODO: warn if more than 1 param with the same name

			if (swaggerHooks.operation){
				swaggerHooks.operation(operation, route, resourceType, path);
			}

			return operation;
		},

		setOperationConsumes = function (payloadParameters, route, operation) {
			if (!payloadParameters.length) { //if no payload parameters, no consumes attribute
				return;
			}

			if (route.settings.payload && route.settings.payload.allow && route.settings.payload.parse) {
				operation.consumes = route.settings.payload.allow;
			} else {
				operation.consumes = consumesDefaults;
			}
		},

		getModelForRoute = function(route, modelKind, modelGetter){
			var plugins = route.settings.plugins;
			var model;
			if (plugins && plugins[options.pluginName] &&
				plugins[options.pluginName][modelKind] && modelGetter()) {
				model = _.cloneDeep(modelGetter());

				if (model.type === 'array') {
					model = _.cloneDeep(model.items);
				}
				else if (model.type !== 'object') {
					return null;
				}
			}

			return model;
		},

		getRequestModelForRoute = function(route){
			return getModelForRoute(route, 'payload', function(){
				return route.settings.plugins[options.pluginName].payload;
			});
		},

		getResponseModelForRoute = function(route) {
			return getModelForRoute(route, 'response', function(){
				return route.settings.plugins[options.pluginName].response.schema;
			});
		},

		generateNestedModels = function (model, models, prefix, parent){
			if (!model.properties){
				return;
			}

			parent = parent || '';

			Object.keys(model.properties).forEach(function(prop){
				if (model.properties[prop].properties ||
				 	model.properties[prop].type === 'object' ||
				 	(Array.isArray(model.properties[prop].type) &&
				 	model.properties[prop].type.indexOf('object') >= 0)){
					models[prefix + prop] = _.cloneDeep(model.properties[prop]);

					generateNestedModels(model.properties[prop], models, prefix, parent + prop + '.');

					model.properties[prop] = { $ref: prefix + prop};
				}
			});
		},

		swaggerParamTypeMap = {
			path: 'path',
			query: 'query',
			payload: 'body',
			headers: 'header'
		},
		defaultResourceListingModel = {
			apiVersion: options.apiVersion || getApplicationVersion().split('.')[0],
			swaggerVersion: '1.2',
			apis: []
		},
		defaultApiDeclaration = {
			apiVersion: options.apiVersion || getApplicationVersion().split('.')[0],
			swaggerVersion: '1.2',
			basePath: '',
			resourcePath: '',
			produces: null,
			apis: null
		};

	this.isValidApi = function(routes, apiName) {
		var routesByGroupNames = getRoutesGroupedByName(routes);
		return routesByGroupNames.hasOwnProperty(apiName);
	};

	this.getResourceListingModel = function(routes) {
		var routesByGroupNames = getRoutesGroupedByName(routes),
			resourceListingModel = _.cloneDeep(defaultResourceListingModel);

		resourceListingModel.apis = [];
		Object.keys(routesByGroupNames).forEach(function(item) {
			resourceListingModel.apis.push({ path: '/' + item });
		});

		return resourceListingModel;
	};

	this.getApiDeclarationModel = function(routes, apiName) {
		var cached = apiDocsCache[apiName];
		if (cached){
			return cached;
		}

		var routesByGroupNames = getRoutesGroupedByName(routes),
			routesByPath = getRoutesGroupedByPath(routesByGroupNames[apiName]),
			apiObj = _.cloneDeep(defaultApiDeclaration);

		apiObj.apis = [];
		apiObj.basePath = options.baseUrl;
		apiObj.resourcePath = '/' + apiName;
		apiObj.produces = options.responseContentTypes;

		apiObj.consumes = _.chain(routesByPath)
							.map(function(val) { return val; })
							.flatten()
							.map(function(route) {
								if (route.settings.payload && route.settings.payload.parse) {
									return (route.settings.payload.allow) ? route.settings.payload.allow : consumesDefaults;
								}
								return null;
							})
							.flatten()
							.uniq()
							.compact()
							.value();

		var models = {};

		for (var prop in routesByPath) {
			if (routesByPath.hasOwnProperty(prop)) {
				var api = {
					path: prop,
					operations: []
				};

				routesByPath[prop].forEach(function(route) {
					var operation = getSwaggerOperationForRoute(route, apiName, prop);
					api.operations.push(operation);

					var responseModel = getResponseModelForRoute(route);

					if (responseModel) {
						models[operation.nickname + '_response'] = responseModel;
						generateNestedModels(responseModel, models, operation.nickname + '_response_');
					}

					var requestModel = getRequestModelForRoute(route);

					if (requestModel) {
						models[operation.nickname + '_body'] = requestModel;
						generateNestedModels(requestModel, models, operation.nickname + '_body_');
					}
				});

				apiObj.apis.push(api);
			}
		}

		if (swaggerHooks.models){
			swaggerHooks.models(models);
		}

		apiObj.models = models;

		apiDocsCache[apiName] = apiObj;

		return apiObj;
	};

};

module.exports = SwaggerManager;<|endoftext|>


<commit_before>var fs      = require("fs");
var cheerio = require("cheerio");
var _       = require('underscore');
var moment  = require('moment');
var argv    = require('argv');
var net     = require('net');
var path    = require('path');
var repl    = require('repl');
var csv     = require('csv');

// Args
argv.option({
  name: 'input',
  short: 'i',
  type: 'string',
  description: 'Defines schema file to open',
  example: "'beardo.js --schema=value' or 'beardo.js -s data/hours.json"
});

argv.option({
  name: 'format',
  short: 'f',
  type: 'csv,string',
  description: 'Defines output formats with html,cli',
  example: "'beardo.js --format=value' or 'beardo.js -f value1,value2'"
});

argv.option({
  name: 'output',
  short: 'o',
  type: 'string',
  description: 'Defines name to save output files as',
  example: "'beardo.js --save=value' or 'beardo.js -s January Invoice'"
});

argv.option({
  name: 'date',
  short: 'd',
  type: 'string',
  description: 'Returns only by current date (currently month only)',
  example: "'beardo.js --date=value' or 'beardo.js -d January or Jan or 01'"
});

argv.option({
  name: 'trim',
  short: 't',
  type: 'list,string',
  description: 'Trims output by a given string value declared in schema',
  example: "'beardo.js --trim=value' or 'beardo.js -t Client'"
});

var args = argv.run();

// File Manipulation
var SaveFile = require('./lib/save_file');

// Beardo
var Beardo = {};

Beardo.Date = {};

Beardo.Date.full = function(date) {

  var this_date = date.replace(/-/g,'');
  var filter_date = args.options.date.replace(/-/g, '');

  if (this_date >= filter_date) {
    //console.log('this date: 'this_date + ' is greater than filter date: ' + filter_date);
    return true;
  } else {
    return false;
  }
};

Beardo.Date.year_month = function(date) {

  if (date.indexOf(args.options.date) > -1) {
    //console.log('date filter by year_month ' + date);
    return true;
  } else {
    return false;
  }
};

Beardo.Date.month_day = function(date) {

  if (date.indexOf(args.options.date) > -1) {
    //console.log('date filter by month_day ' + date);
    return true;
  } else {
    return false;
  }
};

Beardo.Date.year = function(date) {

  if (date.indexOf(args.options.date) > -1) {
    //console.log('date filter by year ' + date);
    return true;
  } else {
    return false;
  }
};

Beardo.Date.month = function(date) {

  var date_trim = args.options.date.toLowerCase();
  var date_full = moment(date).format('MMMM').toLowerCase();
  var date_abbr = moment(date).format('MMM').toLowerCase();
  var date_numb = moment(date).format('MM').toLowerCase();

  if (_.indexOf([date_full, date_abbr, date_numb], date_trim) > -1) {
    //console.log('date matches filter: ' + date_trim)
    return true;
  } else {
    return false;
  }
};

Beardo.Date.none = function(parts) {
  console.log('no date filtering performed');
};

Beardo.Trim = function(parts) {
  if (args.options.trim !== undefined) {

    var part = parts[3].trim();

    if (_.indexOf(args.options.trim, part) > -1) {
      //console.log('client: ' + part + ' matches: ' + args.options.trim);
      return true;
    } else {
      return false;
    }
  } else {
    return true;
  }
};

// Load Data & Parse
Beardo.Twirl = function(path, resource) {

  var resource_file = path + '/' + resource.path;

  fs.exists(resource_file, function(exists) {
  	if (exists) {

  		console.log('Beardo is twirling some data');

      fs.stat(resource_file, function(error, stats) {
        fs.open(resource_file, "r", function(error, fd) {

          var buffer = new Buffer(stats.size);

          fs.read(fd, buffer, 0, buffer.length, null, function(error, bytesRead, buffer) {
            fs.close(fd);

            var data = buffer.toString("utf8", 0, buffer.length);
            // var lines = data.split("\n");
            // delete lines[0];

            var hours = 0;

            // Totals (for tallying)
            // console.log(resource.schema.fields);
            var outputs = {
              totals: {
                hours: 0,
                money: 0.00,
              },
              cli: '',
              html: ''
            };

            // Make Totals
            var increment_output = function(item) {

              outputs.totals.hours += item.time;
              outputs.totals.money += (item.time * item.rate);

              // CLI format
              outputs.cli += item.date + ' ' + item.time + ' \t' + item.client + ' \t' + item.description + '\n';

              // HTML format
              if (_.indexOf(args.options.format, 'html') > -1) {
                outputs.html += '
\n';
                outputs.html += '   ' + item.date + '	\n';
                outputs.html += '   ' + item.time + '	\n';
                outputs.html += '    hrs	\n';
                outputs.html += '   ' + item.description + '	\n';
                outputs.html += '
\n';
              }
            };

            var mapLineToSchema = function(parts, schema, fields){
              // line is the line being processed,
              // schema is the schema provided in the resource,
              // fields is the fields required in the output, if blank it
              // defaults to everything in the schema.
              // var parts = line.split(',');
              var lineItem = {};

              _.each(schema.fields, function(field, index){
                if (fields === undefined || fields.indexOf(field.name) !== -1){
                  var parsed;

                  if (field.type === 'date') {
                    parsed = moment(parts[index]).format('D MMM');
                  }
                  if (field.type === 'number'){
                    parsed = parseFloat(parts[index]);
                  }
                  if (field.type === 'string'){
                    parsed = parts[index].trim();
                  }
                  if (field.type === 'boolean'){
                    parsed = parts[index];
                    if (parsed === 'yes') parsed = true;
                    else if (parsed === 'no') parse = false;
                  }

                  // For Output
                  lineItem[field.name] = parsed;

                }
              });
              return lineItem;
            };

            // Filter by Date / Type
            var date_filter = 'none';

            if (args.options.date !== undefined) {

              var is_date_full        = /[0-9]{4}-[0-9]{2}-[0-9]{2}/;
              var is_date_year_month  = /[0-9]{4}-[0-9]{2}/;
              var is_date_month_day   = /[0-9]{2}-[0-9]{2}/;
              var is_date_year        = /[0-9]{4}/;

              if (is_date_full.exec(args.options.date)) {
                date_filter = 'full';
              } else if (is_date_year_month.exec(args.options.date)) {
                date_filter = 'year_month';
              } else if (is_date_month_day.exec(args.options.date)) {
                date_filter = 'month_day';
              } else if (is_date_year.exec(args.options.date)) {
                date_filter = 'year';
              } else {
                date_filter = 'month';
              }

              console.log('filter date by: ' + date_filter);
            }

            // Loop Through Items

            csv.parse(data, function(err, data){
              if (err){
                console.log("Had a problem with the CSV File: ", err);
              }
              _.each(data, function(line, index){
                if (index !== 0){ // skip the first line
                  var parts = line;
                  // Filter Date & Trim
                  var check_date = Beardo.Date[date_filter](parts[0]);
                  var check_trim = Beardo.Trim(parts);

                  if (_.indexOf([check_date, check_trim], false) === -1) {
                    var item_output = mapLineToSchema(line, resource.schema);

                    increment_output(item_output);
                  }
                }
              });

              // FIXME: OUTPUT STUFF (Refactor out)
              console.log('-----------------------------------------------------------------------------');
              console.log('Output Formats: ' + args.options.format);
              console.log('-----------------------------------------------------------------------------');
              console.log(outputs.cli);
              console.log('-----------------------------------------------------------------------------');
              console.log('Total hours worked: ' + outputs.totals.hours);
              console.log('Total monies earned: $' + outputs.totals.money);

              // Output HTML
              if (_.indexOf(args.options.format, 'html') > -1) {

                // Get HTML Template
                var template_path = './templates/invoice.html';

                // Open
                fs.exists(template_path, function(exists) {
                  if (exists) {

                    console.log('Beardo loaded template');
                    fs.stat(template_path, function(error, stats) {
                      fs.open(template_path, "r", function(error, fd) {
                        var buffer = new Buffer(stats.size);
                        fs.read(fd, buffer, 0, buffer.length, null, function(error, bytesRead, buffer) {
                          fs.close(fd);

                          // Invoice Name
                          var output_name = 'Beardo - ' + moment().format('D MMMM YYYY');
                          if (args.options.output) {
                            output_name = args.options.output;
                          }

                          var template_file = buffer.toString("utf8", 0, buffer.length);
                          var template_html = _.template(template_file);
                          var output_html   = template_html({
                            generated_name: output_name,
                            generated_date: moment().format('Do MMMM, YYYY'),
                            hours_rows: outputs.html,
                            hours_total: outputs.totals.hours,
                            money_total: outputs.totals.money
                          });

                          var saveFile = new SaveFile(fs, 'output/' + output_name + '.html', output_html);

                        });
                      });
                    });
                  }
                });
              }

            });
          });
        });
      });
  	}
  	else {
      console.log('awwww no data');
  	}

  });

};

// Load Schema
Beardo.Grow = function(schema_file) {

  fs.exists(schema_file, function(exists) {
  	if (exists) {

  		console.log('Splendid schema exists open it up');

      var path = require('path').dirname(schema_file);

      fs.stat(schema_file, function(error, stats) {
        fs.open(schema_file, "r", function(error, fd) {

          var buffer = new Buffer(stats.size);

          fs.read(fd, buffer, 0, buffer.length, null, function(error, bytesRead, buffer) {
            fs.close(fd);

            var json = buffer.toString("utf8", 0, buffer.length);
            var schema = JSON.parse(json);

            console.log('Get item from schema: ' + schema[0].name);

            // If Schema Contains Multiple
            _.each(schema[0].resources, function(resource, key) {

              console.log('Twirl resource: ' + resource.path);

              // Open Data
              Beardo.Twirl(path, resource);

            });

          });

        });
      });

    }
    else {
      console.log('awwww no schema');
    }

  });
};

// Start It Up
if (args.options.input !== undefined) {
  Beardo.Grow(args.options.input);
} else {
  console.log('404 No beard found \nAre you sure you specified an --input -i value');
}

<commit_msg>typo in argv help line<commit_after>var fs      = require("fs");
var cheerio = require("cheerio");
var _       = require('underscore');
var moment  = require('moment');
var argv    = require('argv');
var net     = require('net');
var path    = require('path');
var repl    = require('repl');
var csv     = require('csv');

// Args
argv.option({
  name: 'input',
  short: 'i',
  type: 'string',
  description: 'Defines schema file to open',
  example: "'beardo.js --input=value' or 'beardo.js -i data/hours.json"
});

argv.option({
  name: 'format',
  short: 'f',
  type: 'csv,string',
  description: 'Defines output formats with html,cli',
  example: "'beardo.js --format=value' or 'beardo.js -f value1,value2'"
});

argv.option({
  name: 'output',
  short: 'o',
  type: 'string',
  description: 'Defines name to save output files as',
  example: "'beardo.js --save=value' or 'beardo.js -s January Invoice'"
});

argv.option({
  name: 'date',
  short: 'd',
  type: 'string',
  description: 'Returns only by current date (currently month only)',
  example: "'beardo.js --date=value' or 'beardo.js -d January or Jan or 01'"
});

argv.option({
  name: 'trim',
  short: 't',
  type: 'list,string',
  description: 'Trims output by a given string value declared in schema',
  example: "'beardo.js --trim=value' or 'beardo.js -t Client'"
});

var args = argv.run();

// File Manipulation
var SaveFile = require('./lib/save_file');

// Beardo
var Beardo = {};

Beardo.Date = {};

Beardo.Date.full = function(date) {

  var this_date = date.replace(/-/g,'');
  var filter_date = args.options.date.replace(/-/g, '');

  if (this_date >= filter_date) {
    //console.log('this date: 'this_date + ' is greater than filter date: ' + filter_date);
    return true;
  } else {
    return false;
  }
};

Beardo.Date.year_month = function(date) {

  if (date.indexOf(args.options.date) > -1) {
    //console.log('date filter by year_month ' + date);
    return true;
  } else {
    return false;
  }
};

Beardo.Date.month_day = function(date) {

  if (date.indexOf(args.options.date) > -1) {
    //console.log('date filter by month_day ' + date);
    return true;
  } else {
    return false;
  }
};

Beardo.Date.year = function(date) {

  if (date.indexOf(args.options.date) > -1) {
    //console.log('date filter by year ' + date);
    return true;
  } else {
    return false;
  }
};

Beardo.Date.month = function(date) {

  var date_trim = args.options.date.toLowerCase();
  var date_full = moment(date).format('MMMM').toLowerCase();
  var date_abbr = moment(date).format('MMM').toLowerCase();
  var date_numb = moment(date).format('MM').toLowerCase();

  if (_.indexOf([date_full, date_abbr, date_numb], date_trim) > -1) {
    //console.log('date matches filter: ' + date_trim)
    return true;
  } else {
    return false;
  }
};

Beardo.Date.none = function(parts) {
  console.log('no date filtering performed');
};

Beardo.Trim = function(parts) {
  if (args.options.trim !== undefined) {

    var part = parts[3].trim();

    if (_.indexOf(args.options.trim, part) > -1) {
      //console.log('client: ' + part + ' matches: ' + args.options.trim);
      return true;
    } else {
      return false;
    }
  } else {
    return true;
  }
};

// Load Data & Parse
Beardo.Twirl = function(path, resource) {

  var resource_file = path + '/' + resource.path;

  fs.exists(resource_file, function(exists) {
  	if (exists) {

  		console.log('Beardo is twirling some data');

      fs.stat(resource_file, function(error, stats) {
        fs.open(resource_file, "r", function(error, fd) {

          var buffer = new Buffer(stats.size);

          fs.read(fd, buffer, 0, buffer.length, null, function(error, bytesRead, buffer) {
            fs.close(fd);

            var data = buffer.toString("utf8", 0, buffer.length);
            // var lines = data.split("\n");
            // delete lines[0];

            var hours = 0;

            // Totals (for tallying)
            // console.log(resource.schema.fields);
            var outputs = {
              totals: {
                hours: 0,
                money: 0.00,
              },
              cli: '',
              html: ''
            };

            // Make Totals
            var increment_output = function(item) {

              outputs.totals.hours += item.time;
              outputs.totals.money += (item.time * item.rate);

              // CLI format
              outputs.cli += item.date + ' ' + item.time + ' \t' + item.client + ' \t' + item.description + '\n';

              // HTML format
              if (_.indexOf(args.options.format, 'html') > -1) {
                outputs.html += '
\n';
                outputs.html += '   ' + item.date + '	\n';
                outputs.html += '   ' + item.time + '	\n';
                outputs.html += '    hrs	\n';
                outputs.html += '   ' + item.description + '	\n';
                outputs.html += '
\n';
              }
            };

            var mapLineToSchema = function(parts, schema, fields){
              // line is the line being processed,
              // schema is the schema provided in the resource,
              // fields is the fields required in the output, if blank it
              // defaults to everything in the schema.
              // var parts = line.split(',');
              var lineItem = {};

              _.each(schema.fields, function(field, index){
                if (fields === undefined || fields.indexOf(field.name) !== -1){
                  var parsed;

                  if (field.type === 'date') {
                    parsed = moment(parts[index]).format('D MMM');
                  }
                  if (field.type === 'number'){
                    parsed = parseFloat(parts[index]);
                  }
                  if (field.type === 'string'){
                    parsed = parts[index].trim();
                  }
                  if (field.type === 'boolean'){
                    parsed = parts[index];
                    if (parsed === 'yes') parsed = true;
                    else if (parsed === 'no') parse = false;
                  }

                  // For Output
                  lineItem[field.name] = parsed;

                }
              });
              return lineItem;
            };

            // Filter by Date / Type
            var date_filter = 'none';

            if (args.options.date !== undefined) {

              var is_date_full        = /[0-9]{4}-[0-9]{2}-[0-9]{2}/;
              var is_date_year_month  = /[0-9]{4}-[0-9]{2}/;
              var is_date_month_day   = /[0-9]{2}-[0-9]{2}/;
              var is_date_year        = /[0-9]{4}/;

              if (is_date_full.exec(args.options.date)) {
                date_filter = 'full';
              } else if (is_date_year_month.exec(args.options.date)) {
                date_filter = 'year_month';
              } else if (is_date_month_day.exec(args.options.date)) {
                date_filter = 'month_day';
              } else if (is_date_year.exec(args.options.date)) {
                date_filter = 'year';
              } else {
                date_filter = 'month';
              }

              console.log('filter date by: ' + date_filter);
            }

            // Loop Through Items

            csv.parse(data, function(err, data){
              if (err){
                console.log("Had a problem with the CSV File: ", err);
              }
              _.each(data, function(line, index){
                if (index !== 0){ // skip the first line
                  var parts = line;
                  // Filter Date & Trim
                  var check_date = Beardo.Date[date_filter](parts[0]);
                  var check_trim = Beardo.Trim(parts);

                  if (_.indexOf([check_date, check_trim], false) === -1) {
                    var item_output = mapLineToSchema(line, resource.schema);

                    increment_output(item_output);
                  }
                }
              });

              // FIXME: OUTPUT STUFF (Refactor out)
              console.log('-----------------------------------------------------------------------------');
              console.log('Output Formats: ' + args.options.format);
              console.log('-----------------------------------------------------------------------------');
              console.log(outputs.cli);
              console.log('-----------------------------------------------------------------------------');
              console.log('Total hours worked: ' + outputs.totals.hours);
              console.log('Total monies earned: $' + outputs.totals.money);

              // Output HTML
              if (_.indexOf(args.options.format, 'html') > -1) {

                // Get HTML Template
                var template_path = './templates/invoice.html';

                // Open
                fs.exists(template_path, function(exists) {
                  if (exists) {

                    console.log('Beardo loaded template');
                    fs.stat(template_path, function(error, stats) {
                      fs.open(template_path, "r", function(error, fd) {
                        var buffer = new Buffer(stats.size);
                        fs.read(fd, buffer, 0, buffer.length, null, function(error, bytesRead, buffer) {
                          fs.close(fd);

                          // Invoice Name
                          var output_name = 'Beardo - ' + moment().format('D MMMM YYYY');
                          if (args.options.output) {
                            output_name = args.options.output;
                          }

                          var template_file = buffer.toString("utf8", 0, buffer.length);
                          var template_html = _.template(template_file);
                          var output_html   = template_html({
                            generated_name: output_name,
                            generated_date: moment().format('Do MMMM, YYYY'),
                            hours_rows: outputs.html,
                            hours_total: outputs.totals.hours,
                            money_total: outputs.totals.money
                          });

                          var saveFile = new SaveFile(fs, 'output/' + output_name + '.html', output_html);

                        });
                      });
                    });
                  }
                });
              }

            });
          });
        });
      });
  	}
  	else {
      console.log('awwww no data');
  	}

  });

};

// Load Schema
Beardo.Grow = function(schema_file) {

  fs.exists(schema_file, function(exists) {
  	if (exists) {

  		console.log('Splendid schema exists open it up');

      var path = require('path').dirname(schema_file);

      fs.stat(schema_file, function(error, stats) {
        fs.open(schema_file, "r", function(error, fd) {

          var buffer = new Buffer(stats.size);

          fs.read(fd, buffer, 0, buffer.length, null, function(error, bytesRead, buffer) {
            fs.close(fd);

            var json = buffer.toString("utf8", 0, buffer.length);
            var schema = JSON.parse(json);

            console.log('Get item from schema: ' + schema[0].name);

            // If Schema Contains Multiple
            _.each(schema[0].resources, function(resource, key) {

              console.log('Twirl resource: ' + resource.path);

              // Open Data
              Beardo.Twirl(path, resource);

            });

          });

        });
      });

    }
    else {
      console.log('awwww no schema');
    }

  });
};

// Start It Up
if (args.options.input !== undefined) {
  Beardo.Grow(args.options.input);
} else {
  console.log('404 No beard found \nAre you sure you specified an --input -i value');
}

<|endoftext|>


<commit_before>import React from 'react';
import Menu from './Menu.react';

import {
	RouteHandler
} from 'react-router';

class MainApp extends React.Component {
	render() {
		return (

UniJS Demo

				<Menu></Menu>

				<RouteHandler/>

		);
	}
}
export
default MainApp;
<commit_msg>Clean Up<commit_after>import React from 'react';
import Menu from './Menu.react';

import {
	RouteHandler
} from 'react-router';

class Main extends React.Component {
	render() {
		return (

UniJS Demo

				<Menu></Menu>

				<RouteHandler/>

		);
	}
}
export
default Main;
<|endoftext|>


<commit_before>function subscriberManagementPage() {
  var $page = $('#subscriber-management-page')
  var $subscribers = $page.find('.subscribers-list')
  var $subscriberNameQuery = $page.find('#subscriber-name-query')

  $page.on('show', function(event, subscriberId) {
    updateLocationHash(subscriberId || '')
    $.get('/subscribers?' + $.param({ roles: currentFilters() }), function(subscribers) {
      renderSubscribers(subscribers)

      // Apply subscriber search
      $subscriberNameQuery.trigger('input')

      if (subscriberId) {
        var $selected = $subscribers.find('.result[data-id=' + subscriberId + ']')
        openDetails($selected)
        var top = $selected.offset().top - 25
        $('body,html').animate({ scrollTop: top })
      }
    })
  })

  $subscriberNameQuery.on('input', function() {
    var searchString = $(this).val().toLowerCase()
    $subscribers.find('.result').each(function() {
      var name = $(this).children('.name').text().toLowerCase()
      $(this).toggle(_.contains(name, searchString))
    })
    closeDetails()
  })

  $page.find('.filters').change(function() { $page.trigger('show') })

  $subscribers.on('click', '.result', function() {
    var $this = $(this)
    var wasSelected = $this.hasClass('selected')
    closeDetails()
    if (!wasSelected) {
      openDetails($this)
    }
  })

  $page.find('button[name=new-subscriber]').on('click', function() {
    var $newSubscriberForm = renderSubscriberDetails()

    $newSubscriberForm.find('.modify-only').remove()

    bindEventHandlers($newSubscriberForm, function(subscriberData) {
      subscriberData.roles = $newSubscriberForm.find('input[name=roles]')
        .filter(':checked').map(function() { return $(this).val() }).toArray()

      $.post('/accounts/', JSON.stringify(subscriberData), function(subscriber) {
        $subscribers.find('.result.selected').data('subscriber', subscriber)
        var $subscriber = renderSubscriber(subscriber).css('display', 'none')
        $subscribers.prepend($subscriber)
        $subscriber.slideToggle()
        closeDetails()
      })
    })

    $newSubscriberForm.find('input[name=roles]').on('change', function() {
      var $roles = $newSubscriberForm.find('input[name=roles]')
      if ($newSubscriberForm.find('input[name=roles]:checked').length >= 1) {
        $roles.get().forEach(function(e) { e.setCustomValidity('') })
      } else {
        $roles.get().forEach(function(e) { e.setCustomValidity('You must choose at least one role') })
      }
    })

    // This triggers validation for roles checkboxes, which are by default invalid
    $newSubscriberForm.find('input[name=roles]').trigger('change')

    closeDetails()
    $subscribers.addClass('selected').prepend($newSubscriberForm)
    $newSubscriberForm.slideDown()
  })

  function openDetails($row) {
    var subscriber = $row.data('subscriber')
    var $subscriberDetails = renderSubscriberDetails(subscriber)

    $subscriberDetails.find('.new-only').remove()
    $subscriberDetails.find('button[name=remove]').toggle(utils.hasRole(user, 'root'))

    bindEventHandlers($subscriberDetails, function(subscriberData) {
      $.ajax('/accounts/' + subscriber._id, { type: 'PUT', data: JSON.stringify(subscriberData) })
        .done(function(subscriber) {
          $subscribers.find('.result.selected').replaceWith(renderSubscriber(subscriber))
          closeDetails()
      })
    })

    $row.addClass('selected').after($subscriberDetails)
    updateLocationHash(subscriber._id)
    $subscriberDetails.slideDown()
  }

  function bindEventHandlers($subscriberDetails, submitCallback) {
    var $form = $subscriberDetails.find('form')

    $form.submit(function(event) {
      event.preventDefault()

      var subscriberData = {
        name: findInput('name').val(),
        emailAddresses: _.pluck(findInput('emailAddresses').select2('data'), 'text'),
        yTunnus: findInput('yTunnus').val(),
        address: {
          street: findInput('address.street').val(),
          city: findInput('address.city').val(),
          zip: findInput('address.zip').val(),
          country: findInput('address.country').val()
        },
        billing: {
          invoiceText: $form.find('textarea[name="billing.invoiceText"]').val(),
          language: findInput('billing.language').val()
        },
        eInvoice: {},
        contactName: findInput('contactName').val(),
        phoneNumber: findInput('phoneNumber').val(),
        users: findInput('classifiers').select2('data').map(select2OptionToIdNamePair)
      }
      if ($form.find('input[name=billing-extra]').prop('checked')) {
        var extraBillingType = $form.find('input[name=billing-extra-type]:checked').val()
        if (extraBillingType === 'address') {
          subscriberData.billing.address = {
            street: findInput('billing.address.street').val(),
            city: findInput('billing.address.city').val(),
            zip: findInput('billing.address.zip').val(),
            country: findInput('billing.address.country').val()
          }
        } else if (extraBillingType === 'eInvoice') {
          subscriberData.eInvoice = {
            address: findInput('eInvoice.address').val(),
            operator: findInput('eInvoice.operator').val()
          }
        }
      }

      submitCallback(subscriberData)

      function findInput(name) {
        return $subscriberDetails.find('input[name="' + name + '"]')
      }
    })

    $form.find('input').on('blur select2-blur', function() { $(this).addClass('touched') })

    $form.find('input.select2-offscreen').on('change validate', function() {
      $(this).toggleClass('invalid', !this.checkValidity())
    })

    $form.on('input change', _.debounce(function() { $(this).trigger('validate') }, 200))

    $form.on('validate', function() {
      $(this).find('button[type=submit]').prop('disabled', !this.checkValidity())
    })

    $form.find('input[name=emailAddresses]').on('change', function(event) {
      var emails = event.val
      if (!_.isEmpty(emails) && _.all(emails, validateEmail)) {
        this.setCustomValidity('')
      } else {
        this.setCustomValidity('Invalid email')
      }
      $(this).trigger('validate')

      function validateEmail(email) {
        return new RegExp('.+@.+\\..+').test(email)
      }
    })

    $subscriberDetails.find('button[name=remove]').click(function() {
      var $selected = $page.find('.result.selected')
      var subscriber = $selected.data('subscriber')
      showDialog($('#templates').find('.remove-subscriber-dialog').clone()
        .find('.subscriber-name').text(subscriber.name).end()
        .find('button[name=remove]').click(removeSubscriber).end()
        .find('button[name=cancel]').click(closeDialog).end())

      function removeSubscriber() {
        $.ajax('/accounts/' + subscriber._id, { type: 'DELETE' }).done(function() {
          closeDialog()
          closeDetails()
          $selected.slideUp(function() { $(this).remove() })
        })
      }
    })
  }

  function closeDetails() {
    $subscribers.find('.result.selected').removeClass('selected')
    $subscribers.find('.subscriber-details').slideUp(function() { $(this).remove() })
    updateLocationHash('')
  }

  function updateLocationHash(subscriberId) {
    location.hash = '#tilaajat/' + subscriberId
  }

  function renderSubscribers(subscribers) {
    $subscribers.empty()
    _(subscribers).sortBy('name').map(renderSubscriber).forEach(function(acc) { $subscribers.append(acc) })
  }

  function renderSubscriber(subscriber) {
    return $('
', { class: 'result', 'data-id': subscriber._id })
      .data('subscriber', subscriber)
      .append($('', { class: 'name' }).text(subscriber.name))
      .append($('', { class: 'roles' }).html(renderRoles(subscriber.roles)))

    function renderRoles(roles) {
      if (_.isEmpty(roles)) return ''
      return _.map(roles, function(role) { return enums.roles[role] }).join(', ')
    }
  }

  function currentFilters() {
    return $page.find('.filters input').filter(':checked').map(function() { return $(this).attr('name') }).toArray()
  }

  function renderSubscriberDetails(subscriber) {
    var $subscriberDetails = $('#templates').find('.subscriber-details').clone()
    var eInvoice = utils.getProperty(subscriber, 'eInvoice')
    var billingAddress = utils.getProperty(subscriber, 'billing.address')
    var extraBillingType = _.isEmpty(billingAddress) ? 'eInvoice' : 'address'

    $subscriberDetails.find('input[name], textarea[name]').each(_.partial(setInputValWithProperty, subscriber))

    $subscriberDetails.find('input[name=billing-extra], input[name=billing-extra-type]').on('click', toggleBillingExtra)

    select2Autocomplete({
      $el: $subscriberDetails.find('input[name=classifiers]'),
      path: function(term) { return '/users/search?q=' + encodeURIComponent(term) },
      multiple: true,
      toOption: accountToSelect2Option,
      fromOption: select2OptionToIdNamePair
    })

    $subscriberDetails
      .find('input[name=classifiers]').trigger('setVal', utils.getProperty(subscriber, 'users')).end()
      .find('input[name="address.country"]').select2({ data: select2DataFromEnumObject(enums.countries) }).end()
      .find('input[name=emailAddresses]').select2({ tags: [], multiple: true }).end()
      .find('input[name="billing.address.country"]').select2({ data: select2DataFromEnumObject(enums.countries) }).end()
      .find('input[name=billing-extra]').prop('checked', !(_.isEmpty(billingAddress) && _.isEmpty(eInvoice))).end()
      .find('input[name=billing-extra-type][value=' + extraBillingType + ']').prop('checked', true).end()
      .find('input[name="billing.language"]').select2({ data: select2DataFromEnumObject(enums.billingLanguages) }).end()

    toggleBillingExtra($subscriberDetails)

    return $subscriberDetails

    function setInputValWithProperty(object) {
      var name = $(this).attr('name')
      var property = utils.getProperty(object, name)
      if (property !== undefined) $(this).val(property)
    }

    function accountToSelect2Option(account) {
      if (!account) return null
      return {
        id: account._id,
        text: account.name + (account.username ? ' (' + account.username + ')' : ''),
        name: account.username ? account.username : account.name
      }
    }

    function toggleBillingExtra() {
      var extraBillingEnabled = $subscriberDetails.find('input[name=billing-extra]').prop('checked')
      $subscriberDetails.find('.billing-extra-fields input').prop('disabled', !extraBillingEnabled)

      if (extraBillingEnabled) {
        var type = $subscriberDetails.find('input[name=billing-extra-type]:checked').val()
        var $addressInputs = $subscriberDetails.find('.billing-extra-fields .billing-address input')
        var $eInvoiceInputs = $subscriberDetails.find('.billing-extra-fields .eInvoice input')

        $addressInputs.prop('disabled', type === 'eInvoice')
        $eInvoiceInputs.prop('disabled', type === 'address')
      }
    }
  }

  function select2OptionToIdNamePair(x) {
    if (!x) return null
    return { _id: x.id, name: x.name }
  }

}
<commit_msg>Trigger select2 validation when opening form<commit_after>function subscriberManagementPage() {
  var $page = $('#subscriber-management-page')
  var $subscribers = $page.find('.subscribers-list')
  var $subscriberNameQuery = $page.find('#subscriber-name-query')

  $page.on('show', function(event, subscriberId) {
    updateLocationHash(subscriberId || '')
    $.get('/subscribers?' + $.param({ roles: currentFilters() }), function(subscribers) {
      renderSubscribers(subscribers)

      // Apply subscriber search
      $subscriberNameQuery.trigger('input')

      if (subscriberId) {
        var $selected = $subscribers.find('.result[data-id=' + subscriberId + ']')
        openDetails($selected)
        var top = $selected.offset().top - 25
        $('body,html').animate({ scrollTop: top })
      }
    })
  })

  $subscriberNameQuery.on('input', function() {
    var searchString = $(this).val().toLowerCase()
    $subscribers.find('.result').each(function() {
      var name = $(this).children('.name').text().toLowerCase()
      $(this).toggle(_.contains(name, searchString))
    })
    closeDetails()
  })

  $page.find('.filters').change(function() { $page.trigger('show') })

  $subscribers.on('click', '.result', function() {
    var $this = $(this)
    var wasSelected = $this.hasClass('selected')
    closeDetails()
    if (!wasSelected) {
      openDetails($this)
    }
  })

  $page.find('button[name=new-subscriber]').on('click', function() {
    var $newSubscriberForm = renderSubscriberDetails()

    $newSubscriberForm.find('.modify-only').remove()

    bindEventHandlers($newSubscriberForm, function(subscriberData) {
      subscriberData.roles = $newSubscriberForm.find('input[name=roles]')
        .filter(':checked').map(function() { return $(this).val() }).toArray()

      $.post('/accounts/', JSON.stringify(subscriberData), function(subscriber) {
        $subscribers.find('.result.selected').data('subscriber', subscriber)
        var $subscriber = renderSubscriber(subscriber).css('display', 'none')
        $subscribers.prepend($subscriber)
        $subscriber.slideToggle()
        closeDetails()
      })
    })

    $newSubscriberForm.find('input[name=roles]').on('change', function() {
      var $roles = $newSubscriberForm.find('input[name=roles]')
      if ($newSubscriberForm.find('input[name=roles]:checked').length >= 1) {
        $roles.get().forEach(function(e) { e.setCustomValidity('') })
      } else {
        $roles.get().forEach(function(e) { e.setCustomValidity('You must choose at least one role') })
      }
    })

    // This triggers validation for roles checkboxes, which are by default invalid
    $newSubscriberForm.find('input[name=roles]').trigger('change')

    closeDetails()
    $subscribers.addClass('selected').prepend($newSubscriberForm)
    $newSubscriberForm.slideDown()
  })

  function openDetails($row) {
    var subscriber = $row.data('subscriber')
    var $subscriberDetails = renderSubscriberDetails(subscriber)

    $subscriberDetails.find('.new-only').remove()
    $subscriberDetails.find('button[name=remove]').toggle(utils.hasRole(user, 'root'))

    bindEventHandlers($subscriberDetails, function(subscriberData) {
      $.ajax('/accounts/' + subscriber._id, { type: 'PUT', data: JSON.stringify(subscriberData) })
        .done(function(subscriber) {
          $subscribers.find('.result.selected').replaceWith(renderSubscriber(subscriber))
          closeDetails()
      })
    })

    $row.addClass('selected').after($subscriberDetails)
    updateLocationHash(subscriber._id)
    $subscriberDetails.slideDown()
  }

  function bindEventHandlers($subscriberDetails, submitCallback) {
    var $form = $subscriberDetails.find('form')

    $form.submit(function(event) {
      event.preventDefault()

      var subscriberData = {
        name: findInput('name').val(),
        emailAddresses: _.pluck(findInput('emailAddresses').select2('data'), 'text'),
        yTunnus: findInput('yTunnus').val(),
        address: {
          street: findInput('address.street').val(),
          city: findInput('address.city').val(),
          zip: findInput('address.zip').val(),
          country: findInput('address.country').val()
        },
        billing: {
          invoiceText: $form.find('textarea[name="billing.invoiceText"]').val(),
          language: findInput('billing.language').val()
        },
        eInvoice: {},
        contactName: findInput('contactName').val(),
        phoneNumber: findInput('phoneNumber').val(),
        users: findInput('classifiers').select2('data').map(select2OptionToIdNamePair)
      }
      if ($form.find('input[name=billing-extra]').prop('checked')) {
        var extraBillingType = $form.find('input[name=billing-extra-type]:checked').val()
        if (extraBillingType === 'address') {
          subscriberData.billing.address = {
            street: findInput('billing.address.street').val(),
            city: findInput('billing.address.city').val(),
            zip: findInput('billing.address.zip').val(),
            country: findInput('billing.address.country').val()
          }
        } else if (extraBillingType === 'eInvoice') {
          subscriberData.eInvoice = {
            address: findInput('eInvoice.address').val(),
            operator: findInput('eInvoice.operator').val()
          }
        }
      }

      submitCallback(subscriberData)

      function findInput(name) {
        return $subscriberDetails.find('input[name="' + name + '"]')
      }
    })

    $form.find('input').on('blur select2-blur', function() { $(this).addClass('touched') })

    $form.find('input.select2-offscreen').on('change validate', function() {
      $(this).toggleClass('invalid', !this.checkValidity())
    })

    $form.find('input.select2-offscreen').trigger('validate')

    $form.on('input change', _.debounce(function() { $(this).trigger('validate') }, 200))

    $form.on('validate', function() {
      $(this).find('button[type=submit]').prop('disabled', !this.checkValidity())
    })

    $form.find('input[name=emailAddresses]').on('change', function(event) {
      var emails = event.val
      if (!_.isEmpty(emails) && _.all(emails, validateEmail)) {
        this.setCustomValidity('')
      } else {
        this.setCustomValidity('Invalid email')
      }
      $(this).trigger('validate')

      function validateEmail(email) {
        return new RegExp('.+@.+\\..+').test(email)
      }
    })

    $subscriberDetails.find('button[name=remove]').click(function() {
      var $selected = $page.find('.result.selected')
      var subscriber = $selected.data('subscriber')
      showDialog($('#templates').find('.remove-subscriber-dialog').clone()
        .find('.subscriber-name').text(subscriber.name).end()
        .find('button[name=remove]').click(removeSubscriber).end()
        .find('button[name=cancel]').click(closeDialog).end())

      function removeSubscriber() {
        $.ajax('/accounts/' + subscriber._id, { type: 'DELETE' }).done(function() {
          closeDialog()
          closeDetails()
          $selected.slideUp(function() { $(this).remove() })
        })
      }
    })
  }

  function closeDetails() {
    $subscribers.find('.result.selected').removeClass('selected')
    $subscribers.find('.subscriber-details').slideUp(function() { $(this).remove() })
    updateLocationHash('')
  }

  function updateLocationHash(subscriberId) {
    location.hash = '#tilaajat/' + subscriberId
  }

  function renderSubscribers(subscribers) {
    $subscribers.empty()
    _(subscribers).sortBy('name').map(renderSubscriber).forEach(function(acc) { $subscribers.append(acc) })
  }

  function renderSubscriber(subscriber) {
    return $('
', { class: 'result', 'data-id': subscriber._id })
      .data('subscriber', subscriber)
      .append($('', { class: 'name' }).text(subscriber.name))
      .append($('', { class: 'roles' }).html(renderRoles(subscriber.roles)))

    function renderRoles(roles) {
      if (_.isEmpty(roles)) return ''
      return _.map(roles, function(role) { return enums.roles[role] }).join(', ')
    }
  }

  function currentFilters() {
    return $page.find('.filters input').filter(':checked').map(function() { return $(this).attr('name') }).toArray()
  }

  function renderSubscriberDetails(subscriber) {
    var $subscriberDetails = $('#templates').find('.subscriber-details').clone()
    var eInvoice = utils.getProperty(subscriber, 'eInvoice')
    var billingAddress = utils.getProperty(subscriber, 'billing.address')
    var extraBillingType = _.isEmpty(billingAddress) ? 'eInvoice' : 'address'

    $subscriberDetails.find('input[name], textarea[name]').each(_.partial(setInputValWithProperty, subscriber))

    $subscriberDetails.find('input[name=billing-extra], input[name=billing-extra-type]').on('click', toggleBillingExtra)

    select2Autocomplete({
      $el: $subscriberDetails.find('input[name=classifiers]'),
      path: function(term) { return '/users/search?q=' + encodeURIComponent(term) },
      multiple: true,
      toOption: accountToSelect2Option,
      fromOption: select2OptionToIdNamePair
    })

    $subscriberDetails
      .find('input[name=classifiers]').trigger('setVal', utils.getProperty(subscriber, 'users')).end()
      .find('input[name="address.country"]').select2({ data: select2DataFromEnumObject(enums.countries) }).end()
      .find('input[name=emailAddresses]').select2({ tags: [], multiple: true }).end()
      .find('input[name="billing.address.country"]').select2({ data: select2DataFromEnumObject(enums.countries) }).end()
      .find('input[name=billing-extra]').prop('checked', !(_.isEmpty(billingAddress) && _.isEmpty(eInvoice))).end()
      .find('input[name=billing-extra-type][value=' + extraBillingType + ']').prop('checked', true).end()
      .find('input[name="billing.language"]').select2({ data: select2DataFromEnumObject(enums.billingLanguages) }).end()

    toggleBillingExtra($subscriberDetails)

    return $subscriberDetails

    function setInputValWithProperty(object) {
      var name = $(this).attr('name')
      var property = utils.getProperty(object, name)
      if (property !== undefined) $(this).val(property)
    }

    function accountToSelect2Option(account) {
      if (!account) return null
      return {
        id: account._id,
        text: account.name + (account.username ? ' (' + account.username + ')' : ''),
        name: account.username ? account.username : account.name
      }
    }

    function toggleBillingExtra() {
      var extraBillingEnabled = $subscriberDetails.find('input[name=billing-extra]').prop('checked')
      $subscriberDetails.find('.billing-extra-fields input').prop('disabled', !extraBillingEnabled)

      if (extraBillingEnabled) {
        var type = $subscriberDetails.find('input[name=billing-extra-type]:checked').val()
        var $addressInputs = $subscriberDetails.find('.billing-extra-fields .billing-address input')
        var $eInvoiceInputs = $subscriberDetails.find('.billing-extra-fields .eInvoice input')

        $addressInputs.prop('disabled', type === 'eInvoice')
        $eInvoiceInputs.prop('disabled', type === 'address')
      }
    }
  }

  function select2OptionToIdNamePair(x) {
    if (!x) return null
    return { _id: x.id, name: x.name }
  }

}
<|endoftext|>


<commit_before>'use strict';

var browser = require('util/browser');

var ShortcutsFix = require('./shortcuts-fix');

var debug = require('debug')('window-menu');

/**
 * Application Window Menu integration
 */
function WindowMenu(app) {

  this.fix = new ShortcutsFix(app);

  // Updating Menu
  app.on('tools:state-changed', (tab, state) => {
    debug('Notifying menu about client state change', state);

    // fix for Ctrl+A shortcut that does not work reliably on Windows And Linux
    if (!isMac()) {
      state.bpmn ? this.fix.bind() : this.fix.unbind();
    }

    browser.send('menu:update', state);
  });

  // Listening on menu actions
  browser.on('menu:action', function(err, action, options) {
    debug('Received action from menu: ' + action, options);

    app.triggerAction(action, options);
  });

}

module.exports = WindowMenu;

function isMac() {
  return window.navigator.platform === 'MacIntel';
}<commit_msg>fix(client): fix select all key binding for CMMN<commit_after>'use strict';

var browser = require('util/browser');

var ShortcutsFix = require('./shortcuts-fix');

var debug = require('debug')('window-menu');

/**
 * Application Window Menu integration
 */
function WindowMenu(app) {

  this.fix = new ShortcutsFix(app);

  // Updating Menu
  app.on('tools:state-changed', (tab, state) => {
    debug('Notifying menu about client state change', state);

    // fix for Ctrl+A shortcut that does not work reliably on Windows And Linux
    if (!isMac()) {
      state.bpmn || state.cmmn ? this.fix.bind() : this.fix.unbind();
    }

    browser.send('menu:update', state);
  });

  // Listening on menu actions
  browser.on('menu:action', function(err, action, options) {
    debug('Received action from menu: ' + action, options);

    app.triggerAction(action, options);
  });

}

module.exports = WindowMenu;

function isMac() {
  return window.navigator.platform === 'MacIntel';
}<|endoftext|>


<commit_before>import { Settings } from "api"
import LinkTo from "components/LinkTo"
import _get from "lodash/get"
import { Task } from "models"
import PropTypes from "prop-types"
import React from "react"
import { Table } from "react-bootstrap"
import REMOVE_ICON from "resources/delete.png"

const TaskTable = ({
  id,
  tasks,
  showParent,
  showOrganization,
  showDelete,
  showDescription,
  onDelete
}) => {
  const tasksExist = _get(tasks, "length", 0) > 0

  return (

      {tasksExist ? (

                Name
                {/* TODO: Implement conditional labels, until then, we need to be explicit here */}
                {showParent && Objective	}
                {showOrganization && Tasked organizations	}
                {showDescription && Description	}

              {Task.map(tasks, task => (

                    <LinkTo modelType="Task" model={task}>
                      {task.shortName} - {task.longName}
                    </LinkTo>

                  {showParent && (

                      {task.customFieldRef1 && (
                        <LinkTo task={task.customFieldRef1}>
                          {task.customFieldRef1.shortName}
                        </LinkTo>
                      )}

                  )}
                  {showOrganization && (

                      {task.taskedOrganizations.map(org => (
                        <LinkTo
                          modelType="Organization"
                          model={org}
                          key={`${task.uuid}-${org.uuid}`}
                        />
                      ))}

                  )}
                  {showDescription && (

                      {task.longName}

                  )}
                  {showDelete && (
                     onDelete(task)}
                      id={"taskDelete_" + task.uuid}
                    >

                        <img
                          src={REMOVE_ICON}
                          height={14}
                          alt={`Remove ${Settings.fields.task.shortLabel}`}
                        />

                  )}

              ))}

          {tasks.length === 0 && (

              No {Settings.fields.task.shortLabel} selected.

          )}

      ) : (
        No effort found
      )}

  )
}

TaskTable.propTypes = {
  id: PropTypes.string,
  tasks: PropTypes.array,
  showParent: PropTypes.bool,
  showDelete: PropTypes.bool,
  onDelete: PropTypes.func,
  showOrganization: PropTypes.bool,
  showDescription: PropTypes.bool
}

TaskTable.defaultProps = {
  showDelete: false,
  showOrganization: false
}

export default TaskTable
<commit_msg>Fix task naming in TaskTable<commit_after>import { Settings } from "api"
import LinkTo from "components/LinkTo"
import _get from "lodash/get"
import { Task } from "models"
import PropTypes from "prop-types"
import React from "react"
import { Table } from "react-bootstrap"
import REMOVE_ICON from "resources/delete.png"

const TaskTable = ({
  id,
  tasks,
  showParent,
  showOrganization,
  showDelete,
  showDescription,
  onDelete
}) => {
  const tasksExist = _get(tasks, "length", 0) > 0

  return (

      {tasksExist ? (

                Name
                {/* TODO: Implement conditional labels, until then, we need to be explicit here */}
                {showParent && Objective	}
                {showOrganization && Tasked organizations	}
                {showDescription && Description	}

              {Task.map(tasks, task => (

                    <LinkTo modelType="Task" model={task}>
                      {task.shortName}
                    </LinkTo>

                  {showParent && (

                      {task.customFieldRef1 && (
                        <LinkTo task={task.customFieldRef1}>
                          {task.customFieldRef1.shortName}
                        </LinkTo>
                      )}

                  )}
                  {showOrganization && (

                      {task.taskedOrganizations.map(org => (
                        <LinkTo
                          modelType="Organization"
                          model={org}
                          key={`${task.uuid}-${org.uuid}`}
                        />
                      ))}

                  )}
                  {showDescription && (

                      {task.longName}

                  )}
                  {showDelete && (
                     onDelete(task)}
                      id={"taskDelete_" + task.uuid}
                    >

                        <img
                          src={REMOVE_ICON}
                          height={14}
                          alt={`Remove ${Settings.fields.task.shortLabel}`}
                        />

                  )}

              ))}

          {tasks.length === 0 && (

              No {Settings.fields.task.shortLabel} selected.

          )}

      ) : (
        No effort found
      )}

  )
}

TaskTable.propTypes = {
  id: PropTypes.string,
  tasks: PropTypes.array,
  showParent: PropTypes.bool,
  showDelete: PropTypes.bool,
  onDelete: PropTypes.func,
  showOrganization: PropTypes.bool,
  showDescription: PropTypes.bool
}

TaskTable.defaultProps = {
  showDelete: false,
  showOrganization: false
}

export default TaskTable
<|endoftext|>


<commit_before>/*
 * ms-rpc.js
 * Angular.js module for using ModelSEED JSON-RPC services
 *
 * Authors:
 *   https://github.com/nconrad
 *
 * Todo:
 *   - delegate directly to service names
 *
*/

angular.module('ms-rpc', [])
    .config([ '$provide', '$httpProvider',
    function($provide, $httpProvider) {

    $httpProvider.defaults.headers.post['Content-Type'] = "application/x-www-form-urlencoded";
    $httpProvider.defaults.headers.put['Content-Type'] = "application/x-www-form-urlencoded";

    return $provide.decorator('$http', ['$delegate', '$rootScope', '$q', 'config',
        function($delegate, $rootScope, $q, $config) {

            $delegate.rpc = function(service, method, parameters, isOrdered){
                var deferred = $q.defer();

                // short hand service names
                if (service == 'ws') {
                    var url = $config.services.ws_url;
                    var method = 'Workspace.'+method;
                } else if (service == 'ms') {
                    var url = $config.services.ms_url;
                    var method = 'ProbModelSEED.'+method;
                }

                var data = {version: "1.1",
                            method: method,
                            id: String(Math.random()).slice(2)};

                if (isOrdered)
                    data.params = parameters;
                else
                    data.params = [parameters];

                var config = angular.extend({'headers':
                                                {'Authorization': $rootScope.token}
                                            }, config);

                $delegate.post(url, data, config)
                     .then(function(response) {
                        // only handle actual data
                        return deferred.resolve(response.data.result ? response.data.result[0] : null);
                     }).catch(function(error) {
                        return deferred.reject(error.data);
                     })

                return deferred.promise;
            };

            return $delegate;
        }]);
}]);<commit_msg>add another service<commit_after>/*
 * ms-rpc.js
 * Angular.js module for using ModelSEED JSON-RPC services
 *
 * Authors:
 *   https://github.com/nconrad
 *
 * Todo:
 *   - delegate directly to service names
 *
*/

angular.module('ms-rpc', [])
    .config([ '$provide', '$httpProvider',
    function($provide, $httpProvider) {

    $httpProvider.defaults.headers.post['Content-Type'] = "application/x-www-form-urlencoded";
    $httpProvider.defaults.headers.put['Content-Type'] = "application/x-www-form-urlencoded";

    return $provide.decorator('$http', ['$delegate', '$rootScope', '$q', 'config',
        function($delegate, $rootScope, $q, $config) {

            $delegate.rpc = function(service, method, parameters, isOrdered){
                var deferred = $q.defer();

                // short hand service names
                if (service == 'ws') {
                    var url = $config.services.ws_url;
                    var method = 'Workspace.'+method;
                } else if (service == 'ms') {
                    var url = $config.services.ms_url;
                    var method = 'ProbModelSEED.'+method;
                } else if (service == 'app') {
                    var url = $config.services.app_url;
                    var method = 'AppService.'+method;
                }

                var data = {version: "1.1",
                            method: method,
                            id: String(Math.random()).slice(2)};

                if (isOrdered)
                    data.params = parameters;
                else
                    data.params = [parameters];

                var config = angular.extend({'headers':
                                                {'Authorization': $rootScope.token}
                                            }, config);

                $delegate.post(url, data, config)
                     .then(function(response) {
                        // only handle actual data
                        return deferred.resolve(response.data.result ? response.data.result[0] : null);
                     }).catch(function(error) {
                        return deferred.reject(error.data);
                     })

                return deferred.promise;
            };

            return $delegate;
        }]);
}]);<|endoftext|>


<commit_before>'use strict';
var models = require('uekplan-models');
/**
 * @todo add event type as labels
 * @returns {Promise}
 */
var updateParentsId = () => {
    return new Promise((resolve, reject)=> {
        console.log('Labels:parrentUpdate:start');
        models.label.findAll({
            where: {
                $or: [
                    {type: 'F'},
                    {type: 'B'},
                    {type: 'C'}
                ]
            }, order: [
                [models.sequelize.fn('', models.sequelize.col('key')), 'DESC'],
                ['key', 'DESC']
            ]
        }).then((res)=> {
            var promiseList = [];
            res.forEach((item)=> {
                promiseList.push(models.label.update(
                    {
                        parentId: item.dataValues.id
                    }, {
                        where: {
                            parentText: item.dataValues.key
                        }
                    }
                ));
            });

            Promise.all(promiseList)
                .then(()=> {
                    resolve(loadLabels());
                })
                .catch((err)=> {
                    reject(err);
                })
        }).catch((err)=> {
            reject(err);
        });
    });
}
/**
 *
 * @returns {Promise}
 */
var loadLabels = ()=> {
    console.log('Loading labels from db');
    return new Promise((resolve, reject)=> {
        models.label.findAll({
            where: {
                type: {$ne: '?'}
            },
            order: [
                [models.sequelize.fn('character_length', models.sequelize.col('key')), 'DESC']
            ]
        })
            .then((data) => {
                var labels = {};
                data.forEach((element)=> {
                    labels[element.dataValues.timetableId || element.dataValues.key] = element.dataValues;
                });
                resolve(labels);
            })
            .catch((err)=> {
                reject(err);
            });
    });
}

var updateLabels = (labels)=> {
    return new Promise((resolve, reject)=> {
        console.log('Updating labels in db');

        var promiseList = [];
        for (var label in labels) {
            promiseList.push(models.label.findOrCreate({
                where: {
                    timetableId: labels[label].timetableId,
                    key: labels[label].key
                },
                defaults: labels[label]
            }));
        }
        Promise.all(promiseList)
            .then(()=> {
                resolve(updateParentsId());
            })
            .catch((err)=> {
                reject(err);
            });
    });
}

var getPrefix = (val)=> {
    return (val.split(',').length > 1) ? val.split(',')[1] : null;
}

var resolveTutorsName = ()=> {
    return new Promise((resolve, reject)=> {
        models.label.findAll({
            where: {
                type: 'N',
                value: {$ne: null}
            }
        }).then((tutors)=> {
            tutors.forEach((tutor)=> {
                tutor.dataValues.prefix = getPrefix(tutor.dataValues.key);

                var prefix = ( tutor.dataValues.prefix) ? tutor.dataValues.prefix.length : 0;

                var sKey = tutor.dataValues.key.slice(0, ( ( prefix === 0) ? tutor.dataValues.key.length : tutor.dataValues.key.length - prefix - 1)).trim();
                var sValue = tutor.dataValues.value.slice(prefix, tutor.dataValues.value.length).trim();

                var sKeyFirstSpace = sKey.indexOf(' ');

                var i = 0;
                do {
                    if (sValue.slice(sValue.length - ( sKeyFirstSpace + i)) === sKey.slice(0, sKeyFirstSpace + i)) {
                        tutor.dataValues.surname = sValue.slice(sKey.length - sKeyFirstSpace - i).trim();
                        tutor.dataValues.forename = sValue.slice(0, sValue.length - sKeyFirstSpace - i).trim();
                        break;
                    }
                    i++;
                } while (i < sKey.length);
            })
            tutors.forEach((tutor)=> {

                var list = [];
                list.push(models.label.update({
                    surname: tutor.dataValues.surname,
                    forename: tutor.dataValues.forename,
                    prefix: tutor.dataValues.prefix
                }, {
                    where: {
                        id: tutor.dataValues.id
                    }
                }));
                Promise.all(list)
                    .then((x)=> {
                        resolve();
                    })
                    .catch((err)=> {
                        reject(err);
                    });
            });
        })
            .catch((err)=> {
                reject(err);
            });
    });
};

module.exports = {
    resolveTutorsName: resolveTutorsName,
    updateLabels: updateLabels,
    loadLabels: loadLabels
}

<commit_msg> trimmed prefix value before updating label in db<commit_after>'use strict';
var models = require('uekplan-models');
/**
 * @todo add event type as labels
 * @returns {Promise}
 */
var updateParentsId = () => {
    return new Promise((resolve, reject)=> {
        console.log('Labels:parrentUpdate:start');
        models.label.findAll({
            where: {
                $or: [
                    {type: 'F'},
                    {type: 'B'},
                    {type: 'C'}
                ]
            }, order: [
                [models.sequelize.fn('', models.sequelize.col('key')), 'DESC'],
                ['key', 'DESC']
            ]
        }).then((res)=> {
            var promiseList = [];
            res.forEach((item)=> {
                promiseList.push(models.label.update(
                    {
                        parentId: item.dataValues.id
                    }, {
                        where: {
                            parentText: item.dataValues.key
                        }
                    }
                ));
            });

            Promise.all(promiseList)
                .then(()=> {
                    resolve(loadLabels());
                })
                .catch((err)=> {
                    reject(err);
                })
        }).catch((err)=> {
            reject(err);
        });
    });
}
/**
 *
 * @returns {Promise}
 */
var loadLabels = ()=> {
    console.log('Loading labels from db');
    return new Promise((resolve, reject)=> {
        models.label.findAll({
            where: {
                type: {$ne: '?'}
            },
            order: [
                [models.sequelize.fn('character_length', models.sequelize.col('key')), 'DESC']
            ]
        })
            .then((data) => {
                var labels = {};
                data.forEach((element)=> {
                    labels[element.dataValues.timetableId || element.dataValues.key] = element.dataValues;
                });
                resolve(labels);
            })
            .catch((err)=> {
                reject(err);
            });
    });
}

var updateLabels = (labels)=> {
    return new Promise((resolve, reject)=> {
        console.log('Updating labels in db');

        var promiseList = [];
        for (var label in labels) {
            promiseList.push(models.label.findOrCreate({
                where: {
                    timetableId: labels[label].timetableId,
                    key: labels[label].key
                },
                defaults: labels[label]
            }));
        }
        Promise.all(promiseList)
            .then(()=> {
                resolve(updateParentsId());
            })
            .catch((err)=> {
                reject(err);
            });
    });
}

var getPrefix = (val)=> {
    return (val.split(',').length > 1) ? val.split(',')[1] : null;
}

var resolveTutorsName = ()=> {
    return new Promise((resolve, reject)=> {
        models.label.findAll({
            where: {
                type: 'N',
                value: {$ne: null}
            }
        }).then((tutors)=> {
            tutors.forEach((tutor)=> {
                tutor.dataValues.prefix = getPrefix(tutor.dataValues.key);

                var prefix = ( tutor.dataValues.prefix) ? tutor.dataValues.prefix.length : 0;

                var sKey = tutor.dataValues.key.slice(0, ( ( prefix === 0) ? tutor.dataValues.key.length : tutor.dataValues.key.length - prefix - 1)).trim();
                var sValue = tutor.dataValues.value.slice(prefix, tutor.dataValues.value.length).trim();

                var sKeyFirstSpace = sKey.indexOf(' ');

                var i = 0;
                do {
                    if (sValue.slice(sValue.length - ( sKeyFirstSpace + i)) === sKey.slice(0, sKeyFirstSpace + i)) {
                        tutor.dataValues.surname = sValue.slice(sKey.length - sKeyFirstSpace - i).trim();
                        tutor.dataValues.forename = sValue.slice(0, sValue.length - sKeyFirstSpace - i).trim();
                        break;
                    }
                    i++;
                } while (i < sKey.length);
            })
            tutors.forEach((tutor)=> {

                var list = [];
                list.push(models.label.update({
                    surname: tutor.dataValues.surname,
                    forename: tutor.dataValues.forename,
                    prefix: tutor.dataValues.prefix.trim()
                }, {
                    where: {
                        id: tutor.dataValues.id
                    }
                }));
                Promise.all(list)
                    .then((x)=> {
                        resolve();
                    })
                    .catch((err)=> {
                        reject(err);
                    });
            });
        })
            .catch((err)=> {
                reject(err);
            });
    });
};

module.exports = {
    resolveTutorsName: resolveTutorsName,
    updateLabels: updateLabels,
    loadLabels: loadLabels
}

<|endoftext|>


<commit_before>import initStoryshots from '@storybook/addon-storyshots';
initStoryshots();<commit_msg>Remove storybook snapshots file<commit_after><|endoftext|>


<commit_before>// Source: https://github.com/ludwick/reveal.js-mermaid-plugin

(function(){

  function fixUpSvgSize(divElem, svgElem) {
    var width = svgElem.getBoundingClientRect().width;
    var height = svgElem.getBoundingClientRect().height;
    var divWidth = divElem.offsetWidth;
    var divHeight = divElem.offsetHeight;

    if (width > divWidth || height > divHeight) {
      var viewBox = '0 0 ' + width + ' ' + height;
      svgElem.setAttribute('viewBox', viewBox);
      svgElem.setAttribute('width', divElem.offsetWidth);
      svgElem.setAttribute('height', divElem.offsetHeight);
    }
  }

  function getDataElem(slide) {
    var children = slide.getElementsByClassName('diagram-data');
    var spans = Array.prototype.filter.call(children, function(element) {
      return element.nodeName === 'SPAN';
    });

    var diagramSource = slide.getAttribute('data-diagram-source');
    if (diagramSource) {
      var diagramSlides = document.getElementsByClassName('diagram-slide');

      var sourceSlides = Array.prototype.filter.call(diagramSlides, function(slide) {
        return slide.getAttribute('data-state') === diagramSource;
      });

      return getDataElem(sourceSlides[0]);
    } else {
      return spans[0];
    }
  }

  function getDisplayDiv(slide) {
    var children = slide.getElementsByClassName('diagram-display');
    var divs = Array.prototype.filter.call(children, function(element) {
      return element.nodeName === 'DIV';
    });

    return divs[0];
  }

  function isDiagramSlide(slide) {
    return slide.classList.contains("diagram-slide");
  }

  function destroyDiagram(slide) {
    if (!isDiagramSlide(slide)) { return; }

    var svgDiv = getDisplayDiv(slide);
    while (svgDiv.firstChild) {
      svgDiv.removeChild(svgDiv.firstChild);
    }
    svgDiv.removeAttribute("data-processed");
  }

  function showDiagram(slide) {

    if (!isDiagramSlide(slide)) { return; }

    var dataElem = getDataElem(slide);
    var svgDiv = getDisplayDiv(slide);

    svgDiv.innerHTML = dataElem.innerHTML;

    mermaid.flowchartConfig
    var config = {};
    mermaid.init(config, svgDiv);

    // Fix up svg element size
    var svgElem = svgDiv.getElementsByTagName("svg")[0];
    if (svgElem) {
      fixUpSvgSize(svgDiv, svgElem);
    }

  }

  Reveal.addEventListener( 'slidechanged', function( event ) {
    if (event.previousSlide) {
      destroyDiagram(event.previousSlide);
    }

    if (event.currentSlide) {
      showDiagram(event.currentSlide);
    }
  });

}());
<commit_msg>Rerender diagram after overview navigation<commit_after>// Source: https://github.com/ludwick/reveal.js-mermaid-plugin

(function(){

  function fixUpSvgSize(divElem, svgElem) {
    var width = svgElem.getBoundingClientRect().width;
    var height = svgElem.getBoundingClientRect().height;
    var divWidth = divElem.offsetWidth;
    var divHeight = divElem.offsetHeight;

    if (width > divWidth || height > divHeight) {
      var viewBox = '0 0 ' + width + ' ' + height;
      svgElem.setAttribute('viewBox', viewBox);
      svgElem.setAttribute('width', divElem.offsetWidth);
      svgElem.setAttribute('height', divElem.offsetHeight);
    }
  }

  function getDataElem(slide) {
    var children = slide.getElementsByClassName('diagram-data');
    var spans = Array.prototype.filter.call(children, function(element) {
      return element.nodeName === 'SPAN';
    });

    var diagramSource = slide.getAttribute('data-diagram-source');
    if (diagramSource) {
      var diagramSlides = document.getElementsByClassName('diagram-slide');

      var sourceSlides = Array.prototype.filter.call(diagramSlides, function(slide) {
        return slide.getAttribute('data-state') === diagramSource;
      });

      return getDataElem(sourceSlides[0]);
    } else {
      return spans[0];
    }
  }

  function getDisplayDiv(slide) {
    var children = slide.getElementsByClassName('diagram-display');
    var divs = Array.prototype.filter.call(children, function(element) {
      return element.nodeName === 'DIV';
    });

    return divs[0];
  }

  function isDiagramSlide(slide) {
    return slide.classList.contains("diagram-slide");
  }

  function destroyDiagram(slide) {
    if (!isDiagramSlide(slide)) { return; }

    var svgDiv = getDisplayDiv(slide);
    while (svgDiv.firstChild) {
      svgDiv.removeChild(svgDiv.firstChild);
    }
    svgDiv.removeAttribute("data-processed");
  }

  function showDiagram(slide) {

    if (!isDiagramSlide(slide)) { return; }

    var dataElem = getDataElem(slide);
    var svgDiv = getDisplayDiv(slide);

    svgDiv.innerHTML = dataElem.innerHTML;

    mermaid.flowchartConfig
    var config = {};
    mermaid.init(config, svgDiv);

    // Fix up svg element size
    var svgElem = svgDiv.getElementsByTagName("svg")[0];
    if (svgElem) {
      fixUpSvgSize(svgDiv, svgElem);
    }

  }

  Reveal.addEventListener( 'slidechanged', function( event ) {
    if (event.previousSlide) {
      destroyDiagram(event.previousSlide);
    }

    if (event.currentSlide) {
      showDiagram(event.currentSlide);
    }
  });

  Reveal.addEventListener('overviewhidden', function (event) {
      if (event.currentSlide) {
          destroyDiagram(event.currentSlide);
          showDiagram(event.currentSlide);
      }
  });
}());
<|endoftext|>


<commit_before>#!/usr/bin/env node

var path = require ('path');
var fs = require ('graceful-fs');
// var likeness = require ('likeness');
var sublayer = require ('./main');

var argv = require ('minimist') (process.argv, {
    default:        { verbose:'info' },
    boolean:        [  ],
    string:         [ 'verbose', 'config', 'port', 'adminPort' ],
    alias:          { v:'verbose', c:'config', p:'port', a:'adminPort' }
});

var config;
if (!argv.config)
    config = {};
else {
    try {
        var configPath = path.resolve (process.cwd(), argv.config);
        var configStr = fs.readFileSync (configPath).toString();
    } catch (err) {
        console.log ('cannot resolve config file at '+argv.config);
        return process.exit (1);
    }

    try {
        var config = JSON.parse (configStr);
    } catch (err) {
        console.log ('config file was invalid json');
        console.log (err);
        return process.exit (1);
    }
}

// var context = new likeness.helpers.JSContext();
// context.compile (config, function (err, configValidator, metaschema) {
//     if (err) {
//         console.log ('unexpected error while compiling configuration validation schema');
//         console.log (err);
//         return process.exit (1);
//     }

//     try {
//         configValidator.validate (config);
//     } catch (err) {
//         console.log ('config file failed validation');
//         console.log (err);
//         return process.exit (1);
//     }

//     // etc
// });

var port = argv.port || config.port;
var adminPort = argv.adminPort || config.adminPort;
if (!port || !adminPort) {
    console.log ('both --port and --adminPort must be configured');
    return process.exit (1);
}

var layer = new sublayer (config);
layer.listen (port, adminPort, function (err) {
    if (err)
        return layer.logger.fatal (err);
    layer.logger.info (layer.nodeInfo, 'layer node online');
});
<commit_msg>sanity test<commit_after>#!/usr/bin/env node

var path = require ('path');
var fs = require ('graceful-fs');
// var likeness = require ('likeness');
var sublayer = require ('./main');

var argv = require ('minimist') (process.argv, {
    default:        { verbose:'info' },
    boolean:        [  ],
    string:         [ 'verbose', 'config', 'port', 'adminPort' ],
    alias:          { v:'verbose', c:'config', p:'port', a:'adminPort' }
});

var config;
if (!argv.config)
    config = {};
else {
    try {
        var configPath = path.resolve (process.cwd(), argv.config);
        var configStr = fs.readFileSync (configPath).toString();
    } catch (err) {
        console.log ('cannot resolve config file at '+argv.config);
        return process.exit (1);
    }

    try {
        var config = JSON.parse (configStr);
    } catch (err) {
        console.log ('config file was invalid json');
        console.log (err);
        return process.exit (1);
    }
}

// var context = new likeness.helpers.JSContext();
// context.compile (config, function (err, configValidator, metaschema) {
//     if (err) {
//         console.log ('unexpected error while compiling configuration validation schema');
//         console.log (err);
//         return process.exit (1);
//     }

//     try {
//         configValidator.validate (config);
//     } catch (err) {
//         console.log ('config file failed validation');
//         console.log (err);
//         return process.exit (1);
//     }

//     // etc
// });

var port = argv.port || config.port;
var adminPort = argv.adminPort || config.adminPort;
if (!port || !adminPort) {
    console.log ('both --port and --adminPort must be configured');
    return process.exit (1);
}

var layer = new sublayer (config);
layer.listen (port, adminPort, function (err) {
    if (err)
        return layer.logger.fatal (err);
    layer.logger.info (layer.nodeInfo, 'layer node online');
});

setInterval (function(){ console.log ('am I losing my mind?'); }, 3000);
<|endoftext|>