<commit_before>'use strict';

const stripJs = require('strip-js');
const globalHooks = require('../../../hooks');
const hooks = require('feathers-hooks');
const auth = require('feathers-authentication');

const getAverageRating = function(submissions){
    // Durchschnittsnote berechnen
    if (submissions.length > 0) {
        // Nur bewertete Abgaben einbeziehen
        let submissiongrades = submissions.filter(s => Number.isInteger(s.grade));
        // Abgaben vorhanden?
        if(submissiongrades.length > 0){
            // Noten aus Abgabe auslesen
            submissiongrades = submissiongrades.map(s => s.grade);
            // Durchschnittsnote berechnen
            const ratingsum = submissiongrades.reduce(function(a, b) { return a + b; }, 0);
            return (ratingsum / submissiongrades.length).toFixed(2);
        }
    }
    return undefined;
};

const filterApplicableHomework = hook => {
    let data = hook.result.data || hook.result;
    data = data.filter(function (c) {
        return (new Date(c.availableDate).getTime() < Date.now()
            && c.courseId != null
            && ((c.courseId.userIds || []).indexOf(hook.params.account.userId) != -1) && !c.private)
          || JSON.stringify(c.teacherId) == JSON.stringify(hook.params.account.userId);
    });
    return Promise.resolve(hook);
};

const addStats = hook => {
    let data = hook.result.data || hook.result;
    const submissionService = hook.app.service('/submissions');
    const arrayed = !(Array.isArray(data));
    data = (Array.isArray(data))?(data):([data]);
    return submissionService.find({query: {
            homeworkId: {$in: (data.map(n => n._id))}
        }}).then((submissions) => {
            data = data.map(function(e){
                var c = JSON.parse(JSON.stringify(e)); // don't know why, but without this line it's not working :/
                if(!c.private){
                    let submissionP = (submissions.data.filter(function(n){return JSON.stringify(c._id) == JSON.stringify(n.homeworkId)
                        && n.comment != undefined && n.comment != "";}).length/((c.courseId || {}).userIds || []).length)*100;
                    let gradeP = (submissions.data.filter(function(n){return JSON.stringify(c._id) == JSON.stringify(n.homeworkId)
                            && ( n.gradeComment != '' || Number.isInteger(n.grade) );}).length/((c.courseId || {}).userIds || []).length)*100;
                    c.stats = {
                        userCount: ((c.courseId || {}).userIds || []).length,
                        submissionCount: submissions.data.filter(function(n){return JSON.stringify(c._id) == JSON.stringify(n.homeworkId)
                            && n.comment != undefined && n.comment != "";}).length,
                        submissionPercentage: (submissionP)?submissionP.toFixed(2):undefined,
                        gradeCount: submissions.data.filter(function(n){return JSON.stringify(c._id) == JSON.stringify(n.homeworkId)
                            && ( n.gradeComment != '' || Number.isInteger(n.grade) );}).length,
                        gradePercentage: (gradeP)?gradeP.toFixed(2):undefined,
                        averageGrade: getAverageRating(submissions.data.filter(function(n){return JSON.stringify(c._id) == JSON.stringify(n.homeworkId);}))
                    };
                }
                return c;
            });
            if(arrayed){data = data[0];}
            (hook.result.data)?(hook.result.data = data):(hook.result = data);
    });
};

exports.before = {
    all: [auth.hooks.authenticate('jwt'), (hook) => {
        if (hook.data && hook.data.description) {
            hook.data.description = stripJs(hook.data.description);
        }

        return hook;
    }],
    find: [globalHooks.mapPaginationQuery.bind(this)],
    get: [],
    create: [],
    update: [],
    patch: [],
    remove: []
};

exports.after = {
  all: [],
  find: [filterApplicableHomework, addStats],
  get: [addStats],
  create: [],
  update: [],
  patch: [],
  remove: []
};
<commit_msg>Revert "empty commit"<commit_after>'use strict';

const stripJs = require('strip-js');
const globalHooks = require('../../../hooks');
const hooks = require('feathers-hooks');
const auth = require('feathers-authentication');

const getAverageRating = function(submissions){
    // Durchschnittsnote berechnen
    if (submissions.length > 0) {
        // Nur bewertete Abgaben einbeziehen
        let submissiongrades = submissions.filter(s => Number.isInteger(s.grade));
        // Abgaben vorhanden?
        if(submissiongrades.length > 0){
            // Noten aus Abgabe auslesen
            submissiongrades = submissiongrades.map(s => s.grade);
            // Durchschnittsnote berechnen
            const ratingsum = submissiongrades.reduce(function(a, b) { return a + b; }, 0);
            return (ratingsum / submissiongrades.length).toFixed(2);
        }
    }
    return undefined;
};

const filterApplicableHomework = hook => {
    let data = hook.result.data || hook.result;
    data = data.filter(function (c) {
        return (new Date(c.availableDate).getTime() < Date.now()
            && c.courseId != null
            && ((c.courseId.userIds || []).indexOf(hook.params.account.userId) != -1) && !c.private)
          || JSON.stringify(c.teacherId) == JSON.stringify(hook.params.account.userId);
    });
    return Promise.resolve(hook);
};

const addStats = hook => {
    let data = hook.result.data || hook.result;
    const submissionService = hook.app.service('/submissions');
    const arrayed = !(Array.isArray(data));
    data = (Array.isArray(data))?(data):([data]);
    return submissionService.find({query: {
            homeworkId: {$in: (data.map(n => n._id))}
        }}).then((submissions) => {
            data = data.map(function(e){
                var c = JSON.parse(JSON.stringify(e)) // don't know why, but without this line it's not working :/
                if(!c.private){
                    let submissionP = (submissions.data.filter(function(n){return JSON.stringify(c._id) == JSON.stringify(n.homeworkId)
                        && n.comment != undefined && n.comment != ""}).length/((c.courseId || {}).userIds || []).length)*100;
                    let gradeP = (submissions.data.filter(function(n){return JSON.stringify(c._id) == JSON.stringify(n.homeworkId)
                            && ( n.gradeComment != '' || Number.isInteger(n.grade) )}).length/((c.courseId || {}).userIds || []).length)*100;
                    c.stats = {
                        userCount: ((c.courseId || {}).userIds || []).length,
                        submissionCount: submissions.data.filter(function(n){return JSON.stringify(c._id) == JSON.stringify(n.homeworkId)
                            && n.comment != undefined && n.comment != ""}).length,
                        submissionPercentage: (submissionP)?submissionP.toFixed(2):undefined,
                        gradeCount: submissions.data.filter(function(n){return JSON.stringify(c._id) == JSON.stringify(n.homeworkId)
                            && ( n.gradeComment != '' || Number.isInteger(n.grade) )}).length,
                        gradePercentage: (gradeP)?gradeP.toFixed(2):undefined,
                        averageGrade: getAverageRating(submissions.data.filter(function(n){return JSON.stringify(c._id) == JSON.stringify(n.homeworkId);}))
                    };
                }
                return c;
            });
            if(arrayed){data = data[0];}
            (hook.result.data)?(hook.result.data = data):(hook.result = data);
    });
}

exports.before = {
    all: [auth.hooks.authenticate('jwt'), (hook) => {
        if (hook.data && hook.data.description) {
            hook.data.description = stripJs(hook.data.description);
        }

        return hook;
    }],
    find: [globalHooks.mapPaginationQuery.bind(this)],
    get: [],
    create: [],
    update: [],
    patch: [],
    remove: []
};

exports.after = {
  all: [],
  find: [filterApplicableHomework, addStats],
  get: [addStats],
  create: [],
  update: [],
  patch: [],
  remove: []
};
<|endoftext|>


<commit_before>/**
 * maryamyriameliamurphies.js
 *
 * @name traversable.js
 * @fileOverview
 * Traversable type class
 */

 /** @module maryamyriameliamurphies.js/source/traversable */

 ////////////////////////////////////////////////////////////////////////////////////////////////////
 // Traversable

 /**
  * A `Traversable` is a functor representing data structures that can be traversed from left to right. They
  * must define a `traverse` method and also be instances of `Functor` and `Foldable`.
  * @const {Function} - Returns `true` if an object is an instance of `Traversable` and `false` otherwise.
  */
 const Traversable = defines(`fmap`, `foldr`, `traverse`);

 /**
  * Map each element of a structure to an action, evaluate these actions from left to right, and collect
  * the results.
  * Haskell> traverse :: Applicative f => (a -> f b) -> t a -> f (t b)
  * @param {Function} f - The function to map.
  * @param {Object} a - The traversable structure to traverse.
  * @returns {Object} - A collection of the results of the traversal.
  * @example
  * let lst = list(1,2,3);
  * let f = x => list(x + 7);
  * traverse(f)(lst);         // => [[8:9:10:[]]:[]]
  * let tup = tuple(1,2);
  * traverse(f, tup);         // => [(1,9):[]]
  */
 function traverse(f, a) {
   let p = (f, a) => { return Traversable(a) ? dataType(a).traverse(f, a) : error.typeError(a, traverse); }
   return partial(p, f, a);
 }

 /**
  * Map each element of a structure to a monadic action, evaluate these actions from left to right,
  * and collect the results. This function is essentially the same as `traverse`.
  * Haskell> mapM :: Monad m => (a -> m b) -> t a -> m (t b)
  * @param {Function} f - The function to map.
  * @param {Object} m - The monad to traverse.
  * @returns {Object} - A collection of the results of the traversal.
  */
 function mapM(f, m) {
   let p = (f, m) => Monad(m) ? dataType(m).traverse(f, m) : error.typeError(m, mapM);
   return partial(p, f, m);
 }

 /**
  * Evaluate each monadic action in the structure from left to right, and collect the results.
  * Haskell> sequence :: Monad m => t (m a) -> m (t a)
  * @param {Object} m - The monadic collection of actions.
  * @returns {Object} - A collection of the results.
  * @example
  * let lst = list(1,2,3);
  * let llst = list(lst);
  * sequence(llst);        // => [[1:[]]:[2:[]]:[3:[]]:[]]
  */
 function sequence(m) { return Monad(m) ? traverse(id, m) : error.typeError(m, sequence); }
<commit_msg>Update traversable.js<commit_after>/**
 * maryamyriameliamurphies.js
 *
 * @name traversable.js
 * @author Steven J. Syrek
 * @file Traversable type class.
 * @license ISC
 */

/** @module maryamyriameliamurphies.js/source/traversable */

////////////////////////////////////////////////////////////////////////////////////////////////////
// Traversable

/**
 * A `Traversable` is a functor representing data structures that can be traversed from left to right. They
 * must define a `traverse` method and also be instances of `Functor` and `Foldable`.
 * @const {Function} - Returns `true` if an object is an instance of `Traversable` and `false` otherwise.
 */
