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

var checkAuthorization = function (req, res, next) {
    if (!req.user) {
        return res.send(401,{ error: 'The user can not do this action witout login.' });
    }
    next();
};

function setup(app) {
	//Routes
	var politicians = require('./lib/routes/politicians.js'),
		proposals = require('./lib/routes/proposals.js'),
		//political_parties = require('./lib/routes/political_parties'),
		userModel = require('./lib/model/userModel'),
		users = require('./lib/routes/users'),
		//comments = require('./lib/routes/comments'),
		rating = require('./lib/routes/ratings'),
		goods = require('./lib/routes/goods'),
		curriculum = require('./lib/routes/curriculum'),
		importation = require('./lib/aux/import');

	//Local login routes
	app.post('/v1/user/register', userModel.validadeUser, users.register);
	app.post('/v1/user/login', users.login);
	app.get('/v1/user/logout', users.logout);
	app.get('/v1/user/validadeMail/:username/:comfirmationPass', users.validadeMail);

	app.get('/v1/profile', users.findById);
	app.get('/v1/profile/ratings', users.findRatingsById);

	//Login Twitter:
	//app.get('/v1/connect/twitter', users.loginTwitter);
	//app.get('/v1/connect/twitter/callback', users.loginTwitterCallback);

	app.get('/v1/auth/facebook', passport.authenticate('facebook', { scope: ['public_profile', 'email', 'user_birthday'] }));
	app.get('/v1/auth/facebook/callback', passport.authenticate('facebook', { successRedirect: '/v1/auth/success', failureRedirect: '/v1/auth/failure' }));
	app.get('/v1/auth/success', function(req, res) {
	    res.send("<script>window.close()</script>");
	});
	app.get('/v1/auth/failure', function(req, res) {
	    res.send("<script>window.close()</script>");
	});

	//Login Google:
	//app.get('/v1/auth/google', users.loginGoogle);
	//app.get('/v1/auth/google/return', users.loginGoogleCallback);

	//Login Linkedin:
	//app.get('/v1/auth/linkedin', users.loginLinkedin);
	//app.get('/v1/auth/linkedin/callback', users.loginLinkedinCalback);

	//Politicians routes
	app.get('/v1/politicians', politicians.findAll);
	app.get('/v1/politician/:id', politicians.findById);
	app.get('/v1/politician/:id/proposals', politicians.findProposalsById);
	app.get('/v1/politician/:id/goods', politicians.findGoodsById);
	app.get('/v1/politician/:id/curriculum', politicians.findCurriculumById);
	//app.post('/v1/politician', checkAuthorization, politicians.add);
	//app.put('/v1/politician/:id', checkAuthorization, politicians.update);
	//app.delete('/v1/politician/:id', checkAuthorization, politicians.delete);

	//Proposals routes
	app.get('/v1/proposals', proposals.findAll);
	app.get('/v1/proposal/:id', proposals.findById);
	app.post('/v1/proposal', checkAuthorization, proposals.add);
	//app.put('/v1/proposal/:id', checkAuthorization, proposals.update);
	app.delete('/v1/proposal/:id', checkAuthorization, proposals.delete);

	//Goods routes
	app.get('/v1/goods', goods.findAll);
	app.get('/v1/good/:id', goods.findById);
	//app.post('/v1/good', checkAuthorization, goods.add);
	//app.put('/v1/good/:id', checkAuthorization, goods.update);
	//app.delete('/v1/good/:id', checkAuthorization, goods.delete);

	//Curriculum routes
	app.get('/v1/curriculums', curriculum.findAll);
	app.get('/v1/curriculum/:id', curriculum.findById);
	//app.post('/v1/curriculum', checkAuthorization, curriculum.add);
	//app.put('/v1/curriculum/:id', checkAuthorization, curriculum.update);
	//app.delete('/v1/curriculum/:id', checkAuthorization, curriculum.delete);

	//Political Parties routes
	//app.get('/v1/political_parties', political_parties.findAll);
	//app.get('/v1/political_parties/:sigla', political_parties.findById);
	//app.post('/v1/political_parties', checkAuthorization, political_parties.add);
	//app.put('/v1/political_parties/:sigla', checkAuthorization, political_parties.update);
	//app.delete('/v1/political_parties/:sigla', checkAuthorization, political_parties.delete);

	/*//Comments routes
	app.get('/v1/comments', comments.findAll);
	app.get('/v1/comments/:id', comments.findById);
	app.post('/v1/comment', checkAuthorization, comments.add);
	app.delete('/v1/comment/:id', checkAuthorization, comments.delete);*/

	app.get('/v1/rating/:id', rating.findById);
	app.post('/v1/rating/:id', checkAuthorization, rating.update);
	app.get('/v1/graphRating/:id', rating.generatesGraphById);

	//app.post('/v1/importProposal', importation.importProposal);
	//app.post('/v1/deleteProposal', importation.deleteProposal);
	//app.post('/v1/importCurriculum', importation.importCurriculum);
	//app.post('/v1/deleteCurriculum', importation.deleteCurriculum);
};

exports.setup = setup;<commit_msg>Comentando propostas<commit_after>var passport = require('passport');

var checkAuthorization = function (req, res, next) {
    if (!req.user) {
        return res.send(401,{ error: 'The user can not do this action witout login.' });
    }
    next();
};

function setup(app) {
	//Routes
	var politicians = require('./lib/routes/politicians.js'),
		proposals = require('./lib/routes/proposals.js'),
		//political_parties = require('./lib/routes/political_parties'),
		userModel = require('./lib/model/userModel'),
		users = require('./lib/routes/users'),
		//comments = require('./lib/routes/comments'),
		rating = require('./lib/routes/ratings'),
		goods = require('./lib/routes/goods'),
		curriculum = require('./lib/routes/curriculum'),
		importation = require('./lib/aux/import');

	//Local login routes
	app.post('/v1/user/register', userModel.validadeUser, users.register);
	app.post('/v1/user/login', users.login);
	app.get('/v1/user/logout', users.logout);
	app.get('/v1/user/validadeMail/:username/:comfirmationPass', users.validadeMail);

	app.get('/v1/profile', users.findById);
	app.get('/v1/profile/ratings', users.findRatingsById);

	//Login Twitter:
	//app.get('/v1/connect/twitter', users.loginTwitter);
	//app.get('/v1/connect/twitter/callback', users.loginTwitterCallback);

	app.get('/v1/auth/facebook', passport.authenticate('facebook', { scope: ['public_profile', 'email', 'user_birthday'] }));
	app.get('/v1/auth/facebook/callback', passport.authenticate('facebook', { successRedirect: '/v1/auth/success', failureRedirect: '/v1/auth/failure' }));
	app.get('/v1/auth/success', function(req, res) {
	    res.send("<script>window.close()</script>");
	});
	app.get('/v1/auth/failure', function(req, res) {
	    res.send("<script>window.close()</script>");
	});

	//Login Google:
	//app.get('/v1/auth/google', users.loginGoogle);
	//app.get('/v1/auth/google/return', users.loginGoogleCallback);

	//Login Linkedin:
	//app.get('/v1/auth/linkedin', users.loginLinkedin);
	//app.get('/v1/auth/linkedin/callback', users.loginLinkedinCalback);

	//Politicians routes
	app.get('/v1/politicians', politicians.findAll);
	app.get('/v1/politician/:id', politicians.findById);
	app.get('/v1/politician/:id/proposals', politicians.findProposalsById);
	app.get('/v1/politician/:id/goods', politicians.findGoodsById);
	app.get('/v1/politician/:id/curriculum', politicians.findCurriculumById);
	//app.post('/v1/politician', checkAuthorization, politicians.add);
	//app.put('/v1/politician/:id', checkAuthorization, politicians.update);
	//app.delete('/v1/politician/:id', checkAuthorization, politicians.delete);

	//Proposals routes
	app.get('/v1/proposals', proposals.findAll);
	app.get('/v1/proposal/:id', proposals.findById);
	//app.post('/v1/proposal', checkAuthorization, proposals.add);
	//app.put('/v1/proposal/:id', checkAuthorization, proposals.update);
	//app.delete('/v1/proposal/:id', checkAuthorization, proposals.delete);

	//Goods routes
	app.get('/v1/goods', goods.findAll);
	app.get('/v1/good/:id', goods.findById);
	//app.post('/v1/good', checkAuthorization, goods.add);
	//app.put('/v1/good/:id', checkAuthorization, goods.update);
	//app.delete('/v1/good/:id', checkAuthorization, goods.delete);

	//Curriculum routes
	app.get('/v1/curriculums', curriculum.findAll);
	app.get('/v1/curriculum/:id', curriculum.findById);
	//app.post('/v1/curriculum', checkAuthorization, curriculum.add);
	//app.put('/v1/curriculum/:id', checkAuthorization, curriculum.update);
	//app.delete('/v1/curriculum/:id', checkAuthorization, curriculum.delete);

	//Political Parties routes
	//app.get('/v1/political_parties', political_parties.findAll);
	//app.get('/v1/political_parties/:sigla', political_parties.findById);
	//app.post('/v1/political_parties', checkAuthorization, political_parties.add);
	//app.put('/v1/political_parties/:sigla', checkAuthorization, political_parties.update);
	//app.delete('/v1/political_parties/:sigla', checkAuthorization, political_parties.delete);

	/*//Comments routes
	app.get('/v1/comments', comments.findAll);
	app.get('/v1/comments/:id', comments.findById);
	app.post('/v1/comment', checkAuthorization, comments.add);
	app.delete('/v1/comment/:id', checkAuthorization, comments.delete);*/

	app.get('/v1/rating/:id', rating.findById);
	app.post('/v1/rating/:id', checkAuthorization, rating.update);
	app.get('/v1/graphRating/:id', rating.generatesGraphById);

	//app.post('/v1/importProposal', importation.importProposal);
	//app.post('/v1/deleteProposal', importation.deleteProposal);
	//app.post('/v1/importCurriculum', importation.importCurriculum);
	//app.post('/v1/deleteCurriculum', importation.deleteCurriculum);

	//Services for Blind Test app
	//app.get('/v1/blindTest/proposals/sort/:qtd', proposals.findRandom);
	//app.get('/v1/blindTest/proposals/themes', proposals.findThemes);
	//app.get('/v1/blindTest/user/ratings', checkAuthorization, users.findRatingsById);
	//app.post('/v1/blindTest/rating/:id', checkAuthorization, rating.update);
};

exports.setup = setup;<|endoftext|>


<commit_before>// Copyright 2016 Martin Reinhardt

// This simply downloads Galen

'use strict';

var cp = require('child_process');
var fs = require('fs-extra');
var helper = require('galenframework/lib/helper');
var kew = require('kew');
var npmconf = require('npmconf');
var path = require('path');
var httpreq = require('httpreq');
var which = require('which');
var npmWhich = require('npm-which')(process.cwd());
var log = require('npmlog');

var originalPath = process.env.PATH;

// If the process exits without going through exit(), then we did not complete.
var validExit = false;

process.on('exit', function() {
    if (!validExit) {
        log.info('Install exited unexpectedly');
        exit(1);
    }
});

// NPM adds bin directories to the path, which will cause `which` to find the
// bin for this package not the actual galenframework-cli bin.  Also help out people who
// put ./bin on their path
process.env.PATH = helper.cleanPath(originalPath);

var tmpPath = null;

