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

/**
 * # nodegame-server make script
 *
 */

if (!process.argv || !process.argv.length) {
    console.log('No input argument. Aborting');
    return;
}

/**
 * Module dependencies.
 */

var program = require('commander'),
smoosh = require('smoosh'),
os = require('os'),
fs = require('fs'),
util = require('util'),
exec = require('child_process').exec,
path = require('path'),
J = require('JSUS').JSUS;

var pkg = require('../package.json'),
version = pkg.version;

var ngcDir = J.resolveModuleDir('nodegame-client');
var JSUSDir = J.resolveModuleDir('JSUS');
var NDDBDir = J.resolveModuleDir('NDDB');
var shelfDir = J.resolveModuleDir('shelf.js');
var ngwindowDir = J.resolveModuleDir('nodegame-window');
var ngwidgetsDir = J.resolveModuleDir('nodegame-widgets');

var build_client = require(ngcDir + 'bin/build.js').build;
var build_client_support = require(ngcDir + 'bin/build.js').build_support;
var build_JSUS = require(JSUSDir + 'bin/build.js').build;
var build_NDDB = require(NDDBDir + 'bin/build.js').build;
var build_shelf = require(shelfDir + 'bin/build.js').build;
var build_ngwindow = require(ngwindowDir + 'bin/build.js').build;
var build_ngwidgets = require(ngwidgetsDir + 'bin/build.js').build;

var rootDir = path.resolve(__dirname, '..');
var buildDir = rootDir + '/public/javascripts/';
var cssDir = rootDir + '/public/stylesheets/';
var libDir = rootDir + '/lib/';
var confDir = rootDir + '/conf/';

var buildDir_client = ngcDir + 'build/';
var buildDir_JSUS = JSUSDir + 'build/';
var buildDir_NDDB = NDDBDir + 'build/';
var buildDir_shelf = shelfDir + 'build/';
var buildDir_ngWindow = ngwindowDir + 'build/';
var buildDir_ngWidgets = ngwidgetsDir + 'build/';

program
    .version(version);

program
    .command('clean')
    .description('Removes all files from build folder')
    .action(function(){
        J.cleandDir(buildDir);
    });

program
    .command('build-client [options]')
    .description('Creates a nodegame-client custom build')
// TODO: keep options update with client, or find a way to use the options
// defined in the client
    .option('-B, --bare', 'bare naked nodegame-client (no dependencies)')
    .option('-J, --JSUS', 'with JSUS')
    .option('-N, --NDDB', 'with NDDB')
    .option('-W, --window', 'with nodeGame-window')
    .option('-w, --widgets', 'with nodeGame-widgets')
    .option('-d, --addons', 'with nodeGame-client addons')
    .option('-s, --shelf', 'with Shelf.js')
    .option('-e, --es5', 'with support for old browsers')
    .option('-a, --all', 'full build of nodeGame-client')
    .option('-C, --clean', 'clean build directory')
    .option('-A, --analyse', 'analyse build')
    .option('-o, --output <file>', 'output file (without .js)')
    .action(function(env, options) {
        if (options.output && path.extname(options.output) === '.js') {
            options.output = path.basename(options.output, '.js');
        }
        options.clean = true;
        build_client(options);
        J.copyFromDir(buildDir_client, buildDir, '.js');
    });

program
    .command('multibuild')
    .description('Builds a set of javascript libraries for nodeGame')
    .action(function(){
        console.log('Multi-build for nodegame-server v.' + version);

        // nodegame-client
        build_client({
            clean: true,
            all: true,
            output: "nodegame-full",
        });
        build_client({
            bare: true,
            output: "nodegame-bare",
        });
        build_client({
            output: "nodegame",
        });
        //              build_client_support({
        //                      all: true,
        //              });

        J.copyFromDir(buildDir_client, buildDir, '.js');

        // JSUS
        build_JSUS({
            lib: ['obj','array','eval','parse','random','time','dom'],
            clean: true,
        });

        J.copyFromDir(buildDir_JSUS, buildDir, '.js');

        // NDDB
        build_NDDB({
            clean: true,
            all: true,
            output: "nddb-full",
        });
        build_NDDB({
            bare: true,
            output: "nddb-bare",
        });
        build_NDDB({
            JSUS: true,
            output: "nddb",
        });

        J.copyFromDir(buildDir_NDDB, buildDir, '.js');

        // Shelf.js
        build_shelf({
            clean: true,
            all: true,
            output: "shelf-full",
        });
        build_shelf({
            lib: ['amplify','cookie'],
            output: "shelf-browser",
        });
        build_shelf({
            lib: ['amplify'],
            output: "shelf-amplify",
        });
        build_shelf({
            lib: ['cookie'],
            output: "shelf-cookie",
        });
        build_shelf({
            lib: ['fs'],
            output: "shelf-fs",
        });

        J.copyFromDir(buildDir_shelf, buildDir, '.js');

        // ng-widgets
        build_ngwidgets({
            all: true,
            clean: true,
        });

        J.copyFromDir(buildDir_ngWidgets, buildDir, '.js');

        // ng-window
        build_ngwindow({
            all: true,
            clean: true,
        });

        J.copyFromDir(buildDir_ngWindow, buildDir, '.js');

        console.log('All javascript files built and copied to public/javascript/');
    });

program
    .command('build-css')
    .description('Copies all stylesheets files  into public/stylesheets/ and builds nodegame.css')
    .option('-o, --output <file>', 'output file (without .css)')
    .option('-A, --analyse', 'analyse build')
    .option('-C, --clean', 'clean CSS directory')
    .action(function(options) {
        var config, runIt, out, smooshed;

        // Copy CSS files from submodules.
        copyCSS();

        // Set output name.
        out = options.output || "nodegame";
        if (path.extname(out) === '.css') {
	    out = path.basename(out, '.css');
        }

        // Configurations for file smooshing.
        config = {
	    // VERSION: version,

	    // Use JSHINT to spot code irregularities.
	    JSHINT_OPTS: {
	        boss: true,
	        forin: true,
	        browser: true,
	    },

	    CSS: {
                // Need the extra slash.
	        DIST_DIR: '/' + cssDir
	    }
        };

        config.CSS[out] = [
            cssDir + 'window.css',
            cssDir + 'widgets.css'
        ];

	smooshed = smoosh.config(config);

	// Removes all files from the CSS folder.
	if (options.clean) {
	    smooshed.clean();
	}

	// Builds both uncompressed and compressed files.
	smooshed.build();

    	if (options.analyse) {
    	    smooshed.run(); // runs jshint on full build
    	    smooshed.analyze(); // analyzes everything
    	}

        console.log('All CSS files copied, and ' + out + '.css created.');

    });

program
    .command('refresh')
    .option('-a, --all', 'copy all js and css files')
    .option('-j, --js-only', 'copy only js files')
    .option('-c, --css-only', 'copy only css files')
    .description('Copies build files (.js) and style files (.css) from submodules into public/')
    .action(function(options) {
        if (!options.all && !options.js && !options.css) {
            options.all = true;
        }

        if (options.all || options.js) {
            try {
                J.copyFromDir(buildDir_client, buildDir, '.js');
            }
            catch(e) {
                console.log('make refresh: could not find nodegame-client directory.');
            }
            try {
                J.copyFromDir(buildDir_ngWindow, buildDir, '.js');
            }
            catch(e) {
                console.log('make refresh: could not find nodegame-window directory.');
            }
            try {
                J.copyFromDir(buildDir_ngWidgets, buildDir, '.js');
            }
            catch(e) {
                console.log('make refresh: could not find nodegame-widgets directory.');
            }
            try {
                J.copyFromDir(buildDir_JSUS, buildDir, '.js');
            }
            catch(e) {
                console.log('make refresh: could not find JSUS directory.');
            }
            try {
                J.copyFromDir(buildDir_NDDB, buildDir, '.js');
            }
            catch(e) {
                console.log('make refresh: could not find NDDB directory.');
            }
            try {
                J.copyFromDir(buildDir_shelf, buildDir, '.js');
            }
            catch(e) {
                console.log('make refresh: could not find Shelf.js directory.');
            }
        }

        if (options.all || options.css) {
            copyCSS();
        }

        console.log('All files copied to public/');
    });

program
    .command('doc')
    .description('Builds documentation files')
    .action(function(){
        console.log('Building documentation for nodegame-server v.' + version);
        // http://nodejs.org/api.html#_child_processes
        var dockerDir = J.resolveModuleDir('docker');
        var command = dockerDir + 'docker -i ' + rootDir + ' index.js lib/ -o ' + rootDir + '/docs/';
        var child = exec(command, function (error, stdout, stderr) {
            util.print(stdout);
            util.print(stderr);
            if (error !== null) {
                console.log('build error: ' + error);
            }
        });
    });

program
    .command('sync <path> [options]')
    .description('Sync the folder with the specified target directory (must exists)')
    .option('-a, --all', 'sync /lib and /conf folders (default)')
    .option('-l, --lib', 'sync the /lib folder')
    .option('-c, --conf', 'sync the /conf folder')
    .action(function(path, options) {

        if ('undefined' === typeof options) {
            options = {};
            options.all = true;
        }

        if (options.all) {
            copyDirTo(confDir, path + '/conf/');
            copyDirTo(libDir, path + '/lib/');
        }

        else if (options.conf) {
            copyDirTo(confDir, path);
        }

        else if (options.lib) {
            copyDirTo(libDir, path);
        }

        console.log('Done.');

    });

