JamesonNetworks/Nirodha

View on GitHub
bin/view.js

Summary

Maintainability
F
3 days
Test Coverage
var fs = require('fs');
var logger = require('jslogging');
var async = require('async');
var compressor = require('node-minify');

var utils = require('./utilities.js');
var testing = require('../testing.json');
var lm = require('./libraryManager.js');

var script = {
    js : {
        start: '<script type="text/javascript" src="',
        end: '"></script>\n'
    },
    css: {
        start: '<link rel="stylesheet" href="',
        end: '">\n'
    }
};

// Constants
var TEMPLATE_KEY = '{templates}';

exports = module.exports = new View();

/**
 * Expose `nirodhaManager`.
 */

exports.View = View;

function View() {
}

View.prototype.init = function(viewname) {
    this.name = viewname;
    logger.debug('Did all the right stuff exist?' + (fs.existsSync(viewname + '.json') && fs.existsSync(viewname + '.html')));
    if(fs.existsSync(viewname + '.json') && fs.existsSync(viewname + '.html')) {
        this.includes = JSON.parse(fs.readFileSync(viewname + '.json', 'utf-8'));
        this.pageText = fs.readFileSync(viewname + '.html', 'utf-8');
    }
    
};

View.prototype.create = function(callback) {
    var viewname = this.name;
    if(typeof(this.name) === 'undefined' || this.name === '') {
        throw new Error('No view name, did you call view.init with a name?');
    }
    var nirodhaPath = utils.getNirodhaPath();
    async.series({
        createDefaultView: function(cb) {
            utils.copyFile(nirodhaPath + 'tmpl/defaultView.html', viewname + '.html', function(err) {
                if(err) {
                    cb(err);
                }
                else {
                    logger.log('Successfully created ' + viewname + '.html');
                    cb(null, true);
                }
            });
        },
        createDefaultJavascript: function(cb) {
            utils.copyFile(nirodhaPath + 'tmpl/defaultView.js', 'custom/js/' + viewname + '.js', function(err) {
                if(err) {
                    cb(err);
                }
                else {
                    logger.log('Successfully created ' + viewname + '.js');
                    cb(null, true);
                }
            });
        },
        createDefaultCSS: function(cb) {
            utils.copyFile(nirodhaPath + 'tmpl/defaultView.css', 'custom/css/' + viewname + '.css', function(err) {
                if(err) {
                    cb(err);
                }
                else {
                    logger.log('Successfully created ' + viewname + '.css');
                    cb(null, true);
                }
            });
        },
        createDefaultJSON: function(cb) {
            // Copy in the default json accessories
            utils.copyFile(nirodhaPath + 'tmpl/defaultView.json', viewname + '.json', function(err) {
                if(err) {
                    cb(err);
                }
                else {
                    logger.log('Successfully created ' + viewname + '.json');
                    cb(null, true);
                }
            });
        },
        createDefaultTemplates: function(cb) {
            // Copy in the default json accessories
            utils.copyFile(nirodhaPath + 'tmpl/defaultView_templates.html', 'custom/templates/' + viewname + '_templates.html', function(err) {
                if(err) {
                    cb(err);
                }
                else {
                    logger.log('Successfully created ' + viewname + '_templates.html');
                    cb(null, true);
                }
            });
        }
    }, function(err, results) {
        if(err) {
            logger.warn('An error occured copying the default view files: ' + err + ' ' + JSON.stringify(results));
            logger.debug('dir: ' + process.cwd());
            logger.warn(JSON.stringify(err));
            callback(err);
        }
        else {
            this.includes = JSON.parse(fs.readFileSync(viewname + '.json', 'utf-8'));
            this.pageText = fs.readFileSync(viewname + '.html', 'utf-8');
            if(typeof(callback) !== 'undefined') {
                callback(null, testing.view.viewcreated);                
            }
        }
    });
};

/**
 *  These are all for deploying the view
 */

function getLibraries(cwd, type, include, callback) {
    
    process.chdir(cwd);
    logger.debug('Entering loop to add ' + type + ' libraries');
    var files = include.libs[type];
    var text = '';
    logger.debug('JS Library lengths: ' + files.length);

    if(files.length === 0) {
        callback(null, '');
    }
    else {
        
        for(var i = 0; i < files.length; i++) {

            logger.debug('Inserting the following ' + type + ' library: ' + files[i]);
            text = text + lm.getLibraryContentsSync(files[i]) + '\n';
            logger.debug('Text is ' + text);
            if(i === files.length-1) {
                logger.debug('Got into the end...' + text);
                callback(null, text);
            }
        }
    }
}