// If the user manually installed galen, we want
// to use the existing version.
//
// Do not re-use a manually-installed galen with
// a different version.
//
// Do not re-use an npm-installed galen, because
// that can lead to weird circular dependencies between
// local versions and global versions.
var whichDeferred = kew.defer();
which('galen', whichDeferred.makeNodeResolver());
whichDeferred.promise
    .then((result) => installAdditionalDrivers(result))
    .fail(() => npmWhich('galen', (err, result) => {
        if (err) {
            log.error('Galen installation failed', err, err.stack);
            exit(1);
        } else {
            return installAdditionalDrivers(result);
        }
    }));

function installAdditionalDrivers(galenPath) {
    var defer = kew.defer();
    defer.resolve();
    defer.promise.then(function() {
            // Horrible hack to avoid problems during global install. We check to see if
            // the file `which` found is our own bin script.
            if (galenPath.indexOf(path.join('npm', 'galenframework-cli')) !== -1) {
                log.info('Looks like an `npm install -g` on windows; unable to check for already installed version.');
                throw new Error('Global install');
            }

            var contents = fs.readFileSync(galenPath, 'utf8');
            if ((/NPM_INSTALL_MARKER/).test(contents)) {

                log.info('Looks like an `npm install -g`; unable to check for already installed version.');
                throw new Error('Global install');
            } else {
                var checkVersionDeferred = kew.defer();
                cp.execFile(galenPath, ['--version'], checkVersionDeferred.makeNodeResolver());

return checkVersionDeferred.promise;
            }
        })
        .then(function() {
            log.info('galenframework-cli detected');
            var npmconfDeferred = kew.defer();
            npmconf.load(npmconfDeferred.makeNodeResolver());

return npmconfDeferred.promise;
        })
        .then(function(conf) {
            tmpPath = findSuitableTempDirectory(conf);
            var platform = process.platform;
            // offer safari driver installation
            if (platform === 'darwin') {
                var npmconfDeferred = kew.defer();
                npmconf.load(npmconfDeferred.makeNodeResolver());
                npmconfDeferred.promise.then(function() {
                    var downloadUrl = process.env.SAFARIDRIVER_CDNURL ||
                        'https://selenium-release.storage.googleapis.com/2.48/SafariDriver.safariextz';
                    var fileName = downloadUrl.split('/').pop();
                    var downloadedFile = path.join(tmpPath, fileName);
                    if (!fs.existsSync(downloadedFile)) {
                        log.info('Downloading', downloadUrl);

return requestBinary(downloadUrl, downloadedFile);
                    }
                        log.info('Download already available at', downloadedFile);

return downloadedFile;

                }).then(function(downloadedFile) {
                    // request to open safari extension installation
                    var spawn = require('child_process').spawn;
                    log.info('Opening file ', downloadedFile);
                    spawn('open', [downloadedFile], {
                        'detached': true
                    });
                    exit(0);
                })
.fail(function(err) {
                    log.error('Safari Driver installation failed', err, err.stack);
                    exit(1);
                });
            } else {
                exit(0);
            }
        })
}

function exit(code) {
    validExit = true;
    process.env.PATH = originalPath;
    process.exit(code || 0);
}

function findSuitableTempDirectory(npmConf) {
    var now = Date.now();
    var candidateTmpDirs = [
        process.env.TMPDIR || process.env.TEMP || npmConf.get('tmp'),
        '/tmp',
        path.join(process.cwd(), 'tmp')
    ];

    for (var i = 0; i < candidateTmpDirs.length; i++) {
        var candidatePath = path.join(candidateTmpDirs[i], 'galenframework-cli');

        try {
            fs.mkdirsSync(candidatePath, '0777');
            // Make double sure we have 0777 permissions; some operating systems
            // default umask does not allow write by default.
            fs.chmodSync(candidatePath, '0777');
            var testFile = path.join(candidatePath, now + '.tmp');
            fs.writeFileSync(testFile, 'test');
            fs.unlinkSync(testFile);

return candidatePath;
        } catch (e) {
            log.info(candidatePath, 'is not writable:', e.message);
        }
    }

    log.error('Can not find a writable tmp directory.');
    exit(1);
}

function requestBinary(url, dest) {
    var deferred = kew.defer();
    log.info('Receiving...');

    httpreq.get(url, {'binary': true}, function(err, res) {
        if (err) {
            deferred.reject(err);
            log.error('Error making request.');
        } else {
            fs.writeFile(dest, res.body, function(err) {
                if (err) {
                    deferred.reject(err);
                    log.info('Error writing file');
                } else {
                    log.info('Saved to', dest);
                    deferred.resolve(dest);
                }
            });
        }
    });

return deferred.promise;
}

if (process.platform === 'darwin') {
    console.info('\n\nTo \x1b[4menable CLI tab autocompletion\x1b[0m run: \n' +
        ' \x1b[7mgalen completion >> ~/.profile\x1b[0m ' +
        '\n\n');
}
if (process.platform === 'linux') {
    console.info('\n\nTo \x1b[4menable CLI tab autocompletion\x1b[0m run: \n' +
        ' \x1b[7mgalen completion >> ~/.bashrc\x1b[0m \n' +
        'or\n' +
        ' \x1b[7mgalen completion >> .~/.zshrc\x1b[0m ' +
        '\n\n');
}<commit_msg>feat(Safari): Drop Safari extentsion installation<commit_after>// Copyright 2016 Martin Reinhardt

// This simply downloads Galen

'use strict';

var cp = require('child_process');
var fs = require('fs-extra');
var helper = require('galenframework/lib/helper');
var kew = require('kew');
var npmconf = require('npmconf');
var path = require('path');
var httpreq = require('httpreq');
var which = require('which');
var npmWhich = require('npm-which')(process.cwd());
var log = require('npmlog');

var originalPath = process.env.PATH;

// If the process exits without going through exit(), then we did not complete.
var validExit = false;

process.on('exit', function() {
    if (!validExit) {
        log.info('Install exited unexpectedly');
        exit(1);
    }
});

// NPM adds bin directories to the path, which will cause `which` to find the
// bin for this package not the actual galenframework-cli bin.  Also help out people who
// put ./bin on their path
process.env.PATH = helper.cleanPath(originalPath);

var tmpPath = null;

// If the user manually installed galen, we want
// to use the existing version.
//
// Do not re-use a manually-installed galen with
// a different version.
//
// Do not re-use an npm-installed galen, because
// that can lead to weird circular dependencies between
// local versions and global versions.
var whichDeferred = kew.defer();
which('galen', whichDeferred.makeNodeResolver());
whichDeferred.promise
    .then((result) => installAdditionalDrivers(result))
    .fail(() => npmWhich('galen', (err, result) => {
        if (err) {
            log.error('Galen installation failed', err, err.stack);
            exit(1);
        } else {
            return installAdditionalDrivers(result);
        }
    }));

function installAdditionalDrivers(galenPath) {
    var defer = kew.defer();
    defer.resolve();
    defer.promise.then(function() {
            // Horrible hack to avoid problems during global install. We check to see if
            // the file `which` found is our own bin script.
            if (galenPath.indexOf(path.join('npm', 'galenframework-cli')) !== -1) {
                log.info('Looks like an `npm install -g` on windows; unable to check for already installed version.');
                throw new Error('Global install');
            }

            var contents = fs.readFileSync(galenPath, 'utf8');
            if ((/NPM_INSTALL_MARKER/).test(contents)) {

                log.info('Looks like an `npm install -g`; unable to check for already installed version.');
                throw new Error('Global install');
            } else {
                var checkVersionDeferred = kew.defer();
                cp.execFile(galenPath, ['--version'], checkVersionDeferred.makeNodeResolver());

return checkVersionDeferred.promise;
            }
        })
        .then(function() {
            log.info('galenframework-cli detected');
            var npmconfDeferred = kew.defer();
            npmconf.load(npmconfDeferred.makeNodeResolver());

return npmconfDeferred.promise;
        })
        .then(function() {
          exit(0);
        })
}

function exit(code) {
    validExit = true;
    process.env.PATH = originalPath;
    process.exit(code || 0);
}

function findSuitableTempDirectory(npmConf) {
    var now = Date.now();
    var candidateTmpDirs = [
        process.env.TMPDIR || process.env.TEMP || npmConf.get('tmp'),
        '/tmp',
        path.join(process.cwd(), 'tmp')
    ];

    for (var i = 0; i < candidateTmpDirs.length; i++) {
        var candidatePath = path.join(candidateTmpDirs[i], 'galenframework-cli');

        try {
            fs.mkdirsSync(candidatePath, '0777');
            // Make double sure we have 0777 permissions; some operating systems
            // default umask does not allow write by default.
            fs.chmodSync(candidatePath, '0777');
            var testFile = path.join(candidatePath, now + '.tmp');
            fs.writeFileSync(testFile, 'test');
            fs.unlinkSync(testFile);

return candidatePath;
        } catch (e) {
            log.info(candidatePath, 'is not writable:', e.message);
        }
    }

    log.error('Can not find a writable tmp directory.');
    exit(1);
}

function requestBinary(url, dest) {
    var deferred = kew.defer();
    log.info('Receiving...');

    httpreq.get(url, {'binary': true}, function(err, res) {
        if (err) {
            deferred.reject(err);
            log.error('Error making request.');
        } else {
            fs.writeFile(dest, res.body, function(err) {
                if (err) {
                    deferred.reject(err);
                    log.info('Error writing file');
                } else {
                    log.info('Saved to', dest);
                    deferred.resolve(dest);
                }
            });
        }
    });

return deferred.promise;
}

if (process.platform === 'darwin') {
    console.info('\n\nTo \x1b[4menable CLI tab autocompletion\x1b[0m run: \n' +
        ' \x1b[7mgalen completion >> ~/.profile\x1b[0m ' +
        '\n\n');
}
if (process.platform === 'linux') {
    console.info('\n\nTo \x1b[4menable CLI tab autocompletion\x1b[0m run: \n' +
        ' \x1b[7mgalen completion >> ~/.bashrc\x1b[0m \n' +
        'or\n' +
        ' \x1b[7mgalen completion >> .~/.zshrc\x1b[0m ' +
        '\n\n');
}
<|endoftext|>


<commit_before>var expect = require('chai').expect,
    sdk = require('../../lib/index.js'),
    Certificate = sdk.Certificate;

