<commit_before>/**
 * Returns an object {name, index} having a generated name and an index
 * for a Creep with memory.role 'role' which is to be spawned by Spawn 'spawn'
 */
function getNameByRole(spawn, role)
{
    var creepIndex = 0;
    var creeps = Game.creeps;

    while (creeps[spawn.room.name + 'X' + role + 'X' + creepIndex])
    {
        creepIndex++;
    }

    var answer =
    {
        name : spawn.room.name + 'X' + role + 'X' + creepIndex,
        index : creepIndex
    };
    return answer;
}

/**
 * Makes a Spawn 'spawn' create a Creep with memory.role 'role' and bodyparts 'parts'
 */
function createByRole (spawn, role, parts)
{
    var creepInfo = getNameByRole(spawn, role);

    var spawnOutput = spawn.createCreep(parts, creepInfo.name, { role: role, index: creepInfo.index })

    // If spawning process started succesfully
    if (spawnOutput == creepInfo.name)
    {
        console.log("Spawning " + role + ": " + creepInfo.name);
        return true;
    }

    console.log ("Couldn't spawn a creep, error: " + spawnOutput);
    return false;
}

/**
 * Returns how many (integer) creeps with memory.role 'role'
 * are already in Spawn "spawn"'s creation queue
 */
function countInQueue(spawn, role)
{
    var inQueue = 0;
    for (var i in spawn.memory.queue)
    {
        var creepSpec = spawn.memory.queue[i];
        if (creepSpec[0] == role) inQueue++;
    }
    return inQueue;
}

/** Checks if there are more or equal Creeps with memory.role 'role' in the same room
 * as Spawn 'spawn'. If not, schedules the appropriate amount of such Creeps to be produced
 * by Spawn 'spawn' with bodies specified by 'parts'. 'creeps' contains already existing creeps
 * of any role. 'creeps' is of type <string, Creep array>
 */
function checkCreepSupply(spawn, role, creeps, desiredAmount, parts)
{

    if (spawn.spawning)
    {
        return;
    }

    if (!spawn.memory.queue)
    {
        spawn.memory.queue = [];
    }

    // num of creeps in the room
    var inRoom = creeps[role] ? creeps[role].length : 0;
    // num of creeps scheduled for creation
    var inQueue = countInQueue(spawn, role);
    // adds creeps to the queue until the total of in room
    // and in queue reaches the desired quantity
    while (inRoom + inQueue < desiredAmount)
    {
        spawn.memory.queue.push([role, parts]);
        inQueue++;
    }

}

var LIFETIME = 1500;
/**
 * If called every tick, makes Spawn 'spawn' produce a Creep with memory.role 'role'
 * and body specified by 'parts' every 'interval' amount of ticks with stagger 'stagger'
 */
function spawnCreepEvery(spawn, role, interval, stagger, parts)
{
    if ((Game.time - stagger) % interval == 0 && countInQueue(spawn, role) == 0)
    {
        if (!spawn.memory.queue)
        {
            spawn.memory.queue = [];
        }
        spawn.memory.queue.push([role, parts]);
    }
}

/**
 * Makes Spawn 'spawn' create Creeps according to its creation queue
 */
function spawnFromQueue(spawn)
{
    // Spawn's busy
    if (spawn.spawning)
        return;
    // Nothing to create, queue's empty
    if (!spawn.memory.queue || !spawn.memory.queue.length)
        return;
    // Creation process started successfully
    if (createByRole(spawn, spawn.memory.queue[0][0], spawn.memory.queue[0][1]))
    {
        spawn.memory.queue.shift();
    }
}

var COST            = {};
COST[MOVE]          = 50;
COST[WORK]          = 100;
COST[CARRY]         = 50;
COST[ATTACK]        = 80;
COST[RANGED_ATTACK] = 150;
COST[HEAL]          = 250;
COST[TOUGH]         = 10;

/**
 * Calculates the energy cost of a Creep with bodyparts 'parts'
 */
function calculateCost (parts)
{
    var cost = 0;
    console.log ("----------------");
    console.log ("Evaluating cost:");
    for (var i in parts)
    {
        var part = parts[i];
        console.log (part);
        if (COST[part])
        {
            cost += COST[part];
        }
    }
    console.log ("Evaluated cost: " + cost);
    console.log ("----------------");
    return cost;
}

var MAX_PARTS = 30;

function generateBody (baseParts, maxEnergy)
{
    var baseBody = [];
    baseBody = baseBody.concat (baseParts);

    // Add enougn MOVE parts to let it move at half the max speed
    for (var i = 0; i < baseParts.length / 2; i++)
    {
        baseBody.push(MOVE);
    }

    // How many baseBodys we can produce with maxEnergy
    var times = Math.floor (maxEnergy / calculateCost(baseBody));

    // If there are more parts than maximum, lower the 'times' accordingly
    if (times * baseBody.length > MAX_PARTS)
    {
        times = Math.floor (MAX_PARTS / baseBody.length);
    }
    else if (times == 0)
    {
        return [];
    }

    // Construct a finalBody out of 'times' baseBodys, which is the biggest body affordable for the maxEnergy
    var finalBody = [];
    for (var i = 0; i < times; i++)
    {
        finalBody = finalBody.concat (baseBody);
    }

    //console.log ('baseBody cost: ' + calculateCost(baseBody));
    //console.log ('maximum energy: '+ maxEnergy);
    //console.log (finalBody);
    return finalBody;
}

/**
 * Makes Spawn 'spawn' perform spawner behaviour
 */
module.exports = function (spawn)
{
    var allCreeps = spawn.room.find(FIND_MY_CREEPS);

    // Make a dictionary 'roleCreeps' <string, Creep Array>
    // with roles as hash codes
    var roleCreeps = {};
    for (var i in allCreeps)
    {
        var thisCreep = allCreeps[i];

        if (!roleCreeps[thisCreep.memory.role])
        {
            roleCreeps[thisCreep.memory.role] = [];
        }

        roleCreeps[thisCreep.memory.role].push(thisCreep);
    }

    // Get total energy usable in Creep creation
    var totalEnergy = spawn.energy;

    // Find all extensions
    var extensions = spawn.room.find(FIND_MY_STRUCTURES, {
        filter: function (s)
        {
            return s.structureType == STRUCTURE_EXTENSION;
        }
    });

    for (var i in extensions)
    {
        totalEnergy += extensions[i].energy;
    }

    var baseBodies = require ('baseBodies');

    // Max energy a single creep may cost
    var spawningEnergy = totalEnergy;

    var harvesterBody = generateBody (baseBodies['harvester'], spawningEnergy);
    var guardBody =     generateBody (baseBodies['guard'],     spawningEnergy);

    console.log ("Harvester body: ");
    console.log (harvesterBody);

    spawnCreepEvery  (spawn, 'harvester', Math.round(LIFETIME / 6), 0, harvesterBody);
    checkCreepSupply (spawn, 'harvester', roleCreeps,               1, harvesterBody);

    spawnCreepEvery (spawn, 'upgrader', LIFETIME / 2, 100, generateBody (baseBodies['upgrader'], spawningEnergy));
    spawnCreepEvery (spawn, 'builder',  LIFETIME / 2, 200, generateBody (baseBodies['builder'],  spawningEnergy));

    // Make number of guards and number of enemies in the room match
    var targets = spawn.room.find (FIND_HOSTILE_CREEPS);
    var min = targets.length < 1 ? 1 : targets.length;
    checkCreepSupply (spawn, 'guard', roleCreeps, min, guardBody);

    // Find all storages in the room
    var storages = spawn.room.find(FIND_MY_STRUCTURES, {
        filter: function (s)
        {
            return s.structureType == STRUCTURE_STORAGE;
        }
    });

    // If there are storages in the room, schedule creation of tankers
    if (storages.length >= 1)
    {
        var tankerBody = generateBody (baseBodies['tanker'], spawningEnergy);
        checkCreepSupply (spawn, 'tanker', roleCreeps,   1,   tankerBody);
        spawnCreepEvery  (spawn, 'tanker', LIFETIME / 2, 400, tankerBody);
    }

    spawnFromQueue (spawn);
}<commit_msg>minor<commit_after>/**
 * Returns an object {name, index} having a generated name and an index
 * for a Creep with memory.role 'role' which is to be spawned by Spawn 'spawn'
 */
function getNameByRole(spawn, role)
{
    var creepIndex = 0;
    var creeps = Game.creeps;

    while (creeps[spawn.room.name + 'X' + role + 'X' + creepIndex])
    {
        creepIndex++;
    }

    var answer =
    {
        name : spawn.room.name + 'X' + role + 'X' + creepIndex,
        index : creepIndex
    };
    return answer;
}

/**
 * Makes a Spawn 'spawn' create a Creep with memory.role 'role' and bodyparts 'parts'
 */
function createByRole (spawn, role, parts)
{
    var creepInfo = getNameByRole(spawn, role);

    var spawnOutput = spawn.createCreep(parts, creepInfo.name, { role: role, index: creepInfo.index })

    // If spawning process started succesfully
    if (spawnOutput == creepInfo.name)
    {
        console.log("Spawning " + role + ": " + creepInfo.name);
        return true;
    }

    console.log ("Couldn't spawn a creep, error: " + spawnOutput);
    return false;
}

/**
 * Returns how many (integer) creeps with memory.role 'role'
 * are already in Spawn "spawn"'s creation queue
 */
function countInQueue(spawn, role)
{
    var inQueue = 0;
    for (var i in spawn.memory.queue)
    {
        var creepSpec = spawn.memory.queue[i];
        if (creepSpec[0] == role) inQueue++;
    }
    return inQueue;
}

/** Checks if there are more or equal Creeps with memory.role 'role' in the same room
 * as Spawn 'spawn'. If not, schedules the appropriate amount of such Creeps to be produced
 * by Spawn 'spawn' with bodies specified by 'parts'. 'creeps' contains already existing creeps
 * of any role. 'creeps' is of type <string, Creep array>
 */
function checkCreepSupply(spawn, role, creeps, desiredAmount, parts)
{

    if (spawn.spawning)
    {
        return;
    }

    if (!spawn.memory.queue)
    {
        spawn.memory.queue = [];
    }

    // num of creeps in the room
    var inRoom = creeps[role] ? creeps[role].length : 0;
    // num of creeps scheduled for creation
    var inQueue = countInQueue(spawn, role);
    // adds creeps to the queue until the total of in room
    // and in queue reaches the desired quantity
    while (inRoom + inQueue < desiredAmount)
    {
        spawn.memory.queue.push([role, parts]);
        inQueue++;
    }

}

var LIFETIME = 1500;
/**
 * If called every tick, makes Spawn 'spawn' produce a Creep with memory.role 'role'
 * and body specified by 'parts' every 'interval' amount of ticks with stagger 'stagger'
 */
function spawnCreepEvery(spawn, role, interval, stagger, parts)
{
    if ((Game.time - stagger) % interval == 0 && countInQueue(spawn, role) == 0)
    {
        if (!spawn.memory.queue)
        {
            spawn.memory.queue = [];
        }
        spawn.memory.queue.push([role, parts]);
    }
}

/**
 * Makes Spawn 'spawn' create Creeps according to its creation queue
 */
function spawnFromQueue(spawn)
{
    // Spawn's busy
    if (spawn.spawning)
        return;
    // Nothing to create, queue's empty
    if (!spawn.memory.queue || !spawn.memory.queue.length)
        return;
    // Creation process started successfully
    if (createByRole(spawn, spawn.memory.queue[0][0], spawn.memory.queue[0][1]))
    {
        spawn.memory.queue.shift();
    }
}

var COST            = {};
COST[MOVE]          = 50;
COST[WORK]          = 100;
COST[CARRY]         = 50;
COST[ATTACK]        = 80;
COST[RANGED_ATTACK] = 150;
COST[HEAL]          = 250;
COST[TOUGH]         = 10;

/**
 * Calculates the energy cost of a Creep with bodyparts 'parts'
 */