function copyDirTo(inputDir, targetDir) {

    if (!targetDir) {
        console.log('You must specify a target directory for the \'sync\' command');
        return;
    }

    targetDir = path.resolve(targetDir);

    if (!fs.existsSync(targetDir)) {
        console.log(targetDir + ' does not exist');
        return false;
    }

    var stats = fs.lstatSync(targetDir);
    if (!stats.isDirectory()) {
        console.log(targetDir + ' is not a directory');
        return false;
    }

    targetDir = targetDir + '/';

    console.log('nodegame-server v.' + version + ': syncing ' + inputDir + ' with ' + targetDir);

    J.copyDirSyncRecursive(inputDir, targetDir);
}

function copyCSS(options) {
    try {
        J.copyFromDir(ngwindowDir + 'css/', cssDir, '.css');
    }
    catch(e) {
        console.log('make refresh: could not find nodegame-window css directory.');
    }
    try {
        J.copyFromDir(ngwidgetsDir + 'css/', cssDir, '.css');
    }
    catch(e) {
        console.log('make refresh: could not find nodegame-window css directory.');
    }
}

//Parsing options
program.parse(process.argv);
<commit_msg>make can build CSS correctly<commit_after>#!/usr/bin/env node

/**
 * # nodegame-server make script
 *
 */

if (!process.argv || !process.argv.length) {
    console.log('No input argument. Aborting');
    return;
}

/**
 * Module dependencies.
 */

var program = require('commander'),
smoosh = require('smoosh'),
os = require('os'),
fs = require('fs'),
util = require('util'),
exec = require('child_process').exec,
path = require('path'),
J = require('JSUS').JSUS;

var pkg = require('../package.json'),
version = pkg.version;

var ngcDir = J.resolveModuleDir('nodegame-client');
var JSUSDir = J.resolveModuleDir('JSUS');
var NDDBDir = J.resolveModuleDir('NDDB');
var shelfDir = J.resolveModuleDir('shelf.js');
var ngwindowDir = J.resolveModuleDir('nodegame-window');
var ngwidgetsDir = J.resolveModuleDir('nodegame-widgets');

var build_client = require(ngcDir + 'bin/build.js').build;
var build_client_support = require(ngcDir + 'bin/build.js').build_support;
var build_JSUS = require(JSUSDir + 'bin/build.js').build;
var build_NDDB = require(NDDBDir + 'bin/build.js').build;
var build_shelf = require(shelfDir + 'bin/build.js').build;
var build_ngwindow = require(ngwindowDir + 'bin/build.js').build;
var build_ngwidgets = require(ngwidgetsDir + 'bin/build.js').build;

var rootDir = path.resolve(__dirname, '..');
var buildDir = rootDir + '/public/javascripts/';
var cssDir = rootDir + '/public/stylesheets/';
var libDir = rootDir + '/lib/';
var confDir = rootDir + '/conf/';

var buildDir_client = ngcDir + 'build/';
var buildDir_JSUS = JSUSDir + 'build/';
var buildDir_NDDB = NDDBDir + 'build/';
var buildDir_shelf = shelfDir + 'build/';
var buildDir_ngWindow = ngwindowDir + 'build/';
var buildDir_ngWidgets = ngwidgetsDir + 'build/';

program
    .version(version);

program
    .command('clean')
    .description('Removes all files from build folder')
    .action(function(){
        J.cleandDir(buildDir);
    });

program
    .command('build-client [options]')
    .description('Creates a nodegame-client custom build')
// TODO: keep options update with client, or find a way to use the options
// defined in the client
    .option('-B, --bare', 'bare naked nodegame-client (no dependencies)')
    .option('-J, --JSUS', 'with JSUS')
    .option('-N, --NDDB', 'with NDDB')
    .option('-W, --window', 'with nodeGame-window')
    .option('-w, --widgets', 'with nodeGame-widgets')
    .option('-d, --addons', 'with nodeGame-client addons')
    .option('-s, --shelf', 'with Shelf.js')
    .option('-e, --es5', 'with support for old browsers')
    .option('-a, --all', 'full build of nodeGame-client')
    .option('-C, --clean', 'clean build directory')
    .option('-A, --analyse', 'analyse build')
    .option('-o, --output <file>', 'output file (without .js)')
    .action(function(env, options) {
        if (options.output && path.extname(options.output) === '.js') {
            options.output = path.basename(options.output, '.js');
        }
        options.clean = true;
        build_client(options);
        J.copyFromDir(buildDir_client, buildDir, '.js');
    });

program
    .command('multibuild')
    .description('Builds a set of javascript libraries for nodeGame')
    .action(function(){
        console.log('Multi-build for nodegame-server v.' + version);

        // nodegame-client
        build_client({
            clean: true,
            all: true,
            output: "nodegame-full",
        });
        build_client({
            bare: true,
            output: "nodegame-bare",
        });
        build_client({
            output: "nodegame",
        });
        //              build_client_support({
        //                      all: true,
        //              });

        J.copyFromDir(buildDir_client, buildDir, '.js');

        // JSUS
        build_JSUS({
            lib: ['obj','array','eval','parse','random','time','dom'],
            clean: true,
        });

        J.copyFromDir(buildDir_JSUS, buildDir, '.js');

        // NDDB
        build_NDDB({
            clean: true,
            all: true,
            output: "nddb-full",
        });
        build_NDDB({
            bare: true,
            output: "nddb-bare",
        });
        build_NDDB({
            JSUS: true,
            output: "nddb",
        });

        J.copyFromDir(buildDir_NDDB, buildDir, '.js');

        // Shelf.js
        build_shelf({
            clean: true,
            all: true,
            output: "shelf-full",
        });
        build_shelf({
            lib: ['amplify','cookie'],
            output: "shelf-browser",
        });
        build_shelf({
            lib: ['amplify'],
            output: "shelf-amplify",
        });
        build_shelf({
            lib: ['cookie'],
            output: "shelf-cookie",
        });
        build_shelf({
            lib: ['fs'],
            output: "shelf-fs",
        });

        J.copyFromDir(buildDir_shelf, buildDir, '.js');

        // ng-widgets
        build_ngwidgets({
            all: true,
            clean: true,
        });

        J.copyFromDir(buildDir_ngWidgets, buildDir, '.js');

        // ng-window
        build_ngwindow({
            all: true,
            clean: true,
        });

        J.copyFromDir(buildDir_ngWindow, buildDir, '.js');

        console.log('All javascript files built and copied to public/javascript/');
    });

program
    .command('build-css')
    .description('Copies all stylesheets files  into public/stylesheets/ and builds nodegame.css')
    .option('-o, --output <file>', 'output file (without .css)')
    .option('-A, --analyse', 'analyse build')
    .option('-C, --clean', 'clean CSS directory')
    .action(function(options) {
        var config, runIt, out, smooshed;

        function copyAndBuild() {
	    // Copy CSS files from submodules.
            copyCSS(null, function() {
                // Set output name.
                out = options.output || "nodegame";
                if (path.extname(out) === '.css') {
	            out = path.basename(out, '.css');
                }

                // Configurations for file smooshing.
                config = {
	            // VERSION: version,

	            // Use JSHINT to spot code irregularities.
	            JSHINT_OPTS: {
	                boss: true,
	                forin: true,
	                browser: true,
	            },

	            CSS: {
                        // Need the extra slash.
	                DIST_DIR: '/' + cssDir
	            }
                };

                config.CSS[out] = [
                    cssDir + 'window.css',
                    cssDir + 'widgets.css'
                ];
	        smooshed = smoosh.config(config);

	        // Builds both uncompressed and compressed files.
	        smooshed.build();

    	        if (options.analyse) {
    	            smooshed.run(); // runs jshint on full build
    	            smooshed.analyze(); // analyzes everything
    	        }

                console.log('All CSS files copied, and ' + out + '.css created.');
            });
        }

	// Removes all files from the CSS folder.
	if (options.clean) {
	    J.cleanDir(cssDir, '.css', copyAndBuild);
        }
        else {
            copyAndBuild();
        }

    });

program
    .command('refresh')
    .option('-a, --all', 'copy all js and css files')
    .option('-j, --js-only', 'copy only js files')
    .option('-c, --css-only', 'copy only css files')
    .description('Copies build files (.js) and style files (.css) from submodules into public/')
    .action(function(options) {
        if (!options.all && !options.js && !options.css) {
            options.all = true;
        }

        if (options.all || options.js) {
            try {
                J.copyFromDir(buildDir_client, buildDir, '.js');
            }
            catch(e) {
                console.log('make refresh: could not find nodegame-client directory.');
            }
            try {
                J.copyFromDir(buildDir_ngWindow, buildDir, '.js');
            }
            catch(e) {
                console.log('make refresh: could not find nodegame-window directory.');
            }
            try {
                J.copyFromDir(buildDir_ngWidgets, buildDir, '.js');
            }
            catch(e) {
                console.log('make refresh: could not find nodegame-widgets directory.');
            }
            try {
                J.copyFromDir(buildDir_JSUS, buildDir, '.js');
            }
            catch(e) {
                console.log('make refresh: could not find JSUS directory.');
            }
            try {
                J.copyFromDir(buildDir_NDDB, buildDir, '.js');
            }
            catch(e) {
                console.log('make refresh: could not find NDDB directory.');
            }
            try {
                J.copyFromDir(buildDir_shelf, buildDir, '.js');
            }
            catch(e) {
                console.log('make refresh: could not find Shelf.js directory.');
            }
        }

        if (options.all || options.css) {
            copyCSS();
        }

        console.log('All files copied to public/');
    });