describe('Certificate', function () {
    describe('constructor', function () {
        it('should allow creating an empty Certificate', function () {
            var certificate = new Certificate();
            expect(certificate).to.not.eql(undefined);
            expect(certificate._postman_propertyName).to.not.eql('Certificate');
        });

        it('should correctly identify Certificate instances', function () {
            var certificate = new Certificate();

            expect(Certificate.isCertificate(certificate)).to.be.true;
            expect(Certificate.isCertificate({})).to.be.false;
            expect(Certificate.isCertificate({ _postman_propertyName: 'certificate' })).to.be.false;
        });
    });

    describe('canApplyTo', function () {
        it('should return false for empty target URLs', function () {
            var certificate = new Certificate({ matches: ['https://google.com/*'] });
            expect(certificate.canApplyTo('')).to.be.false;
            expect(certificate.canApplyTo(new sdk.Url())).to.be.false;
        });

        it('should return true only when tested with a match', function () {
            var certificate = new Certificate({ matches: ['https://google.com/*'] });
            expect(certificate.canApplyTo('https://www.google.com')).to.be.false;
            expect(certificate.canApplyTo('https://example.com')).to.be.false;
            expect(certificate.canApplyTo('https://google.com')).to.be.true;
        });

        it('should return true when tested with a match on any of the allowed matches', function () {
            var certificate = new Certificate({ matches: ['https://google.com/*', 'https://*.example.com/*'] });
            expect(certificate.canApplyTo('https://twitter.com')).to.be.false;
            expect(certificate.canApplyTo('https://foo.example.com')).to.be.true;
            expect(certificate.canApplyTo('https://google.com')).to.be.true;
        });

        it('should disallow test string with protocol not http or https', function () {
            var certificate = new Certificate({ matches: ['http://*'], server: 'https://proxy.com/' });
            expect(certificate.canApplyTo('foo://www.google.com')).to.be.false;
            expect(certificate.canApplyTo('file://www.google.com')).to.be.false;
        });

        it('should disallow any test string when match protocol is not http or https', function () {
            var certificate = new Certificate({ matches: ['ftp://*'], server: 'https://proxy.com/' });
            expect(certificate.canApplyTo('foo://www.google.com')).to.be.false;
            expect(certificate.canApplyTo('file://www.google.com')).to.be.false;
            expect(certificate.canApplyTo('http://www.google.com')).to.be.false;
            expect(certificate.canApplyTo('https://www.google.com')).to.be.false;
        });
    });

    describe('toJSON', function () {
        it('should contain host property', function () {
            var rawCert = {
                    matches: ['https://postman-echo.com/*', 'https://bla.com/*'],
                    key: { src: '/Users/here' },
                    cert: { src: '/Users/here' },
                    passphrase: 'iamhere'
                },
                certificate = new Certificate(rawCert),
                serialisedCertificate = certificate.toJSON();
            expect(serialisedCertificate).to.deep.include({
                key: rawCert.cert,
                cert: rawCert.cert,
                passphrase: rawCert.passphrase
            });
        });

        it('should not contain key value', function () {
            var rawCert = {
                    matches: ['https://postman-echo.com/*', 'https://bla.com/*'],
                    key: { src: '/Users/here' },
                    cert: { src: '/Users/here' },
                    passphrase: 'iamhere'
                },
                certificate = new Certificate(rawCert),
                serialisedCertificate;

            certificate.key.value = 'something';
            certificate.cert.value = 'something-else';
            serialisedCertificate = certificate.toJSON();

            expect(serialisedCertificate.key).to.not.have.property('value');
            expect(serialisedCertificate.cert).to.not.have.property('value');
        });
    });
});
<commit_msg>Update changes in certificate test<commit_after>var expect = require('chai').expect,
    sdk = require('../../lib/index.js'),
    Certificate = sdk.Certificate;

describe('Certificate', function () {
    describe('constructor', function () {
        it('should allow creating an empty Certificate', function () {
            var certificate = new Certificate();
            expect(certificate).to.not.eql(undefined);
            expect(certificate._postman_propertyName).to.not.eql('Certificate');
        });

        it('should correctly identify Certificate instances', function () {
            var certificate = new Certificate();

            expect(Certificate.isCertificate(certificate)).to.be.true;
            expect(Certificate.isCertificate({})).to.be.false;
            expect(Certificate.isCertificate({ _postman_propertyName: 'certificate' })).to.be.false;
        });
    });

    describe('canApplyTo', function () {
        it('should return false for empty target URLs', function () {
            var certificate = new Certificate({ matches: ['https://google.com/*'] });
            expect(certificate.canApplyTo('')).to.be.false;
            expect(certificate.canApplyTo(new sdk.Url())).to.be.false;
        });

        it('should return true only when tested with a match', function () {
            var certificate = new Certificate({ matches: ['https://google.com/*'] });
            expect(certificate.canApplyTo('https://www.google.com')).to.be.false;
            expect(certificate.canApplyTo('https://example.com')).to.be.false;
            expect(certificate.canApplyTo('https://google.com')).to.be.true;
        });

        it('should return true when tested with a match on any of the allowed matches', function () {
            var certificate = new Certificate({ matches: ['https://google.com/*', 'https://*.example.com/*'] });
            expect(certificate.canApplyTo('https://twitter.com')).to.be.false;
            expect(certificate.canApplyTo('https://foo.example.com')).to.be.true;
            expect(certificate.canApplyTo('https://google.com')).to.be.true;
        });

        it('should disallow test string with protocol not http or https', function () {
            var certificate = new Certificate({ matches: ['http://*'], server: 'https://proxy.com/' });
            expect(certificate.canApplyTo('foo://www.google.com')).to.be.false;
            expect(certificate.canApplyTo('file://www.google.com')).to.be.false;
        });

        it('should disallow any test string when match protocol is not http or https', function () {
            var certificate = new Certificate({ matches: ['ftp://*'], server: 'https://proxy.com/' });
            expect(certificate.canApplyTo('foo://www.google.com')).to.be.false;
            expect(certificate.canApplyTo('file://www.google.com')).to.be.false;
            expect(certificate.canApplyTo('http://www.google.com')).to.be.false;
            expect(certificate.canApplyTo('https://www.google.com')).to.be.false;
        });
    });

    describe('toJSON', function () {
        it('should contain host property', function () {
            var rawCert = {
                    matches: ['https://postman-echo.com/*', 'https://bla.com/*'],
                    key: { src: '/Users/here' },
                    cert: { src: '/Users/here' },
                    passphrase: 'iamhere'
                },
                certificate = new Certificate(rawCert),
                serialisedCertificate = certificate.toJSON();

            expect(serialisedCertificate).to.deep.include({
                key: rawCert.cert,
                cert: rawCert.cert,
                passphrase: rawCert.passphrase
            });
        });

        it('should not contain key value', function () {
            var rawCert = {
                    matches: ['https://postman-echo.com/*', 'https://bla.com/*'],
                    key: { src: '/Users/here' },
                    cert: { src: '/Users/here' },
                    passphrase: 'iamhere'
                },
                certificate = new Certificate(rawCert),
                serialisedCertificate;

            certificate.key.value = 'something';
            certificate.cert.value = 'something-else';
            serialisedCertificate = certificate.toJSON();

            expect(serialisedCertificate.key).to.not.have.property('value');
            expect(serialisedCertificate.cert).to.not.have.property('value');
        });
    });
});
<|endoftext|>


<commit_before>/**
 *
 */
'use strict';

import {Component, PropTypes} from 'react';
import pureRender from 'pure-render-decorator';
import uid from 'uid';
import classNames from 'classnames';
import percentage from '../utils/percentage';

/**
 *
 */
function makeText(props) {
	return props.percentage + '%';
}

/**
 *
 */
@pureRender
export default class ProgressBar extends Component {

	/**
	 *
	 */
	static propTypes = {
		id: PropTypes.string,
		orientation: PropTypes.string,
		min: PropTypes.number,
		max: PropTypes.number,
		value: PropTypes.number,
		text: PropTypes.func
	}

	/**
	 *
	 */
	static defaultProps = {
		id: 'rea11y-' + uid(),
		orientation: 'horizontal',
		min: 0,
		max: 100,
		value: 0,
		text: makeText
	}

	/**
	 *
	 */
	constructor(props) {
		super(props);

		this.state = {
			percentage: percentage(props.value, props.max)
		};

		this.setupTarget();
		this.updateTarget();
	}

	/**
	 *
	 */
	componentWillReceiveProps(props) {
		this.setState({
			percentage: percentage(props.value, props.max)
		});
	}

	/**
	 *
	 */
	componentDidUpdate() {
		this.updateTarget();
	}

	/**
	 *
	 */
	setupTarget() {
		if (this.props.target) {
			this.props.target.setAttribute(
				'aria-describedby',
				this.props.id
			);
		}
	}

	/**
	 *
	 */
	updateTarget() {
		if (this.props.target) {
			const {value, min, max} = this.props;
			const busy = (value > min) && (value < max);

			this.props.target.setAttribute('aria-busy', busy);
		}
	}

	/**
	 *
	 */
	render() {
		const text = this.text();
		const style = this.style();

		const className = classNames([
			'rea11y-progress-bar',
			'rea11y-progress-bar-' + this.props.orientation
		]);

		return (

					{text}

		);
	}

	/**
	 *
	 */
	text() {
		return this.props.text({
			min: this.props.min,
			max: this.props.max,
			value: this.props.value,
			percentage: this.state.percentage
		});
	}

	/**
	 *
	 */
	style() {
		const property = (this.props.orientation === 'horizontal')
			? 'width'
			: 'height';

		return {
			[property]: this.state.percentage + '%'
		};
	}
}
<commit_msg>Coding style<commit_after>/**
 *
 */
'use strict';

import {Component, PropTypes} from 'react';
import pureRender from 'pure-render-decorator';
import uid from 'uid';
import classNames from 'classnames';
import percentage from '../utils/percentage';

/**
 *
 */
function makeText(props) {
	return props.percentage + '%';
}

/**
 *
 */
@pureRender
export default class ProgressBar extends Component {

	/**
	 *
	 */
	static propTypes = {
		id: PropTypes.string,
		orientation: PropTypes.string,
		min: PropTypes.number,
		max: PropTypes.number,
		value: PropTypes.number,
		text: PropTypes.func
	}

	/**
	 *
	 */
	static defaultProps = {
		id: 'rea11y-' + uid(),
		orientation: 'horizontal',
		min: 0,
		max: 100,
		value: 0,
		text: makeText
	}

	/**
	 *
	 */
	constructor(props) {
		super(props);

		this.state = {
			percentage: percentage(props.value, props.max)
		};

		this.setupTarget();
		this.updateTarget();
	}

	/**
	 *
	 */
	componentWillReceiveProps(props) {
		this.setState({
			percentage: percentage(props.value, props.max)
		});
	}

	/**
	 *
	 */
	componentDidUpdate() {
		this.updateTarget();
	}

	/**
	 *
	 */
	setupTarget() {
		if (this.props.target) {
			this.props.target.setAttribute(
				'aria-describedby',
				this.props.id
			);
		}
	}

	/**
	 *
	 */
	updateTarget() {
		if (this.props.target) {
			const {value, min, max} = this.props;
			const busy = (value > min) && (value < max);

			this.props.target.setAttribute('aria-busy', busy);
		}
	}

	/**
	 *
	 */
	render() {
		const text = this.text();
		const className = classNames([
			'rea11y-progress-bar',
			'rea11y-progress-bar-' + this.props.orientation
		]);

		return (

					{text}

		);
	}

	/**
	 *
	 */
	text() {
		return this.props.text({
			min: this.props.min,
			max: this.props.max,
			value: this.props.value,
			percentage: this.state.percentage
		});
	}

	/**
	 *
	 */
	style() {
		const property = (this.props.orientation === 'horizontal')
			? 'width'
			: 'height';

		return {
			[property]: this.state.percentage + '%'
		};
	}
}
<|endoftext|>


<commit_before>/**

  locals-editor.js

**/

//
//  Dependencies
//

var chalk = require("chalk"),
    utils = require("./cli-utils");

//
//  Exports
//

