<commit_before>var Comb = require('csscomb-core');
var gonzales = require('gonzales-pe');
var fs = require('fs');
var path = require('path');

/**
 * Converts CSS string to AST.
 *
 * @param {String} text CSS string
 * @param {String} [syntax] Syntax name (e.g., `scss`)
 * @param {String} [filename]
 * @returns {Array} AST
 */
function cssToAST(text, syntax, filename) {
    var string = JSON.stringify;
    var fileInfo = filename ? ' at ' + filename : '';
    var tree;

    try {
        tree = gonzales.parse(text, { syntax: syntax });
    } catch (e) {
        throw new Error('Parsing error' + fileInfo + ': ' + e.message);
    }

    // TODO: When can tree be undefined? <tg>
    if (typeof tree === 'undefined') {
        throw new Error('Undefined tree' + fileInfo + ': ' + string(text) + ' => ' + string(tree));
    }

    return tree;
}

/**
 * Gets option's data needed for detection
 *
 * @param {String} optionName
 * @returns {Object} Object with option's name, link to `detect()` method
 * and default value for the case when nothing can be detected
 */
function getHandler(optionName) {
    var option = require('./options/' + optionName);
    if (!option.detect) throw new Error('Option does not have `detect()` method.');
    return {
        name: option.name,
        detect: option.detect,
        detectDefault: option.detectDefault
    };
}

/**
 * Processes tree node and detects options.
 *
 * @param {Array} node Tree node
 * @param {Number} level Indent level
 * @param {Object} handler Object with option's data
 * @param {Object} detectedOptions
 */
function detectInNode(node, level, handler, detectedOptions) {
    node.map(function(tree) {
        var detected = handler.detect(tree);
        var variants = detectedOptions[handler.name];
        if (typeof detected === 'object') {
            variants.push.apply(variants, detected);
        } else if (typeof detected !== 'undefined') {
            variants.push(detected);
        }

        //if (nodeType === 'atrulers' || nodeType === 'block') level++;
    });
}

/**
 * Processes tree and detects options.
 *
 * @param {Array} tree
 * @param {Array} handlers List of options that we should look for
 * @returns {Object} Map with detected options and all variants of possible
 * values
 */
function detectInTree(tree, handlers) {
    var detectedOptions = {};
    // We walk across complete tree for each handler,
    // because we need strictly maintain order in which handlers work,
    // despite fact that handlers work on different level of the tree.
    handlers.forEach(function(handler) {
        detectedOptions[handler.name] = [];
        // TODO: Pass all parameters as one object? <tg>
        detectInNode(tree, 0, handler, detectedOptions);
    });
    return detectedOptions;
}

/**
 * Gets the detected options.
 *
 * @param {Object} detected
 * @param {Array} handlers
 * @returns {Object}
 */
function getDetectedOptions(detected, handlers) {
    var options = {};
    Object.keys(detected).forEach(function(option) {
        // List of all the detected variants from the stylesheet for the given option:
        var values = detected[option];
        var i;
        if (!values.length) {
            // If there are no values for the option, check if there is a default one:
            for (i = handlers.length; i--;) {
                if (handlers[i].name === option &&
                    handlers[i].detectDefault !== undefined) {
                    options[option] = handlers[i].detectDefault;
                    break;
                }
            }
        } else if (values.length === 1) {
            options[option] = values[0];
        } else {
            // If there are more than one value for the option, find the most popular one;
            // `variants` would be populated with the popularity for different values.
            var variants = {};
            var bestGuess = null;
            var maximum = 0;
            for (i = values.length; i--;) {
                var currentValue = values[i];
                // Count the current value:
                if (variants[currentValue]) {
                    variants[currentValue]++;
                } else {
                    variants[currentValue] = 1;
                }
                // If the current variant is the most popular one, treat
                // it as the best guess:
                if (variants[currentValue] >= maximum) {
                    maximum = variants[currentValue];
                    bestGuess = currentValue;
                }
            }
            if (bestGuess !== null) {
                options[option] = bestGuess;
            }
        }
    });

    return options;
}

/**
 * Starts Code Style processing process.
 *
 * @param {String|Object} config
 * @constructor
 * @name CSScomb
 */
var CSScomb = function(config) {
    var options = fs.readdirSync(__dirname + '/options').map(function(option) {
        return require('./options/' + option);
    });

    var comb = new Comb(options, 'css', 'less', 'scss', 'sass');

    // If config was passed, configure:
    if (typeof config === 'string') {
        config = CSScomb.getConfig(config);
    }
    if (typeof config === 'object') {
        comb.configure(config);
    }

    return comb;
};

/**
 * STATIC METHODS
 * Methods that can be called without creating an instance:
 *   - getConfig;
 *   - getCustomConfig;
 *   - getCustomConfigPath;
 *   - detectInFile;
 *   - detectInString.
 * For example: `CSScomb.getConfig('zen')`
 */

/**
 * Gets one of configuration files from configs' directory.
 *
 * @param {String} name Config's name, e.g. 'yandex'
 * @returns {Object} Configuration object
 */
CSScomb.getConfig = function getConfig(name) {
    var DEFAULT_CONFIG_NAME = 'csscomb';
    name = name || DEFAULT_CONFIG_NAME;

    if (typeof name !== 'string') {
        throw new Error('Config name must be a string.');
    }

    var CONFIG_DIR_PATH = '../config';
    var availableConfigsNames = fs.readdirSync(__dirname + '/' + CONFIG_DIR_PATH)
        .map(function(configFileName) {
            return configFileName.split('.')[0];  // strip file extension(s)
        });

    if (availableConfigsNames.indexOf(name) < 0) {
        var configsNamesAsString = availableConfigsNames
            .map(function(configName) {
                return '\'' + configName + '\'';
            })
            .join(', ');
        throw new Error('"' + name + '" is not a valid config name. Try one of ' +
            'the following: ' + configsNamesAsString + '.');
    }

    return require(CONFIG_DIR_PATH + '/' + name + '.json');
};

/**
 * Gets configuration from provided config path or looks for it in common
 * places.
 *
 * @param {String} [configPath]
 * @returns {Object|null}
 */
CSScomb.getCustomConfig = function getCustomConfig(configPath) {
    var config;
    configPath = configPath || CSScomb.getCustomConfigPath();

    try {
        config = require(configPath);
    } catch (e) {
        config = null;
    }

    return config;
};

/**
 * Looks for a config file: recursively from current (process) directory
 * up to $HOME dir
 * If no custom config file is found, return `null`.
 *
 * @param {String} [configPath]
 * @returns {String | null}
 */
CSScomb.getCustomConfigPath = function getCustomConfigPath(configPath) {
    var HOME = process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE;

    configPath = configPath || path.join(process.cwd(), '.csscomb.json');

    // If we've finally found a config, return its path:
    if (fs.existsSync(configPath)) return fs.realpathSync(configPath);

    // If we are in HOME dir already and yet no config file, return a default
    // one from our package.
    // If project is located not under HOME, compare to root instead.
    // Since there appears to be no good way to get root path in
    // Windows, assume that if current dir has no parent dir, we're in
    // root.
    var dirname = path.dirname(configPath);
    var parentDirname = path.dirname(dirname);
    if (dirname === HOME || dirname === parentDirname) return null;

    // If there is no config in this directory, go one level up and look for
    // a config there:
    configPath = path.join(parentDirname, '.csscomb.json');
    return CSScomb.getCustomConfigPath(configPath);
};

/**
 * Detects the options in the given file
 *
 * @param {String} path Path to the stylesheet
 * @param {Array} options List of options to detect
 * @returns {Object} Detected options
 */
CSScomb.detectInFile = function detectInFile(path, options) {
    var stylesheet = fs.readFileSync(path, 'utf8');
    return CSScomb.detectInString(stylesheet, options);
};

/**
 * Detects the options in the given string
 *
 * @param {String} text Stylesheet
 * @param {Array} options List of options to detect
 * @returns {Object} Detected options
 */
CSScomb.detectInString = function detectInString(text, options) {
    var result;
    var handlers = [];

    if (!text) return text;

    var optionNames = fs.readdirSync(__dirname + '/options');
    optionNames.forEach(function(option) {
        option = option.slice(0, -3);
        if (options && options.indexOf(option) < 0) return;
        try {
            handlers.push(getHandler(option));
        } catch (e) {
            console.warn('\nFailed to load "%s" option:\n%s', option, e.message);
        }
    });

    var tree = cssToAST(text);
    var detectedOptions = detectInTree(tree, handlers);
    result = getDetectedOptions(detectedOptions, handlers);

    // Handle conflicting options with spaces around braces:
    var blockIndent = result['block-indent'];
    var spaceAfterOpeningBrace = result['space-after-opening-brace'];

    if (typeof blockIndent === 'string' &&
        spaceAfterOpeningBrace &&
        spaceAfterOpeningBrace.indexOf('\n') > -1) {
        result['space-after-opening-brace'] = '\n';
    }

    return result;
};

module.exports = CSScomb;
<commit_msg>Use readFileSync and JSON parse to read config<commit_after>var Comb = require('csscomb-core');
var gonzales = require('gonzales-pe');
var fs = require('fs');
var path = require('path');