program
    .command('doc')
    .description('Builds documentation files')
    .action(function(){
        console.log('Building documentation for nodegame-server v.' + version);
        // http://nodejs.org/api.html#_child_processes
        var dockerDir = J.resolveModuleDir('docker');
        var command = dockerDir + 'docker -i ' + rootDir + ' index.js lib/ -o ' + rootDir + '/docs/';
        var child = exec(command, function (error, stdout, stderr) {
            util.print(stdout);
            util.print(stderr);
            if (error !== null) {
                console.log('build error: ' + error);
            }
        });
    });

program
    .command('sync <path> [options]')
    .description('Sync the folder with the specified target directory (must exists)')
    .option('-a, --all', 'sync /lib and /conf folders (default)')
    .option('-l, --lib', 'sync the /lib folder')
    .option('-c, --conf', 'sync the /conf folder')
    .action(function(path, options) {

        if ('undefined' === typeof options) {
            options = {};
            options.all = true;
        }

        if (options.all) {
            copyDirTo(confDir, path + '/conf/');
            copyDirTo(libDir, path + '/lib/');
        }

        else if (options.conf) {
            copyDirTo(confDir, path);
        }

        else if (options.lib) {
            copyDirTo(libDir, path);
        }

        console.log('Done.');

    });

function copyDirTo(inputDir, targetDir) {

    if (!targetDir) {
        console.log('You must specify a target directory for the \'sync\' command');
        return;
    }

    targetDir = path.resolve(targetDir);

    if (!fs.existsSync(targetDir)) {
        console.log(targetDir + ' does not exist');
        return false;
    }

    var stats = fs.lstatSync(targetDir);
    if (!stats.isDirectory()) {
        console.log(targetDir + ' is not a directory');
        return false;
    }

    targetDir = targetDir + '/';

    console.log('nodegame-server v.' + version + ': syncing ' + inputDir + ' with ' + targetDir);

    J.copyDirSyncRecursive(inputDir, targetDir);
}

function copyCSS(options, cb) {
    var asyncQueue = new J.getQueue();
    try {
        asyncQueue.add('window');
        J.copyFromDir(ngwindowDir + 'css/', cssDir, '.css', function() {
            asyncQueue.remove('window');
        });
    }
    catch(e) {
        console.log('make refresh: could not find nodegame-window css directory.');
        asyncQueue.remove('window');
    }
    try {
        asyncQueue.add('widgets');
        J.copyFromDir(ngwidgetsDir + 'css/', cssDir, '.css', function() {
            asyncQueue.remove('widgets');
        });
    }
    catch(e) {
        console.log('make refresh: could not find nodegame-window css directory.');
        asyncQueue.remove('widgets');
    }

    if (cb) {
        asyncQueue.onReady(cb);
    }
}

//Parsing options
program.parse(process.argv);
<|endoftext|>


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

var path  = require('path');
var fs    = require('fs');
var ytdl  = require('..');
var cliff = require('cliff');
require('colors');

var info = JSON.parse(
    fs.readFileSync(path.resolve(__dirname, '..', 'package.json')));

var opts = require('nomnom')
  .option('version', {
    abbr: 'v'
  , flag: true
  , callback: function() {
      console.log('v' + info.version);
      process.exit();
    }
  , help: 'Print program version.'
  })
  .option('url', {
    position: 0
  , required: true
  , help: 'URL to the video.'
  })
  .option('quality', {
    abbr: 'q'
  , metavar: 'ITAG'
  , help: 'Video quality to download. Default: `highest`'
  })
  .option('start', {
    abbr: 's'
  , metavar: 'TIME'
  , help: 'Where to begin the video. ie 1m3s, 45s, 2300.'
  })
  .option('output', {
    abbr: 'o'
  , metavar: 'FILE'
  , help: 'Where to save the file. Default: stdout'
  })
  .option('filterContainer', {
    full: 'filter-container'
  , metavar: 'REGEXP'
  , help: 'Filter in format container.'
  })
  .option('unfilterContainer', {
    full: 'unfilter-container'
  , metavar: 'REGEXP'
  , help: 'Filter out format container.'
  })
  .option('filterResolution', {
    full: 'filter-resolution'
  , metavar: 'REGEXP'
  , help: 'Filter in format resolution.'
  })
  .option('unfilterResolution', {
    full: 'unfilter-resolution'
  , metavar: 'REGEXP'
  , help: 'Filter out format resolution.'
  })
  .option('filterEncoding', {
    full: 'filter-encoding'
  , metavar: 'REGEXP'
  , help: 'Filter in format encoding.'
  })
  .option('unfilterEncoding', {
    full: 'unfilter-encoding'
  , metavar: 'REGEXP'
  , help: 'Filter out format encoding.'
  })
  .option('info', {
    abbr: 'i'
  , flag: true
  , help: 'Print only video information without downloading'
  })
  .script('ytdl')
  .colors()
  .parse()
  ;

/**
 * Converts seconds into human readable time hh:mm:ss
 *
 * @param {Number} seconds
 * @return {String}
 */
function toHumanTime(seconds) {
  var h = Math.floor(seconds / 3600);
  if (h < 10) { h = '0' + h; }
  var m = Math.floor(seconds / 60) % 60;
  if (m < 10) { m = '0' + m; }
  var s = seconds % 60;
  if (s < 10) { s = '0' + s; }
  return h + ':' + m + ':' + s;
}

/**
 * Prints basic video information.
 *
 * @param {Object} info
 */
function printVideoInfo(info) {
  console.log();
  console.log('title: '.grey.bold + info.title);
  console.log('author: '.grey.bold + info.author);
  var rating = typeof info.avg_rating === 'number' ?
    info.avg_rating.toFixed(1) : info.avg_rating;
  console.log('average rating: '.grey.bold + rating);
  console.log('view count: '.grey.bold + info.view_count);
  console.log('length: '.grey.bold + toHumanTime(info.length_seconds));
}

if (opts.info) {
  ytdl.getInfo(opts.url, function(err, info) {
    if (err) {
      console.error(err.message);
      process.exit(1);
      return;
    }

    printVideoInfo(info);

    console.log('formats:'.grey.bold);
    var cols = ['itag', 'container', 'resolution', 'encoding'];
    var colors = ['green', 'blue', 'green', 'blue'];
    console.log(cliff.stringifyObjectRows(info.formats, cols, colors));
    ytdl.cache.die();
  });
  return;
}

var output = opts.output;
var writeStream = output ? fs.createWriteStream(output) : process.stdout;

var ytdlOptions = {};
ytdlOptions.quality = opts.quality;
ytdlOptions.begin = opts.begin;

// Create filters.
var filters = [];

/**
 * @param {String} field
 * @param {String} regexpStr
 * @param {Boolean|null} negated
 */
function createFilter(field, regexpStr, negated) {
  try {
    var regexp = new RegExp(regexpStr, 'i');
  } catch (err) {
    console.error(err.message);
    process.exit(1);
  }

  filters.push(function(format) {
    return negated !== regexp.test(format[field]);
  });
}

['container', 'resolution', 'encoding'].forEach(function(field) {
  var key = 'filter' + field[0].toUpperCase() + field.slice(1);
  if (opts[key]) {
    createFilter(field, opts[key], false);
  }

  key = 'un' + key;
  if (opts[key]) {
    createFilter(field, opts[key], true);
  }
});

ytdlOptions.filter = function(format) {
  return filters.every(function(filter) {
    return filter(format);
  });
};

var readStream = ytdl(opts.url, ytdlOptions);
readStream.pipe(writeStream);

// Converst bytes to human readable unit.
// Thank you Amir from StackOverflow.
var units = ' KMGTPEZYXWVU';
function toHumanSize(bytes) {
  if (bytes <= 0) { return 0; }
  var t2 = Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), 12);
  return (Math.round(bytes * 100 / Math.pow(1024, t2)) / 100) +
          units.charAt(t2).replace(' ', '') + 'B';
}

// Print progress bar and some video info if not streaming to stdout.
if (output) {
  readStream.on('info', function(info, format) {
    printVideoInfo(info);
    console.log('container: '.grey.bold + format.container);
    console.log('resolution: '.grey.bold + format.resolution);
    console.log('encoding: '.grey.bold + format.encoding);
    console.log('size: '.grey.bold + toHumanSize(format.size));
    console.log('output: '.grey.bold + output);
    console.log();

    // Create progress bar.
    var bar = require('progress-bar').create(process.stdout, 50);
    bar.format = '$bar; $percentage;%';

    // Keep track of progress.
    var dataRead = 0;
    readStream.on('data', function(data) {
      dataRead += data.length;
      var percent = dataRead / format.size;
      bar.update(percent);
    });

    ytdl.cache.die();

  });
}