const Traversable = defines(`fmap`, `foldr`, `traverse`);

/**
 * Map each element of a structure to an action, evaluate these actions from left to right, and collect
 * the results.
 * Haskell> traverse :: Applicative f => (a -> f b) -> t a -> f (t b)
 * @param {Function} f - The function to map.
 * @param {Object} a - The traversable structure to traverse.
 * @returns {Object} - A collection of the results of the traversal.
 * @example
 * const lst = list(1,2,3);
 * const f = x => list(x + 7);
 * const tup = tuple(1,2);
 * traverse(f)(lst);         // => [[8:9:10:[]]:[]]
 * traverse(f, tup);         // => [(1,9):[]]
 */
export function traverse(f, a) {
  const traverseP = (f, a) => { return Traversable(a) ? dataType(a).traverse(f, a) : error.typeError(a, traverse); }
  return partial(traverseP, f, a);
}

/**
 * Map each element of a structure to a monadic action, evaluate these actions from left to right,
 * and collect the results. This function is essentially the same as `traverse`.
 * Haskell> mapM :: Monad m => (a -> m b) -> t a -> m (t b)
 * @param {Function} f - The function to map.
 * @param {Object} m - The monad to traverse.
 * @returns {Object} - A collection of the results of the traversal.
 */
export function mapM(f, m) {
  const mapMP = (f, m) => Monad(m) ? dataType(m).traverse(f, m) : error.typeError(m, mapM);
  return partial(mapMP, f, m);
}

/**
 * Evaluate each monadic action in the structure from left to right, and collect the results.
 * Haskell> sequence :: Monad m => t (m a) -> m (t a)
 * @param {Object} m - The monadic collection of actions.
 * @returns {Object} - A collection of the results.
 * @example
 * const lst = list(1,2,3);
 * const llst = list(lst);
 * sequence(llst);        // => [[1:[]]:[2:[]]:[3:[]]:[]]
 */
export function sequence(m) { return Monad(m) ? traverse(id, m) : error.typeError(m, sequence); }
<|endoftext|>


<commit_before>/**
	Implements an HTML checkbox input, with support for grouping
*/
enyo.kind({
	name: "enyo.Checkbox",
	//* @protected
	kind: enyo.Input,
	attributes: {
		type: "checkbox"
	},
	events: {
		onActivate: ""
	},
	//* @public
	published: {
		//* Value of the checkbox
		checked: false,
		//* Group API requirement for determining selected item
		active: false
	},
	//* @protected
	handlers: {
		onchange: "change",
		onclick: "click"
	},
	create: function() {
		this.inherited(arguments);
		this.checkedChanged();
	},
	// instance 'checked' property is linked to DOM 'checked' property
	getChecked: function() {
		return Boolean(this.getNodeProperty("checked", this.checked));
	},
	checkedChanged: function() {
		this.setNodeProperty("checked", this.checked);
		this.setAttribute("checked", this.checked ? "checked" : "");
		this.setActive(this.checked);
	},
	// active property, and onActivate event, are part of "GroupItem" interface
	// that we support in this object
	activeChanged: function() {
		this.active = Boolean(this.active);
		this.setChecked(this.active);
		this.bubble("onActivate");
		this.notifyContainer();
	},
	// all input type controls support 'value' property
	setValue: function(inValue) {
		this.log();
		this.setChecked(Boolean(inValue));
	},
	getValue: function() {
		return this.getChecked();
	},
	valueChanged: function() {
		// inherited behavior is to set "value" attribute and node-property
		// which does not apply to checkbox (uses "checked") so
		// we squelch the inherited method
	},
	change: function() {
		this.setActive(this.getChecked());
	},
	click: function(inSender, inEvent) {
		// Various versions of IE (notably IE8) do not fire 'onchange' for
		// checkboxes, so we discern change via 'click'.
		// Note: keyboard interaction (e.g. pressing space when focused) fires
		// a click event.
		if (enyo.platform.ie <= 8) {
			this.bubble("onchange", inEvent);
		}
	}
});
<commit_msg>remove extra log<commit_after>/**
	Implements an HTML checkbox input, with support for grouping
*/
enyo.kind({
	name: "enyo.Checkbox",
	//* @protected
	kind: enyo.Input,
	attributes: {
		type: "checkbox"
	},
	events: {
		onActivate: ""
	},
	//* @public
	published: {
		//* Value of the checkbox
		checked: false,
		//* Group API requirement for determining selected item
		active: false
	},
	//* @protected
	handlers: {
		onchange: "change",
		onclick: "click"
	},
	create: function() {
		this.inherited(arguments);
		this.checkedChanged();
	},
	// instance 'checked' property is linked to DOM 'checked' property
	getChecked: function() {
		return Boolean(this.getNodeProperty("checked", this.checked));
	},
	checkedChanged: function() {
		this.setNodeProperty("checked", this.checked);
		this.setAttribute("checked", this.checked ? "checked" : "");
		this.setActive(this.checked);
	},
	// active property, and onActivate event, are part of "GroupItem" interface
	// that we support in this object
	activeChanged: function() {
		this.active = Boolean(this.active);
		this.setChecked(this.active);
		this.bubble("onActivate");
		this.notifyContainer();
	},
	// all input type controls support 'value' property
	setValue: function(inValue) {
		this.setChecked(Boolean(inValue));
	},
	getValue: function() {
		return this.getChecked();
	},
	valueChanged: function() {
		// inherited behavior is to set "value" attribute and node-property
		// which does not apply to checkbox (uses "checked") so
		// we squelch the inherited method
	},
	change: function() {
		this.setActive(this.getChecked());
	},
	click: function(inSender, inEvent) {
		// Various versions of IE (notably IE8) do not fire 'onchange' for
		// checkboxes, so we discern change via 'click'.
		// Note: keyboard interaction (e.g. pressing space when focused) fires
		// a click event.
		if (enyo.platform.ie <= 8) {
			this.bubble("onchange", inEvent);
		}
	}
});
<|endoftext|>


<commit_before>'use strict';

// Based on Alex Arnell's inheritance implementation.

window.Class = (function () {

	function Subclass() {
		// The base Subclass implementation (does nothing).
	}

	function create() {
		var parent, properties, id;
		id = -1;
		parent = null;
		properties = iterate(arguments);
		if (typeOf(properties[0]) === 'function') {
			parent = properties.shift();
		}
		function Caste() {
			if (typeOf(this.initialize) === 'function') {
				this.initialize.apply(this, arguments);
			}
		}
		Object.extend(Caste, Class.Methods);
		Caste.superclass = parent;
		Caste.subclasses = [];
		if (parent) {
			Subclass.prototype = parent.prototype;
			Caste.prototype = new Subclass;
			parent.subclasses.push(Caste);
		}
		while (++id < properties.length) {
			Caste.implement(properties[id]);
		}
		if (!typeOf(Caste.prototype.initialize)) {
			Caste.prototype.initialize = function () {
				// No Operation
			};
		}
		Caste.prototype.constructor = Caste;
		return Caste;
	}

	function mutate(items) {
		// N/A yet.
	}

	function implement(source) {
		var ancestor, properties, id, property, value, method;
		ancestor = this.superclass && this.superclass.prototype;
		properties = Object.keys(source);
		id = -1;
		if (IS_DONTENUM_BUGGY) {
			if (source.toString != Object.prototype.toString) {
				properties.push('toString');
			}
			if (source.valueOf != Object.prototype.valueOf) {
				properties.push('valueOf');
			}
		}
		while (++id < properties.length) {
			property = properties[id];
			value = source[property];
			if (property === 'implements') {
				if (typeOf(value) === 'function') {
					// N/A yet.
				} else {
					// N/A yet.
				}
			}
			if (ancestor && typeOf(value) === 'function' && value.argumentNames()[0] === '$super') {
				method = value;
				value = (function (fn) {
					return function () {
						return ancestor[fn].apply(this, arguments);
					};
				})(property).wrap(method);
				value.valueOf = (function (method) {
					return function () {
						return method.valueOf.call(method);
					};
				})(method);
				value.toString = (function (method) {
					return function () {
						return method.toString.call(method);
					};
				})(method);
			}
			this.prototype[property] = value;
		}
		return this;
	}

	return {
		create: create,
		Methods: {
			extend: Object.extend,
			implement: implement
		}
	};

}());
<commit_msg>v0.0.1<commit_after>'use strict';

// Based on Alex Arnell's inheritance implementation.

window.Class = (function () {

	function Subclass() {
		// The base Subclass implementation (does nothing).
	}

	function create() {
		var parent, properties, id;
		id = -1;
		parent = null;
		properties = iterate(arguments);
		if (typeOf(properties[0]) === 'function') {
			parent = properties.shift();
		}
		function Caste() {
			if (typeOf(this.initialize) === 'function') {
				this.initialize.apply(this, arguments);
			}
		}
		Object.extend(Caste, Class.Methods);
		Caste.superclass = parent;
		Caste.subclasses = [];
		if (parent) {
			Subclass.prototype = parent.prototype;
			Caste.prototype = new Subclass;
			parent.subclasses.push(Caste);
		}
		while (++id < properties.length) {
			Caste.implement(properties[id]);
		}
		if (!typeOf(Caste.prototype.initialize)) {
			Caste.prototype.initialize = function () {
				// No Operation
			};
		}
		Caste.prototype.constructor = Caste;
		return Caste;
	}

	function mutate(items) {
		// N/A yet.
	}

	function implement(source) {
		var ancestor, properties, id, property, value, method;
		ancestor = this.superclass && this.superclass.prototype;
		properties = Object.keys(source);
		id = -1;
		if (IS_DONTENUM_BUGGY) {
			if (source.toString != Object.prototype.toString) {
				properties.push('toString');
			}
			if (source.valueOf != Object.prototype.valueOf) {
				properties.push('valueOf');
			}
		}
		while (++id < properties.length) {
			property = properties[id];
			value = source[property];
			if (property === 'implements') {
				if (typeOf(value) === 'function') {
					// N/A yet.
				} else {
					// N/A yet.
				}
			}
			if (ancestor && typeOf(value) === 'function' && value.argumentNames()[0] === '$super') {
				method = value;
				value = (function (fn) {
					return function () {
						return ancestor[fn].apply(this, arguments);
					};
				})(property).wrap(method);
				value.valueOf = (function (method) {
					return function () {
						return method.valueOf.call(method);
					};
				})(method);
				value.toString = (function (method) {
					return function () {
						return method.toString.call(method);
					};
				})(method);
			}
			this.prototype[property] = value;
		}
		return this;
	}

	return {
		create: create,
		Methods: {
			extend: Object.extend,
			implement: implement
		}
	};

}());