var Vars = module.exports = {
  addLocal: function(key, val) {
    Vars.add("locals", key, val);
  },

  listLocals: function() {
    Vars.list("locals", "Locals");
  },

  /**

    Outputs a list of local variables.

    @param key The key to lookup
    @param title The title to output

  **/

  list: function(key, title) {

    var editor = require("./config-editor"),
        vars   = editor.get(key) || {},
        str;

    console.log("");
    console.log(chalk.cyan(" " + title + ":"));
    console.log("");

    if (!Object.keys(vars).length)
      console.log("   There are no " + key + " variables in your project");
    else {
      str = JSON.stringify(vars, null, 2).split("\n").map(function(line) { return "   " + line; }).join("\n");
      console.log(str);
    }

    console.log("");

  },

  /**

    Adds a local variable and acknolwedges with confirmation.

    @param {String} parent Which variable to change (e.g. locals, env)
    @param {String} key The key to lookup (supports dot-notation)
    @param {*} val The value to assign

  **/

  add: function(parent, key, val) {

    var editor = require("./config-editor");

    console.log("");

    // Perform type casting
    if (val === "false")
      val = false;
    else if (val === "true")
      val = true;
    else if (/^\-?([0-9]+\.?[0-9]*|\.[0-9]*)$/.test(val))
      val = parseFloat(val);

    editor.set(parent + "." + key, val);
    editor.save();

    console.log("   " + chalk.cyan("Added:") + " " + parent + " variable " + chalk.yellow(key) + " now contains " + chalk.yellow(val));
    console.log("");

  },

  /**

    Removes a local variable and acknowledges with confirmation.

    @param {String} key The key to remove (supports dot-notation)

  **/

  remove: function(key) {

    var editor = require("./config-editor"),
        prev = editor.get("locals." + key);

    console.log("");

    editor.unset("locals." + key);
    editor.save();

    if ("undefined" === typeof prev)
      console.log("   " + chalk.red("No Change:") + " there was no local variable called " + chalk.yellow(key));
    else if ("object" === typeof prev)
      console.log("   " + chalk.cyan("Removed:") + " local variable " + chalk.yellow(key) + " has been unset");
    else
      console.log("   " + chalk.cyan("Removed:") + " local variable " + chalk.yellow(key) + " has been unset from " + chalk.yellow(prev));
    console.log("");

  }

};
<commit_msg>vars-editor: abstracts #remove and creates #removeLocal<commit_after>/**

  locals-editor.js

**/

//
//  Dependencies
//

var chalk = require("chalk"),
    utils = require("./cli-utils");

//
//  Exports
//

var Vars = module.exports = {
  addLocal: function(key, val) {
    Vars.add("locals", key, val);
  },

  listLocals: function() {
    Vars.list("locals", "Locals");
  },

  removeLocal: function(key, val) {
    Vars.remove("locals", key);
  },

  /**

    Outputs a list of local variables.

    @param key The key to lookup
    @param title The title to output

  **/

  list: function(key, title) {

    var editor = require("./config-editor"),
        vars   = editor.get(key) || {},
        str;

    console.log("");
    console.log(chalk.cyan(" " + title + ":"));
    console.log("");

    if (!Object.keys(vars).length)
      console.log("   There are no " + key + " variables in your project");
    else {
      str = JSON.stringify(vars, null, 2).split("\n").map(function(line) { return "   " + line; }).join("\n");
      console.log(str);
    }

    console.log("");

  },

  /**

    Adds a local variable and acknolwedges with confirmation.

    @param {String} parent Which variable to change (e.g. locals, env)
    @param {String} key The key to lookup (supports dot-notation)
    @param {*} val The value to assign

  **/

  add: function(parent, key, val) {

    var editor = require("./config-editor");

    console.log("");

    // Perform type casting
    if (val === "false")
      val = false;
    else if (val === "true")
      val = true;
    else if (/^\-?([0-9]+\.?[0-9]*|\.[0-9]*)$/.test(val))
      val = parseFloat(val);

    editor.set(parent + "." + key, val);
    editor.save();

    console.log("   " + chalk.cyan("Added:") + " " + parent + " variable " + chalk.yellow(key) + " now contains " + chalk.yellow(val));
    console.log("");

  },

  /**

    Removes a local variable and acknowledges with confirmation.

    @param {String} parent Which variable to change (e.g. locals, env)
    @param {String} key The key to remove (supports dot-notation)

  **/

  remove: function(parent, key) {

    var editor = require("./config-editor"),
        prev = editor.get(parent + "." + key);

    console.log("");

    editor.unset(parent + "." + key);
    editor.save();

    if ("undefined" === typeof prev)
      console.log("   " + chalk.red("No Change:") + " there was no " + parent + " variable called " + chalk.yellow(key));
    else if ("object" === typeof prev)
      console.log("   " + chalk.cyan("Removed: ") + parent + " variable " + chalk.yellow(key) + " has been unset");
    else
      console.log("   " + chalk.cyan("Removed: ") + parent + " variable " + chalk.yellow(key) + " has been unset from " + chalk.yellow(prev));
    console.log("");

  }

};
<|endoftext|>


<commit_before>var keystone = require('twreporter-keystone');
var transform = require('model-transform');
var Types = keystone.Field.Types;

var Post = new keystone.List('Post', {
	autokey: { path: 'slug', from: 'name', unique: true },
    defaultSort: '-createdAt',
});

Post.add({
	name: { type: String, required: true },
    title: { type: String, require: true, default: 'untitled' },
    subtitle: { type: String, require: false },
	state: { type: Types.Select, options: 'draft, published, scheduled, archived', default: 'draft', index: true },
	publishedDate: { type: Date, index: true, default: Date.now, dependsOn: { '$or': { state: [ 'published', 'scheduled' ] } }},
	writters: { type: Types.Relationship, ref: 'Contact', many: true },
	photographers: { type: Types.Relationship, ref: 'Contact', many: true },
	designers: { type: Types.Relationship, ref: 'Contact', many: true },
	engineers: { type: Types.Relationship, ref: 'Contact', many: true },
    extend_byline: { type: String, require: false },
	heroImage: { type: Types.ImageRelationship, ref: 'Image' },
    heroImageSize: { type: Types.Select, options: 'extend, normal, small', default: 'normal', dependsOn: { heroImage: {'$regex': '.+/i'}}},
	content: {
		brief: { type: Types.Html, wysiwyg: true, height: 150 },
		extended: { type: Types.Html, wysiwyg: true, height: 400 }
	},
	categories: { type: Types.Relationship, ref: 'PostCategory', many: true },
	style: { type: Types.Select, options: 'article, review, photography', default: 'article', index: true },
    topics: { type: Types.Relationship, ref: 'Topic' },
    topics_ref: { type: Types.Relationship, ref: 'Topic', hidden: true },
    copyright: { type: Types.Select, options: 'Creative-Commons, Copyrighted', default: 'Copyrighted', index: true },
	tags: { type: Types.Relationship, ref: 'Tag', many: true },
    relateds: {type: Types.Relationship, ref: 'Post', many: true },
    og_title: { type: String, require: false},
    og_description: { type: String, require: false},
	og_image: { type: Types.ImageRelationship, ref: 'Image' },
	isFeatured: { type: Boolean, index: true },
    createTime: { type: Date, default: Date.now },
});

Post.relationship({ ref: 'Post', refPath: 'relateds' });

Post.schema.virtual('content.full').get(() => {
	return this.content.extended || this.content.brief;
});

transform.toJSON(Post);
Post.defaultColumns = 'title, name, state|20%, author|20%, categories|20%, publishedDate|20%';
Post.schema.pre('save', function(next) {
    if (this.topics) {
        this.topics_ref = this.topics
    }
    next();
});
Post.register();
<commit_msg>seperate the content to brief and content for the extended<commit_after>var keystone = require('twreporter-keystone');
var transform = require('model-transform');
var Types = keystone.Field.Types;

var Post = new keystone.List('Post', {
	autokey: { path: 'slug', from: 'name', unique: true },
    defaultSort: '-createdAt',
});

Post.add({
	name: { type: String, required: true },
    title: { type: String, require: true, default: 'untitled' },
    subtitle: { type: String, require: false },
	state: { type: Types.Select, options: 'draft, published, scheduled, archived', default: 'draft', index: true },
	publishedDate: { type: Date, index: true, default: Date.now, dependsOn: { '$or': { state: [ 'published', 'scheduled' ] } }},
	writters: { type: Types.Relationship, ref: 'Contact', many: true },
	photographers: { type: Types.Relationship, ref: 'Contact', many: true },
	designers: { type: Types.Relationship, ref: 'Contact', many: true },
	engineers: { type: Types.Relationship, ref: 'Contact', many: true },
    extend_byline: { type: String, require: false },
	heroImage: { type: Types.ImageRelationship, ref: 'Image' },
    heroImageSize: { type: Types.Select, options: 'extend, normal, small', default: 'normal', dependsOn: { heroImage: {'$regex': '.+/i'}}},
	brief: { type: Types.Html, wysiwyg: true, height: 150 },
	content: { type: Types.Html, wysiwyg: true, height: 400 },
	categories: { type: Types.Relationship, ref: 'PostCategory', many: true },
	style: { type: Types.Select, options: 'article, review, photography', default: 'article', index: true },
    topics: { type: Types.Relationship, ref: 'Topic' },
    topics_ref: { type: Types.Relationship, ref: 'Topic', hidden: true },
    copyright: { type: Types.Select, options: 'Creative-Commons, Copyrighted', default: 'Copyrighted', index: true },
	tags: { type: Types.Relationship, ref: 'Tag', many: true },
    relateds: {type: Types.Relationship, ref: 'Post', many: true },
    og_title: { type: String, require: false},
    og_description: { type: String, require: false},
	og_image: { type: Types.ImageRelationship, ref: 'Image' },
	isFeatured: { type: Boolean, index: true },
    createTime: { type: Date, default: Date.now },
});

Post.relationship({ ref: 'Post', refPath: 'relateds' });

Post.schema.virtual('content.full').get(() => {
	return this.content.extended || this.content.brief;
});

transform.toJSON(Post);
Post.defaultColumns = 'title, name, state|20%, author|20%, categories|20%, publishedDate|20%';
Post.schema.pre('save', function(next) {
    if (this.topics) {
        this.topics_ref = this.topics
    }
    next();
});
Post.register();
<|endoftext|>


<commit_before>'use strict';
describe('controller specs', function() {
  var $scope;

  beforeEach(module('myApp.controllers'));

  beforeEach(inject(function($rootScope, $controller) {
    $scope = $rootScope.$new();
    $controller('helloWorldCtrl', {$scope: $scope});
  }));

  it('should create "person" model with first name "Jane"', function() {
    expect($scope.person.firstName).toBe('Jane');
  });

  it('should create "person" model with last name "Doe"', function() {
    expect($scope.person.firstName).toBe('Doe');
  });
});
<commit_msg>I'm an idiot, update of variable I'm testing<commit_after>'use strict';
describe('controller specs', function() {
  var $scope;

  beforeEach(module('myApp.controllers'));

  beforeEach(inject(function($rootScope, $controller) {
    $scope = $rootScope.$new();
    $controller('helloWorldCtrl', {$scope: $scope});
  }));

  it('should create "person" model with first name "Jane"', function() {
    expect($scope.person.firstName).toBe('Jane');
  });

  it('should create "person" model with last name "Doe"', function() {
    expect($scope.person.lastName).toBe('Doe');
  });
});
<|endoftext|>


