<commit_before>module.exports = function(grunt) {
    grunt.initConfig({
        // 配置文件，参考package.json配置方式，必须设置项是
        // name, version, author
        // name作为gallery发布后的模块名
        // version是版本，也是发布目录
        // author必须是{name: "xxx", email: "xxx"}格式
        pkg: grunt.file.readJSON('package.json'),
        //banner: '/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - ' +
        //    '<%= grunt.template.today("yyyy-mm-dd h:MM:ss TT") %>\n' +
        //    '<%= pkg.homepage ? "* " + pkg.homepage + "\\n" : "" %>' +
        //    '* Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' +
        //    ' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %> */\n',

		// jshint语法检查
		jshint: {
			options: {
				ignores: ["src/config.js"]
			},
			all: ["src/**/*.js"]
		},

		// less->css
		less: {
			dynamic_mappings: {
				files: [
					{
						expand: true,
						cwd: 'src/',
						src: ['**/*.less'],
						dest: 'src/',
						ext: '.css'
					}
				]
			}
		},

		// 页面解析，模块依赖关系抽取
		wtbuild: {
			compile: {
				options: {
					compileOnly: true,
					domain: '<%= pkg.domain%>',
					group: '<%= pkg.group%>',
					project: '<%= pkg.project%>',
					version: '<%= pkg.version%>'
				},
				files: [{
					src: 'src/page/*.{shtml,html}',
					dest: 'build/page'
				}]
			},
			dep: {
				options: {
					packages: [{
						name: 'widget',
						path: 'src/'
					}, {
						name: 'util',
						path: 'src/'
					}],
					depExt: '.dep',
					depOnly: true,
					depFilePath: 'src/mods.js'
				},
				files: [{
					src: 'src/**/*.js'
				}]
			}
		},

        // 压缩js文件
        uglify: {
			dynamic_mappings: {
				files: [
					{
						expand: true,
						cwd: 'src/',
						src: ['**/*.js'],
						dest: 'build/',
						ext: '-min.js'
					}
				]
			}
        },

        // 压缩css文件
        cssmin: {
			dynamic_mappings: {
				files: [
					{
						expand: true,
						cwd: 'src/',
						src: ['**/*.css'],
						dest: 'build/',
						ext: '-min.css'
					}
				]
			}
        },

		// 复制文件
		copy: {
			main: {
				files: [
					{
						expand: true,
						cwd: 'src/',
						src: ['**/*.{js,css}'],
						dest: 'build/'
					}
				]
			}
		}
    });

    // 使用到的任务，可以增加其他任务
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-contrib-cssmin');
    grunt.loadNpmTasks('grunt-contrib-jshint');
    grunt.loadNpmTasks('grunt-contrib-less');
    grunt.loadNpmTasks('grunt-contrib-copy');
    grunt.loadNpmTasks('grunt-wtbuild');
    grunt.registerTask('buildmod', ['wtbuild:dep']);
    grunt.registerTask('default', ['jshint', 'less', 'wtbuild:dep', 'wtbuild:compile', 'uglify', 'cssmin', 'copy']);
    grunt.registerTask('build', ['jshint', 'less', 'wtbuild:dep', 'wtbuild:compile', 'uglify', 'cssmin', 'copy']);
};
<commit_msg>modify<commit_after>module.exports = function(grunt) {
    grunt.initConfig({
        // 配置文件，参考package.json配置方式，必须设置项是
        // name, version, author
        // name作为gallery发布后的模块名
        // version是版本，也是发布目录
        // author必须是{name: "xxx", email: "xxx"}格式
        pkg: grunt.file.readJSON('package.json'),
        //banner: '/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - ' +
        //    '<%= grunt.template.today("yyyy-mm-dd h:MM:ss TT") %>\n' +
        //    '<%= pkg.homepage ? "* " + pkg.homepage + "\\n" : "" %>' +
        //    '* Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' +
        //    ' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %> */\n',

		// jshint语法检查
		jshint: {
			options: {
				ignores: ["src/config.js"]
			},
			all: ["src/**/*.js"]
		},

		// less->css
		less: {
			main: {
				files: [
					{
						expand: true,
						cwd: 'src/',
						src: ['**/*.less'],
						dest: 'src/',
						ext: '.css'
					}
				]
			}
		},

		// 页面解析，模块依赖关系抽取
		wtbuild: {
			compile: {
				options: {
					compileOnly: true,
					domain: '<%= pkg.domain%>',
					group: '<%= pkg.group%>',
					project: '<%= pkg.project%>',
					version: '<%= pkg.version%>'
				},
				files: [{
					src: 'src/page/*.{shtml,html}',
					dest: 'build/page'
				}]
			},
			dep: {
				options: {
					packages: [{
						name: 'widget',
						path: 'src/'
					}, {
						name: 'util',
						path: 'src/'
					}],
					depExt: '.dep',
					depOnly: true,
					depFilePath: 'src/mods.js'
				},
				files: [{
					src: 'src/**/*.js'
				}]
			}
		},

        // 压缩js文件
        uglify: {
			main: {
				files: [
					{
						expand: true,
						cwd: 'src/',
						src: ['**/*.js'],
						dest: 'build/',
						ext: '.js'
					}
				]
			}
        },

        // 压缩css文件
        cssmin: {
			main: {
				files: [
					{
						expand: true,
						cwd: 'src/',
						src: ['**/*.css'],
						dest: 'build/',
						ext: '.css'
					}
				]
			}
        },

		// 复制文件
		//copy: {
		//	main: {
		//		files: [
		//			{
		//				expand: true,
		//				cwd: 'src/',
		//				src: ['**/*.{js,css}'],
		//				dest: 'build/'
		//			}
		//		]
		//	}
		//}
    });

    // 使用到的任务，可以增加其他任务
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-contrib-cssmin');
    grunt.loadNpmTasks('grunt-contrib-jshint');
    grunt.loadNpmTasks('grunt-contrib-less');
    grunt.loadNpmTasks('grunt-contrib-copy');
    grunt.loadNpmTasks('grunt-wtbuild');
    grunt.registerTask('buildmod', ['wtbuild:dep']);
    grunt.registerTask('default', ['jshint', 'less', 'wtbuild:dep', 'wtbuild:compile', 'uglify', 'cssmin']);
    grunt.registerTask('build', ['jshint', 'less', 'wtbuild:dep', 'wtbuild:compile', 'uglify', 'cssmin']);
};
<|endoftext|>


<commit_before>'use strict';

var gulp = require('gulp');

// load plugins
var $ = require('gulp-load-plugins')();

var nodemon = require('nodemon');
var openApp = require('open');

var path = require('path');
var Q = require('q');
var strftime = require('strftime');

var shell = require('shelljs');

var gitRevision = shell.exec('git rev-parse --short HEAD', { silent:true }).output;

var environments = ['dev', 'www'];

var config = {
    pub: 'public',
    pkg: require('./package.json'),
    src: path.resolve('app'),
    app: path.resolve('app', 'public'),
    models: path.resolve('app', 'models'),
    dist: path.resolve('dist'),
    cordova: path.resolve('cordova/www/'),
    buildTarget: 'dev', // ['dev', 'www', 'pub']
    temp: path.resolve('.tmp'),
    test: path.resolve('test'),
    server: path.resolve('app', 'app.js'),
    hostname: 'localhost',
    port: 3000,
    baseUrl: '/',
    today: Date.now(),
    revision: (gitRevision.indexOf('fatal') > -1)?null:gitRevision.replace(/(\r\n|\n|\r)/gm, ''),
    version: require('./package.json').version
};

if (!config.revision) {
    $.util.log($.util.colors.yellow('Git repository missing.'), 'Consider running', $.util.colors.cyan('git init'));
}

var tasks = {
    clean: function (taskTarget) {
        var glob = [config.temp];
        if (taskTarget === 'dist') {
            glob.push(path.join(config.dist, config.buildTarget));
        }
        $.util.log('Cleaning ', $.util.colors.magenta(glob));
        return gulp.src(glob, { read: false })
            .pipe($.rimraf({ force: true }));
    },
    jshint: function () {
        $.util.log('Linting javascript files...');
        var glob = [
            'gulpfile.js',
            path.join(config.src, 'app.js'),
            path.join(config.src, 'routes.js'),
            path.join(config.models, '**/*.js'),
            path.join(config.app, 'components/**/*.js'),
            path.join(config.app, 'controllers/**/*.js'),
            path.join(config.app, 'directives/**/*.js'),
            path.join(config.app, 'scripts/**/*.js'),
            // exclude loopback services file, it fails miserably
            '!' + path.join(config.app, 'scripts/services/lbServices.js')
        ];
        return gulp.src(glob)
            .pipe($.jshint('.jshintrc'))
            .pipe($.jshint.reporter('jshint-stylish'));
    },
    jsonlint: function () {
        $.util.log('Linting JSON files...');
        var glob = [
            '*.json'
        ];
        return gulp.src(glob)
            .pipe($.jsonlint())
            .pipe($.jsonlint.reporter());
    },
    sass: function (taskTarget) {
        $.util.log('Compiling SASS files...');
        var glob = path.join(config.app, 'styles/app.scss');
        var dest = (taskTarget === 'dist')?path.join(config.dist, config.buildTarget, config.pub, 'styles'):path.join(config.temp, 'styles');
        return gulp.src(glob)
            // as the css is not 1-to-1, this doesn't work as expected
            // .pipe($.changed(dest, { extension: '.css' }))
            .pipe($.rubySass({
                sourcemap: true,
                style: (taskTarget === 'dist' && config.buildTarget !== 'dev')?'compressed':'expanded',
                precision: 10,
                lineNumbers: (taskTarget === 'dist')?false:true,
                debugInfo: (taskTarget === 'dist')?false:true
            }))
            .pipe(gulp.dest(dest));
    },
    jade: function (taskTarget) {
        $.util.log('Compiling Jade files...');
        var glob = [path.join(config.app, '**/*.jade'), path.join('!', config.app, '**/_*.jade')];
        var dest = (taskTarget === 'dist')?path.join(config.dist, config.buildTarget, config.pub):config.temp;
        var LOCALS = {
            DEBUG: (taskTarget === 'dist')?false:true,
            LOCAL: (taskTarget === 'dist')?false:true,
            ENV: (taskTarget === 'server')?'local':config.buildTarget,
            GIT_REVISION: config.revision,
            VERSION: 'v' + config.pkg.version,
            DATE_STAMP: strftime('%B %d, %Y %H:%M:%S', new Date(config.today)),
            YEAR: new Date(config.today).getFullYear()
        };
        return gulp.src(glob)
            // as the jade files are not 1-to-1 this doesn't work as expected
            // .pipe($.changed(dest, { extension: '.html' }))
            .pipe($.jade({
                locals: LOCALS,
                pretty: (taskTarget === 'dist' && config.buildTarget !== 'dev')?false:true
            }))
            .pipe(gulp.dest(dest));
    },
    image: function (taskTarget) {
        $.util.log('Minifing image files...');
        var glob = [
            path.join(config.app, 'images/**/*.{png,jpg,jpeg}'),
            path.join(config.app, 'styles/images/**/*.{png,jpg,jpeg}'),
        ];
        var dest = (taskTarget === 'dist')?path.join(config.dist, config.buildTarget, config.pub):config.temp;
        return gulp.src(glob, { base: config.app })
            .pipe($.imagemin())
            .pipe(gulp.dest(dest));
    },
    usemin: function (taskTarget) {
        $.util.log('Processing usemin js blocks in HTML files...');
        var glob = path.join(config.dist, config.buildTarget, config.pub, '*.html');
        var dest = (taskTarget === 'dist')?path.join(config.dist, config.buildTarget, config.pub):config.temp;
        return gulp.src(glob)
            .pipe($.usemin({
                css: ['concat', $.rev()],
                angularJs: ['concat', $.ngAnnotate(), $.uglify(), $.rev()],
                js: ['concat', $.uglify(), $.rev()]
            }))
            .pipe(gulp.dest(dest));
    },
    copyAssets: function (taskTarget) {
        $.util.log('Copying front end assets into build destination...');
        // copy all assets relative to config.app
        var glob = [
            // copy gif files manually as they are not compressed
            path.join(config.app, 'images/**/*.gif'),
            path.join(config.app, 'styles/**/*.gif'),
            path.join(config.app, 'styles/fonts/**/*'),
            path.join(config.app, 'favicon.ico')
        ];
        var dest = (taskTarget === 'dist')?path.join(config.dist, config.buildTarget, config.pub):config.temp;
        return gulp.src(glob, { base: config.app })
            .pipe(gulp.dest(dest));
    },
    copyServer: function (taskTarget) {
        $.util.log('Copying node assets into build destination...');
        // copy all assets relative to config.src
        var glob = [
            path.join(config.models, '**/*'),
            path.join(config.src, 'app.js'),
            path.join(config.src, 'app.json'),
            path.join(config.src, 'datasources.json'),
            path.join(config.src, 'models.json'),
            path.join(config.src, 'views/**/*')
        ];
        var dest = (taskTarget === 'dist')?path.join(config.dist, config.buildTarget):config.temp;
        return gulp.src(glob, { base: config.src })
            .pipe(gulp.dest(dest));
    },
    copyPackage: function (taskTarget) {
        $.util.log('Copying package.json into build destination...');
        // copy all assets relative to root
        var glob = 'package.json';
        var dest = (taskTarget === 'dist')?path.join(config.dist, config.buildTarget):config.temp;
        return gulp.src(glob)
            .pipe(gulp.dest(dest));
    },
    addBanner: function (taskTarget) {
        $.util.log('Add debug header to files...');
        var glob = [
            path.join(config.dist, config.buildTarget, config.pub, '**/*.css'),
            path.join(config.dist, config.buildTarget, config.pub, '**/*.js')
        ];
        var dest = (taskTarget === 'dist')?path.join(config.dist, config.buildTarget, config.pub):config.temp;
        var banner = [
            '/**',
            ' * <%= pkg.name %> - <%= pkg.description %>',
            ' * @version v<%= pkg.version %>',
            ' * @link <%= pkg.homepage %>',
            ' * @license <%= pkg.license %>',
            ' * @revision <%= revision %>',
            ' * @build <%= build %>',
            ' */',
            ''
        ].join('\n');

        return gulp.src(glob)
            .pipe($.header(banner, {
                pkg : config.pkg,
                revision: config.revision,
                build: strftime('%B %d, %Y %H:%M:%S', new Date(config.today))
            }))
            .pipe(gulp.dest(dest));
    }
};