readStream.on('end', function onend() {
  console.log();
});

process.on('SIGINT', function onsigint() {
  console.log();
  process.exit();
});
<commit_msg>listen for error event<commit_after>#!/usr/bin/env node

var path  = require('path');
var fs    = require('fs');
var ytdl  = require('..');
var cliff = require('cliff');
require('colors');

var info = JSON.parse(
    fs.readFileSync(path.resolve(__dirname, '..', 'package.json')));

var opts = require('nomnom')
  .option('version', {
    abbr: 'v'
  , flag: true
  , callback: function() {
      console.log('v' + info.version);
      process.exit();
    }
  , help: 'Print program version.'
  })
  .option('url', {
    position: 0
  , required: true
  , help: 'URL to the video.'
  })
  .option('quality', {
    abbr: 'q'
  , metavar: 'ITAG'
  , help: 'Video quality to download. Default: `highest`'
  })
  .option('start', {
    abbr: 's'
  , metavar: 'TIME'
  , help: 'Where to begin the video. ie 1m3s, 45s, 2300.'
  })
  .option('output', {
    abbr: 'o'
  , metavar: 'FILE'
  , help: 'Where to save the file. Default: stdout'
  })
  .option('filterContainer', {
    full: 'filter-container'
  , metavar: 'REGEXP'
  , help: 'Filter in format container.'
  })
  .option('unfilterContainer', {
    full: 'unfilter-container'
  , metavar: 'REGEXP'
  , help: 'Filter out format container.'
  })
  .option('filterResolution', {
    full: 'filter-resolution'
  , metavar: 'REGEXP'
  , help: 'Filter in format resolution.'
  })
  .option('unfilterResolution', {
    full: 'unfilter-resolution'
  , metavar: 'REGEXP'
  , help: 'Filter out format resolution.'
  })
  .option('filterEncoding', {
    full: 'filter-encoding'
  , metavar: 'REGEXP'
  , help: 'Filter in format encoding.'
  })
  .option('unfilterEncoding', {
    full: 'unfilter-encoding'
  , metavar: 'REGEXP'
  , help: 'Filter out format encoding.'
  })
  .option('info', {
    abbr: 'i'
  , flag: true
  , help: 'Print only video information without downloading'
  })
  .script('ytdl')
  .colors()
  .parse()
  ;

/**
 * Converts seconds into human readable time hh:mm:ss
 *
 * @param {Number} seconds
 * @return {String}
 */
function toHumanTime(seconds) {
  var h = Math.floor(seconds / 3600);
  if (h < 10) { h = '0' + h; }
  var m = Math.floor(seconds / 60) % 60;
  if (m < 10) { m = '0' + m; }
  var s = seconds % 60;
  if (s < 10) { s = '0' + s; }
  return h + ':' + m + ':' + s;
}

/**
 * Prints basic video information.
 *
 * @param {Object} info
 */
function printVideoInfo(info) {
  console.log();
  console.log('title: '.grey.bold + info.title);
  console.log('author: '.grey.bold + info.author);
  var rating = typeof info.avg_rating === 'number' ?
    info.avg_rating.toFixed(1) : info.avg_rating;
  console.log('average rating: '.grey.bold + rating);
  console.log('view count: '.grey.bold + info.view_count);
  console.log('length: '.grey.bold + toHumanTime(info.length_seconds));
}

if (opts.info) {
  ytdl.getInfo(opts.url, function(err, info) {
    if (err) {
      console.error(err.message);
      process.exit(1);
      return;
    }

    printVideoInfo(info);

    console.log('formats:'.grey.bold);
    var cols = ['itag', 'container', 'resolution', 'encoding'];
    var colors = ['green', 'blue', 'green', 'blue'];
    console.log(cliff.stringifyObjectRows(info.formats, cols, colors));
    ytdl.cache.die();
  });
  return;
}

var output = opts.output;
var writeStream = output ? fs.createWriteStream(output) : process.stdout;

var ytdlOptions = {};
ytdlOptions.quality = opts.quality;
ytdlOptions.begin = opts.begin;

// Create filters.
var filters = [];

/**
 * @param {String} field
 * @param {String} regexpStr
 * @param {Boolean|null} negated
 */
function createFilter(field, regexpStr, negated) {
  try {
    var regexp = new RegExp(regexpStr, 'i');
  } catch (err) {
    console.error(err.message);
    process.exit(1);
  }

  filters.push(function(format) {
    return negated !== regexp.test(format[field]);
  });
}

['container', 'resolution', 'encoding'].forEach(function(field) {
  var key = 'filter' + field[0].toUpperCase() + field.slice(1);
  if (opts[key]) {
    createFilter(field, opts[key], false);
  }

  key = 'un' + key;
  if (opts[key]) {
    createFilter(field, opts[key], true);
  }
});

ytdlOptions.filter = function(format) {
  return filters.every(function(filter) {
    return filter(format);
  });
};

var readStream = ytdl(opts.url, ytdlOptions);
readStream.pipe(writeStream);

readStream.on('error', function(err) {
  console.error(err.stack);
  process.exit(1);
});

// Converst bytes to human readable unit.
// Thank you Amir from StackOverflow.
var units = ' KMGTPEZYXWVU';
function toHumanSize(bytes) {
  if (bytes <= 0) { return 0; }
  var t2 = Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), 12);
  return (Math.round(bytes * 100 / Math.pow(1024, t2)) / 100) +
          units.charAt(t2).replace(' ', '') + 'B';
}

// Print progress bar and some video info if not streaming to stdout.
if (output) {
  readStream.on('info', function(info, format) {
    printVideoInfo(info);
    console.log('container: '.grey.bold + format.container);
    console.log('resolution: '.grey.bold + format.resolution);
    console.log('encoding: '.grey.bold + format.encoding);
    console.log('size: '.grey.bold + toHumanSize(format.size));
    console.log('output: '.grey.bold + output);
    console.log();

    // Create progress bar.
    var bar = require('progress-bar').create(process.stdout, 50);
    bar.format = '$bar; $percentage;%';

    // Keep track of progress.
    var dataRead = 0;
    readStream.on('data', function(data) {
      dataRead += data.length;
      var percent = dataRead / format.size;
      bar.update(percent);
    });

    ytdl.cache.die();

  });
}

readStream.on('end', function onend() {
  console.log();
});

process.on('SIGINT', function onsigint() {
  console.log();
  process.exit();
});
<|endoftext|>


<commit_before>module.exports = function (options = {}) {
    var defaults = {
        'metric': 'loc',
        'attribute': 'height',
        'min': 10,
        'max': 10000,
        'logarithmic': true,
        'logscale' : 0.05,
        'factor': 10
    };

    for (var key in defaults) {
        if (key in options) {
            continue;
        }

        options[key] = defaults[key];
    }

    return function (node, version, model) {
        // Applies only to classes
        if (node.children.length) {
            return;
        }

        var attributes = model.attributes(node, version);
        if (!(options.metric in attributes)) {
            return;
        }

        var loc = attributes[options.metric];

        if (options.logarithmic) {
            loc = Math.log(loc * options.logscale);
        }

        loc *= options.factor;

        var newAttributes = {};
        newAttributes[options.attribute] = Math.min(Math.max(loc, options.min), options.max);
        return newAttributes;
    };
};
<commit_msg>Logarithmus mit Basis (Werte brauchen noch arbeit)<commit_after>module.exports = function (options = {}) {
    var defaults = {
        'metric': 'loc',
        'attribute': 'height',
        'min': 10,
        'max': 180,
        'logarithmic': true,
        'logscale' : 0.08,
        'logsbase' : 1.2,
        'factor': 4
    };

    for (var key in defaults) {
        if (key in options) {
            continue;
        }

        options[key] = defaults[key];
    }

    return function (node, version, model) {
        // Applies only to classes
        if (node.children.length) {
            return;
        }

        var attributes = model.attributes(node, version);
        if (!(options.metric in attributes)) {
            return;
        }

        var loc = attributes[options.metric];

        if (options.logarithmic) {
            loc = Math.log((loc * options.logscale) + 1) / Math.log(options.logsbase);
        }

        loc *= options.factor;

        console.log(attributes[options.metric], ' => ', loc);

        var newAttributes = {};
        newAttributes[options.attribute] = Math.min(Math.max(loc, options.min), options.max);
        return newAttributes;
    };
};
<|endoftext|>


<commit_before>import {
    GraphQLID,
    GraphQLInt,
    GraphQLList,
    GraphQLNonNull,
    GraphQLObjectType,
    GraphQLInputObjectType,
    GraphQLSchema,
    GraphQLString,
    parse,
    extendSchema,
} from 'graphql';
import { pluralize, camelize } from 'inflection';

import getTypesFromData from './getTypesFromData';
import getFilterTypesFromData from './getFilterTypesFromData';
import { isRelationshipField } from '../relationships';
import { getRelatedType } from '../nameConverter';