View.prototype.getLibraries = function(cwd, type, include, callback) {
    return getLibraries(cwd, type, include, callback);
};

View.prototype.deploy = function(minify, callback) {
    var viewHandle = this;
    async.series({
        GenerateJS: function(cb) {
            viewHandle.generateJavascript(minify, cb);
        },
        GenerateCSS: function(cb) {
            viewHandle.generateCSS(minify, cb);
        },
        GenerateHTML: function(cb) {
            viewHandle.renderForDeploy(cb);
        },
        CopyStaticFiles: function(cb) {
            viewHandle.copyStaticFiles(cb);
        }
    }, function(err, result) {
        callback(err, result);
    });
};

View.prototype.generateSupportFilesForDeploy = function(type, minify, callback) {
    
    var viewHandle = this;
    if(typeof(this.includes) === 'undefined') {
        throw new Error('Includes was undefined');
    }
    var includes = this.includes;
    async.series({
        BuildText: function(cb) {
            var getLibraryCallback = function(err, text) {
                var finalText = '';
                if(err) {
                    logger.warn(err);
                }
                logger.debug('Text is ' + text);
                finalText += text;
                // Minify the files
                logger.debug('Current working directory is ' + process.cwd());
                fs.writeFileSync('./deploy/' + type + '/' + viewHandle.name + '-' + includeTitle + '.' + type + '.temp', finalText);
                if(cnt === includes.length-1) {
                    logger.debug('Writing as finalText: ' + finalText);
                    cb();
                }
            };

            for(var cnt = 0; cnt < includes.length; cnt++) {
                var include = includes[cnt];
                // Make fs friendly title
                var includeTitle = include.title.substring(1, include.title.length-1);
                logger.debug('Setting title to ' + includeTitle);
                viewHandle.getLibraries(process.cwd(), type, include, getLibraryCallback);
            }
        },
        MinifyFile: function(cb) {
            var include;
            var includeTitle;

            var inPath;
            var outPath;
            if(minify) {
                var minifier;
                if(type === 'js') {
                    minifier = 'gcc';
                }
                else if(type === 'css') {
                    minifier = 'yui-css';
                }

                for(var i = 0; i < includes.length; i++) {
                    include = includes[i];
                    includeTitle = include.title.substring(1, include.title.length-1);

                    inPath = './deploy/' + type + '/' + viewHandle.name + '-' + includeTitle + '.' + type + '.temp';
                    outPath = './deploy/' + type + '/' + viewHandle.name + '-' + includeTitle + '.' + type;

                    try {
                        new compressor.minify({
                            type: minifier,
                            fileIn: inPath,
                            fileOut: outPath
                        });
                    }
                    catch (e) {
                        logger.warn('Error occured in minification: ' + e);
                    }
                }
            }
            else {
                for(var k = 0; k < includes.length; k++) {
                    include = includes[k];
                    includeTitle = include.title.substring(1, include.title.length-1);

                    inPath = './deploy/' + type + '/' + viewHandle.name + '-' + includeTitle + '.' + type + '.temp';
                    outPath = './deploy/' + type + '/' + viewHandle.name + '-' + includeTitle + '.' + type;

                    fs.writeFileSync(outPath, fs.readFileSync(inPath), 'utf-8');
                    fs.unlinkSync(inPath);
                }
            }

            cb(null, 'Minification Complete');
        }
    }, function(err, result) {
        callback(err, result);
    });
};

View.prototype.generateJavascript = function(minify, callback) {
    this.generateSupportFilesForDeploy('js', minify, callback);
};

View.prototype.generateCSS = function(minify, callback) {
    this.generateSupportFilesForDeploy('css', minify, callback);
};

function addInTemplates(pageText, templates) {
    var start = pageText.indexOf(TEMPLATE_KEY);
    var end  = pageText.indexOf(TEMPLATE_KEY) + TEMPLATE_KEY.length;
    var firstpart = pageText.substring(0, start);
    var lastpart = pageText.substring(end, pageText.length);
    // logger.log('template text: ' + template_text);
    return(firstpart + templates + lastpart); 
}