// Externalize
window.Class.getDefinitionName = getDefinitionName;
window.Class.typeOf = typeOf;
<|endoftext|>


<commit_before>import { addStartAppTask, addStartServiceTask, checkAppStarted, prepareBundleSupported } from './utils';
import buildApp, { archiveApp } from './build.js';
import { checkUrls, getInformation } from './status';
import { map, promisify } from 'bluebird';
import chalk from 'chalk';
import { cloneDeep } from 'lodash';
import debug from 'debug';
import fs from 'fs';
import nodemiral from 'nodemiral';
import os from 'os';
import random from 'random-seed';
import uuid from 'uuid';

const log = debug('mup:module:meteor');

function tmpBuildPath(appPath, api) {
  const rand = random.create(appPath);
  const uuidNumbers = [];
  for (let i = 0; i < 16; i++) {
    uuidNumbers.push(rand(255));
  }

  return api.resolvePath(
    os.tmpdir(),
    `mup-meteor-${uuid.v4({ random: uuidNumbers })}`
  );
}

export function logs(api) {
  log('exec => mup meteor logs');
  const config = api.getConfig().app;
  if (!config) {
    console.error('error: no configs found for meteor');
    process.exit(1);
  }

  const args = api.getArgs();
  if (args[0] === 'meteor') {
    args.shift();
  }

  const sessions = api.getSessions(['app']);

  return api.getDockerLogs(config.name, sessions, args);
}

export function setup(api) {
  log('exec => mup meteor setup');
  const config = api.getConfig().app;
  if (!config) {
    console.error('error: no configs found for meteor');
    process.exit(1);
  }

  const list = nodemiral.taskList('Setup Meteor');

  list.executeScript('Setup Environment', {
    script: api.resolvePath(__dirname, 'assets/meteor-setup.sh'),
    vars: {
      name: config.name
    }
  });

  if (config.ssl && typeof config.ssl.autogenerate !== 'object') {
    const basePath = api.getBasePath();

    if (config.ssl.upload !== false) {
      list.executeScript('Cleaning up SSL Certificates', {
        script: api.resolvePath(__dirname, 'assets/ssl-cleanup.sh'),
        vars: {
          name: config.name
        }
      });
      list.copy('Copying SSL Certificate Bundle', {
        src: api.resolvePath(basePath, config.ssl.crt),
        dest: `/opt/${config.name}/config/bundle.crt`
      });

      list.copy('Copying SSL Private Key', {
        src: api.resolvePath(basePath, config.ssl.key),
        dest: `/opt/${config.name}/config/private.key`
      });
    }

    list.executeScript('Verifying SSL Configurations', {
      script: api.resolvePath(__dirname, 'assets/verify-ssl-config.sh'),
      vars: {
        name: config.name
      }
    });
  }

  const sessions = api.getSessions(['app']);

  return api.runTaskList(list, sessions, { verbose: api.verbose });
}

function getBuildOptions(api) {
  const config = api.getConfig().app;
  const appPath = api.resolvePath(api.getBasePath(), config.path);

  const buildOptions = config.buildOptions || {};
  buildOptions.buildLocation =
    buildOptions.buildLocation || tmpBuildPath(appPath, api);

  return buildOptions;
}

function shouldRebuild(api) {
  let rebuild = true;
  const { buildLocation } = getBuildOptions(api);
  const bundlePath = api.resolvePath(buildLocation, 'bundle.tar.gz');

  if (api.getOptions()['cached-build']) {
    const buildCached = fs.existsSync(bundlePath);

    // If build is not cached, rebuild is true
    // even though the --cached-build flag was used
    if (buildCached) {
      rebuild = false;
    }
  }

  return rebuild;
}

export async function build(api) {
  const config = api.getConfig().app;
  const appPath = api.resolvePath(api.getBasePath(), config.path);
  const buildOptions = getBuildOptions(api);

  const rebuild = shouldRebuild(api);

  if (rebuild && api.getOptions()['cached-build']) {
    console.log('Unable to use previous build. It doesn\'t exist.');
  } else if (!rebuild) {
    console.log('Not building app. Using build from previous deploy at');
    console.log(buildOptions.buildLocation);
  }

  if (rebuild) {
    console.log('Building App Bundle Locally');
    await buildApp(appPath, buildOptions, api.getVerbose(), api);
  }
}

export async function push(api) {
  log('exec => mup meteor push');

  await api.runCommand('meteor.build');

  const config = api.getConfig().app;
  if (!config) {
    console.error('error: no configs found for meteor');
    process.exit(1);
  }

  const buildOptions = getBuildOptions(api);

  const bundlePath = api.resolvePath(buildOptions.buildLocation, 'bundle.tar.gz');

  if (shouldRebuild(api)) {
    await promisify(archiveApp)(buildOptions.buildLocation, api);
  }

  const list = nodemiral.taskList('Pushing Meteor App');

  list.copy('Pushing Meteor App Bundle to the Server', {
    src: bundlePath,
    dest: `/opt/${config.name}/tmp/bundle.tar.gz`,
    progressBar: config.enableUploadProgressBar
  });

  if (prepareBundleSupported(config.docker)) {
    list.executeScript('Prepare Bundle', {
      script: api.resolvePath(
        __dirname,
        'assets/prepare-bundle.sh'
      ),
      vars: {
        appName: config.name,
        dockerImage: config.docker.image,
        env: config.env,
        buildInstructions: config.docker.buildInstructions || []
      }
    });
  }

  const sessions = api.getSessions(['app']);

  return api.runTaskList(list, sessions, {
    series: true,
    verbose: api.verbose
  });
}

export function envconfig(api) {
  log('exec => mup meteor envconfig');

  const config = api.getConfig().app;
  const servers = api.getConfig().servers;
  let bindAddress = '0.0.0.0';

  if (!config) {
    console.error('error: no configs found for meteor');
    process.exit(1);
  }

  config.log = config.log || {
    opts: {
      'max-size': '100m',
      'max-file': 10
    }
  };

  config.nginx = config.nginx || {};

  if (config.docker && config.docker.bind) {
    bindAddress = config.docker.bind;
  }

  if (config.dockerImageFrontendServer) {
    config.docker.imageFrontendServer = config.dockerImageFrontendServer;
  }
  if (!config.docker.imageFrontendServer) {
    config.docker.imageFrontendServer = 'meteorhacks/mup-frontend-server';
  }

  // If imagePort is not set, go with port 80 which was the traditional
  // port used by kadirahq/meteord and meteorhacks/meteord
  config.docker.imagePort = config.docker.imagePort || 80;

  if (config.ssl) {
    config.ssl.port = config.ssl.port || 443;
  }

  const list = nodemiral.taskList('Configuring App');
  list.copy('Pushing the Startup Script', {
    src: api.resolvePath(__dirname, 'assets/templates/start.sh'),
    dest: `/opt/${config.name}/config/start.sh`,
    vars: {
      appName: config.name,
      port: config.env.PORT || 80,
      bind: bindAddress,
      sslConfig: config.ssl,
      logConfig: config.log,
      volumes: config.volumes,
      docker: config.docker,
      proxyConfig: api.getConfig().proxy,
      nginxClientUploadLimit: config.nginx.clientUploadLimit || '10M'
    }
  });

  const env = cloneDeep(config.env);
  env.METEOR_SETTINGS = JSON.stringify(api.getSettings());
  // sending PORT to the docker container is useless.

  // setting PORT in the config is used for the publicly accessible
  // port.

  // docker.imagePort is used for the port exposed from the container.
  // In case the docker.imagePort is different than the container's
  // default port, we set the env PORT to docker.imagePort.
  env.PORT = config.docker.imagePort;

  const hostVars = {};
  Object.keys(config.servers).forEach(key => {
    if (config.servers[key].env) {
      hostVars[servers[key].host] = { env: config.servers[key].env };
    }
    if (config.servers[key].settings) {
      const settings = JSON.stringify(api.getSettingsFromPath(
        config.servers[key].settings));
      if (hostVars[servers[key].host]) {
        hostVars[servers[key].host].env.METEOR_SETTINGS = settings;
      } else {
        hostVars[servers[key].host] = { env: { METEOR_SETTINGS: settings } };
      }
    }
  });

  list.copy('Sending Environment Variables', {
    src: api.resolvePath(__dirname, 'assets/templates/env.list'),
    dest: `/opt/${config.name}/config/env.list`,
    hostVars,
    vars: {
      env: env || {},
      appName: config.name
    }
  });

  const sessions = api.getSessions(['app']);

  return api.runTaskList(list, sessions, {
    series: true,
    verbose: api.verbose
  });
}

export async function start(api) {
  log('exec => mup meteor start');
  const config = api.getConfig().app;
  const service = api.getConfig().swarm !== undefined;

  if (!config) {
    console.error('error: no configs found for meteor');
    process.exit(1);
  }

  const list = nodemiral.taskList('Start Meteor');

  if (service) {
    addStartServiceTask(list, api);
  } else {
    addStartAppTask(list, api);
    checkAppStarted(list, api);
  }

  const sessions = service ? await api.getManagerSession() : api.getSessionapi.getSessions(['app']);

  return api.runTaskList(list, [sessions], {
    series: true,
    verbose: api.verbose
  });
}

export function deploy(api) {
  log('exec => mup meteor deploy');

  // validate settings and config before starting
  api.getSettings();
  const config = api.getConfig().app;
  if (!config) {
    console.error('error: no configs found for meteor');
    process.exit(1);
  }

  return api
    .runCommand('meteor.push')
    .then(() => api.runCommand('default.reconfig'));
}

export function stop(api) {
  log('exec => mup meteor stop');
  const config = api.getConfig().app;
  if (!config) {
    console.error('error: no configs found for meteor');
    process.exit(1);
  }

  const list = nodemiral.taskList('Stop Meteor');

  list.executeScript('Stop Meteor', {
    script: api.resolvePath(__dirname, 'assets/meteor-stop.sh'),
    vars: {
      appName: config.name
    }
  });

  const sessions = api.getSessions(['app']);

  return api.runTaskList(list, sessions, { verbose: api.verbose });
}

export function restart(api) {
  const list = nodemiral.taskList('Restart Meteor');
  const sessions = api.getSessions(['app']);
  const config = api.getConfig().app;

  list.executeScript('Stop Meteor', {
    script: api.resolvePath(__dirname, 'assets/meteor-stop.sh'),
    vars: {
      appName: config.name
    }
  });

  addStartAppTask(list, api);
  checkAppStarted(list, api);

  return api.runTaskList(list, sessions, {
    series: true,
    verbose: api.verbose
  });
}