<commit_before>import React from 'react'
import { Link } from 'react-router'
const { object, func } = React.PropTypes
import { filter } from 'lodash'
import Avatar from './Avatar'
import Dropdown from './Dropdown'
import { changeEventResponse } from '../actions'

export default class RSVPControl extends React.Component {
  static propTypes = {
    currentUser: object,
    post: object,
    dispatch: func
  }

  render () {
    var props = this.props
    let { post, currentUser } = props

    var yeses = filter(post.responders, er => er.response === 'yes')
    var maybes = filter(post.responders, er => er.response === 'maybe')
    var nos = filter(post.responders, er => er.response === 'no')
    var eventResponse = (filter(post.responders, responder => responder.id === currentUser.id)[0] || {response: ''}).response
    var yesHeader = {header: 'Going', id: -1}
    var maybeHeader = {header: 'Maybe', id: -2}
    var noHeader = {header: 'Can\'t Go', id: -3}

    var responderList = []
    if (yeses.length > 0) {
      responderList.push(yesHeader)
      responderList = responderList.concat(yeses)
    }
    if (maybes.length > 0) {
      responderList.push(maybeHeader)
      responderList = responderList.concat(maybes)
    }
    if (nos.length > 0) {
      responderList.push(noHeader)
      responderList = responderList.concat(nos)
    }

    var eventResponseClicked = function (response) {
      return e => {
        props.dispatch(changeEventResponse(post.id, response, currentUser))
      }
    }

    return (

          <button type='button' onClick={eventResponseClicked('yes')} className={'rsvp-yes btn btn-default ' + (eventResponse === 'yes' ? 'active' : '')}>
            Going
            {yeses.length > 0 && ` (${yeses.length})`}
          </button>
          <button type='button' onClick={eventResponseClicked('maybe')} className={'rsvp-maybe btn btn-default ' + (eventResponse === 'maybe' ? 'active' : '')}>
            Maybe
            {maybes.length > 0 && ` (${maybes.length})`}
          </button>
          <button type='button' onClick={eventResponseClicked('no')} className={'rsvp-no btn btn-default ' + (eventResponse === 'no' ? 'active' : '')}>
            {"Can't Go"}
            {nos.length > 0 && ` (${nos.length})`}
          </button>

        {post.responders.length > 0 &&

          <Dropdown className='responses-dropdown' toggleChildren={See Responses}>
            {responderList.map(personOrHeader =>

              {personOrHeader.header
                ? {personOrHeader.header}
                :
                <Avatar person={personOrHeader} /> <Link className='person' to={`/u/${personOrHeader.id}`}>{personOrHeader.name}</Link>
              }

)}
          </Dropdown>

}

    )
  }
}
<commit_msg>use classnames module<commit_after>import React from 'react'
import { Link } from 'react-router'
import cx from 'classnames'
const { object, func } = React.PropTypes
import { filter } from 'lodash'
import Avatar from './Avatar'
import Dropdown from './Dropdown'
import { changeEventResponse } from '../actions'

export default class RSVPControl extends React.Component {
  static propTypes = {
    currentUser: object,
    post: object,
    dispatch: func
  }

  render () {
    var props = this.props
    let { post, currentUser } = props

    var yeses = filter(post.responders, er => er.response === 'yes')
    var maybes = filter(post.responders, er => er.response === 'maybe')
    var nos = filter(post.responders, er => er.response === 'no')
    var eventResponse = (filter(post.responders, responder => responder.id === currentUser.id)[0] || {response: ''}).response
    var yesHeader = {header: 'Going', id: -1}
    var maybeHeader = {header: 'Maybe', id: -2}
    var noHeader = {header: 'Can\'t Go', id: -3}

    var responderList = []
    if (yeses.length > 0) {
      responderList.push(yesHeader)
      responderList = responderList.concat(yeses)
    }
    if (maybes.length > 0) {
      responderList.push(maybeHeader)
      responderList = responderList.concat(maybes)
    }
    if (nos.length > 0) {
      responderList.push(noHeader)
      responderList = responderList.concat(nos)
    }

    var eventResponseClicked = function (response) {
      return e => {
        props.dispatch(changeEventResponse(post.id, response, currentUser))
      }
    }

    return (

          <button type='button' onClick={eventResponseClicked('yes')} className={cx('rsvp-yes', 'btn', 'btn-default', {'active': eventResponse === 'yes'})}>
            Going
            {yeses.length > 0 && ` (${yeses.length})`}
          </button>
          <button type='button' onClick={eventResponseClicked('maybe')} className={cx('rsvp-maybe', 'btn', 'btn-default', {'active': eventResponse === 'maybe'})}>
            Maybe
            {maybes.length > 0 && ` (${maybes.length})`}
          </button>
          <button type='button' onClick={eventResponseClicked('no')} className={cx('rsvp-no', 'btn', 'btn-default', {'active': eventResponse === 'no'})}>
            {"Can't Go"}
            {nos.length > 0 && ` (${nos.length})`}
          </button>

        {post.responders.length > 0 &&

          <Dropdown className='responses-dropdown' toggleChildren={See Responses}>
            {responderList.map(personOrHeader =>

              {personOrHeader.header
                ? {personOrHeader.header}
                :
                <Avatar person={personOrHeader} /> <Link className='person' to={`/u/${personOrHeader.id}`}>{personOrHeader.name}</Link>
              }

)}
          </Dropdown>

}

    )
  }
}
<|endoftext|>


<commit_before>var vdom = require('virtual-dom')
  , h = vdom.h
  , globalize = require('globalize')
  , AtomicEmitter = require('atomic-emitter')

// load cldr data
globalize.load(require('cldr-data/supplemental/likelySubtags.json'))
globalize.load(require('cldr-data/supplemental/plurals.json'))// for cardinals
globalize.load(require('cldr-data/supplemental/ordinals.json'))// for ordinals

module.exports = setup
module.exports.consumes = ['ui', 'settings']

function setup(plugin, imports, register) {
  var ui = imports.ui
    , settings = imports.settings

  // Monkeypatch ui

  ui.globalize = globalize
  ui._ = (id) => globalize.messageFormatter(id)
  ui.onLocalize = AtomicEmitter()
  ui.action_setLcoale =  function(locale) {
    return {type: 'SET_LOCALE', payload: locale}
  }
  ui.renderLocaleSetting = renderLocaleSetting

  // SET_LOCALE middleware + reducer

  ui.reduxMiddleware.push(globalizeMiddleware)
  function globalizeMiddleware(store) {
    return next => action => {
      if('SET_LOCALE' === action.type || 'LOAD_STATE' === action.type) {
        var newLocale = action.payload.locale || action.payload
        if(globalize.locale() !== newLocale) {
          fetch(ui.baseURL+'/locales/'+newLocale+'.json')
          .then((res) => res.json())
          .then((json) => {
            globalize.loadMessages(json)
            globalize.locale(newLocale)
            document.documentElement.dir = ui.config.locales[newLocale].direction
            next(action)
            ui.onLocalize.emit(newLocale)
          })
          return
        }
      }
      return next(action)
    }
  }

  ui.reduxReducerMap.locale = function(state, action) {
    if('undefined' === typeof state) return null
    if('SET_LOCALE' === action.type) {
      return action.payload
    }
    return state
  }

  ui.onStart(() => {
    var locale = navigator.language
      || navigator.userLanguage // IE
      || 'en' // default
    ui.store.dispatch({type: 'SET_LOCALE', payload: locale})
  })

  // Locale setting

  settings.onRenderUserSettings((children) => {
    children.push(renderLocaleSetting(ui.store))
  })

  function renderLocaleSetting(store) {
    var currentLanguage = store.getState().locale
    return h('div', [
      h('h4', ui._('ui/locale')())
    , h('ul.list-group', [
        h('li.list-group-item', [
          h('label', [
            ui._('ui/select-language')()+': '
          , h('select'
            , { 'ev-change': onchange, value: currentLanguage }
            , Object.keys(ui.config.locales).map(locale => {
                return h('option'
                , { value: locale
                  , attributes: currentLanguage == locale? {selected: true} : {}
                  }
                , ui.config.locales[locale].nativeName
                )
              }))
          ])
        ])
      ])
    ])

    function onchange(evt) {
      store.dispatch(
        settings.action_setForUser({'ui:locale':evt.currentTarget.value})
      )
    }
  }

  // Integrate with settings

  settings.onChange(() => {
    var state = ui.store.getState()
    if (!state.session.user) return
    var locale = settings.getForUser('ui:locale')
    if(locale && state.locale !== locale) {
      ui.store.dispatch(ui.action_setLcoale(locale))
    }
  })

  register()
}
<commit_msg>[localize] Fix locale detection: Properly implement fallback mechanism<commit_after>var vdom = require('virtual-dom')
  , h = vdom.h
  , globalize = require('globalize')
  , AtomicEmitter = require('atomic-emitter')

// load cldr data
globalize.load(require('cldr-data/supplemental/likelySubtags.json'))
globalize.load(require('cldr-data/supplemental/plurals.json'))// for cardinals
globalize.load(require('cldr-data/supplemental/ordinals.json'))// for ordinals

module.exports = setup
module.exports.consumes = ['ui', 'settings']

function setup(plugin, imports, register) {
  var ui = imports.ui
    , settings = imports.settings

  // Monkeypatch ui

  ui.globalize = globalize
  ui._ = (id) => globalize.messageFormatter(id)
  ui.onLocalize = AtomicEmitter()
  ui.action_setLcoale =  function(locale) {
    return {type: 'SET_LOCALE', payload: locale}
  }
  ui.renderLocaleSetting = renderLocaleSetting

  // SET_LOCALE middleware + reducer

  ui.reduxMiddleware.push(globalizeMiddleware)
  function globalizeMiddleware(store) {
    return next => action => {
      if('SET_LOCALE' === action.type || 'LOAD_STATE' === action.type) {
        var newLocale = action.payload.locale || action.payload
        if(globalize.locale() !== newLocale) {
          return fetch(ui.baseURL+'/locales/'+newLocale+'.json')
	  .then((res) => {
	    if (res.status != 200) throw new Error('Not ok')
	    return res.json()
	  })
          .then((json) => {
            globalize.loadMessages(json)
            globalize.locale(newLocale)
            document.documentElement.dir = ui.config.locales[newLocale].direction
            next(action)
            ui.onLocalize.emit(newLocale)
          })
        }
      }
      return next(action)
    }
  }

  ui.reduxReducerMap.locale = function(state, action) {
    if('undefined' === typeof state) return null
    if('SET_LOCALE' === action.type) {
      return action.payload
    }
    return state
  }

  ui.action_setLocale = function(locale) {
    return {type: 'SET_LOCALE', payload: locale}
  }

  ui.action_setLocaleWithFallbacks = function*(locales) {
    for (var i=0; i<locales.length; i++) {
      try {
        yield ui.action_setLocale(locales[i])
        return
      }catch(e) {
        // Do nothing -- next locale will be set.
      }
    }
    throw new Error('No locales found. Network down?')
  }

  ui.onStart(() => {
    var locales = [
      navigator.language || navigator.userLanguage
    , getLocaleRoot(navigator.language || navigator.userLanguage)
    , 'en' // default
    ]
    store.dispatch(ui.action_setLocaleWithFallbacks(locales))
  })

  function getLocaleRoot(locale) {
    if (!~locale.indexOf('-')) return
    return locale.split('-')[0]
  }

  // Locale setting

  settings.onRenderUserSettings((children) => {
    children.push(renderLocaleSetting(ui.store))
  })

  function renderLocaleSetting(store) {
    var currentLanguage = store.getState().locale
    return h('div', [
      h('h4', ui._('ui/locale')())
    , h('ul.list-group', [
        h('li.list-group-item', [
          h('label', [
            ui._('ui/select-language')()+': '
          , h('select'
            , { 'ev-change': onchange, value: currentLanguage }
            , Object.keys(ui.config.locales).map(locale => {
                return h('option'
                , { value: locale
                  , attributes: currentLanguage == locale? {selected: true} : {}
                  }
                , ui.config.locales[locale].nativeName
                )
              }))
          ])
        ])
      ])
    ])

    function onchange(evt) {
      store.dispatch(
        settings.action_setForUser({'ui:locale':evt.currentTarget.value})
      )
    }
  }

  // Integrate with settings

  settings.onChange(() => {
    var state = ui.store.getState()
    if (!state.session.user) return
    var locale = settings.getForUser('ui:locale')
    if(locale && state.locale !== locale) {
      ui.store.dispatch(ui.action_setLcoale(locale))
    }
  })

  register()
}
<|endoftext|>