/**
 * Converts CSS string to AST.
 *
 * @param {String} text CSS string
 * @param {String} [syntax] Syntax name (e.g., `scss`)
 * @param {String} [filename]
 * @returns {Array} AST
 */
function cssToAST(text, syntax, filename) {
    var string = JSON.stringify;
    var fileInfo = filename ? ' at ' + filename : '';
    var tree;

    try {
        tree = gonzales.parse(text, { syntax: syntax });
    } catch (e) {
        throw new Error('Parsing error' + fileInfo + ': ' + e.message);
    }

    // TODO: When can tree be undefined? <tg>
    if (typeof tree === 'undefined') {
        throw new Error('Undefined tree' + fileInfo + ': ' + string(text) + ' => ' + string(tree));
    }

    return tree;
}

/**
 * Gets option's data needed for detection
 *
 * @param {String} optionName
 * @returns {Object} Object with option's name, link to `detect()` method
 * and default value for the case when nothing can be detected
 */
function getHandler(optionName) {
    var option = require('./options/' + optionName);
    if (!option.detect) throw new Error('Option does not have `detect()` method.');
    return {
        name: option.name,
        detect: option.detect,
        detectDefault: option.detectDefault
    };
}

/**
 * Processes tree node and detects options.
 *
 * @param {Array} node Tree node
 * @param {Number} level Indent level
 * @param {Object} handler Object with option's data
 * @param {Object} detectedOptions
 */
function detectInNode(node, level, handler, detectedOptions) {
    node.map(function(tree) {
        var detected = handler.detect(tree);
        var variants = detectedOptions[handler.name];
        if (typeof detected === 'object') {
            variants.push.apply(variants, detected);
        } else if (typeof detected !== 'undefined') {
            variants.push(detected);
        }

        //if (nodeType === 'atrulers' || nodeType === 'block') level++;
    });
}

/**
 * Processes tree and detects options.
 *
 * @param {Array} tree
 * @param {Array} handlers List of options that we should look for
 * @returns {Object} Map with detected options and all variants of possible
 * values
 */
function detectInTree(tree, handlers) {
    var detectedOptions = {};
    // We walk across complete tree for each handler,
    // because we need strictly maintain order in which handlers work,
    // despite fact that handlers work on different level of the tree.
    handlers.forEach(function(handler) {
        detectedOptions[handler.name] = [];
        // TODO: Pass all parameters as one object? <tg>
        detectInNode(tree, 0, handler, detectedOptions);
    });
    return detectedOptions;
}

/**
 * Gets the detected options.
 *
 * @param {Object} detected
 * @param {Array} handlers
 * @returns {Object}
 */
function getDetectedOptions(detected, handlers) {
    var options = {};
    Object.keys(detected).forEach(function(option) {
        // List of all the detected variants from the stylesheet for the given option:
        var values = detected[option];
        var i;
        if (!values.length) {
            // If there are no values for the option, check if there is a default one:
            for (i = handlers.length; i--;) {
                if (handlers[i].name === option &&
                    handlers[i].detectDefault !== undefined) {
                    options[option] = handlers[i].detectDefault;
                    break;
                }
            }
        } else if (values.length === 1) {
            options[option] = values[0];
        } else {
            // If there are more than one value for the option, find the most popular one;
            // `variants` would be populated with the popularity for different values.
            var variants = {};
            var bestGuess = null;
            var maximum = 0;
            for (i = values.length; i--;) {
                var currentValue = values[i];
                // Count the current value:
                if (variants[currentValue]) {
                    variants[currentValue]++;
                } else {
                    variants[currentValue] = 1;
                }
                // If the current variant is the most popular one, treat
                // it as the best guess:
                if (variants[currentValue] >= maximum) {
                    maximum = variants[currentValue];
                    bestGuess = currentValue;
                }
            }
            if (bestGuess !== null) {
                options[option] = bestGuess;
            }
        }
    });

    return options;
}

/**
 * Starts Code Style processing process.
 *
 * @param {String|Object} config
 * @constructor
 * @name CSScomb
 */
var CSScomb = function(config) {
    var options = fs.readdirSync(__dirname + '/options').map(function(option) {
        return require('./options/' + option);
    });

    var comb = new Comb(options, 'css', 'less', 'scss', 'sass');

    // If config was passed, configure:
    if (typeof config === 'string') {
        config = CSScomb.getConfig(config);
    }
    if (typeof config === 'object') {
        comb.configure(config);
    }

    return comb;
};

/**
 * STATIC METHODS
 * Methods that can be called without creating an instance:
 *   - getConfig;
 *   - getCustomConfig;
 *   - getCustomConfigPath;
 *   - detectInFile;
 *   - detectInString.
 * For example: `CSScomb.getConfig('zen')`
 */

/**
 * Gets one of configuration files from configs' directory.
 *
 * @param {String} name Config's name, e.g. 'yandex'
 * @returns {Object} Configuration object
 */
CSScomb.getConfig = function getConfig(name) {
    var DEFAULT_CONFIG_NAME = 'csscomb';
    name = name || DEFAULT_CONFIG_NAME;

    if (typeof name !== 'string') {
        throw new Error('Config name must be a string.');
    }

    var CONFIG_DIR_PATH = '../config';
    var availableConfigsNames = fs.readdirSync(__dirname + '/' + CONFIG_DIR_PATH)
        .map(function(configFileName) {
            return configFileName.split('.')[0];  // strip file extension(s)
        });

    if (availableConfigsNames.indexOf(name) < 0) {
        var configsNamesAsString = availableConfigsNames
            .map(function(configName) {
                return '\'' + configName + '\'';
            })
            .join(', ');
        throw new Error('"' + name + '" is not a valid config name. Try one of ' +
            'the following: ' + configsNamesAsString + '.');
    }

    return require(CONFIG_DIR_PATH + '/' + name + '.json');
};

/**
 * Gets configuration from provided config path or looks for it in common
 * places.
 *
 * @param {String} [configPath]
 * @returns {Object|null}
 */
CSScomb.getCustomConfig = function getCustomConfig(configPath) {
    var config;
    configPath = configPath || CSScomb.getCustomConfigPath();

    try {
        config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
    } catch (e) {
        config = null;
    }

    return config;
};

/**
 * Looks for a config file: recursively from current (process) directory
 * up to $HOME dir
 * If no custom config file is found, return `null`.
 *
 * @param {String} [configPath]
 * @returns {String | null}
 */
CSScomb.getCustomConfigPath = function getCustomConfigPath(configPath) {
    var HOME = process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE;

    configPath = configPath || path.join(process.cwd(), '.csscomb.json');

    // If we've finally found a config, return its path:
    if (fs.existsSync(configPath)) return fs.realpathSync(configPath);

    // If we are in HOME dir already and yet no config file, return a default
    // one from our package.
    // If project is located not under HOME, compare to root instead.
    // Since there appears to be no good way to get root path in
    // Windows, assume that if current dir has no parent dir, we're in
    // root.
    var dirname = path.dirname(configPath);
    var parentDirname = path.dirname(dirname);
    if (dirname === HOME || dirname === parentDirname) return null;

    // If there is no config in this directory, go one level up and look for
    // a config there:
    configPath = path.join(parentDirname, '.csscomb.json');
    return CSScomb.getCustomConfigPath(configPath);
};

/**
 * Detects the options in the given file
 *
 * @param {String} path Path to the stylesheet
 * @param {Array} options List of options to detect
 * @returns {Object} Detected options
 */
CSScomb.detectInFile = function detectInFile(path, options) {
    var stylesheet = fs.readFileSync(path, 'utf8');
    return CSScomb.detectInString(stylesheet, options);
};

/**
 * Detects the options in the given string
 *
 * @param {String} text Stylesheet
 * @param {Array} options List of options to detect
 * @returns {Object} Detected options
 */
CSScomb.detectInString = function detectInString(text, options) {
    var result;
    var handlers = [];

    if (!text) return text;

    var optionNames = fs.readdirSync(__dirname + '/options');
    optionNames.forEach(function(option) {
        option = option.slice(0, -3);
        if (options && options.indexOf(option) < 0) return;
        try {
            handlers.push(getHandler(option));
        } catch (e) {
            console.warn('\nFailed to load "%s" option:\n%s', option, e.message);
        }
    });

    var tree = cssToAST(text);
    var detectedOptions = detectInTree(tree, handlers);
    result = getDetectedOptions(detectedOptions, handlers);

    // Handle conflicting options with spaces around braces:
    var blockIndent = result['block-indent'];
    var spaceAfterOpeningBrace = result['space-after-opening-brace'];

    if (typeof blockIndent === 'string' &&
        spaceAfterOpeningBrace &&
        spaceAfterOpeningBrace.indexOf('\n') > -1) {
        result['space-after-opening-brace'] = '\n';
    }

    return result;
};

module.exports = CSScomb;
<|endoftext|>


<commit_before>'use strict';
var colName = "daemons";
var grpConfCol = "daemon_grpconf";

var async = require("async");