// make individual tasks available
gulp.task('jshint', tasks.jshint);

// taskify individual build and server tasks
var taskList = Object.keys(tasks);

taskList.forEach(function (taskName) {
    // use first environment as default task, should be dev
    gulp.task(taskName, [taskName + ':' + environments[0]]);
    environments.forEach(function (environment) {
        gulp.task(taskName + ':' + environment, function() {
            config.buildTarget = environment;
            return tasks[taskName]('dist');
        });
    });
});

function buildProject () {
    var deferred = Q.defer();
    // List of build task function names
    var taskList = [
        'clean',
        'jshint',
        'jsonlint',
        'sass',
        'jade',
        'image',
        'usemin',
        'copyAssets',
        'copyServer',
        'copyPackage',
        'addBanner'
    ];
    var queue = new Q();
    taskList.forEach(function (task) {
        queue = queue.then(function () {
            // cheap conversion of task stream to promise
            var taskDeferred = Q.defer();
            // call the task name with the task type dist|server
            tasks[task]('dist')
                // not sure if I'm using buffer correctly but it does the trick
                .pipe($.util.buffer(function () {
                    taskDeferred.resolve();
                }));
            return taskDeferred.promise;
        });
    });
    queue = queue.then(function explode() {
        deferred.resolve();
    });
    return deferred.promise;
}

function startServer () {
    var deferred = Q.defer();
    // List of build task function names
    var taskList = [
        'clean',
        'jshint',
        'jsonlint',
        'sass',
        'jade'
    ];
    var queue = new Q();
    taskList.forEach(function (task) {
        queue = queue.then(function () {
            // cheap conversion of task stream to promise
            var taskDeferred = Q.defer();
            // call the task name with the task type dist|server
            tasks[task]('server')
                // not sure if I'm using buffer correctly but it does the trick
                .pipe($.util.buffer(function () {
                    taskDeferred.resolve();
                }));
            return taskDeferred.promise;
        });
    });
    queue = queue.then(function explode() {
        deferred.resolve();
    });
    return deferred.promise;
}

// Gulp Tasks

// allias for build:dev task
gulp.task('build', ['build:dev']);

gulp.task('build:dev', function() {
    config.buildTarget = 'dev';
    return buildProject('dev');
});

gulp.task('build:www', function() {
    config.buildTarget = 'www';
    return buildProject('www');
});

gulp.task('build:prod', function() {
    config.buildTarget = 'prod';
    return buildProject('prod');
});

gulp.task('server', function() {
    startServer().then(function () {
        var server = $.livereload();
        $.util.log('Starting local server...');
        gulp.watch(path.join(config.app, '**/*.{scss,sass}'), function (file) {
            $.util.log('File updated', $.util.colors.magenta(file.path));
            tasks.sass()
                // not sure if I'm using buffer correctly but it does the trick
                .pipe($.util.buffer(function () {
                    server.changed(file.path);
                }));

        });
        gulp.watch(path.join(config.app, '**/*.jade'), function (file) {
            $.util.log('File updated', $.util.colors.magenta(file.path));
            tasks.jade()
                // not sure if I'm using buffer correctly but it does the trick
                .pipe($.util.buffer(function () {
                    server.changed(file.path);
                }));
        });

        var livereloadGlob = [
            path.join(config.app, 'images/**/*.{gif,png,jpg,jpeg}'),
            path.join(config.app, 'styles/images/**/*.{gif,png,jpg,jpeg}'),
            path.join(config.app, 'components/**/*.js'),
            path.join(config.app, 'controllers/**/*.js'),
            path.join(config.app, 'directives/**/*.js'),
            path.join(config.app, 'scripts/**/*.js')
        ];
        gulp.watch(livereloadGlob, function (file) {
            $.util.log('File updated', $.util.colors.magenta(file.path));
            server.changed(file.path);
        });

        nodemon({
            script: config.server,
            args: [
                '--port=' + config.port,
                '--hostname=' + config.hostname,
                '--baseurl=' + config.baseUrl,
                '--local'
            ],
            stdout: false,
            watch: [
                config.server,
                config.models
            ]
        })
            .once('start', function () {
                // delay a second, express is not always immediately ready
                setTimeout(function() {
                    openApp('http://' + config.hostname + ':' + config.port + config.baseUrl);
                }, 1000);
            })
            .on('stdout', function (msg) {
                $.util.log('Server:', $.util.colors.magenta(msg));
            });
    });
});
<commit_msg>- Update default task for individual task list so that they don't impact dist targets - Build tasks are now dynamically built for each environment configured in the environments variable<commit_after>'use strict';

var gulp = require('gulp');

// load plugins
var $ = require('gulp-load-plugins')();

var nodemon = require('nodemon');
var openApp = require('open');

var path = require('path');
var Q = require('q');
var strftime = require('strftime');

var shell = require('shelljs');

var gitRevision = shell.exec('git rev-parse --short HEAD', { silent:true }).output;

var environments = ['dev', 'www'];

var config = {
    pub: 'public',
    pkg: require('./package.json'),
    src: path.resolve('app'),
    app: path.resolve('app', 'public'),
    models: path.resolve('app', 'models'),
    dist: path.resolve('dist'),
    cordova: path.resolve('cordova/www/'),
    buildTarget: 'dev', // ['dev', 'www', 'pub']
    temp: path.resolve('.tmp'),
    test: path.resolve('test'),
    server: path.resolve('app', 'app.js'),
    hostname: 'localhost',
    port: 3000,
    baseUrl: '/',
    today: Date.now(),
    revision: (gitRevision.indexOf('fatal') > -1)?null:gitRevision.replace(/(\r\n|\n|\r)/gm, ''),
    version: require('./package.json').version
};

if (!config.revision) {
    $.util.log($.util.colors.yellow('Git repository missing.'), 'Consider running', $.util.colors.cyan('git init'));
}

var tasks = {
    clean: function (taskTarget) {
        var glob = [config.temp];
        if (taskTarget === 'dist') {
            glob.push(path.join(config.dist, config.buildTarget));
        }
        $.util.log('Cleaning ', $.util.colors.magenta(glob));
        return gulp.src(glob, { read: false })
            .pipe($.rimraf({ force: true }));
    },
    jshint: function () {
        $.util.log('Linting javascript files...');
        var glob = [
            'gulpfile.js',
            path.join(config.src, 'app.js'),
            path.join(config.src, 'routes.js'),
            path.join(config.models, '**/*.js'),
            path.join(config.app, 'components/**/*.js'),
            path.join(config.app, 'controllers/**/*.js'),
            path.join(config.app, 'directives/**/*.js'),
            path.join(config.app, 'scripts/**/*.js'),
            // exclude loopback services file, it fails miserably
            '!' + path.join(config.app, 'scripts/services/lbServices.js')
        ];
        return gulp.src(glob)
            .pipe($.jshint('.jshintrc'))
            .pipe($.jshint.reporter('jshint-stylish'));
    },
    jsonlint: function () {
        $.util.log('Linting JSON files...');
        var glob = [
            '*.json'
        ];
        return gulp.src(glob)
            .pipe($.jsonlint())
            .pipe($.jsonlint.reporter());
    },
    sass: function (taskTarget) {
        $.util.log('Compiling SASS files...');
        var glob = path.join(config.app, 'styles/app.scss');
        var dest = (taskTarget === 'dist')?path.join(config.dist, config.buildTarget, config.pub, 'styles'):path.join(config.temp, 'styles');
        return gulp.src(glob)
            // as the css is not 1-to-1, this doesn't work as expected
            // .pipe($.changed(dest, { extension: '.css' }))
            .pipe($.rubySass({
                sourcemap: true,
                style: (taskTarget === 'dist' && config.buildTarget !== 'dev')?'compressed':'expanded',
                precision: 10,
                lineNumbers: (taskTarget === 'dist')?false:true,
                debugInfo: (taskTarget === 'dist')?false:true
            }))
            .pipe(gulp.dest(dest));
    },
    jade: function (taskTarget) {
        $.util.log('Compiling Jade files...');
        var glob = [path.join(config.app, '**/*.jade'), path.join('!', config.app, '**/_*.jade')];
        var dest = (taskTarget === 'dist')?path.join(config.dist, config.buildTarget, config.pub):config.temp;
        var LOCALS = {
            DEBUG: (taskTarget === 'dist')?false:true,
            LOCAL: (taskTarget === 'dist')?false:true,
            ENV: (taskTarget === 'server')?'local':config.buildTarget,
            GIT_REVISION: config.revision,
            VERSION: 'v' + config.pkg.version,
            DATE_STAMP: strftime('%B %d, %Y %H:%M:%S', new Date(config.today)),
            YEAR: new Date(config.today).getFullYear()
        };
        return gulp.src(glob)
            // as the jade files are not 1-to-1 this doesn't work as expected
            // .pipe($.changed(dest, { extension: '.html' }))
            .pipe($.jade({
                locals: LOCALS,
                pretty: (taskTarget === 'dist' && config.buildTarget !== 'dev')?false:true
            }))
            .pipe(gulp.dest(dest));
    },
    image: function (taskTarget) {
        $.util.log('Minifing image files...');
        var glob = [
            path.join(config.app, 'images/**/*.{png,jpg,jpeg}'),
            path.join(config.app, 'styles/images/**/*.{png,jpg,jpeg}'),
        ];
        var dest = (taskTarget === 'dist')?path.join(config.dist, config.buildTarget, config.pub):config.temp;
        return gulp.src(glob, { base: config.app })
            .pipe($.imagemin())
            .pipe(gulp.dest(dest));
    },
    usemin: function (taskTarget) {
        $.util.log('Processing usemin js blocks in HTML files...');
        var glob = path.join(config.dist, config.buildTarget, config.pub, '*.html');
        var dest = (taskTarget === 'dist')?path.join(config.dist, config.buildTarget, config.pub):config.temp;
        return gulp.src(glob)
            .pipe($.usemin({
                css: ['concat', $.rev()],
                angularJs: ['concat', $.ngAnnotate(), $.uglify(), $.rev()],
                js: ['concat', $.uglify(), $.rev()]
            }))
            .pipe(gulp.dest(dest));
    },
    copyAssets: function (taskTarget) {
        $.util.log('Copying front end assets into build destination...');
        // copy all assets relative to config.app
        var glob = [
            // copy gif files manually as they are not compressed
            path.join(config.app, 'images/**/*.gif'),
            path.join(config.app, 'styles/**/*.gif'),
            path.join(config.app, 'styles/fonts/**/*'),
            path.join(config.app, 'favicon.ico')
        ];
        var dest = (taskTarget === 'dist')?path.join(config.dist, config.buildTarget, config.pub):config.temp;
        return gulp.src(glob, { base: config.app })
            .pipe(gulp.dest(dest));
    },
    copyServer: function (taskTarget) {
        $.util.log('Copying node assets into build destination...');
        // copy all assets relative to config.src
        var glob = [
            path.join(config.models, '**/*'),
            path.join(config.src, 'app.js'),
            path.join(config.src, 'app.json'),
            path.join(config.src, 'datasources.json'),
            path.join(config.src, 'models.json'),
            path.join(config.src, 'views/**/*')
        ];
        var dest = (taskTarget === 'dist')?path.join(config.dist, config.buildTarget):config.temp;
        return gulp.src(glob, { base: config.src })
            .pipe(gulp.dest(dest));
    },
    copyPackage: function (taskTarget) {
        $.util.log('Copying package.json into build destination...');
        // copy all assets relative to root
        var glob = 'package.json';
        var dest = (taskTarget === 'dist')?path.join(config.dist, config.buildTarget):config.temp;
        return gulp.src(glob)
            .pipe(gulp.dest(dest));
    },
    addBanner: function (taskTarget) {
        $.util.log('Add debug header to files...');
        var glob = [
            path.join(config.dist, config.buildTarget, config.pub, '**/*.css'),
            path.join(config.dist, config.buildTarget, config.pub, '**/*.js')
        ];
        var dest = (taskTarget === 'dist')?path.join(config.dist, config.buildTarget, config.pub):config.temp;
        var banner = [
            '/**',
            ' * <%= pkg.name %> - <%= pkg.description %>',
            ' * @version v<%= pkg.version %>',
            ' * @link <%= pkg.homepage %>',
            ' * @license <%= pkg.license %>',
            ' * @revision <%= revision %>',
            ' * @build <%= build %>',
            ' */',
            ''
        ].join('\n');

        return gulp.src(glob)
            .pipe($.header(banner, {
                pkg : config.pkg,
                revision: config.revision,
                build: strftime('%B %d, %Y %H:%M:%S', new Date(config.today))
            }))
            .pipe(gulp.dest(dest));
    }
};