<commit_before>/*
Copyright (C) 2017  Cloudbase Solutions SRL

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

import React, { Component, PropTypes } from 'react';
import withStyles from 'isomorphic-style-loader/lib/withStyles';
import moment from 'moment';
import Table from '../Table';
import s from './Tasks.scss';
import TextTruncate from 'react-text-truncate';
import LoadingIcon from "../LoadingIcon/LoadingIcon";
import ProgressBar from '../ProgressBar';
import Helper from '../Helper';

function hasProgress(msg) {
  if (msg.indexOf('progress:') > -1) {
    let progressStr = msg.substr(msg.indexOf('progress:'))
    let value = progressStr.match(/(100|[0-9]{1,2})%/)
    return value[1]
  } else {
    return false
  }
}

class Tasks extends Component {

  static propTypes = {
    tasks: PropTypes.array
  }

  constructor(props) {
    super(props)
    this.headers = [
      { label: "Task", key: 'task_type', width: 1 },
      { label: "Instance", key: 'instance', width: 1 },
      { label: "Latest Message", key: 'latest_message', width: 2 },
      { label: "Timestamp", key: 'timestamp', width: 1 }
    ]

    this.state = {
      listItems: []
    }
  }

  componentWillMount() {
    this.componentWillReceiveProps(this.props)
  }

  componentWillReceiveProps(newProps) {
    let listItems = []
    if (newProps.tasks) {
      newProps.tasks.forEach((item) => {
        let latestMessage
        if (item.progress_updates.length && item.progress_updates[item.progress_updates.length - 1]) {
          latestMessage = item.progress_updates[item.progress_updates.length - 1].message
        } else {
          latestMessage = "-"
        }

        let progressUpdates = []
        if (item.progress_updates.length) {
          let first = true

          if (item.progress_updates[0] !== null) {
            item.progress_updates.sort((a, b) => moment(a.created_at).isAfter(moment(b.created_at)))
          }
          for (let i = item.progress_updates.length - 1; i >= 0; i--) {
            let date = "-"
            if (item.progress_updates[i]) {
              let createdAt = Helper.getTimeObject(item.progress_updates[i].created_at)
              date = moment(createdAt).format("YYYY-MM-DD HH:mm:ss")

              progressUpdates.push(

                  {date}

                    {item.progress_updates[i] && item.progress_updates[i].message}
                    {hasProgress(item.progress_updates[i].message) &&
                    <ProgressBar progress={hasProgress(item.progress_updates[i].message)} />
                    }

)
              first = false
            }
          }
          if (progressUpdates.length == 0) {
            progressUpdates = "N/A"
          }
        } else {
          progressUpdates = "N/A"
        }

        let taskDetails = (

Status

{item.status}

ID

{item.id}

Exception details

              {item.exception_details && item.exception_details.length ?
                (<TextTruncate line={10} text={item.exception_details} truncateText="..." />) : "N/A"}

Depends on

{item.depends_on && item.depends_on[0] ? item.depends_on[0] : "N/A"}

Progress Updates

{progressUpdates}

)

        let taskType = item.task_type.replace(/_/g, " ").toLowerCase()
        taskType = taskType.charAt(0).toUpperCase() + taskType.slice(1)

        let newItem = {
          task_type: (

            <TextTruncate line={1} truncateText="..." text={taskType} />
          ),
          instance: <TextTruncate line={1} text={item.instance} truncateText="..." />,
          latest_message: <TextTruncate line={1} truncateText="..." text={latestMessage} />,
          timestamp: item.updated_at ? Helper.getTimeObject(moment(item.updated_at)).format("YYYY-MM-DD HH:mm:ss") :
            "-",
          detailView: taskDetails,
          openState: item.status === 'RUNNING'
        }
        listItems.push(newItem)
      }, this)
    }
    this.setState({ listItems: listItems })
  }

  render() {
    return (

        { this.state ?
          (

) : <LoadingIcon />
        }

    );
  }

}

export default withStyles(Tasks, s);
<commit_msg>Fixes sorting of the task progress updates - changes from created_at to updated_at<commit_after>/*
Copyright (C) 2017  Cloudbase Solutions SRL

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

import React, { Component, PropTypes } from 'react';
import withStyles from 'isomorphic-style-loader/lib/withStyles';
import moment from 'moment';
import Table from '../Table';
import s from './Tasks.scss';
import TextTruncate from 'react-text-truncate';
import LoadingIcon from "../LoadingIcon/LoadingIcon";
import ProgressBar from '../ProgressBar';
import Helper from '../Helper';

function hasProgress(msg) {
  if (msg.indexOf('progress:') > -1) {
    let progressStr = msg.substr(msg.indexOf('progress:'))
    let value = progressStr.match(/(100|[0-9]{1,2})%/)
    return value[1]
  } else {
    return false
  }
}

class Tasks extends Component {

  static propTypes = {
    tasks: PropTypes.array
  }

  constructor(props) {
    super(props)
    this.headers = [
      { label: "Task", key: 'task_type', width: 1 },
      { label: "Instance", key: 'instance', width: 1 },
      { label: "Latest Message", key: 'latest_message', width: 2 },
      { label: "Timestamp", key: 'timestamp', width: 1 }
    ]

    this.state = {
      listItems: []
    }
  }

  componentWillMount() {
    this.componentWillReceiveProps(this.props)
  }

  componentWillReceiveProps(newProps) {
    let listItems = []
    if (newProps.tasks) {
      newProps.tasks.forEach((item) => {
        let latestMessage
        if (item.progress_updates.length && item.progress_updates[item.progress_updates.length - 1]) {
          latestMessage = item.progress_updates[item.progress_updates.length - 1].message
        } else {
          latestMessage = "-"
        }

        let progressUpdates = []
        if (item.progress_updates.length) {
          let first = true

          if (item.progress_updates[0] !== null) {
            item.progress_updates.sort((a, b) => moment(a.updated_at).isAfter(moment(b.updated_at)))
          }
          for (let i = item.progress_updates.length - 1; i >= 0; i--) {
            let date = "-"
            if (item.progress_updates[i]) {
              let createdAt = Helper.getTimeObject(item.progress_updates[i].created_at)
              date = moment(createdAt).format("YYYY-MM-DD HH:mm:ss")

              progressUpdates.push(

                  {date}

                    {item.progress_updates[i] && item.progress_updates[i].message}
                    {hasProgress(item.progress_updates[i].message) &&
                    <ProgressBar progress={hasProgress(item.progress_updates[i].message)} />
                    }

)
              first = false
            }
          }
          if (progressUpdates.length == 0) {
            progressUpdates = "N/A"
          }
        } else {
          progressUpdates = "N/A"
        }

        let taskDetails = (

Status

{item.status}

ID

{item.id}

Exception details

              {item.exception_details && item.exception_details.length ?
                (<TextTruncate line={10} text={item.exception_details} truncateText="..." />) : "N/A"}

Depends on

{item.depends_on && item.depends_on[0] ? item.depends_on[0] : "N/A"}

Progress Updates

{progressUpdates}

)

        let taskType = item.task_type.replace(/_/g, " ").toLowerCase()
        taskType = taskType.charAt(0).toUpperCase() + taskType.slice(1)

        let newItem = {
          task_type: (

            <TextTruncate line={1} truncateText="..." text={taskType} />
          ),
          instance: <TextTruncate line={1} text={item.instance} truncateText="..." />,
          latest_message: <TextTruncate line={1} truncateText="..." text={latestMessage} />,
          timestamp: item.updated_at ? Helper.getTimeObject(moment(item.updated_at)).format("YYYY-MM-DD HH:mm:ss") :
            "-",
          detailView: taskDetails,
          openState: item.status === 'RUNNING'
        }
        listItems.push(newItem)
      }, this)
    }
    this.setState({ listItems: listItems })
  }

  render() {
    return (

        { this.state ?
          (

) : <LoadingIcon />
        }

    );
  }

}

export default withStyles(Tasks, s);
<|endoftext|>


<commit_before>describe(
  require('../../__fixtures/utils/test_helper')
    .create()
    .testName(__filename, 3),
  function() {
    var expect = require('expect.js');
    const promisify = require('../../../lib/system/shared/promisify');

    it('can promisify a basic function', async () => {
      let f = (x, callback) => callback(null, x);
      let fpromise = promisify(f);
      expect(await fpromise(4)).to.eql(4);
    });

    it('can promisify a basic function - error case ', async () => {
      let f = (x, callback) => callback(new Error('test error'));
      let fpromise = promisify(f);
      let errored;
      try {
        await fpromise('whatever');
      } catch (e) {
        errored = true;
        expect(e.toString()).to.eql('Error: test error');
      }
      expect(errored).to.be(true);
    });

    it('can promisify a function that returns more than 1 argument ', async () => {
      let f = (x, y, callback) => callback(null, x, y);
      let fpromise = promisify(f);
      expect(await fpromise(1, 2)).to.eql([1,2]);
    });
  }
);
<commit_msg>SMC-4550: linted<commit_after>describe(
  require('../../__fixtures/utils/test_helper')
    .create()
    .testName(__filename, 3),
  function() {
    var expect = require('expect.js');
    const promisify = require('../../../lib/system/shared/promisify');

    it('can promisify a basic function', async () => {
      let f = (x, callback) => callback(null, x);
      let fpromise = promisify(f);
      expect(await fpromise(4)).to.eql(4);
    });

    it('can promisify a basic function - error case ', async () => {
      let f = (x, callback) => callback(new Error('test error'));
      let fpromise = promisify(f);
      let errored;
      try {
        await fpromise('whatever');
      } catch (e) {
        errored = true;
        expect(e.toString()).to.eql('Error: test error');
      }
      expect(errored).to.be(true);
    });

    it('can promisify a function that returns more than 1 argument ', async () => {
      let f = (x, y, callback) => callback(null, x, y);
      let fpromise = promisify(f);
      expect(await fpromise(1, 2)).to.eql([1, 2]);
    });
  }
);
<|endoftext|>


<commit_before>/*
Copyright (C) 2017  Cloudbase Solutions SRL

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

import React, { Component, PropTypes } from 'react';
import withStyles from 'isomorphic-style-loader/lib/withStyles';
import moment from 'moment';
import Table from '../Table';
import s from './Tasks.scss';
import TextTruncate from 'react-text-truncate';
import NotificationActions from '../../actions/NotificationActions'
import LoadingIcon from "../LoadingIcon/LoadingIcon";
import ProgressBar from '../ProgressBar';
import Helper from '../Helper';

function hasProgress(msg) {
  if (msg.indexOf('progress:') > -1) {
    let progressStr = msg.substr(msg.indexOf('progress:'))
    let value = progressStr.match(/(100|[0-9]{1,2})%/)
    return value[1]
  } else {
    return false
  }
}

class Tasks extends Component {

  static propTypes = {
    tasks: PropTypes.array,
    execution: PropTypes.object
  }

  constructor(props) {
    super(props)
    this.headers = [
      { label: "Task", key: 'task_type', width: 1 },
      { label: "Instance", key: 'instance', width: 1 },
      { label: "Latest Message", key: 'latest_message', width: 2 },
      { label: "Timestamp", key: 'timestamp', width: 1 }
    ]

    this.state = {
      listItems: [],
      execution: null
    }
  }

  componentWillMount() {
    this.componentWillReceiveProps(this.props)
  }

  componentWillReceiveProps(newProps) {
    let listItems = []
    if (newProps.tasks) {
      newProps.tasks.forEach(item => {
        let latestMessage
        if (item.progress_updates.length && item.progress_updates[item.progress_updates.length - 1]) {
          latestMessage = item.progress_updates[item.progress_updates.length - 1].message
        } else {
          latestMessage = "-"
        }

        let progressUpdates = []
        if (item.progress_updates.length) {
          let first = true

          if (item.progress_updates[0] !== null) {
            item.progress_updates.sort((a, b) => moment(a.created_at).isAfter(moment(b.created_at)))
          }
          for (let i = item.progress_updates.length - 1; i >= 0; i--) {
            let date = "-"
            if (item.progress_updates[i]) {
              let createdAt = Helper.getTimeObject(item.progress_updates[i].created_at)
              date = moment(createdAt).format("YYYY-MM-DD HH:mm:ss")

              progressUpdates.push(

                  {date}

                    {item.progress_updates[i] && item.progress_updates[i].message}
                    {hasProgress(item.progress_updates[i].message) &&
                    <ProgressBar progress={hasProgress(item.progress_updates[i].message)} />
                    }

)
              first = false
            }
          }
          if (progressUpdates.length == 0) {
            progressUpdates = "N/A"
          }
        } else {
          progressUpdates = "N/A"
        }

        let taskDetails = (

Status

{item.status}

ID

 this.copyIdClick(item)}
              onMouseDown={e => e.stopPropagation()}
              onMouseUp={e => e.stopPropagation()}
            >{item.id}

Exception details

              {item.exception_details && item.exception_details.length ?
                (<TextTruncate line={10} text={item.exception_details} truncateText="..." />) : "N/A"}

Depends on

{item.depends_on && item.depends_on[0] ? item.depends_on[0] : "N/A"}

Progress Updates

{progressUpdates}

)

        let taskType = item.task_type.replace(/_/g, " ").toLowerCase()
        taskType = taskType.charAt(0).toUpperCase() + taskType.slice(1)

        let newItem = {
          task_type: (

            <TextTruncate line={1} truncateText="..." text={taskType} />
          ),
          instance: <TextTruncate line={1} text={item.instance} truncateText="..." />,
          latest_message: <TextTruncate line={1} truncateText="..." text={latestMessage} />,
          timestamp: item.created_at ? Helper.getTimeObject(moment(item.created_at)).format("YYYY-MM-DD HH:mm:ss") :
            "-",
          detailView: taskDetails,
          openState: item.status === 'RUNNING'
        }
        listItems.push(newItem)
      }, this)
    }
    this.setState({ listItems: listItems, execution: newProps.execution })
  }

  copyIdClick(item) {
    let succesful = Helper.copyTextToClipboard(item.id)

    if (succesful) {
      NotificationActions.notify('The ID has been copied to clipboard.')
    } else {
      NotificationActions.notify('The ID couldn\'t be copied', 'error')
    }
  }

  render() {
    return (

        { this.state ?
          (

) : <LoadingIcon />
        }

    );
  }

}

export default withStyles(Tasks, s);
<commit_msg>Add a more permissive way to identify percentages in task execution progress update messages<commit_after>/*
Copyright (C) 2017  Cloudbase Solutions SRL

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

import React, { Component, PropTypes } from 'react';
import withStyles from 'isomorphic-style-loader/lib/withStyles';
import moment from 'moment';
import Table from '../Table';
import s from './Tasks.scss';
import TextTruncate from 'react-text-truncate';
import NotificationActions from '../../actions/NotificationActions'
import LoadingIcon from "../LoadingIcon/LoadingIcon";
import ProgressBar from '../ProgressBar';
import Helper from '../Helper';

let getProgressPercentage = (msg) => {
  let match = msg.match(/.*progress.*?(100|\d{1,2})%/)
  return match && match[1]
}

class Tasks extends Component {

  static propTypes = {
    tasks: PropTypes.array,
    execution: PropTypes.object
  }

  constructor(props) {
    super(props)
    this.headers = [
      { label: "Task", key: 'task_type', width: 1 },
      { label: "Instance", key: 'instance', width: 1 },
      { label: "Latest Message", key: 'latest_message', width: 2 },
      { label: "Timestamp", key: 'timestamp', width: 1 }
    ]

    this.state = {
      listItems: [],
      execution: null
    }
  }

  componentWillMount() {
    this.componentWillReceiveProps(this.props)
  }

  componentWillReceiveProps(newProps) {
    let listItems = []
    if (newProps.tasks) {
      newProps.tasks.forEach(item => {
        let latestMessage
        if (item.progress_updates.length && item.progress_updates[item.progress_updates.length - 1]) {
          latestMessage = item.progress_updates[item.progress_updates.length - 1].message
        } else {
          latestMessage = "-"
        }

        let progressUpdates = []
        if (item.progress_updates.length) {
          let first = true

          if (item.progress_updates[0] !== null) {
            item.progress_updates.sort((a, b) => moment(a.created_at).isAfter(moment(b.created_at)))
          }
          for (let i = item.progress_updates.length - 1; i >= 0; i--) {
            let date = "-"
            let progressUpdate = item.progress_updates[i]
            if (progressUpdate) {
              let createdAt = Helper.getTimeObject(progressUpdate.created_at)
              date = moment(createdAt).format("YYYY-MM-DD HH:mm:ss")

              let percentage = getProgressPercentage(progressUpdate.message)
              progressUpdates.push(

                  {date}

                    {progressUpdate.message}
                    {percentage && <ProgressBar progress={percentage} />}

)
              first = false
            }
          }
          if (progressUpdates.length == 0) {
            progressUpdates = "N/A"
          }
        } else {
          progressUpdates = "N/A"
        }

        let taskDetails = (

Status

{item.status}

ID

 this.copyIdClick(item)}
              onMouseDown={e => e.stopPropagation()}
              onMouseUp={e => e.stopPropagation()}
            >{item.id}

Exception details

              {item.exception_details && item.exception_details.length ?
                (<TextTruncate line={10} text={item.exception_details} truncateText="..." />) : "N/A"}

Depends on

{item.depends_on && item.depends_on[0] ? item.depends_on[0] : "N/A"}

Progress Updates

{progressUpdates}

)

        let taskType = item.task_type.replace(/_/g, " ").toLowerCase()
        taskType = taskType.charAt(0).toUpperCase() + taskType.slice(1)

        let newItem = {
          task_type: (

            <TextTruncate line={1} truncateText="..." text={taskType} />
          ),
          instance: <TextTruncate line={1} text={item.instance} truncateText="..." />,
          latest_message: <TextTruncate line={1} truncateText="..." text={latestMessage} />,
          timestamp: item.created_at ? Helper.getTimeObject(moment(item.created_at)).format("YYYY-MM-DD HH:mm:ss") :
            "-",
          detailView: taskDetails,
          openState: item.status === 'RUNNING'
        }
        listItems.push(newItem)
      }, this)
    }
    this.setState({ listItems: listItems, execution: newProps.execution })
  }

  copyIdClick(item) {
    let succesful = Helper.copyTextToClipboard(item.id)

    if (succesful) {
      NotificationActions.notify('The ID has been copied to clipboard.')
    } else {
      NotificationActions.notify('The ID couldn\'t be copied', 'error')
    }
  }

  render() {
    return (

        { this.state ?
          (

) : <LoadingIcon />
        }

    );
  }

}

export default withStyles(Tasks, s);
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import Camper from './camper';
import { connect } from 'react-redux';
import { getCampers30Days } from '../actions';

class CamperList extends Component {
  componentDidMount() {
    this.props.getCampers30Days();
  }

  renderCampers(camper) {
    console.log(camper)
    return
{camper.username}
;
    const campers30Days = this.props.campers30Days;
  }

  render() {
    // console.log(this.props.campers30Days)
    if (!this.props.campers30Days) {
      return
Loading...
;
    }
    return (

        {this.props.campers30Days.map((camper) => this.renderCampers(camper))}

    )
  };
}

function mapStateToProps(state) {
  return { campers30Days: state.campers30Days }
}

export default connect(mapStateToProps, { getCampers30Days })(CamperList)
// <Camper data={ this.props.camperInfo }/>
// {this.renderCampers()}
// {this.props.campers30Days.map(this.renderCampers)}
// {this.props.campers30Days.map((camper) => this.renderCampers)}

// {this.props.campers30Days.map((camper) => {
//   return
{camper.username}

// })}
// {this.renderCampers()}
<commit_msg>Rendered users into table, included index that serves as ranking<commit_after>import React, { Component } from 'react';
import Camper from './camper';
import { connect } from 'react-redux';
import { getCampers30Days } from '../actions';

class CamperList extends Component {
  componentDidMount() {
    this.props.getCampers30Days();
  }

  renderCampers(camper, index) {
    console.log(camper)
    return (

        {index+1}
        {camper.username}
        {camper.recent}
        {camper.alltime}

    )
  }

  render() {
    return (

              #
              Camper
              Points in the past 30 days
              All time points

            {this.props.campers30Days.map((camper, index) => this.renderCampers(camper, index))}

    )
  };
}

function mapStateToProps(state) {
  return { campers30Days: state.campers30Days }
}

export default connect(mapStateToProps, { getCampers30Days })(CamperList)
// <Camper data={ this.props.camperInfo }/>

// {this.props.campers30Days.map((camper) => {
//   return
{camper.username}

// })}
// {this.renderCampers()}
<|endoftext|>


<commit_before>import mongoose from 'mongoose';
var Schema = mongoose.Schema;

// 订阅表

const FeedSchema = new Schema({
    xml:            {type: String},
    type:           {type: String},
    version:        {type: String},
    title:          {type: String},
    description:    {type: String},
    date:           {type: Date},
    pubdate:        {type: Date},
    link:           {type: String},
    xmlurl:         {type: String},
    absurl:         {type: String},
    author:         {type: String},
    langulage:      {type: String},
    favicon:        {type: String},
    copyright:      {type: String},
    generator:      {type: String},
    categories:     {type: String},

    feedNum:        {type: Number, default: 0},         // 订阅人数
    lastScan:       {type: Date, defaukt: Date.now()}   // 上次扫描时间
});

var Feed = mongoose.model('Feed', FeedSchema);

module.exports = Feed;
<commit_msg>修复了Feed表默认文件夹问题<commit_after>import mongoose from 'mongoose';
var Schema = mongoose.Schema;

// 订阅表

const FeedSchema = new Schema({
    xml:            {type: String},
    type:           {type: String},
    version:        {type: String},
    title:          {type: String},
    description:    {type: String},
    date:           {type: Date},
    pubdate:        {type: Date},
    link:           {type: String},
    xmlurl:         {type: String},
    absurl:         {type: String},
    author:         {type: String},
    langulage:      {type: String},
    favicon:        {type: String},
    copyright:      {type: String},
    generator:      {type: String},
    categories:     {type: String, default: 'default'},

    feedNum:        {type: Number, default: 0},         // 订阅人数
    lastScan:       {type: Date, defaukt: Date.now()}   // 上次扫描时间
});

var Feed = mongoose.model('Feed', FeedSchema);

module.exports = Feed;
<|endoftext|>


<commit_before>import { connect } from 'react-redux';
import { selectBalance, doNotify } from 'lbry-redux';
import WalletSend from './view';

const perform = dispatch => ({
  openModal: (modal, props) => dispatch(doNotify(modal, props)),
});

const select = state => ({
  balance: selectBalance(state),
});

export default connect(select, perform)(WalletSend);
<commit_msg>fix linting for walletSend component<commit_after>import { connect } from 'react-redux';
import { selectBalance, doNotify } from 'lbry-redux';
import WalletSend from './view';

const perform = dispatch => ({
  openModal: (modal, props) => dispatch(doNotify(modal, props)),
});

const select = state => ({
  balance: selectBalance(state),
});

export default connect(
  select,
  perform
)(WalletSend);
<|endoftext|>


<commit_before>/**
 * Created by rcartier13 on 2/5/14.
 */