function calculateCost (parts)
{
    var cost = 0;
    console.log ("----------------");
    console.log ("Evaluating cost:");
    for (var i in parts)
    {
        var part = parts[i];
        console.log (part);
        if (COST[part])
        {
            cost += COST[part];
        }
    }
    console.log ("Evaluated cost: " + cost);
    console.log ("----------------");
    return cost;
}

var MAX_PARTS = 30;

function generateBody (baseParts, maxEnergy)
{
    var baseBody = [];
    baseBody = baseBody.concat (baseParts);

    // Add enough MOVE parts to let it move at half the max speed
    for (var i = 0; i < baseParts.length / 2; i++)
    {
        baseBody.push (MOVE);
    }

    // How many baseBodys we can produce with maxEnergy
    var times = Math.floor (maxEnergy / calculateCost(baseBody));

    // If there are more parts than maximum, lower the 'times' accordingly
    if (times * baseBody.length > MAX_PARTS)
    {
        times = Math.floor (MAX_PARTS / baseBody.length);
    }
    else if (times == 0)
    {
        return [];
    }

    // Construct a finalBody out of 'times' baseBodys, which is the biggest body affordable for the maxEnergy
    var finalBody = [];
    for (var i = 0; i < times; i++)
    {
        finalBody = finalBody.concat (baseBody);
    }

    //console.log ('baseBody cost: ' + calculateCost(baseBody));
    //console.log ('maximum energy: '+ maxEnergy);
    //console.log (finalBody);
    return finalBody;
}

/**
 * Makes Spawn 'spawn' perform spawner behaviour
 */
module.exports = function (spawn)
{
    var allCreeps = spawn.room.find(FIND_MY_CREEPS);

    // Make a dictionary 'roleCreeps' <string, Creep Array>
    // with roles as hash codes
    var roleCreeps = {};
    for (var i in allCreeps)
    {
        var thisCreep = allCreeps[i];

        if (!roleCreeps[thisCreep.memory.role])
        {
            roleCreeps[thisCreep.memory.role] = [];
        }

        roleCreeps[thisCreep.memory.role].push(thisCreep);
    }

    // Get total energy usable in Creep creation
    var totalEnergy = spawn.energy;

    // Find all extensions
    var extensions = spawn.room.find(FIND_MY_STRUCTURES, {
        filter: function (s)
        {
            return s.structureType == STRUCTURE_EXTENSION;
        }
    });

    for (var i in extensions)
    {
        totalEnergy += extensions[i].energy;
    }

    var baseBodies = require ('baseBodies');

    // Max energy a single creep may cost
    var spawningEnergy = totalEnergy;

    var harvesterBody = generateBody (baseBodies['harvester'], spawningEnergy);
    var guardBody =     generateBody (baseBodies['guard'],     spawningEnergy);

    console.log ("Harvester body: ");
    console.log (harvesterBody);

    spawnCreepEvery  (spawn, 'harvester', Math.round(LIFETIME / 6), 0, harvesterBody);
    checkCreepSupply (spawn, 'harvester', roleCreeps,               1, harvesterBody);

    spawnCreepEvery (spawn, 'upgrader', LIFETIME / 2, 100, generateBody (baseBodies['upgrader'], spawningEnergy));
    spawnCreepEvery (spawn, 'builder',  LIFETIME / 2, 200, generateBody (baseBodies['builder'],  spawningEnergy));

    // Make number of guards and number of enemies in the room match
    var targets = spawn.room.find (FIND_HOSTILE_CREEPS);
    var min = targets.length < 1 ? 1 : targets.length;
    checkCreepSupply (spawn, 'guard', roleCreeps, min, guardBody);

    // Find all storages in the room
    var storages = spawn.room.find(FIND_MY_STRUCTURES, {
        filter: function (s)
        {
            return s.structureType == STRUCTURE_STORAGE;
        }
    });

    // If there are storages in the room, schedule creation of tankers
    if (storages.length >= 1)
    {
        var tankerBody = generateBody (baseBodies['tanker'], spawningEnergy);
        checkCreepSupply (spawn, 'tanker', roleCreeps,   1,   tankerBody);
        spawnCreepEvery  (spawn, 'tanker', LIFETIME / 2, 400, tankerBody);
    }

    spawnFromQueue (spawn);
}<|endoftext|>


<commit_before>/* REQUIRED DEPENDENCIES */
var reload = require('require-reload')(require);
var fs = require('fs');
var Command = reload('./Command.js');
var _Logger = reload('./Logger.js');

/**
 * @class
 * @classdesc Handles a directory of .js files formatted as {@link Command}.
 * @prop {String} prefix Prefix for the commands handled by this CommandManager.
 * @prop {String} dir Path where the commands are located from the root directory.
 * @prop {Object<Command>} commands The loaded {@link Command}s.
 */
class CommandManager {

	/**
	 * @constructor
	 * @arg {Object} config The bot's config settings.
	 * @arg {String} prefix Prefix for the commands handled by this CommandManager.
	 * @arg {String} [dir="commands/user/"] Path to load command from, from the root directory of the bot.
	 * @arg {Sting} [color] The color to log commands with.
	 */
	constructor(config, prefix, dir = 'commands/user/', color) {
		this.prefix = prefix;
		this.directory = `${__dirname}/../${dir}`;
		this.commands = {};
		this.logger = new _Logger(config.logTimestamp, color);
	}

	/**
	 * Initialize the command manager, loading each command in the set directory.
	 * @arg {Client} bot
	 * @arg {Object} config The bot's config settings.
	 * @returns {Promise}
	 */
	initialize(bot, config) {
		return new Promise((resolve, reject) => {
			fs.readdir(this.directory, (err, files) => {
				if (err) reject(`Error reading commands directory: ${err}`);
				else if (!files) reject(`No files in directory ${this.directory}`);
				else {
					for (let name of files) {
						if (name.endsWith('.js')) {
							try {
								name = name.replace(/\.js$/, '');
								this.commands[name] = new Command(name, this.prefix, reload(this.directory + name + '.js'), bot, config);
							} catch (e) {
								this.logger.error(`${e}\n${e.stack}`, 'Error loading command ' + name);
							}
						}
					}
					resolve();
				}
			});
		});
	}

	/**
	 * Called when a message is detected with the prefix. Decides what to do.
	 * @arg {Eris} bot The client.
	 * @arg {Eris.Message} msg The matching message.
	 * @arg {Object} config The JSON formatted config file.
	 */
	processCommand(bot, msg, config) {
		let name = msg.content.replace(this.prefix, '').split(/ |\n/)[0];
		let command = this.checkForMatch(name.toLowerCase());
		if (command !== null) {
			let suffix = msg.content.replace(this.prefix + name, '').trim();
			this.logger.logCommand(msg.channel.guild === undefined ? null : msg.channel.guild.name, msg.author.username, this.prefix + command.name, msg.cleanContent.replace(this.prefix + name, '').trim());
			return command.execute(bot, msg, suffix, config, this.logger);
		} else if (name.toLowerCase() === 'help') {
			return this.help(bot, msg, msg.content.replace(this.prefix + name, '').trim());
		}
	}

	/**
	 * Checks if there is a matching command in this CommandManager.
	 * @arg {String} name The command name to look for.
	 * @returns {?Command} Returns the matching {@link Command} or false.
	 */
	checkForMatch(name) {
		if (name.startsWith(this.prefix)) {
			name = name.substr(1);
		}
		for (let key in this.commands) {
			if (key === name || this.commands[key].aliases.includes(name)) {
				return this.commands[key];
			}
		}
		return null;
	}

	/**
	 * Built-in help command
	 * If no command is specified it will DM a list of commands.
	 * If a command is specified it will send info on that command.
	 * @arg {Eris} bot The client.
	 * @arg {Eris.Message} msg The message that triggered the command.
	 * @arg {String} [command] The command to get help for.
	 */
	help(bot, msg, command) {
		this.logger.logCommand(msg.channel.guild === undefined ? null : msg.channel.guild.name, msg.author.username, this.prefix + 'help', command);
		if (!command) {
			let messageQueue = [];
			let currentMessage = `\n// Here's a list of my commands. For more info do: ${this.prefix}help <command>`;
			for (let cmd in this.commands) {
				if (this.commands[cmd].hidden === true) continue;
				let toAdd = this.commands[cmd].helpShort;
				if (currentMessage.length + toAdd.length >= 1900) {
					messageQueue.push(currentMessage);
					currentMessage = '';
				}
				currentMessage += '\n' + toAdd;
			}
			messageQueue.push(currentMessage);
			bot.getDMChannel(msg.author.id).then(chan => {
				let sendInOrder = setInterval(() => {
					if (messageQueue.length > 0) {
						bot.createMessage(chan.id, '```glsl' + messageQueue.shift() + '```');
					} else {
						clearInterval(sendInOrder);
					}
				}, 300);
			});
		} else {
			let cmd = this.checkForMatch(command);
			if (cmd === null) {
				bot.createMessage(msg.channel.id, `Command \`${this.prefix}${command}\` not found`);
			} else {
				bot.createMessage(msg.channel.id, cmd.helpMessage);
			}
		}
	}

	/**
	 * Reload or load a command.
	 * @arg {Client} bot The client.
	 * @arg {String} channelId The channel to respond in.
	 * @arg {String} command The command to reload or load.
	 * @arg {Object} config The bot's config.
	 */
	reload(bot, channelId, command, config) {
		fs.access(`${this.directory}${command}.js`, fs.R_OK | fs.F_OK, error => {
			if (error) {
				bot.createMessage(channelId, 'Command does not exist');
			} else {
				try {
					if (this.commands.hasOwnProperty(command)) {
						this.commands[command].destroy();
					}
					this.commands[command] = new Command(command, this.prefix, reload(`${this.directory}${command}.js`), config, bot);
					bot.createMessage(channelId, `Command ${this.prefix}${command} loaded`);
				} catch (error) {
					this.logger.error(error, 'Error reloading command ' + command);
					bot.createMessage(channelId, `Error loading command: ${error}`);
				}
			}
		});
	}
}

module.exports = CommandManager;<commit_msg>added a response that auto-deletes to help commands<commit_after>/* REQUIRED DEPENDENCIES */
var reload = require('require-reload')(require);
var fs = require('fs');
var Command = reload('./Command.js');
var _Logger = reload('./Logger.js');

/**
 * @class
 * @classdesc Handles a directory of .js files formatted as {@link Command}.
 * @prop {String} prefix Prefix for the commands handled by this CommandManager.
 * @prop {String} dir Path where the commands are located from the root directory.
 * @prop {Object<Command>} commands The loaded {@link Command}s.
 */
class CommandManager {

	/**
	 * @constructor
	 * @arg {Object} config The bot's config settings.
	 * @arg {String} prefix Prefix for the commands handled by this CommandManager.
	 * @arg {String} [dir="commands/user/"] Path to load command from, from the root directory of the bot.
	 * @arg {Sting} [color] The color to log commands with.
	 */
	constructor(config, prefix, dir = 'commands/user/', color) {
		this.prefix = prefix;
		this.directory = `${__dirname}/../${dir}`;
		this.commands = {};
		this.logger = new _Logger(config.logTimestamp, color);
	}

	/**
	 * Initialize the command manager, loading each command in the set directory.
	 * @arg {Client} bot
	 * @arg {Object} config The bot's config settings.
	 * @returns {Promise}
	 */
	initialize(bot, config) {
		return new Promise((resolve, reject) => {
			fs.readdir(this.directory, (err, files) => {
				if (err) reject(`Error reading commands directory: ${err}`);
				else if (!files) reject(`No files in directory ${this.directory}`);
				else {
					for (let name of files) {
						if (name.endsWith('.js')) {
							try {
								name = name.replace(/\.js$/, '');
								this.commands[name] = new Command(name, this.prefix, reload(this.directory + name + '.js'), bot, config);
							} catch (e) {
								this.logger.error(`${e}\n${e.stack}`, 'Error loading command ' + name);
							}
						}
					}
					resolve();
				}
			});
		});
	}