/**
 * Get a GraphQL schema from data
 *
 * @example
 * const data = {
 *    "posts": [
 *        {
 *            "id": 1,
 *            "title": "Lorem Ipsum",
 *            "views": 254,
 *            "user_id": 123,
 *        },
 *        {
 *            "id": 2,
 *            "title": "Sic Dolor amet",
 *            "views": 65,
 *            "user_id": 456,
 *        },
 *    ],
 *    "users": [
 *        {
 *            "id": 123,
 *            "name": "John Doe"
 *        },
 *        {
 *            "id": 456,
 *            "name": "Jane Doe"
 *        }
 *    ],
 * };
 * const types = getTypesFromData(data);
 * // type Post {
 * //     id: ID
 * //     title: String
 * //     views: Int
 * //     user_id: ID
 * // }
 * //
 * // type User {
 * //     id: ID
 * //     name: String
 * // }
 * //
 * // type Query {
 * //     Post(id: ID!): Post
 * //     allPosts(page: Int, perPage: Int, sortField: String, sortOrder: String, filter: PostFilter): [Post]
 * //     User(id: ID!): User
 * //     allUsers(page: Int, perPage: Int, sortField: String, sortOrder: String, filter: UserFilter): [User]
 * // }
 * //
 * // type Mutation {
 * //     createPost(data: String): Post
 * //     updatePost(data: String): Post
 * //     removePost(id: ID!): Boolean
 * //     createUser(data: String): User
 * //     updateUser(data: String): User
 * //     removeUser(id: ID!): Boolean
 * // }
 */
export default (data) => {
    const types = getTypesFromData(data);
    const typesByName = types.reduce((types, type) => {
        types[type.name] = type;
        return types;
    }, {});

    const filterTypesByName = getFilterTypesFromData(data);

    const listMetadataType = new GraphQLObjectType({
        name: 'ListMetadata',
        fields: {
            count: { type: GraphQLInt },
        },
    });

    const queryType = new GraphQLObjectType({
        name: 'Query',
        fields: types.reduce((fields, type) => {
            fields[type.name] = {
                type: typesByName[type.name],
                args: {
                    id: { type: new GraphQLNonNull(GraphQLID) },
                },
            };
            fields[`all${camelize(pluralize(type.name))}`] = {
                type: new GraphQLList(typesByName[type.name]),
                args: {
                    page: { type: GraphQLInt },
                    perPage: { type: GraphQLInt },
                    sortField: { type: GraphQLString },
                    sortOrder: { type: GraphQLString },
                    filter: { type: filterTypesByName[type.name] },
                },
            };
            fields[`_all${camelize(pluralize(type.name))}Meta`] = {
                type: listMetadataType,
                args: {
                    page: { type: GraphQLInt },
                    perPage: { type: GraphQLInt },
                    filter: { type: filterTypesByName[type.name] },
                },
            };
            return fields;
        }, {}),
    });

    const mutationType = new GraphQLObjectType({
        name: 'Mutation',
        fields: types.reduce((fields, type) => {
            const typeFields = typesByName[type.name].getFields();
            const nullableTypeFields = Object.keys(typeFields).reduce(
                (f, fieldName) => {
                    f[fieldName] = Object.assign({}, typeFields[fieldName], {
                        type:
                            fieldName !== 'id' &&
                            typeFields[fieldName].type instanceof GraphQLNonNull
                                ? typeFields[fieldName].type.ofType
                                : typeFields[fieldName].type,
                    });
                    return f;
                },
                {}
            );
            const { id, ...createFields } = typeFields;

            // Build input type.
            const inputFields = Object.keys(typeFields).reduce(
                (f, fieldName) => {
                    f[fieldName] = Object.assign({}, typeFields[fieldName]);
                    delete f[fieldName].resolve;
                    return f;
                },
                {}
            );

            console.log(typeFields);
            const createManyInputType = new GraphQLInputObjectType({
                name: type.name + 'Input',
                fields: inputFields,
            });

            fields[`create${type.name}`] = {
                type: typesByName[type.name],
                args: createFields,
            };
            fields[`createMany${type.name}`] = {
                type: new GraphQLList(typesByName[type.name]),
                args: {
                    data: {
                        type: new GraphQLList(createManyInputType),
                    },
                },
            };
            fields[`update${type.name}`] = {
                type: typesByName[type.name],
                args: nullableTypeFields,
            };
            fields[`remove${type.name}`] = {
                type: typesByName[type.name],
                args: {
                    id: { type: new GraphQLNonNull(GraphQLID) },
                },
            };
            return fields;
        }, {}),
    });

    const schema = new GraphQLSchema({
        query: queryType,
        mutation: mutationType,
    });

    /**
     * extend schema to add relationship fields
     *
     * @example
     * If the `post` key contains a 'user_id' field, then
     * add one-to-many and many-to-one type extensions:
     *     extend type Post { User: User }
     *     extend type User { Posts: [Post] }
     */
    const schemaExtension = Object.values(typesByName).reduce((ext, type) => {
        Object.keys(type.getFields())
            .filter(isRelationshipField)
            .map((fieldName) => {
                const relType = getRelatedType(fieldName);
                const rel = pluralize(type.toString());
                ext += `
extend type ${type} { ${relType}: ${relType} }
extend type ${relType} { ${rel}: [${type}] }`;
            });
        return ext;
    }, '');

    return schemaExtension
        ? extendSchema(schema, parse(schemaExtension))
        : schema;
};
<commit_msg>chore: Remove another console log.<commit_after>import {
    GraphQLID,
    GraphQLInt,
    GraphQLList,
    GraphQLNonNull,
    GraphQLObjectType,
    GraphQLInputObjectType,
    GraphQLSchema,
    GraphQLString,
    parse,
    extendSchema,
} from 'graphql';
import { pluralize, camelize } from 'inflection';

import getTypesFromData from './getTypesFromData';
import getFilterTypesFromData from './getFilterTypesFromData';
import { isRelationshipField } from '../relationships';
import { getRelatedType } from '../nameConverter';

/**
 * Get a GraphQL schema from data
 *
 * @example
 * const data = {
 *    "posts": [
 *        {
 *            "id": 1,
 *            "title": "Lorem Ipsum",
 *            "views": 254,
 *            "user_id": 123,
 *        },
 *        {
 *            "id": 2,
 *            "title": "Sic Dolor amet",
 *            "views": 65,
 *            "user_id": 456,
 *        },
 *    ],
 *    "users": [
 *        {
 *            "id": 123,
 *            "name": "John Doe"
 *        },
 *        {
 *            "id": 456,
 *            "name": "Jane Doe"
 *        }
 *    ],
 * };
 * const types = getTypesFromData(data);
 * // type Post {
 * //     id: ID
 * //     title: String
 * //     views: Int
 * //     user_id: ID
 * // }
 * //
 * // type User {
 * //     id: ID
 * //     name: String
 * // }
 * //
 * // type Query {
 * //     Post(id: ID!): Post
 * //     allPosts(page: Int, perPage: Int, sortField: String, sortOrder: String, filter: PostFilter): [Post]
 * //     User(id: ID!): User
 * //     allUsers(page: Int, perPage: Int, sortField: String, sortOrder: String, filter: UserFilter): [User]
 * // }
 * //
 * // type Mutation {
 * //     createPost(data: String): Post
 * //     updatePost(data: String): Post
 * //     removePost(id: ID!): Boolean
 * //     createUser(data: String): User
 * //     updateUser(data: String): User
 * //     removeUser(id: ID!): Boolean
 * // }
 */