var logger = (require('../../logging/vip-winston')).Logger;
var _fileName = "overview-processor";

var config = require('../../config');
var feedIdMapper = require('../../feedIdMapper');
var mongoose = require('mongoose');
var schemas = require('../../dao/schemas');
var async = require('async');
var when = require('when');
var moment = require('moment');

var contests = require('./contests');
var results = require('./results');
var contest = require('./contest');
var locality = require('./locality');
var pollinglocations = require('./pollinglocations');

var _ = require('underscore');

var overviewModels = [];
var functionArr = [];

function runOverviewProcessor(feedId) {
  // overview-processor as a whole (start)
  logger.profileSeparately(_fileName);

  functionArr.push(pollinglocations.kickoffPollingLoc);
  functionArr.push(contests.kickoffContest);
  functionArr.push(results.kickoffResults);
  functionArr.push(contest.kickoffContest);
  functionArr.push(locality.kickoffLocality);

  calculateFields(feedId, function() {
    when.all(overviewModels).then(onSaveComplete, errorHandler);
  });
}

function errorHandler(err) {
  logger.error(err);
  exitProcess(1);
}

function onSaveComplete(results) {
  // overview-processor as a whole (end)
  logger.profileSeparately(_fileName);

  logger.info('Shutting down overview processor');

  // just grab the feedid from any overview object
  // and set the feed to complete
  schemas.models.feeds.findOne({_id: results[0]._feed}, function(err, feed) {

    schemas.models.feeds.findById(results[0]._feed, { payload: 0 })
      .populate('_state')
      .populate('_election')
      .exec(function(err, feed) {

        var title = "";

        // add feed date
        title += ( feed._election && feed._election.date ? moment(feed._election.date).utc().format('YYYY-MM-DD') + "-" : "");
        // add feed state
        title += ( feed._state && feed._state.name ? feed._state.name + "-" : "");
        // add feed electiontype
        title += ( feed._election && feed._election.electionType ? feed._election.electionType + "-" : "");

        var completedOnDate = moment().utc();

        // pass in the date completed as time
        var friendlyId = feedIdMapper.makeFriendlyId(completedOnDate.valueOf(), title);

        // note: send is synchronous
        if (process.send) {
          // add the friendly id to the list of ids loaded into memory
          // tell the parent about the friendlyid of the current feed being processed to do this
          process.send({"messageId": 2, "friendlyId": friendlyId, "feedId": feed._id});
        }

        // now also save the friendly feed id
        schemas.models.feeds.update({_id: feed._id},
          {
            feedStatus: 'Complete',
            complete: true,
            completedOn: completedOnDate,
            friendlyId: friendlyId
          },
          function(err, feed) {

            // now close out the mongoose connection and exit the process
            mongoose.disconnect();
            process.exit(0);
          }
        );
      })
  });

}