	/**
	 * Called when a message is detected with the prefix. Decides what to do.
	 * @arg {Eris} bot The client.
	 * @arg {Eris.Message} msg The matching message.
	 * @arg {Object} config The JSON formatted config file.
	 */
	processCommand(bot, msg, config) {
		let name = msg.content.replace(this.prefix, '').split(/ |\n/)[0];
		let command = this.checkForMatch(name.toLowerCase());
		if (command !== null) {
			let suffix = msg.content.replace(this.prefix + name, '').trim();
			this.logger.logCommand(msg.channel.guild === undefined ? null : msg.channel.guild.name, msg.author.username, this.prefix + command.name, msg.cleanContent.replace(this.prefix + name, '').trim());
			return command.execute(bot, msg, suffix, config, this.logger);
		} else if (name.toLowerCase() === 'help') {
			return this.help(bot, msg, msg.content.replace(this.prefix + name, '').trim());
		}
	}

	/**
	 * Checks if there is a matching command in this CommandManager.
	 * @arg {String} name The command name to look for.
	 * @returns {?Command} Returns the matching {@link Command} or false.
	 */
	checkForMatch(name) {
		if (name.startsWith(this.prefix)) {
			name = name.substr(1);
		}
		for (let key in this.commands) {
			if (key === name || this.commands[key].aliases.includes(name)) {
				return this.commands[key];
			}
		}
		return null;
	}

	/**
	 * Built-in help command
	 * If no command is specified it will DM a list of commands.
	 * If a command is specified it will send info on that command.
	 * @arg {Eris} bot The client.
	 * @arg {Eris.Message} msg The message that triggered the command.
	 * @arg {String} [command] The command to get help for.
	 */
	help(bot, msg, command) {
		this.logger.logCommand(msg.channel.guild === undefined ? null : msg.channel.guild.name, msg.author.username, this.prefix + 'help', command);
		if (!command) {
			let messageQueue = [];
			let currentMessage = `\n// Here's a list of my commands. For more info do: ${this.prefix}help <command>`;
			for (let cmd in this.commands) {
				if (this.commands[cmd].hidden === true) continue;
				let toAdd = this.commands[cmd].helpShort;
				if (currentMessage.length + toAdd.length >= 1900) {
					messageQueue.push(currentMessage);
					currentMessage = '';
				}
				currentMessage += '\n' + toAdd;
			}
			messageQueue.push(currentMessage);
			bot.getDMChannel(msg.author.id).then(chan => {
				let sendInOrder = setInterval(() => {
					if (messageQueue.length > 0) {
						bot.createMessage(chan.id, '```glsl' + messageQueue.shift() + '```');
					} else {
						clearInterval(sendInOrder);
					}
				}, 300);
			}).then(bot.createMessage(msg.channel.id, ':thumbsup:').then(sentMsg => {
				setTimeout(() => { sentMsg.delete(); }, 5000);
			}));
		} else {
			let cmd = this.checkForMatch(command);
			if (cmd === null) {
				bot.createMessage(msg.channel.id, `Command \`${this.prefix}${command}\` not found`);
			} else {
				bot.createMessage(msg.channel.id, cmd.helpMessage);
			}
		}
	}

	/**
	 * Reload or load a command.
	 * @arg {Client} bot The client.
	 * @arg {String} channelId The channel to respond in.
	 * @arg {String} command The command to reload or load.
	 * @arg {Object} config The bot's config.
	 */
	reload(bot, channelId, command, config) {
		fs.access(`${this.directory}${command}.js`, fs.R_OK | fs.F_OK, error => {
			if (error) {
				bot.createMessage(channelId, 'Command does not exist');
			} else {
				try {
					if (this.commands.hasOwnProperty(command)) {
						this.commands[command].destroy();
					}
					this.commands[command] = new Command(command, this.prefix, reload(`${this.directory}${command}.js`), config, bot);
					bot.createMessage(channelId, `Command ${this.prefix}${command} loaded`);
				} catch (error) {
					this.logger.error(error, 'Error reloading command ' + command);
					bot.createMessage(channelId, `Error loading command: ${error}`);
				}
			}
		});
	}
}

module.exports = CommandManager;<|endoftext|>


<commit_before>angular.module('yds').directive('ydsHybrid', ['Data', '$http', '$stateParams', '$timeout',
	function(Data, $http, $stateParams, $timeout){
	return {
		restrict: 'E',
		scope: {},
		template: '
' +
					'
0">' +
							'' +
							'  Error: {{ydsAlert}}' +
					'
' +
				  '
',
		compile: function(tElem, tAttrs){
			return {
				pre: function(scope, element, iAttrs) {
					scope.ydsAlert = "";
					var embedCode = $stateParams.embedCode;

					var hybridContainer = angular.element(element[0].querySelector('.hybrid-container'));

					//create a random id for the element that will render the chart
					var elementId = "hybrid" + Data.createRandomId();
					hybridContainer[0].id = elementId;

					// Recover saved object from embed code and visualise it
					Data.recoverEmbedCode(embedCode)
					.then (function (response) {
						visualiseProject(response.embedding.project_id, response.embedding.type)
					}, function (error) {
						scope.ydsAlert = error.message;
						console.log('error during Data.recoverEmbedCode:', error);
					});

					/**
					 * Formats the server's response according to the chart type
					 * @param viewType	Chart type (pie, line, map etc.)
                     * @param response	Server's response
                     * @returns {{}}	Formatted response
                     */
					var formatResponseData = function(viewType, response) {
						var newData = {};					// Object to put formatted data in
						var responseData = response.data;	// Data from the response

						// Get graph data
						newData.data = responseData.data;

						// Get view and find title from view
						var titleView = _.first(response.view);

						newData.title = responseData[titleView.attribute];
						if (_.isUndefined(newData.title)) {
							newData.title = Data.deepObjSearch(responseData, titleView.attribute);
						}

						// Get remaining fields (depending on the view type)
						switch(viewType) {
							case "line":
							case "pie":
								// Get series name
								newData.series = responseData.series;
								break;
							case "bar":
								// Get categories
								newData.categories = responseData.categories;
								break;
							default:
								console.error("Unknown chart type!");
						}

						// Return formatted data
						return newData;
					};

					//function to create a pie visualisation using data from the server
					var pieVisualisation = function (response) {
						var formattedData = formatResponseData("pie", response);

						var options = {
							chart: {
								plotBackgroundColor: null,
								plotBorderWidth: null,
								plotShadow: false,
								type: 'pie',
								renderTo: elementId
							},
							title: {
								text: formattedData.title
							},
							tooltip: {
								pointFormat: '{series.name}: {point.percentage:.1f}%'
							},
							plotOptions: {
								pie: {
									allowPointSelect: true,
									cursor: 'pointer',
									dataLabels: {
										enabled: false
									},
									showInLegend: true
								}
							},
							series: [{
								name: formattedData.series,
								colorByPoint: true,
								data: formattedData.data
							}],
							exporting: {
								enabled: false
							}
						};

						var chart = new Highcharts.Chart(options);
					};

					//function to create a bar visualisation using data from the server
					var barVisualisation = function (response) {
						var formattedData = formatResponseData("bar", response);

						var options = {
							chart: {
								type: 'column',
								renderTo: elementId
							},
							title: {
								text: formattedData.title
							},
							xAxis: {
								categories: formattedData.categories,
								crosshair: true
							},
							tooltip: {
								headerFormat: '{point.key}
',
								pointFormat: '
{series.name}: 	' +
								'{point.y:.1f}
',
								footerFormat: '
',
								shared: true,
								useHTML: true
							},
							plotOptions: {
								column: {
									pointPadding: 0.2,
									borderWidth: 0
								}
							},
							series: formattedData.data,
							exporting: {
								enabled: false
							}
						};

						var chart = new Highcharts.Chart(options);
					};

					//function to create a line visualisation using data from the server
					var lineVisualisation = function (response) {
						var formattedData = formatResponseData("line", response);

						var options = {
							chart: {
								renderTo: elementId
							},
							rangeSelector: {
								selected: 1
							},

							title: {
								text: formattedData.title
							},
							series: [{
								name: formattedData.series,
								data: formattedData.data,
								tooltip: {
									valueDecimals: 2
								}
							}],
							exporting: {
								enabled: false
							}
						};

						var chart = new Highcharts.StockChart(options);
					};

					//function to create a map visualisation using data from the server
					var mapVisualisation = function (response) {
						var map = L.map(elementId, {
							center: [35.52, 23.80],
							zoom: 5
						});

						L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
							maxZoom: 18,
							attribution: 'Map data © OpenStreetMap contributors',
						}).addTo(map);

						var polyline = L.polyline([]).addTo(map);
						var route = angular.copy(response.route);
						for (var i=0; i<route.length; i++){
							polyline.addLatLng([parseFloat(route[i].lng),parseFloat(route[i].lat)]);
						}

						// zoom the map to the polyline
						map.fitBounds(polyline.getBounds());
					};

					//function responsible for the visualisation of a project depending on the project id and the vis_type
					var visualiseProject = function (projectId, vizType) {
						vizType = vizType.toLowerCase();

						if (vizType == "pie") {
							Data.getProjectVis(vizType, projectId, "default", "en")
							.then(function (response) {
								pieVisualisation(response);
							}, function (error) {
								console.log('error', error);
							});
						} else if (vizType == "bar") {
							Data.getProjectVis(vizType, projectId, "default", "en")
							.then(function (response) {
								barVisualisation(response);
							}, function (error) {
								console.log('error', error);
							});
						} else if (vizType == "line") {
							Data.getProjectVis(vizType, projectId, "default", "en")
							.then(function (response) {
								lineVisualisation(response);
							}, function (error) {
								console.log('error', error);
							});
						} else if (vizType == "map") {
							Data.getProjectVis(vizType, projectId, "default", "en")
							.then(function (response) {
								mapVisualisation(response);
							}, function (error) {
								console.log('error', error);
							});
						}
					};
				}
			}
		}
	}
}]);<commit_msg>Hybrid component formats map data correctly<commit_after>angular.module('yds').directive('ydsHybrid', ['Data', '$http', '$stateParams', '$timeout',
	function(Data, $http, $stateParams, $timeout){
	return {
		restrict: 'E',
		scope: {},
		template: '
' +
					'
0">' +
							'' +
							'  Error: {{ydsAlert}}' +
					'
' +
				  '
',
		compile: function(tElem, tAttrs){
			return {
				pre: function(scope, element, iAttrs) {
					scope.ydsAlert = "";
					var embedCode = $stateParams.embedCode;

					var hybridContainer = angular.element(element[0].querySelector('.hybrid-container'));

					//create a random id for the element that will render the chart
					var elementId = "hybrid" + Data.createRandomId();
					hybridContainer[0].id = elementId;

					// Recover saved object from embed code and visualise it
					Data.recoverEmbedCode(embedCode)
					.then (function (response) {
						visualiseProject(response.embedding.project_id, response.embedding.type)
					}, function (error) {
						scope.ydsAlert = error.message;
						console.log('error during Data.recoverEmbedCode:', error);
					});

					/**
					 * Formats the server's response according to the chart type
					 * @param viewType	Chart type (pie, line, map etc.)
                     * @param response	Server's response
                     * @returns {{}}	Formatted response
                     */
					var formatResponseData = function(viewType, response) {
						var newData = {};					// Object to put formatted data in
						var responseData = response.data;	// Data from the response

						// If chart is not a map, get some data that is common for all of them
						if (viewType != "map") {
							// Get graph data
							newData.data = responseData.data;

							// Get view and find title from view
							var titleView = _.first(response.view);

							newData.title = responseData[titleView.attribute];
							if (_.isUndefined(newData.title)) {
								newData.title = Data.deepObjSearch(responseData, titleView.attribute);
							}
						}

						// Get remaining fields (depending on the view type)
						switch(viewType) {
							case "line":
							case "pie":
								// Get series name
								newData.series = responseData.series;
								break;
							case "bar":
								// Get categories
								newData.categories = responseData.categories;
								break;
							case "map":
								// Get route
								newData.route = _.first(responseData.routes).asWKT;
								break;
							default:
								console.error("Unknown chart type!");
						}

						// Return formatted data
						return newData;
					};

					//function to create a pie visualisation using data from the server
					var pieVisualisation = function (response) {
						var formattedData = formatResponseData("pie", response);

						var options = {
							chart: {
								plotBackgroundColor: null,
								plotBorderWidth: null,
								plotShadow: false,
								type: 'pie',
								renderTo: elementId
							},
							title: {
								text: formattedData.title
							},
							tooltip: {
								pointFormat: '{series.name}: {point.percentage:.1f}%'
							},
							plotOptions: {
								pie: {
									allowPointSelect: true,
									cursor: 'pointer',
									dataLabels: {
										enabled: false
									},
									showInLegend: true
								}
							},
							series: [{
								name: formattedData.series,
								colorByPoint: true,
								data: formattedData.data
							}],
							exporting: {
								enabled: false
							}
						};

						var chart = new Highcharts.Chart(options);
					};

					//function to create a bar visualisation using data from the server
					var barVisualisation = function (response) {
						var formattedData = formatResponseData("bar", response);

						var options = {
							chart: {
								type: 'column',
								renderTo: elementId
							},
							title: {
								text: formattedData.title
							},
							xAxis: {
								categories: formattedData.categories,
								crosshair: true
							},
							tooltip: {
								headerFormat: '{point.key}
',
								pointFormat: '
{series.name}: 	' +
								'{point.y:.1f}
',
								footerFormat: '
',
								shared: true,
								useHTML: true
							},
							plotOptions: {
								column: {
									pointPadding: 0.2,
									borderWidth: 0
								}
							},
							series: formattedData.data,
							exporting: {
								enabled: false
							}
						};

						var chart = new Highcharts.Chart(options);
					};

					//function to create a line visualisation using data from the server
					var lineVisualisation = function (response) {
						var formattedData = formatResponseData("line", response);

						var options = {
							chart: {
								renderTo: elementId
							},
							rangeSelector: {
								selected: 1
							},

							title: {
								text: formattedData.title
							},
							series: [{
								name: formattedData.series,
								data: formattedData.data,
								tooltip: {
									valueDecimals: 2
								}
							}],
							exporting: {
								enabled: false
							}
						};

						var chart = new Highcharts.StockChart(options);
					};

					//function to create a map visualisation using data from the server
					var mapVisualisation = function (response) {
						var formattedData = formatResponseData("map", response);

						var map = L.map(elementId, {
							center: [35.52, 23.80],
							zoom: 5
						});

						L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
							maxZoom: 18,
							attribution: 'Map data © OpenStreetMap contributors',
						}).addTo(map);

						var polyline = L.polyline([]).addTo(map);
						var route = angular.copy(formattedData.route);
						for (var i=0; i<route.length; i++){
							polyline.addLatLng([parseFloat(route[i].lng),parseFloat(route[i].lat)]);
						}

						// zoom the map to the polyline
						map.fitBounds(polyline.getBounds());
					};

					//function responsible for the visualisation of a project depending on the project id and the vis_type
					var visualiseProject = function (projectId, vizType) {
						vizType = vizType.toLowerCase();

						if (vizType == "pie") {
							Data.getProjectVis(vizType, projectId, "default", "en")
							.then(function (response) {
								pieVisualisation(response);
							}, function (error) {
								console.log('error', error);
							});
						} else if (vizType == "bar") {
							Data.getProjectVis(vizType, projectId, "default", "en")
							.then(function (response) {
								barVisualisation(response);
							}, function (error) {
								console.log('error', error);
							});
						} else if (vizType == "line") {
							Data.getProjectVis(vizType, projectId, "default", "en")
							.then(function (response) {
								lineVisualisation(response);
							}, function (error) {
								console.log('error', error);
							});
						} else if (vizType == "map") {
							Data.getProjectVis(vizType, projectId, "default", "en")
							.then(function (response) {
								mapVisualisation(response);
							}, function (error) {
								console.log('error', error);
							});
						}
					};
				}
			}
		}
	}
}]);<|endoftext|>