export default (data) => {
    const types = getTypesFromData(data);
    const typesByName = types.reduce((types, type) => {
        types[type.name] = type;
        return types;
    }, {});

    const filterTypesByName = getFilterTypesFromData(data);

    const listMetadataType = new GraphQLObjectType({
        name: 'ListMetadata',
        fields: {
            count: { type: GraphQLInt },
        },
    });

    const queryType = new GraphQLObjectType({
        name: 'Query',
        fields: types.reduce((fields, type) => {
            fields[type.name] = {
                type: typesByName[type.name],
                args: {
                    id: { type: new GraphQLNonNull(GraphQLID) },
                },
            };
            fields[`all${camelize(pluralize(type.name))}`] = {
                type: new GraphQLList(typesByName[type.name]),
                args: {
                    page: { type: GraphQLInt },
                    perPage: { type: GraphQLInt },
                    sortField: { type: GraphQLString },
                    sortOrder: { type: GraphQLString },
                    filter: { type: filterTypesByName[type.name] },
                },
            };
            fields[`_all${camelize(pluralize(type.name))}Meta`] = {
                type: listMetadataType,
                args: {
                    page: { type: GraphQLInt },
                    perPage: { type: GraphQLInt },
                    filter: { type: filterTypesByName[type.name] },
                },
            };
            return fields;
        }, {}),
    });

    const mutationType = new GraphQLObjectType({
        name: 'Mutation',
        fields: types.reduce((fields, type) => {
            const typeFields = typesByName[type.name].getFields();
            const nullableTypeFields = Object.keys(typeFields).reduce(
                (f, fieldName) => {
                    f[fieldName] = Object.assign({}, typeFields[fieldName], {
                        type:
                            fieldName !== 'id' &&
                            typeFields[fieldName].type instanceof GraphQLNonNull
                                ? typeFields[fieldName].type.ofType
                                : typeFields[fieldName].type,
                    });
                    return f;
                },
                {}
            );
            const { id, ...createFields } = typeFields;

            // Build input type.
            const inputFields = Object.keys(typeFields).reduce(
                (f, fieldName) => {
                    f[fieldName] = Object.assign({}, typeFields[fieldName]);
                    delete f[fieldName].resolve;
                    return f;
                },
                {}
            );

            const createManyInputType = new GraphQLInputObjectType({
                name: type.name + 'Input',
                fields: inputFields,
            });

            fields[`create${type.name}`] = {
                type: typesByName[type.name],
                args: createFields,
            };
            fields[`createMany${type.name}`] = {
                type: new GraphQLList(typesByName[type.name]),
                args: {
                    data: {
                        type: new GraphQLList(createManyInputType),
                    },
                },
            };
            fields[`update${type.name}`] = {
                type: typesByName[type.name],
                args: nullableTypeFields,
            };
            fields[`remove${type.name}`] = {
                type: typesByName[type.name],
                args: {
                    id: { type: new GraphQLNonNull(GraphQLID) },
                },
            };
            return fields;
        }, {}),
    });

    const schema = new GraphQLSchema({
        query: queryType,
        mutation: mutationType,
    });

    /**
     * extend schema to add relationship fields
     *
     * @example
     * If the `post` key contains a 'user_id' field, then
     * add one-to-many and many-to-one type extensions:
     *     extend type Post { User: User }
     *     extend type User { Posts: [Post] }
     */
    const schemaExtension = Object.values(typesByName).reduce((ext, type) => {
        Object.keys(type.getFields())
            .filter(isRelationshipField)
            .map((fieldName) => {
                const relType = getRelatedType(fieldName);
                const rel = pluralize(type.toString());
                ext += `
extend type ${type} { ${relType}: ${relType} }
extend type ${relType} { ${rel}: [${type}] }`;
            });
        return ext;
    }, '');

    return schemaExtension
        ? extendSchema(schema, parse(schemaExtension))
        : schema;
};
<|endoftext|>


<commit_before>'use strict';

var async  = require('async');
var exec   = require('child_process').exec;
var moment = require('moment');
var _      = require('underscore');
var path   = require('path');

_.templateSettings = {
  interpolate : /\{\{(.+?)\}\}/g
};

/**
 * Deploy helper
 * @param {Object} options                    Options to set up deploy
 * @param {String} options.user               User deploy from
 * @param {String} options.domain             Remote server domain
 * @param {String} options.deployTo           Remote folder to deploy in
 *
 * @param {String} options.repository         Git repository of project
 * @param {String} [options.branch='master']  Git branch that will be used for deploy
 *
 * @param {String} [options.deployFrom]       Remote folder to deploy from
 * @param {String} [options.keepReleases=3]   Amount of releases to keep
 */
function Deploy(options, done) {
  var releaseName = moment().format('YYYYMMDDHHmmss'),
      that = this;

  this.options = options;
  this._commands = [];

  options.branch = options.branch || 'master';
  options.keepReleases = options.keepReleases || 3;
  options.hooks = options.hooks || {};

  this._folders = {
    logsPath:     path.join(options.deployTo, '/logs'),
    sharedPath:   path.join(options.deployTo, '/shared'),
    releasesPath: path.join(options.deployTo, '/releases'),

    currentPath:  path.join(options.deployTo, '/current'),
  };

  this._folders.releasePath = path.join(this._folders.releasesPath, releaseName);

  this.run('ls -1 {{releasesPath}}', { quiet: true });
  this.exec(function (err, results) {
    var ls = results[0],
        releases = ls.trim().split('\n'),
        length = releases.length,
        folders = that._folders;

    console.log(JSON.stringify(releases));

    _.extend(folders, {
      currentRelease:  length > 0 ? path.join(folders.releasesPath, releases[length - 1]) : null,
      previousRelease: length > 1 ? path.join(folders.releasesPath, releases[length - 2]) : null,
    });

    // for current release it will be redefined to {{releasePath}}
    folders.latestRelease = folders.currentRelease;

    done();
  });
}

Deploy.prototype.setup = function (done) {
  console.log('Starting...');

  this.run('mkdir -p {{releasesPath}} {{logsPath}} {{sharedPath}}');

  this.exec(done);
};

Deploy.prototype.start = function (done) {
  var that = this;

  this._folders.latestRelease = this._folders.releasePath;
  this._trigger('beforeDeploy', start);

  function start() {
    that.run('mkdir -p {{releasePath}}');
    that.run('git clone -q -b {{branch}} {{repository}} {{releasePath}}');
    that.exec(npmInstall);
  }

  /**
   * Install dependencies
   */
  function npmInstall(err) {
    if (err) {
      throw err;
    }

    that._npmInstall(symlink);
  }

  /**
   * Update/create symlink of current release
   */
  function symlink(err) {
    if (err) {
      throw err;
    }

    that.run('rm -f {{currentPath}}');
    that.run('ln -s {{releasePath}} {{currentPath}}');
    that.exec(cleanup);
  }

  function cleanup(err) {
    if (err) {
      throw err;
    }

    that.cleanup(function (err) {
      if (err) {
        throw err;
      }

      that._trigger('afterDeploy', done);
    });
  }
};

/**
 * Install project dependencies
 *
 * @param  {Function} done Installing dependencies done hook
 */
Deploy.prototype._npmInstall = function (done) {
  var that = this;

  this._trigger('beforeNpm', function () {
    that.run('cd {{releasePath}} && test -f {{releasePath}}/package.json && npm install || true');
    that.exec(function (err) {
      if (err) {
        throw err;
      }

      that._trigger('afterNpm', done);
    });
  });
};

Deploy.prototype.rollback = function (done) {
  var that = this;

  this.run('ls -1 {{releasesPath}}', { quiet: true });
  this.exec(rollback);

  function rollback(err, results) {
    var ls = results[0].trim(),
        folders = ls.split('\n'),
        release,
        previousRelease;

    if (folders.length < 2) {
      throw 'Rolling back is impossible, there are less then 2 releases.';
    }

    release = that._folders.releasesPath + '/' + folders[folders.length - 1];
    previousRelease = that._folders.releasesPath + '/' + folders[folders.length - 2];

    that.run('rm -f {{currentPath}}');
    that.run('ln -s ' + previousRelease + ' {{currentPath}}');
    that.run('rm -Rf ' + release);
    that.exec(done);
  }
};

/**
 * Remove releases that are not needed
 *
 * @param  {Function} done Cleanup done callback
 */
Deploy.prototype.cleanup = function (done) {
  var that = this;

  this.run([
    'ls -1td {{releasesPath}}/*',
    'tail -n +' + (this.options.keepReleases + 1),
    'xargs rm -rf'
  ].join(' | '), { quiet: true });
  this.exec(done);
};

/**
 * Trigger hooks
 */
Deploy.prototype._trigger = function (name, done) {
  var that = this,
      hook = this.options.hooks[name],
      isHookAsync = false;

  if (typeof hook === 'undefined') {
    // hook is not defined
    done();
    return;
  } else if (typeof hook !== 'function') {
    console.log('Hook `%s` should be a function', name);
    done();
    return;
  }

  console.log(
    (moment().format('YYYY-MM-DD HH:mm:ss') + ' executing ' + '`' + name +'`').green
  );

  hook.call(
    {
      // async hooks execution
      async: function () {
        isHookAsync = true;
        return afterHook;
      }
    },

    this.run.bind(this),
    this.runLocally.bind(this)
  );

  if ( !isHookAsync ) {
    afterHook();
  }

  function afterHook() {
    that.exec(done);
  }
};

/**
 * Add commands for remote execution
 *
 * @param {String}  command                 Command to execute
 * @param {Object}  [options]               Command execution options
 * @param {Boolean} [options.local=false]   Run command locally
 * @param {Boolean} [options.quiet=false]   Do not show output on the screen
 */
Deploy.prototype.run = function (command, options) {
  options = _.extend({ quiet: false, local: false }, options || {});

  this._commands.push({
    command: this._expandCommand(command),
    local: options.local,
    quiet: options.quiet
  });
};

/**
 * Add commands for local execution
 *
 * @param {String}  command                 Command to execute
 * @param {Object}  [options]               Command execution options
 * @param {Boolean} [options.quiet=false]   Do not show output on the screen
 */
Deploy.prototype.runLocally = function (command, options) {
  options = _.extend({ quiet: false }, options || {});
  options.local = true;
  this.run(command, options);
};

/**
 * Execute stored commands
 *
 * @param  {Function} done Callback that will be called when all commands executed
 */