// make individual tasks available
gulp.task('jshint', tasks.jshint);

// taskify individual build and server tasks
var taskList = Object.keys(tasks);

taskList.forEach(function (taskName) {
    gulp.task(taskName, function() {
        return tasks[taskName]();
    });
    environments.forEach(function (environment) {
        gulp.task(taskName + ':' + environment, function() {
            config.buildTarget = environment;
            return tasks[taskName]('dist');
        });
    });
});

function buildProject () {
    var deferred = Q.defer();
    // List of build task function names
    var taskList = [
        'clean',
        'jshint',
        'jsonlint',
        'sass',
        'jade',
        'image',
        'usemin',
        'copyAssets',
        'copyServer',
        'copyPackage',
        'addBanner'
    ];
    var queue = new Q();
    taskList.forEach(function (task) {
        queue = queue.then(function () {
            // cheap conversion of task stream to promise
            var taskDeferred = Q.defer();
            // call the task name with the task type dist|server
            tasks[task]('dist')
                // not sure if I'm using buffer correctly but it does the trick
                .pipe($.util.buffer(function () {
                    taskDeferred.resolve();
                }));
            return taskDeferred.promise;
        });
    });
    queue = queue.then(function explode() {
        deferred.resolve();
    });
    return deferred.promise;
}

function startServer () {
    var deferred = Q.defer();
    // List of build task function names
    var taskList = [
        'clean',
        'jshint',
        'jsonlint',
        'sass',
        'jade'
    ];
    var queue = new Q();
    taskList.forEach(function (task) {
        queue = queue.then(function () {
            // cheap conversion of task stream to promise
            var taskDeferred = Q.defer();
            // call the task name with the task type dist|server
            tasks[task]('server')
                // not sure if I'm using buffer correctly but it does the trick
                .pipe($.util.buffer(function () {
                    taskDeferred.resolve();
                }));
            return taskDeferred.promise;
        });
    });
    queue = queue.then(function explode() {
        deferred.resolve();
    });
    return deferred.promise;
}

// Gulp Tasks

// use first environment as default build alias, should be dev
gulp.task('build', ['build:' + environments[0]]);
environments.forEach(function (environment) {
    gulp.task('build:' + environment, function() {
        config.buildTarget = environment;
        return buildProject(environment);
    });
});

gulp.task('server', function() {
    startServer().then(function () {
        var server = $.livereload();
        $.util.log('Starting local server...');
        gulp.watch(path.join(config.app, '**/*.{scss,sass}'), function (file) {
            $.util.log('File updated', $.util.colors.magenta(file.path));
            tasks.sass()
                // not sure if I'm using buffer correctly but it does the trick
                .pipe($.util.buffer(function () {
                    server.changed(file.path);
                }));

        });
        gulp.watch(path.join(config.app, '**/*.jade'), function (file) {
            $.util.log('File updated', $.util.colors.magenta(file.path));
            tasks.jade()
                // not sure if I'm using buffer correctly but it does the trick
                .pipe($.util.buffer(function () {
                    server.changed(file.path);
                }));
        });

        var livereloadGlob = [
            path.join(config.app, 'images/**/*.{gif,png,jpg,jpeg}'),
            path.join(config.app, 'styles/images/**/*.{gif,png,jpg,jpeg}'),
            path.join(config.app, 'components/**/*.js'),
            path.join(config.app, 'controllers/**/*.js'),
            path.join(config.app, 'directives/**/*.js'),
            path.join(config.app, 'scripts/**/*.js')
        ];
        gulp.watch(livereloadGlob, function (file) {
            $.util.log('File updated', $.util.colors.magenta(file.path));
            server.changed(file.path);
        });

        nodemon({
            script: config.server,
            args: [
                '--port=' + config.port,
                '--hostname=' + config.hostname,
                '--baseurl=' + config.baseUrl,
                '--local'
            ],
            stdout: false,
            watch: [
                config.server,
                config.models
            ]
        })
            .once('start', function () {
                // delay a second, express is not always immediately ready
                setTimeout(function() {
                    openApp('http://' + config.hostname + ':' + config.port + config.baseUrl);
                }, 1000);
            })
            .on('stdout', function (msg) {
                $.util.log('Server:', $.util.colors.magenta(msg));
            });
    });
});
<|endoftext|>


<commit_before>var gulp = require('gulp'),
    jade = require('gulp-jade'),
    less = require('gulp-less'),
    newer = require('gulp-newer'),
    rename = require('gulp-rename'),
    uglify = require('gulp-uglify'),
    requirejs = require('requirejs'),
    imagemin = require('gulp-imagemin'),
    connect = require('gulp-connect'),
    prefixer = require('gulp-autoprefixer'),

    src = {
        js: 'src/**/*.js',
        jade: 'src/index.jade',
        jade_all: 'src/**/index.jade',
        less: 'src/style.less',
        less_all: 'src/**/*.less',
        bower: {
            'js': [
                'bower_components/jquery/jquery.js',
                'bower_components/requirejs/require.js'<% if (bootstrap) { %>,
                'bower_components/bootstrap/dist/js/bootstrap.js'<% } if (backbone) { %>,
                'bower_components/backbone/backbone.js',
                'bower_components/underscore/underscore.js'<% } %>
            ],
            'css': [<% if (bootstrap) { %>
                'bower_components/bootstrap/dist/css/bootstrap.min.css'<% } %>
            ]
        }
    },
    dst = 'dst';

gulp.task('copy-images', function() {
    return gulp.src('images/*')
        .pipe(newer(dst + '/images'))
        .pipe(imagemin({
            progressive: true,
            svgoPlugins: [{removeViewBox: false}]
        }))
        .pipe(gulp.dest(dst + '/images'));
});

gulp.task('copy-vendor-js', function() {
    return gulp.src(src.bower.js)
        .pipe(rename(function(path) {
            path.basename += '.min'
        }))
        .pipe(newer(dst + '/scripts'))
        .pipe(uglify())
        .pipe(gulp.dest(dst + '/scripts'));
});

gulp.task('copy-vendor-css', function() {
    return gulp.src(src.bower.css)
        .pipe(newer(dst))
        .pipe(gulp.dest(dst));
});

gulp.task('js', ['copy-vendor-js'], function() {
    return gulp.src(src.js)
        .pipe(gulp.dest(dst + '/scripts'))
        .pipe(connect.reload());
});

gulp.task('rjs', ['js'], function() {
    return requirejs.optimize({
        baseUrl: dst + '/scripts',
        name: 'script',
        out: dst + '/scripts/script.min.js',
        paths: {
            jquery: 'empty:',
            backbone: 'empty:',
            bootstrap: 'empty:',
            underscore: 'empty:'
        }
    });
});

gulp.task('jade', function() {
    return gulp.src(src.jade)
        .pipe(jade({
            pretty: true,
            data: {
                min: false
            }
        }))
        .on('error', console.log)
        .pipe(gulp.dest(dst))
        .pipe(connect.reload());
});

gulp.task('jade-min', function() {
    return gulp.src(src.jade)
        .pipe(jade({
            pretty: true,
            data: {
                min: true
            }
        }))
        .on('error', console.log)
        .pipe(gulp.dest(dst))
        .pipe(connect.reload());
});

gulp.task('less', ['copy-vendor-css'], function() {
    return gulp.src(src.less)
        .pipe(less({
            optimization: 1
        }))
        .pipe(prefixer('last 2 version', '> 1%', 'ie 8', 'ie 7'))
        .on('error', console.log)
        .pipe(gulp.dest(dst))
        .pipe(connect.reload());
});

gulp.task('less-min', ['copy-vendor-css'], function() {
    return gulp.src(src.less)
        .pipe(less({
            optimization: 1,
            compress: true,
            yuicompress: true
        }))
        .pipe(prefixer('last 2 version', '> 1%', 'ie 8', 'ie 7'))
        .pipe(rename('style.min.css'))
        .on('error', console.log)
        .pipe(gulp.dest(dst))
        .pipe(connect.reload());
});

gulp.task('server', function() {
    connect.server({
        root: 'dst',
        port: 3000,
        livereload: true
    });
});

gulp.task('watch', ['server'], function() {
    gulp.watch(src.js, ['js']);
    gulp.watch(src.jade_all, ['jade']);
    gulp.watch(src.less_all, ['less']);
});

gulp.task('devel', ['js', 'jade', 'less', 'copy-images']);
gulp.task('build', ['rjs', 'jade-min', 'less-min', 'copy-images']);

gulp.task('default', ['devel', 'watch']);
<commit_msg>jade watch fix<commit_after>var gulp = require('gulp'),
    jade = require('gulp-jade'),
    less = require('gulp-less'),
    newer = require('gulp-newer'),
    rename = require('gulp-rename'),
    uglify = require('gulp-uglify'),
    requirejs = require('requirejs'),
    imagemin = require('gulp-imagemin'),
    connect = require('gulp-connect'),
    prefixer = require('gulp-autoprefixer'),

    src = {
        js: 'src/**/*.js',
        jade: 'src/index.jade',
        jade_all: 'src/**/*.jade',
        less: 'src/style.less',
        less_all: 'src/**/*.less',
        bower: {
            'js': [
                'bower_components/jquery/jquery.js',
                'bower_components/requirejs/require.js'<% if (bootstrap) { %>,
                'bower_components/bootstrap/dist/js/bootstrap.js'<% } if (backbone) { %>,
                'bower_components/backbone/backbone.js',
                'bower_components/underscore/underscore.js'<% } %>
            ],
            'css': [<% if (bootstrap) { %>
                'bower_components/bootstrap/dist/css/bootstrap.min.css'<% } %>
            ]
        }
    },
    dst = 'dst';

gulp.task('copy-images', function() {
    return gulp.src('images/*')
        .pipe(newer(dst + '/images'))
        .pipe(imagemin({
            progressive: true,
            svgoPlugins: [{removeViewBox: false}]
        }))
        .pipe(gulp.dest(dst + '/images'));
});

