<commit_before>const crypto = require('crypto');
const fs = require('fs');
const path = require('path');
const zlib = require('zlib');

const chokidar = require('chokidar');
const mime = require('mime');
const Negotiator = require('negotiator');
const react = require('react-tools');
const sass = require('sass');
const sassGraph = require('sass-graph');
const Snockets = require('snockets');
const UglifyJS = require('uglify-js');
const UglifyCss = require('uglifycss');

const availableEncodings = ['gzip', 'identity'];
const gzipContentTypes = require('./gzipContentTypes.js');

exports.static = function static(directory, options) {
    directory = path.resolve(directory || 'public');

    if (!options) {
        options = {};
    }

    if (!('hashify' in options)) {
        options.hashify = true;
    }

    if (!options.sass) {
        options.sass = {};
    }

    if (!options.snockets) {
        options.snockets = {};
    }

    if (!options.jsx) {
        options.jsx = {};
    }

    options.snockets.async = false;

    if (!options.uglifycss) {
        options.uglifycss = {
            enabled: true
        };
    }

    if (!options.uglifyjs) {
        options.uglifyjs = {
            enabled: true
        };
    }

    if (!options.watch) {
        options.watch = {
            enabled: true
        };
    }

    if (options.hostname) {
        if (typeof options.hostname !== 'string') {
            throw Error('hostname must be a string');
        } else if (options.hostname.slice(-1) === '/') {
            options.hostname = options.hostname.slice(0, options.hostname.length - 1);
        }
    }

    if (options.sass.imagePath) {
        if (typeof options.sass.imagePath !== 'string') {
            throw Error('sass.imagePath must be a string');
        }
    }

    if (!options.sass.functions) {
        options.sass.functions = {};
    }

    options.sass.functions['image-url($img)'] = function(img) {
        return new sass.types.String('url("' +
            (options.sass.imagePath ?
                path.join('/', options.sass.imagePath, img.getValue()) :
                path.join('/', img.getValue())
            ) +
            '")');
    };

    var files = {};
    var snockets = new Snockets();
    var stylesheets = [];
    var watcher;

    function cacheFile(filePath, stat) {
        var data;
        var ext = path.extname(filePath);
        var relativeUrl = toRelativeUrl(filePath);

        // Compilation steps
        if (ext === '.scss' && !shouldIgnore(relativeUrl, options.sass.ignore)) {
            // Sass
            options.sass.file = filePath;
            data = sass.renderSync(options.sass).css.toString();

            // Future steps should treat this as plain CSS
            relativeUrl = relativeUrl.replace(/.scss$/, '.css');
            ext = '.css';
        } else if (ext === '.js' && !shouldIgnore(relativeUrl, options.snockets.ignore)) {
            // Snockets
            try {
                data = snockets.getConcatenation(filePath, options.snockets);
            } catch (e) {
                // Snockets can't parse, so just pass the js file along
                console.warn(`Snockets skipping ${filePath}:\n    ${e}`);
                data = fs.readFileSync(filePath).toString();
            }
        }

        if (ext === '.js' && !shouldIgnore(relativeUrl, options.jsx.ignore)) {
            // React
            data = data || fs.readFileSync(filePath).toString();

            try {
                data = react.transform(data, options.jsx);
            } catch (e) {
                // React can't transform, so just pass the js file along
                console.warn(`JSX compiler skipping ${filePath}:\n    ${e}`);
                data = fs.readFileSync(filePath).toString();
            }
        }

        // Postprocessing steps
        if (ext === '.css') {
            if (options.uglifycss.enabled) {
                // Uglifycss
                data = data ? UglifyCss.processString(data, options.uglifycss) : UglifyCss.processFiles([filePath], options.uglifycss);
            }
        } else if (ext === '.js' && options.uglifyjs.enabled && !shouldIgnore(relativeUrl, options.uglifyjs.ignore)) {
            var uglifyjsOptions = JSON.parse(JSON.stringify(options.uglifyjs));
            delete uglifyjsOptions.enabled;
            delete uglifyjsOptions.ignore;

            var result = UglifyJS.minify(data, uglifyjsOptions);

            if (result.error) {
                console.warn(`UglifyJS skipping ${filePath}:\n    ${JSON.stringify(result.error)}`);
            } else {
                data = result.code;
            }
        }

        // Have data?
        data = data || fs.readFileSync(filePath);

        // Cache file and hash, generate hash later if it's CSS because we're going to modify the contents
        files[relativeUrl] = {
            content: data,
            contentLength: typeof data === 'string' ? Buffer.byteLength(data) : data.length,
            contentType: mime.getType(relativeUrl),
            hash: ext !== '.css' ? crypto.createHash('md5').update(data).digest('hex') : '',
            modified: stat.mtime
        };

        // If-Modified-Since doesn't support millisecond precision
        files[relativeUrl].modified.setMilliseconds(0);

        if (ext === '.css') {
            stylesheets.push(relativeUrl);
        }

        return relativeUrl;
    }

    function dehashifyPath(filePath) {
        if (!options.hashify) {
            return {
                path: filePath,
                hash: undefined
            };
        }

        var hashRegex = /-[0-9a-f]+(\.[^.]*$)/;
        var hashMatch = filePath.match(hashRegex);
        var hash = hashMatch ? hashMatch[0].slice(1).replace(/\.([^.]*$)/, '') : '';

        return {
            path: hash.length == 32 ? filePath.replace(hashRegex, '$1') : filePath,
            hash: hash.length == 32 ? hash : null
        };
    }

    function gzip(file, callback) {
        if (file.gzippedContent && file.gzippedContentLength) {
            return callback(null, file);
        }

        zlib.gzip(file.content, function(err, gzippedContent) {
            if (err) {
                return callback(err);
            }

            file.gzippedContent = gzippedContent;
            file.gzippedContentLength = gzippedContent.length;

            callback(null, file);
        });
    }

    function hashifyCss(cssPath) {
        return files[cssPath].content.toString().replace(/url\(['"]?(.*?)['"]?\)/g, function(match, filename) {
            var file;

            if (filename[0] === '/') {
                file = files[filename];
            } else {
                var cssDir = path.dirname(cssPath);
                filename = path.normalize(path.join(cssDir, filename)).replace(/\\/g, '/');
                file = files[filename];
            }

            if (file) {
                return 'url(' + urlBuilder(filename) + ')';
            }

            return match;
        });
    }

    function hashifyPath(filePath, hash) {
        if (!filePath.includes('.')) {
            return filePath.replace(/([?#].*)?$/, `-${hash}$1`);
        }

        return filePath.replace(/\.([^.]*)([?#].*)?$/, `-${hash}.$1$2`);
    }

    function prefixSlash(path) {
        return path[0] === '/' ? path : '/' + path;
    }

    function reloadFile(filePath, stat) {
        stat = typeof stat === 'object' ? stat : fs.statSync(filePath);

        var ext = path.extname(filePath);

        if (ext === '.scss') {
            sassGraph.parseDir(directory).index[filePath].importedBy.forEach(reloadFile);
        } else if (ext === '.js') {
            // Clear snockets cache
            snockets.cache = {};
            snockets.concatCache = {};

            snockets.scan(filePath);
            snockets.depGraph.parentsOf(filePath).forEach(reloadFile);
        }

        var relativeUrl = cacheFile(filePath, stat);

        if (stylesheets.includes(relativeUrl)) {
            files[relativeUrl].content = hashifyCss(relativeUrl);
            files[relativeUrl].hash = crypto.createHash('md5').update(files[relativeUrl].content).digest('hex');
        }
    }

    function toRelativeUrl(filePath) {
        var relativeUrl = path.relative(directory, path.resolve(filePath));

        // Make URI-friendly and prepend a /
        return prefixSlash(relativeUrl).replace(/\\/g, '/');
    }

    function shouldIgnore(filePath, ignore) {
        if (!ignore) {
            // Not ignoring anything
            return false;
        }

        if (Array.isArray(ignore)) {
            // Multiple things to ignore
            return ignore.some(function ignoreElementMatch(ignored) {
                return shouldIgnore(filePath, ignored);
            });
        }

        return filePath.match(ignore) !== null;
    }

    function stripQueryAndTarget(filePath) {
        return filePath.replace(/[?#].*$/, '');
    }

    function urlBuilder(filePath) {
        var file = files[stripQueryAndTarget(prefixSlash(filePath))];

        if (file) {
            var uri = prefixSlash(filePath);

            if (options.hashify) {
                uri = hashifyPath(uri, file.hash);
            }

            if (options && options.hostname) {
                uri = '//' + options.hostname + uri;
            }

            return uri;
        } else {
            return filePath;
        }
    }

    // Load all files synchronously
    (function loadFiles(workingDir) {
        var contents = fs.readdirSync(workingDir);

        contents.forEach(function loadDirectory(file) {
            var filePath = path.join(workingDir, file);
            var stat = fs.statSync(filePath);

            if (stat.isDirectory()) {
                return loadFiles(filePath);
            }

            cacheFile(filePath, stat);
        });
    })(directory);

    // Hashify URLs in stylesheets
    stylesheets.forEach(function(stylesheet) {
        files[stylesheet].content = hashifyCss(stylesheet);
        files[stylesheet].hash = crypto.createHash('md5').update(files[stylesheet].content).digest('hex');
    });

    // Watch for changes
    if (options.watch.enabled) {
        const jsDirectories = Array.from(new Set(Object.keys(snockets.depGraph.map).map(d => path.dirname(d))));
        const sassDirectories = Array.from(new Set(Object.keys(sassGraph.parseDir(directory).index).map(d => path.dirname(d))));

        watcher = chokidar.watch([directory, ...jsDirectories, ...sassDirectories], {
            ignoreInitial: true
        });

        watcher.on('add', reloadFile);

        watcher.on('change', reloadFile);

        watcher.on('unlink', function(path) {
            var compiledPath = path.replace(/\.scss$/, '.css');
            delete files[toRelativeUrl(compiledPath)];
        });
    }

    return function staticMiddleware(req, res, next) {
        // Ignore anything that's not a GET or HEAD request
        if (req.method !== 'GET' && req.method !== 'HEAD') {
            return next();
        }

        // Register view helper if we haven't already
        if (!req.app.locals.electricity) {
            req.app.locals.electricity = {
                url: urlBuilder
            };
        }

        var reqInfo = dehashifyPath(req.path);
        var file = files[reqInfo.path];

        if (!file) {
            return next();
        }

        // Verify file matches the requested hash, otherwise 302
        if (options.hashify && reqInfo.hash !== file.hash) {
            res.set({
                'Cache-Control': 'no-cache',
                'Expires': '0',
                'Pragma': 'no-cache'
            });

            console.log(file.hash);

            return res.redirect(hashifyPath(reqInfo.path, file.hash));
        }

        var expires = new Date();
        expires.setYear(expires.getFullYear() + 1);

        res.set({
            'Cache-Control': 'public, max-age=31536000',
            'Content-Type': file.contentType,
            'ETag': file.hash,
            'Expires': expires.toUTCString(),
            'Last-Modified': file.modified.toUTCString()
        });

        if (options.headers) {
            res.set(options.headers);
        }

        if (req.get('If-None-Match') === file.hash) {
            res.status(304);
            res.end();
        } else if (new Date(req.get('If-Modified-Since')) >= file.modified) {
            res.status(304);
            res.end();
        } else {
            res.set({ 'Content-Length': file.contentLength });
            res.status(200);

            if (req.method === 'HEAD') {
                return res.end();
            }

            var negotiator = new Negotiator(req);

            if (negotiator.encodings(availableEncodings).indexOf('gzip') === 0 && gzipContentTypes.indexOf(file.contentType) !== -1) {
                gzip(file, function(err, gzippedFile) {
                    if (err) {
                        return next(err);
                    }

                    res.set({
                        'Content-Encoding': 'gzip',
                        'Content-Length': gzippedFile.gzippedContentLength
                    });

                    res.send(file.gzippedContent);
                });
            } else {
                res.send(file.content);
            }
        }
    };
};
<commit_msg>remove console.log<commit_after>const crypto = require('crypto');
const fs = require('fs');
const path = require('path');
const zlib = require('zlib');

const chokidar = require('chokidar');
const mime = require('mime');
const Negotiator = require('negotiator');
const react = require('react-tools');
const sass = require('sass');
const sassGraph = require('sass-graph');
const Snockets = require('snockets');
const UglifyJS = require('uglify-js');
const UglifyCss = require('uglifycss');

const availableEncodings = ['gzip', 'identity'];
const gzipContentTypes = require('./gzipContentTypes.js');

exports.static = function static(directory, options) {
    directory = path.resolve(directory || 'public');

    if (!options) {
        options = {};
    }

    if (!('hashify' in options)) {
        options.hashify = true;
    }

    if (!options.sass) {
        options.sass = {};
    }

    if (!options.snockets) {
        options.snockets = {};
    }

    if (!options.jsx) {
        options.jsx = {};
    }

    options.snockets.async = false;

    if (!options.uglifycss) {
        options.uglifycss = {
            enabled: true
        };
    }

    if (!options.uglifyjs) {
        options.uglifyjs = {
            enabled: true
        };
    }

    if (!options.watch) {
        options.watch = {
            enabled: true
        };
    }

    if (options.hostname) {
        if (typeof options.hostname !== 'string') {
            throw Error('hostname must be a string');
        } else if (options.hostname.slice(-1) === '/') {
            options.hostname = options.hostname.slice(0, options.hostname.length - 1);
        }
    }

    if (options.sass.imagePath) {
        if (typeof options.sass.imagePath !== 'string') {
            throw Error('sass.imagePath must be a string');
        }
    }

    if (!options.sass.functions) {
        options.sass.functions = {};
    }

    options.sass.functions['image-url($img)'] = function(img) {
        return new sass.types.String('url("' +
            (options.sass.imagePath ?
                path.join('/', options.sass.imagePath, img.getValue()) :
                path.join('/', img.getValue())
            ) +
            '")');
    };

    var files = {};
    var snockets = new Snockets();
    var stylesheets = [];
    var watcher;

    function cacheFile(filePath, stat) {
        var data;
        var ext = path.extname(filePath);
        var relativeUrl = toRelativeUrl(filePath);

        // Compilation steps
        if (ext === '.scss' && !shouldIgnore(relativeUrl, options.sass.ignore)) {
            // Sass
            options.sass.file = filePath;
            data = sass.renderSync(options.sass).css.toString();

            // Future steps should treat this as plain CSS
            relativeUrl = relativeUrl.replace(/.scss$/, '.css');
            ext = '.css';
        } else if (ext === '.js' && !shouldIgnore(relativeUrl, options.snockets.ignore)) {
            // Snockets
            try {
                data = snockets.getConcatenation(filePath, options.snockets);
            } catch (e) {
                // Snockets can't parse, so just pass the js file along
                console.warn(`Snockets skipping ${filePath}:\n    ${e}`);
                data = fs.readFileSync(filePath).toString();
            }
        }

        if (ext === '.js' && !shouldIgnore(relativeUrl, options.jsx.ignore)) {
            // React
            data = data || fs.readFileSync(filePath).toString();

            try {
                data = react.transform(data, options.jsx);
            } catch (e) {
                // React can't transform, so just pass the js file along
                console.warn(`JSX compiler skipping ${filePath}:\n    ${e}`);
                data = fs.readFileSync(filePath).toString();
            }
        }

        // Postprocessing steps
        if (ext === '.css') {
            if (options.uglifycss.enabled) {
                // Uglifycss
                data = data ? UglifyCss.processString(data, options.uglifycss) : UglifyCss.processFiles([filePath], options.uglifycss);
            }
        } else if (ext === '.js' && options.uglifyjs.enabled && !shouldIgnore(relativeUrl, options.uglifyjs.ignore)) {
            var uglifyjsOptions = JSON.parse(JSON.stringify(options.uglifyjs));
            delete uglifyjsOptions.enabled;
            delete uglifyjsOptions.ignore;

            var result = UglifyJS.minify(data, uglifyjsOptions);

            if (result.error) {
                console.warn(`UglifyJS skipping ${filePath}:\n    ${JSON.stringify(result.error)}`);
            } else {
                data = result.code;
            }
        }

        // Have data?
        data = data || fs.readFileSync(filePath);

        // Cache file and hash, generate hash later if it's CSS because we're going to modify the contents
        files[relativeUrl] = {
            content: data,
            contentLength: typeof data === 'string' ? Buffer.byteLength(data) : data.length,
            contentType: mime.getType(relativeUrl),
            hash: ext !== '.css' ? crypto.createHash('md5').update(data).digest('hex') : '',
            modified: stat.mtime
        };

        // If-Modified-Since doesn't support millisecond precision
        files[relativeUrl].modified.setMilliseconds(0);

        if (ext === '.css') {
            stylesheets.push(relativeUrl);
        }

        return relativeUrl;
    }

    function dehashifyPath(filePath) {
        if (!options.hashify) {
            return {
                path: filePath,
                hash: undefined
            };
        }

        var hashRegex = /-[0-9a-f]+(\.[^.]*$)/;
        var hashMatch = filePath.match(hashRegex);
        var hash = hashMatch ? hashMatch[0].slice(1).replace(/\.([^.]*$)/, '') : '';

        return {
            path: hash.length == 32 ? filePath.replace(hashRegex, '$1') : filePath,
            hash: hash.length == 32 ? hash : null
        };
    }

    function gzip(file, callback) {
        if (file.gzippedContent && file.gzippedContentLength) {
            return callback(null, file);
        }

        zlib.gzip(file.content, function(err, gzippedContent) {
            if (err) {
                return callback(err);
            }

            file.gzippedContent = gzippedContent;
            file.gzippedContentLength = gzippedContent.length;

            callback(null, file);
        });
    }

    function hashifyCss(cssPath) {
        return files[cssPath].content.toString().replace(/url\(['"]?(.*?)['"]?\)/g, function(match, filename) {
            var file;

            if (filename[0] === '/') {
                file = files[filename];
            } else {
                var cssDir = path.dirname(cssPath);
                filename = path.normalize(path.join(cssDir, filename)).replace(/\\/g, '/');
                file = files[filename];
            }

            if (file) {
                return 'url(' + urlBuilder(filename) + ')';
            }

            return match;
        });
    }

    function hashifyPath(filePath, hash) {
        if (!filePath.includes('.')) {
            return filePath.replace(/([?#].*)?$/, `-${hash}$1`);
        }

        return filePath.replace(/\.([^.]*)([?#].*)?$/, `-${hash}.$1$2`);
    }

    function prefixSlash(path) {
        return path[0] === '/' ? path : '/' + path;
    }

    function reloadFile(filePath, stat) {
        stat = typeof stat === 'object' ? stat : fs.statSync(filePath);

        var ext = path.extname(filePath);

        if (ext === '.scss') {
            sassGraph.parseDir(directory).index[filePath].importedBy.forEach(reloadFile);
        } else if (ext === '.js') {
            // Clear snockets cache
            snockets.cache = {};
            snockets.concatCache = {};

            snockets.scan(filePath);
            snockets.depGraph.parentsOf(filePath).forEach(reloadFile);
        }

        var relativeUrl = cacheFile(filePath, stat);

        if (stylesheets.includes(relativeUrl)) {
            files[relativeUrl].content = hashifyCss(relativeUrl);
            files[relativeUrl].hash = crypto.createHash('md5').update(files[relativeUrl].content).digest('hex');
        }
    }

    function toRelativeUrl(filePath) {
        var relativeUrl = path.relative(directory, path.resolve(filePath));

        // Make URI-friendly and prepend a /
        return prefixSlash(relativeUrl).replace(/\\/g, '/');
    }

    function shouldIgnore(filePath, ignore) {
        if (!ignore) {
            // Not ignoring anything
            return false;
        }

        if (Array.isArray(ignore)) {
            // Multiple things to ignore
            return ignore.some(function ignoreElementMatch(ignored) {
                return shouldIgnore(filePath, ignored);
            });
        }

        return filePath.match(ignore) !== null;
    }

    function stripQueryAndTarget(filePath) {
        return filePath.replace(/[?#].*$/, '');
    }

    function urlBuilder(filePath) {
        var file = files[stripQueryAndTarget(prefixSlash(filePath))];

        if (file) {
            var uri = prefixSlash(filePath);

            if (options.hashify) {
                uri = hashifyPath(uri, file.hash);
            }

            if (options && options.hostname) {
                uri = '//' + options.hostname + uri;
            }

            return uri;
        } else {
            return filePath;
        }
    }

    // Load all files synchronously
    (function loadFiles(workingDir) {
        var contents = fs.readdirSync(workingDir);

        contents.forEach(function loadDirectory(file) {
            var filePath = path.join(workingDir, file);
            var stat = fs.statSync(filePath);

            if (stat.isDirectory()) {
                return loadFiles(filePath);
            }

            cacheFile(filePath, stat);
        });
    })(directory);

    // Hashify URLs in stylesheets
    stylesheets.forEach(function(stylesheet) {
        files[stylesheet].content = hashifyCss(stylesheet);
        files[stylesheet].hash = crypto.createHash('md5').update(files[stylesheet].content).digest('hex');
    });

    // Watch for changes
    if (options.watch.enabled) {
        const jsDirectories = Array.from(new Set(Object.keys(snockets.depGraph.map).map(d => path.dirname(d))));
        const sassDirectories = Array.from(new Set(Object.keys(sassGraph.parseDir(directory).index).map(d => path.dirname(d))));

        watcher = chokidar.watch([directory, ...jsDirectories, ...sassDirectories], {
            ignoreInitial: true
        });

        watcher.on('add', reloadFile);

        watcher.on('change', reloadFile);

        watcher.on('unlink', function(path) {
            var compiledPath = path.replace(/\.scss$/, '.css');
            delete files[toRelativeUrl(compiledPath)];
        });
    }

    return function staticMiddleware(req, res, next) {
        // Ignore anything that's not a GET or HEAD request
        if (req.method !== 'GET' && req.method !== 'HEAD') {
            return next();
        }

        // Register view helper if we haven't already
        if (!req.app.locals.electricity) {
            req.app.locals.electricity = {
                url: urlBuilder
            };
        }

        var reqInfo = dehashifyPath(req.path);
        var file = files[reqInfo.path];

        if (!file) {
            return next();
        }

        // Verify file matches the requested hash, otherwise 302
        if (options.hashify && reqInfo.hash !== file.hash) {
            res.set({
                'Cache-Control': 'no-cache',
                'Expires': '0',
                'Pragma': 'no-cache'
            });

            return res.redirect(hashifyPath(reqInfo.path, file.hash));
        }

        var expires = new Date();
        expires.setYear(expires.getFullYear() + 1);

        res.set({
            'Cache-Control': 'public, max-age=31536000',
            'Content-Type': file.contentType,
            'ETag': file.hash,
            'Expires': expires.toUTCString(),
            'Last-Modified': file.modified.toUTCString()
        });

        if (options.headers) {
            res.set(options.headers);
        }

        if (req.get('If-None-Match') === file.hash) {
            res.status(304);
            res.end();
        } else if (new Date(req.get('If-Modified-Since')) >= file.modified) {
            res.status(304);
            res.end();
        } else {
            res.set({ 'Content-Length': file.contentLength });
            res.status(200);

            if (req.method === 'HEAD') {
                return res.end();
            }

            var negotiator = new Negotiator(req);

            if (negotiator.encodings(availableEncodings).indexOf('gzip') === 0 && gzipContentTypes.indexOf(file.contentType) !== -1) {
                gzip(file, function(err, gzippedFile) {
                    if (err) {
                        return next(err);
                    }

                    res.set({
                        'Content-Encoding': 'gzip',
                        'Content-Length': gzippedFile.gzippedContentLength
                    });

                    res.send(file.gzippedContent);
                });
            } else {
                res.send(file.content);
            }
        }
    };
};
<|endoftext|>


<commit_before>var redis = require('redis');

var internals = {};

internals.defaults = {
  global:{limit: -1 , bucketLength: 1},
  routes: {},
  redis:{}
};

exports.register = function(plugin, options, next) {
  var settings = plugin.hapi.utils.applyToDefaults(internals.defaults, options);
  var redisClient  = redis.createClient(options.redis.port, options.redis.host, options.redis.options);
  plugin.state('cl-hapi-rate',{});

  plugin.route({
    method: 'GET',
    path: "/ratelimit",
    handler: function(request, reply) {
      reply(429);
    }
  });

  plugin.ext('onRequest', function(request, callback) {
    var ipts = request.info.remoteAddress+':'+Math.floor((new Date()).getTime()/1000)
    redisClient.get(ipts,function(err, token){
      if(token && token > 1) { //TODO: test for routes or global limit
        request.setUrl("/ratelimit");
        request.setMethod("GET");
        return callback();
      }else{
        redisClient.multi([['INCR',ipts],['EXPIRE', ipts, 120]]).exec(function(err) {
          return callback();
        });
      }
    });
  });
  next();
};
<commit_msg>Hapi Error for response<commit_after>var redis = require('redis');

var internals = {};

internals.defaults = {
  global:{limit: -1 , bucketLength: 1},
  routes: {},
  redis:{}
};

exports.register = function(plugin, options, next) {
  var settings = plugin.hapi.utils.applyToDefaults(internals.defaults, options);
  var redisClient  = redis.createClient(options.redis.port, options.redis.host, options.redis.options);
  plugin.state('cl-hapi-rate',{});

  plugin.route({
    method: 'GET',
    path: "/ratelimit",
    handler: function(request, reply) {
      var error = Hapi.error.badRequest('Rate limit exceeded');
      error.output.statusCode = 429;    // Assign a custom error code
      error.reformat();
      reply(error);
    }
  });

  plugin.ext('onRequest', function(request, callback) {
    var ipts = request.info.remoteAddress+':'+Math.floor((new Date()).getTime()/1000)
    redisClient.get(ipts,function(err, token){
      if(token && token > 1) { //TODO: test for routes or global limit
        request.setUrl("/ratelimit");
        request.setMethod("GET");
        return callback();
      }else{
        redisClient.multi([['INCR',ipts],['EXPIRE', ipts, 120]]).exec(function(err) {
          return callback();
        });
      }
    });
  });
  next();
};
<|endoftext|>


<commit_before>var Boom = require('boom');

var internals = {
	tags: ['hapi-boombox']
};

internals.boom = function boom(error, returnError, convert) {

	var explosion = null;

	// convert && return error by default
	if (convert === null || convert === undefined) {
		convert = true;
	}

	if (returnError === null || returnError === undefined) {
		returnError = true;
	}

	if (convert) {
		if (typeof error === 'string') {
			var data = internals.errors[error];

			if (!data) {
				explosion = Boom.badImplementation(error + ' is not a valid error key');
			} else {
				if (returnError) {
					var customBoom = Boom[data.type]();

					explosion = new Error(data.message);

					Boom.wrap(explosion, customBoom.output.statusCode, data.message);
				} else {
					explosion = data.message;
				}
			}
		} else if (error instanceof Error) {
			Boom.wrap(error, 400);

			explosion = error;
		} else if (returnError) {
			explosion = new Error(error);
		} else {
			explosion = error;
		}
	} else if (returnError) {
		explosion = new Error(error);
	} else {
		explosion = error;
	}

	if (returnError) {
		return explosion;
	}

	return explosion.message || explosion;
};

exports.register = function (server, options, next) {

	if (!options.hasOwnProperty('errors')) {
		throw new Error('Options must include errors object');
	}

	internals.errors = options.errors;

	server.decorate('reply', 'boom', function (error, returnError, convert) {

		var explosion = internals.boom(error, returnError, convert);
		this.response(explosion);

		var log = {
			error: explosion.output || explosion,
			data: {
				path: this.request.url.path,
				query: this.request.query,
				method: this.request.method,
				payload: this.request.payload,
				headers: this.request.headers,
				info: this.request.info
			}
		};

		if (this.request.auth.credentials) {
			log.data.credentials = {
				id: this.request.auth.credentials.id,
				name: this.request.auth.credentials.name
			};
		}

		return server.log(internals.tags, log);
	});

	server.decorate('server', 'boom', function (error, returnError, convert) {

		var explosion = internals.boom(error, returnError, convert);

		server.log(internals.tags, explosion.output || explosion);

		return explosion;
	});

	server.log(internals.tags, 'Registered reply.boom() and server.boom()');

	return next();
};

exports.register.attributes = {
	pkg: require('../package.json')
};
<commit_msg>back to 100% cc<commit_after>var Boom = require('boom');

var internals = {
	tags: ['hapi-boombox']
};

internals.boom = function boom(error, returnError, convert) {

	var explosion = null;

	// convert && return error by default
	if (convert === null || convert === undefined) {
		convert = true;
	}

	if (returnError === null || returnError === undefined) {
		returnError = true;
	}

	if (convert) {
		if (typeof error === 'string') {
			var data = internals.errors[error];

			if (!data) {
				explosion = Boom.badImplementation(error + ' is not a valid error key');
			} else {
				if (returnError) {
					var customBoom = Boom[data.type]();

					explosion = new Error(data.message);

					Boom.wrap(explosion, customBoom.output.statusCode, data.message);
				} else {
					explosion = data.message;
				}
			}
		} else if (error instanceof Error) {
			Boom.wrap(error, 400);

			explosion = error;
		} else if (returnError) {
			explosion = new Error(error);
		} else {
			explosion = error;
		}
	} else if (returnError) {
		explosion = new Error(error);
	} else {
		explosion = error;
	}

	if (returnError) {
		return explosion;
	}

	return explosion.message || explosion;
};

exports.register = function (server, options, next) {

	if (!options.hasOwnProperty('errors')) {
		throw new Error('Options must include errors object');
	}

	internals.errors = options.errors;

	server.decorate('reply', 'boom', function (error, returnError, convert) {

		var explosion = internals.boom(error, returnError, convert);

		var log = {
			error: explosion.output || explosion,
			data: {
				path: this.request.url.path,
				query: this.request.query,
				method: this.request.method,
				payload: this.request.payload,
				headers: this.request.headers,
				info: this.request.info
			}
		};

		if (this.request.auth.credentials) {
			log.data.credentials = {
				id: this.request.auth.credentials.id,
				name: this.request.auth.credentials.name
			};
		}

		this.response(explosion);
		return server.log(internals.tags, log);
	});

	server.decorate('server', 'boom', function (error, returnError, convert) {

		var explosion = internals.boom(error, returnError, convert);

		server.log(internals.tags, explosion.output || explosion);

		return explosion;
	});

	server.log(internals.tags, 'Registered reply.boom() and server.boom()');

	return next();
};

exports.register.attributes = {
	pkg: require('../package.json')
};
<|endoftext|>


<commit_before>var gulp = require("gulp"),
    exec = require("child_process").exec,
    nodemon = require("gulp-nodemon"),
    jshint = require("gulp-jshint"),
    less = require("gulp-less"),
    autoprefixer = require("gulp-autoprefixer"),
    nodemon = require("gulp-nodemon");

var jsFiles = ["*.js", "app/js/**.js"];
var templateFiles = ["app/**.hbr", "app/**.md", "app/content/**.md"];
var lessFiles = ["app/less/**.less"];

gulp.task("compileLess", function() {
  gulp.src(lessFiles)
  .pipe(less())
  .pipe(autoprefixer("last 2 versions", "> 1%", "ie 8"))
  .pipe(gulp.dest("app/css"));
});

gulp.task("lint", function() {
  gulp.src(jsFiles)
  .pipe(jshint())
  .pipe(jshint.reporter("default"));
});

gulp.task("server", function() {
  nodemon({
    script: "./index.js",
    options: "-e js"
  });
});

gulp.task("compile", function() {
  exec("node build.js", function(err, stdout, stderr) {
    if (err) throw err;
    console.log(stdout);
  });
});

gulp.task("watch", function() {
  gulp.watch(lessFiles, ["compileLess"]);
  gulp.watch(jsFiles, ["lint"]);
  gulp.watch(templateFiles, ["compile"]);
});

gulp.task("dev", ["watch", "server", "compile"]);

gulp.task("default", ["lint", "compileLess", "compile"]);
<commit_msg>Added gulp build process<commit_after>var gulp = require("gulp"),
    exec = require("child_process").exec,
    nodemon = require("gulp-nodemon"),
    jshint = require("gulp-jshint"),
    less = require("gulp-less"),
    autoprefixer = require("gulp-autoprefixer"),
    nodemon = require("gulp-nodemon");

var jsFiles = ["*.js", "app/js/**.js"];
var templateFiles = ["app/**.hbr", "app/**.md", "app/content/**.md"];
var lessFiles = ["app/less/**.less"];

gulp.task("compileLess", function() {
  gulp.src(lessFiles)
  .pipe(less())
  .pipe(autoprefixer("last 2 versions", "> 1%", "ie 8"))
  .pipe(gulp.dest("app/css"));
});

gulp.task("lint", function() {
  gulp.src(jsFiles)
  .pipe(jshint())
  .pipe(jshint.reporter("default"));
});

gulp.task("server", function() {
  nodemon({
    script: "./index.js",
    options: "-e js"
  });
});

gulp.task("compile", function() {
  exec("node build.js", function(err, stdout, stderr) {
    if (err) throw err;
    console.log(stdout);
  });
});

gulp.task("watch", function() {
  gulp.watch(lessFiles, ["compileLess"]);
  gulp.watch(jsFiles, ["lint"]);
  gulp.watch(templateFiles, ["compile"]);
});

gulp.task("move-to-dist", function() {
  gulp.src("app/css/*.css")
  .pipe(gulp.dest("dist/css/"));

  gulp.src("app/images/*")
  .pipe(gulp.dest("dist/images/"));

  gulp.src("app/js/*.js")
  .pipe(gulp.dest("dist/js"));

  gulp.src(["app/*.html", "app/*.json", "app/*.hbr"])
  .pipe(gulp.dest("dist/"));
});

gulp.task("dev", ["watch", "server", "compile"]);

gulp.task("default", ["lint", "compileLess", "compile"]);

gulp.task("build", ["default", "move-to-dist"]);
<|endoftext|>


<commit_before>'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _jsqr = require('jsqr');

var _jsqr2 = _interopRequireDefault(_jsqr);

var _raf = require('raf');

var _raf2 = _interopRequireDefault(_raf);

require('md-gum-polyfill');

require('webrtc-adapter');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

_raf2.default.polyfill();

var Reader = function (_Component) {
  _inherits(Reader, _Component);

  function Reader(props) {
    _classCallCheck(this, Reader);

    var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(Reader).call(this, props));

    _this.initiate = _this.initiate.bind(_this);
    _this.initiateLegacyMode = _this.initiateLegacyMode.bind(_this);
    _this.check = _this.check.bind(_this);
    _this.handleVideo = _this.handleVideo.bind(_this);
    _this.handleLoadStart = _this.handleLoadStart.bind(_this);
    _this.handleInputChange = _this.handleInputChange.bind(_this);
    _this.clearComponent = _this.clearComponent.bind(_this);
    _this.handleReaderLoad = _this.handleReaderLoad.bind(_this);

    _this.componentWillUnmount = _this.clearComponent;
    return _this;
  }

  _createClass(Reader, [{
    key: 'componentDidMount',
    value: function componentDidMount() {
      if (!this.props.legacyMode) {
        this.initiate();
      } else {
        this.initiateLegacyMode();
      }
    }
  }, {
    key: 'componentWillReceiveProps',
    value: function componentWillReceiveProps(newProps) {
      if (!newProps.legacyMode && this.props.facingMode != newProps.facingMode) {
        this.clearComponent();
        this.initiate();
      }
      if (!this.props.legacyMode && newProps.legacyMode) {
        this.clearComponent();
        this.componentDidUpdate = this.initiateLegacyMode;
      }
      if (this.props.legacyMode && !newProps.legacyMode) {
        this.clearComponent();
        this.initiate();
      }
    }
  }, {
    key: 'clearComponent',
    value: function clearComponent() {
      if (this._interval) clearInterval(this._interval);

      if (typeof this.stopCamera === 'function') this.stopCamera();

      if (this.requestFrameId) {
        window.cancelAnimationFrame(this.requestFrameId);
        delete this.requestFrameId;
      }

      if (this.reader) {
        this.reader.removeEventListener('load', this.handleReaderLoad);
        this.reader = undefined;
      }

      if (this.refs.img) {
        this.refs.img.removeEventListener('load', this.check);
      }
    }
  }, {
    key: 'initiate',
    value: function initiate() {
      var _props = this.props;
      var handleError = _props.handleError;
      var facingMode = _props.facingMode;

      var constrains = {
        video: {
          facingMode: facingMode ? {
            exact: facingMode == 'rear' ? 'environment' : 'user'
          } : undefined,
          width: { min: 360, ideal: 1280, max: 1920 },
          height: { min: 240, ideal: 720, max: 1080 }
        }
      };

      try {
        navigator.mediaDevices.getUserMedia(constrains).then(this.handleVideo).catch(function (e) {
          return handleError(e.name);
        });
      } catch (e) {
        handleError('Not compatible with getUserMedia.');
      }
    }
  }, {
    key: 'handleVideo',
    value: function handleVideo(stream) {
      var preview = this.refs.preview;

      if (window.URL.createObjectURL) {
        preview.src = window.URL.createObjectURL(stream);
      } else if (window.webkitURL) {
        preview.src = window.webkitURL.createObjectURL(stream);
      } else if (preview.mozSrcObject !== undefined) {
        preview.mozSrcObject = stream;
      } else {
        preview.src = stream;
      }

      var streamTrack = stream.getTracks()[0];
      this.stopCamera = streamTrack.stop.bind(streamTrack);

      preview.addEventListener('loadstart', this.handleLoadStart);
    }
  }, {
    key: 'handleLoadStart',
    value: function handleLoadStart() {
      var preview = this.refs.preview;
      preview.play();
      if (this.props.interval) {
        this._interval = setInterval(this.check, this.props.interval);
      } else if (!this.requestFrameId) {
        this.check();
      }

      preview.removeEventListener('loadstart', this.handleLoadStart);
    }
  }, {
    key: 'check',
    value: function check() {
      var _props2 = this.props;
      var interval = _props2.interval;
      var handleScan = _props2.handleScan;
      var legacyMode = _props2.legacyMode;
      var _refs = this.refs;
      var preview = _refs.preview;
      var canvas = _refs.canvas;
      var img = _refs.img;

      var width = Math.floor(legacyMode ? img.naturalWidth : preview.videoWidth);
      var height = Math.floor(legacyMode ? img.naturalHeight : preview.videoHeight);
      if (width >= 2000 || height >= 2000) {
        width = width / 2;
        height = height / 2;
      }

      canvas.width = width;
      canvas.height = height;

      if (!interval && !legacyMode) this.requestFrameId = window.requestAnimationFrame(this.check);

      if (legacyMode || preview && preview.readyState === preview.HAVE_ENOUGH_DATA) {
        var ctx = canvas.getContext('2d');
        ctx.drawImage(legacyMode ? img : preview, 0, 0, width, height);

        var imageData = ctx.getImageData(0, 0, width, height);
        var decoded = _jsqr2.default.decodeQRFromImage(imageData.data, width, height);

        if (decoded) handleScan(decoded);
      }
    }
  }, {
    key: 'initiateLegacyMode',
    value: function initiateLegacyMode() {
      this.reader = new FileReader();

      this.reader.addEventListener('load', this.handleReaderLoad);

      this.refs.img.addEventListener('load', this.check, false);

      this.componentDidUpdate = undefined;
    }
  }, {
    key: 'handleInputChange',
    value: function handleInputChange(e) {
      this.reader.readAsDataURL(e.target.files[0]);
    }
  }, {
    key: 'handleReaderLoad',
    value: function handleReaderLoad(e) {
      this.refs.img.src = e.target.result;
    }
  }, {
    key: 'render',
    value: function render() {
      var previewStyle = _extends({
        display: 'block',
        objectFit: 'contain'
      }, this.props.previewStyle);
      var canvasStyle = {
        display: 'none'
      };

      return _react2.default.createElement(
        'section',
        null,
        this.props.legacyMode ? _react2.default.createElement(
          'div',
          null,
          _react2.default.createElement('input', { style: this.props.inputStyle, type: 'file', accept: 'image/*', ref: 'input', onChange: this.handleInputChange }),
          _react2.default.createElement('img', { style: _extends({}, previewStyle, { display: 'none' }), ref: 'img' })
        ) : _react2.default.createElement('video', { style: previewStyle, ref: 'preview' }),
        _react2.default.createElement('canvas', { style: canvasStyle, ref: 'canvas' })
      );
    }
  }]);

  return Reader;
}(_react.Component);

exports.default = Reader;

Reader.defaultProps = {
  interval: null,
  previewStyle: {},
  inputStyle: {}
};
Reader.propTypes = {
  handleScan: _react.PropTypes.func.isRequired,
  handleError: _react.PropTypes.func.isRequired,
  interval: _react.PropTypes.number,
  previewStyle: _react.PropTypes.object,
  inputStyle: _react.PropTypes.object,
  facingMode: _react.PropTypes.string,
  legacyMode: _react.PropTypes.bool
};<commit_msg>Build<commit_after>'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _jsqr = require('jsqr');

var _jsqr2 = _interopRequireDefault(_jsqr);

var _raf = require('raf');

var _raf2 = _interopRequireDefault(_raf);

require('md-gum-polyfill');

require('webrtc-adapter');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

_raf2.default.polyfill();

var Reader = function (_Component) {
  _inherits(Reader, _Component);

  function Reader(props) {
    _classCallCheck(this, Reader);

    var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(Reader).call(this, props));

    _this.initiate = _this.initiate.bind(_this);
    _this.initiateLegacyMode = _this.initiateLegacyMode.bind(_this);
    _this.check = _this.check.bind(_this);
    _this.handleVideo = _this.handleVideo.bind(_this);
    _this.handleLoadStart = _this.handleLoadStart.bind(_this);
    _this.handleInputChange = _this.handleInputChange.bind(_this);
    _this.clearComponent = _this.clearComponent.bind(_this);
    _this.handleReaderLoad = _this.handleReaderLoad.bind(_this);

    _this.componentWillUnmount = _this.clearComponent;
    return _this;
  }

  _createClass(Reader, [{
    key: 'componentDidMount',
    value: function componentDidMount() {
      if (!this.props.legacyMode) {
        this.initiate();
      } else {
        this.initiateLegacyMode();
      }
    }
  }, {
    key: 'componentWillReceiveProps',
    value: function componentWillReceiveProps(newProps) {
      if (!newProps.legacyMode && this.props.facingMode != newProps.facingMode) {
        this.clearComponent();
        this.initiate();
      }
      if (!this.props.legacyMode && newProps.legacyMode) {
        this.clearComponent();
        this.componentDidUpdate = this.initiateLegacyMode;
      }
      if (this.props.legacyMode && !newProps.legacyMode) {
        this.clearComponent();
        this.initiate();
      }
    }
  }, {
    key: 'clearComponent',
    value: function clearComponent() {
      if (this._interval) clearInterval(this._interval);

      if (typeof this.stopCamera === 'function') this.stopCamera();

      if (this.requestFrameId) {
        window.cancelAnimationFrame(this.requestFrameId);
        delete this.requestFrameId;
      }

      if (this.reader) {
        this.reader.removeEventListener('load', this.handleReaderLoad);
        this.reader = undefined;
      }

      if (this.refs.img) {
        this.refs.img.removeEventListener('load', this.check);
      }
    }
  }, {
    key: 'initiate',
    value: function initiate() {
      var _props = this.props;
      var handleError = _props.handleError;
      var facingMode = _props.facingMode;

      var constrains = {
        video: {
          facingMode: facingMode ? {
            exact: facingMode == 'rear' ? 'environment' : 'user'
          } : undefined,
          width: { min: 360, ideal: 1280, max: 1920 },
          height: { min: 240, ideal: 720, max: 1080 }
        }
      };

      try {
        navigator.mediaDevices.getUserMedia(constrains).then(this.handleVideo).catch(function (e) {
          return handleError(e.name);
        });
      } catch (e) {
        handleError('Not compatible with getUserMedia.');
      }
    }
  }, {
    key: 'handleVideo',
    value: function handleVideo(stream) {
      var preview = this.refs.preview;

      if (window.URL.createObjectURL) {
        preview.src = window.URL.createObjectURL(stream);
      } else if (window.webkitURL) {
        preview.src = window.webkitURL.createObjectURL(stream);
      } else if (preview.mozSrcObject !== undefined) {
        preview.mozSrcObject = stream;
      } else {
        preview.src = stream;
      }

      var streamTrack = stream.getTracks()[0];
      this.stopCamera = streamTrack.stop.bind(streamTrack);

      preview.addEventListener('loadstart', this.handleLoadStart);
    }
  }, {
    key: 'handleLoadStart',
    value: function handleLoadStart() {
      var preview = this.refs.preview;
      preview.play();
      if (this.props.interval) {
        this._interval = setInterval(this.check, this.props.interval);
      } else if (!this.requestFrameId) {
        this.check();
      }

      preview.removeEventListener('loadstart', this.handleLoadStart);
    }
  }, {
    key: 'check',
    value: function check() {
      var _props2 = this.props;
      var interval = _props2.interval;
      var handleScan = _props2.handleScan;
      var legacyMode = _props2.legacyMode;
      var _refs = this.refs;
      var preview = _refs.preview;
      var canvas = _refs.canvas;
      var img = _refs.img;

      var width = Math.floor(legacyMode ? img.naturalWidth : preview.videoWidth);
      var height = Math.floor(legacyMode ? img.naturalHeight : preview.videoHeight);

      if (legacyMode) {
        var ratio = 1.2;
        while ((width > height ? width : height) > 1000) {
          width = Math.floor(width / ratio);
          height = Math.floor(height / ratio);
        }
      }

      canvas.width = width;
      canvas.height = height;

      if (!interval && !legacyMode) this.requestFrameId = window.requestAnimationFrame(this.check);

      if (legacyMode || preview && preview.readyState === preview.HAVE_ENOUGH_DATA) {
        var ctx = canvas.getContext('2d');
        ctx.drawImage(legacyMode ? img : preview, 0, 0, width, height);

        this.props.handleScan('height:' + height + ', width:' + width);

        var imageData = ctx.getImageData(0, 0, width, height);
        var decoded = _jsqr2.default.decodeQRFromImage(imageData.data, width, height);

        if (decoded) handleScan(decoded);
      }
    }
  }, {
    key: 'initiateLegacyMode',
    value: function initiateLegacyMode() {
      this.reader = new FileReader();

      this.reader.addEventListener('load', this.handleReaderLoad);

      this.refs.img.addEventListener('load', this.check, false);

      this.componentDidUpdate = undefined;
    }
  }, {
    key: 'handleInputChange',
    value: function handleInputChange(e) {
      this.reader.readAsDataURL(e.target.files[0]);
    }
  }, {
    key: 'handleReaderLoad',
    value: function handleReaderLoad(e) {
      this.refs.img.src = e.target.result;
    }
  }, {
    key: 'render',
    value: function render() {
      var previewStyle = _extends({
        display: 'block',
        objectFit: 'contain'
      }, this.props.previewStyle);
      var canvasStyle = {
        display: 'none'
      };

      return _react2.default.createElement(
        'section',
        null,
        this.props.legacyMode ? _react2.default.createElement(
          'div',
          null,
          _react2.default.createElement('input', { style: this.props.inputStyle, type: 'file', accept: 'image/*', ref: 'input', onChange: this.handleInputChange }),
          _react2.default.createElement('img', { style: _extends({}, previewStyle, { display: 'none' }), ref: 'img' })
        ) : _react2.default.createElement('video', { style: previewStyle, ref: 'preview' }),
        _react2.default.createElement('canvas', { style: canvasStyle, ref: 'canvas' })
      );
    }
  }]);

  return Reader;
}(_react.Component);

exports.default = Reader;

Reader.defaultProps = {
  interval: null,
  previewStyle: {},
  inputStyle: {}
};
Reader.propTypes = {
  handleScan: _react.PropTypes.func.isRequired,
  handleError: _react.PropTypes.func.isRequired,
  interval: _react.PropTypes.number,
  previewStyle: _react.PropTypes.object,
  inputStyle: _react.PropTypes.object,
  facingMode: _react.PropTypes.string,
  legacyMode: _react.PropTypes.bool
};<|endoftext|>


<commit_before>(function(){

  function Lumine(){

    this.Scenes = {};
    this.Layers = {};

  }

  Lumine.prototype = {

    Composer: require('./composer'),
    Canvas: require('./canvas'),
    Shaders: require('./shaders'),
    Passes: require('./passes'),

    use: function(Scenes, Layers){

      var allScenes, allLayers;

      if(arguments.length > 1){
        allScenes = Scenes;
        allLayers = Layers;
      }
      else{
        allScenes = Scenes.hasOwnProperty('Scenes') ? Scenes.Scenes : {};
        allLayers = Scenes.hasOwnProperty('Layers') ? Scenes.Layers : {};
      }

      Object.keys(allScenes).forEach(function(name){
        this.Scenes[name] = allScenes[name];
      }.bind(this));

      Object.keys(allLayers).forEach(function(name){
        this.Layers[name] = allLayers[name];
      }.bind(this));

      return this;

    },

    init: function(scenes, options, done){

      var opts = options || {};

      Object.keys(scenes).forEach(function(type){

        var sceneOpts = scenes[type],
            scene = new this.Scenes[type](
              // find the canvas element
              opts.canvas
              || sceneOpts.canvas
              || document.querySelector('canvas.' + type)
              || document.querySelector('canvas.lumine'),
              sceneOpts
            );

        scene.canvas.start();

      });

    }

  };

  module.exports = window.Lumine = new Lumine();

})();<commit_msg>Fixing scene declaration.<commit_after>(function(){

  function Lumine(){

    this.Scenes = {};
    this.Layers = {};

  }

  Lumine.prototype = {

    Composer: require('./composer'),
    Canvas: require('./canvas'),
    Shaders: require('./shaders'),
    Passes: require('./passes'),

    use: function(Scenes, Layers){

      var allScenes, allLayers;

      if(arguments.length > 1){
        allScenes = Scenes;
        allLayers = Layers;
      }
      else{
        allScenes = Scenes.hasOwnProperty('Scenes') ? Scenes.Scenes : {};
        allLayers = Scenes.hasOwnProperty('Layers') ? Scenes.Layers : {};
      }

      Object.keys(allScenes).forEach(function(name){
        this.Scenes[name] = allScenes[name];
      }.bind(this));

      Object.keys(allLayers).forEach(function(name){
        this.Layers[name] = allLayers[name];
      }.bind(this));

      return this;

    },

    init: function(scenes, options, done){

      var opts = options || {};

      Object.keys(scenes).forEach(function(type){

        var sceneOpts = scenes[type],

            scene = new this.Scenes[type](

              // find the canvas element
              opts.canvas
              || sceneOpts.canvas
              || document.querySelector('canvas.' + type)
              || document.querySelector('canvas.lumine'),

              // this lumine instance
              this,

              // options
              sceneOpts

            );

        scene.canvas.start();

      }.bind(this));

    }

  };

  module.exports = window.Lumine = new Lumine();

})();<|endoftext|>


<commit_before>var louis = require("../test/louis"),
	cowboy = require("../lib/cowboy"),
	http = require('http');

var server = http.createServer(function (req, res) {
  res.writeHead(200, {"Content-Type": "text/plain"});
  res.end("Hello World\n");
});

server.listen(3000);

var lou = new louis({
	freq: 1000,
	total: 10
});

var boy = new cowboy();

lou.start();

lou.on("data", function( mask, bg ){
	boy.mask(mask, bg);
});

boy.on("done", function( image ){
	console.log('done');
});<commit_msg>comments and consoles<commit_after>var louis = require("../test/louis"),
	cowboy = require("../lib/cowboy"),
	http = require('http');

var server = http.createServer(function (req, res) {
  res.writeHead(200, {"Content-Type": "text/plain"});
  res.end("Hello World\n");
});

server.listen(3000);

var lou = new louis({
	freq: 1000,
	total: 10
});

var boy = new cowboy();

//start the test setInterval
lou.start();

lou.on("data", function( depth, rgb ){
	console.log("depth: " + depth);
	console.log("test rgb: " + rgb);
	boy.mask(depth, rgb);
});

boy.on("done", function( image ){
	console.log('done');
});<|endoftext|>


<commit_before>var _ = require('lodash');
var async = require('async-chainable');
var csvParser = require('csv-parser');
var fs = require('fs');
var gulp = require('gulp');
var gutil = require('gulp-util');
var util = require('util');

var paths = {
	html: './index.html',
	srsCsv: './data/sr-disease-interventions.csv',
	rctsCsv: './data/rct-disease-interventions.csv',
};

gulp.task('default', ['build']);

gulp.task('build', function(next) {
	async()
		.limit(50)

		// Read in external data
		.parallel({
			rowsR: function(next) {
				var rows = [];
				fs.createReadStream(paths.rctsCsv)
					.pipe(csvParser())
					.on('data', function(row) {
						var values = _.values(row);
						if (values[0] && values[1] && values[2])
							rows.push(values);
					})
					.on('error', next)
					.on('finish', function() {
						next(null, rows);
					});
			},
			rowsS: function(next) {
				var rows = [];
				fs.createReadStream(paths.srsCsv)
					.pipe(csvParser())
					.on('data', function(row) {
						var values = _.values(row);
						if (values[0] && values[1] && values[2])
							rows.push(values);
					})
					.on('error', next)
					.on('finish', function() {
						next(null, rows);
					});
			},
			html: function(next) {
				fs.readFile(paths.html, next);
			},
		})

		// Process data into a hash
		.parallel({
			lookupS: function(next) {
				var lookup = {};

				this.rowsS.forEach(function(row) {
					var key = row[1] + '-' + row[2];
					if (lookup[key]) {
						lookup[key].value++;
					} else {
						lookup[key] = {
							disease: row[1],
							intervention: row[2],
							value: 1,
						};
					}
				});
				next(null, lookup);
			},
			lookupR: function(next) {
				var lookup = {};

				this.rowsR.forEach(function(row) {
					var key = row[1] + '-' + row[2];
					if (lookup[key]) {
						lookup[key].value++;
					} else {
						lookup[key] = {
							disease: row[1],
							intervention: row[2],
							value: 1,
						};
					}
				});
				next(null, lookup);
			}
		})

		// Format back into an array
		.set('disguardedRcts', 0)
		.parallel({
			dataR: function(next) {
				var self = this;
				var data = [];
				_.forEach(this.lookupR, function(relationship) {
					if (!relationship.disease || !relationship.intervention) return;
					if (relationship.value < 3) { // FILTER: Disguard any RCT link below this limit
						self.disguardedRcts++;
						return;
					}
					data.push([
						relationship.intervention,
						relationship.disease,
						relationship.value,
					]);
				});
				next(null, data);
			},
			dataS: function(next) {
				var self = this;
				var data = [];
				_.forEach(this.lookupS, function(relationship) {
					if (!relationship.disease || !relationship.intervention) return;
					data.push([
						relationship.intervention,
						relationship.disease,
						relationship.value,
					]);
				});
				next(null, data);
			},
		})

		// Write file
		.then(function(next) {
			fs.writeFile(paths.html, this.html
				.toString()
				.replace(/\/\/ AUTO-INSERTED DATA \(SRs\) {{{[\s\S]+?}}}/, '// AUTO-INSERTED DATA (SRs) {{{\n' + util.inspect(this.dataS) + ';\n// }}}')
				.replace(/\/\/ AUTO-INSERTED DATA \(RCTs\) {{{[\s\S]+?}}}/, '// AUTO-INSERTED DATA (RCTs) {{{\n' + util.inspect(this.dataR) + ';\n// }}}')
			, next);
		})

		// Print statistics
		.then(function(next) {
			gutil.log(
				'RCT Papers:',
				_.keys(this.lookupR).length,
				'(',
				_(this.lookupR)
					.pluck('disease')
					.uniq()
					.value()
					.length,
				'diseases,',
				_(this.lookupR)
					.pluck('intervention')
					.uniq()
					.value()
					.length,
				'interventions,',
				this.disguardedRcts,
				' disguarded links)'
			);

			gutil.log(
				'SR Papers:',
				_.keys(this.lookupS).length,
				'(',
				_(this.lookupS)
					.pluck('disease')
					.uniq()
					.value()
					.length,
				'diseases,',
				_(this.lookupS)
					.pluck('intervention')
					.uniq()
					.value()
					.length,
				'interventions )'
			);

			next();
		})

		.end(next);
});
<commit_msg>Tweaks to data generation process<commit_after>var _ = require('lodash');
var async = require('async-chainable');
var csvParser = require('csv-parser');
var fs = require('fs');
var gulp = require('gulp');
var gutil = require('gulp-util');
var util = require('util');

var options = {
	minRCT: 5, // FILTER: Disguard any RCT link below this limit
};

var paths = {
	html: './index.html',
	srsCsv: './data/sr-disease-interventions.csv',
	rctsCsv: './data/rct-disease-interventions.csv',
};

gulp.task('default', ['build']);

gulp.task('build', function(next) {
	async()
		.limit(50)

		// Read in external data
		.parallel({
			rowsR: function(next) {
				var rows = [];
				fs.createReadStream(paths.rctsCsv)
					.pipe(csvParser())
					.on('data', function(row) {
						var values = _.values(row);
						if (values[0] && values[1] && values[2])
							rows.push(values);
					})
					.on('error', next)
					.on('finish', function() {
						next(null, rows);
					});
			},
			rowsS: function(next) {
				var rows = [];
				fs.createReadStream(paths.srsCsv)
					.pipe(csvParser())
					.on('data', function(row) {
						var values = _.values(row);
						if (values[0] && values[1] && values[2])
							rows.push(values);
					})
					.on('error', next)
					.on('finish', function() {
						next(null, rows);
					});
			},
			html: function(next) {
				fs.readFile(paths.html, next);
			},
		})

		// Process data into a hash
		.parallel({
			lookupS: function(next) {
				var lookup = {};

				this.rowsS.forEach(function(row) {
					var key = row[1] + '-' + row[2];
					if (lookup[key]) {
						lookup[key].value++;
					} else {
						lookup[key] = {
							disease: row[2],
							intervention: row[1],
							value: 1,
						};
					}
				});
				next(null, lookup);
			},
			lookupR: function(next) {
				var lookup = {};

				this.rowsR.forEach(function(row) {
					var key = row[1] + '-' + row[2];
					if (lookup[key]) {
						lookup[key].value++;
					} else {
						lookup[key] = {
							disease: row[2],
							intervention: row[1],
							value: 1,
						};
					}
				});
				next(null, lookup);
			}
		})

		// Format back into an array
		.set('disguardedRcts', 0)
		.parallel({
			dataR: function(next) {
				var self = this;
				var data = [];
				_.forEach(this.lookupR, function(relationship) {
					if (!relationship.disease || !relationship.intervention) return;
					if (relationship.value < options.minRCT) { // FILTER: Disguard any RCT link below this limit
						self.disguardedRcts++;
						return;
					}
					data.push([
						relationship.intervention,
						relationship.disease,
						relationship.value,
					]);
				});
				next(null, data);
			},
			dataS: function(next) {
				var self = this;
				var data = [];
				_.forEach(this.lookupS, function(relationship) {
					if (!relationship.disease || !relationship.intervention) return;
					data.push([
						relationship.intervention,
						relationship.disease,
						relationship.value,
					]);
				});
				next(null, data);
			},
		})

		// Check for gaps in SR from RCT
		.then(function(next) {
			var self = this;
			this.dataR.forEach(function(link) {
				if (_.find(self.dataS, function(l) {
					return l[0] == link[0] && l[1] == link[1];
				}) === undefined) {
					self.dataS.push([
						link[0],
						link[1],
						0,
					]);
				}
			});
			next();
		})

		// Compile sort list of Interventions
		.parallel({
			sortOrderInt: function(next) {
				var sortOrder = {};

				this.dataR.forEach(function(link) {
					if (!sortOrder[link[0]])
						sortOrder[link[0]] = 0;
					sortOrder[link[0]] += link[2];
				});

				next(null, sortOrder);
			},
			sortOrderDis: function(next) {
				var sortOrder = {};

				this.dataR.forEach(function(link) {
					if (!sortOrder[link[1]])
						sortOrder[link[1]] = 0;
					sortOrder[link[1]] += link[2];
				});

				next(null, sortOrder);
			},
		})

		// Sort array by RCT value
		.parallel([
			function(next) {
				var self = this;
				this.dataR.sort(function(a, b) {
					var sortValueIntA = self.sortOrderInt[a[0]] || 0;
					var sortValueIntB = self.sortOrderInt[b[0]] || 0;
					var sortValueDisA = self.sortOrderDis[a[1]] || 0;
					var sortValueDisB = self.sortOrderDis[b[1]] || 0;

					if (sortValueIntA > sortValueIntB) {
						return -1;
					} else if (sortValueIntA < sortValueIntB) {
						return 1;
					} else if (sortValueDisA > sortValueDisB) {
						return -1;
					} else if (sortValueDisA < sortValueDisB) {
						return 1;
					} else {
						return 0;
					}
				});
				next();
			},
			function(next) {
				var self = this;
				this.dataS.sort(function(a, b) {
					var sortValueIntA = self.sortOrderInt[a[0]] || 0;
					var sortValueIntB = self.sortOrderInt[b[0]] || 0;
					var sortValueDisA = self.sortOrderDis[a[1]] || 0;
					var sortValueDisB = self.sortOrderDis[b[1]] || 0;

					a[3] = sortValueIntA + '<=>' + sortValueIntB + '!' + sortValueDisA + '<=>' + sortValueDisB;

					if (sortValueIntA > sortValueIntB) {
						return -1;
					} else if (sortValueIntA < sortValueIntB) {
						return 1;
					} else if (sortValueDisA > sortValueDisB) {
						return -1;
					} else if (sortValueDisA < sortValueDisB) {
						return 1;
					} else {
						return 0;
					}
				});
				next();
			},
		])

		// Write file
		.then(function(next) {
			fs.writeFile(paths.html, this.html
				.toString()
				.replace(/\/\/ AUTO-INSERTED DATA \(SRs\) {{{[\s\S]+?}}}/, '// AUTO-INSERTED DATA (SRs) {{{\n' + util.inspect(this.dataS) + ';\n// }}}')
				.replace(/\/\/ AUTO-INSERTED DATA \(RCTs\) {{{[\s\S]+?}}}/, '// AUTO-INSERTED DATA (RCTs) {{{\n' + util.inspect(this.dataR) + ';\n// }}}')
			, next);
		})

		// Print statistics
		.then(function(next) {
			gutil.log(
				'RCT Papers:',
				_.keys(this.lookupR).length,
				'(',
				_(this.lookupR)
					.pluck('disease')
					.uniq()
					.value()
					.length,
				'diseases,',
				_(this.lookupR)
					.pluck('intervention')
					.uniq()
					.value()
					.length,
				'interventions,',
				this.disguardedRcts,
				' disguarded links)'
			);

			gutil.log(
				'SR Papers:',
				_.keys(this.lookupS).length,
				'(',
				_(this.lookupS)
					.pluck('disease')
					.uniq()
					.value()
					.length,
				'diseases,',
				_(this.lookupS)
					.pluck('intervention')
					.uniq()
					.value()
					.length,
				'interventions )'
			);

			next();
		})

		.end(next);
});
<|endoftext|>


<commit_before>'use strict'

const fs = require('fs')
const rollup = require('rollup').rollup
const _ = require('lodash')

function createPreprocessor (customConfig, baseConfig, logger) {
	const dependencyMap = new Map()
	const staleDependants = new Set()
	const log = logger.create('preprocessor.rollup')

	let cache

	/**
	 * Manually update the modified and accessed timestamps
	 * of all dependants marked by changed dependencies.
	 */
	const recompileDependants = _.debounce(() => {
		const now = Date.now()
		for (const dependant of staleDependants.values()) {
			fs.utimes(dependant, now, now, () => {
				log.debug('Recompiling dependant %s', dependant)
			})
		}
		staleDependants.clear()
	}, 50)

	const config = _.assign({}, baseConfig, (customConfig || {}).options)

	function preprocess (content, file, done) {
		log.debug('Processing %s', file.originalPath)

		try {
			config.entry = file.originalPath
			config.cache = cache

			rollup(config).then(bundle => {

				/**
				 * Map all dependencies of the current file
				 */
				file.dependencies = bundle.modules
					.map(module => module.id)
					.filter(id => id !== file.originalPath)

				dependencyMap.set(file.originalPath, file.dependencies)

				/**
				 * Check all dependants to see if the current file
				 * is one of their dependencies, marking those that
				 * match as stale and triggering their recompilation.
				 */
				for (const entry of dependencyMap.entries()) {
					const dependant = entry[0]
					const dependencies = entry[1]
					if (dependencies.indexOf(file.originalPath) !== -1) {
						staleDependants.add(dependant)
						recompileDependants()
					}
				}

				const generated = bundle.generate(config)

				const processed = (config.sourceMap === 'inline')
					? generated.code + `\n//# sourceMappingURL=${generated.map.toUrl()}\n`
					: generated.code

				cache = bundle
				done(null, processed)
			})
			.catch(error => {
				log.error('Failed to process %s\n\n%s\n', file.originalPath, error.message)
				done(error, null)
			})

		} catch (exception) {
			log.error('Exception processing %s\n\n%s\n', file.originalPath, exception.message)
			done(exception, null)
		}
	}

	return preprocess
}

createPreprocessor.$inject = ['args', 'config.rollupPreprocessor', 'logger']

module.exports = {
	'preprocessor:rollup': ['factory', createPreprocessor],
}
<commit_msg>update rollup integration [fixed #22]<commit_after>'use strict'

const fs = require('fs')
const rollup = require('rollup').rollup
const _ = require('lodash')

function createPreprocessor (customConfig, baseConfig, logger) {
	const dependencyMap = new Map()
	const staleDependants = new Set()
	const log = logger.create('preprocessor.rollup')

	let cache

	/**
	 * Manually update the modified and accessed timestamps
	 * of all dependants marked by changed dependencies.
	 */
	const recompileDependants = _.debounce(() => {
		const now = Date.now()
		for (const dependant of staleDependants.values()) {
			fs.utimes(dependant, now, now, () => {
				log.debug('Recompiling dependant %s', dependant)
			})
		}
		staleDependants.clear()
	}, 50)

	const config = _.assign({}, baseConfig, (customConfig || {}).options)

	function preprocess (content, file, done) {
		log.debug('Processing %s', file.originalPath)

		try {
			config.entry = file.originalPath
			config.cache = cache

			rollup(config).then(bundle => {

				/**
				 * Map all dependencies of the current file
				 */
				file.dependencies = bundle.modules
					.map(module => module.id)
					.filter(id => id !== file.originalPath)

				dependencyMap.set(file.originalPath, file.dependencies)

				/**
				 * Check all dependants to see if the current file
				 * is one of their dependencies, marking those that
				 * match as stale and triggering their recompilation.
				 */
				for (const entry of dependencyMap.entries()) {
					const dependant = entry[0]
					const dependencies = entry[1]
					if (dependencies.indexOf(file.originalPath) !== -1) {
						staleDependants.add(dependant)
						recompileDependants()
					}
				}

				// Return the promise so that errors will be handled by the `catch` statement below.
				return Promise.resolve(bundle.generate(config)).then((generated) => {
					const processed = (config.sourceMap === 'inline')
						? generated.code + `\n//# sourceMappingURL=${generated.map.toUrl()}\n`
						: generated.code

					cache = bundle
					done(null, processed)
				})
			})
			.catch(error => {
				log.error('Failed to process %s\n\n%s\n', file.originalPath, error.message)
				done(error, null)
			})

		} catch (exception) {
			log.error('Exception processing %s\n\n%s\n', file.originalPath, exception.message)
			done(exception, null)
		}
	}

	return preprocess
}

createPreprocessor.$inject = ['args', 'config.rollupPreprocessor', 'logger']

module.exports = {
	'preprocessor:rollup': ['factory', createPreprocessor],
}
<|endoftext|>


<commit_before>//-------------------------------------------------------------------------------
// Copyright IBM Corp. 2015
//
// Licensed under the Apache License, Version 2.0 (the 'License');
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an 'AS IS' BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//-------------------------------------------------------------------------------

'use strict';

var request = require('request');
var _ = require('lodash');
var async = require('async');
var pipesSDK = require.main.require('simple-data-pipe-sdk');
var connectorExt = pipesSDK.connectorExt;
var bluemixHelperConfig = require.main.require('bluemix-helper-config');
var configManager = bluemixHelperConfig.configManager;
var vcapServices = bluemixHelperConfig.vcapServices;
var util = require('util');

var concurrency = 20;	//Async queue concurrency
/**
 * Pipes Connector for Reddit
 */
function redditConnector( parentDirPath ){

	//Call constructor from super class
	connectorExt.call(this, 'reddit', 'Reddit AMA', {
		extraRequiredFields: 'amaURL',
		useOAuth: false,
		useCustomTables: true
	});

	this.getTablePrefix = function(){
		return 'reddit';
	}

	this.getCloudantDbName = function(pipe, table){
		return pipe.name + '_' + table.name;
	}

	var watsonToneAnalyzerService = vcapServices.getService( configManager.get('WATSON_TONE_ANALYZER') || 'tone analyzer' );

	this.fetchRecords = function( table, pushRecordFn, done, pipeRunStep, pipeRunStats, logger, pipe, pipeRunner ){

	// TODO set log level
	logger.level('info');

console.log(table);

		if ( !watsonToneAnalyzerService ){
			var msg = 'Unable to find Watson Tone Analyzer Service';
			logger.error( msg );
			return done( msg );
		}

		if (( !pipe.amaURL ) || (pipe.amaURL.length < 1)){
			return done('Missing or empty field amaURL');
		}

		var amaJsonURL = '';
		// append json suffix to amaURL
		// input: https://www.reddit.com/r/IAmA/comments/3ilzey/were_a_bunch_of_developers_from_ibm_ask_us.json or
		//        https://www.reddit.com/r/IAmA/comments/3ilzey/were_a_bunch_of_developers_from_ibm_ask_us or
		//        https://www.reddit.com/r/IAmA/comments/3ilzey/were_a_bunch_of_developers_from_ibm_ask_us/
		// output https://www.reddit.com/r/IAmA/comments/3ilzey/were_a_bunch_of_developers_from_ibm_ask_us.json

        if(pipe.amaURL.match(/\.json$/)) {
        	amaJsonURL = pipe.amaURL;
        }
        else {
			if(pipe.amaURL.charAt(pipe.amaURL.length-1) == '/') {
				amaJsonURL = pipe.amaURL.replace(/\/+$/,'.json');
			}
			else {
				amaJsonURL = pipe.amaURL + '.json';
			}
		}

		logger.info('Connecting to AMA with url ' + amaJsonURL);

		request.get(amaJsonURL, {'json': true},
			function( err, response, body ){
				if ( err ){
					logger.error('Unable to fetch AMA: ' + err );
					return done( err );
				}

				logger.debug('Reddit API response: ' + response);

				// Create an async queue to process the record with Watson Tone Analyzer
				var q = async.queue( function( post, callback ){

					logger.debug(util.inspect(post));

					var msg = '';

					// Call Tone analyzer to get sentiments from the post
					// https://www.ibm.com/smarterplanet/us/en/ibmwatson/developercloud/doc/tone-analyzer/output.shtml
					request.post( watsonToneAnalyzerService.credentials.url + '/v3/tone?version=2016-02-11',{
						'auth': {
						  'user': watsonToneAnalyzerService.credentials.username,
						  'pass': watsonToneAnalyzerService.credentials.password,
						  'sendImmediately': true
						},
						'json': {
							'text': post.selftext || post.body
						}
					}, function( err, response, body ){

						if ( err ){
							msg = 'Error querying Watson Tone Analyzer service: ' + err;
							logger.error(msg);
							return callback( msg );
						}

						logger.debug('WTA response: ' + util.inspect(response));
						logger.debug('WTA body: ' + util.inspect(body));

						if(response.statusCode >= 300) {
							msg = 'Call to Watson Tone Analyzer URL ' + response.request.uri.href + ' returned status ' + response.statusCode + ' (' + response.body.error + ')';
							logger.error(msg);
							return callback(msg);
						}

						var sentiments = {
											author: post.author,
											created: post.created_utc,
											edited: post.edited,
											id: post.id,
											num_comments: post.num_comments,
											title: post.title || '',
											text: post.selftext || post.body
                                         };

                        if(body.sentences_tone) {
                        	// process sentiment analysis results

                        	/*
                        	    Sample API v3 result (1 record per sentence in the post)

								 {
								  sentence_id: 0,
								  text: 'What language do you guys use the most?'
								  input_from: 0,
								  input_to: 39,
								  tone_categories:
								   [ { tones: [
								               {"score":0.121007, "tone_id":"anger", "tone_name":"Anger"},
								               {"score":0.096337, "tone_id":"disgust", "tone_name":"Disgust"},
								               {"score":0.251543, "tone_id":"fear", "tone_name":"Fear"},
								               {"score":0.242078, "tone_id":"joy", "tone_name":"Joy"},
								               {"score":0.289034, "tone_id":"sadness", "tone_name":"Sadness"}
											  ],
								       category_id: 'emotion_tone',
								       category_name: 'Emotion Tone' },
								     { tones: [
											   {"score":0, "tone_id":"analytical", "tone_name":"Analytical"},
											   {"score":0,"tone_id":"confident","tone_name":"Confident"},
											   {"score":0,"tone_id":"tentative","tone_name":"Tentative"}
								     		  ],
								       category_id: 'writing_tone',
								       category_name: 'Writing Tone' },
								     { tones: [
								     		   {"score":0.332, "tone_id":"openness_big5", "tone_name":"Openness"},
								     		   {"score":0.784, "tone_id":"conscientiousness_big5", "tone_name":"Conscientiousness"},
								     		   {"score":0.367, "tone_id":"extraversion_big5", "tone_name":"Extraversion"},
								     		   {"score":0.567, "tone_id":"agreeableness_big5", "tone_name":"Agreeableness"},
								     		   {"score":0.628,"tone_id":"neuroticism_big5", "tone_name":"Emotional Range"}
								     		  ],
								       category_id: 'social_tone',
								       category_name: 'Social Tone'
								     }
								   ]
								 }

                        	*/

                        	_.forEach(body.sentences_tone, function(sentence) {

								if(sentence.tone_categories){
									// tone categories are ['emotion_tone','writing_tone','social_tone']
									_.forEach(sentence.tone_categories, function(tone_category) {
										if(! sentiments.hasOwnProperty([tone_category.category_id])) {
											sentiments[tone_category.category_id] = tone_category.tones;
											/*

											   sentiments."emotion_tone" = [
															                {"score":0.121007, "tone_id":"anger", "tone_name":"Anger"},
															                {"score":0.096337, "tone_id":"disgust", "tone_name":"Disgust"},
															                {"score":0.251543, "tone_id":"fear", "tone_name":"Fear"},
															                {"score":0.242078, "tone_id":"joy", "tone_name":"Joy"},
															                {"score":0.289034, "tone_id":"sadness", "tone_name":"Sadness"}
															               ]
											*/
										}
										else {
											// todo agggregation
										}
									});
								}
							});

							// save in Cloudant
                            pushRecordFn(sentiments);

                        }
                        else {
                        	// No tone analyzer results were returned
                        	// Don't store post in Cloudant
                        	logger.warn('No Tone Analyze results were returned for ' + sentiments.text + '.');
                        }

   						return callback();

                    }); // post
				}, concurrency ); // async

				_.forEach( body, function( listing ){
					if ( listing.kind == 'Listing' && listing.hasOwnProperty('data' ) ){
						if ( listing.data.hasOwnProperty('children') ){
							//Get the children from the data fields, only process the top posts for now
							_.forEach( listing.data.children, function( post ){
								if ( post.hasOwnProperty('data') ){
									// add post to queue only if it contains text
									if((post.data.hasOwnProperty('selftext')) || (post.data.hasOwnProperty('body'))) {
										q.push( post.data );
									}
								}
							});
						}
					}
				});

				// Drain function is invoked after all posts have been processed
				q.drain = function(){
					// pipe processing complete
					return done();
				}

				// if the queue is empty asynchronous processing has already completed (or there was nothing to process)
				if(q.idle()) {
					return done();
				}

			}
		);
	};
}

//Extend event Emitter
require('util').inherits(redditConnector, connectorExt);

module.exports = new redditConnector();
<commit_msg>use document tone<commit_after>//-------------------------------------------------------------------------------
// Copyright IBM Corp. 2015
//
// Licensed under the Apache License, Version 2.0 (the 'License');
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an 'AS IS' BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//-------------------------------------------------------------------------------

'use strict';

var request = require('request');
var _ = require('lodash');
var async = require('async');
var pipesSDK = require.main.require('simple-data-pipe-sdk');
var connectorExt = pipesSDK.connectorExt;
var bluemixHelperConfig = require.main.require('bluemix-helper-config');
var configManager = bluemixHelperConfig.configManager;
var vcapServices = bluemixHelperConfig.vcapServices;
var util = require('util');

var concurrency = 20;	//Async queue concurrency
/**
 * Pipes Connector for Reddit
 */
function redditConnector( parentDirPath ){

	//Call constructor from super class
	connectorExt.call(this, 'reddit', 'Reddit AMA', {
		extraRequiredFields: 'amaURL',
		useOAuth: false,
		useCustomTables: true
	});

	this.getTablePrefix = function(){
		return 'reddit';
	}

	this.getCloudantDbName = function(pipe, table){
		return pipe.name + '_' + table.name;
	}

	var watsonToneAnalyzerService = vcapServices.getService( configManager.get('WATSON_TONE_ANALYZER') || 'tone analyzer' );

	this.fetchRecords = function( table, pushRecordFn, done, pipeRunStep, pipeRunStats, logger, pipe, pipeRunner ){

	// TODO set log level
	logger.level('info');

console.log(table);

		if ( !watsonToneAnalyzerService ){
			var msg = 'Unable to find Watson Tone Analyzer Service';
			logger.error( msg );
			return done( msg );
		}

		if (( !pipe.amaURL ) || (pipe.amaURL.length < 1)){
			return done('Missing or empty field amaURL');
		}

		var amaJsonURL = '';
		// append json suffix to amaURL
		// input: https://www.reddit.com/r/IAmA/comments/3ilzey/were_a_bunch_of_developers_from_ibm_ask_us.json or
		//        https://www.reddit.com/r/IAmA/comments/3ilzey/were_a_bunch_of_developers_from_ibm_ask_us or
		//        https://www.reddit.com/r/IAmA/comments/3ilzey/were_a_bunch_of_developers_from_ibm_ask_us/
		// output https://www.reddit.com/r/IAmA/comments/3ilzey/were_a_bunch_of_developers_from_ibm_ask_us.json

        if(pipe.amaURL.match(/\.json$/)) {
        	amaJsonURL = pipe.amaURL;
        }
        else {
			if(pipe.amaURL.charAt(pipe.amaURL.length-1) == '/') {
				amaJsonURL = pipe.amaURL.replace(/\/+$/,'.json');
			}
			else {
				amaJsonURL = pipe.amaURL + '.json';
			}
		}

		logger.info('Connecting to AMA with url ' + amaJsonURL);

		request.get(amaJsonURL, {'json': true},
			function( err, response, body ){
				if ( err ){
					logger.error('Unable to fetch AMA: ' + err );
					return done( err );
				}

				logger.debug('Reddit API response: ' + response);

				// Create an async queue to process the record with Watson Tone Analyzer
				var q = async.queue( function( post, callback ){

					logger.debug(util.inspect(post));

					var msg = '';

					// Call Tone analyzer to get sentiments from the post
					// https://www.ibm.com/smarterplanet/us/en/ibmwatson/developercloud/doc/tone-analyzer/output.shtml
					request.post( watsonToneAnalyzerService.credentials.url + '/v3/tone?version=2016-02-11',{
						'auth': {
						  'user': watsonToneAnalyzerService.credentials.username,
						  'pass': watsonToneAnalyzerService.credentials.password,
						  'sendImmediately': true
						},
						'json': {
							'text': post.selftext || post.body
						}
					}, function( err, response, body ){

						if ( err ){
							msg = 'Error querying Watson Tone Analyzer service: ' + err;
							logger.error(msg);
							return callback( msg );
						}

						logger.debug('WTA response: ' + util.inspect(response));
						logger.debug('WTA body: ' + util.inspect(body));

						if(response.statusCode >= 300) {
							msg = 'Call to Watson Tone Analyzer URL ' + response.request.uri.href + ' returned status ' + response.statusCode + ' (' + response.body.error + ')';
							logger.error(msg);
							return callback(msg);
						}

						var sentiments = {
											author: post.author,
											created: post.created_utc,
											edited: post.edited,
											id: post.id,
											num_comments: post.num_comments,
											title: post.title || '',
											text: post.selftext || post.body
                                         };

                        if(body.document_tone) {

                        	/*

                        	Tone Analyzer API v3 output

							{
							    document_tone: {

												tone_categories: [
																  	{
																  	  tones: [ [Object], [Object], [Object], [Object], [Object] ],
																  	  category_id: 'emotion_tone',
																      category_name: 'Emotion Tone'
																    },
																    {
																      tones: [ [Object], [Object], [Object] ],
																      category_id: 'writing_tone',
																      category_name: 'Writing Tone'
																    },
																    {
																      tones: [ [Object], [Object], [Object], [Object], [Object] ],
																      category_id: 'social_tone',
																      category_name: 'Social Tone'
																    }
															      ]
										        },
							    sentences_tone: ...

							}

                        	*/

							logger.debug('Document tone categories: ' + util.inspect(body.document_tone.tone_categories));

							_.forEach(body.document_tone.tone_categories, function(tone_category) {
								sentiments[tone_category.category_id] = {
									                                      category_name : tone_category.category_name,
									                                      tones: tone_category.tones
									                                    };
							});

                        	// save in Cloudant
                            pushRecordFn(sentiments);

                        }
                        else {
                        	// No tone analyzer results were returned
                        	// Don't store post in Cloudant
                        	logger.warn('No Tone Analyzer results were returned for ' + sentiments.title + '.');
                        }

   						return callback();

                    }); // post
				}, concurrency ); // async

				_.forEach( body, function( listing ){
					if ( listing.kind == 'Listing' && listing.hasOwnProperty('data' ) ){
						if ( listing.data.hasOwnProperty('children') ){
							//Get the children from the data fields, only process the top posts for now
							_.forEach( listing.data.children, function( post ){
								if ( post.hasOwnProperty('data') ){
									// add post to queue only if it contains text
									if((post.data.hasOwnProperty('selftext')) || (post.data.hasOwnProperty('body'))) {
										q.push( post.data );
									}
								}
							});
						}
					}
				});

				// Drain function is invoked after all posts have been processed
				q.drain = function(){
					// pipe processing complete
					return done();
				}

				// if the queue is empty asynchronous processing has already completed (or there was nothing to process)
				if(q.idle()) {
					return done();
				}

			}
		);
	};
}

//Extend event Emitter
require('util').inherits(redditConnector, connectorExt);

module.exports = new redditConnector();
<|endoftext|>


<commit_before>var gulp = require('gulp'),
    minifycss = require('gulp-minify-css'),
    jshint = require('gulp-jshint'),
    stylish = require('jshint-stylish'),
    uglify = require('gulp-uglify'),
    usemin = require('gulp-usemin'),
    imagemin = require('gulp-imagemin'),
    rename = require('gulp-rename'),
    concat = require('gulp-concat'),
    notify = require('gulp-notify'),
    cache = require('gulp-cache'),
    changed = require('gulp-changed'),
    rev = require('gulp-rev'),
    browserSync = require('browser-sync'),
    del = require('del');

gulp.task('jshint', function() {
  return gulp.src('app/scripts/**/*.js')
  .pipe(jshint())
  .pipe(jshint.reporter(stylish));
});

// Clean
gulp.task('clean', function() {
    return del(['dist']);
});

// Default task
gulp.task('default', ['clean'], function() {
    gulp.start('usemin', 'imagemin','copyfonts');
});
<commit_msg>add new rules<commit_after>var gulp = require('gulp'),
    minifycss = require('gulp-minify-css'),
    jshint = require('gulp-jshint'),
    stylish = require('jshint-stylish'),
    uglify = require('gulp-uglify'),
    usemin = require('gulp-usemin'),
    imagemin = require('gulp-imagemin'),
    rename = require('gulp-rename'),
    concat = require('gulp-concat'),
    notify = require('gulp-notify'),
    cache = require('gulp-cache'),
    changed = require('gulp-changed'),
    rev = require('gulp-rev'),
    browserSync = require('browser-sync'),
    del = require('del');

gulp.task('jshint', function() {
  return gulp.src('app/scripts/**/*.js')
  .pipe(jshint())
  .pipe(jshint.reporter(stylish));
});

// Clean
gulp.task('clean', function() {
    return del(['dist']);
});

// Default task
gulp.task('default', ['clean'], function() {
    gulp.start('usemin', 'imagemin','copyfonts');
});

gulp.task('usemin',['jshint'], function () {
  return gulp.src('./app/menu.html')
      .pipe(usemin({
        css:[minifycss(),rev()],
        js: [uglify(),rev()]
      }))
      .pipe(gulp.dest('dist/'));
});

// Images
gulp.task('imagemin', function() {
  return del(['dist/images']), gulp.src('app/images/**/*')
    .pipe(cache(imagemin({ optimizationLevel: 3, progressive: true, interlaced: true })))
    .pipe(gulp.dest('dist/images'))
    .pipe(notify({ message: 'Images task complete' }));
});

gulp.task('copyfonts', ['clean'], function() {
   gulp.src('./bower_components/font-awesome/fonts/**/*.{ttf,woff,eof,svg}*')
   .pipe(gulp.dest('./dist/fonts'));
   gulp.src('./bower_components/bootstrap/dist/fonts/**/*.{ttf,woff,eof,svg}*')
   .pipe(gulp.dest('./dist/fonts'));
});
<|endoftext|>