function validateId(mongo, req, cb) {
    try {
        req.soajs.inputmaskData.id = mongo.ObjectId(req.soajs.inputmaskData.id);
        return cb(null);
    } catch (e) {
        return cb(e);
    }
}

function checkIfError(req, res, data, cb) {
    if (data.error) {
        if (typeof (data.error) === 'object' && data.error.message) {
            req.soajs.log.error(data.error);
        }

        return res.jsonp(req.soajs.buildResponse({"code": data.code, "msg": data.config.errors[data.code]}));
    } else {
        if (cb) return cb();
    }
}

function searchForJob (jobName, jobs, cb) {
    for (var job in jobs) {
        if (job === jobName) {
            return cb (null, job);
        }
    }
    return cb("Job not found");
}

module.exports = {

    "list": function (config, mongo, req, res) {
        var criteria = ((req.soajs.inputmaskData.daemonNames) && (req.soajs.inputmaskData.daemonNames.length > 0)) ? {'name': {$in: req.soajs.inputmaskData.daemonNames}} : {};
        mongo.find(colName, criteria, function (error, records) {
            var data = {config: config, error: error, code: 718};
            checkIfError(req, res, data, function () {
                if (req.soajs.inputmaskData.getGroupConfigs) {
                    async.each (records, function (daemonRecord, cb) {
                        mongo.find (grpConfCol, {'daemon': daemonRecord.name}, {"daemonConfigGroup": 1, "_id": 0}, function (error, grpConfs) {
                            daemonRecord.grpConf = grpConfs;
                            cb (error, daemonRecord);
                        });
                    }, function (error, result) {
                        checkIfError(req, res, {config: config, error: error, code: 600}, function () {
                            return res.jsonp(req.soajs.buildResponse(null, records));
                        });
                    });
                } else {
                    return res.jsonp(req.soajs.buildResponse(null, records));
                }
            });
        });
    },

    "listGroupConfig": function (config, mongo, req, res) {
        var criteria = ((req.soajs.inputmaskData.grpConfNames) && (req.soajs.inputmaskData.grpConfNames.length > 0)) ? {'name': {$in: req.soajs.inputmaskData.grpConfNames}} : {};
        mongo.find(grpConfCol, criteria, function (error, records) {
            var data = {config: config, error: error, code: 719};
            checkIfError(req, res, data, function () {
                return res.jsonp(req.soajs.buildResponse(null, records));
            });
        });
    },

    "addGroupConfig": function (config, mongo, req, res) {
        var criteria = {
            'daemonConfigGroup': req.soajs.inputmaskData.groupName,
            'daemon': req.soajs.inputmaskData.daemon,
            'interval': req.soajs.inputmaskData.interval,
            'status': req.soajs.inputmaskData.status,
            'processing': req.soajs.inputmaskData.processing,
            'jobs': req.soajs.inputmaskData.jobs,
            'order': req.soajs.inputmaskData.order,
            'solo': req.soajs.inputmaskData.solo
        };
        mongo.count (grpConfCol, {"daemonConfigGroup": req.soajs.inputmaskData.groupName}, function (error, count) {
            var data = {config: config, error: error, code: 717};
            checkIfError(req, res, data, function () {
                checkIfError(req, res, {config: config, error: count > 0, code: 714}, function () {
                    mongo.insert (grpConfCol, criteria, function (error, result) {
                        data = {config: config, error: error || !result, code: 717};
                        checkIfError(req, res, data, function () {
                            return res.jsonp(req.soajs.buildResponse(null, true));
                        });
                    });
                });
            });
        });
    },

    "updateGroupConfig": function (config, mongo, req, res) {
        validateId(mongo, req, function (error) {
            var data = {config: config, error: error, code: 701};
            checkIfError(req, res, data, function () {
                var criteria = {'_id': req.soajs.inputmaskData.id};
                var update = {
                    '$set': {
                        'daemonConfigGroup': req.soajs.inputmaskData.groupName,
                        'daemon': req.soajs.inputmaskData.daemon,
                        'interval': req.soajs.inputmaskData.interval,
                        'status': req.soajs.inputmaskData.status,
                        'processing': req.soajs.inputmaskData.processing,
                        'jobs': req.soajs.inputmaskData.jobs,
                        'order': req.soajs.inputmaskData.order,
                        'solo': req.soajs.inputmaskData.solo
                    }
                };
                mongo.update(grpConfCol, criteria, update, function (error, result) {
                    data = {config: config, error: error || !result, code: 715};
                    checkIfError(req, res, data, function () {
                        return res.jsonp (req.soajs.buildResponse(null, true));
                    });
                });
            });
        });
    },

    "deleteGroupConfig": function (config, mongo, req, res) {
        validateId(mongo, req, function (error) {
            var data = {config: config, error: error, code: 701};
            checkIfError(req, res, data, function () {
                var criteria = {'_id': req.soajs.inputmaskData.id};
                mongo.remove(grpConfCol, criteria, function (error, result) {
                    data = {config: config, error: error || !result, code: 716};
                    checkIfError(req, res, data, function () {
                        return res.jsonp(req.soajs.buildResponse(null, true));
                    });
                });
            });
        });
    },

    "updateServiceConfig": function  (config, mongo, req, res) {
        validateId(mongo, req, function (error) {
            var data = {config: config, error: error, code: 701};
            checkIfError(req, res, data, function () {
                mongo.findOne(grpConfCol, {_id: req.soajs.inputmaskData.id}, function (error, group) {
                    data = {config: config, error: error || !group, code: 725};
                    checkIfError(req, res, data, function () {
                        searchForJob(req.soajs.inputmaskData.jobName, group.jobs, function (error, job) {
                            data = {config: config, error: error || !job, code: 724};
                            checkIfError(req, res, data, function () {
                                group.jobs[job].serviceConfig[req.soajs.inputmaskData.env] = req.soajs.inputmaskData.config;
                                if (Object.keys(group.jobs[job].serviceConfig[req.soajs.inputmaskData.env]).length === 0) {
                                    delete group.jobs[job].serviceConfig[req.soajs.inputmaskData.env];
                                }

                                mongo.save(grpConfCol, group, function (error) {
                                    data = {config: config, error: error, code: 720};
                                    checkIfError(req, res, data, function () {
                                        return res.jsonp(req.soajs.buildResponse(null, true));
                                    });
                                });
                            });
                        });
                    });
                });
            });
        });
    },

    "listServiceConfig": function (config, mongo, req, res) {
        validateId(mongo, req, function (error) {
            var data = {config: config, error: error, code: 701};
            checkIfError(req, res, data, function () {
                mongo.findOne(grpConfCol, {_id: req.soajs.inputmaskData.id}, function (error, group) {
                    data = {config: config, error: error || !group, code: 725};
                    checkIfError(req, res, data, function () {
                        searchForJob(req.soajs.inputmaskData.jobName, group.jobs, function (error, job) {
                            data = {config: config, error: error || !job, code: 724};
                            checkIfError(req, res, data, function () {
                                return res.jsonp(req.soajs.buildResponse(null, group.jobs[job].serviceConfig));
                            });
                        });
                    });
                })
            });
        });
    },

    "updateTenantExtKeys": function (config, mongo, req, res) {
        validateId(mongo, req, function (error) {
            var data = {config: config, error: error, code: 701};
            checkIfError(req, res, data, function () {
                mongo.findOne(grpConfCol, {_id: req.soajs.inputmaskData.id}, function (error, group) {
                    data = {config: config, error: error || !group, code: 725};
                    checkIfError(req, res, data, function () {
                        searchForJob(req.soajs.inputmaskData.jobName, group.jobs, function (error, job) {
                            data = {config: config, error: error || !job, code: 724};
                            checkIfError(req, res, data, function () {
                                group.jobs[job].tenantExtKeys = req.soajs.inputmaskData.tenantExtKeys;
                                group.jobs[job].tenantsInfo = req.soajs.inputmaskData.tenantsInfo;

                                mongo.save(grpConfCol, group, function (error) {
                                    data = {config: config, error: error, code: 722};
                                    checkIfError(req, res, data, function () {
                                        return res.jsonp(req.soajs.buildResponse(null, true));
                                    });
                                });
                            });
                        });
                    });
                });
            });
        });
    },

    "listTenantExtKeys": function (config, mongo, req, res) {
        validateId(mongo, req, function (error) {
            var data = {config: config, error: error, code: 701};
            checkIfError(req, res, data, function () {
                mongo.findOne(grpConfCol, {_id: req.soajs.inputmaskData.id}, function (error, group) {
                    data = {config: config, error: error || !group, code: 725};
                    checkIfError(req, res, data, function () {
                        searchForJob(req.soajs.inputmaskData.jobName, group.jobs, function (error, job) {
                            data = {config: config, error: error || !job, code: 724};
                            checkIfError(req, res, data, function () {
                                return res.jsonp(req.soajs.buildResponse(null, group.jobs[job].tenantsInfo));
                            });
                        });
                    });
                });
            });
        });
    }
};<commit_msg>Enhanced mongo query in add group config<commit_after>'use strict';
var colName = "daemons";
var grpConfCol = "daemon_grpconf";