View.prototype.renderForDeploy = function(callback) {
    var includes = this.includes;
    var pageText = this.pageText;

    logger.debug('view is : ' + this.name);
    var template_filename = './custom/templates/' + this.name + '_templates.html';
    logger.debug('Adding the templates html to the core html file...');
    logger.debug('Loading the following file: ' + template_filename);
    var template_text = fs.readFileSync(template_filename).toString();

    pageText = addInTemplates(pageText, template_text);

    logger.debug('Writing final html file...');
    for(var i = 0; i < includes.length; i++) {
        var libobject = includes[i];
        var title = libobject.title.substring(1, libobject.title.length-1);
        var firstPartOfPage = pageText.substring(0, pageText.indexOf(libobject.title));
        var lastPartOfPage = pageText.substring(pageText.indexOf(libobject.title) + libobject.title.length, pageText.length);
        var jsincludes = (script.js.start + '/js/' + this.name  + '-' + title + '.js' + script.js.end);
        var cssincludes = (script.css.start + '/css/' + this.name + '-' + title + '.css' + script.css.end);
        pageText = firstPartOfPage + jsincludes + cssincludes + lastPartOfPage;
    }

    fs.writeFileSync('./deploy/' + this.name + '.html', pageText);
    callback(null, 'HTML Successfully written');
};

View.prototype.copyStaticFiles = function(callback) {
    var staticDirectory = 'custom/static';
    utils.walkSync(staticDirectory, function(dir, directories, fileNames) {
        logger.debug('Directory: ' + dir);
        logger.debug('FileNames: ' + JSON.stringify(fileNames));
        if(typeof(fileNames) !== 'undefined') {
            for(var i = 0; i < fileNames.length; i++) {
                var writeDir;
                if(dir === staticDirectory) {
                    writeDir = 'deploy/';
                }
                else {
                    logger.log('Directory to write to: ' + dir.substring(staticDirectory.length, dir.length), 7);
                    writeDir =  'deploy' + dir.substring(staticDirectory.length, dir.length) + '/';
                    var folderExists = fs.existsSync(writeDir);
                    if(!folderExists) {
                        fs.mkdirSync(writeDir);
                    }
                }
                logger.log(writeDir + fileNames[i], 7);
                logger.log('FileName: ' + JSON.stringify(fileNames[i]), 7);
                var data = fs.readFileSync(dir + '/' + fileNames[i]);
                fs.writeFileSync(writeDir + fileNames[i], data);
            }
        }
        //logger.log('Loading file ' + one + '/' + three, 7);
        callback(null, 'Static files written');
    });
};

/**
 *  These are all for serving the view
 */
function generateIncludes(libobject, type) {
    var files = libobject.libs[type];

    logger.log('Generating includes...', 7);
    logger.log('Library lengths: ' + files.length, 7);

    // Insert references to the new js library files
    var includes = "";
    if(files.length === 0) {
        return;
    }
    else {
        for(var i = 0; i < files.length; i++) {
            logger.log('Inserting the following ' + type + ' library: ' + files[i], 7);
            includes += (script[type].start + files[i] + script[type].end);

            if(i === files.length-1) {
                return includes;
            }
        }
    }
}

View.prototype.getIncludes = function() {
    return JSON.parse(JSON.stringify(this.includes));
};

View.prototype.generateIncludesAsHTMLInserts = function() {
    var results = [];

    if(typeof(this.includes) === 'undefined') {
        throw new Error('Did you run lm init?');
    }

    for(var i = 0; i < this.includes.length; i++) {
        var libobject = {};
        var currentInclude = this.includes[i]; 
        libobject.title = {};
        logger.debug('Current Includes: ' + JSON.stringify(this.includes));
        libobject.css = generateIncludes(currentInclude, 'css');
        libobject.js = generateIncludes(currentInclude, 'js');
        results.push(libobject);
    }

    return results;
};

View.prototype.render = function() {
    var includes = this.generateIncludesAsHTMLInserts();
    var pageText = this.pageText;

    logger.debug('view is : ' + this.name);
    var template_filename = './custom/templates/' + this.name + '_templates.html';
    logger.debug('Adding the templates html to the core html file...');
    logger.debug('Loading the following file: ' + template_filename);
    var template_text = fs.readFileSync(template_filename).toString();

    var start = pageText.indexOf(TEMPLATE_KEY);
    var end  = pageText.indexOf(TEMPLATE_KEY) + TEMPLATE_KEY.length;
    var firstpart = pageText.substring(0, start);
    var lastpart = pageText.substring(end, pageText.length);
    // logger.log('template text: ' + template_text);
    pageText = firstpart + template_text + lastpart; 
    logger.debug('Pagetext is ' + pageText);
    logger.debug('Writing final html file...');

    for(var i = 0; i < includes.length; i++) {
        var libobject = includes[i];

        start = pageText.indexOf(libobject.title);
        end = start + libobject.title.length;
        firstpart = pageText.substring(0, start);
        lastpart = pageText.substring(end, pageText.length);

        pageText = firstpart + libobject.js + libobject.css + lastpart;
    }
    return pageText;
};