gulp.task('copy-vendor-js', function() {
    return gulp.src(src.bower.js)
        .pipe(rename(function(path) {
            path.basename += '.min'
        }))
        .pipe(newer(dst + '/scripts'))
        .pipe(uglify())
        .pipe(gulp.dest(dst + '/scripts'));
});

gulp.task('copy-vendor-css', function() {
    return gulp.src(src.bower.css)
        .pipe(newer(dst))
        .pipe(gulp.dest(dst));
});

gulp.task('js', ['copy-vendor-js'], function() {
    return gulp.src(src.js)
        .pipe(gulp.dest(dst + '/scripts'))
        .pipe(connect.reload());
});

gulp.task('rjs', ['js'], function() {
    return requirejs.optimize({
        baseUrl: dst + '/scripts',
        name: 'script',
        out: dst + '/scripts/script.min.js',
        paths: {
            jquery: 'empty:',
            backbone: 'empty:',
            bootstrap: 'empty:',
            underscore: 'empty:'
        }
    });
});

gulp.task('jade', function() {
    return gulp.src(src.jade)
        .pipe(jade({
            pretty: true,
            data: {
                min: false
            }
        }))
        .on('error', console.log)
        .pipe(gulp.dest(dst))
        .pipe(connect.reload());
});

gulp.task('jade-min', function() {
    return gulp.src(src.jade)
        .pipe(jade({
            pretty: true,
            data: {
                min: true
            }
        }))
        .on('error', console.log)
        .pipe(gulp.dest(dst))
        .pipe(connect.reload());
});

gulp.task('less', ['copy-vendor-css'], function() {
    return gulp.src(src.less)
        .pipe(less({
            optimization: 1
        }))
        .pipe(prefixer('last 2 version', '> 1%', 'ie 8', 'ie 7'))
        .on('error', console.log)
        .pipe(gulp.dest(dst))
        .pipe(connect.reload());
});

gulp.task('less-min', ['copy-vendor-css'], function() {
    return gulp.src(src.less)
        .pipe(less({
            optimization: 1,
            compress: true,
            yuicompress: true
        }))
        .pipe(prefixer('last 2 version', '> 1%', 'ie 8', 'ie 7'))
        .pipe(rename('style.min.css'))
        .on('error', console.log)
        .pipe(gulp.dest(dst))
        .pipe(connect.reload());
});

gulp.task('server', function() {
    connect.server({
        root: 'dst',
        port: 3000,
        livereload: true
    });
});

gulp.task('watch', ['server'], function() {
    gulp.watch(src.js, ['js']);
    gulp.watch(src.jade_all, ['jade']);
    gulp.watch(src.less_all, ['less']);
});

gulp.task('devel', ['js', 'jade', 'less', 'copy-images']);
gulp.task('build', ['rjs', 'jade-min', 'less-min', 'copy-images']);

gulp.task('default', ['devel', 'watch']);
<|endoftext|>


<commit_before>'use strict';
var util = require('util');
var path = require('path');
var yeoman = require('yeoman-generator');

module.exports = <%= _.capitalize(generatorName) %>Generator;

function <%= _.capitalize(generatorName) %>Generator(args, options, config) {
  yeoman.generators.Base.apply(this, arguments);

  this.on('end', function () {
    console.log('\nI\'m all done. Just run ' + 'npm install & bower install'.bold.yellow + ' to install the required dependencies.');
  });

  this.pkg = JSON.parse(this.readFileAsString(path.join(__dirname, '../package.json')));
}

util.inherits(<%= _.capitalize(generatorName) %>Generator, yeoman.generators.NamedBase);

<%= _.capitalize(generatorName) %>Generator.prototype.askFor = function askFor() {
  var cb = this.async();

  // welcome message
  var welcome =
  '\n     _-----_' +
  '\n    |       |' +
  '\n    |' + '--(o)--'.red + '|   .--------------------------.' +
  '\n   `---------´  |    ' + 'Welcome to Yeoman,'.yellow.bold + '    |' +
  '\n    ' + '( '.yellow + '_' + '´U`'.yellow + '_' + ' )'.yellow + '   |   ' + 'ladies and gentlemen!'.yellow.bold + '  |' +
  '\n    /___A___\\   \'__________________________\'' +
  '\n     |  ~  |'.yellow +
  '\n   __' + '\'.___.\''.yellow + '__' +
  '\n ´   ' + '`  |'.red + '° ' + '´ Y'.red + ' `\n';

  console.log(welcome);

  var prompts = [{
    name: 'someOption',
    message: 'Would you like to enable this option?',
    default: 'Y/n',
    warning: 'Yes: Enabling this will be totally awesome!'
  }];

  this.prompt(prompts, function (err, props) {
    if (err) {
      return this.emit('error', err);
    }

    this.someOption = (/y/i).test(props.someOption);

    cb();
  }.bind(this));
};

<%= _.capitalize(generatorName) %>Generator.prototype.app = function app() {
  this.mkdir('app');
  this.mkdir('app/templates');
};

<%= _.capitalize(generatorName) %>Generator.prototype.projectfiles = function projectfiles() {
  this.copy('editorconfig', '.editorconfig');
  this.copy('jshintrc', '.jshintrc');
};
<commit_msg>Cover new prompt and installDependencies<commit_after>'use strict';
var util = require('util');
var path = require('path');
var yeoman = require('yeoman-generator');

module.exports = <%= _.capitalize(generatorName) %>Generator;

function <%= _.capitalize(generatorName) %>Generator(args, options, config) {
  yeoman.generators.Base.apply(this, arguments);

  this.on('end', function () {
    this.installDependencies();
  });

  this.pkg = JSON.parse(this.readFileAsString(path.join(__dirname, '../package.json')));
}

util.inherits(<%= _.capitalize(generatorName) %>Generator, yeoman.generators.NamedBase);

<%= _.capitalize(generatorName) %>Generator.prototype.askFor = function askFor() {
  var cb = this.async();

  // welcome message
  var welcome =
  '\n     _-----_' +
  '\n    |       |' +
  '\n    |' + '--(o)--'.red + '|   .--------------------------.' +
  '\n   `---------´  |    ' + 'Welcome to Yeoman,'.yellow.bold + '    |' +
  '\n    ' + '( '.yellow + '_' + '´U`'.yellow + '_' + ' )'.yellow + '   |   ' + 'ladies and gentlemen!'.yellow.bold + '  |' +
  '\n    /___A___\\   \'__________________________\'' +
  '\n     |  ~  |'.yellow +
  '\n   __' + '\'.___.\''.yellow + '__' +
  '\n ´   ' + '`  |'.red + '° ' + '´ Y'.red + ' `\n';

  console.log(welcome);

  var prompts = [{
    name: 'someOption',
    message: 'Would you like to enable this option?',
    default: true,
    warning: 'Yes: Enabling this will be totally awesome!'
  }];

  this.prompt(prompts, function (err, props) {
    if (err) {
      return this.emit('error', err);
    }

    this.someOption = props.someOption;

    cb();
  }.bind(this));
};

<%= _.capitalize(generatorName) %>Generator.prototype.app = function app() {
  this.mkdir('app');
  this.mkdir('app/templates');
};

<%= _.capitalize(generatorName) %>Generator.prototype.projectfiles = function projectfiles() {
  this.copy('editorconfig', '.editorconfig');
  this.copy('jshintrc', '.jshintrc');
};
<|endoftext|>


<commit_before>function isObjectId(id) {
  return /^[0-9a-fA-F]{24}$/.test(id);
}

function isEmail(str) {
  return /[^\s@]+@[^\s@]+\.[^\s@]+/.test(str);
}

function isNonEmptyString(str) {
  return typeof str === "string" && str !== "";
}

function isOption(opt) {
  return isNonEmptyString(opt) && (opt === "all" || opt === "latest");
}

function checkLogin(body) {
  if(!isNonEmptyString(body.username)) {
    return "Please enter your username";
  }

  if(!isNonEmptyString(body.password)) {
    return "Plase enter your password";
  }

  return true;
}

function checkRegister(body) {
  if(!isNonEmptyString(body.username)) {
    return "Please enter a valid username";
  }

  if(!isEmail(body.email)) {
    return "Please enter a valid email address";
  }

  if(!isNonEmptyString(body.password)) {
    return "Please enter a password";
  }

  if(!isNonEmptyString(body.confirm_password)) {
    return "Please confirm your password";
  }

  if(body.password !== body.confirm_password) {
    return "Passwords don't match";
  }

  return true;
}

function checkSearch(query) {
  if(typeof query === "object" && !query.q) {
    return "Please enter a valid search string";
  }

  return true;
}

function checkBook(book) {
  if(!book.id || typeof book.hasImage !== "boolean") {
    return "You tried to add an invalid book";
  }
  return true;
}

function checkSettings(body) {
  if(!isNonEmptyString(body.new_pw)) {
    return "Please enter a new password";
  }

  if(!isNonEmptyString(body.confirm_new_pw)) {
    return "Plase confirm your password";
  }

  if(body.new_pw !== body.confirm_new_pw) {
    return "New passwords don't match";
  }

  return true;
}

function checkFind(q) {
  if(q.option) {
    return isOption(q.option) ? true : "Invalid optional search";
  }

  if(!isNonEmptyString(q.query)) {
    return "Please enter a valid search string";
  }

  return true;
}

function stageHasError(body) {
  if(body.nextStages) {
    return stageHasError({ stages: body.nextStages });
  }

  let stages = Object.keys(body.stages);
  let check = ["initiand", "acceptand"];
  var error = false;

  if(stages.length !== 2) {
    return true;
  }

  stages.forEach((stage) => {
    if(check.indexOf(stage) === -1) {
      error = true;
    }
    if(!Array.isArray(body.stages[stage])) {
      error = true;
    }
    body.stages[stage].forEach(id => error = !isObjectId(id) ? true : error);
  });

  return error;
}

const trade = {
  initiate: function(body) {
    let parties = Object.keys(body.parties);
    let check = ["initiand", "acceptand"];
    var error = false;

    parties.forEach((party) => {
      if(check.indexOf(party) === -1) {
        error = true;
      }
      if(!isObjectId(body.parties[party])) {
        error = true;
      }
    });

    error = stageHasError(body);

    if(error) {
      return "invalid payload";
    }

    if(body.parties.initiand === body.parties.acceptand) {
      return "You can't start a trade with yourself";
    }

    return true;
  },
  accept: function(body) {
    if(!isObjectId(body.tradeId) || !isObjectId(body.acceptandId)) {
      return "invalid payload";
    }
    return true;
  },
  decline: function(body) {
    if(!isObjectId(body.tradeId) || !isObjectId(body.declinerId)) {
      return "invalid payload";
    }
    return true;
  },
  negotiate: function(body) {
    if(!isObjectId(body.negotiatorId) || !isObjectId(body.tradeId)) {
      return "invalid payload";
    }
    if(stageHasError(body)) {
      return "invalid payload";
    }
    return true;
  }
};

module.exports = function check_input(type) {
  return function(req, res, next) {
    let isValid;
    switch(type) {
      case "login":
        isValid = checkLogin(req.body);
        break;

      case "register":
        isValid = checkRegister(req.body);
        break;

      case "search":
        isValid = checkSearch(req.query);
        break;

      case "find":
        isValid = checkFind(req.query);
        break;

      case "book":
        isValid = checkBook(req.body);
        break;

      case "settings":
        isValid = checkSettings(req.body);
        break;

      case "trade_initiate":
        isValid = trade.initiate(req.body);
        break;

      case "trade_accept":
        isValid = trade.accept(req.body);
        break;

      case "trade_decline":
        isValid = trade.decline(req.body);
        break;

      case "trade_negotiate":
        isValid = trade.negotiate(req.body);
        break;

      default:
        if(process.env.NODE_ENV !== "production") {
          console.log("Attention! check_input() default case triggerd!");
        }
        return next();
    }

    if(isValid === true) {
      return next();
    }

    res.status(400).send({
      error: {
        message: isValid
      }
    });
  };
};
<commit_msg>simplify error checking code<commit_after>function isObjectId(id) {
  return /^[0-9a-fA-F]{24}$/.test(id);
}

function isEmail(str) {
  return /[^\s@]+@[^\s@]+\.[^\s@]+/.test(str);
}

function isNonEmptyString(str) {
  return typeof str === "string" && str !== "";
}

function isOption(opt) {
  return isNonEmptyString(opt) && (opt === "all" || opt === "latest");
}