<commit_before>/* eslint-disable no-unused-vars */
/* eslint-disable no-undef */
function doPost(e) {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheets()[0];

  sheet.appendRow(['data', e]);
  return ContentService.createTextOutput('OK');
}<commit_msg>update write rating data<commit_after>/* eslint-disable no-unused-vars */
/* eslint-disable no-undef */
function doPost(e) {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheets()[0];

  var req = JSON.parse(e.postData.contents);
  var date = new Date();

  sheet.appendRow([date.getFullYear(), date.getMonth() + 1, date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds(), req.ratings, req.session_duration, req.message]);
  return ContentService.createTextOutput('OK');
}<|endoftext|>


<commit_before>var _ = require('lodash');
var path = require('canonical-path');
var packagePath = __dirname;

module.exports = function(config) {

  require('../jsdoc')(config);
  require('../nunjucks')(config);

  config.merge('rendering.nunjucks.config.tags', {
    variableStart: '{$',
    variableEnd: '$}'
  });

  config.append('source.fileReaders', require('./file-readers/ngdoc'));

  config.append('processing.tagDefinitions', require('./tag-defs'));
  config.append('processing.inlineTagDefinitions', [
    require('./inline-tag-defs/link')
  ]);

  // Replace the default compute-path processor
  var processors = config.get('processing.processors');
  _.remove(processors, {name: 'compute-path'});
  config.append('processing.processors', [
    require('./processors/compute-path')
  ]);

  config.append('processing.processors', [
    require('./processors/partial-names'),
    require('./processors/filter-ngdocs'),
    require('./processors/compute-id'),
    require('./processors/api-docs'),
    require('./processors/component-groups-generate')
  ]);

  config.prepend('rendering.templateFolders', path.resolve(packagePath, 'templates'));

  config.prepend('rendering.templatePatterns', [
    '${ doc.template }',
    '${doc.area}/${ doc.id }.${ doc.docType }.template.html',
    '${doc.area}/${ doc.id }.template.html',
    '${doc.area}/${ doc.docType }.template.html',
    '${ doc.id }.${ doc.docType }.template.html',
    '${ doc.id }.template.html',
    '${ doc.docType }.template.html'
  ]);

  config.append('rendering.filters', [
    require('./rendering/filters/code'),
    require('./rendering/filters/link'),
    require('./rendering/filters/type-class')
  ]);

  config.append('rendering.tags', [
    require('./rendering/tags/code')
  ]);

  return config;
};
<commit_msg>refact(ngdoc package): update to no-config<commit_after>var path = require('canonical-path');
var Package = require('dgeni').Package;

module.exports = new Package('ngdoc', [require('../jsdoc'), require('../nunjucks')])

.factory(require('./file-readers/ngdoc'))
.factory(require('./inline-tag-defs/link'))
.factory(require('./services/getLinkInfo'))
.factory(require('./services/getPartialNames'))
.factory(require('./services/parseCodeName'))
.factory(require('./services/partialNameMap'))

.processor(require('./processors/apiDocs'))
.processor(require('./processors/component-groups-generate'))
.processor(require('./processors/compute-path')) // Override the current computePathProcessor with our own
.processor(require('./processors/compute-id'))
.processor(require('./processors/filter-ngdocs'))
.processor(require('./processors/collectPartialNames'))

.config(function(readFilesProcessor, ngdocFileReader) {
  readFilesProcessor.fileReaders.push(ngdocFileReader);
})

.config(function(parseTagsProcessor, getInjectables) {
  parseTagsProcessorprocessing.tagDefinitions =
      parseTagsProcessorprocessing.tagDefinitions.concat(getInjectables(require('./tag-defs')));
})

.config(function(inlineTagProcessor, linkInlineTagDef) {
  inlineTagProcessor.inlineTagDefinitions.push(linkInlineTagDef);
})

.config(function(templateEngine, getInjectables) {

  templateEngine.config.tags = {
    variableStart: '{$',
    variableEnd: '$}'
  };

  templateEngine.templateFolders.shift(path.resolve(packagePath, 'templates'));

  templateEngine.templatePatterns = [
    '${ doc.template }',
    '${doc.area}/${ doc.id }.${ doc.docType }.template.html',
    '${doc.area}/${ doc.id }.template.html',
    '${doc.area}/${ doc.docType }.template.html',
    '${ doc.id }.${ doc.docType }.template.html',
    '${ doc.id }.template.html',
    '${ doc.docType }.template.html'
  ].concat(templateEngine.templatePatterns);

  templateEngine.filters = templateEngine.filters.concat(getInjectables([
    require('./rendering/filters/code'),
    require('./rendering/filters/link'),
    require('./rendering/filters/type-class')
  ]));

  templateEngine.tags.concat(getInjectables([require('./rendering/tags/code')]));
});
<|endoftext|>


<commit_before>// -------------------------------------------------------------------------- \\
// File: Sequence.js                                                          \\
// Module: API                                                                \\
// Requires: namespace.js                                                     \\
// Author: Neil Jenkins                                                       \\
// License: © 2010-2015 FastMail Pty Ltd. MIT Licensed.                       \\
// -------------------------------------------------------------------------- \\

/*global O, JMAP */

"use strict";

( function ( JMAP ) {

var noop = function () {};

var Sequence = O.Class({

    Extends: O.Object,

    init: function () {
        this.queue = [];
        this.index = 0;
        this.length = 0;
        this.afterwards = noop;

        Sequence.parent.init.call( this );
    },

    then: function ( fn ) {
        this.queue.push( fn );
        this.increment( 'length', 1 );
        return this;
    },

    go: function go ( data ) {
        var index = this.index,
            length = this.length,
            fn = this.queue[ index ];
        if ( index < length ) {
            index += 1;
            this.set( 'index', index );
            fn( go.bind( this ), data );
            if ( index === length ) {
                this.afterwards( index, length );
            }
        }
        return this;
    },

    cancel: function () {
        var index = this.index,
            length = this.length;
        if ( index < length ) {
            this.set( 'length', 0 );
            this.afterwards( index, length );
            this.fire( 'cancel' );
        }
        return this;
    },

    progress: function () {
        var index = this.index,
            length = this.length;
        return length ? Math.round( ( index / length ) * 100 ) : 100;
    }.property( 'index', 'length' )
});

JMAP.Sequence = Sequence;

}( JMAP ) );
<commit_msg>Add Sequence#lastly method<commit_after>// -------------------------------------------------------------------------- \\
// File: Sequence.js                                                          \\
// Module: API                                                                \\
// Requires: namespace.js                                                     \\
// Author: Neil Jenkins                                                       \\
// License: © 2010-2015 FastMail Pty Ltd. MIT Licensed.                       \\
// -------------------------------------------------------------------------- \\

/*global O, JMAP */

"use strict";

( function ( JMAP ) {

var noop = function () {};

var Sequence = O.Class({

    Extends: O.Object,

    init: function () {
        this.queue = [];
        this.index = 0;
        this.length = 0;
        this.afterwards = noop;

        Sequence.parent.init.call( this );
    },

    then: function ( fn ) {
        this.queue.push( fn );
        this.increment( 'length', 1 );
        return this;
    },

    lastly: function ( fn ) {
        this.afterwards = fn;
        return this;
    },

    go: function go ( data ) {
        var index = this.index,
            length = this.length,
            fn = this.queue[ index ];
        if ( index < length ) {
            index += 1;
            this.set( 'index', index );
            fn( go.bind( this ), data );
            if ( index === length ) {
                this.afterwards( index, length );
            }
        }
        return this;
    },

    cancel: function () {
        var index = this.index,
            length = this.length;
        if ( index < length ) {
            this.set( 'length', 0 );
            this.afterwards( index, length );
            this.fire( 'cancel' );
        }
        return this;
    },

    progress: function () {
        var index = this.index,
            length = this.length;
        return length ? Math.round( ( index / length ) * 100 ) : 100;
    }.property( 'index', 'length' )
});

JMAP.Sequence = Sequence;

}( JMAP ) );
<|endoftext|>