var async = require("async");

function validateId(mongo, req, cb) {
    try {
        req.soajs.inputmaskData.id = mongo.ObjectId(req.soajs.inputmaskData.id);
        return cb(null);
    } catch (e) {
        return cb(e);
    }
}

function checkIfError(req, res, data, cb) {
    if (data.error) {
        if (typeof (data.error) === 'object' && data.error.message) {
            req.soajs.log.error(data.error);
        }

        return res.jsonp(req.soajs.buildResponse({"code": data.code, "msg": data.config.errors[data.code]}));
    } else {
        if (cb) return cb();
    }
}

function searchForJob (jobName, jobs, cb) {
    for (var job in jobs) {
        if (job === jobName) {
            return cb (null, job);
        }
    }
    return cb("Job not found");
}

module.exports = {

    "list": function (config, mongo, req, res) {
        var criteria = ((req.soajs.inputmaskData.daemonNames) && (req.soajs.inputmaskData.daemonNames.length > 0)) ? {'name': {$in: req.soajs.inputmaskData.daemonNames}} : {};
        mongo.find(colName, criteria, function (error, records) {
            var data = {config: config, error: error, code: 718};
            checkIfError(req, res, data, function () {
                if (req.soajs.inputmaskData.getGroupConfigs) {
                    async.each (records, function (daemonRecord, cb) {
                        mongo.find (grpConfCol, {'daemon': daemonRecord.name}, {"daemonConfigGroup": 1, "_id": 0}, function (error, grpConfs) {
                            daemonRecord.grpConf = grpConfs;
                            cb (error, daemonRecord);
                        });
                    }, function (error, result) {
                        checkIfError(req, res, {config: config, error: error, code: 600}, function () {
                            return res.jsonp(req.soajs.buildResponse(null, records));
                        });
                    });
                } else {
                    return res.jsonp(req.soajs.buildResponse(null, records));
                }
            });
        });
    },

    "listGroupConfig": function (config, mongo, req, res) {
        var criteria = ((req.soajs.inputmaskData.grpConfNames) && (req.soajs.inputmaskData.grpConfNames.length > 0)) ? {'name': {$in: req.soajs.inputmaskData.grpConfNames}} : {};
        mongo.find(grpConfCol, criteria, function (error, records) {
            var data = {config: config, error: error, code: 719};
            checkIfError(req, res, data, function () {
                return res.jsonp(req.soajs.buildResponse(null, records));
            });
        });
    },

    "addGroupConfig": function (config, mongo, req, res) {
        var criteria = {
            'daemonConfigGroup': req.soajs.inputmaskData.groupName,
            'daemon': req.soajs.inputmaskData.daemon,
            'interval': req.soajs.inputmaskData.interval,
            'status': req.soajs.inputmaskData.status,
            'processing': req.soajs.inputmaskData.processing,
            'jobs': req.soajs.inputmaskData.jobs,
            'order': req.soajs.inputmaskData.order,
            'solo': req.soajs.inputmaskData.solo
        };
        mongo.count (grpConfCol, {"daemonConfigGroup": req.soajs.inputmaskData.groupName, "daemon": req.soajs.inputmaskData.daemon}, function (error, count) {
            var data = {config: config, error: error, code: 717};
            checkIfError(req, res, data, function () {
                checkIfError(req, res, {config: config, error: count > 0, code: 714}, function () {
                    mongo.insert (grpConfCol, criteria, function (error, result) {
                        data = {config: config, error: error || !result, code: 717};
                        checkIfError(req, res, data, function () {
                            return res.jsonp(req.soajs.buildResponse(null, true));
                        });
                    });
                });
            });
        });
    },

    "updateGroupConfig": function (config, mongo, req, res) {
        validateId(mongo, req, function (error) {
            var data = {config: config, error: error, code: 701};
            checkIfError(req, res, data, function () {
                var criteria = {'_id': req.soajs.inputmaskData.id};
                var update = {
                    '$set': {
                        'daemonConfigGroup': req.soajs.inputmaskData.groupName,
                        'daemon': req.soajs.inputmaskData.daemon,
                        'interval': req.soajs.inputmaskData.interval,
                        'status': req.soajs.inputmaskData.status,
                        'processing': req.soajs.inputmaskData.processing,
                        'jobs': req.soajs.inputmaskData.jobs,
                        'order': req.soajs.inputmaskData.order,
                        'solo': req.soajs.inputmaskData.solo
                    }
                };
                mongo.update(grpConfCol, criteria, update, function (error, result) {
                    data = {config: config, error: error || !result, code: 715};
                    checkIfError(req, res, data, function () {
                        return res.jsonp (req.soajs.buildResponse(null, true));
                    });
                });
            });
        });
    },

    "deleteGroupConfig": function (config, mongo, req, res) {
        validateId(mongo, req, function (error) {
            var data = {config: config, error: error, code: 701};
            checkIfError(req, res, data, function () {
                var criteria = {'_id': req.soajs.inputmaskData.id};
                mongo.remove(grpConfCol, criteria, function (error, result) {
                    data = {config: config, error: error || !result, code: 716};
                    checkIfError(req, res, data, function () {
                        return res.jsonp(req.soajs.buildResponse(null, true));
                    });
                });
            });
        });
    },

    "updateServiceConfig": function  (config, mongo, req, res) {
        validateId(mongo, req, function (error) {
            var data = {config: config, error: error, code: 701};
            checkIfError(req, res, data, function () {
                mongo.findOne(grpConfCol, {_id: req.soajs.inputmaskData.id}, function (error, group) {
                    data = {config: config, error: error || !group, code: 725};
                    checkIfError(req, res, data, function () {
                        searchForJob(req.soajs.inputmaskData.jobName, group.jobs, function (error, job) {
                            data = {config: config, error: error || !job, code: 724};
                            checkIfError(req, res, data, function () {
                                group.jobs[job].serviceConfig[req.soajs.inputmaskData.env] = req.soajs.inputmaskData.config;
                                if (Object.keys(group.jobs[job].serviceConfig[req.soajs.inputmaskData.env]).length === 0) {
                                    delete group.jobs[job].serviceConfig[req.soajs.inputmaskData.env];
                                }

                                mongo.save(grpConfCol, group, function (error) {
                                    data = {config: config, error: error, code: 720};
                                    checkIfError(req, res, data, function () {
                                        return res.jsonp(req.soajs.buildResponse(null, true));
                                    });
                                });
                            });
                        });
                    });
                });
            });
        });
    },

    "listServiceConfig": function (config, mongo, req, res) {
        validateId(mongo, req, function (error) {
            var data = {config: config, error: error, code: 701};
            checkIfError(req, res, data, function () {
                mongo.findOne(grpConfCol, {_id: req.soajs.inputmaskData.id}, function (error, group) {
                    data = {config: config, error: error || !group, code: 725};
                    checkIfError(req, res, data, function () {
                        searchForJob(req.soajs.inputmaskData.jobName, group.jobs, function (error, job) {
                            data = {config: config, error: error || !job, code: 724};
                            checkIfError(req, res, data, function () {
                                return res.jsonp(req.soajs.buildResponse(null, group.jobs[job].serviceConfig));
                            });
                        });
                    });
                })
            });
        });
    },

    "updateTenantExtKeys": function (config, mongo, req, res) {
        validateId(mongo, req, function (error) {
            var data = {config: config, error: error, code: 701};
            checkIfError(req, res, data, function () {
                mongo.findOne(grpConfCol, {_id: req.soajs.inputmaskData.id}, function (error, group) {
                    data = {config: config, error: error || !group, code: 725};
                    checkIfError(req, res, data, function () {
                        searchForJob(req.soajs.inputmaskData.jobName, group.jobs, function (error, job) {
                            data = {config: config, error: error || !job, code: 724};
                            checkIfError(req, res, data, function () {
                                group.jobs[job].tenantExtKeys = req.soajs.inputmaskData.tenantExtKeys;
                                group.jobs[job].tenantsInfo = req.soajs.inputmaskData.tenantsInfo;

                                mongo.save(grpConfCol, group, function (error) {
                                    data = {config: config, error: error, code: 722};
                                    checkIfError(req, res, data, function () {
                                        return res.jsonp(req.soajs.buildResponse(null, true));
                                    });
                                });
                            });
                        });
                    });
                });
            });
        });
    },

    "listTenantExtKeys": function (config, mongo, req, res) {
        validateId(mongo, req, function (error) {
            var data = {config: config, error: error, code: 701};
            checkIfError(req, res, data, function () {
                mongo.findOne(grpConfCol, {_id: req.soajs.inputmaskData.id}, function (error, group) {
                    data = {config: config, error: error || !group, code: 725};
                    checkIfError(req, res, data, function () {
                        searchForJob(req.soajs.inputmaskData.jobName, group.jobs, function (error, job) {
                            data = {config: config, error: error || !job, code: 724};
                            checkIfError(req, res, data, function () {
                                return res.jsonp(req.soajs.buildResponse(null, group.jobs[job].tenantsInfo));
                            });
                        });
                    });
                });
            });
        });
    }
};
<|endoftext|>