Deploy.prototype.exec = function (done) {
  var that = this;

  async.mapSeries(this._commands, function (command, callback) {
    var _exec,
        cmd = command.command;

    that.log(command);

    _exec = exec(
      command.local ? cmd : that._remoteCommand(cmd),
      callback
    );

    if ( !command.quiet ) {
      _exec.stdout.pipe(process.stdout);
      _exec.stderr.pipe(process.stderr);
    }
  }, function () {
    that._commands = [];
    done.apply(null, arguments);
  });
};

/**
 * Expand command: augment with variables, e.g. folders, user, domain
 *
 * @param {String} command Command to expand
 * @return {String}        Expanded command
 */
Deploy.prototype._expandCommand = function (command) {
  var data = _.extend({}, this.options, this._folders);

  return _.template(command, data);
};

/**
 * Convert command to remote
 */
Deploy.prototype._remoteCommand = function (command) {
  command = command.replace(/\"/g, '\\\"');

  return _.template(
    'ssh -A {{host}} "{{command}}"',
    { host: this.options.user + '@' + this.options.domain, command: command }
  );
};

Deploy.prototype.log = function (command) {
  var isLocal = command.local,
      cmd     = command.command,
      log     = '* ';

  log = '*' + (' executing ' + (isLocal ? 'locally: ' : '') + '"' + cmd + '"').yellow;

  console.log(log);
};

module.exports = {
  Deploy: Deploy
};
<commit_msg>Refactor rollback.<commit_after>'use strict';

var async  = require('async');
var exec   = require('child_process').exec;
var moment = require('moment');
var _      = require('underscore');
var path   = require('path');

_.templateSettings = {
  interpolate : /\{\{(.+?)\}\}/g
};

/**
 * Deploy helper
 * @param {Object} options                    Options to set up deploy
 * @param {String} options.user               User deploy from
 * @param {String} options.domain             Remote server domain
 * @param {String} options.deployTo           Remote folder to deploy in
 *
 * @param {String} options.repository         Git repository of project
 * @param {String} [options.branch='master']  Git branch that will be used for deploy
 *
 * @param {String} [options.deployFrom]       Remote folder to deploy from
 * @param {String} [options.keepReleases=3]   Amount of releases to keep
 */
function Deploy(options, done) {
  var releaseName = moment().format('YYYYMMDDHHmmss'),
      that = this;

  this.options = options;
  this._commands = [];

  options.branch = options.branch || 'master';
  options.keepReleases = options.keepReleases || 3;
  options.hooks = options.hooks || {};

  this._folders = {
    logsPath:     path.join(options.deployTo, '/logs'),
    sharedPath:   path.join(options.deployTo, '/shared'),
    releasesPath: path.join(options.deployTo, '/releases'),

    currentPath:  path.join(options.deployTo, '/current'),
  };

  this._folders.releasePath = path.join(this._folders.releasesPath, releaseName);

  this.run('ls -1 {{releasesPath}}', { quiet: true });
  this.exec(function (err, results) {
    var ls = results[0],
        releases = ls.trim().split('\n'),
        length = releases.length,
        folders = that._folders;

    _.extend(folders, {
      currentRelease:  length > 0 ? path.join(folders.releasesPath, releases[length - 1]) : null,
      previousRelease: length > 1 ? path.join(folders.releasesPath, releases[length - 2]) : null,
    });

    // for current release it will be redefined to {{releasePath}}
    folders.latestRelease = folders.currentRelease;

    done();
  });
}

Deploy.prototype.setup = function (done) {
  console.log('Starting...');

  this.run('mkdir -p {{releasesPath}} {{logsPath}} {{sharedPath}}');

  this.exec(done);
};

Deploy.prototype.start = function (done) {
  var that = this;

  this._folders.latestRelease = this._folders.releasePath;
  this._trigger('beforeDeploy', start);

  function start() {
    that.run('mkdir -p {{releasePath}}');
    that.run('git clone -q -b {{branch}} {{repository}} {{releasePath}}');
    that.exec(npmInstall);
  }

  /**
   * Install dependencies
   */
  function npmInstall(err) {
    if (err) {
      throw err;
    }

    that._npmInstall(symlink);
  }

  /**
   * Update/create symlink of current release
   */
  function symlink(err) {
    if (err) {
      throw err;
    }

    that.run('rm -f {{currentPath}}');
    that.run('ln -s {{releasePath}} {{currentPath}}');
    that.exec(cleanup);
  }

  function cleanup(err) {
    if (err) {
      throw err;
    }

    that.cleanup(function (err) {
      if (err) {
        throw err;
      }

      that._trigger('afterDeploy', done);
    });
  }
};

/**
 * Install project dependencies
 *
 * @param  {Function} done Installing dependencies done hook
 */
Deploy.prototype._npmInstall = function (done) {
  var that = this;

  this._trigger('beforeNpm', function () {
    that.run('cd {{releasePath}} && test -f {{releasePath}}/package.json && npm install || true');
    that.exec(function (err) {
      if (err) {
        throw err;
      }

      that._trigger('afterNpm', done);
    });
  });
};

Deploy.prototype.rollback = function (done) {
  var that = this;

  if (this._folders.previousRelease) {
    this.run('rm -Rf {{currentPath}}; ln -s {{previousRelease}} {{currentPath}}');
    this.exec(rollbackCleanup);
  } else {
    throw 'Rolling back is impossible, there are less then 2 releases.';
  }

  function rollbackCleanup() {
    that.run('if [ `readlink {{currentPath}}` != {{currentRelease}} ]; then rm -rf {{currentRelease}}; fi');
    that.exec(done);
  }
};

/**
 * Remove releases that are not needed
 *
 * @param  {Function} done Cleanup done callback
 */
Deploy.prototype.cleanup = function (done) {
  var that = this;

  this.run([
    'ls -1td {{releasesPath}}/*',
    'tail -n +' + (this.options.keepReleases + 1),
    'xargs rm -rf'
  ].join(' | '), { quiet: true });
  this.exec(done);
};

/**
 * Trigger hooks
 */
Deploy.prototype._trigger = function (name, done) {
  var that = this,
      hook = this.options.hooks[name],
      isHookAsync = false;

  if (typeof hook === 'undefined') {
    // hook is not defined
    done();
    return;
  } else if (typeof hook !== 'function') {
    console.log('Hook `%s` should be a function', name);
    done();
    return;
  }

  console.log(
    (moment().format('YYYY-MM-DD HH:mm:ss') + ' executing ' + '`' + name +'`').green
  );

  hook.call(
    {
      // async hooks execution
      async: function () {
        isHookAsync = true;
        return afterHook;
      }
    },

    this.run.bind(this),
    this.runLocally.bind(this)
  );

  if ( !isHookAsync ) {
    afterHook();
  }

  function afterHook() {
    that.exec(done);
  }
};

/**
 * Add commands for remote execution
 *
 * @param {String}  command                 Command to execute
 * @param {Object}  [options]               Command execution options
 * @param {Boolean} [options.local=false]   Run command locally
 * @param {Boolean} [options.quiet=false]   Do not show output on the screen
 */
Deploy.prototype.run = function (command, options) {
  options = _.extend({ quiet: false, local: false }, options || {});

  this._commands.push({
    command: this._shellEscape( this._expandCommand(command) ),
    local: options.local,
    quiet: options.quiet
  });
};

/**
 * Add commands for local execution
 *
 * @param {String}  command                 Command to execute
 * @param {Object}  [options]               Command execution options
 * @param {Boolean} [options.quiet=false]   Do not show output on the screen
 */
Deploy.prototype.runLocally = function (command, options) {
  options = _.extend({ quiet: false }, options || {});
  options.local = true;
  this.run(command, options);
};

/**
 * Execute stored commands
 *
 * @param  {Function} done Callback that will be called when all commands executed
 */
Deploy.prototype.exec = function (done) {
  var that = this;

  async.mapSeries(this._commands, function (command, callback) {
    var _exec,
        cmd = command.command;

    that.log(command);

    _exec = exec(
      command.local ? cmd : that._remoteCommand(cmd),
      callback
    );

    if ( !command.quiet ) {
      _exec.stdout.pipe(process.stdout);
      _exec.stderr.pipe(process.stderr);
    }
  }, function () {
    that._commands = [];
    done.apply(null, arguments);
  });
};

/**
 * Expand command: augment with variables, e.g. folders, user, domain
 *
 * @param {String} command Command to expand
 * @return {String}        Expanded command
 */
Deploy.prototype._expandCommand = function (command) {
  var data = _.extend({}, this.options, this._folders);

  return _.template(command, data);
};

/**
 * Convert command to remote
 */
Deploy.prototype._remoteCommand = function (command) {
  return _.template(
    'ssh -A {{host}} "{{command}}"',
    { host: this.options.user + '@' + this.options.domain, command: command }
  );
};

Deploy.prototype.log = function (command) {
  var isLocal = command.local,
      cmd     = command.command,
      log     = '* ';

  log = '*' + (' executing ' + (isLocal ? 'locally: ' : '') + '"' + cmd + '"').yellow;

  console.log(log);
};

Deploy.prototype._shellEscape = function (str) {
  return str.replace(/([\`\[\]\"\'])/g, '\\$1');
};

module.exports = {
  Deploy: Deploy
};
<|endoftext|>


<commit_before>'use strict';

const gulp = require('gulp');
const extOpt = require('js.shared').config.get('extension');
const replace = require('gulp-batch-replace');

module.exports = function () {
    let phs = [];

    Object.keys(extOpt.replace).forEach(function (ph) {
        phs.push([ph, extOpt.replace[ph]]);
    });

    return gulp
        .src(extOpt.manifest.json)
        .pipe(replace(phs))
        .pipe(gulp.dest(extOpt.dist));
};
<commit_msg>+ --env=local switch for https://localhost:8181/api/<commit_after>'use strict';

const gulp = require('gulp');
const extOpt = require('js.shared').config.get('extension');
const replace = require('gulp-batch-replace');
const args = require('yargs').argv;

module.exports = function () {
    let phs = [];

    if(args.env === 'dev'){
        extOpt.replace.REMOTE_API_URL = 'https://localhost:8181/api/'
    }

    Object.keys(extOpt.replace).forEach(function (ph) {
        phs.push([ph, extOpt.replace[ph]]);
    });

    return gulp
        .src(extOpt.manifest.json)
        .pipe(replace(phs))
        .pipe(gulp.dest(extOpt.dist));
};
<|endoftext|>


<commit_before>var filepickerUpload = require('../../services/filepickerUpload');

// the newCurrentUser dependency will change once the rest of
// the app is switched over to using the new User API
var dependencies = ['$scope', '$analytics', 'currentUser', 'growl'];
dependencies.push(function($scope, $analytics, currentUser, growl) {
  var user = $scope.user = currentUser,
    editData = $scope.editData = _.pick(user, [
      'bio', 'skills', 'organizations', 'avatar_url', 'banner_url',
      'twitter_name', 'linkedin_url', 'facebook_url'
    ]),
    edited = {};

  $scope.save = function() {
    if (editData.banner_url === require('../../services/defaultUserBanner')) {
      editData.banner_url = null;
    }

    var saveData = _.clone(editData);
    if (!edited.skills) delete saveData.skills;
    if (!edited.organizations) delete saveData.organizations;

    user.update(saveData, function() {
      _.extend(user, saveData);
      $scope.cancel();
    });
  };

  $scope.cancel = function() {
    $scope.$state.go('profile', {id: user.id});
  };

  $scope.add = function(event, type) {
    if (event.which == 13) {
      editData[type].unshift(event.target.value);
      event.target.value = '';
      edited[type] = true;
    }
    return true;
  };

  $scope.remove = function(value, type) {
    editData[type].splice(editData[type].indexOf(value), 1);
    edited[type] = true;
  };

  var imageChangeFn = function(opts) {
    return function() {
      filepickerUpload({
        path: opts.path,
        convert: opts.convert,
        success: function(url) {
          editData[opts.fieldName] = url;
          $analytics.eventTrack('Profile: Changed ' + opts.humanName, {user_id: user.id});
        },
        failure: function(error) {
          growl.addErrorMessage('An error occurred while uploading the image. Please try again.');
          $analytics.eventTrack('Profile: Failed to Change ' + opts.humanName, {user_id: user.id});
        }
      });
    };
  };

  $scope.changeAvatar = imageChangeFn({
    fieldName: 'avatar_url',
    humanName: 'Icon',
    path: 'thumb',
    convert: {width: 200, height: 200, fit: 'clip', rotate: "exif"}
  });

  $scope.changeBanner = imageChangeFn({
    fieldName: 'banner_url',
    humanName: 'Banner',
    path: 'userBanner',
    convert: {width: 1600, format: 'jpg', fit: 'max', rotate: "exif"}
  });

  $scope.changeTwitter = function() {
    var response = prompt(
      'Enter your Twitter username, or leave blank:',
      editData.twitter_name
    );
    if (response) editData.twitter_name = response;
  };

  $scope.changeFacebook = function() {
    if (editData.facebook_url) {
      if (confirm('Choose OK to remove your Facebook information.')) {
        editData.facebook_url = null;
      }
    } else {
      FB.login(function() {
        FB.api('/me', function(resp) {
          editData.facebook_url = resp.link;
        })
      })
    }
  };

  $scope.changeLinkedin = function() {
    if (editData.linkedin_url) {
      if (confirm('Choose OK to remove your LinkedIn information.')) {
        editData.linkedin_url = null;
      }
    } else {
      var left = document.documentElement.clientWidth/2 - 520/2;
      $scope.linkedinDialog = window.open('/noo/linkedin/authorize', 'linkedinAuth',
        'width=400, height=625, titlebar=no, toolbar=no, menubar=no, left=' + left);
    }
  };

  $scope.finishLinkedinChange = function(url) {
    editData.linkedin_url = url;
    $scope.linkedinDialog.close();
  };

});

module.exports = function(angularModule) {
  angularModule.controller('ProfileEditCtrl', dependencies);
};
<commit_msg>added analytics to track user changes to profile<commit_after>var filepickerUpload = require('../../services/filepickerUpload');

// the newCurrentUser dependency will change once the rest of
// the app is switched over to using the new User API
var dependencies = ['$scope', '$analytics', 'currentUser', 'growl'];
dependencies.push(function($scope, $analytics, currentUser, growl) {
  var user = $scope.user = currentUser,
    editData = $scope.editData = _.pick(user, [
      'bio', 'skills', 'organizations', 'avatar_url', 'banner_url',
      'twitter_name', 'linkedin_url', 'facebook_url'
    ]),
    edited = {};

  $scope.save = function() {
    if (editData.banner_url === require('../../services/defaultUserBanner')) {
      editData.banner_url = null;
    }

    var saveData = _.clone(editData);
    if (!edited.skills) delete saveData.skills;
    if (!edited.organizations) delete saveData.organizations;

    user.update(saveData, function() {
      _.extend(user, saveData);
      $analytics.eventTrack('My Profile: Saved Changes');
      $scope.cancel();
    });
  };

  $scope.cancel = function() {
    $scope.$state.go('profile', {id: user.id});
  };

  $scope.add = function(event, type) {
    if (event.which == 13) {
      editData[type].unshift(event.target.value);
      event.target.value = '';
      edited[type] = true;
      $analytics.eventTrack('My Profile: Edit: Add to Profile', {item_type: type});
    }
    return true;
  };

  $scope.remove = function(value, type) {
    editData[type].splice(editData[type].indexOf(value), 1);
    edited[type] = true;
  };

  var imageChangeFn = function(opts) {
    return function() {
      filepickerUpload({
        path: opts.path,
        convert: opts.convert,
        success: function(url) {
          editData[opts.fieldName] = url;
          $analytics.eventTrack('Profile: Changed ' + opts.humanName, {user_id: user.id});
        },
        failure: function(error) {
          growl.addErrorMessage('An error occurred while uploading the image. Please try again.');
          $analytics.eventTrack('Profile: Failed to Change ' + opts.humanName, {user_id: user.id});
        }
      });
    };
  };

  $scope.changeAvatar = imageChangeFn({
    fieldName: 'avatar_url',
    humanName: 'Icon',
    path: 'thumb',
    convert: {width: 200, height: 200, fit: 'clip', rotate: "exif"}
  });

  $scope.changeBanner = imageChangeFn({
    fieldName: 'banner_url',
    humanName: 'Banner',
    path: 'userBanner',
    convert: {width: 1600, format: 'jpg', fit: 'max', rotate: "exif"}
  });

  $scope.changeTwitter = function() {
    var response = prompt(
      'Enter your Twitter username, or leave blank:',
      editData.twitter_name
    );
    if (response) {
      editData.twitter_name = response;
      $analytics.eventTrack('My Profile: Edit: Add Social Media Link to Profile', {provider: 'Twitter'});
    }
  };

  $scope.changeFacebook = function() {
    if (editData.facebook_url) {
      if (confirm('Choose OK to remove your Facebook information.')) {
        editData.facebook_url = null;
        $analytics.eventTrack('My Profile: Edit: Remove Social Media Link from Profile', {provider: 'Facebook'});
      }
    } else {
      FB.login(function() {
        FB.api('/me', function(resp) {
          editData.facebook_url = resp.link;
          $analytics.eventTrack('My Profile: Edit: Add Social Media Link to Profile', {provider: 'Facebook'});
        })
      })
    }
  };

  $scope.changeLinkedin = function() {
    if (editData.linkedin_url) {
      if (confirm('Choose OK to remove your LinkedIn information.')) {
        editData.linkedin_url = null;
        $analytics.eventTrack('My Profile: Edit: Remove Social Media Link from Profile', {provider: 'LinkedIn'});

      }
    } else {
      var left = document.documentElement.clientWidth/2 - 520/2;
      $scope.linkedinDialog = window.open('/noo/linkedin/authorize', 'linkedinAuth',
        'width=400, height=625, titlebar=no, toolbar=no, menubar=no, left=' + left);
    }
  };

  $scope.finishLinkedinChange = function(url) {
    editData.linkedin_url = url;
    $scope.linkedinDialog.close();
    $analytics.eventTrack('My Profile: Edit: Add Social Media Link to Profile', {provider: 'LinkedIn'});
  };

});

module.exports = function(angularModule) {
  angularModule.controller('ProfileEditCtrl', dependencies);
};
<|endoftext|>