<commit_before>/*eslint-env node */
/*
this is called node-helper as node already has an utility
it has simple helper functions

look a the end of this file to see what's available
*/
var fs = require("fs");

/*--File System---------------------------------------------------------*/
function copyFileOnce(sourceFile, destinationFile, callback){
	var success = false;
	if(isDirSync(sourceFile)) {
		if (callback) callback('copyFileOnce: ' + sourceFile + 'is a directory');
	}
	if(isDirSync(destinationFile)) {
		if (callback) callback('copyFileOnce: ' + destinationFile + ' is a Directory');
	}
	try{
	  fs.statSync(destinationFile);
			if (callback) {
				callback('copyFileOnce: ' + destinationFile + ' already exists');
			}
			return success;
	}catch (err) {
		try{
			fs.statSync(sourceFile);
			fs.writeFileSync(destinationFile, fs.readFileSync(sourceFile));
			if (callback) callback('copyFileOnce: copied ' + sourceFile + ' to ' + destinationFile);
			success = true;
		}catch (err) {
			if (callback) {
				callback('copyFileOnce: ' + sourceFile + ' does not exists');
			}
		}
	}
	return success;
}

function isDirSync(dirPath) {
  try {
    return fs.statSync(dirPath).isDirectory();
  } catch (e) {
    if (e.code === 'ENOENT') {
      return false;
    } else {
      throw e;
    }
  }
}

function loadFile(filePath){
	fs.stat(filePath, function(err) {
		if(err === null) {
			//asynch here
		} else {
			console.error(err);
			return '';
		}
	});
	var	data = loadFileSynch(filePath);
	return data;
}

function mkDirOnce (dirPath, callback) {
  try {
    fs.statSync(dirPath);
    if (callback) callback('createDirectoryOnce found ' + dirPath);
  } catch(e) {
    try {
      fs.mkdirSync(dirPath);
      if (callback) callback('createDirectoryOnce created ' + dirPath);
    }catch(error){
      if (callback) callback(error);
    }
  }
}

function saveFile(filePath, data){
	checkFile(filePath, function(){
		fs.writeFile(filePath, data,  function(err) {
		   if (err) {
			   console.error(err);
		   }
		});
	});
}
//--fs helper------------------------------------
function checkFile(filePath, callback){
	fs.stat(filePath, function(err, stat) {
		if(err === null) {
			callback();
		} else if(err.code === 'ENOENT') {
			console.log('creating file ' + filePath);
			fs.writeFile(filePath, {flag: 'wx'}, function (err, data) {
                callback();
            });
		} else {
			console.log('Some other error: ', err.code);
		}
	});
}
function loadFileSynch (filePath){
	var data = '';
	try {
		data = fs.readFileSync(filePath);
	} catch (err) {
		console.log('error: loading file', err.code);
	}
	return data;
}
/*--Other------------------------------------------------------------------*/
function getTimeStamp(){
	var today = new Date();
	var h = today.getHours();
	var m = today.getMinutes();
	var s = today.getSeconds();
	var timeStamp  = h + ":" + m + ":" + s;
	return timeStamp;
}

function getUserHome() {
  var uDir = process.env.USERPROFILE;
  if (getValidString(uDir) === '.'){
    uDir = process.env['HOME'];
  }
  uDir = getValidString(uDir);
  return uDir;
}

function getValidInteger(value) {
	if(!isNaN(value) && parseInt(Number(value)) == value && !isNaN(parseInt(value, 10))){
		return value;
	}
  return 0;
}

function getValidString(value){
	if (typeof value === 'undefined' || !value)  {
    return '.';
	}
	if(Boolean(value)){
			if(!isEmpty(value)){
				return value;
			}
	}
	return '.';
}
//--Is--
function isEmpty (str) {
    return !str || 0 === str.length;
}
function isINT (value) {
  return !isNaN(value) && parseInt(Number(value)) === value && !isNaN(parseInt(value));
}

function log(text){
	var timeStamp  = getTimeStamp();
	try {
		if(text){
			console.log('[LOG] ' + timeStamp + ' ' + text);
		}else {
			console.log('[LOG] ' + timeStamp);
		}
	} catch (error) {
		console.log('[LOG] ' + timeStamp + ' ' + 'error: ' + error);
	}
}

//--end if .is...
function showData(data, comment, delay){
	if(delay){
		sleep(delay);
	}
	try {
		if(data){
			if(!comment){
				comment = '';
			}
			console.log('data ' + comment);
			if(data !== undefined){
				console.log(data.toString());
			} else {
				console.log('undefined');
			}
		}
	} catch (error) {
		console.log("Showing data caused error: " + error);
	}
}

//--Helper
function sleep(delay, comment) {
	var sleeping = ' ...sleeping ' + delay;
	if(comment){
		console.log(comment + sleeping);
	}else {
		console.log(sleeping);
	}
  var start = new Date().getTime();
	while (new Date().getTime() < start + delay) {}
}

module.exports = {
  copyFileOnce:					copyFileOnce,
	getTimeStamp:					getTimeStamp,
  getUserHome:          getUserHome,
  getValidInteger:      getValidInteger,
  getValidString:       getValidString,
	isDirSync:						isDirSync,
  isEmpty:              isEmpty,
  isINT:                isINT,
  loadFile:             loadFile,
  log:									log,
  mkDirOnce:            mkDirOnce,
  saveFile:             saveFile,
  showData:             showData
};
<commit_msg>just made it look a bit nicer on github<commit_after>/*eslint-env node */
/*
this is called node-helper as node already has an utility
a single javascript file to make the repeating node js stuff a one liner. No outside dependencies wanted here

look a the end of this file to see what's available
*/
var fs = require("fs");

/*--File System---------------------------------------------------------*/
function copyFileOnce(sourceFile, destinationFile, callback){
	var success = false;
	if(isDirSync(sourceFile)) {
		if (callback) callback('copyFileOnce: ' + sourceFile + 'is a directory');
	}
	if(isDirSync(destinationFile)) {
		if (callback) callback('copyFileOnce: ' + destinationFile + ' is a Directory');
	}
	try{
	  fs.statSync(destinationFile);
			if (callback) {
				callback('copyFileOnce: ' + destinationFile + ' already exists');
			}
			return success;
	}catch (err) {
		try{
			fs.statSync(sourceFile);
			fs.writeFileSync(destinationFile, fs.readFileSync(sourceFile));
			if (callback) callback('copyFileOnce: copied ' + sourceFile + ' to ' + destinationFile);
			success = true;
		}catch (err) {
			if (callback) {
				callback('copyFileOnce: ' + sourceFile + ' does not exists');
			}
		}
	}
	return success;
}

function isDirSync(dirPath) {
  try {
    return fs.statSync(dirPath).isDirectory();
  } catch (e) {
    if (e.code === 'ENOENT') {
      return false;
    } else {
      throw e;
    }
  }
}

function loadFile(filePath){
	fs.stat(filePath, function(err) {
		if(err === null) {
			//asynch here
		} else {
			console.error(err);
			return '';
		}
	});
	var	data = loadFileSynch(filePath);
	return data;
}

function mkDirOnce (dirPath, callback) {
  try {
    fs.statSync(dirPath);
    if (callback) callback('createDirectoryOnce found ' + dirPath);
  } catch(e) {
    try {
      fs.mkdirSync(dirPath);
      if (callback) callback('createDirectoryOnce created ' + dirPath);
    }catch(error){
      if (callback) callback(error);
    }
  }
}

function saveFile(filePath, data){
	checkFile(filePath, function(){
		fs.writeFile(filePath, data,  function(err) {
		   if (err) {
			   console.error(err);
		   }
		});
	});
}
/*--fs helper------------------------------------------------------------------*/
function checkFile(filePath, callback){
	fs.stat(filePath, function(err, stat) {
		if(err === null) {
			callback();
		} else if(err.code === 'ENOENT') {
			console.log('creating file ' + filePath);
			fs.writeFile(filePath, {flag: 'wx'}, function (err, data) {
                callback();
            });
		} else {
			console.log('Some other error: ', err.code);
		}
	});
}
function loadFileSynch (filePath){
	var data = '';
	try {
		data = fs.readFileSync(filePath);
	} catch (err) {
		console.log('error: loading file', err.code);
	}
	return data;
}
/*--Other------------------------------------------------------------------*/
function getTimeStamp(){
	var today = new Date();
	var h = today.getHours();
	var m = today.getMinutes();
	var s = today.getSeconds();
	var timeStamp  = h + ":" + m + ":" + s;
	return timeStamp;
}

function getUserHome() {
  var uDir = process.env.USERPROFILE;
  if (getValidString(uDir) === '.'){
    uDir = process.env['HOME'];
  }
  uDir = getValidString(uDir);
  return uDir;
}

function getValidInteger(value) {
	if(!isNaN(value) && parseInt(Number(value)) == value && !isNaN(parseInt(value, 10))){
		return value;
	}
  return 0;
}

function getValidString(value){
	if (typeof value === 'undefined' || !value)  {
    return '.';
	}
	if(Boolean(value)){
			if(!isEmpty(value)){
				return value;
			}
	}
	return '.';
}

function isEmpty (str) {
    return !str || 0 === str.length;
}
function isINT (value) {
  return !isNaN(value) && parseInt(Number(value)) === value && !isNaN(parseInt(value));
}

function log(text){
	var timeStamp  = getTimeStamp();
	try {
		if(text){
			console.log('[LOG] ' + timeStamp + ' ' + text);
		}else {
			console.log('[LOG] ' + timeStamp);
		}
	} catch (error) {
		console.log('[LOG] ' + timeStamp + ' ' + 'error: ' + error);
	}
}

function showData(data, comment, delay){
	if(delay){
		sleep(delay);
	}
	try {
		if(data){
			if(!comment){
				comment = '';
			}
			console.log('data ' + comment);
			if(data !== undefined){
				console.log(data.toString());
			} else {
				console.log('undefined');
			}
		}
	} catch (error) {
		console.log("Showing data caused error: " + error);
	}
}

function sleep(delay, comment) {
	var sleeping = ' ...sleeping ' + delay;
	if(comment){
		console.log(comment + sleeping);
	}else {
		console.log(sleeping);
	}
  var start = new Date().getTime();
	while (new Date().getTime() < start + delay) {}
}

module.exports = {
  copyFileOnce:		copyFileOnce,
  getTimeStamp:		getTimeStamp,
  getUserHome:      getUserHome,
  getValidInteger:  getValidInteger,
  getValidString:   getValidString,
  isDirSync:		isDirSync,
  isEmpty:          isEmpty,
  isINT:            isINT,
  loadFile:         loadFile,
  log:	     		log,
  mkDirOnce:        mkDirOnce,
  saveFile:         saveFile,
  showData:         showData
};
<|endoftext|>


<commit_before>var fs = require('fs');
var path = require('path');
var spawn = require('child_process').spawn;
var spawnSync = require('child_process').spawnSync;
var express = require('express');
var app = express();
var server = require('http').Server(app);
var io = require('socket.io')(server);
var argv = require('minimist')(process.argv.slice(2));
var moment = require('moment');
var TsharkProbeParser = require('./src/TsharkProbeParser');
var TsharkProcessLauncher = require('./src/TsharkProcessLauncher');

var help = argv.help || argv.h;
var iface = argv.interface || argv.i;
var outputFile = argv.output || argv.o || __dirname + '/../data/probes.csv';
var csvOnly = argv['csv-only'] || argv.n;
var liveOnly = argv['live-only'] || argv.l;
var dryRun = argv['dry-run'] || argv.d;
var launchBrowser = argv['launch-browser'] || argv.b;
var dontServe = argv['dont-serve'] || argv.x;