export async function status(api) {
  const config = api.getConfig();
  const lines = [];
  const servers = Object.keys(config.app.servers)
    .map(key => config.servers[key]);

  const results = await map(
    servers,
    server => getInformation(server, config.app.name, api),
    { concurrency: 2 }
  );
  const urlResults = await map(
    servers,
    server => checkUrls(server, config.app, api),
    { concurrency: 2 }
  );

  let overallColor = 'green';

  function updateColor(color) {
    if (color === 'yellow' && overallColor !== 'red') {
      overallColor = color;
    } else if (color === 'red') {
      overallColor = color;
    }
  }

  results.forEach((result, index) => {
    updateColor(result.statusColor);
    updateColor(result.restartColor);

    lines.push(` - ${result.host}: ${chalk[result.statusColor](result.status)} `);

    if (result.status === 'Stopped') {
      return;
    }

    lines.push(`    Created at ${result.created}`);
    lines.push(chalk[result.restartColor](`    Restarted ${result.restartCount} times`));

    lines.push('    ENV: ');
    result.env.forEach(envVar => {
      lines.push(`     - ${envVar}`);
    });

    if (result.exposedPorts.length > 0) {
      lines.push('    Exposed Ports:');
      result.exposedPorts.forEach(port => {
        lines.push(`     - ${port}`);
      });
    }

    if (result.publishedPorts.length > 0) {
      lines.push('    Published Ports:');
      result.publishedPorts.forEach(port => {
        lines.push(`     - ${port}`);
      });
    }

    const urlResult = urlResults[index];
    if (result.publishedPorts.length > 0) {
      lines.push(`    App running at http://${result.host}:${result.publishedPorts[0].split('/')[0]}`);
      lines.push(`     - Available in app's docker container: ${urlResult.inDocker}`);
      lines.push(`     - Available on server: ${urlResult.remote}`);
      lines.push(`     - Available on local computer: ${urlResult.local}`);
    } else {
      lines.push('    App available through reverse proxy');
      lines.push(`     - Available in app's docker container: ${urlResult.inDocker}`);
    }
  });

  console.log(chalk[overallColor]('\n=> Meteor Status'));
  console.log(lines.join('\n'));
}
<commit_msg>Fix starting app<commit_after>import { addStartAppTask, addStartServiceTask, checkAppStarted, prepareBundleSupported } from './utils';
import buildApp, { archiveApp } from './build.js';
import { checkUrls, getInformation } from './status';
import { map, promisify } from 'bluebird';
import chalk from 'chalk';
import { cloneDeep } from 'lodash';
import debug from 'debug';
import fs from 'fs';
import nodemiral from 'nodemiral';
import os from 'os';
import random from 'random-seed';
import uuid from 'uuid';

const log = debug('mup:module:meteor');

function tmpBuildPath(appPath, api) {
  const rand = random.create(appPath);
  const uuidNumbers = [];

  for (let i = 0; i < 16; i++) {
    uuidNumbers.push(rand(255));
  }

  return api.resolvePath(
    os.tmpdir(),
    `mup-meteor-${uuid.v4({ random: uuidNumbers })}`
  );
}

export function logs(api) {
  log('exec => mup meteor logs');
  const config = api.getConfig().app;

  if (!config) {
    console.error('error: no configs found for meteor');
    process.exit(1);
  }

  const args = api.getArgs();

  if (args[0] === 'meteor') {
    args.shift();
  }

  const sessions = api.getSessions(['app']);

  return api.getDockerLogs(config.name, sessions, args);
}

export function setup(api) {
  log('exec => mup meteor setup');
  const config = api.getConfig().app;

  if (!config) {
    console.error('error: no configs found for meteor');
    process.exit(1);
  }

  const list = nodemiral.taskList('Setup Meteor');

  list.executeScript('Setup Environment', {
    script: api.resolvePath(__dirname, 'assets/meteor-setup.sh'),
    vars: {
      name: config.name
    }
  });

  if (config.ssl && typeof config.ssl.autogenerate !== 'object') {
    const basePath = api.getBasePath();

    if (config.ssl.upload !== false) {
      list.executeScript('Cleaning up SSL Certificates', {
        script: api.resolvePath(__dirname, 'assets/ssl-cleanup.sh'),
        vars: {
          name: config.name
        }
      });
      list.copy('Copying SSL Certificate Bundle', {
        src: api.resolvePath(basePath, config.ssl.crt),
        dest: `/opt/${config.name}/config/bundle.crt`
      });

      list.copy('Copying SSL Private Key', {
        src: api.resolvePath(basePath, config.ssl.key),
        dest: `/opt/${config.name}/config/private.key`
      });
    }

    list.executeScript('Verifying SSL Configurations', {
      script: api.resolvePath(__dirname, 'assets/verify-ssl-config.sh'),
      vars: {
        name: config.name
      }
    });
  }

  const sessions = api.getSessions(['app']);

  return api.runTaskList(list, sessions, { verbose: api.verbose });
}

function getBuildOptions(api) {
  const config = api.getConfig().app;
  const appPath = api.resolvePath(api.getBasePath(), config.path);

  const buildOptions = config.buildOptions || {};

  buildOptions.buildLocation =
    buildOptions.buildLocation || tmpBuildPath(appPath, api);

  return buildOptions;
}

function shouldRebuild(api) {
  let rebuild = true;
  const { buildLocation } = getBuildOptions(api);
  const bundlePath = api.resolvePath(buildLocation, 'bundle.tar.gz');

  if (api.getOptions()['cached-build']) {
    const buildCached = fs.existsSync(bundlePath);

    // If build is not cached, rebuild is true
    // even though the --cached-build flag was used
    if (buildCached) {
      rebuild = false;
    }
  }

  return rebuild;
}

export async function build(api) {
  const config = api.getConfig().app;
  const appPath = api.resolvePath(api.getBasePath(), config.path);
  const buildOptions = getBuildOptions(api);

  const rebuild = shouldRebuild(api);

  if (rebuild && api.getOptions()['cached-build']) {
    console.log('Unable to use previous build. It doesn\'t exist.');
  } else if (!rebuild) {
    console.log('Not building app. Using build from previous deploy at');
    console.log(buildOptions.buildLocation);
  }

  if (rebuild) {
    console.log('Building App Bundle Locally');
    await buildApp(appPath, buildOptions, api.getVerbose(), api);
  }
}

export async function push(api) {
  log('exec => mup meteor push');

  await api.runCommand('meteor.build');

  const config = api.getConfig().app;

  if (!config) {
    console.error('error: no configs found for meteor');
    process.exit(1);
  }

  const buildOptions = getBuildOptions(api);

  const bundlePath = api.resolvePath(buildOptions.buildLocation, 'bundle.tar.gz');

  if (shouldRebuild(api)) {
    await promisify(archiveApp)(buildOptions.buildLocation, api);
  }

  const list = nodemiral.taskList('Pushing Meteor App');

  list.copy('Pushing Meteor App Bundle to the Server', {
    src: bundlePath,
    dest: `/opt/${config.name}/tmp/bundle.tar.gz`,
    progressBar: config.enableUploadProgressBar
  });

  if (prepareBundleSupported(config.docker)) {
    list.executeScript('Prepare Bundle', {
      script: api.resolvePath(
        __dirname,
        'assets/prepare-bundle.sh'
      ),
      vars: {
        appName: config.name,
        dockerImage: config.docker.image,
        env: config.env,
        buildInstructions: config.docker.buildInstructions || []
      }
    });
  }

  const sessions = api.getSessions(['app']);

  return api.runTaskList(list, sessions, {
    series: true,
    verbose: api.verbose
  });
}

export function envconfig(api) {
  log('exec => mup meteor envconfig');

  const config = api.getConfig().app;
  const servers = api.getConfig().servers;
  let bindAddress = '0.0.0.0';

  if (!config) {
    console.error('error: no configs found for meteor');
    process.exit(1);
  }

  config.log = config.log || {
    opts: {
      'max-size': '100m',
      'max-file': 10
    }
  };

  config.nginx = config.nginx || {};

  if (config.docker && config.docker.bind) {
    bindAddress = config.docker.bind;
  }

  if (config.dockerImageFrontendServer) {
    config.docker.imageFrontendServer = config.dockerImageFrontendServer;
  }
  if (!config.docker.imageFrontendServer) {
    config.docker.imageFrontendServer = 'meteorhacks/mup-frontend-server';
  }

  // If imagePort is not set, go with port 80 which was the traditional
  // port used by kadirahq/meteord and meteorhacks/meteord
  config.docker.imagePort = config.docker.imagePort || 80;

  if (config.ssl) {
    config.ssl.port = config.ssl.port || 443;
  }

  const list = nodemiral.taskList('Configuring App');

  list.copy('Pushing the Startup Script', {
    src: api.resolvePath(__dirname, 'assets/templates/start.sh'),
    dest: `/opt/${config.name}/config/start.sh`,
    vars: {
      appName: config.name,
      port: config.env.PORT || 80,
      bind: bindAddress,
      sslConfig: config.ssl,
      logConfig: config.log,
      volumes: config.volumes,
      docker: config.docker,
      proxyConfig: api.getConfig().proxy,
      nginxClientUploadLimit: config.nginx.clientUploadLimit || '10M'
    }
  });

  const env = cloneDeep(config.env);

  env.METEOR_SETTINGS = JSON.stringify(api.getSettings());
  // sending PORT to the docker container is useless.

  // setting PORT in the config is used for the publicly accessible
  // port.

  // docker.imagePort is used for the port exposed from the container.
  // In case the docker.imagePort is different than the container's
  // default port, we set the env PORT to docker.imagePort.
  env.PORT = config.docker.imagePort;

  const hostVars = {};

  Object.keys(config.servers).forEach(key => {
    if (config.servers[key].env) {
      hostVars[servers[key].host] = { env: config.servers[key].env };
    }
    if (config.servers[key].settings) {
      const settings = JSON.stringify(api.getSettingsFromPath(
        config.servers[key].settings));

      if (hostVars[servers[key].host]) {
        hostVars[servers[key].host].env.METEOR_SETTINGS = settings;
      } else {
        hostVars[servers[key].host] = { env: { METEOR_SETTINGS: settings } };
      }
    }
  });

  list.copy('Sending Environment Variables', {
    src: api.resolvePath(__dirname, 'assets/templates/env.list'),
    dest: `/opt/${config.name}/config/env.list`,
    hostVars,
    vars: {
      env: env || {},
      appName: config.name
    }
  });

  const sessions = api.getSessions(['app']);

  return api.runTaskList(list, sessions, {
    series: true,
    verbose: api.verbose
  });
}