<commit_before>var fs = require('fs')
  , path = require('path')
  , express = require('express')
  , Mincer = require('mincer')
  , coffee = require('coffee-script');

global.SCHEDULER = require('node-schedule');

module.exports.logger = logger = require('./logger');
module.exports.Dashing = function Dashing() {
  var dashing = {};
  dashing.root = path.resolve(__dirname, '../../..');
  dashing.NODE_ENV = process.env.NODE_ENV || 'development';

  dashing.view_engine = process.env.VIEW_ENGINE || 'jade';

  dashing.mincer = {};
  dashing.mincer.environment = new Mincer.Environment();
  dashing.mincer.assets_prefix = '/assets';
  dashing.mincer.environment.appendPath('assets/javascripts');
  dashing.mincer.environment.appendPath('assets/stylesheets');
  dashing.mincer.environment.appendPath('assets/fonts');
  dashing.mincer.environment.appendPath('assets/images');
  dashing.mincer.environment.appendPath('widgets');
  dashing.mincer.environment.appendPath(path.resolve(__dirname, '../javascripts'));

  dashing.public_folder = dashing.root + '/public';
  dashing.views = dashing.root + '/dashboards';
  dashing.settings = dashing.root + '/settings';
  dashing.default_dashboard = null;
  dashing.port = (process.env.PORT || 3030);

  dashing.protected = function(req, res, next) {
    next();
  };

  dashing._protected = function(req, res, next) {
    dashing.protected(req, res, next);
  }

  var expressLoggerOptions = {
    format: 'dev',
    stream: {
      write: function(message, encoding) {
        logger.info(message);
      }
    }
  };

  // setup Express
  var app = express();
  app.configure('development', function() {
    Mincer.logger.use(logger);
  });
  app.configure('production', function() {
    expressLoggerOptions.format = 'short';
    // In production we assume that assets are not changed between requests,
    // so we use cached version of environment.
    // All file system methods are cached for the instances lifetime.
    dashing.mincer.environment = dashing.mincer.environment.index;
  });
  app.configure(function() {
    app.set('views', dashing.views);
    app.set('view engine', dashing.view_engine);
    if (dashing.view_engine === 'ejs') {
      app.use(require('express-ejs-layouts'));
    }
    app.use(express.logger(expressLoggerOptions));
    app.use(express.errorHandler());
    app.use(express.compress());
    app.use(express.json());
    app.use(express.urlencoded());
    app.use(express.methodOverride());
    app.use(dashing.mincer.assets_prefix, Mincer.createServer(dashing.mincer.environment));
    app.use(express.static(dashing.public_folder));
    app.use(app.router);
  });
  app.set('development', dashing.NODE_ENV === 'development');
  app.set('production', dashing.NODE_ENV === 'production');

  var connections = {};
  var history = {};

  app.get('/events', dashing._protected, function(req, res) {
    // let request last as long as possible
    req.socket.setTimeout(0);

    var conn = {
      id: (new Date().getTime().toString() + Math.floor(Math.random() * 1000).toString()),
      send: function(body) {
        res.write(body);
        res.flush(); // need to flush with .compress()
      }
    };
    connections[conn.id] = conn;

    // send headers for event-stream connection
    res.writeHead(200, {
      'Content-Type': 'text/event-stream',
      'Cache-Control': 'no-cache',
      'Connection': 'keep-alive',
      'X-Accel-Buffering': 'no' // Disable buffering for nginx
    });
    res.write('\n');
    res.write(Array(2049).join(' ') + '\n'); // 2kb padding for IE
    res.write(latest_events());
    res.flush(); // need to flush with .compress()

    req.on('close', function() {
      delete connections[conn.id];
    });
  });

  app.get('/', function(req, res) {
    if (dashing.default_dashboard) {
      res.redirect(dashing.default_dashboard);
    } else {
      first_dashboard(function(err, dashboard) {
        if (err) {
          next(err);
        } else if (dashboard) {
          res.redirect(dashboard);
        } else {
          next(new Error('There are no dashboards in your dashboard directory.'));
        }
      });
    }
  });

  app.get('/:dashboard', dashing._protected, function(req, res) {
    var dashboard = req.params.dashboard;
    fs.exists([dashing.views, dashboard + '.' + dashing.view_engine].join(path.sep), function(exists) {
      if (exists) {
        var templateVars = {
          dashboard: dashboard,
          request: req
        };
        var settingsPath = [dashing.settings, dashboard + '.json'].join(path.sep);
        fs.exists(settingsPath, function(exists) {
          if (exists) {
            templateVars.settings = require(settingsPath);
          }
          res.render(dashboard, templateVars);
        });
      } else {
        res.status(404).sendfile(dashing.public_folder + '/404.html');
      }
    });
  });

  app.get('/views/:widget?.html', dashing._protected, function(req, res) {
    var widget = req.params.widget;
    res.sendfile([dashing.root, 'widgets', widget, widget + '.html'].join(path.sep));
  });

  app.post('/widgets/:id', function(req, res) {
    var auth_token = req.body.auth_token;
    if (!dashing.auth_token || dashing.auth_token == auth_token) {
      send_event(req.params.id, req.body);
      res.send(204);
    } else {
      res.send(401, 'Invalid API key');
    }
  });

  // The 404 Route (ALWAYS Keep this as the last route)
  app.use(function(req, res, next) {
    res.status(404).sendfile(dashing.public_folder + '/404.html');
  });

  // Error handler
  app.use(function(err, req, res, next) {
    logger.error(err.stack);
    res.send(500, err);
  });

  function send_event(id, body) {
    body.id = id;
    body.updatedAt = Date.now();
    var event = format_event(body);
    history[id] = event;
    for (var k in connections) {
      connections[k].send(event);
    }
  }
  global.send_event = send_event;

  function format_event(body) {
    return 'data: ' + JSON.stringify(body) + '\n\n';
  }

  function latest_events() {
    var str = [];
    for (var id in history) {
      str.push(history[id]);
    }
    return str.join('');
  }

  function first_dashboard(fn) {
    fs.readdir(dashing.views, function(err, files) {
      if (err) fn(err);
      var regex = new RegExp('(\w*)\.' + dashing.view_engine + '$');
      for (var i in files) {
        var file = files[i];
        if (file.match(regex) && file !== 'layout.' + dashing.view_engine) {
          fn(null, file.substring(0, file.length - (dashing.view_engine.length + 1)));
          return;
        }
      }
      fn(null, null);
    });
  }

  // Load custom libraries
  fs.readdir([dashing.root, 'lib'].join(path.sep), function(err, files) {
    if (err) throw err;
    for (var i in files) {
      var file = [dashing.root, 'lib', files[i]].join(path.sep);
      require(file);
    }
  });

  // Lod jobs files
  var job_path = process.env.JOB_PATH || [dashing.root, 'jobs'].join(path.sep);
  fs.readdir(job_path, function(err, files) {
    if (err) throw err;
    for (var i in files) {
      var file = [job_path, files[i]].join(path.sep);
      if (file.match(/(\w*)\.job\.(js|coffee)$/)) {
        logger.log('Loading job file:', files[i]);
        require(file);
      }
    }
  });

  dashing.start = function() {
    app.listen(dashing.port);
    logger.info('Listening on http://0.0.0.0:' + dashing.port + (process.env.__daemon === 'false' ? ', CTRL+C to stop' : ''));
  }
  dashing.app = app;
  return dashing;
};
<commit_msg>fix: start jobs when dashing starts not during require<commit_after>var fs = require('fs')
  , path = require('path')
  , express = require('express')
  , Mincer = require('mincer')
  , coffee = require('coffee-script');

global.SCHEDULER = require('node-schedule');