if (!iface || help) {
	console.log('Usage: sudo node server --interface=<device> [options]');
	console.log('Options:');
	console.log('    --help, -h                        Get help. Shows this screen. ');
	console.log('    --interface=<device, -i <device>  Interface to capture probe requests with. e.g. -i wlan0');
	console.log('                                      This interface will use be set into monitor mode.');
	console.log('    --output=<file>, -o <file>        Output Probes to CSV file. Using data/probes.csv by default.');
	console.log('    --csv-only, -n                    Use input CSV only, do not use tshark to live capture probes.');
	console.log('    --live-only, -l                   Use tshark probe stream only. Do not load probes from CSV.');
	console.log('    --dry-run, -d                     Do not stream captured probe requests to output file.');
	console.log('    --launch-browser, -b              Open the server\'s url in the system\'s default browser.');
	console.log('    --dont-serve, -x                  Do not launch the server. Used for collecting probe requests only.');
	process.exit(0);
}

if (csvOnly && liveOnly) {
	console.log('Both --csv-only and --live-only flags are present. These flags are mutually exclusive. Use --help flat to print usage.');
	process.exit(0);
}

var rootCheckProc = spawnSync('id', ['-u'], { encoding: 'utf8' });
if (rootCheckProc.output[1] != '0\n') {
	console.log('This script must be run as root.');
	console.log('    sudo node server.js --interface=<device> [options]');
	process.exit(0);
}

var procLauncher = undefined;
var tsharkProcess = undefined;
var channelHopProcess = undefined;
var writeStream = undefined;

var probeParser = new TsharkProbeParser();

if (!csvOnly) {
	procLauncher = new TsharkProcessLauncher(iface, true);
	tsharkProcess = procLauncher.tsharkProcess;
	channelHopProcess = procLauncher.channelHopProcess;
}

if (!dryRun) {
	writeStream = fs.createWriteStream(outputFile, { flags: 'a', encoding: 'utf8' });
}

if (tsharkProcess) {

	tsharkProcess.stdout.on('data', function (data) {

		var lines = data.toString('utf8').split('\n');

		for (var i = 0; i < lines.length; i++) {
			// this will fire the probeParser.on('probeReceived') event
			// if the packet is parsed successfully
			probeParser.parseLine(lines[i]);
		}
	});

	tsharkProcess.stderr.on('data', function (data) {
	  	console.log('stderr: ' + data);
	});

	tsharkProcess.on('close', function (code) {
	  	console.log('tshark process exited with code ' + code);
	  	if (writeStream) {
	  		writeStream.close();
	  	}
	});
}

// register event first
probeParser.on('probeReceived', function(packet){

	if (writeStream) {
		var csvLine = packet.mac + ',' + packet.ssid + ',' + packet.timestamp + '\n'
		writeStream.write(csvLine);
	}

	console.log(moment(packet.timestamp).format('YYYY-MM-DD HH:mm:ss') + '    MAC: ' + packet.mac + '    SSID: ' + packet.ssid);
});

if (liveOnly) {
	app.get('/data/probes.csv', function(req, res){
		res.sendFile(path.resolve(__dirname + '/../data/empty.csv'));
	});
}

app.use('/data', express.static(path.resolve(__dirname + '/../data')));
app.use(express.static(path.resolve(__dirname + '/../public')));

io.on('connection', function (socket) {
    probeParser.on('probeReceived', function(probe){
    	if (!csvOnly) {
    		socket.emit('probeReceived', probe);
    	}
    });
});

if (!dontServe) {

	server.listen(3000, function () {

	  var host = 'localhost';
	  var port = server.address().port

	  console.log('[ server ] Server listening at http://%s:%s', host, port)

	  if (launchBrowser) {

			var proc = spawnSync('which', ['firefox'], { encoding: 'utf8' });
			if (proc.status == 0) {

				var url = 'http://localhost:' + port;
		  	console.log('[ server ] Launching default system browser to url: ' + url)
		  	var browserProc = spawn('firefox', ['--new-window', url]);
		  	browserProc.stderr.pipe(process.stderr);

			} else {
				console.log('[ server ] Warning: Could not launch browser window as firefox is not installed');
			}
	  }

	});
}
<commit_msg>Fix tshark stderr outputing integers at regular intervals https://github.com/brannondorsey/ProbeRequestCollectorsKit/issues/1<commit_after>var fs = require('fs');
var path = require('path');
var spawn = require('child_process').spawn;
var spawnSync = require('child_process').spawnSync;
var express = require('express');
var app = express();
var server = require('http').Server(app);
var io = require('socket.io')(server);
var argv = require('minimist')(process.argv.slice(2));
var moment = require('moment');
var TsharkProbeParser = require('./src/TsharkProbeParser');
var TsharkProcessLauncher = require('./src/TsharkProcessLauncher');

var help = argv.help || argv.h;
var iface = argv.interface || argv.i;
var outputFile = argv.output || argv.o || __dirname + '/../data/probes.csv';
var csvOnly = argv['csv-only'] || argv.n;
var liveOnly = argv['live-only'] || argv.l;
var dryRun = argv['dry-run'] || argv.d;
var launchBrowser = argv['launch-browser'] || argv.b;
var dontServe = argv['dont-serve'] || argv.x;

if (!iface || help) {
	console.log('Usage: sudo node server --interface=<device> [options]');
	console.log('Options:');
	console.log('    --help, -h                        Get help. Shows this screen. ');
	console.log('    --interface=<device, -i <device>  Interface to capture probe requests with. e.g. -i wlan0');
	console.log('                                      This interface will use be set into monitor mode.');
	console.log('    --output=<file>, -o <file>        Output Probes to CSV file. Using data/probes.csv by default.');
	console.log('    --csv-only, -n                    Use input CSV only, do not use tshark to live capture probes.');
	console.log('    --live-only, -l                   Use tshark probe stream only. Do not load probes from CSV.');
	console.log('    --dry-run, -d                     Do not stream captured probe requests to output file.');
	console.log('    --launch-browser, -b              Open the server\'s url in the system\'s default browser.');
	console.log('    --dont-serve, -x                  Do not launch the server. Used for collecting probe requests only.');
	process.exit(0);
}

if (csvOnly && liveOnly) {
	console.log('Both --csv-only and --live-only flags are present. These flags are mutually exclusive. Use --help flat to print usage.');
	process.exit(0);
}

var rootCheckProc = spawnSync('id', ['-u'], { encoding: 'utf8' });
if (rootCheckProc.output[1] != '0\n') {
	console.log('This script must be run as root.');
	console.log('    sudo node server.js --interface=<device> [options]');
	process.exit(0);
}

var procLauncher = undefined;
var tsharkProcess = undefined;
var channelHopProcess = undefined;
var writeStream = undefined;

var probeParser = new TsharkProbeParser();

if (!csvOnly) {
	procLauncher = new TsharkProcessLauncher(iface, true);
	tsharkProcess = procLauncher.tsharkProcess;
	channelHopProcess = procLauncher.channelHopProcess;
}

if (!dryRun) {
	writeStream = fs.createWriteStream(outputFile, { flags: 'a', encoding: 'utf8' });
}

if (tsharkProcess) {

	tsharkProcess.stdout.on('data', function (data) {

		var lines = data.toString('utf8').split('\n');

		for (var i = 0; i < lines.length; i++) {
			// this will fire the probeParser.on('probeReceived') event
			// if the packet is parsed successfully
			probeParser.parseLine(lines[i]);
		}
	});

	tsharkProcess.stderr.on('data', function (data) {

		var buff = data.toString('utf8');

		// tshark v1.10.6 emits stderr integers at regular intervals. Ignore them.
		if (!buff.match(/\d/)) {
			console.log('Tshark stderr: ' + buff);
		}
	});

	tsharkProcess.on('close', function (code) {
	  	console.log('tshark process exited with code ' + code);
	  	if (writeStream) {
	  		writeStream.close();
	  	}
	});
}

// register event first
probeParser.on('probeReceived', function(packet){

	if (writeStream) {
		var csvLine = packet.mac + ',' + packet.ssid + ',' + packet.timestamp + '\n'
		writeStream.write(csvLine);
	}

	console.log(moment(packet.timestamp).format('YYYY-MM-DD HH:mm:ss') + '    MAC: ' + packet.mac + '    SSID: ' + packet.ssid);
});

if (liveOnly) {
	app.get('/data/probes.csv', function(req, res){
		res.sendFile(path.resolve(__dirname + '/../data/empty.csv'));
	});
}

app.use('/data', express.static(path.resolve(__dirname + '/../data')));
app.use(express.static(path.resolve(__dirname + '/../public')));

io.on('connection', function (socket) {
    probeParser.on('probeReceived', function(probe){
    	if (!csvOnly) {
    		socket.emit('probeReceived', probe);
    	}
    });
});

if (!dontServe) {

	server.listen(3000, function () {

	  var host = 'localhost';
	  var port = server.address().port

	  console.log('[ server ] Server listening at http://%s:%s', host, port)

	  if (launchBrowser) {

			var proc = spawnSync('which', ['firefox'], { encoding: 'utf8' });
			if (proc.status == 0) {

				var url = 'http://localhost:' + port;
		  	console.log('[ server ] Launching default system browser to url: ' + url)
		  	var browserProc = spawn('firefox', ['--new-window', url]);
		  	browserProc.stderr.pipe(process.stderr);

			} else {
				console.log('[ server ] Warning: Could not launch browser window as firefox is not installed');
			}
	  }

	});
}
<|endoftext|>


<commit_before>//Dependencies
var express           = require('express'),
    app               = express(),
    _                 = require('underscore'),
    server            = require('http').createServer(app),
    io                = require('socket.io').listen(server),
    redis             = require('redis'),
    moment            = require('moment'),
    yaml              = require('js-yaml'),
    fs                = require('fs');

//Configuation
var pubsub_prefix     = 'socketio.',
    redis_conf        = yaml.safeLoad(fs.readFileSync('./redis.yml', 'utf8')),
    node_env          = process.env.NODE_ENV          || 'development',
    port              = redis_conf[node_env]['port']  || 6379,
    host              = redis_conf[node_env]['host']  || 'localhost',
    commander_redis   = redis.createClient(port, host);

var log = function(msg) {console.log('['+moment().format('h:mm:ss a')+'] '+msg);};

// Not binding the 'error' event will cause node to stop when Redis is unreachable
commander_redis.on('error',   function (err)  {log('La connection à Redis a échoué: ['+err+']');});

// ASYNC JOBS
var async             = require('async'),
    spawn             = require('child_process').spawn,
    jobs              = 1;  // typically a command line option, because it is unique
                            // to the machine
function setup_job(opts, done)
{
  log('starting '+opts.params[opts.params.length - 1]);
  var params = opts.params;
  var bin = opts.bin;
  var field = opts.bin+' '+opts.params.join(' ');
  delete opts['params'];
  delete opts['bin'];
  var R = spawn(bin, params, opts);
  R.stdout.on('data',function(buf) {});
  R.stderr.on('data',function(buf) {});
  R.on('exit',function(code)
  {
    log('got exit code: '+code)
    commander_redis.HDEL('coursestovacuum_jobs', field, function() {
      commander_redis.HLEN('coursestovacuum_jobs', function(err, len) {
        if ((len == 0) && (field != 'ruby ../getSubtitles.rb'))
          jobForCourses([{params:'../getSubtitles.rb', bin: 'ruby'}]);
      });
    });
    if(code==1)
      done();
    else
      done();
    return null;
  });
  commander_redis.HSET('coursestovacuum_jobs', field, true);
  return null;
}
var course_queue=async.queue(setup_job, jobs);

//instaciante jobs
var jobForCourses = function(cmds) {
  // baseline options for every job
  for (var i = cmds.length - 1; i >= 0; i--) {
    var opts = {  cwd: __dirname,
                  env: process.env,
                  params: cmds[i].params,
                  bin: cmds[i].bin
               };
    commander_redis.HSET('coursestovacuum_jobs', opts.bin+' '+opts.params.join(' '), false);
    log('queueing: '+opts.bin+' '+opts.params.join(' '));
    course_queue.push(opts);
  };
};