export async function start(api) {
  log('exec => mup meteor start');
  const config = api.getConfig().app;
  const service = api.getConfig().swarm !== undefined;

  if (!config) {
    console.error('error: no configs found for meteor');
    process.exit(1);
  }

  const list = nodemiral.taskList('Start Meteor');

  if (service) {
    addStartServiceTask(list, api);
  } else {
    addStartAppTask(list, api);
    checkAppStarted(list, api);
  }

  const sessions = service ? await api.getManagerSession() : api.getSessions(['app']);

  return api.runTaskList(list, [sessions], {
    series: true,
    verbose: api.verbose
  });
}

export function deploy(api) {
  log('exec => mup meteor deploy');

  // validate settings and config before starting
  api.getSettings();
  const config = api.getConfig().app;

  if (!config) {
    console.error('error: no configs found for meteor');
    process.exit(1);
  }

  return api
    .runCommand('meteor.push')
    .then(() => api.runCommand('default.reconfig'));
}

export function stop(api) {
  log('exec => mup meteor stop');
  const config = api.getConfig().app;

  if (!config) {
    console.error('error: no configs found for meteor');
    process.exit(1);
  }

  const list = nodemiral.taskList('Stop Meteor');

  list.executeScript('Stop Meteor', {
    script: api.resolvePath(__dirname, 'assets/meteor-stop.sh'),
    vars: {
      appName: config.name
    }
  });

  const sessions = api.getSessions(['app']);

  return api.runTaskList(list, sessions, { verbose: api.verbose });
}

export function restart(api) {
  const list = nodemiral.taskList('Restart Meteor');
  const sessions = api.getSessions(['app']);
  const config = api.getConfig().app;

  list.executeScript('Stop Meteor', {
    script: api.resolvePath(__dirname, 'assets/meteor-stop.sh'),
    vars: {
      appName: config.name
    }
  });

  addStartAppTask(list, api);
  checkAppStarted(list, api);

  return api.runTaskList(list, sessions, {
    series: true,
    verbose: api.verbose
  });
}

export async function status(api) {
  const config = api.getConfig();
  const lines = [];
  const servers = Object.keys(config.app.servers)
    .map(key => config.servers[key]);

  const results = await map(
    servers,
    server => getInformation(server, config.app.name, api),
    { concurrency: 2 }
  );
  const urlResults = await map(
    servers,
    server => checkUrls(server, config.app, api),
    { concurrency: 2 }
  );

  let overallColor = 'green';

  function updateColor(color) {
    if (color === 'yellow' && overallColor !== 'red') {
      overallColor = color;
    } else if (color === 'red') {
      overallColor = color;
    }
  }

  results.forEach((result, index) => {
    updateColor(result.statusColor);
    updateColor(result.restartColor);

    lines.push(` - ${result.host}: ${chalk[result.statusColor](result.status)} `);

    if (result.status === 'Stopped') {
      return;
    }

    lines.push(`    Created at ${result.created}`);
    lines.push(chalk[result.restartColor](`    Restarted ${result.restartCount} times`));

    lines.push('    ENV: ');
    result.env.forEach(envVar => {
      lines.push(`     - ${envVar}`);
    });

    if (result.exposedPorts.length > 0) {
      lines.push('    Exposed Ports:');
      result.exposedPorts.forEach(port => {
        lines.push(`     - ${port}`);
      });
    }

    if (result.publishedPorts.length > 0) {
      lines.push('    Published Ports:');
      result.publishedPorts.forEach(port => {
        lines.push(`     - ${port}`);
      });
    }

    const urlResult = urlResults[index];

    if (result.publishedPorts.length > 0) {
      lines.push(`    App running at http://${result.host}:${result.publishedPorts[0].split('/')[0]}`);
      lines.push(`     - Available in app's docker container: ${urlResult.inDocker}`);
      lines.push(`     - Available on server: ${urlResult.remote}`);
      lines.push(`     - Available on local computer: ${urlResult.local}`);
    } else {
      lines.push('    App available through reverse proxy');
      lines.push(`     - Available in app's docker container: ${urlResult.inDocker}`);
    }
  });

  console.log(chalk[overallColor]('\n=> Meteor Status'));
  console.log(lines.join('\n'));
}
<|endoftext|>


<commit_before><commit_msg>fix 新規オブジェクト投稿<commit_after><|endoftext|>


<commit_before>/* global it describe context */
describe('Main', () => {
  describe('Method A', () => {
    context('Context 1', () => {
      it('should happen anything', () => {
        throw new Error('just on error');
      });
    });

    context.only('Context 2', () => {
      it.skip('should happen blablabla', () => {
        throw new Error('just on error');
      });

      it('should happen mimimi', () => {
      });
    });
  });

  describe('Method B  ', () => {
  });
});
<commit_msg>hooks na pratica<commit_after>/* global it describe before after beforeEach afterEach */
describe('Main', () => {
  let arr;

  // roda uma vez, antes do bloco
  before(() => {
    // inicia uma conexão no banco
    // criar um conjunto de dados
  });

  // roda uma vez, depois do bloco
  after(() => {
    // fecha conexão do banco
    // apagar esse conjunto de dados
  });

  // roda todas as vezes, antes de CADA bloco
  beforeEach(() => {
    arr = [1, 2, 3];
  });

  // roda todas as vezes, depois de CADA bloco
  afterEach(() => {

  });

  it('should have a size of 4 when push another value to the array', () => {
    arr.push(4);
    console.log(arr.length); // 4
  });

  it('should remove the value 3 when use pop in the array', () => {
    console.log(arr.pop() === 3); // true
  });

  it('should have a size of 2 when pop a value from the array', () => {
    arr.pop();
    console.log(arr.length); // 2
  });

});
/*
describe('Main', () => {
 describe('Method A', () => {
   context('Context 1', () => {
     it('should happen anything', () => {
       throw new Error('just on error');
     });
   });

   context.only('Context 2', () => {
     it.skip('should happen blablabla', () => {
       throw new Error('just o n error');
     });

     it('should happen mimimi', () => {
     });
   });

 });

 describe('Method B  ', () => {
 });
});
*/
<|endoftext|>


<commit_before>import React from 'react'

export default class DialogRemove extends React.Component {
  constructor (props) {
    super(props)

    this.state = {
      open: this.props.open
    }
  }

  componentWillReceiveProps (props) {
    this.setState({open: props.open})
  }

  render () {
    return null
  }
}<commit_msg>remove useless<commit_after><|endoftext|>