module.exports.logger = logger = require('./logger');
module.exports.Dashing = function Dashing() {
  var dashing = {};
  dashing.root = path.resolve(__dirname, '../../..');
  dashing.NODE_ENV = process.env.NODE_ENV || 'development';

  dashing.view_engine = process.env.VIEW_ENGINE || 'jade';

  dashing.mincer = {};
  dashing.mincer.environment = new Mincer.Environment();
  dashing.mincer.assets_prefix = '/assets';
  dashing.mincer.environment.appendPath('assets/javascripts');
  dashing.mincer.environment.appendPath('assets/stylesheets');
  dashing.mincer.environment.appendPath('assets/fonts');
  dashing.mincer.environment.appendPath('assets/images');
  dashing.mincer.environment.appendPath('widgets');
  dashing.mincer.environment.appendPath(path.resolve(__dirname, '../javascripts'));

  dashing.public_folder = dashing.root + '/public';
  dashing.views = dashing.root + '/dashboards';
  dashing.settings = dashing.root + '/settings';
  dashing.default_dashboard = null;
  dashing.port = (process.env.PORT || 3030);

  dashing.protected = function(req, res, next) {
    next();
  };

  dashing._protected = function(req, res, next) {
    dashing.protected(req, res, next);
  }

  var expressLoggerOptions = {
    format: 'dev',
    stream: {
      write: function(message, encoding) {
        logger.info(message);
      }
    }
  };

  // setup Express
  var app = express();
  app.configure('development', function() {
    Mincer.logger.use(logger);
  });
  app.configure('production', function() {
    expressLoggerOptions.format = 'short';
    // In production we assume that assets are not changed between requests,
    // so we use cached version of environment.
    // All file system methods are cached for the instances lifetime.
    dashing.mincer.environment = dashing.mincer.environment.index;
  });
  app.configure(function() {
    app.set('views', dashing.views);
    app.set('view engine', dashing.view_engine);
    if (dashing.view_engine === 'ejs') {
      app.use(require('express-ejs-layouts'));
    }
    app.use(express.logger(expressLoggerOptions));
    app.use(express.errorHandler());
    app.use(express.compress());
    app.use(express.json());
    app.use(express.urlencoded());
    app.use(express.methodOverride());
    app.use(dashing.mincer.assets_prefix, Mincer.createServer(dashing.mincer.environment));
    app.use(express.static(dashing.public_folder));
    app.use(app.router);
  });
  app.set('development', dashing.NODE_ENV === 'development');
  app.set('production', dashing.NODE_ENV === 'production');

  var connections = {};
  var history = {};

  app.get('/events', dashing._protected, function(req, res) {
    // let request last as long as possible
    req.socket.setTimeout(0);

    var conn = {
      id: (new Date().getTime().toString() + Math.floor(Math.random() * 1000).toString()),
      send: function(body) {
        res.write(body);
        res.flush(); // need to flush with .compress()
      }
    };
    connections[conn.id] = conn;

    // send headers for event-stream connection
    res.writeHead(200, {
      'Content-Type': 'text/event-stream',
      'Cache-Control': 'no-cache',
      'Connection': 'keep-alive',
      'X-Accel-Buffering': 'no' // Disable buffering for nginx
    });
    res.write('\n');
    res.write(Array(2049).join(' ') + '\n'); // 2kb padding for IE
    res.write(latest_events());
    res.flush(); // need to flush with .compress()

    req.on('close', function() {
      delete connections[conn.id];
    });
  });

  app.get('/', function(req, res) {
    if (dashing.default_dashboard) {
      res.redirect(dashing.default_dashboard);
    } else {
      first_dashboard(function(err, dashboard) {
        if (err) {
          next(err);
        } else if (dashboard) {
          res.redirect(dashboard);
        } else {
          next(new Error('There are no dashboards in your dashboard directory.'));
        }
      });
    }
  });

  app.get('/:dashboard', dashing._protected, function(req, res) {
    var dashboard = req.params.dashboard;
    fs.exists([dashing.views, dashboard + '.' + dashing.view_engine].join(path.sep), function(exists) {
      if (exists) {
        var templateVars = {
          dashboard: dashboard,
          request: req
        };
        var settingsPath = [dashing.settings, dashboard + '.json'].join(path.sep);
        fs.exists(settingsPath, function(exists) {
          if (exists) {
            templateVars.settings = require(settingsPath);
          }
          res.render(dashboard, templateVars);
        });
      } else {
        res.status(404).sendfile(dashing.public_folder + '/404.html');
      }
    });
  });

  app.get('/views/:widget?.html', dashing._protected, function(req, res) {
    var widget = req.params.widget;
    res.sendfile([dashing.root, 'widgets', widget, widget + '.html'].join(path.sep));
  });

  app.post('/widgets/:id', function(req, res) {
    var auth_token = req.body.auth_token;
    if (!dashing.auth_token || dashing.auth_token == auth_token) {
      send_event(req.params.id, req.body);
      res.send(204);
    } else {
      res.send(401, 'Invalid API key');
    }
  });

  // The 404 Route (ALWAYS Keep this as the last route)
  app.use(function(req, res, next) {
    res.status(404).sendfile(dashing.public_folder + '/404.html');
  });

  // Error handler
  app.use(function(err, req, res, next) {
    logger.error(err.stack);
    res.send(500, err);
  });

  function send_event(id, body) {
    body.id = id;
    body.updatedAt = Date.now();
    var event = format_event(body);
    history[id] = event;
    for (var k in connections) {
      connections[k].send(event);
    }
  }
  global.send_event = send_event;

  function format_event(body) {
    return 'data: ' + JSON.stringify(body) + '\n\n';
  }

  function latest_events() {
    var str = [];
    for (var id in history) {
      str.push(history[id]);
    }
    return str.join('');
  }

  function first_dashboard(fn) {
    fs.readdir(dashing.views, function(err, files) {
      if (err) fn(err);
      var regex = new RegExp('(\w*)\.' + dashing.view_engine + '$');
      for (var i in files) {
        var file = files[i];
        if (file.match(regex) && file !== 'layout.' + dashing.view_engine) {
          fn(null, file.substring(0, file.length - (dashing.view_engine.length + 1)));
          return;
        }
      }
      fn(null, null);
    });
  }

  // Load custom libraries
  fs.readdir([dashing.root, 'lib'].join(path.sep), function(err, files) {
    if (err) throw err;
    for (var i in files) {
      var file = [dashing.root, 'lib', files[i]].join(path.sep);
      require(file);
    }
  });

  function start_jobs() {
    // Load jobs files
    var job_path = process.env.JOB_PATH || [dashing.root, 'jobs'].join(path.sep);
    fs.readdir(job_path, function(err, files) {
      if (err) throw err;
      for (var i in files) {
        var file = [job_path, files[i]].join(path.sep);
        if (file.match(/(\w*)\.job\.(js|coffee)$/)) {
          logger.info('Loading job file:', files[i]);
          require(file);
        }
      }
    });
  }

  function start_express() {
    app.listen(dashing.port);
    logger.info('Listening on http://0.0.0.0:' + dashing.port + (process.env.__daemon === 'false' ? ', CTRL+C to stop' : ''));
  }

  dashing.start = function() {
    try {
      start_jobs();
      start_express();
    } catch(e) {
      logger.error("Unable to start dashing");
      logger.error(e.toString()); // winston is not catching these?
    }
  }
  dashing.app = app;
  return dashing;
};
<|endoftext|>


<commit_before>//Import dependencies
var colors = require('colors');

//Display object
var display = {};

//Display a done message
display.done = function(text){ console.log('  DONE   '.black.bgGreen.bold + ' ' + text.green.bold); },

//Display a warning message
display.warning = function(text){ console.log(' WARNING '.black.bgYellow.bold + ' ' + text.yellow.bold); },

//Display an error message
display.error = function(text){ console.log('  ERROR  '.black.bgRed.bold + ' ' + text.red.bold); },

//Display an info message
display.info = function(text){ console.log('  INFO   '.black.bgBlue.bold + ' ' + text.blue.bold); };

//Exports to node
module.exports = display;
<commit_msg>lib/display.js: updated error display<commit_after>//Import dependencies
var colors = require('colors');

//Display object
var display = {};

//Display a done message
display.done = function(text){ console.log('  DONE   '.black.bgGreen.bold + ' ' + text.green.bold); },

//Display a warning message
display.warning = function(text){ console.log(' WARNING '.black.bgYellow.bold + ' ' + text.yellow.bold); },

//Display an error message
display.error = function(text){ console.error('  ERROR  '.black.bgRed.bold + ' ' + text.red.bold); },

//Display an info message
display.info = function(text){ console.log('  INFO   '.black.bgBlue.bold + ' ' + text.blue.bold); };

//Exports to node
module.exports = display;
<|endoftext|>


<commit_before>/**
 * Module dependencies.
 */

var Attribute = require('./attribute');
var Text = require('./text');

/**
 * Expose 'Element'
 */

module.exports = Element;

/**
 * Element interface.
 *
 * Represents an object of a document.
 *
 * @param {String} tag
 * @api public
 */

function Element(tag) {
  this.localName = tag;
  this.nodeType = 1;
  this.childNodes = [];
  // note: attributes should be an array like
  // we should use Map
  this.attributes = new NamedNodeMap();
}

function NamedNodeMap() {

}

NamedNodeMap.prototype.setNamedItem = function(attr) {
  this[attr.localName] = attr;
};

/**
 * Set attribute.
 *
 * @param {String} name
 * @param {Any} value
 * @api public
 */

Element.prototype.setAttribute = function(name, value) {
  var attr = new Attribute(name);
  attr.appendChild(new Text(value));
  this.attributes[name] = attr;
};

/**
 * Append child node (element or text
 * node).
 *
 * @param  {Element | Text} child
 * @return {Element} child
 * @api public
 */

Element.prototype.appendChild = function(child) {
  this.childNodes.push(child);
  child.parentNode = this;
  return child;
};

/**
 * Return element first child.
 *
 * @note should we use define getter
 * or object property?
 *
 * @return {Element | Text}
 * @api public
 */

Element.prototype.__defineGetter__('firstChild', function () {
  return this.childNodes[0];
});

Element.prototype.__defineGetter__('nextSibling', function () {
  var nodes = this.parentNode.childNodes;
  var idx = nodes.indexOf(this);
  return nodes[idx + 1];
});

/**
 * Render string element.
 *
 * @return {String}
 * @api private
 */