function calculateFields(feedId, saveCalc) {
  async.eachSeries(functionArr, function(func, done) {
    func(feedId, createOverviewModel, done);
  }, saveCalc);
};

function createOverviewModel(name, overview, errors, section, feed) {

  if(overview.amount == undefined) {
    overviewModels.push(schemas.models.overview.create({
      elementType: name,
      amount: 0,
      errorCount: 0,
      section: section,
      _feed: feed
    }));
    return;
  }

  var pct = overview.schemaFieldCount !== 0 ? parseInt((overview.fieldCount / overview.schemaFieldCount) * 100) : 0;

  // Sometimes errors is NaN, or possibly "NaN", not sure what we can do except to convert to 0.
  var errorCount = +errors || 0;

  var create = {
    elementType: name,
    amount: overview.amount,
    completePct: pct,
    errorCount: errorCount,
    section: section,
    _feed: feed
  };
  overviewModels.push(schemas.models.overview.create(create));
};

// To debug an overview for a specific feed, uncomment this, and call node overview-processor.js feedid
// if (process.argv.length > 1 && process.argv[1] != null) {
//   logger.info("running overview-processor manually");
//   schemas.initSchemas(mongoose);

//   mongoose.connect(config.mongoose.connectionString);
//   db = mongoose.connection;
//   db.on('error', console.error.bind(console, 'MongoDB connection error: '));
//   db.once('open', function callback() {
//     logger.info("initialized VIP database via Mongoose");
//     runOverviewProcessor(process.argv[2]);
//   });
// }
// else {
//   logger.error("ERROR: insufficient arguments provided to overview-processor.js\n");

//   logger.info("Usage: node  overview-processor.js  feedid");
//   logger.info("");

//   exitProcess(1);
// }

function exitProcess(code){

  // now close out the mongoose connection and exit the process
  mongoose.disconnect();
  process.exit(code);
}

exports.runOverviewProcessor = runOverviewProcessor;
<commit_msg>[TH] clean up debugging entry point<commit_after>/**
 * Created by rcartier13 on 2/5/14.
 */

var logger = (require('../../logging/vip-winston')).Logger;
var _fileName = "overview-processor";

var config = require('../../config');
var feedIdMapper = require('../../feedIdMapper');
var mongoose = require('mongoose');
var schemas = require('../../dao/schemas');
var async = require('async');
var when = require('when');
var moment = require('moment');

var contests = require('./contests');
var results = require('./results');
var contest = require('./contest');
var locality = require('./locality');
var pollinglocations = require('./pollinglocations');

var _ = require('underscore');

var overviewModels = [];
var functionArr = [];

function runOverviewProcessor(feedId) {
  // overview-processor as a whole (start)
  logger.profileSeparately(_fileName);

  functionArr.push(pollinglocations.kickoffPollingLoc);
  functionArr.push(contests.kickoffContest);
  functionArr.push(results.kickoffResults);
  functionArr.push(contest.kickoffContest);
  functionArr.push(locality.kickoffLocality);

  calculateFields(feedId, function() {
    when.all(overviewModels).then(onSaveComplete, errorHandler);
  });
}

function errorHandler(err) {
  logger.error(err);
  exitProcess(1);
}

function onSaveComplete(results) {
  // overview-processor as a whole (end)
  logger.profileSeparately(_fileName);

  logger.info('Shutting down overview processor');

  // just grab the feedid from any overview object
  // and set the feed to complete
  schemas.models.feeds.findOne({_id: results[0]._feed}, function(err, feed) {

    schemas.models.feeds.findById(results[0]._feed, { payload: 0 })
      .populate('_state')
      .populate('_election')
      .exec(function(err, feed) {

        var title = "";

        // add feed date
        title += ( feed._election && feed._election.date ? moment(feed._election.date).utc().format('YYYY-MM-DD') + "-" : "");
        // add feed state
        title += ( feed._state && feed._state.name ? feed._state.name + "-" : "");
        // add feed electiontype
        title += ( feed._election && feed._election.electionType ? feed._election.electionType + "-" : "");

        var completedOnDate = moment().utc();

        // pass in the date completed as time
        var friendlyId = feedIdMapper.makeFriendlyId(completedOnDate.valueOf(), title);

        // note: send is synchronous
        if (process.send) {
          // add the friendly id to the list of ids loaded into memory
          // tell the parent about the friendlyid of the current feed being processed to do this
          process.send({"messageId": 2, "friendlyId": friendlyId, "feedId": feed._id});
        }

        // now also save the friendly feed id
        schemas.models.feeds.update({_id: feed._id},
          {
            feedStatus: 'Complete',
            complete: true,
            completedOn: completedOnDate,
            friendlyId: friendlyId
          },
          function(err, feed) {

            // now close out the mongoose connection and exit the process
            mongoose.disconnect();
            process.exit(0);
          }
        );
      })
  });

}

function calculateFields(feedId, saveCalc) {
  async.eachSeries(functionArr, function(func, done) {
    func(feedId, createOverviewModel, done);
  }, saveCalc);
};

function createOverviewModel(name, overview, errors, section, feed) {

  if(overview.amount == undefined) {
    overviewModels.push(schemas.models.overview.create({
      elementType: name,
      amount: 0,
      errorCount: 0,
      section: section,
      _feed: feed
    }));
    return;
  }

  var pct = overview.schemaFieldCount !== 0 ? parseInt((overview.fieldCount / overview.schemaFieldCount) * 100) : 0;

  // Sometimes errors is NaN, or possibly "NaN", not sure what we can do except to convert to 0.
  var errorCount = +errors || 0;

  var create = {
    elementType: name,
    amount: overview.amount,
    completePct: pct,
    errorCount: errorCount,
    section: section,
    _feed: feed
  };
  overviewModels.push(schemas.models.overview.create(create));
};

function exitProcess(code){
  // now close out the mongoose connection and exit the process
  mongoose.disconnect();
  process.exit(code);
}

// To debug an overview for a specific feed, uncomment this, and call node overview-processor.js feedid
if (process.argv.length > 2 && process.argv[1].indexOf("overview-processor.js") !== -1) {
  if (process.argv[1] != null) {
    logger.info("running overview-processor manually");
    schemas.initSchemas(mongoose);

    mongoose.connect(config.mongoose.connectionString);
    db = mongoose.connection;
    db.on('error', console.error.bind(console, 'MongoDB connection error: '));
    db.once('open', function callback() {
      logger.info("initialized VIP database via Mongoose");
      runOverviewProcessor(process.argv[2]);
    });
  } else {
    logger.error("ERROR: insufficient arguments provided to overview-processor.js\n");

    logger.info("Usage: node  overview-processor.js  feedid");
    logger.info("");

    exitProcess(1);
  }
}

exports.runOverviewProcessor = runOverviewProcessor;
<|endoftext|>