function checkLogin(body) {
  if(!isNonEmptyString(body.username)) {
    return "Please enter your username";
  }

  if(!isNonEmptyString(body.password)) {
    return "Plase enter your password";
  }

  return true;
}

function checkRegister(body) {
  if(!isNonEmptyString(body.username)) {
    return "Please enter a valid username";
  }

  if(!isEmail(body.email)) {
    return "Please enter a valid email address";
  }

  if(!isNonEmptyString(body.password)) {
    return "Please enter a password";
  }

  if(!isNonEmptyString(body.confirm_password)) {
    return "Please confirm your password";
  }

  if(body.password !== body.confirm_password) {
    return "Passwords don't match";
  }

  return true;
}

function checkSearch(query) {
  if(typeof query === "object" && !query.q) {
    return "Please enter a valid search string";
  }

  return true;
}

function checkBook(book) {
  if(!book.id || typeof book.hasImage !== "boolean") {
    return "You tried to add an invalid book";
  }
  return true;
}

function checkSettings(body) {
  if(!isNonEmptyString(body.new_pw)) {
    return "Please enter a new password";
  }

  if(!isNonEmptyString(body.confirm_new_pw)) {
    return "Plase confirm your password";
  }

  if(body.new_pw !== body.confirm_new_pw) {
    return "New passwords don't match";
  }

  return true;
}

function checkFind(q) {
  if(q.option) {
    return isOption(q.option) ? true : "Invalid optional search";
  }

  if(!isNonEmptyString(q.query)) {
    return "Please enter a valid search string";
  }

  return true;
}

function stageHasError(body) {
  if(body.nextStages) {
    return stageHasError({ stages: body.nextStages });
  }

  if(!body.stages.initiand || !body.stages.acceptand) {
    return true;
  }

  var error = false;

  let lookForObjectId = (id) => {
    error = !isObjectId(id) ? true : error;
  };

  body.stages.initiand.forEach(lookForObjectId);
  body.stages.acceptand.forEach(lookForObjectId);

  return error;
}

const trade = {
  initiate: function(body) {
    if(!isObjectId(body.parties && body.parties.initiand) || !isObjectId(body.parties && body.parties.acceptand) || stageHasError(body)) {
      return "invalid payload";
    }
    if(body.parties.initiand === body.parties.acceptand) {
      return "You can't start a trade with yourself";
    }
    return true;
  },
  accept: function(body) {
    if(!isObjectId(body.tradeId) || !isObjectId(body.acceptandId)) {
      return "invalid payload";
    }
    return true;
  },
  decline: function(body) {
    if(!isObjectId(body.tradeId) || !isObjectId(body.declinerId)) {
      return "invalid payload";
    }
    return true;
  },
  negotiate: function(body) {
    if(!isObjectId(body.negotiatorId) || !isObjectId(body.tradeId)) {
      return "invalid payload";
    }
    if(stageHasError(body)) {
      return "invalid payload";
    }
    return true;
  }
};

module.exports = function check_input(type) {
  return function(req, res, next) {
    let isValid;
    switch(type) {
      case "login":
        isValid = checkLogin(req.body);
        break;

      case "register":
        isValid = checkRegister(req.body);
        break;

      case "search":
        isValid = checkSearch(req.query);
        break;

      case "find":
        isValid = checkFind(req.query);
        break;

      case "book":
        isValid = checkBook(req.body);
        break;

      case "settings":
        isValid = checkSettings(req.body);
        break;

      case "trade_initiate":
        isValid = trade.initiate(req.body);
        break;

      case "trade_accept":
        isValid = trade.accept(req.body);
        break;

      case "trade_decline":
        isValid = trade.decline(req.body);
        break;

      case "trade_negotiate":
        isValid = trade.negotiate(req.body);
        break;

      default:
        if(process.env.NODE_ENV !== "production") {
          console.log("Attention! check_input() default case triggerd!");
        }
        return next();
    }

    if(isValid === true) {
      return next();
    }

    res.status(400).send({
      error: {
        message: isValid
      }
    });
  };
};
<|endoftext|>


<commit_before>/**
 * @fileoverview Base functions and globals for sactraffic.org.
 * @requires jQuery
 */

/**
 * Global variable for the traffic map.
 * Allows other elements to interact with it if it's defined.
 */
var trafficmap;

/**
 * Setup code for the index page.
 */
function init_index () {
	if (screen.width > 480) {
		trafficmap = new TrafficMap('map');
		trafficmap.show_live_cams();
		//trafficmap.show_gtraffic();

		//TrafficNews.show("#sactraffic_news", "http://www.lectroid.net/category/sactrafficorg/feed/", 7);
	}

	get_incidents(RequestArgs.get('id'));
}

/**
 * Fetches the incident JSON and processes it accordingly.
 */
function get_incidents (id) {
	jQuery.getJSON('/json?dispatch=SACC', function (data) {
		var incidents = new IncidentList(data);
		incidents.makeList(jQuery('#incidentlist'));

		// Refresh the detail box if it's open, fallback to the id param
		var detailboxId = jQuery('#detailbox .incidentID').html();
		if (detailboxId) {
			// See if the incident is still active, if it is refresh it,
			// if not, close it.
			var detailBoxIncident = incidents.getIncidentById(detailboxId);
			if (typeof(detailBoxIncident) === 'undefined') {
				incidents.getIncident(0).hideDetailBox();
			} else {
				incidents.getIncidentById(detailboxId).showDetailBox();
			}
		} else if (typeof (id) !== 'undefined') {
			incidents.getIncidentById(id).showDetailBox();
		}

		if (typeof trafficmap !== 'undefined') {
			trafficmap.update(incidents);
		}

		setTimeout(get_incidents, 60000);
	});
}
<commit_msg>JS style nit.<commit_after>/**
 * @fileoverview Base functions and globals for sactraffic.org.
 * @requires jQuery
 */

/**
 * Global variable for the traffic map.
 * Allows other elements to interact with it if it's defined.
 */
var trafficmap;

/**
 * Setup code for the index page.
 */
var init_index = function () {
	if (screen.width > 480) {
		trafficmap = new TrafficMap('map');
		trafficmap.show_live_cams();
		//trafficmap.show_gtraffic();

		//TrafficNews.show("#sactraffic_news", "http://www.lectroid.net/category/sactrafficorg/feed/", 7);
	}

	get_incidents(RequestArgs.get('id'));
}

/**
 * Fetches the incident JSON and processes it accordingly.
 */
var get_incidents = function (id) {
	jQuery.getJSON('/json?dispatch=SACC', function (data) {
		var incidents = new IncidentList(data);
		incidents.makeList(jQuery('#incidentlist'));

		// Refresh the detail box if it's open, fallback to the id param
		var detailboxId = jQuery('#detailbox .incidentID').html();
		if (detailboxId) {
			// See if the incident is still active, if it is refresh it,
			// if not, close it.
			var detailBoxIncident = incidents.getIncidentById(detailboxId);
			if (typeof(detailBoxIncident) === 'undefined') {
				incidents.getIncident(0).hideDetailBox();
			} else {
				incidents.getIncidentById(detailboxId).showDetailBox();
			}
		} else if (typeof (id) !== 'undefined') {
			incidents.getIncidentById(id).showDetailBox();
		}

		if (typeof trafficmap !== 'undefined') {
			trafficmap.update(incidents);
		}

		setTimeout(get_incidents, 60000);
	});
}
<|endoftext|>


<commit_before>import _ from 'lodash';

import Input from './input.js';

class TextField extends Input {
  constructor(definition = {}) {
    super(definition);

    this.placeholder = definition.placeholder;
    this.size = definition.size;
    this.maxLength = definition.maxLength;
    this.prefix = definition.prefix || "";
    this.suffix = definition.suffix || "";
  }
  getHtmlAttributes() {
    return _.extend(super.getHtmlAttributes(), {
      placeholder: this.placeholder,
      size: this.size,
      maxLength: this.maxLength,
    });
  }
  // getters and setters
  get type() {
    return 'text';
  }
  set placeholder(value) {
    this._props.placeholder = value;
  }
  get placeholder() {
    return this._props.placeholder;
  }
  set size(value) {
    this._props.size = value;
  }
  get size() {
    return this._props.size;
  }
  set maxLength(value) {
    this._props.maxLength = value;
  }
  get maxLength() {
    return this._props.maxLength;
  }
  set prefix(value) {
    this._props.prefix = value;
  }
  get prefix() {
    return this._props.prefix;
  }
  set suffix(value) {
    this._props.suffix = value;
  }
  get suffix() {
    return this._props.suffix;
  }
}

export default TextField;
<commit_msg>eliminated lodash from textfield<commit_after>import Input from './input.js';

class TextField extends Input {
  constructor(definition = {}) {
    super(definition);

    this.placeholder = definition.placeholder;
    this.size = definition.size;
    this.maxLength = definition.maxLength;
    this.prefix = definition.prefix || "";
    this.suffix = definition.suffix || "";
  }
  getHtmlAttributes() {
    return _.extend(super.getHtmlAttributes(), {
      placeholder: this.placeholder,
      size: this.size,
      maxLength: this.maxLength,
    });
  }
  // getters and setters
  get type() {
    return 'text';
  }
  set placeholder(value) {
    this._props.placeholder = value;
  }
  get placeholder() {
    return this._props.placeholder;
  }
  set size(value) {
    this._props.size = value;
  }
  get size() {
    return this._props.size;
  }
  set maxLength(value) {
    this._props.maxLength = value;
  }
  get maxLength() {
    return this._props.maxLength;
  }
  set prefix(value) {
    this._props.prefix = value;
  }
  get prefix() {
    return this._props.prefix;
  }
  set suffix(value) {
    this._props.suffix = value;
  }
  get suffix() {
    return this._props.suffix;
  }
}

export default TextField;
<|endoftext|>


<commit_before>/* See license.txt for terms of usage */

// ************************************************************************************************
// Constants

const CLASS_ID = Components.ID("{2D92593E-14D0-48ce-B260-A9881BBF9C8B}");
const CLASS_NAME = "Firebug HTTP Observer Service";
const CONTRACT_ID = "@joehewitt.com/firebug-http-observer;1";

const Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;