Element.prototype.render = function() {
  var key = attrs(this.localName, this.attributes) + '>';
  var result = '<' + key;
  for(var i = 0, l = this.childNodes.length; i < l; i++) {
    result += this.childNodes[i].render();
  }
  result += '</' + this.localName + '>';
  return result;
};

/**
 * Render attributes node list
 * into string.
 *
 * @param  {String} tag
 * @param  {Array} attributes
 * @return {String}
 * @api private
 */

function attrs(tag, attributes) {
  var arr = Object.keys(attributes);
  var length = arr.length;
  if(length) {
    for(var i = 0; i < length; i++) {
      tag = tag + ' ' + attributes[arr[i]].render();
    }
  }
  return tag;
}
<commit_msg>add next sibling handler, should refactor into node interface<commit_after>/**
 * Module dependencies.
 */

var Attribute = require('./attribute');
var Text = require('./text');

/**
 * Expose 'Element'
 */

module.exports = Element;

/**
 * Element interface.
 *
 * Represents an object of a document.
 *
 * @param {String} tag
 * @api public
 */

function Element(tag) {
  this.localName = tag;
  this.nodeType = 1;
  this.childNodes = [];
  // note: attributes should be an array like
  // we should use Map
  this.attributes = new NamedNodeMap();
}

function NamedNodeMap() {

}

NamedNodeMap.prototype.setNamedItem = function(attr) {
  this[attr.localName] = attr;
};

/**
 * Set attribute.
 *
 * @param {String} name
 * @param {Any} value
 * @api public
 */

Element.prototype.setAttribute = function(name, value) {
  var attr = new Attribute(name);
  attr.appendChild(new Text(value));
  this.attributes[name] = attr;
};

/**
 * Append child node (element or text
 * node).
 *
 * @param  {Element | Text} child
 * @return {Element} child
 * @api public
 */

Element.prototype.appendChild = function(child) {
  this.childNodes.push(child);
  child.parentNode = this;
  return child;
};

/**
 * Return element first child.
 *
 * @note should we use define getter
 * or object property?
 *
 * @return {Element | Text}
 * @api public
 */

Element.prototype.__defineGetter__('firstChild', function () {
  return this.childNodes[0];
});

/**
 * Return next element sibling
 * if exists.
 *
 * @return {Element | Text}
 * @api public
 */

Element.prototype.__defineGetter__('nextSibling', function () {
  // todo: we should avoid exception if parentNode undefined
  var nodes = this.parentNode.childNodes;
  var idx = nodes.indexOf(this);
  return nodes[idx + 1];
});

/**
 * Render string element.
 *
 * @return {String}
 * @api private
 */

Element.prototype.render = function() {
  var key = attrs(this.localName, this.attributes) + '>';
  var result = '<' + key;
  for(var i = 0, l = this.childNodes.length; i < l; i++) {
    result += this.childNodes[i].render();
  }
  result += '</' + this.localName + '>';
  return result;
};

/**
 * Render attributes node list
 * into string.
 *
 * @param  {String} tag
 * @param  {Array} attributes
 * @return {String}
 * @api private
 */

function attrs(tag, attributes) {
  var arr = Object.keys(attributes);
  var length = arr.length;
  if(length) {
    for(var i = 0; i < length; i++) {
      tag = tag + ' ' + attributes[arr[i]].render();
    }
  }
  return tag;
}
<|endoftext|>


<commit_before>var db = require("./db");
var api = require("./api");

/*
 * default handler for all events.
 */
function default_ev_handler(msg, rcpts){

	if( rcpts == undefined ){

		if( !msg.ev_data.doc.rcpts )
			return;

		rcpts = msg.ev_data.doc.rcpts;
		var	idx = rcpts.indexOf(msg.ev_data.uid);

		if( idx != -1)
			rcpts.splice(idx,1);

	}

	delete msg.ev_data.doc;

	for(i in rcpts){

		db.save("events", { ev_rcpt:rcpts[i], ev_msg:msg, _id: Math.random().toString(36).substring(2,10) }, function(err,val){

			if(err)
				throw err;
		});
		push( rcpts[i], msg );
	}
}

api.on("ev_create", function( msg ){

	if( !msg.ev_data.doc.rcpts )
		return;

	var rcpts = msg.ev_data.doc.rcpts,
		idx = rcpts.indexOf(msg.ev_data.doc.uid);

	if( idx != -1)
		rcpts.splice(idx,1);

	delete msg.ev_data.doc.rcpts;
	msg.ev_data.doc.wid = msg.ev_data.doc._id;
	delete msg.ev_data.doc._id;

	for(i in rcpts){

		db.save("events", { ev_rcpt:rcpts[i], ev_msg:msg, _id: Math.random().toString(36).substring(2,10) }, function(err,val){

			if(err)
				throw err;
		});
		push( rcpts[i], msg );
	}
});

/*
 * handler for ev_join event type.
 */
api.on("ev_join", function( msg, rcpts ){

	default_ev_handler( msg, rcpts );
});

/*
 * handler for ev_unjoin event type
 */
api.on("ev_unjoin", function( msg, rcpts ){

	default_ev_handler( msg, rcpts );
});

/*
 * handler for ev_add event type.
 */
api.on("ev_add", function( msg, rcpts ){

	default_ev_handler( msg, rcpts );
});

/*
 * handler for ev_rem event type.
 */
api.on("ev_rem", function( msg, rcpts ){

	default_ev_handler( msg, rcpts );
});

/*
 * handler for the ev_set event type.
 */
api.on("ev_set",function( msg, rcpts ){

	default_ev_handler( msg, rcpts );
});

/*
 * handler for the ev_incr event type.
 */
api.on("ev_incr",function( msg, rcpts ){

	default_ev_handler( msg, rcpts );
});

/*
 * handler for the ev_decr event type.
 */
api.on("ev_decr",function( msg, rcpts ){

	default_ev_handler( msg, rcpts );
});

/*
 * handler for the ev_push event type.
 */
api.on("ev_push",function( msg, rcpts ){

	default_ev_handler( msg, rcpts );
});

/*
 * handler for the ev_pop event type.
 */
api.on("ev_pop",function( msg, rcpts ){

	default_ev_handler( msg, rcpts );
});

/*
 * handler for the ev_pull event type.
 */
api.on("ev_pull",function( msg, rcpts ){

	default_ev_handler( msg, rcpts );
});

api.on("ev_ping", function( msg ){

	var rcpt = msg.ev_data.uid;
	delete msg.ev_data.uid;
	msg.ev_data.ts3 = new Date().getTime();
	push(rcpt, msg);

});

/*
 * subscribers list
 */
var subscribers = {};

var get_sub = exports.get_subscription = function ( uid ){

	if( uid == undefined )
		throw new Error("Invoke with a uid");

	return subscribers["" + uid];
}

/*
 * remove uid from the subscribers list.
 */
var rem_subscription = exports.rem_subscription  = function( uid ){

	if(uid == undefined)
		throw new Error("Must invoke with a uid");

	delete subscribers["" + uid];

}

/*
 * Add uid to the subscribers list.
 */
var add_subscription = exports.add_subscription = function( uid, http_resp ){

	subscribers["" + uid] = {http:http_resp};
}

/*
 * is subscriber uid connected?
 */
var is_subscribed = exports.is_subscribed = function( uid ){

	if(uid == undefined)
		throw new Error("Must invoke with a uid");

	return subscribers["" + uid] != undefined;
}

/*
 * push message to subscriber.
 */
function push( rcpt, msg ){

	if( is_subscribed(rcpt) ){

		var http_resp = subscribers["" + rcpt].http;
		http_resp.write( JSON.stringify(msg) + "\n" );
	}
}

/*
 * Recuperamos los eventos del usuario uid desde la marca temporal ts y se los enviamos.
 *
 */
function push_events( uid, tstamp ){

	//recuperamos los eventos de la base de datos
	db.selectObjectsWithOrder("events",{ev_rcpt:uid, "ev_msg.ev_tstamp":{$gt:tstamp}},{},{"ev_msg.ev_tstamp":1},function(err,results){

		for(i in results)
			push(uid, results[i].ev_msg);

	});

}

exports.api = {};
exports.api.listen = function( ev_type, ev_handler ){

	api.on(ev_type,function( msg, rcpts ){

		if( ev_handler == undefined )
			default_ev_handler( msg, rcpts );
		else
			ev_handler( msg, rcpts );
	});
}

exports.remote = {};
/*
 *
 * Llamada RPC para suscribirse a la cola de eventos.
 */
//TODO: refactorizar el codigo de suscripcion.
exports.remote.subscribe = function( http_resp, params ){

	if(params.uid == undefined){

		http_resp.end();
		return;
	}

	add_subscription(params.uid, http_resp);

	http_resp.on("close", function(){

		console.log('Client closed: [%d]', params.uid);
		rem_subscription(params.uid);
	});

	http_resp.connection.on("error", function(ex){

		http_resp.connection.destroy();

	});

	if( params.tstamp )
		push_events(params.uid, params.tstamp);

}