io.sockets.on('connection', function (socket) {

  socket.on('course_job', function (data)
  {
    if ('cmds' in data)
      jobForCourses(data.cmds);
  });

  socket.on('save_content', function (data)
  {
    if ('courses' in data)
    {
      log('courses to save: '+data.courses.course_name+', '+data.courses.chapter);
      if (commander_redis.connected)
      {
        commander_redis.RPUSH('france-universite-numerique-mooc', data.courses.course_name);
        commander_redis.RPUSH(data.courses.course_name, data.courses.course_name+'[_-_]'+data.courses.session);
        commander_redis.HSET(data.courses.course_name+'[_-_]'+data.courses.session, data.courses.chapter, JSON.stringify(data.courses.parts));
      }
    }
  });

});

server.listen(8811, 'localhost');
log("listenning on localhost:8811");

<commit_msg>handling errors when spanning new process<commit_after>//Dependencies
var express           = require('express'),
    app               = express(),
    _                 = require('underscore'),
    server            = require('http').createServer(app),
    io                = require('socket.io').listen(server),
    redis             = require('redis'),
    moment            = require('moment'),
    yaml              = require('js-yaml'),
    fs                = require('fs');

//Configuation
var pubsub_prefix     = 'socketio.',
    redis_conf        = yaml.safeLoad(fs.readFileSync('./redis.yml', 'utf8')),
    node_env          = process.env.NODE_ENV          || 'development',
    port              = redis_conf[node_env]['port']  || 6379,
    host              = redis_conf[node_env]['host']  || 'localhost',
    commander_redis   = redis.createClient(port, host);

var log = function(msg) {console.log('['+moment().format('h:mm:ss a')+'] '+msg);};

// Not binding the 'error' event will cause node to stop when Redis is unreachable
commander_redis.on('error',   function (err)  {log('La connection à Redis a échoué: ['+err+']');});

// ASYNC JOBS
var async             = require('async'),
    spawn             = require('child_process').spawn,
    jobs              = 1;  // typically a command line option, because it is unique
                            // to the machine
function setup_job(opts, done)
{
  log('starting '+opts.params[opts.params.length - 1]);
  var params = opts.params;
  var bin = opts.bin;
  var field = opts.bin+' '+opts.params.join(' ');
  delete opts['params'];
  delete opts['bin'];
  var R = spawn(bin, params, opts);
  R.stdout.on('data',function(buf) {});
  R.stderr.on('data',function(buf) {});
  R.on('error',function(err) {console.log(err)});
  R.on('exit' ,function(code)
  {
    log('got exit code: '+code)
    commander_redis.HDEL('coursestovacuum_jobs', field, function() {
      commander_redis.HLEN('coursestovacuum_jobs', function(err, len) {
        if ((len == 0) && (field != 'ruby ../getSubtitles.rb'))
          jobForCourses([{params:'../getSubtitles.rb', bin: 'ruby'}]);
      });
    });
    if(code==1)
      done();
    else
      done();
    return null;
  });
  commander_redis.HSET('coursestovacuum_jobs', field, true);
  return null;
}
var course_queue=async.queue(setup_job, jobs);

//instaciante jobs
var jobForCourses = function(cmds) {
  // baseline options for every job
  for (var i = cmds.length - 1; i >= 0; i--) {
    var opts = {  cwd: __dirname,
                  env: process.env,
                  params: cmds[i].params,
                  bin: cmds[i].bin
               };
    commander_redis.HSET('coursestovacuum_jobs', opts.bin+' '+opts.params.join(' '), false);
    log('queueing: '+opts.bin+' '+opts.params.join(' '));
    course_queue.push(opts);
  };
};

io.sockets.on('connection', function (socket) {

  socket.on('course_job', function (data)
  {
    if ('cmds' in data)
      jobForCourses(data.cmds);
  });

  socket.on('save_content', function (data)
  {
    if ('courses' in data)
    {
      log('courses to save: '+data.courses.course_name+', '+data.courses.chapter);
      if (commander_redis.connected)
      {
        commander_redis.RPUSH('france-universite-numerique-mooc', data.courses.course_name);
        commander_redis.RPUSH(data.courses.course_name, data.courses.course_name+'[_-_]'+data.courses.session);
        commander_redis.HSET(data.courses.course_name+'[_-_]'+data.courses.session, data.courses.chapter, JSON.stringify(data.courses.parts));
      }
    }
  });

});

server.listen(8811, 'localhost');
log("listenning on localhost:8811");

<|endoftext|>


<commit_before>var nodecr = require('nodecr');
var http = require("http");
var url = require('url');
var fs = require('fs');

function start() {
	function onRequest(request, response) {
		var body = "";
		request.on("data", function (chunk) {
			body += chunk;
		});
		request.on("end", function() {
			console.log("\n" + (new Date()) + ": Request received.");
			if (body != "") {
				body = body.replace(/^data:image\/jpeg;base64,/,"");
				fs.writeFile("temp/temp.jpg", body, 'base64', function(err) {
					if (err) {
						console.log((new Date()) + ": " + err);
					}
				});
			}
			nodecr.process("temp/temp.jpg", function(err, text) {
				if (err) {
					console.log("Tesseract error!");
					response.writeHead(500, {"Content-Type": "text/plain", "Access-Control-Allow-Origin": "*"});
					response.write("Tesseract error");
					response.end();
					fs.unlink("temp/temp.jpg", function(err) {
						if (err) {
							console.log((new Date()) + ": Couldn't delete temp.jpg!");
						} else {
							console.log((new Date()) + ": temp.jpg deleted");
						}
					});
				} else {
					console.log("Success: %s", text);
					response.writeHead(200, {"Content-Type": "text/plain", "Access-Control-Allow-Origin": "*"});
					response.write(text.substring(0, 5));
					response.end();
					fs.unlink("temp/temp.jpg", function(err) {
						if (err) {
							console.log((new Date()) + ": Couldn't delete temp.jpg!");
						} else {
							console.log((new Date()) + ": temp.jpg deleted");
						}
					});
				}
			});
		});
	}
	http.createServer(onRequest).listen(8888);
	console.log((new Date()) + ": Server has started.");
}

exports.start = start;<commit_msg>fix a small bug<commit_after>var nodecr = require('nodecr');
var http = require("http");
var url = require('url');
var fs = require('fs');

function start() {
	function onRequest(request, response) {
		var body = "";
		request.on("data", function (chunk) {
			body += chunk;
		});
		request.on("end", function() {
			console.log("\n" + (new Date()) + ": Request received.");
			if (body != "") {
				body = body.replace(/^data:image\/jpeg;base64,/,"");
				fs.writeFile("temp/temp.jpg", body, 'base64', function(err) {
					if (err) {
						console.log((new Date()) + ": " + err);
					}
				});
			}
			nodecr.process("temp/temp.jpg", function(err, text) {
				if (err) {
					console.log("Tesseract error!");
					response.writeHead(500, {"Content-Type": "text/plain", "Access-Control-Allow-Origin": "*"});
					response.write("Tesseract error");
					response.end();
					fs.unlink("temp/temp.jpg", function(err) {
						if (err) {
							console.log((new Date()) + ": Couldn't delete temp.jpg!");
						} else {
							console.log((new Date()) + ": temp.jpg deleted");
						}
					});
				} else {
					console.log("Success: %s", text);
					response.writeHead(200, {"Content-Type": "text/plain", "Access-Control-Allow-Origin": "*"});
					response.write(text.substring(0, text.length - 2));
					response.end();
					fs.unlink("temp/temp.jpg", function(err) {
						if (err) {
							console.log((new Date()) + ": Couldn't delete temp.jpg!");
						} else {
							console.log((new Date()) + ": temp.jpg deleted");
						}
					});
				}
			});
		});
	}
	http.createServer(onRequest).listen(8888);
	console.log((new Date()) + ": Server has started.");
}

exports.start = start;<|endoftext|>


<commit_before>/* global require, module */
/* Magic Mirror
 * Node Helper: MMM-NetworkScanner
 *
 * By Ian Perrin http://ianperrin.com
 * MIT Licensed.
 */

const NodeHelper = require("node_helper");
const ping = require('ping')
const sudo = require("sudo");

module.exports = NodeHelper.create({
    start: function function_name () {
        console.log("Starting module: " + this.name);
    },

    // Override socketNotificationReceived method.
    socketNotificationReceived: function(notification, payload) {
        console.log(this.name + ' received ' + notification);

        if (notification === "SCAN_NETWORK") {
            this.devices = payload;
            this.scanNetworkMAC();
            this.scanNetworkIP(payload);
            return true;
        }

//        if (notification === "TEST") {
//         console.log("Recived a test notification with the following payload:");
//         console.log(payload);
//        }
    },

    scanNetworkMAC: function() {
        console.log(this.name + " is scanning for mac addresses");

        var self = this;
        var arp = sudo(['arp-scan', '-l', '-q']);
        var buffer = '';
        var errstream = '';

        arp.stdout.on('data', function (data) {
            buffer += data;
        });

        arp.stderr.on('data', function (data) {
            errstream += data;
        });

        arp.on('error', function (err) {
            errstream += err;
        });

        arp.on('close', function (code) {
            if (code !== 0) {
                console.log(self.name + " received an error running arp-scan: " + code + " - " + errstream);
                return;
            }
            //Parse the response
            var rows = buffer.split('\n');
            var macAddresses = [];

            // ARP-SCAN table
            for (var i = 2; i < rows.length; i++) {
                var cells = rows[i].split('\t').filter(String);
                if (cells[1] && macAddresses.indexOf(cells[1].toUpperCase()) === -1) {
                    macAddresses.push(cells[1].toUpperCase());
                }
            }

//            console.log("MAC_ADDRESSES", macAddresses);

            self.sendSocketNotification('MAC_ADDRESSES', macAddresses);
        });

    },

   scanNetworkIP: function(payload) {
      var self = this;
      console.log(this.name + " is scanning for ip addresses");

      console.log("Recived payload: ",payload);

      var devices = payload;
      var deviceList = [];

      function updateIPAddresses(devices) {
         devices.forEach( function(device) {
            if ("ipAddress" in device) {
               ping.sys.probe(device.ipAddress, function(isAlive) {
                  var deviceStatus = {name: device.name, online:isAlive};
//                  console.log(deviceStatus);
                  deviceList.push(deviceStatus);
                  self.sendSocketNotification("IP_ADDRESS", deviceStatus);
               });
            };
         });
      }

//      function printDevices(deviceList) {
//         console.log("deviceList: ",deviceList);
//      };

      updateIPAddresses(devices);

//         callback(deviceList);

   },
});
<commit_msg>minor refactor<commit_after>/* global require, module */
/* Magic Mirror
 * Node Helper: MMM-NetworkScanner
 *
 * By Ian Perrin http://ianperrin.com
 * MIT Licensed.
 */

const NodeHelper = require("node_helper");
const ping = require("ping");
const sudo = require("sudo");