<commit_before>var _download = (function () {

    var that = {};

    that.current_sheet = function () {
        var i, j;
        var data = '';
        var html = [];
        var form;
        var columns = _utils.filter( function ( e ) {
                return e['basic'] === true;
           }, _store.active_columns() );

        _assert.not_equal( columns.length, 0,
                           ">> DOWNLOAD
Columns length === 0" );

        var rows = _store.active_rows();

        _assert.not_equal( rows.length, 0,
                           ">> DOWNLOAD
Rows length === 0" );

        for( i = 0; i < columns.length; i += 1 ) {
            data += columns[i]['label'];
            data += ';';
        }
        data += '|';

        for( i = 0; i < rows.length; i += 1 ) {
            for( j = 0; j < columns.length; j += 1 ) {
                data += rows[i][ columns[j]['key'] ];
                data += ';';
            }
            data += '|';
        }

        _assert.not_equal( data, '',
                           ">> DOWNLOAD
Data string empty" );

        $('#download-form')
            .find('input')
            .val( data.slice( 0, data.length-1 ) )
            .end()
            .submit();
    };

    return that;
})();
<commit_msg>Download gives hierarchical csv files<commit_after>var _download = (function () {

    var that = {};

    that.current_sheet = function () {
        var i, j;
        var data = '';
        var html = [];
        var form;
        var columns, rows;

        var add_children = function ( parent ) {
            var i;
            var children = _utils.filter( function ( e ) {
                return e['parent'] === parent;
            }, _store.active_rows() );

            if( children.length === 0 ) {
                return;
            }

            for( i = 0; i < children.length; i += 1 ) {
                data += children[i]['idef'] + ';';
                if( !!children[i]['parent'] === false ) {
                    data += ';'
                }
                else {
                    data += children[i]['parent'] + ';';
                }
                data += children[i]['level'] + ';';

                for( j = 0; j < columns.length; j += 1 ) {
                    data += children[i][ columns[j]['key'] ];
                    data += ';';
                }
                data += '|';

                add_children( children[i]['idef'] );
            }
        };

        columns = _utils.filter( function ( e ) {
                return e['basic'] === true;
           }, _store.active_columns() );

        _assert.not_equal( columns.length, 0,
                           ">> DOWNLOAD
Columns length === 0" );

        data += 'ID;Rodzic;Poziom;';

        for( i = 0; i < columns.length; i += 1 ) {
            data += columns[i]['label'];
            data += ';';
        }
        data += '|';

        add_children( null );

        _assert.not_equal( data, '',
                           ">> DOWNLOAD
Data string empty" );

        $('#download-form')
            .find('input')
            .val( data.slice( 0, data.length-1 ) )
            .end()
            .submit();
    };

    return that;
})();
<|endoftext|>


<commit_before>function reformat(input) {
	//split input into purchases
	var purchases = [];
	var purchase = null;
	var lines = input.split('\n');
	for (var i = 0; i < lines.length; i++) {
		var match = lines[i].match(/([^"]*;)+"\s*(\d+)-\s*(\d+)-\s*(\d+)\s*\d+\s*(\d+):(\d+)\s*"/);
		if (match) {
			if (purchase != null) {
				purchases.push(purchase);
			}
			purchase = {
				'day': match[2],
				'month': match[3],
				'year': match[4],
				'hour': match[5],
				'minute': match[6],
				'isBulletin': false,
				'lines': []
			};
		} else {
			if (purchase != null) {
				purchase.lines.push(lines[i]);
			}
		}
	}

	// parse purchase lines
	var bulletin = null;
	purchases = purchases.map(function(p) {
		var summaryStartIndex = -1;
		for (var i = 1; i < p.lines.length; i++) {
			if (p.lines[i].indexOf('Gesamt') > -1) {
				summaryStartIndex = i;
				break;
			} else if (p.lines[i].indexOf('Tagesbericht') > -1) {
				p.isBulletin = true;
				break;
			}
		}
		if (summaryStartIndex == -1 && !p.isBulletin) {
			return false;
		}
		p.id = p.lines[0].match(/([^"]*;)+"\s*(#\d+ \d+ \d+)/)[2];
		if (p.isBulletin) {
			bulletin = p;
		} else {
			p.products = [];
			// parse products
			for (var i = 1; i < summaryStartIndex; i++) {
				var product = parseProductLine(p.lines[i]);
				if (product) {
					if (product.quantity[0] === '-') {
						if (p.lines[i-1].indexOf('Retour') > -1) {
							product.note = 'Retour';
						} else if (p.lines[i-1].indexOf('Sofort Storno') > -1) {
							if (p.products.length > 0 && ('-' + p.products[p.products.length - 1].quantity) === product.quantity) {
								p.products.splice(p.products.length - 1, 1);
								continue;
							} else {
								product.note = 'Sofort Storno';
							}
						}
					}
					p.products.push(product);
				}
			}

			// parse summary
			p.summary = parseProductLine(p.lines[summaryStartIndex]);
			delete p.summary.name;
			delete p.summary.note;
			p.summary.vats = {};
			for (var i = summaryStartIndex + 1; i < p.lines.length; i++) {
				var match = p.lines[i].match(/([^"]*;)+"\s+MwSt\s*(\d+%)\s*(-?\d+\.\d+)/);
				if (match) {
					p.summary.vats[match[2]] = match[3];
				}
			}
		}
		return p;
	});

	return JSON.stringify(purchases, null, 2);
}

function parseProductLine(line) {
	var match = line.match(/([^"]*;)+"(-?\d+(\.\d+)?)\s+(.*?)\s+(-?\d+\.\d+)/);
	if (match) {
		return {
			'quantity': match[2],
			'name': match[4],
			'price': match[5],
			'note': ''
		};
	} else {
		return false;
	}
}

onmessage = function(e) {
	var input = e.data.splice(0, 1)[0];
	var args = e.data;

	var results = input.map(function(i) {
		i.content = reformat(i.content);
		return i;
	});

	postMessage(results);
}
<commit_msg>Interpret Bulletin<commit_after>function reformat(input) {
	//split input into purchases
	var purchases = [];
	var purchase = null;
	var lines = input.split('\n');
	for (var i = 0; i < lines.length; i++) {
		var match = lines[i].match(/([^"]*;)+"\s*(\d+)-\s*(\d+)-\s*(\d+)\s*\d+\s*(\d+):(\d+)\s*"/);
		if (match) {
			if (purchase != null) {
				purchases.push(purchase);
			}
			purchase = {
				'day': match[2],
				'month': match[3],
				'year': match[4],
				'hour': match[5],
				'minute': match[6],
				'isBulletin': false,
				'lines': []
			};
		} else {
			if (purchase != null) {
				purchase.lines.push(lines[i]);
			}
		}
	}

	// parse purchase lines
	var bulletin = null;
	purchases = purchases.map(function(p) {
		var summaryStartIndex = -1;
		for (var i = 1; i < p.lines.length; i++) {
			if (p.lines[i].indexOf('Gesamt') > -1) {
				summaryStartIndex = i;
				break;
			} else if (p.lines[i].indexOf('Tagesbericht') > -1) {
				p.isBulletin = true;
				break;
			}
		}
		if (summaryStartIndex == -1 && !p.isBulletin) {
			return false;
		}
		p.id = p.lines[0].match(/([^"]*;)+"\s*(#\d+ \d+ \d+)/)[2];
		if (p.isBulletin) {
			bulletin = p;
			p.counter = p.lines[4].match(/([^"]*;)+"\s*Z[^\d]*([^"]*)"/);
			p.quantity = p.lines[5].match(/([^"]*;)+"\s*A[^\d]*([^"]*)"/);
			p.price = p.lines[6].match(/([^"]*;)+"\s*B[^\d]*([^"]*)"/);
			if (p.counter && p.quantity && p.price) {
				p.counter = p.counter[2];
				p.quantity = p.quantity[2];
				p.price = p.price[2];
			} else {
				throw 'Bulletin not parsable: ' + JSON.stringify(p, null, 2);
			}

			// parse products
			p.products = [];
			var taxesStartIndex = -1;
			for (var i = 8; i < p.lines.length; i++) {
				if (p.lines[i].indexOf('Steuern') > -1) {
					taxesStartIndex = i;
					break;
				}
			}
			for (var i = 8; i < taxesStartIndex; i+=4) {
				var product = {
					'id': p.lines[i].match(/([^"]*;)+"\s*(#\d+)/)[2],
					'name': p.lines[i+1].match(/([^"]*;)+"\s*([^"]*?)\s*"/)[2],
					'quantity': p.lines[i+2].match(/([^"]*;)+"\s*A[^ ]+ +([^"]*)"/)[2],
					'price': p.lines[i+3].match(/([^"]*;)+"\s*B[^ ]+ +([^"]*)"/)[2]
				};
				p.products.push(product);
			}
			var paymentMethodsStartIndex = -1;
			for (var i = taxesStartIndex; i < p.lines.length; i++) {
				if (p.lines[i].indexOf('Zahlungsarten') > -1) {
					paymentMethodsStartIndex = i;
					break;
				}
			}
			p.taxes = {};
			for (var i = taxesStartIndex + 1; i < paymentMethodsStartIndex; i+=4) {
				p.taxes[p.lines[i].match(/([^"]*;)+"\s*MwSt\s*([^"]*?)\s*"/)[2]] = p.lines[i+3].match(/([^"]*;)+"\s*MwSt\s*([^"]*)"/)[2];
			}
		} else {
			p.products = [];
			// parse products
			for (var i = 1; i < summaryStartIndex; i++) {
				var product = parseProductLine(p.lines[i]);
				if (product) {
					if (product.quantity[0] === '-') {
						if (p.lines[i-1].indexOf('Retour') > -1) {
							product.note = 'Retour';
						} else if (p.lines[i-1].indexOf('Sofort Storno') > -1) {
							if (p.products.length > 0 && ('-' + p.products[p.products.length - 1].quantity) === product.quantity) {
								p.products.splice(p.products.length - 1, 1);
								continue;
							} else {
								product.note = 'Sofort Storno';
							}
						}
					}
					p.products.push(product);
				}
			}

			// parse summary
			p.summary = parseProductLine(p.lines[summaryStartIndex]);
			delete p.summary.name;
			delete p.summary.note;
			p.summary.taxes = {};
			for (var i = summaryStartIndex + 1; i < p.lines.length; i++) {
				var match = p.lines[i].match(/([^"]*;)+"\s+MwSt\s*(\d+%)\s*(-?\d+\.\d+)/);
				if (match) {
					p.summary.taxes[match[2]] = match[3];
				}
			}
		}
		return p;
	});

	return JSON.stringify(purchases, null, 2);
}

function parseProductLine(line) {
	var match = line.match(/([^"]*;)+"(-?\d+(\.\d+)?)\s+(.*?)\s+(-?\d+\.\d+)/);
	if (match) {
		return {
			'quantity': match[2],
			'name': match[4],
			'price': match[5],
			'note': ''
		};
	} else {
		return false;
	}
}

onmessage = function(e) {
	var input = e.data.splice(0, 1)[0];
	var args = e.data;

	var results = input.map(function(i) {
		i.content = reformat(i.content);
		return i;
	});

	postMessage(results);
}
<|endoftext|>


<commit_before><commit_msg>Fix token switch<commit_after><|endoftext|>


<commit_before>export const state = {
    i18n: {},
    languages: [],
    keyCollector: false,
};

export const getters = {
    isInitialised: state => Object.keys(state.i18n).length > 0,
    __: (state, getters, rootState, rootGetters) => (key, params) => {
        const lang = rootGetters['preferences/lang']
          || ((rootState.preferences && rootState.preferences.global)
            ? rootState.preferences.global.lang : null);

        return state.i18n[lang]
          ? state.i18n[lang][key]
          : key;
    },
    documentTitle: (state, getters, rootState) =>
        title => (rootState.meta.extendedDocumentTitle
            ? `${getters.__(title)} | ${rootState.meta.appName}`
            : getters.__(title)),
};

export const mutations = {
    setI18n: (state, i18n) => (state.i18n = i18n),
    setLanguages: (state, languages) => (state.languages = languages),
    addKey: (state, key) => {
        Object.keys(state.i18n).forEach((lang) => {
            state.i18n[lang][key] = '';
        });
    },
    setKeyCollector: (state, status) => (state.keyCollector = status),
};

export const actions = {
    addMissingKey({ commit }, key) {
        axios.patch(route('system.localisation.addKey'), { langKey: key });
        commit('addKey', key);
    },
};
<commit_msg>remove params parameter, no longer in use here<commit_after>export const state = {
    i18n: {},
    languages: [],
    keyCollector: false,
};

export const getters = {
    isInitialised: state => Object.keys(state.i18n).length > 0,
    __: (state, getters, rootState, rootGetters) => (key) => {
        const lang = rootGetters['preferences/lang']
          || ((rootState.preferences && rootState.preferences.global)
            ? rootState.preferences.global.lang : null);

        return state.i18n[lang]
          ? state.i18n[lang][key]
          : key;
    },
    documentTitle: (state, getters, rootState) =>
        title => (rootState.meta.extendedDocumentTitle
            ? `${getters.__(title)} | ${rootState.meta.appName}`
            : getters.__(title)),
};

export const mutations = {
    setI18n: (state, i18n) => (state.i18n = i18n),
    setLanguages: (state, languages) => (state.languages = languages),
    addKey: (state, key) => {
        Object.keys(state.i18n).forEach((lang) => {
            state.i18n[lang][key] = '';
        });
    },
    setKeyCollector: (state, status) => (state.keyCollector = status),
};

export const actions = {
    addMissingKey({ commit }, key) {
        axios.patch(route('system.localisation.addKey'), { langKey: key });
        commit('addKey', key);
    },
};
<|endoftext|>


<commit_before>'use strict';
const Readline = require('@serialport/parser-readline'); // modify
const Delimiter = require('@serialport/parser-delimiter');
const SerialPort = require('@serialport/stream');
SerialPort.Binding = require('@entrylabs/bindings');

/**
 * 스캔이 끝난 후, 선택된 포트로 시리얼포트를 오픈하는 클래스
 * 스캐너에서 open, initialize 가 일어나고,
 * 라우터에서 setRouter, connect 를 거쳐 통신한다.
 */
class Connector {
    static get DEFAULT_CONNECT_LOST_MILLS() {
        return 500;
    }

    static get DEFAULT_SLAVE_DURATION() {
        return 1000;
    }

    constructor(hwModule, hardwareOptions) {
        this.options = hardwareOptions;
        this.hwModule = hwModule;

        /**
         * @type {MainRouter}
         */
        this.router = undefined;

        /**
         * @type {SerialPort}
         */
        this.serialPort = undefined;

        this.connected = false;
        this.received = false;
    }

    /**
     * MainRouter 를 세팅한다.
     * @param {MainRouter} router
     */
    setRouter(router) {
        this.router = router;
    }

    /**
     * 시리얼포트 생성자 옵션을 만든다.
     * @param serialPortOptions
     * @returns {Object} SerialPort 내 defaultSettings 참조
     * @private
     */
    _makeSerialPortOptions(serialPortOptions) {
        const _options = {
            autoOpen: true,
            baudRate: 9600,
            parity: 'none',
            dataBits: 8,
            stopBits: 1,
            bufferSize: 65536,
        };

        if (serialPortOptions.flowControl === 'hardware') {
            _options.rtscts = true;
        } else if (serialPortOptions.flowControl === 'software') {
            _options.xon = true;
            _options.xoff = true;
        }

        Object.assign(_options, serialPortOptions);
        return _options;
    }

    /**
     * 시리얼포트를 오픈한다.
     * @param {string} port COMPortName
     * @returns {Promise<SerialPort>}
     * // TODO 외부에 오픈하는 시리얼포트 로직을 전부 커넥터로 이동
     */
    open(port) {
        return new Promise((resolve, reject) => {
            const hardwareOptions = this.options;
            this.lostTimer = hardwareOptions.lostTimer || Connector.DEFAULT_CONNECT_LOST_MILLS;

            const serialPort = new SerialPort(port, this._makeSerialPortOptions(hardwareOptions));
            this.serialPort = serialPort;

            const { delimiter, byteDelimiter } = hardwareOptions;
            if (delimiter) {
                serialPort.parser = serialPort.pipe(new Readline({ delimiter }));
            } else if (byteDelimiter) {
                serialPort.parser = serialPort.pipe(new Delimiter({
                    delimiter: byteDelimiter,
                    includeDelimiter: true,
                }));
            }

            serialPort.on('error', reject);
            serialPort.on('open', (error) => {
                serialPort.removeAllListeners('open');
                if (error) {
                    reject(error);
                } else {
                    resolve(this.serialPort);
                }
            });
        });
    };

    /**
     * checkInitialData, requestInitialData 가 둘다 존재하는 경우 handShake 를 진행한다.
     * 둘 중 하나라도 없는 경우는 로직을 종료한다.
     * 만약 firmwareCheck 옵션이 활성화 된 경우면 executeFlash 를 세팅하고 종료한다.
     * 이 플래그는 라우터에서 flasher 를 바로 사용해야하는지 판단한다.
     *
     * @returns {Promise<void>} 준비완료 or 펌웨어체크 준비
     */
    initialize() {
        return new Promise((resolve, reject) => {
            const {
                control,
                duration = Connector.DEFAULT_SLAVE_DURATION,
                firmwarecheck,
            } = this.options;
            const hwModule = this.hwModule;

            if (control) {
                if (firmwarecheck) {
                    this.flashFirmware = setTimeout(() => {
                        this.serialPort.parser ?
                        this.serialPort.parser.removeAllListeners('data') :
                        this.serialPort.removeAllListeners('data');
                        this.executeFlash = true;
                        resolve();
                    }, 3000);
                }

                // TODO 리팩토링 필요
                if (hwModule.checkInitialData && hwModule.requestInitialData) {
                    const serialPortReadStream =
                        this.serialPort.parser ? this.serialPort.parser : this.serialPort;
                    if (control === 'master') {
                        serialPortReadStream.on('data', (data) => {
                            const result = hwModule.checkInitialData(data, this.options);

                            if (result === undefined) {
                                this.send(hwModule.requestInitialData());
                            } else {
                                this.serialPort.removeAllListeners('data');
                                serialPortReadStream.removeAllListeners('data');
                                clearTimeout(this.flashFirmware);
                                if (result === true) {
                                    if (hwModule.setSerialPort) {
                                        hwModule.setSerialPort(this.serialPort);
                                    }
                                    resolve();
                                } else {
                                    reject(new Error('Invalid hardware'));
                                }
                            }
                        });
                    } else {
                        // control type is slave
                        serialPortReadStream.on('data', (data) => {
                            const result = hwModule.checkInitialData(data, this.options);
                            if (result !== undefined) {
                                this.serialPort.removeAllListeners('data');
                                serialPortReadStream.removeAllListeners('data');
                                clearTimeout(this.flashFirmware);
                                clearTimeout(this.slaveTimer);
                                if (result === true) {
                                    if (hwModule.setSerialPort) {
                                        hwModule.setSerialPort(this.serialPort);
                                    }
                                    if (hwModule.resetProperty) {
                                        this.send(hwModule.resetProperty());
                                    }
                                    resolve();
                                } else {
                                    reject(new Error('Invalid hardware'));
                                }
                            }
                        });
                        this.slaveTimer = setInterval(() => {
                            this.send(hwModule.requestInitialData(this.serialPort));
                        }, duration);
                    }
                } else {
                    resolve();
                }
            }
        });
    }

    /**
     * router 와 hwModule 양쪽에 state 변경점을 보낸다.
     * @param {string} state
     * @private
     */
    _sendState(state) {
        this.hwModule.eventController && this.hwModule.eventController(state);
        this.router.sendState(state);
    }

    connect() {
        if (!this.router) {
            throw new Error('router must be set');
        }

        if (!this.serialPort) {
            throw new Error('serialPort must be open');
        }

        const router = this.router;
        const serialPort = this.serialPort;
        const hwModule = this.hwModule;
        const {
            control,
            duration = Connector.DEFAULT_SLAVE_DURATION,
            advertise,
            softwareReset,
        } = this.options;

        this.connected = false;
        this.received = true;

        if (hwModule.connect) {
            hwModule.connect();
        }
        this._sendState('connect');

        if (softwareReset) {
            serialPort.set({ dtr: false });
            setTimeout(() => {
                serialPort.set({ dtr: true });
            },1000);
        }

        if (hwModule.afterConnect) {
            hwModule.afterConnect(this, (state) => {
                this.router.sendState(state);
            });
        }

        const serialPortReadStream =
            serialPort.parser ? serialPort.pipe(serialPort.parser) : serialPort;

        serialPortReadStream.on('data', (data) => {
            if (!hwModule.validateLocalData || hwModule.validateLocalData(data)) {
                if (!this.connected) {
                    this.connected = true;
                    this._sendState('connected');
                }

                this.received = true;
                if (hwModule.handleLocalData) {
                    hwModule.handleLocalData(data);
                }

                // 서버로 데이터를 요청한다.
                router.setHandlerData();
                router.sendEncodedDataToServer();

                // 마스터모드인 경우, 데이터를 받자마자 디바이스로 데이터를 보낸다.
                if (control === 'master' && hwModule.requestLocalData) {
                    const data = hwModule.requestLocalData();
                    data && this.send(data);
                }
            }
        });

        serialPort.on('disconnect', () => {
            this.close();
            this._sendState('disconnected');
        });

        // 디바이스 연결 잃어버린 상태에 대한 관리를 모듈에 맡기거나, 직접 관리한다.
        if (hwModule.lostController) {
            hwModule.lostController(this, router.sendState);
        } else {
            /*
             * this.lostTimer 타임 안에 데이터를 수신해야한다. 그렇지 않으면 연결해제처리한다.
             */
            this.connectionLostTimer = setInterval(() => {
                if (this.connected) {
                    if (this.received === false) {
                        this.connected = false;
                        this._sendState('lost');
                    }
                    this.received = false;
                }
            }, this.lostTimer);
        }

        if (duration && control !== 'master') {
            this.requestLocalDataInterval = setInterval(() => {
                if (hwModule.requestLocalData) {
                    const data = hwModule.requestLocalData();
                    data && this.send(data);
                }
                if (hwModule.getProperty) {
                    const data = hwModule.getProperty();
                    if (data) {
                        this.send(data);
                    }
                }
            }, duration);
        }

        if (advertise) {
            this.advertiseInterval = setInterval(() => {
                router.sendEncodedDataToServer();
            }, advertise);
        }
    }

    clear() {
        this.connected = false;
        if (this.connectionLostTimer) {
            clearInterval(this.connectionLostTimer);
            this.connectionLostTimer = undefined;
        }
        if (this.requestLocalDataInterval) {
            clearInterval(this.requestLocalDataInterval);
            this.requestLocalDataInterval = undefined;
        }
        if (this.advertiseInterval) {
            clearInterval(this.advertiseInterval);
            this.advertiseInterval = undefined;
        }
        if (this.serialPort) {
            this.serialPort.removeAllListeners();
        }
        if (this.serialPort.parser) {
            this.serialPort.parser.removeAllListeners();
        }
    };

    close() {
        this.clear();
        if (this.serialPort && this.serialPort.isOpen) {
            this.serialPort.close((e) => {
                this.serialPort = undefined;
            }, null);
        }
    };

    /**
     * 시리얼포트로 연결된 디바이스에 데이터를 보낸다.
     * @param data
     * @param callback
     */
    send(data, callback) {
        if (this.serialPort && this.serialPort.isOpen && data && !this.isSending) {
            this.isSending = true;

            if (this.options.stream === 'string') {
                data = Buffer.from(data, 'utf8');
            }

            this.serialPort.write(data, () => {
                if (this.serialPort) {
                    this.serialPort.drain(() => {
                        this.isSending = false;
                        callback && callback();
                    });
                }
            });
        }
    };
}

module.exports = Connector;
<commit_msg>close 시 serialPort 가 없는 경우에도 parser 가 있다면 찾는 로직 수정<commit_after>'use strict';
const Readline = require('@serialport/parser-readline'); // modify
const Delimiter = require('@serialport/parser-delimiter');
const SerialPort = require('@serialport/stream');
SerialPort.Binding = require('@entrylabs/bindings');

/**
 * 스캔이 끝난 후, 선택된 포트로 시리얼포트를 오픈하는 클래스
 * 스캐너에서 open, initialize 가 일어나고,
 * 라우터에서 setRouter, connect 를 거쳐 통신한다.
 */
class Connector {
    static get DEFAULT_CONNECT_LOST_MILLS() {
        return 500;
    }

    static get DEFAULT_SLAVE_DURATION() {
        return 1000;
    }

    constructor(hwModule, hardwareOptions) {
        this.options = hardwareOptions;
        this.hwModule = hwModule;

        /**
         * @type {MainRouter}
         */
        this.router = undefined;

        /**
         * @type {SerialPort}
         */
        this.serialPort = undefined;

        this.connected = false;
        this.received = false;
    }

    /**
     * MainRouter 를 세팅한다.
     * @param {MainRouter} router
     */
    setRouter(router) {
        this.router = router;
    }

    /**
     * 시리얼포트 생성자 옵션을 만든다.
     * @param serialPortOptions
     * @returns {Object} SerialPort 내 defaultSettings 참조
     * @private
     */
    _makeSerialPortOptions(serialPortOptions) {
        const _options = {
            autoOpen: true,
            baudRate: 9600,
            parity: 'none',
            dataBits: 8,
            stopBits: 1,
            bufferSize: 65536,
        };

        if (serialPortOptions.flowControl === 'hardware') {
            _options.rtscts = true;
        } else if (serialPortOptions.flowControl === 'software') {
            _options.xon = true;
            _options.xoff = true;
        }

        Object.assign(_options, serialPortOptions);
        return _options;
    }

    /**
     * 시리얼포트를 오픈한다.
     * @param {string} port COMPortName
     * @returns {Promise<SerialPort>}
     * // TODO 외부에 오픈하는 시리얼포트 로직을 전부 커넥터로 이동
     */
    open(port) {
        return new Promise((resolve, reject) => {
            const hardwareOptions = this.options;
            this.lostTimer = hardwareOptions.lostTimer || Connector.DEFAULT_CONNECT_LOST_MILLS;

            const serialPort = new SerialPort(port, this._makeSerialPortOptions(hardwareOptions));
            this.serialPort = serialPort;

            const { delimiter, byteDelimiter } = hardwareOptions;
            if (delimiter) {
                serialPort.parser = serialPort.pipe(new Readline({ delimiter }));
            } else if (byteDelimiter) {
                serialPort.parser = serialPort.pipe(new Delimiter({
                    delimiter: byteDelimiter,
                    includeDelimiter: true,
                }));
            }

            serialPort.on('error', reject);
            serialPort.on('open', (error) => {
                serialPort.removeAllListeners('open');
                if (error) {
                    reject(error);
                } else {
                    resolve(this.serialPort);
                }
            });
        });
    };

    /**
     * checkInitialData, requestInitialData 가 둘다 존재하는 경우 handShake 를 진행한다.
     * 둘 중 하나라도 없는 경우는 로직을 종료한다.
     * 만약 firmwareCheck 옵션이 활성화 된 경우면 executeFlash 를 세팅하고 종료한다.
     * 이 플래그는 라우터에서 flasher 를 바로 사용해야하는지 판단한다.
     *
     * @returns {Promise<void>} 준비완료 or 펌웨어체크 준비
     */
    initialize() {
        return new Promise((resolve, reject) => {
            const {
                control,
                duration = Connector.DEFAULT_SLAVE_DURATION,
                firmwarecheck,
            } = this.options;
            const hwModule = this.hwModule;

            if (control) {
                if (firmwarecheck) {
                    this.flashFirmware = setTimeout(() => {
                        this.serialPort.parser ?
                        this.serialPort.parser.removeAllListeners('data') :
                        this.serialPort.removeAllListeners('data');
                        this.executeFlash = true;
                        resolve();
                    }, 3000);
                }

                // TODO 리팩토링 필요
                if (hwModule.checkInitialData && hwModule.requestInitialData) {
                    const serialPortReadStream =
                        this.serialPort.parser ? this.serialPort.parser : this.serialPort;
                    if (control === 'master') {
                        serialPortReadStream.on('data', (data) => {
                            const result = hwModule.checkInitialData(data, this.options);

                            if (result === undefined) {
                                this.send(hwModule.requestInitialData());
                            } else {
                                this.serialPort.removeAllListeners('data');
                                serialPortReadStream.removeAllListeners('data');
                                clearTimeout(this.flashFirmware);
                                if (result === true) {
                                    if (hwModule.setSerialPort) {
                                        hwModule.setSerialPort(this.serialPort);
                                    }
                                    resolve();
                                } else {
                                    reject(new Error('Invalid hardware'));
                                }
                            }
                        });
                    } else {
                        // control type is slave
                        serialPortReadStream.on('data', (data) => {
                            const result = hwModule.checkInitialData(data, this.options);
                            if (result !== undefined) {
                                this.serialPort.removeAllListeners('data');
                                serialPortReadStream.removeAllListeners('data');
                                clearTimeout(this.flashFirmware);
                                clearTimeout(this.slaveTimer);
                                if (result === true) {
                                    if (hwModule.setSerialPort) {
                                        hwModule.setSerialPort(this.serialPort);
                                    }
                                    if (hwModule.resetProperty) {
                                        this.send(hwModule.resetProperty());
                                    }
                                    resolve();
                                } else {
                                    reject(new Error('Invalid hardware'));
                                }
                            }
                        });
                        this.slaveTimer = setInterval(() => {
                            this.send(hwModule.requestInitialData(this.serialPort));
                        }, duration);
                    }
                } else {
                    resolve();
                }
            }
        });
    }

    /**
     * router 와 hwModule 양쪽에 state 변경점을 보낸다.
     * @param {string} state
     * @private
     */
    _sendState(state) {
        this.hwModule.eventController && this.hwModule.eventController(state);
        this.router.sendState(state);
    }

    connect() {
        if (!this.router) {
            throw new Error('router must be set');
        }

        if (!this.serialPort) {
            throw new Error('serialPort must be open');
        }

        const router = this.router;
        const serialPort = this.serialPort;
        const hwModule = this.hwModule;
        const {
            control,
            duration = Connector.DEFAULT_SLAVE_DURATION,
            advertise,
            softwareReset,
        } = this.options;

        this.connected = false;
        this.received = true;

        if (hwModule.connect) {
            hwModule.connect();
        }
        this._sendState('connect');

        if (softwareReset) {
            serialPort.set({ dtr: false });
            setTimeout(() => {
                serialPort.set({ dtr: true });
            },1000);
        }

        if (hwModule.afterConnect) {
            hwModule.afterConnect(this, (state) => {
                this.router.sendState(state);
            });
        }

        const serialPortReadStream =
            serialPort.parser ? serialPort.pipe(serialPort.parser) : serialPort;

        serialPortReadStream.on('data', (data) => {
            if (!hwModule.validateLocalData || hwModule.validateLocalData(data)) {
                if (!this.connected) {
                    this.connected = true;
                    this._sendState('connected');
                }

                this.received = true;
                if (hwModule.handleLocalData) {
                    hwModule.handleLocalData(data);
                }

                // 서버로 데이터를 요청한다.
                router.setHandlerData();
                router.sendEncodedDataToServer();

                // 마스터모드인 경우, 데이터를 받자마자 디바이스로 데이터를 보낸다.
                if (control === 'master' && hwModule.requestLocalData) {
                    const data = hwModule.requestLocalData();
                    data && this.send(data);
                }
            }
        });

        serialPort.on('disconnect', () => {
            this.close();
            this._sendState('disconnected');
        });

        // 디바이스 연결 잃어버린 상태에 대한 관리를 모듈에 맡기거나, 직접 관리한다.
        if (hwModule.lostController) {
            hwModule.lostController(this, router.sendState);
        } else {
            /*
             * this.lostTimer 타임 안에 데이터를 수신해야한다. 그렇지 않으면 연결해제처리한다.
             */
            this.connectionLostTimer = setInterval(() => {
                if (this.connected) {
                    if (this.received === false) {
                        this.connected = false;
                        this._sendState('lost');
                    }
                    this.received = false;
                }
            }, this.lostTimer);
        }

        if (duration && control !== 'master') {
            this.requestLocalDataInterval = setInterval(() => {
                if (hwModule.requestLocalData) {
                    const data = hwModule.requestLocalData();
                    data && this.send(data);
                }
                if (hwModule.getProperty) {
                    const data = hwModule.getProperty();
                    if (data) {
                        this.send(data);
                    }
                }
            }, duration);
        }

        if (advertise) {
            this.advertiseInterval = setInterval(() => {
                router.sendEncodedDataToServer();
            }, advertise);
        }
    }

    clear() {
        this.connected = false;
        if (this.connectionLostTimer) {
            clearInterval(this.connectionLostTimer);
            this.connectionLostTimer = undefined;
        }
        if (this.requestLocalDataInterval) {
            clearInterval(this.requestLocalDataInterval);
            this.requestLocalDataInterval = undefined;
        }
        if (this.advertiseInterval) {
            clearInterval(this.advertiseInterval);
            this.advertiseInterval = undefined;
        }
        if (this.serialPort) {
            this.serialPort.removeAllListeners();
            if (this.serialPort.parser) {
                this.serialPort.parser.removeAllListeners();
            }
        }
    };

    close() {
        this.clear();
        if (this.serialPort && this.serialPort.isOpen) {
            this.serialPort.close((e) => {
                this.serialPort = undefined;
            }, null);
        }
    };

    /**
     * 시리얼포트로 연결된 디바이스에 데이터를 보낸다.
     * @param data
     * @param callback
     */
    send(data, callback) {
        if (this.serialPort && this.serialPort.isOpen && data && !this.isSending) {
            this.isSending = true;

            if (this.options.stream === 'string') {
                data = Buffer.from(data, 'utf8');
            }

            this.serialPort.write(data, () => {
                if (this.serialPort) {
                    this.serialPort.drain(() => {
                        this.isSending = false;
                        callback && callback();
                    });
                }
            });
        }
    };
}

module.exports = Connector;
<|endoftext|>


<commit_before>var util = require('util');
var twitter = require('twitter');

module.exports = function (context, message) {

    context.log(message.twitter.id);
    context.log(message.twitter.token);

    const twit = new twitter({
        consumer_key: process.env.TwitterConsumerKey,
        consumer_secret: process.env.TwitterConsumerSecret,
        access_token_key: process.env.TwitterAccessTokenKey,
        access_token_secret: process.env.TwitterAccessTokenSecret
    });

    return twit.get(`users/show.json?user_id=${message.twitter.id}`)
        .then(log)
        .then(setOutputBinding)

    function setOutputBinding(data) {
        context.bindings.out = data;
        return data;
    }

    function log(data) {
        context.log(data);
        return data;
    }
}<commit_msg>rename<commit_after>var util = require('util');
var twitter = require('twitter');

module.exports = function (context, message) {

    context.log(message.twitter.id);
    context.log(message.twitter.token);

    const twit = new twitter({
        consumer_key: process.env.TwitterConsumerKey,
        consumer_secret: process.env.TwitterConsumerSecret,
        access_token_key: process.env.TwitterAccessTokenKey,
        access_token_secret: process.env.TwitterAccessTokenSecret
    });

    return twit.get(`users/show.json?user_id=${message.twitter.id}`)
        .then(logData)
        .then(setOutputBinding)

    function setOutputBinding(message) {
        context.bindings.out = message;
        return message;
    }

    function logData(message) {
        context.log(message);
        return message;
    }
}<|endoftext|>