//Codigo de ejemplo de connection pooling del driver node.js native
/*
mongodb = require('mongodb');

// Define options. Note poolSize.
var serverOptions = {
  'auto_reconnect': true,
  'poolSize': 5
};

// Now create the server, passing our options.
var serv = new mongodb.Server('localhost', 27017, serverOptions);

// At this point, there is no connection made to the server.

// Create a handle to the Mongo database called 'myDB'.
var dbManager = new mongodb.Db('myDB', serv);

// NOW we initialize ALL 5 connections:
dbManager.open(function (error, db) {
  // Do something with the connection.

  // Make sure to call db.close() when ALL connections need
  // to be shut down.
  db.close();
});
*/

//Modificar muchos documentos a la vez y despues cerrar lal conexion a la base de datos
/*
db.open(function (err, db) {
  db.collection('foo', function (err, collection) {
    var cursor = collection.find({});
    cursor.count(function(err,count)){
      var savesPending = count;

      if(count == 0){
        db.close();
        return;
      }

      var saveFinished = function(){
        savesPending--;
        if(savesPending == 0){
          db.close();
        }
      }

      cursor.each(function (err, doc) {
        if (doc != null) {
          doc.newkey = 'foo'; // Make some changes
          db.save(doc, {safe:true}, saveFinished);
        }
      });
    })
  });
});

//Comunicacion ipc entre dos procesos node.js padre-hijo:

var cp = require('child_process');

var n = cp.fork(__dirname + '/sub.js');

n.on('message', function(m) {
  console.log('PARENT got message:', m);
});

n.send({ hello: 'world' });

And then the child script, 'sub.js' would might look like this:

process.on('message', function(m) {
  console.log('CHILD got message:', m);
});

process.send({ foo: 'bar' });

*/<commit_msg>minor bug fix<commit_after>var db = require("./db");
var api = require("./api");

/*
 * default handler for all events.
 */
function default_ev_handler(msg, rcpts){

	if( rcpts == undefined ){

		if( !msg.ev_data.doc || !msg.ev_data.doc.rcpts )
			return;

		rcpts = msg.ev_data.doc.rcpts;
		var	idx = rcpts.indexOf(msg.ev_data.uid);

		if( idx != -1)
			rcpts.splice(idx,1);

	}

	delete msg.ev_data.doc;

	for(i in rcpts){

		db.save("events", { ev_rcpt:rcpts[i], ev_msg:msg, _id: Math.random().toString(36).substring(2,10) }, function(err,val){

			if(err)
				throw err;
		});
		push( rcpts[i], msg );
	}
}

api.on("ev_create", function( msg ){

	if( !msg.ev_data.doc.rcpts )
		return;

	var rcpts = msg.ev_data.doc.rcpts,
		idx = rcpts.indexOf(msg.ev_data.doc.uid);

	if( idx != -1)
		rcpts.splice(idx,1);

	delete msg.ev_data.doc.rcpts;
	msg.ev_data.doc.wid = msg.ev_data.doc._id;
	delete msg.ev_data.doc._id;

	for(i in rcpts){

		db.save("events", { ev_rcpt:rcpts[i], ev_msg:msg, _id: Math.random().toString(36).substring(2,10) }, function(err,val){

			if(err)
				throw err;
		});
		push( rcpts[i], msg );
	}
});

/*
 * handler for ev_join event type.
 */
api.on("ev_join", function( msg, rcpts ){

	default_ev_handler( msg, rcpts );
});

/*
 * handler for ev_unjoin event type
 */
api.on("ev_unjoin", function( msg, rcpts ){

	default_ev_handler( msg, rcpts );
});

/*
 * handler for ev_add event type.
 */
api.on("ev_add", function( msg, rcpts ){

	default_ev_handler( msg, rcpts );
});

/*
 * handler for ev_rem event type.
 */
api.on("ev_rem", function( msg, rcpts ){

	default_ev_handler( msg, rcpts );
});

/*
 * handler for the ev_set event type.
 */
api.on("ev_set",function( msg, rcpts ){

	default_ev_handler( msg, rcpts );
});

/*
 * handler for the ev_incr event type.
 */
api.on("ev_incr",function( msg, rcpts ){

	default_ev_handler( msg, rcpts );
});

/*
 * handler for the ev_decr event type.
 */
api.on("ev_decr",function( msg, rcpts ){

	default_ev_handler( msg, rcpts );
});

/*
 * handler for the ev_push event type.
 */
api.on("ev_push",function( msg, rcpts ){

	default_ev_handler( msg, rcpts );
});

/*
 * handler for the ev_pop event type.
 */
api.on("ev_pop",function( msg, rcpts ){

	default_ev_handler( msg, rcpts );
});

/*
 * handler for the ev_pull event type.
 */
api.on("ev_pull",function( msg, rcpts ){

	default_ev_handler( msg, rcpts );
});

api.on("ev_ping", function( msg ){

	var rcpt = msg.ev_data.uid;
	delete msg.ev_data.uid;
	msg.ev_data.ts3 = new Date().getTime();
	push(rcpt, msg);

});

/*
 * subscribers list
 */
var subscribers = {};

var get_sub = exports.get_subscription = function ( uid ){

	if( uid == undefined )
		throw new Error("Invoke with a uid");

	return subscribers["" + uid];
}

/*
 * remove uid from the subscribers list.
 */
var rem_subscription = exports.rem_subscription  = function( uid ){

	if(uid == undefined)
		throw new Error("Must invoke with a uid");

	delete subscribers["" + uid];

}

/*
 * Add uid to the subscribers list.
 */
var add_subscription = exports.add_subscription = function( uid, http_resp ){

	subscribers["" + uid] = {http:http_resp};
}

/*
 * is subscriber uid connected?
 */
var is_subscribed = exports.is_subscribed = function( uid ){

	if(uid == undefined)
		throw new Error("Must invoke with a uid");

	return subscribers["" + uid] != undefined;
}

/*
 * push message to subscriber.
 */
function push( rcpt, msg ){

	if( is_subscribed(rcpt) ){

		var http_resp = subscribers["" + rcpt].http;
		http_resp.write( JSON.stringify(msg) + "\n" );
	}
}

/*
 * Recuperamos los eventos del usuario uid desde la marca temporal ts y se los enviamos.
 *
 */
function push_events( uid, tstamp ){

	//recuperamos los eventos de la base de datos
	db.selectObjectsWithOrder("events",{ev_rcpt:uid, "ev_msg.ev_tstamp":{$gt:tstamp}},{},{"ev_msg.ev_tstamp":1},function(err,results){

		for(i in results)
			push(uid, results[i].ev_msg);

	});

}

exports.api = {};
exports.api.listen = function( ev_type, ev_handler ){

	api.on(ev_type,function( msg, rcpts ){

		if( ev_handler == undefined )
			default_ev_handler( msg, rcpts );
		else
			ev_handler( msg, rcpts );
	});
}

exports.remote = {};
/*
 *
 * Llamada RPC para suscribirse a la cola de eventos.
 */
//TODO: refactorizar el codigo de suscripcion.
exports.remote.subscribe = function( http_resp, params ){

	if(params.uid == undefined){

		http_resp.end();
		return;
	}

	add_subscription(params.uid, http_resp);

	http_resp.on("close", function(){

		console.log('Client closed: [%d]', params.uid);
		rem_subscription(params.uid);
	});

	http_resp.connection.on("error", function(ex){

		http_resp.connection.destroy();

	});

	if( params.tstamp )
		push_events(params.uid, params.tstamp);

}

//Codigo de ejemplo de connection pooling del driver node.js native
/*
mongodb = require('mongodb');

// Define options. Note poolSize.
var serverOptions = {
  'auto_reconnect': true,
  'poolSize': 5
};

// Now create the server, passing our options.
var serv = new mongodb.Server('localhost', 27017, serverOptions);

// At this point, there is no connection made to the server.

// Create a handle to the Mongo database called 'myDB'.
var dbManager = new mongodb.Db('myDB', serv);

// NOW we initialize ALL 5 connections:
dbManager.open(function (error, db) {
  // Do something with the connection.

  // Make sure to call db.close() when ALL connections need
  // to be shut down.
  db.close();
});
*/

//Modificar muchos documentos a la vez y despues cerrar lal conexion a la base de datos
/*
db.open(function (err, db) {
  db.collection('foo', function (err, collection) {
    var cursor = collection.find({});
    cursor.count(function(err,count)){
      var savesPending = count;

      if(count == 0){
        db.close();
        return;
      }

      var saveFinished = function(){
        savesPending--;
        if(savesPending == 0){
          db.close();
        }
      }

      cursor.each(function (err, doc) {
        if (doc != null) {
          doc.newkey = 'foo'; // Make some changes
          db.save(doc, {safe:true}, saveFinished);
        }
      });
    })
  });
});

//Comunicacion ipc entre dos procesos node.js padre-hijo:

var cp = require('child_process');

var n = cp.fork(__dirname + '/sub.js');

n.on('message', function(m) {
  console.log('PARENT got message:', m);
});

n.send({ hello: 'world' });

And then the child script, 'sub.js' would might look like this:

process.on('message', function(m) {
  console.log('CHILD got message:', m);
});

process.send({ foo: 'bar' });

*/<|endoftext|>