module.exports = NodeHelper.create({
    start: function function_name () {
        console.log("Starting module: " + this.name);
    },

    // Override socketNotificationReceived method.
    socketNotificationReceived: function(notification, payload) {
        console.log(this.name + " received " + notification);

        if (notification === "SCAN_NETWORK") {
            this.devices = payload;
            this.scanNetworkMAC();
            this.scanNetworkIP(payload);
            return true;
        }

    },

    scanNetworkMAC: function() {
        console.log(this.name + " is scanning for mac addresses");

        var self = this;
        var arp = sudo(['arp-scan', '-l', '-q']);
        var buffer = '';
        var errstream = '';

        arp.stdout.on('data', function (data) {
            buffer += data;
        });

        arp.stderr.on('data', function (data) {
            errstream += data;
        });

        arp.on('error', function (err) {
            errstream += err;
        });

        arp.on('close', function (code) {
            if (code !== 0) {
                console.log(self.name + " received an error running arp-scan: " + code + " - " + errstream);
                return;
            }
            //Parse the response
            var rows = buffer.split('\n');
            var macAddresses = [];

            // ARP-SCAN table
            for (var i = 2; i < rows.length; i++) {
                var cells = rows[i].split('\t').filter(String);
                if (cells[1] && macAddresses.indexOf(cells[1].toUpperCase()) === -1) {
                    macAddresses.push(cells[1].toUpperCase());
                }
            }

            self.sendSocketNotification("MAC_ADDRESSES", macAddresses);
        });

    },

   scanNetworkIP: function(payload) {
      var self = this;
      console.log(this.name + " is scanning for ip addresses", payload);

      var devices = payload;
      var deviceList = [];

      function updateIPAddresses(devices) {
         devices.forEach( function(device) {
            if ("ipAddress" in device) {
               ping.sys.probe(device.ipAddress, function(isAlive) {
                  var deviceStatus = {name: device.name, online:isAlive};
                  deviceList.push(deviceStatus);
                  self.sendSocketNotification("IP_ADDRESS", deviceStatus);
               });
            }
         });
      }

      updateIPAddresses(devices);

   },
});
<|endoftext|>


<commit_before>/* global module, require */
/* Magic Mirror
 * Node Helper: MMM-ModuleScheduler
 *
 * By Ian Perrin http://ianperrin.com
 * MIT Licensed.
 */

var NodeHelper = require("node_helper");
var CronJob = require("cron").CronJob;

module.exports = NodeHelper.create({
    cronJobs: [],

    // Override start method.
    start: function() {
        console.log("Starting node helper for: " + this.name);
    },

    // Override socketNotificationReceived method.
    socketNotificationReceived: function(notification, payload) {
        console.log(this.name + ' received ' + notification);

        if (notification === "SET_CONFIG") {
            console.log(this.name + ' is setting the config');
            this.config = payload;
            return true;
        }

        if (notification === "REMOVE_ALL_SCHEDULES") {
            this.stopAllCronJobs();
            return true;
        }

        if (notification === "CREATE_MODULE_SCHEDULE") {
            this.createScheduleForModule(payload);
            return true;

        }
    },

    stopAllCronJobs: function() {
        console.log(this.name + ' is removing all schedules');
        for (var i = 0; i < this.cronJobs.length; i++) {
            var cronJob = this.cronJobs[i];
            if( typeof cronJob.showJob === 'object') {
                this.stopCronJob(cronJob.showJob);
            }
            if( typeof cronJob.hideJob === 'object') {
                this.stopCronJob(cronJob.hideJob);
            }
        }
        this.cronJobs.length = 0;
    },

    stopCronJob: function(cronJob){
        try {
            cronJob.stop();
        } catch(ex) {
            console.log(this.name + ' could not stop cronJob');
        }
    },

    createScheduleForModule: function(module){
        var moduleSchedules = [];
        var nextShowDate, nextHideDate, nextDimLevel;

        if (Array.isArray(module.schedule)) {
            moduleSchedules = module.schedule;
        } else {
            moduleSchedules.push(module.schedule);
        }

        for (var i = 0; i < moduleSchedules.length; i++) {
            var moduleSchedule = moduleSchedules[i];
	          nextDimLevel = 0;
            if (!moduleSchedule.hasOwnProperty('from') || !moduleSchedule.hasOwnProperty('to')) {
                console.log(this.name + ' cannot schedule' + module.name + ' - check module_schedule');
                break;
            }

            // Create cronnJobs
            console.log(this.name + ' is scheduling ' + module.name + ' using \'' + moduleSchedule.from + '\' and \'' + moduleSchedule.to + '\'');
            var showJob = this.createCronJobForModule(module, moduleSchedule.from, 'show');
            if (!showJob) {
                break;
            }
            var hideJob = this.createCronJobForModule(module, moduleSchedule.to, (moduleSchedule.dimLevel ? 'dim' : 'hide'), moduleSchedule.dimLevel);
            if (!hideJob) {
                showJob.stop();
                break;
            }

            // Store cronJobs
            this.cronJobs.push({module: module, schedule: moduleSchedule, showJob: showJob, hideJob: hideJob});

            // Store next dates
            if (i === 0 || showJob.nextDate().toDate() < nextShowDate ) {
                nextShowDate = showJob.nextDate().toDate();
            }
            if (i === 0 || hideJob.nextDate().toDate() < nextShowDate ) {
                nextHideDate = hideJob.nextDate().toDate();
	              nextDimLevel = moduleSchedule.dimLevel;
            }
        }

        if (nextHideDate && nextShowDate)
        {
            var now = new Date();
            if (nextShowDate > now && nextHideDate > nextShowDate) {
                if (nextDimLevel > 0) {
                    console.log(this.name + ' is dimming ' + module.name);
                    this.sendSocketNotification('DIM_MODULE', {identifier: module.id, dimLevel: nextDimLevel});
                } else {
                    console.log(this.name + ' is hiding ' + module.name);
                    this.sendSocketNotification('HIDE_MODULE', {identifier: module.id});
                }
            }
            console.log(this.name + ' has scheduled ' + module.name);
            console.log(this.name + ' will next show ' + module.name + ' at ' + nextShowDate);
            console.log(this.name + ' will next ' + (nextDimLevel ? 'dim' : 'hide') + ' ' + module.name + ' at ' + nextHideDate);
        }
    },

    createCronJobForModule: function(module, moduleCronTime, action, level) {
        var self = this;

        if(action !== 'show' && action !== 'hide' && action !== 'dim') {
            console.log(self.name + ' requires show/hide/dim for type, not ' + action);
            return false;
        }

        try {
            var job = new CronJob({
                cronTime: moduleCronTime,
                onTick: function() {
                    console.log(self.name + ' is sending notification to ' + action + ' ' + module.name);
                    self.sendSocketNotification(action.toUpperCase() + '_MODULE', {identifier: module.id, dimLevel: level});
                    console.log(self.name + ' will next ' + action + ' ' + module.name + ' at ' + this.nextDate().toDate() + ' using \'' + moduleCronTime + '\'');
                },
                onComplete: function() {
                    console.log(self.name + ' has completed the ' + action + ' job for ' + module.id + ' using \'' + moduleCronTime + '\'');
                },
                start: true
            });
            return job;
        } catch(ex) {
            console.log(this.name + ' could not schedule ' + module.name + ' - check ' + action + ' expression: \'' + moduleCronTime + '\'');
        }
    }
});

<commit_msg>Fix dimLevel with some combination of schedule arrays<commit_after>/* global module, require */
/* Magic Mirror
 * Node Helper: MMM-ModuleScheduler
 *
 * By Ian Perrin http://ianperrin.com
 * MIT Licensed.
 */

var NodeHelper = require("node_helper");
var CronJob = require("cron").CronJob;

module.exports = NodeHelper.create({
    cronJobs: [],

    // Override start method.
    start: function() {
        console.log("Starting node helper for: " + this.name);
    },

    // Override socketNotificationReceived method.
    socketNotificationReceived: function(notification, payload) {
        console.log(this.name + ' received ' + notification);

        if (notification === "SET_CONFIG") {
            console.log(this.name + ' is setting the config');
            this.config = payload;
            return true;
        }

        if (notification === "REMOVE_ALL_SCHEDULES") {
            this.stopAllCronJobs();
            return true;
        }

        if (notification === "CREATE_MODULE_SCHEDULE") {
            this.createScheduleForModule(payload);
            return true;

        }
    },

    stopAllCronJobs: function() {
        console.log(this.name + ' is removing all schedules');
        for (var i = 0; i < this.cronJobs.length; i++) {
            var cronJob = this.cronJobs[i];
            if( typeof cronJob.showJob === 'object') {
                this.stopCronJob(cronJob.showJob);
            }
            if( typeof cronJob.hideJob === 'object') {
                this.stopCronJob(cronJob.hideJob);
            }
        }
        this.cronJobs.length = 0;
    },

    stopCronJob: function(cronJob){
        try {
            cronJob.stop();
        } catch(ex) {
            console.log(this.name + ' could not stop cronJob');
        }
    },

    createScheduleForModule: function(module){
        var moduleSchedules = [];
        var nextShowDate, nextHideDate, nextDimLevel;

        if (Array.isArray(module.schedule)) {
            moduleSchedules = module.schedule;
        } else {
            moduleSchedules.push(module.schedule);
        }

        for (var i = 0; i < moduleSchedules.length; i++) {
            console.log(module.id + ' schedule ' + i);
            var moduleSchedule = moduleSchedules[i];

            if (!moduleSchedule.hasOwnProperty('from') || !moduleSchedule.hasOwnProperty('to')) {
                console.log(this.name + ' cannot schedule' + module.name + ' - check module_schedule');
                break;
            }

            // Create cronnJobs
            console.log(this.name + ' is scheduling ' + module.name + ' using \'' + moduleSchedule.from + '\' and \'' + moduleSchedule.to + '\' with dim level ' + moduleSchedule.dimLevel);
            var showJob = this.createCronJobForModule(module, moduleSchedule.from, 'show');
            if (!showJob) {
                break;
            }
            var hideJob = this.createCronJobForModule(module, moduleSchedule.to, (moduleSchedule.dimLevel ? 'dim' : 'hide'), moduleSchedule.dimLevel);
            if (!hideJob) {
                showJob.stop();
                break;
            }

            // Store cronJobs
            this.cronJobs.push({module: module, schedule: moduleSchedule, showJob: showJob, hideJob: hideJob});

            // Store next dates
            if (i === 0 || showJob.nextDate().toDate() < nextShowDate ) {
                nextShowDate = showJob.nextDate().toDate();
            }
            if (i === 0 || hideJob.nextDate().toDate() < nextShowDate ) {
                nextHideDate = hideJob.nextDate().toDate();
                nextDimLevel = moduleSchedule.dimLevel;
            }
        }

        if (nextHideDate && nextShowDate)
        {
            var now = new Date();
            if (nextShowDate > now && nextHideDate > nextShowDate) {
                if (nextDimLevel > 0) {
                    console.log(this.name + ' is dimming ' + module.name);
                    this.sendSocketNotification('DIM_MODULE', {identifier: module.id, dimLevel: nextDimLevel});
                } else {
                    console.log(this.name + ' is hiding ' + module.name);
                    this.sendSocketNotification('HIDE_MODULE', {identifier: module.id});
                }
            }
            console.log(this.name + ' has scheduled ' + module.name);
            console.log(this.name + ' will next show ' + module.name + ' at ' + nextShowDate);
            console.log(this.name + ' will next ' + (nextDimLevel ? 'dim' : 'hide') + ' ' + module.name + ' at ' + nextHideDate);
        }
    },

    createCronJobForModule: function(module, moduleCronTime, action, level) {
        var self = this;

        if(action !== 'show' && action !== 'hide' && action !== 'dim') {
            console.log(self.name + ' requires show/hide/dim for type, not ' + action);
            return false;
        }

        try {
            var job = new CronJob({
                cronTime: moduleCronTime,
                onTick: function() {
                    console.log(self.name + ' is sending notification to ' + action + ' ' + module.name);
                    self.sendSocketNotification(action.toUpperCase() + '_MODULE', {identifier: module.id, dimLevel: level});
                    console.log(self.name + ' will next ' + action + ' ' + module.name + ' at ' + this.nextDate().toDate() + ' using \'' + moduleCronTime + '\'');
                },
                onComplete: function() {
                    console.log(self.name + ' has completed the ' + action + ' job for ' + module.id + ' using \'' + moduleCronTime + '\'');
                },
                start: true
            });
            return job;
        } catch(ex) {
            console.log(this.name + ' could not schedule ' + module.name + ' - check ' + action + ' expression: \'' + moduleCronTime + '\'');
        }
    }
});

<|endoftext|>