var observerService = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
var categoryManager = Cc["@mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager);

// ************************************************************************************************
// HTTP Request Observer implementation

var FBTrace = null;

/**
 * @service This service is intended as the only HTTP observer registered by Firebug.
 * All FB extensions and Firebug itself should register a listener within this
 * service in order to listen for http-on-modify-request, http-on-examine-response and
 * http-on-examine-cached-response events.
 *
 * See also:
 * Setting_HTTP_request_headers
 */
function HttpRequestObserver()
{
    this.observers = [];
    this.isObserving = false;

    // Get firebug-trace service for logging (the service should be already
    // registered at this moment).
    FBTrace = Cc["@joehewitt.com/firebug-trace-service;1"]
       .getService(Ci.nsISupports).wrappedJSObject.getTracer("extensions.firebug");

    // Get firebug-service to listen for suspendFirebug and resumeFirebug events.
    fbs = Cc["@joehewitt.com/firebug;1"].getService(Ci.nsISupports).wrappedJSObject;

    this.initialize();
}

/* nsIFireBugClient */
var FirebugClient =
{
    disable: function()
    {
        if (gHttpObserverSingleton)
            gHttpObserverSingleton.unregisterObservers();
    },

    enable: function()
    {
        if (gHttpObserverSingleton)
            gHttpObserverSingleton.registerObservers();
    }
}

HttpRequestObserver.prototype =
{
    initialize: function()
    {
        fbs.registerClient(FirebugClient);

        observerService.addObserver(this, "quit-application", false);

        this.registerObservers();

        if (FBTrace.DBG_HTTPOBSERVER)
            FBTrace.sysout("httpObserver.initialize OK");
    },

    shutdown: function()
    {
        fbs.unregisterClient(FirebugClient);

        observerService.removeObserver(this, "quit-application");

        if (FBTrace.DBG_HTTPOBSERVER)
            FBTrace.sysout("httpObserver.shutdown OK");
    },

    registerObservers: function()
    {
        if (FBTrace.DBG_HTTPOBSERVER)
            FBTrace.sysout("httpObserver.registerObservers; wasObserving: " +
                this.isObserving);

        if (this.isObserving)
            return;

        observerService.addObserver(this, "http-on-modify-request", false);
        observerService.addObserver(this, "http-on-examine-response", false);
        observerService.addObserver(this, "http-on-examine-cached-response", false);

        this.isObserving = true;
    },

    unregisterObservers: function()
    {
        if (FBTrace.DBG_HTTPOBSERVER)
            FBTrace.sysout("httpObserver.unregisterObservers; wasObserving: " +
                this.isObserving);

        if (!this.isObserving)
            return;

        observerService.removeObserver(this, "http-on-modify-request");
        observerService.removeObserver(this, "http-on-examine-response");
        observerService.removeObserver(this, "http-on-examine-cached-response");

        this.isObserving = false;
    },

    /* nsIObserve */
    observe: function(subject, topic, data)
    {
        if (topic == "quit-application") {
            this.shutdown();
            return;
        }

        try
        {
            if (FBTrace.DBG_HTTPOBSERVER)
            {
                FBTrace.sysout("httpObserver.observe " + (topic ? topic.toUpperCase() : topic) +
                    ", " + ((subject instanceof Ci.nsIRequest) ? safeGetName(subject) : ""));
            }

            // Notify all registered observers.
            if (topic == "http-on-modify-request" ||
                topic == "http-on-examine-response" ||
                topic == "http-on-examine-cached-response")
            {
                this.notifyObservers(subject, topic, data);
            }
        }
        catch (err)
        {
            if (FBTrace.DBG_ERRORS)
                FBTrace.sysout("httpObserver.observe EXCEPTION", err);
        }
    },

    /* nsIObserverService */
    addObserver: function(observer, topic, weak)
    {
        if (topic != "firebug-http-event")
            throw Cr.NS_ERROR_INVALID_ARG;

        this.observers.push(observer);
    },

    removeObserver: function(observer, topic)
    {
        if (topic != "firebug-http-event")
            throw Cr.NS_ERROR_INVALID_ARG;

        for (var i=0; i<this.observers.length; i++) {
            if (this.observers[i] == observer) {
                this.observers.splice(i, 1);
                return;
            }
        }

        if (FBTrace.DBG_HTTPOBSERVER)
            FBTrace.sysout("httpObserver.removeObserver FAILED (no such observer)");
    },

    notifyObservers: function(subject, topic, data)
    {
        if (FBTrace.DBG_HTTPOBSERVER)
            FBTrace.sysout("httpObserver.notifyObservers (" + this.observers.length + ") " + topic);

        for (var i=0; i<this.observers.length; i++)
            this.observers[i].observe(subject, topic, data);
    },

    enumerateObservers: function(topic)
    {
        return null;
    },

    /* nsISupports */
    QueryInterface: function(iid)
    {
        if (iid.equals(Ci.nsISupports) ||
            iid.equals(Ci.nsIObserverService) ||
            iid.equals(Ci.nsIObserver)) {
            return this;
        }

        throw Cr.NS_ERROR_NO_INTERFACE;
    }
}

function safeGetName(request)
{
    try
    {
        return request.name;
    }
    catch (exc)
    {
        return null;
    }
}

// ************************************************************************************************
// Service factory

var gHttpObserverSingleton = null;
var HttpRequestObserverFactory =
{
    createInstance: function (outer, iid)
    {
        if (outer != null)
            throw Cr.NS_ERROR_NO_AGGREGATION;

        if (iid.equals(Ci.nsISupports) ||
            iid.equals(Ci.nsIObserverService) ||
            iid.equals(Ci.nsIObserver))
        {
            if (!gHttpObserverSingleton)
                gHttpObserverSingleton = new HttpRequestObserver();
            return gHttpObserverSingleton.QueryInterface(iid);
        }

        throw Cr.NS_ERROR_NO_INTERFACE;
    },

    QueryInterface: function(iid)
    {
        if (iid.equals(Ci.nsISupports) ||
            iid.equals(Ci.nsISupportsWeakReference) ||
            iid.equals(Ci.nsIFactory))
            return this;

        throw Cr.NS_ERROR_NO_INTERFACE;
    }
};

// ************************************************************************************************
// Module implementation

var HttpRequestObserverModule =
{
    registerSelf: function (compMgr, fileSpec, location, type)
    {
        compMgr = compMgr.QueryInterface(Ci.nsIComponentRegistrar);
        compMgr.registerFactoryLocation(CLASS_ID, CLASS_NAME,
            CONTRACT_ID, fileSpec, location, type);
    },

    unregisterSelf: function(compMgr, fileSpec, location)
    {
        compMgr = compMgr.QueryInterface(Ci.nsIComponentRegistrar);
        compMgr.unregisterFactoryLocation(CLASS_ID, location);
    },

    getClassObject: function (compMgr, cid, iid)
    {
        if (!iid.equals(Ci.nsIFactory))
            throw Cr.NS_ERROR_NOT_IMPLEMENTED;

        if (cid.equals(CLASS_ID))
            return HttpRequestObserverFactory;

        throw Cr.NS_ERROR_NO_INTERFACE;
    },

    canUnload: function(compMgr)
    {
        return true;
    }
};

// ************************************************************************************************

function NSGetModule(compMgr, fileSpec)
{
    return HttpRequestObserverModule;
}
<commit_msg>define var fbs<commit_after>/* See license.txt for terms of usage */

// ************************************************************************************************
// Constants

const CLASS_ID = Components.ID("{2D92593E-14D0-48ce-B260-A9881BBF9C8B}");
const CLASS_NAME = "Firebug HTTP Observer Service";
const CONTRACT_ID = "@joehewitt.com/firebug-http-observer;1";

const Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;

var observerService = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
var categoryManager = Cc["@mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager);

// ************************************************************************************************
// HTTP Request Observer implementation

var FBTrace = null;
var fbs = null;

/**
 * @service This service is intended as the only HTTP observer registered by Firebug.
 * All FB extensions and Firebug itself should register a listener within this
 * service in order to listen for http-on-modify-request, http-on-examine-response and
 * http-on-examine-cached-response events.
 *
 * See also:
 * Setting_HTTP_request_headers
 */
function HttpRequestObserver()
{
    this.observers = [];
    this.isObserving = false;

    // Get firebug-trace service for logging (the service should be already
    // registered at this moment).
    FBTrace = Cc["@joehewitt.com/firebug-trace-service;1"]
       .getService(Ci.nsISupports).wrappedJSObject.getTracer("extensions.firebug");

    // Get firebug-service to listen for suspendFirebug and resumeFirebug events.
    fbs = Cc["@joehewitt.com/firebug;1"].getService(Ci.nsISupports).wrappedJSObject;

    this.initialize();
}

/* nsIFireBugClient */
var FirebugClient =
{
    disable: function()
    {
        if (gHttpObserverSingleton)
            gHttpObserverSingleton.unregisterObservers();
    },

    enable: function()
    {
        if (gHttpObserverSingleton)
            gHttpObserverSingleton.registerObservers();
    }
}

HttpRequestObserver.prototype =
{
    initialize: function()
    {
        fbs.registerClient(FirebugClient);

        observerService.addObserver(this, "quit-application", false);

        this.registerObservers();

        if (FBTrace.DBG_HTTPOBSERVER)
            FBTrace.sysout("httpObserver.initialize OK");
    },

    shutdown: function()
    {
        fbs.unregisterClient(FirebugClient);

        observerService.removeObserver(this, "quit-application");

        if (FBTrace.DBG_HTTPOBSERVER)
            FBTrace.sysout("httpObserver.shutdown OK");
    },

    registerObservers: function()
    {
        if (FBTrace.DBG_HTTPOBSERVER)
            FBTrace.sysout("httpObserver.registerObservers; wasObserving: " +
                this.isObserving);

        if (this.isObserving)
            return;

        observerService.addObserver(this, "http-on-modify-request", false);
        observerService.addObserver(this, "http-on-examine-response", false);
        observerService.addObserver(this, "http-on-examine-cached-response", false);

        this.isObserving = true;
    },

    unregisterObservers: function()
    {
        if (FBTrace.DBG_HTTPOBSERVER)
            FBTrace.sysout("httpObserver.unregisterObservers; wasObserving: " +
                this.isObserving);

        if (!this.isObserving)
            return;

        observerService.removeObserver(this, "http-on-modify-request");
        observerService.removeObserver(this, "http-on-examine-response");
        observerService.removeObserver(this, "http-on-examine-cached-response");

        this.isObserving = false;
    },

    /* nsIObserve */
    observe: function(subject, topic, data)
    {
        if (topic == "quit-application") {
            this.shutdown();
            return;
        }

        try
        {
            if (FBTrace.DBG_HTTPOBSERVER)
            {
                FBTrace.sysout("httpObserver.observe " + (topic ? topic.toUpperCase() : topic) +
                    ", " + ((subject instanceof Ci.nsIRequest) ? safeGetName(subject) : ""));
            }

            // Notify all registered observers.
            if (topic == "http-on-modify-request" ||
                topic == "http-on-examine-response" ||
                topic == "http-on-examine-cached-response")
            {
                this.notifyObservers(subject, topic, data);
            }
        }
        catch (err)
        {
            if (FBTrace.DBG_ERRORS)
                FBTrace.sysout("httpObserver.observe EXCEPTION", err);
        }
    },

    /* nsIObserverService */
    addObserver: function(observer, topic, weak)
    {
        if (topic != "firebug-http-event")
            throw Cr.NS_ERROR_INVALID_ARG;

        this.observers.push(observer);
    },

    removeObserver: function(observer, topic)
    {
        if (topic != "firebug-http-event")
            throw Cr.NS_ERROR_INVALID_ARG;

        for (var i=0; i<this.observers.length; i++) {
            if (this.observers[i] == observer) {
                this.observers.splice(i, 1);
                return;
            }
        }

        if (FBTrace.DBG_HTTPOBSERVER)
            FBTrace.sysout("httpObserver.removeObserver FAILED (no such observer)");
    },

    notifyObservers: function(subject, topic, data)
    {
        if (FBTrace.DBG_HTTPOBSERVER)
            FBTrace.sysout("httpObserver.notifyObservers (" + this.observers.length + ") " + topic);

        for (var i=0; i<this.observers.length; i++)
            this.observers[i].observe(subject, topic, data);
    },

    enumerateObservers: function(topic)
    {
        return null;
    },

    /* nsISupports */
    QueryInterface: function(iid)
    {
        if (iid.equals(Ci.nsISupports) ||
            iid.equals(Ci.nsIObserverService) ||
            iid.equals(Ci.nsIObserver)) {
            return this;
        }

        throw Cr.NS_ERROR_NO_INTERFACE;
    }
}

function safeGetName(request)
{
    try
    {
        return request.name;
    }
    catch (exc)
    {
        return null;
    }
}

// ************************************************************************************************
// Service factory

var gHttpObserverSingleton = null;
var HttpRequestObserverFactory =
{
    createInstance: function (outer, iid)
    {
        if (outer != null)
            throw Cr.NS_ERROR_NO_AGGREGATION;

        if (iid.equals(Ci.nsISupports) ||
            iid.equals(Ci.nsIObserverService) ||
            iid.equals(Ci.nsIObserver))
        {
            if (!gHttpObserverSingleton)
                gHttpObserverSingleton = new HttpRequestObserver();
            return gHttpObserverSingleton.QueryInterface(iid);
        }

        throw Cr.NS_ERROR_NO_INTERFACE;
    },

    QueryInterface: function(iid)
    {
        if (iid.equals(Ci.nsISupports) ||
            iid.equals(Ci.nsISupportsWeakReference) ||
            iid.equals(Ci.nsIFactory))
            return this;

        throw Cr.NS_ERROR_NO_INTERFACE;
    }
};

// ************************************************************************************************
// Module implementation

var HttpRequestObserverModule =
{
    registerSelf: function (compMgr, fileSpec, location, type)
    {
        compMgr = compMgr.QueryInterface(Ci.nsIComponentRegistrar);
        compMgr.registerFactoryLocation(CLASS_ID, CLASS_NAME,
            CONTRACT_ID, fileSpec, location, type);
    },

    unregisterSelf: function(compMgr, fileSpec, location)
    {
        compMgr = compMgr.QueryInterface(Ci.nsIComponentRegistrar);
        compMgr.unregisterFactoryLocation(CLASS_ID, location);
    },

    getClassObject: function (compMgr, cid, iid)
    {
        if (!iid.equals(Ci.nsIFactory))
            throw Cr.NS_ERROR_NOT_IMPLEMENTED;

        if (cid.equals(CLASS_ID))
            return HttpRequestObserverFactory;

        throw Cr.NS_ERROR_NO_INTERFACE;
    },

    canUnload: function(compMgr)
    {
        return true;
    }
};

// ************************************************************************************************

function NSGetModule(compMgr, fileSpec)
{
    return HttpRequestObserverModule;
}
<|endoftext|>


<commit_before>import AWS from 'aws-sdk/lib/core'
import 'aws-sdk/lib/credentials'
import * as React from 'react'
import * as reduxHook from 'redux-react-hook'

import * as Auth from 'containers/Auth'
import * as APIConnector from 'utils/APIConnector'
import useMemoEq from 'utils/useMemoEq'

class RegistryCredentials extends AWS.Credentials {
  constructor({ req }) {
    super()
    this.req = req
  }

  refresh(callback) {
    if (!this.refreshing) {
      this.refreshing = this.req({ endpoint: '/auth/get_credentials' })
        .then((data) => {
          this.expireTime = new Date(data.Expiration)
          this.accessKeyId = data.AccessKeyId
          this.secretAccessKey = data.SecretAccessKey
          this.sessionToken = data.SessionToken
          delete this.refreshing
          if (callback) callback()
        })
        .catch((e) => {
          delete this.refreshing
          if (callback) callback(e)
          throw e
        })
    }
    return this.refreshing
  }

  suspend() {
    if (this.needsRefresh()) throw this.refresh()
    return this
  }
}

class EmptyCredentials extends AWS.Credentials {
  suspend() {
    return this
  }
}

const useCredentialsMemo = () => {
  const empty = React.useMemo(() => new EmptyCredentials(), [])
  const reg = useMemoEq(APIConnector.use(), (req) => new RegistryCredentials({ req }))

  return useMemoEq(
    {
      auth: reduxHook.useMappedState(Auth.selectors.authenticated),
      reg,
      empty,
    },
    (i) => (i.auth ? i.reg : i.empty),
  )
}

const Ctx = React.createContext()

export const Provider = ({ children }) => (
  <Ctx.Provider value={useCredentialsMemo()}>{children}</Ctx.Provider>
)

export const useCredentials = () => React.useContext(Ctx)

export const use = useCredentials
<commit_msg>fix retries when unable to get aws credentials (#1029)<commit_after>import AWS from 'aws-sdk/lib/core'
import 'aws-sdk/lib/credentials'
import * as React from 'react'
import * as reduxHook from 'redux-react-hook'

import * as Auth from 'containers/Auth'
import * as APIConnector from 'utils/APIConnector'
import useMemoEq from 'utils/useMemoEq'

class RegistryCredentials extends AWS.Credentials {
  constructor({ req }) {
    super()
    this.req = req
  }

  refresh(callback) {
    if (!this.refreshing) {
      this.refreshing = this.req({ endpoint: '/auth/get_credentials' })
        .then((data) => {
          this.expireTime = new Date(data.Expiration)
          this.accessKeyId = data.AccessKeyId
          this.secretAccessKey = data.SecretAccessKey
          this.sessionToken = data.SessionToken
          delete this.refreshing
          if (callback) callback()
        })
        .catch((e) => {
          delete this.refreshing
          this.error = new Error(`Unable to fetch AWS credentials: ${e}`)
          if (callback) callback(this.error)
          throw this.error
        })
    }
    return this.refreshing
  }

  suspend() {
    if (this.error) throw this.error
    if (this.needsRefresh()) throw this.refresh()
    return this
  }
}

class EmptyCredentials extends AWS.Credentials {
  suspend() {
    return this
  }
}

const useCredentialsMemo = () => {
  const empty = React.useMemo(() => new EmptyCredentials(), [])
  const reg = useMemoEq(APIConnector.use(), (req) => new RegistryCredentials({ req }))

  return useMemoEq(
    {
      auth: reduxHook.useMappedState(Auth.selectors.authenticated),
      reg,
      empty,
    },
    (i) => (i.auth ? i.reg : i.empty),
  )
}

const Ctx = React.createContext()

export const Provider = ({ children }) => (
  <Ctx.Provider value={useCredentialsMemo()}>{children}</Ctx.Provider>
)

export const useCredentials = () => React.useContext(Ctx)

export const use = useCredentials
<|endoftext|>


<commit_before>var hzLinks = document.getElementsByTagName('a');
for (var i=0, l=hzLinks.length; i < l; i++) {
	hzLinks[i].addEventListener('mouseenter', hzMouseOn, false);
	hzLinks[i].addEventListener('mouseleave', hzMouseOff, false);
}

var hzDiv = document.createElement('div');
hzDiv.id = 'hzDiv';
hzDiv.resize = function(width, height){
	var x = width;
	var y = height;
	var r = window.devicePixelRatio * (self.options.maxSize / 100);
	var maxX = document.documentElement.clientWidth * r;
	var maxY = document.documentElement.clientHeight * r;
	if((x > maxX) || (y > maxY)){
		var rX = maxX / x;
		var rY = maxY / y;
		if(rX < rY){
			x = Math.floor(x * rX);
			y = Math.floor(y * rX);
		}else{
			x = Math.floor(x * rY);
			y = Math.floor(y * rY);
		}
	}
	this.style.width = x+"px";
	this.style.height = y+"px";
	this.style.marginLeft = Math.floor(x / -2)+"px";
	this.style.marginTop = Math.floor(y / -2)+"px";
}
hzDiv.show = function(el){
	switch(el.toLowerCase()){
		case 'image':
			hzVideo.style.display = 'none';
			hzImg.style.display = 'block';
			break;
		case 'video':
			hzImg.style.display = 'none';
			hzVideo.style.display = 'block';
			break;
		default:
			console.log('panel "show" called with no valid options, oops!');
			return;
	}
	this.style.display = 'block';
	hzText.set();
	if(self.options.keys){ window.addEventListener('keydown', hzKey, false) }
	window.addEventListener('scroll', hzMouseOff, false);
	window.addEventListener('wheel', hzWheel, false);
}
hzDiv.hide = function(){
	window.removeEventListener('keydown', hzKey, false);
	window.removeEventListener('scroll', hzMouseOff, false);
	window.removeEventListener('wheel', hzWheel, false);
	hzDiv.style.display = 'none';
	hzImg.src = null;
	hzVideo.src = null;
}
hzDiv.visit = function(e){
	if(self.options.addHist > 0){
		url = hzCurUrl;
		hzWait = setTimeout(function(){ self.port.emit('visit', url) }, self.options.addHist)
	}
}
hzDiv.style.width = "100px";
hzDiv.style.height = "100px";
hzDiv.addEventListener('show', hzDiv.visit, false);
document.body.appendChild(hzDiv);
//hzDiv.hide();

var hzImg = document.createElement('img');
hzImg.load = function(url, src) {
	var i = document.createElement('img');
	i.url = url;
	i.addEventListener('load', function(){ hzImg.show(this.url, this.src) });
	i.src = src;
}
hzImg.show = function(url, src){
	if(url == hzCurUrl){
		var i = self.options.delay - (new Date().getTime() - hzMark);
		if(i > 0) {
			hzWait = setTimeout( function(){ hzImg.show(url, src) }, i);
		} else {
			this.src = src;
		}
	}
}
hzImg.addEventListener('load', function(e){
	hzDiv.resize(this.naturalWidth, this.naturalHeight);
	hzDiv.show('image');
});
hzDiv.appendChild(hzImg);

var hzText = document.createElement('div');
hzText.set = function(){
	while(this.firstChild){ this.removeChild(this.firstChild) }
	if(hzAlbumImgs.length > 1){
		this.appendChild(document.createTextNode((hzAlbumImgIndex+1)+"/"+hzAlbumImgs.length));
	}else{
		this.appendChild(document.createTextNode(""));
	}
}
hzDiv.appendChild(hzText);

var hzVideo = document.createElement('video');
hzVideo.load = function(url, src){
	var v = document.createElement('video');
	v.url = url;
	v.addEventListener('canplay', function(){ hzVideo.show(this.url, this.src) });
	v.src = src;
	v.autoplay = true;
	v.muted = true;
	v.load();
}
hzVideo.show = function(url, src){
	if(url == hzCurUrl) {
		var i = self.options.delay - (new Date().getTime() - hzMark);
		if(i > 0) {
			hzWait = setTimeout( function(){ hzVideo.show(url, src) }, i);
		} else {
			this.src = src;
		}
	}
}
hzVideo.addEventListener('canplay', function(e){
	hzDiv.resize(this.videoWidth, this.videoHeight);
	hzDiv.show('video');
});
hzVideo.autoplay = true;
hzVideo.loop = true;
hzVideo.muted = true;
hzDiv.appendChild(hzVideo);

function hzKey(e){
	switch(e.keyCode){
		case 37:
			e.deltaY = -1; //left
			break;
		case 39:
			e.deltaY = 1; //right
			break;
	}
	if(e.deltaY){ hzWheel(e) }
}
function hzWheel(e){
	if(hzAlbumImgs.length > 1){
		e.preventDefault();
		e.stopPropagation();
		if(e.deltaY > 0){
			++hzAlbumImgIndex;
			if(hzAlbumImgIndex > hzAlbumImgs.length - 1) { hzAlbumImgIndex = 0 }
		} else if(e.deltaY < 0){
			--hzAlbumImgIndex;
			if(hzAlbumImgIndex < 0){ hzAlbumImgIndex = hzAlbumImgs.length - 1 }
		}
		hzImg.show(hzCurUrl, hzAlbumImgs[hzAlbumImgIndex]);
	}
}

var hzTarget = document.createElement('a');
var hzAlbumImgs, hzAlbumImgIndex, hzCurUrl, hzMark, hzWait;
function hzMouseOn(e){
	if(hzWait){
		if(hzWait.abort){ hzWait.abort() }else{ clearTimeout(hzWait) }
		hzWait = null
	}
	hzDiv.hide();
	hzCurUrl = '';
	hzAlbumImgs = [];
	if(e){
		hzMark = new Date().getTime();
		hzCurUrl = e.target.toString();
		hzTarget.href = hzCurUrl;
		var p = hzTarget.pathname.split('.').reverse();
		if(/bmp|jpeg|jpg|png/i.test(p[0])){ hzImg.load(hzCurUrl, hzTarget.href) }
		else if(/mp4|webm/i.test(p[0])){ hzVideo.load(hzCurUrl, hzTarget.href) }
		else{
			p = hzTarget.hostname.split('.').reverse();
			switch((p[1]+"."+p[0]).toLowerCase()){
				case 'gfycat.com':
					self.port.emit('load', hzCurUrl, hzTarget.protocol+"//gfycat.com/"+hzTarget.pathname.split('.')[0]);
					break;
				case 'imgflip.com':
					p = hzTarget.pathname.split('/');
					if(p.length > 2){ hzTarget.href = hzTarget.protocol+"//i.imgflip.com/"+p[2].split('#')[0]+".jpg" }
					break;
				case 'imgur.com':
					var alb = "";
	 				p = hzTarget.pathname.split('/');
					switch(p[1].toLowerCase()){
						case 'a':
							alb = "https://api.imgur.com/3/album/"+p[2]
						case 'gallery':
							alb = alb || "https://api.imgur.com/3/gallery/"+p[2]
							hzWait = $.ajax({ src:hzCurUrl, url:alb, type:'GET', datatype:'json', beforeSend:function(h){ h.setRequestHeader('Authorization', 'Client-ID f781dcd19302057') },
								success:function(d){
									var delay = 0;
									if(d['data']['images']){
										$.each(d['data']['images'], function(i,v){
											setTimeout( function(){ new Image().src = v['link'] }, delay);
											delay += 1000;
											hzAlbumImgs.push(v['link']);
										});
									} else if(d['data']['link']){
										hzAlbumImgs.push(d['data']['link']);
									}
									if(hzAlbumImgs.length > 0){
										hzImg.load(this.src, hzAlbumImgs[0]);
										hzAlbumImgIndex = 0;
									}
								}
							});
							return;
					}
					hzTarget.pathname = hzTarget.pathname.split('/').pop();
					hzTarget.href = hzTarget.href.split('?')[0].split(',')[0].split('#')[0];
					if(hzTarget.pathname.split('.').length == 1){ hzTarget.href += ".jpg" }
					switch(hzTarget.pathname.split('.').reverse()[0].toLowerCase()) {
						case 'gif':
							hzTarget.href += "v";
						case 'gifv':
							self.port.emit('load', hzCurUrl, hzTarget.href);
							break;
					}
					break;
				case 'livememe.com':
					hzTarget.href = hzTarget.protocol+"//i.lvme.me"+hzTarget.pathname+".jpg";
					break;
				case 'vidble.com':
					hzWait = $.ajax({ src:hzCurUrl, url:hzTarget.href+'?json=1', type:'GET', datatype:'json',
						success:function(d){
							var delay = 0;
							$.each(d['pics'], function(i,v){
								setTimeout( function(){ new Image().src = v }, delay);
								delay += 1000;
								hzAlbumImgs.push(v);
							});
							if(hzAlbumImgs.length > 0) {
								hzImg.load(this.src, hzAlbumImgs[0]);
								hzAlbumImgIndex = 0;
							}
						}
					});
					return;
				case '500px.com':
				case 'artstation.com':
				case 'craigslist.org':
				case 'deviantart.com':
				case 'explosm.net':
				case 'facebook.com':
				case 'flic.kr':
				case 'flickr.com':
				case 'gifyoutube.com':
				case 'gyazo.com':
				case 'instagram.com':
				case 'makeameme.org':
				case 'mypixa.com':
//				case 'pinterest.com':
				case 'swirl.xyz':
				case 'tumblr.com':
				case 'twitter.com':
				case 'vid.me':
				case 'vine.co':
					self.port.emit('load', hzCurUrl, hzTarget.href);
					break;
			}
			hzImg.load(hzCurUrl, hzTarget.href);
//console.log(hzTarget.href);
		}
	}else{
		hzImg.load(hzCurUrl, 'about:blank');
	}
}
function hzMouseOff(e){ hzMouseOn(null) }

self.port.on('image', function(url, imgs){
	hzAlbumImgs = imgs;
	hzAlbumImgIndex = 0;
	hzImg.load(url, hzAlbumImgs[0]);
console.log("loading : " + url);
});

self.port.on('video', function(url, vid){
	hzVideo.load(url, vid);
console.log("loading : " + url);
});
<commit_msg>added some debugging<commit_after>var hzLinks = document.getElementsByTagName('a');
for (var i=0, l=hzLinks.length; i < l; i++) {
	hzLinks[i].addEventListener('mouseenter', hzMouseOn, false);
	hzLinks[i].addEventListener('mouseleave', hzMouseOff, false);
}

var hzDiv = document.createElement('div');
hzDiv.id = 'hzDiv';
hzDiv.resize = function(width, height){
	var x = width;
	var y = height;
	var r = window.devicePixelRatio * (self.options.maxSize / 100);
	var maxX = document.documentElement.clientWidth * r;
	var maxY = document.documentElement.clientHeight * r;
	if((x > maxX) || (y > maxY)){
		var rX = maxX / x;
		var rY = maxY / y;
		if(rX < rY){
			x = Math.floor(x * rX);
			y = Math.floor(y * rX);
		}else{
			x = Math.floor(x * rY);
			y = Math.floor(y * rY);
		}
	}
	this.style.width = x+"px";
	this.style.height = y+"px";
	this.style.marginLeft = Math.floor(x / -2)+"px";
	this.style.marginTop = Math.floor(y / -2)+"px";
}
hzDiv.show = function(el){
	switch(el.toLowerCase()){
		case 'image':
			hzVideo.style.display = 'none';
			hzImg.style.display = 'block';
			break;
		case 'video':
			hzImg.style.display = 'none';
			hzVideo.style.display = 'block';
			break;
		default:
			console.log('panel "show" called with no valid options, oops!');
			return;
	}
	this.style.display = 'block';
	hzText.set();
	if(self.options.keys){ window.addEventListener('keydown', hzKey, false) }
	window.addEventListener('scroll', hzMouseOff, false);
	window.addEventListener('wheel', hzWheel, false);
}
hzDiv.hide = function(){
	window.removeEventListener('keydown', hzKey, false);
	window.removeEventListener('scroll', hzMouseOff, false);
	window.removeEventListener('wheel', hzWheel, false);
	hzDiv.style.display = 'none';
	hzImg.src = null;
	hzVideo.src = null;
}
hzDiv.visit = function(e){
	if(self.options.addHist > 0){
		console.log("adding to history : "+url)
		url = hzCurUrl;
		hzWait = setTimeout(function(){ self.port.emit('visit', url) }, self.options.addHist)
	}
}
hzDiv.style.width = "100px";
hzDiv.style.height = "100px";
hzDiv.addEventListener('show', hzDiv.visit, false);
document.body.appendChild(hzDiv);
//hzDiv.hide();

var hzImg = document.createElement('img');
hzImg.load = function(url, src) {
	var i = document.createElement('img');
	i.url = url;
	i.addEventListener('load', function(){ hzImg.show(this.url, this.src) });
	i.src = src;
}
hzImg.show = function(url, src){
	if(url == hzCurUrl){
		var i = self.options.delay - (new Date().getTime() - hzMark);
		if(i > 0) {
			console.log("delaying popup : "+i);
			hzWait = setTimeout( function(){ hzImg.show(url, src) }, i);
		} else {
			this.src = src;
		}
	}
}
hzImg.addEventListener('load', function(e){
	hzDiv.resize(this.naturalWidth, this.naturalHeight);
	hzDiv.show('image');
});
hzDiv.appendChild(hzImg);

var hzText = document.createElement('div');
hzText.set = function(){
	while(this.firstChild){ this.removeChild(this.firstChild) }
	if(hzAlbumImgs.length > 1){
		this.appendChild(document.createTextNode((hzAlbumImgIndex+1)+"/"+hzAlbumImgs.length));
	}else{
		this.appendChild(document.createTextNode(""));
	}
}
hzDiv.appendChild(hzText);

var hzVideo = document.createElement('video');
hzVideo.load = function(url, src){
	var v = document.createElement('video');
	v.url = url;
	v.addEventListener('canplay', function(){ hzVideo.show(this.url, this.src) });
	v.src = src;
	v.autoplay = true;
	v.muted = true;
//	v.load();
}
hzVideo.show = function(url, src){
	if(url == hzCurUrl) {
		var i = self.options.delay - (new Date().getTime() - hzMark);
		if(i > 0) {
			console.log("delaying popup : "+i);
			hzWait = setTimeout( function(){ hzVideo.show(url, src) }, i);
		} else {
			this.src = src;
		}
	}
}
hzVideo.addEventListener('canplay', function(e){
	hzDiv.resize(this.videoWidth, this.videoHeight);
	hzDiv.show('video');
});
hzVideo.autoplay = true;
hzVideo.loop = true;
hzVideo.muted = true;
hzDiv.appendChild(hzVideo);

function hzKey(e){
	switch(e.keyCode){
		case 37:
			e.deltaY = -1; //left
			break;
		case 39:
			e.deltaY = 1; //right
			break;
	}
	if(e.deltaY){ hzWheel(e) }
}
function hzWheel(e){
	if(hzAlbumImgs.length > 1){
		e.preventDefault();
		e.stopPropagation();
		if(e.deltaY > 0){
			++hzAlbumImgIndex;
			if(hzAlbumImgIndex > hzAlbumImgs.length - 1) { hzAlbumImgIndex = 0 }
		} else if(e.deltaY < 0){
			--hzAlbumImgIndex;
			if(hzAlbumImgIndex < 0){ hzAlbumImgIndex = hzAlbumImgs.length - 1 }
		}
		hzImg.show(hzCurUrl, hzAlbumImgs[hzAlbumImgIndex]);
	}
}

var hzTarget = document.createElement('a');
var hzAlbumImgs, hzAlbumImgIndex, hzCurUrl, hzMark, hzWait;
function hzMouseOn(e){
	if(hzWait){
		if(hzWait.abort){ hzWait.abort() }else{ clearTimeout(hzWait) }
		hzWait = null
	}
	hzDiv.hide();
	hzCurUrl = '';
	hzAlbumImgs = [];
	if(e){
		hzMark = new Date().getTime();
		hzCurUrl = e.target.toString();
		hzTarget.href = hzCurUrl;
		var p = hzTarget.pathname.split('.').reverse();
		if(/bmp|jpeg|jpg|png/i.test(p[0])){ hzImg.load(hzCurUrl, hzTarget.href) }
		else if(/mp4|webm/i.test(p[0])){ hzVideo.load(hzCurUrl, hzTarget.href) }
		else{
			p = hzTarget.hostname.split('.').reverse();
			switch((p[1]+"."+p[0]).toLowerCase()){
				case 'gfycat.com':
					self.port.emit('load', hzCurUrl, hzTarget.protocol+"//gfycat.com/"+hzTarget.pathname.split('.')[0]);
					break;
				case 'imgflip.com':
					p = hzTarget.pathname.split('/');
					if(p.length > 2){ hzTarget.href = hzTarget.protocol+"//i.imgflip.com/"+p[2].split('#')[0]+".jpg" }
					break;
				case 'imgur.com':
					var alb = "";
	 				p = hzTarget.pathname.split('/');
					switch(p[1].toLowerCase()){
						case 'a':
							alb = "https://api.imgur.com/3/album/"+p[2]
						case 'gallery':
							alb = alb || "https://api.imgur.com/3/gallery/"+p[2]
							hzWait = $.ajax({ src:hzCurUrl, url:alb, type:'GET', datatype:'json', beforeSend:function(h){ h.setRequestHeader('Authorization', 'Client-ID f781dcd19302057') },
								success:function(d){
									var delay = 0;
									if(d['data']['images']){
										$.each(d['data']['images'], function(i,v){
											setTimeout( function(){ new Image().src = v['link'] }, delay);
											delay += 1000;
											hzAlbumImgs.push(v['link']);
										});
									} else if(d['data']['link']){
										hzAlbumImgs.push(d['data']['link']);
									}
									if(hzAlbumImgs.length > 0){
										hzImg.load(this.src, hzAlbumImgs[0]);
										hzAlbumImgIndex = 0;
									}
								}
							});
							return;
					}
					hzTarget.pathname = hzTarget.pathname.split('/').pop();
					hzTarget.href = hzTarget.href.split('?')[0].split(',')[0].split('#')[0];
					if(hzTarget.pathname.split('.').length == 1){ hzTarget.href += ".jpg" }
					switch(hzTarget.pathname.split('.').reverse()[0].toLowerCase()) {
						case 'gif':
							hzTarget.href += "v";
						case 'gifv':
							self.port.emit('load', hzCurUrl, hzTarget.href);
							break;
					}
					break;
				case 'livememe.com':
					hzTarget.href = hzTarget.protocol+"//i.lvme.me"+hzTarget.pathname+".jpg";
					break;
				case 'vidble.com':
					hzWait = $.ajax({ src:hzCurUrl, url:hzTarget.href+'?json=1', type:'GET', datatype:'json',
						success:function(d){
							var delay = 0;
							$.each(d['pics'], function(i,v){
								setTimeout( function(){ new Image().src = v }, delay);
								delay += 1000;
								hzAlbumImgs.push(v);
							});
							if(hzAlbumImgs.length > 0) {
								hzImg.load(this.src, hzAlbumImgs[0]);
								hzAlbumImgIndex = 0;
							}
						}
					});
					return;
				case '500px.com':
				case 'artstation.com':
				case 'craigslist.org':
				case 'deviantart.com':
				case 'explosm.net':
				case 'facebook.com':
				case 'flic.kr':
				case 'flickr.com':
				case 'gifyoutube.com':
				case 'gyazo.com':
				case 'instagram.com':
				case 'makeameme.org':
				case 'mypixa.com':
//				case 'pinterest.com':
				case 'swirl.xyz':
				case 'tumblr.com':
				case 'twitter.com':
				case 'vid.me':
				case 'vine.co':
					self.port.emit('load', hzCurUrl, hzTarget.href);
					break;
			}
			hzImg.load(hzCurUrl, hzTarget.href);
//console.log(hzTarget.href);
		}
	}else{
		hzImg.load(hzCurUrl, 'about:blank');
	}
}
function hzMouseOff(e){ hzMouseOn(null) }

self.port.on('image', function(url, imgs){
	hzAlbumImgs = imgs;
	hzAlbumImgIndex = 0;
	hzImg.load(url, hzAlbumImgs[0]);
console.log("loading : " + url);
});

self.port.on('video', function(url, vid){
	hzVideo.load(url, vid);
console.log("loading : " + url);
});
<|endoftext|>