<commit_before>import path from 'path';
import chalk from 'chalk';
import webpack from 'webpack';
import AssetsPlugin from 'assets-webpack-plugin';
import ProgressBarPlugin from 'progress-bar-webpack-plugin';
import baseWpPlugins from '../src/base/wp-plugins';

export const mainPath = path.resolve(__dirname, '..');
export const context = path.resolve(__dirname, '../');
export const buildPath = path.resolve(__dirname, '../dist');
export const basePath = path.resolve(__dirname, '../src/base');
export const dllPath = path.resolve(__dirname, '../dist/dlls');
export const assetsPath = path.resolve(__dirname, '../dist/assets');
export const clientPath = path.resolve(__dirname, '../src/base/client/');
export const manifestPath = buildPath;

export const entry = {
  vendor: [
    'react',
    'redux',
    'react-ga',
    'react-dom',
    'recompose',
    'immutable',
    'prop-types',
    'classnames',
    'react-redux',
    'react-share',
    'react-router',
    'babel-polyfill',
    'isomorphic-fetch',
    'html-react-parser',
    'react-disqus-comments',
    'highlight.js/lib/highlight',
    'react-router-scroll/lib/useScroll',
    'highlight.js/lib/languages/javascript',
  ]
};

export const module = {
  rules: [
    { test: /\.json$/, loader: 'json-loader', include: [mainPath] },
    { test: /\.html/, loader: 'raw-loader', include: [mainPath] },
    { test: /pattern\.svg$/, loader: 'url-loader?limit=100000&name=assets/images/[name].[ext]' },
    { test: /\.(png|jpg|jpeg|gif|svg)$/, loader: 'file-loader', exclude:[/background/], include: [mainPath], options: { name: 'assets/images/icons/[name].[ext]' } }
  ]
};

export const plugins = [
  new ProgressBarPlugin({
    format: `[BASE] ${chalk.blue('i')} Bundling... [:bar] ${chalk.green(':percent')} (:elapsed seconds)`,
    clear: true,
    summary: false,
  }),
  new AssetsPlugin({
    path: buildPath,
    filename: 'webpack-assets.json',
    prettyPrint: true
  }),
  new baseWpPlugins.compileInfoPlugin(),
  new webpack.ContextReplacementPlugin(
    /highlight\.js\/lib\/languages$/,
    new RegExp(`^./(${['javascript'].join('|')})$`),
  )
];

export const postcss = [
  require('postcss-import')(),
  require('postcss-url')(),
  require('postcss-modules-extract-imports'),
  require('postcss-nested')(),
  require('postcss-reporter')(),
  require('precss')(),
  require('postcss-mixins')(),
];

export const resolve = {
  extensions: ['.js', '.jsx', '.css'],
  modules: ['node_modules'],
  alias: {
    'app': path.resolve(__dirname, '../src/app'),
    'base': path.resolve(__dirname, '../src/base'),
    'store': path.resolve(__dirname, '../src/base/store'),
    'styles': path.resolve(__dirname, '../src/app/styles'),
    'mocks': path.resolve(__dirname, '../server/api/mocks'),
    'containers': path.resolve(__dirname, '../src/app/containers'),
    'components': path.resolve(__dirname, '../src/app/components')
  }
};<commit_msg>Url loader fix<commit_after>import path from 'path';
import chalk from 'chalk';
import webpack from 'webpack';
import AssetsPlugin from 'assets-webpack-plugin';
import ProgressBarPlugin from 'progress-bar-webpack-plugin';
import baseWpPlugins from '../src/base/wp-plugins';

export const mainPath = path.resolve(__dirname, '..');
export const context = path.resolve(__dirname, '../');
export const buildPath = path.resolve(__dirname, '../dist');
export const basePath = path.resolve(__dirname, '../src/base');
export const dllPath = path.resolve(__dirname, '../dist/dlls');
export const assetsPath = path.resolve(__dirname, '../dist/assets');
export const clientPath = path.resolve(__dirname, '../src/base/client/');
export const manifestPath = buildPath;

export const entry = {
  vendor: [
    'react',
    'redux',
    'react-ga',
    'react-dom',
    'recompose',
    'immutable',
    'prop-types',
    'classnames',
    'react-redux',
    'react-share',
    'react-router',
    'babel-polyfill',
    'isomorphic-fetch',
    'html-react-parser',
    'react-disqus-comments',
    'highlight.js/lib/highlight',
    'react-router-scroll/lib/useScroll',
    'highlight.js/lib/languages/javascript',
  ]
};

export const module = {
  rules: [
    { test: /\.json$/, loader: 'json-loader', include: [mainPath] },
    { test: /\.html/, loader: 'raw-loader', include: [mainPath] },
    { test: /\.(png|jpg|jpeg|gif|svg)$/, loader: 'url-loader?limit=100000&name=assets/images/[name].[ext]' },

  ]
};

export const plugins = [
  new ProgressBarPlugin({
    format: `[BASE] ${chalk.blue('i')} Bundling... [:bar] ${chalk.green(':percent')} (:elapsed seconds)`,
    clear: true,
    summary: false,
  }),
  new AssetsPlugin({
    path: buildPath,
    filename: 'webpack-assets.json',
    prettyPrint: true
  }),
  new baseWpPlugins.compileInfoPlugin(),
  new webpack.ContextReplacementPlugin(
    /highlight\.js\/lib\/languages$/,
    new RegExp(`^./(${['javascript'].join('|')})$`),
  )
];

export const postcss = [
  require('postcss-import')(),
  require('postcss-url')(),
  require('postcss-modules-extract-imports'),
  require('postcss-nested')(),
  require('postcss-reporter')(),
  require('precss')(),
  require('postcss-mixins')(),
];

export const resolve = {
  extensions: ['.js', '.jsx', '.css'],
  modules: ['node_modules'],
  alias: {
    'app': path.resolve(__dirname, '../src/app'),
    'base': path.resolve(__dirname, '../src/base'),
    'store': path.resolve(__dirname, '../src/base/store'),
    'styles': path.resolve(__dirname, '../src/app/styles'),
    'mocks': path.resolve(__dirname, '../server/api/mocks'),
    'containers': path.resolve(__dirname, '../src/app/containers'),
    'components': path.resolve(__dirname, '../src/app/components')
  }
};<|endoftext|>


<commit_before>var Boom = require('boom');
var Bluebird = require('bluebird');
var Cron = require('cron-parser');
var Express = require('express');
var Jwt = require('jsonwebtoken');
var Webtask = require('webtask-tools');
var _ = require('lodash');

var app = Express();
var router = Express.Router();
var mongo;

Bluebird.longStackTraces();

// Check for required configuration parameters
app.use(function (req, res, next) {
    var data = req.webtaskContext.data;
    var required = ['JOB_COLLECTION', 'MONGO_URL', 'cluster_url'];

    for (var i in required) {
        var key = required[i];

        if (!data[key]) {
            var err = Boom.badGateway('Cron webtask needs to be configured '
                + 'with the parameter: `' + key + '`.', data);
            return next(err);
        }
    }

    next();
});

// Set up connection to mongodb
app.use(function (req, res, next) {
    // Short-cut if mongo is already setup
    if (mongo) {
        req.mongo = mongo;
        return next();
    }

    var MongoClient = require('mongodb').MongoClient;
    var connect = Bluebird.promisify(MongoClient.connect, MongoClient);
    var data = req.webtaskContext.data;

    return connect(data.MONGO_URL)
        .then(function (db) {
            // Store the settled promise resolving to the db object
            mongo = req.mongo = db;
        })
        .catch(function (err) {
            throw Boom.wrap(err, 503, 'Database unreachable.');
        })
        .nodeify(next);
});

// Parse incoming json bodies
app.use(require('body-parser').json());

app.use(router);

app.use(function(err, req, res, next) {
    console.log(err.message);
    console.log(err.stack);

    if (!err.isBoom) err = Boom.wrap(err);

    res
        .set(err.output.headers)
        .status(err.output.statusCode)
        .json(err.output.payload);
});

router.post('/reserve',
    ensure('query', ['count', 'ttl']),
    function (req, res, next) {
        var data = req.webtaskContext.data;
        var jobs = req.mongo.collection(data.JOB_COLLECTION);
        var count = Math.max(0, Math.min(100, parseInt(req.query.count, 10)));
        var now = new Date();
        var nextAvailableAt = new Date(now.valueOf() + (parseInt(data.ttl, 10) * 1000));

        console.log('attempting to reserve ' + count + ' jobs.');

        Bluebird.map(_.range(count), function (n) {
            var filter = {
                cluster_url: data.cluster_url,
                next_available_at: {
                    $lte: now
                },
                state: 'active',
            };
            var update = {
                $set: {
                    next_available_at: nextAvailableAt
                }
            };
            var options = {
                projection: {
                    results: { $slice: 10 }, // Limit to the 10 last results
                },
            };

            return Bluebird.promisify(jobs.findOneAndUpdate, jobs)(filter, update, options, {
                returnOriginal: false, // Return modified
            })
                .get('value'); // Only pull out the value
        })
        // Don't prevent one failure from blocking the entire
        // reservation (that would mean extra waiting on those that
        // didn't fail)
        .settle()
        // Log errors and continue with safe fallback
        .map(function (result) {
            if (result.isRejected()) {
                console.log('error reserving job: ' + result.value().message);
                return null;
            } else {
                return result.value();
            }
        })
        // Elminate error queries and queries that did not match
        // (this is the case when there are fewer than N jobs
        // available for running now)
        .filter(Boolean)
        .tap(function (jobs) {
            console.log('successfully reserved ' + jobs.length + ' job(s).');
        })
        .map(stripMongoId)
        .then(res.json.bind(res), next);
});

router.get('/:container?', function (req, res, next) {
    var data = req.webtaskContext.data;
    var jobs = req.mongo.collection(data.JOB_COLLECTION);
    var query = {
        cluster_url: data.cluster_url,
    };

    // Both admin and user will hit this endpoint. When admin, container can be unset
    if (req.params.container) query.container = req.params.container;

    var limit = req.query.limit
        ? Math.max(0, Math.min(20, parseInt(req.query.limit, 10)))
        : 10;
    var skip = req.query.offset
        ? Math.max(0, parseInt(req.query.offset, 10))
        : 0;
    var cursor = jobs.find(query)
        .skip(skip)
        .limit(limit);

    Bluebird.promisify(cursor.toArray, cursor)()
        .catch(function (err) {
            throw Boom.wrap(err, 503, 'Error querying database.');
        })
        .map(stripMongoId)
        .then(res.json.bind(res), next);
});

// Internal handler for updating a job's state
router.post('/:container/:name',
    ensure('params', ['container', 'name']),
    ensure('body', ['criteria', 'updates']),
    function (req, res, next) {
        var data = req.webtaskContext.data;
        var jobs = req.mongo.collection(data.JOB_COLLECTION);
        var query = canonicalizeDates(_.defaults(req.body.criteria, {
           cluster_url: data.cluster_url,
           container: req.params.container,
           name: req.params.name,
        }));
        var updates = { $set: canonicalizeDates(req.body.updates) };

        Bluebird.promisify(jobs.findOneAndUpdate, jobs)(query, updates, {
            returnOriginal: false,
            upsert: true,
        })
            .catch(function (err) {
                throw Boom.wrap(err, 503, 'Error updating database.');
            })
            .get('value')
            .then(function (job) {
                if (!job) {
                    throw Boom.notFound('No such job `' + req.params.name + '`.');
                }

                return job;
            })
            .then(stripMongoId)
            .then(res.json.bind(res), next);
});

// Create or update an existing cron job (idempotent)
router.put('/:container/:name',
    ensure('params', ['container', 'name']),
    ensure('body', ['token', 'schedule']),
    function (req, res, next) {
        var data = req.webtaskContext.data;
        var maxJobsPerContainer = parseInt(data.max_jobs_per_container, 10) || 100;
        var jobs = req.mongo.collection(data.JOB_COLLECTION);
        var now = new Date();
        var tokenData = Jwt.decode(req.body.token, {complete: true});
        var intervalOptions = {};
        var nextAvailableAt;

        if (tokenData.payload.exp) {
            intervalOptions.endDate = new Date(tokenData.payload.exp * 1000);
        }

        if (tokenData.payload.nbf) {
            intervalOptions.currentDate = new Date(tokenData.payload.nbf * 1000);
        }

        try {
            var interval = Cron.parseExpression(req.body.schedule, intervalOptions);
            nextAvailableAt = interval.next();
        } catch (e) {
            return next(Boom.badRequest('Invalid cron expression `'
                + req.body.schedule + '`.', req.body));
        }

        if (!nextAvailableAt) {
            return next(Boom.badRequest('The provided token\'s `nbf` and `exp` '
                + 'claims are such that the job would never run with the '
                + 'schedule `' + req.body.schedule + '`.'));
        }

        var update = {
            $set: {
                state: 'active',
                schedule: req.body.schedule,
                token: req.body.token,
                cluster_url: data.cluster_url,
                container: req.params.container,
                name: req.params.name,
                expires_at: intervalOptions.endDate || null,
                last_scheduled_at: null,
                next_available_at: nextAvailableAt,
                token_data: tokenData.payload,
            },
            $setOnInsert: {
                results: [],
                run_count: 0,
                error_count: 0,
            }
        };

        var countExistingCursor = jobs.find({
            cluster_url: data.cluster_url,
            container: req.params.container,
        });
        var countExisting = Bluebird.promisify(countExistingCursor.count, countExistingCursor)();

        var alreadyExistsCursor = jobs.find({
            cluster_url: data.cluster_url,
            container: req.params.container,
            name: req.params.name,
        });
        var alreadyExists = Bluebird.promisify(alreadyExistsCursor.count, alreadyExistsCursor)();

        Bluebird.all([countExisting, alreadyExists])
            .catch(function (err) {
                throw Boom.wrap(err, 503, 'Error querying database.');
            })
            .then(function (counts) {
                var sameContainerCount = counts[0];
                var exists = !!counts[1];

                if (!exists && sameContainerCount >= maxJobsPerContainer) {
                    throw Boom.badRequest('Unable to schedule more than '
                        + maxJobsPerContainer
                        + ' jobs per container.');
                }

                return Bluebird.promisify(jobs.findOneAndUpdate, jobs)({
                    cluster_url: data.cluster_url,
                    container: req.params.container,
                    name: req.params.name,
                }, update, {
                    returnOriginal: false,
                    upsert: true,
                })
                    .catch(function (err) {
                        throw Boom.wrap(err, 503, 'Error updating database.');
                    })
                    .get('value');
            })
            .then(stripMongoId)
            .then(res.json.bind(res), next);
});

router.get('/:container/:name',
    ensure('params', ['container', 'name']),
    function (req, res, next) {
        var data = req.webtaskContext.data;
        var jobs = req.mongo.collection(data.JOB_COLLECTION);
        var query = {
            cluster_url: data.cluster_url,
            container: req.params.container,
            name: req.params.name,
        };
        var projection = {
            results: { $slice: 1 },
        };

        Bluebird.promisify(jobs.findOne, jobs)(query, projection)
            .catch(function (err) {
                throw Boom.wrap(err, 503, 'Error querying database.');
            })
            .then(function (job) {
                if (!job) {
                    throw Boom.notFound('No such job `' + req.params.name + '`.');
                }

                return job;
            })
            .then(stripMongoId)
            .then(res.json.bind(res), next);
});

router.delete('/:container/:name',
    ensure('params', ['container', 'name']),
    function (req, res, next) {
        var data = req.webtaskContext.data;
        var jobs = req.mongo.collection(data.JOB_COLLECTION);
        var query = {
            cluster_url: data.cluster_url,
            container: req.params.container,
            name: req.params.name,
        };
        var sort = {
            cluster_url: 1,
            container: 1,
            name: 1,
        };

        Bluebird.promisify(jobs.findAndRemove, jobs)(query, sort, {})
            .catch(function (err) {
                console.log(err);
                throw Boom.wrap(err, 503, 'Error querying database.');
            })
            .get('value')
            .then(function (job) {
                if (!job) {
                    throw Boom.notFound('No such job `' + req.params.name + '`.');
                }

                return job;
            })
            .then(respondWith204(res), next);
});

router.get('/:container/:name/history',
    ensure('params', ['container', 'name']),
    function (req, res, next) {
        var data = req.webtaskContext.data;
        var jobs = req.mongo.collection(data.JOB_COLLECTION);
        var query = {
            cluster_url: data.cluster_url,
            container: req.params.container,
            name: req.params.name,
        };

        var limit = req.query.limit
            ? Math.max(0, Math.min(20, parseInt(req.query.limit, 10)))
            : 10;
        var skip = req.query.offset
            ? Math.max(0, parseInt(req.query.offset, 10))
            : 0;
        var projection = {
            results: { $slice: [skip, limit] },
        };

        Bluebird.promisify(jobs.findOne, jobs)(query, projection)
            .catch(function (err) {
                throw Boom.wrap(err, 503, 'Error querying database.');
            })
            .then(function (job) {
                if (!job) {
                    throw Boom.notFound('No such job `' + req.params.name + '`.');
                }

                return job;
            })
            .get('results')
            .map(stripMongoId)
            .then(res.json.bind(res), next);
});

router.post('/:container/:name/history',
    ensure('params', ['container', 'name']),
    ensure('body', ['created_at', 'type', 'headers', 'statusCode', 'body']),
    function (req, res, next) {
        var data = req.webtaskContext.data;
        var jobs = req.mongo.collection(data.JOB_COLLECTION);
        var result = canonicalizeDates(req.body);
        var query = {
            cluster_url: data.cluster_url,
            container: req.params.container,
            name: req.params.name,
        };
        var update = {
            $push: {
                results: {
                    $each: [result],
                    $position: 0, // Push to head of array
                    $slice: 100, // Maximum 100 history entries
                }
            },
            $inc: {
                run_count: +(result.type === 'success'),
                error_count: +(result.type === 'error'),
            }
        }

        Bluebird.promisify(jobs.findOneAndUpdate, jobs)(query, update, {
            returnOriginal: false,
            upsert: true,
        })
            .catch(function (err) {
                throw Boom.wrap(err, 503, 'Error updating database.');
            })
            .get('value')
            .then(function (job) {
                if (!job) {
                    throw Boom.notFound('No such job `' + req.params.name + '`.');
                }

                return job;
            })
            .then(stripMongoId)
            .then(respondWith204(res), next);
});

module.exports = Webtask.fromConnect(app);

// Helper methods

function ensure (source, fields) {
    return function (req, res, next) {
        var data = req[source];

        for (var i in fields) {
            if (!data[fields[i]]) {
                return next(Boom.badRequest('Missing ' + source + 'parameter '
                    + '`' + fields[i] + '`.'));
            }
        }

        next();
    };
}

function canonicalizeDates (obj) {
    if (_.isArray(obj)) return _.map(obj, canonicalizeDates);
    if (_.isObject(obj)) {
        if (obj['$date']) return new Date(obj['$date']);
        else return _.mapValues(obj, canonicalizeDates);
    }
    return obj;
}

function stripMongoId (doc) {
    if (doc) {
        if (doc._id) delete doc._id;
        if (doc.results) doc.results = _.map(doc.results, stripMongoId);
    }

    return doc;
}

function respondWith204 (res) {
    return function () {
        res.status(204).send();
    };
}
<commit_msg>Correct broken mongodb webtask<commit_after>var Boom = require('boom');
var Bluebird = require('bluebird');
var Cron = require('cron-parser');
var Express = require('express');
var Jwt = require('jsonwebtoken');
var Webtask = require('webtask-tools');
var _ = require('lodash');

var app = Express();
var router = Express.Router();
var mongo;

Bluebird.longStackTraces();

// Check for required configuration parameters
app.use(function (req, res, next) {
    var data = req.webtaskContext.data;
    var required = ['JOB_COLLECTION', 'MONGO_URL', 'cluster_url'];

    for (var i in required) {
        var key = required[i];

        if (!data[key]) {
            var err = Boom.badGateway('Cron webtask needs to be configured '
                + 'with the parameter: `' + key + '`.', data);
            return next(err);
        }
    }

    next();
});

// Set up connection to mongodb
app.use(function (req, res, next) {
    // Short-cut if mongo is already setup
    if (mongo) {
        req.mongo = mongo;
        return next();
    }

    var MongoClient = require('mongodb').MongoClient;
    var connect = Bluebird.promisify(MongoClient.connect, MongoClient);
    var data = req.webtaskContext.data;

    return connect(data.MONGO_URL)
        .then(function (db) {
            // Store the settled promise resolving to the db object
            mongo = req.mongo = db;
        })
        .catch(function (err) {
            throw Boom.wrap(err, 503, 'Database unreachable.');
        })
        .nodeify(next);
});

// Parse incoming json bodies
app.use(require('body-parser').json());

app.use(router);

app.use(function(err, req, res, next) {
    console.log(err.message);
    console.log(err.stack);

    if (!err.isBoom) err = Boom.wrap(err);

    res
        .set(err.output.headers)
        .status(err.output.statusCode)
        .json(err.output.payload);
});

router.post('/reserve',
    ensure('query', ['count', 'ttl']),
    function (req, res, next) {
        var data = req.webtaskContext.data;
        var jobs = req.mongo.collection(data.JOB_COLLECTION);
        var count = Math.max(0, Math.min(100, parseInt(req.query.count, 10)));
        var now = new Date();
        var nextAvailableAt = new Date(now.valueOf() + (parseInt(data.ttl, 10) * 1000));

        console.log('attempting to reserve ' + count + ' jobs.');

        Bluebird.map(_.range(count), function (n) {
            var filter = {
                cluster_url: data.cluster_url,
                next_available_at: {
                    $lte: now
                },
                state: 'active',
            };
            var update = {
                $set: {
                    next_available_at: nextAvailableAt
                }
            };
            var options = {
                projection: {
                    results: { $slice: 10 }, // Limit to the 10 last results
                },
                returnOriginal: false, // Return modified
            };

            return Bluebird.promisify(jobs.findOneAndUpdate, jobs)(filter, update, options)
                .get('value'); // Only pull out the value
        })
        // Don't prevent one failure from blocking the entire
        // reservation (that would mean extra waiting on those that
        // didn't fail)
        .settle()
        // Log errors and continue with safe fallback
        .map(function (result) {
            if (result.isRejected()) {
                console.log('error reserving job: ' + result.value().message);
                return null;
            } else {
                return result.value();
            }
        })
        // Elminate error queries and queries that did not match
        // (this is the case when there are fewer than N jobs
        // available for running now)
        .filter(Boolean)
        .tap(function (jobs) {
            console.log('successfully reserved ' + jobs.length + ' job(s).');
        })
        .map(stripMongoId)
        .then(res.json.bind(res), next);
});

router.get('/:container?', function (req, res, next) {
    var data = req.webtaskContext.data;
    var jobs = req.mongo.collection(data.JOB_COLLECTION);
    var query = {
        cluster_url: data.cluster_url,
    };

    // Both admin and user will hit this endpoint. When admin, container can be unset
    if (req.params.container) query.container = req.params.container;

    var limit = req.query.limit
        ? Math.max(0, Math.min(20, parseInt(req.query.limit, 10)))
        : 10;
    var skip = req.query.offset
        ? Math.max(0, parseInt(req.query.offset, 10))
        : 0;
    var cursor = jobs.find(query)
        .skip(skip)
        .limit(limit);

    Bluebird.promisify(cursor.toArray, cursor)()
        .catch(function (err) {
            throw Boom.wrap(err, 503, 'Error querying database.');
        })
        .map(stripMongoId)
        .then(res.json.bind(res), next);
});

// Internal handler for updating a job's state
router.post('/:container/:name',
    ensure('params', ['container', 'name']),
    ensure('body', ['criteria', 'updates']),
    function (req, res, next) {
        var data = req.webtaskContext.data;
        var jobs = req.mongo.collection(data.JOB_COLLECTION);
        var query = canonicalizeDates(_.defaults(req.body.criteria, {
           cluster_url: data.cluster_url,
           container: req.params.container,
           name: req.params.name,
        }));
        var updates = { $set: canonicalizeDates(req.body.updates) };

        Bluebird.promisify(jobs.findOneAndUpdate, jobs)(query, updates, {
            returnOriginal: false,
            upsert: true,
        })
            .catch(function (err) {
                throw Boom.wrap(err, 503, 'Error updating database.');
            })
            .get('value')
            .then(function (job) {
                if (!job) {
                    throw Boom.notFound('No such job `' + req.params.name + '`.');
                }

                return job;
            })
            .then(stripMongoId)
            .then(res.json.bind(res), next);
});

// Create or update an existing cron job (idempotent)
router.put('/:container/:name',
    ensure('params', ['container', 'name']),
    ensure('body', ['token', 'schedule']),
    function (req, res, next) {
        var data = req.webtaskContext.data;
        var maxJobsPerContainer = parseInt(data.max_jobs_per_container, 10) || 100;
        var jobs = req.mongo.collection(data.JOB_COLLECTION);
        var now = new Date();
        var tokenData = Jwt.decode(req.body.token, {complete: true});
        var intervalOptions = {};
        var nextAvailableAt;

        if (tokenData.payload.exp) {
            intervalOptions.endDate = new Date(tokenData.payload.exp * 1000);
        }

        if (tokenData.payload.nbf) {
            intervalOptions.currentDate = new Date(tokenData.payload.nbf * 1000);
        }

        try {
            var interval = Cron.parseExpression(req.body.schedule, intervalOptions);
            nextAvailableAt = interval.next();
        } catch (e) {
            return next(Boom.badRequest('Invalid cron expression `'
                + req.body.schedule + '`.', req.body));
        }

        if (!nextAvailableAt) {
            return next(Boom.badRequest('The provided token\'s `nbf` and `exp` '
                + 'claims are such that the job would never run with the '
                + 'schedule `' + req.body.schedule + '`.'));
        }

        var update = {
            $set: {
                state: 'active',
                schedule: req.body.schedule,
                token: req.body.token,
                cluster_url: data.cluster_url,
                container: req.params.container,
                name: req.params.name,
                expires_at: intervalOptions.endDate || null,
                last_scheduled_at: null,
                next_available_at: nextAvailableAt,
                token_data: tokenData.payload,
            },
            $setOnInsert: {
                results: [],
                run_count: 0,
                error_count: 0,
            }
        };

        var countExistingCursor = jobs.find({
            cluster_url: data.cluster_url,
            container: req.params.container,
        });
        var countExisting = Bluebird.promisify(countExistingCursor.count, countExistingCursor)();

        var alreadyExistsCursor = jobs.find({
            cluster_url: data.cluster_url,
            container: req.params.container,
            name: req.params.name,
        });
        var alreadyExists = Bluebird.promisify(alreadyExistsCursor.count, alreadyExistsCursor)();

        Bluebird.all([countExisting, alreadyExists])
            .catch(function (err) {
                throw Boom.wrap(err, 503, 'Error querying database.');
            })
            .then(function (counts) {
                var sameContainerCount = counts[0];
                var exists = !!counts[1];

                if (!exists && sameContainerCount >= maxJobsPerContainer) {
                    throw Boom.badRequest('Unable to schedule more than '
                        + maxJobsPerContainer
                        + ' jobs per container.');
                }

                return Bluebird.promisify(jobs.findOneAndUpdate, jobs)({
                    cluster_url: data.cluster_url,
                    container: req.params.container,
                    name: req.params.name,
                }, update, {
                    returnOriginal: false,
                    upsert: true,
                })
                    .catch(function (err) {
                        throw Boom.wrap(err, 503, 'Error updating database.');
                    })
                    .get('value');
            })
            .then(stripMongoId)
            .then(res.json.bind(res), next);
});

router.get('/:container/:name',
    ensure('params', ['container', 'name']),
    function (req, res, next) {
        var data = req.webtaskContext.data;
        var jobs = req.mongo.collection(data.JOB_COLLECTION);
        var query = {
            cluster_url: data.cluster_url,
            container: req.params.container,
            name: req.params.name,
        };
        var projection = {
            results: { $slice: 1 },
        };

        Bluebird.promisify(jobs.findOne, jobs)(query, projection)
            .catch(function (err) {
                throw Boom.wrap(err, 503, 'Error querying database.');
            })
            .then(function (job) {
                if (!job) {
                    throw Boom.notFound('No such job `' + req.params.name + '`.');
                }

                return job;
            })
            .then(stripMongoId)
            .then(res.json.bind(res), next);
});

router.delete('/:container/:name',
    ensure('params', ['container', 'name']),
    function (req, res, next) {
        var data = req.webtaskContext.data;
        var jobs = req.mongo.collection(data.JOB_COLLECTION);
        var query = {
            cluster_url: data.cluster_url,
            container: req.params.container,
            name: req.params.name,
        };
        var sort = {
            cluster_url: 1,
            container: 1,
            name: 1,
        };

        Bluebird.promisify(jobs.findAndRemove, jobs)(query, sort, {})
            .catch(function (err) {
                console.log(err);
                throw Boom.wrap(err, 503, 'Error querying database.');
            })
            .get('value')
            .then(function (job) {
                if (!job) {
                    throw Boom.notFound('No such job `' + req.params.name + '`.');
                }

                return job;
            })
            .then(respondWith204(res), next);
});

router.get('/:container/:name/history',
    ensure('params', ['container', 'name']),
    function (req, res, next) {
        var data = req.webtaskContext.data;
        var jobs = req.mongo.collection(data.JOB_COLLECTION);
        var query = {
            cluster_url: data.cluster_url,
            container: req.params.container,
            name: req.params.name,
        };

        var limit = req.query.limit
            ? Math.max(0, Math.min(20, parseInt(req.query.limit, 10)))
            : 10;
        var skip = req.query.offset
            ? Math.max(0, parseInt(req.query.offset, 10))
            : 0;
        var projection = {
            results: { $slice: [skip, limit] },
        };

        Bluebird.promisify(jobs.findOne, jobs)(query, projection)
            .catch(function (err) {
                throw Boom.wrap(err, 503, 'Error querying database.');
            })
            .then(function (job) {
                if (!job) {
                    throw Boom.notFound('No such job `' + req.params.name + '`.');
                }

                return job;
            })
            .get('results')
            .map(stripMongoId)
            .then(res.json.bind(res), next);
});

router.post('/:container/:name/history',
    ensure('params', ['container', 'name']),
    ensure('body', ['created_at', 'type', 'headers', 'statusCode', 'body']),
    function (req, res, next) {
        var data = req.webtaskContext.data;
        var jobs = req.mongo.collection(data.JOB_COLLECTION);
        var result = canonicalizeDates(req.body);
        var query = {
            cluster_url: data.cluster_url,
            container: req.params.container,
            name: req.params.name,
        };
        var update = {
            $push: {
                results: {
                    $each: [result],
                    $position: 0, // Push to head of array
                    $slice: 100, // Maximum 100 history entries
                }
            },
            $inc: {
                run_count: +(result.type === 'success'),
                error_count: +(result.type === 'error'),
            }
        }

        Bluebird.promisify(jobs.findOneAndUpdate, jobs)(query, update, {
            returnOriginal: false,
            upsert: true,
        })
            .catch(function (err) {
                throw Boom.wrap(err, 503, 'Error updating database.');
            })
            .get('value')
            .then(function (job) {
                if (!job) {
                    throw Boom.notFound('No such job `' + req.params.name + '`.');
                }

                return job;
            })
            .then(stripMongoId)
            .then(respondWith204(res), next);
});

module.exports = Webtask.fromConnect(app);

// Helper methods

function ensure (source, fields) {
    return function (req, res, next) {
        var data = req[source];

        for (var i in fields) {
            if (!data[fields[i]]) {
                return next(Boom.badRequest('Missing ' + source + 'parameter '
                    + '`' + fields[i] + '`.'));
            }
        }

        next();
    };
}

function canonicalizeDates (obj) {
    if (_.isArray(obj)) return _.map(obj, canonicalizeDates);
    if (_.isObject(obj)) {
        if (obj['$date']) return new Date(obj['$date']);
        else return _.mapValues(obj, canonicalizeDates);
    }
    return obj;
}

function stripMongoId (doc) {
    if (doc) {
        if (doc._id) delete doc._id;
        if (doc.results) doc.results = _.map(doc.results, stripMongoId);
    }

    return doc;
}

function respondWith204 (res) {
    return function () {
        res.status(204).send();
    };
}
<|endoftext|>


<commit_before>const { existsSync } = require('fs');
const { Mixin } = require('hops-mixin');
const { join } = require('path');
const strip = require('strip-indent');

class GraphQLMixin extends Mixin {
  constructor(config, ...args) {
    super(config, ...args);
  }

  configureBuild(webpackConfig, loaderConfigs) {
    const { allLoaderConfigs } = loaderConfigs;

    if (
      !allLoaderConfigs.find(({ loader }) => loader === 'graphql-tag/loader')
    ) {
      allLoaderConfigs.splice(allLoaderConfigs.length - 1, 0, {
        test: /\.(graphql|gql)$/,
        loader: 'graphql-tag/loader',
      });
    }
  }

  registerCommands(yargs) {
    yargs.command('graphql', 'Execute GraphQL specific tasks', (yargs) =>
      yargs
        .usage('Usage: hops graphql <command>')
        .command({
          command: 'introspect',
          describe: 'Fetches GraphQL schema information for introspection',
          builder: {
            header: {
              alias: 'H',
              type: 'array',
              default: [],
              describe: strip(`
                Additional HTTP headers to be used when executing the schema
                introspection on the remote server. Specify this multiple
                times to add more headers.\nFormat: "Header: Value"
              `),
            },
          },
          handler: (argv) => {
            require('./lib/fragments')({
              graphqlUri: this.config.graphqlUri,
              schemaFile: this.config.graphqlSchemaFile,
              fragmentsFile: this.config.fragmentsFile,
              headers: argv.header,
            })
              .then(() => {
                if (typeof this.getLogger === 'function') {
                  this.getLogger().info('Fetched and saved GraphQL fragments');
                }
              })
              .catch((err) => {
                if (typeof this.getLogger === 'function') {
                  this.getLogger().error('Could not fetch GraphQL fragments:');
                  this.getLogger().error(err);
                }
              });
          },
        })
        .help('help')
        .alias('h', 'help')
        .demandCommand()
    );
  }

  handleArguments(argv) {
    this.options = { ...this.options, ...argv };
  }

  diagnose({ detectDuplicatePackages, pushWarning, pushError }) {
    detectDuplicatePackages('graphql');
    if (!existsSync(this.config.fragmentsFile)) {
      pushWarning(
        `Could not find a graphql introspection query result at "${this.config.fragmentsFile}".`
      );
      pushWarning('You might need to execute "hops graphql introspect"');
    }

    const manifestPath = join(this.config.rootDir, 'package.json');
    const manifest = require(manifestPath);
    const hasReactApollo = [
      ...Object.keys(manifest.dependencies || {}),
      ...Object.keys(manifest.devDependencies || {}),
    ].includes('react-apollo');
    const hasApolloClient = [
      ...Object.keys(manifest.dependencies || {}),
      ...Object.keys(manifest.devDependencies || {}),
    ].includes('@apollo/client');

    if (hasReactApollo && hasApolloClient) {
      pushError(
        'apollo-version-mismatch',
        `
Found two conflicting versions of apollo (react-apollo and @apollo/client) in "${manifestPath}".
- If you want to use Apollo v2 you need to remove "@apollo/client"
- Otherwise, if you want to use Apollo v3, remove "react-apollo"
`.trim()
      );
    }
  }
}

module.exports = GraphQLMixin;
<commit_msg>chore: remove mixed apollo versions warning<commit_after>const { existsSync } = require('fs');
const { Mixin } = require('hops-mixin');
const strip = require('strip-indent');

class GraphQLMixin extends Mixin {
  constructor(config, ...args) {
    super(config, ...args);
  }

  configureBuild(webpackConfig, loaderConfigs) {
    const { allLoaderConfigs } = loaderConfigs;

    if (
      !allLoaderConfigs.find(({ loader }) => loader === 'graphql-tag/loader')
    ) {
      allLoaderConfigs.splice(allLoaderConfigs.length - 1, 0, {
        test: /\.(graphql|gql)$/,
        loader: 'graphql-tag/loader',
      });
    }
  }

  registerCommands(yargs) {
    yargs.command('graphql', 'Execute GraphQL specific tasks', (yargs) =>
      yargs
        .usage('Usage: hops graphql <command>')
        .command({
          command: 'introspect',
          describe: 'Fetches GraphQL schema information for introspection',
          builder: {
            header: {
              alias: 'H',
              type: 'array',
              default: [],
              describe: strip(`
                Additional HTTP headers to be used when executing the schema
                introspection on the remote server. Specify this multiple
                times to add more headers.\nFormat: "Header: Value"
              `),
            },
          },
          handler: (argv) => {
            require('./lib/fragments')({
              graphqlUri: this.config.graphqlUri,
              schemaFile: this.config.graphqlSchemaFile,
              fragmentsFile: this.config.fragmentsFile,
              headers: argv.header,
            })
              .then(() => {
                if (typeof this.getLogger === 'function') {
                  this.getLogger().info('Fetched and saved GraphQL fragments');
                }
              })
              .catch((err) => {
                if (typeof this.getLogger === 'function') {
                  this.getLogger().error('Could not fetch GraphQL fragments:');
                  this.getLogger().error(err);
                }
              });
          },
        })
        .help('help')
        .alias('h', 'help')
        .demandCommand()
    );
  }

  handleArguments(argv) {
    this.options = { ...this.options, ...argv };
  }

  diagnose({ detectDuplicatePackages, pushWarning }) {
    detectDuplicatePackages('graphql');
    if (!existsSync(this.config.fragmentsFile)) {
      pushWarning(
        `Could not find a graphql introspection query result at "${this.config.fragmentsFile}".`
      );
      pushWarning('You might need to execute "hops graphql introspect"');
    }
  }
}

module.exports = GraphQLMixin;
<|endoftext|>


<commit_before>ManageIQ.angular.app.controller('networkRouterFormController', ['$http', '$scope', 'networkRouterFormId', 'miqService', function($http, $scope, networkRouterFormId, miqService) {
  $scope.networkRouterModel = { name: '' };
  $scope.formId = networkRouterFormId;
  $scope.afterGet = false;
  $scope.modelCopy = angular.copy( $scope.networkRouterModel );
  $scope.model = "networkRouterModel";

  ManageIQ.angular.scope = $scope;

  if (networkRouterFormId == 'new') {
    $scope.networkRouterModel.name = "";
    $scope.newRecord = true;
  } else {
    miqService.sparkleOn();

    $http.get('/network_router/network_router_form_fields/' + networkRouterFormId).success(function(data) {
      $scope.afterGet = true;
      $scope.networkRouterModel.name = data.name;

      $scope.modelCopy = angular.copy( $scope.networkRouterModel );
      miqService.sparkleOff();
    });
  }

  $scope.addClicked = function() {
    var url = 'create/new' + '?button=add';
    miqService.miqAjaxButton(url, $scope.networkRouterModel, { complete: false });
  };

  $scope.cancelClicked = function() {
    if (networkRouterFormId == 'new') {
      var url = '/network_router/create/new' + '?button=cancel';
    } else {
      var url = '/network_router/update/' + networkRouterFormId + '?button=cancel';
    }
    miqService.miqAjaxButton(url, true);
  };

  $scope.saveClicked = function() {
    var url = '/network_router/update/' + networkRouterFormId + '?button=save';
    miqService.miqAjaxButton(url, $scope.networkRouterModel, { complete: false });
  };

  $scope.resetClicked = function() {
    $scope.networkRouterModel = angular.copy( $scope.modelCopy );
    $scope.angularForm.$setPristine(true);
    miqService.miqFlash("warn", "All changes have been reset");
  };

  $scope.filterNetworkManagerChanged = function(id) {
    miqService.sparkleOn();
    $http.get('/network_router/network_router_networks_by_ems/' + id).success(function(data) {
      $scope.available_networks = data.available_networks;
      miqService.sparkleOff();
    });
  };
}]);
<commit_msg>Network Router: Fix angular controller<commit_after>ManageIQ.angular.app.controller('networkRouterFormController', ['$http', '$scope', 'networkRouterFormId', 'miqService', function($http, $scope, networkRouterFormId, miqService) {
  $scope.networkRouterModel = { name: '' };
  $scope.formId = networkRouterFormId;
  $scope.afterGet = false;
  $scope.modelCopy = angular.copy( $scope.networkRouterModel );
  $scope.model = "networkRouterModel";

  ManageIQ.angular.scope = $scope;

  if (networkRouterFormId == 'new') {
    $scope.networkRouterModel.name = "";
    $scope.newRecord = true;
  } else {
    miqService.sparkleOn();

    $http.get('/network_router/network_router_form_fields/' + networkRouterFormId).success(function(data) {
      $scope.afterGet = true;
      $scope.networkRouterModel.name = data.name;

      $scope.modelCopy = angular.copy( $scope.networkRouterModel );
      miqService.sparkleOff();
    });
  }

  $scope.addClicked = function() {
    var url = 'create/new' + '?button=add';
    miqService.miqAjaxButton(url, $scope.networkRouterModel, { complete: false });
  };

  $scope.cancelClicked = function() {
    if (networkRouterFormId == 'new') {
      var url = '/network_router/create/new' + '?button=cancel';
    } else {
      var url = '/network_router/update/' + networkRouterFormId + '?button=cancel';
    }
    miqService.miqAjaxButton(url);
  };

  $scope.saveClicked = function() {
    var url = '/network_router/update/' + networkRouterFormId + '?button=save';
    miqService.miqAjaxButton(url, $scope.networkRouterModel, { complete: false });
  };

  $scope.resetClicked = function() {
    $scope.networkRouterModel = angular.copy( $scope.modelCopy );
    $scope.angularForm.$setPristine(true);
    miqService.miqFlash("warn", "All changes have been reset");
  };

  $scope.filterNetworkManagerChanged = function(id) {
    miqService.sparkleOn();
    $http.get('/network_router/network_router_networks_by_ems/' + id).success(function(data) {
      $scope.available_networks = data.available_networks;
      miqService.sparkleOff();
    });
  };
}]);
<|endoftext|>


<commit_before>if (document.location.hostname == "localhost") {
    var baseurl = "";
} else {
    var baseurl = "https://noconfidencevote.openup.org.za";
}

var agent = navigator.userAgent.toLowerCase();
if (agent.includes("mobile") && agent.includes("android")) {
  document.write('

');
} else {
  document.write('

');
}
document.write('');

document.write("");
<commit_msg>Try to force iframe height for news24 app<commit_after>if (document.location.hostname == "localhost") {
    var baseurl = "";
} else {
    var baseurl = "https://noconfidencevote.openup.org.za";
}

var agent = navigator.userAgent.toLowerCase();
if (agent.includes("mobile") && agent.includes("android")) {
  // addEventListener only available in later chrome versions
  window.addEventListener("load",function(){
    document.getElementById("contactmps-embed-parent").children[0].setAttribute("style", "height: 3000px");
  });
  document.write('

');
} else {
  document.write('

');
}
document.write('');

document.write("");
<|endoftext|>


<commit_before>
var window = window || {};
var self = self || {};

// High-resulution counter: emulate window.performance.now() for THREE.CLOCK
if( window.performance === undefined ) {

	window.performance = { };

}

if( ( window.performance.now === undefined ) && ( process !== undefined ) && ( process.hrtime !== undefined ) ) {

	window.performance.now = function () {

		var time = process.hrtime();
		return ( time[0] + time[1] / 1e9 ) * 1000;

	};

}
<commit_msg>use new Date().getTime() when not in a node.js environment.<commit_after>
var window = window || {};
var self = self || {};

// High-resulution counter: emulate window.performance.now() for THREE.CLOCK
if( window.performance === undefined ) {

	window.performance = { };

}

if( window.performance.now === undefined ) {

	// check if we are in a Node.js environment
	if( ( process !== undefined ) && ( process.hrtime !== undefined ) ) {

		window.performance.now = function () {

			var time = process.hrtime();
			return ( time[0] + time[1] / 1e9 ) * 1000;

		};

	}
	// if not Node.js revert to using the Date class
	else {

		window.performance.now = function() {

			return new Date().getTime();

		};

	}

}
<|endoftext|>


<commit_before>/*
 * Copyrights phwang
 * Written by Paul Hwang
 * File name: go_cluster_module.js
 */

module.exports = {
    malloc: function (cluster_mgr_val, topic_data_val, session_val) {
        return new clusterObject(cluster_mgr_val, topic_data_val, session_val);
    },
};

function clusterObject (cluster_mgr_val, topic_data_val, session_val) {
    "use strict";

    this.init__ = function (cluster_mgr_val, topic_data_val, session_val) {
        this.theClusterMgrObject = cluster_mgr_val;
        session_val.setClusterObject(this);
        this.theSessionArray = [2];
        this.theSessionArray[0] = session_val;
        this.theSessionArrayLength = 1;
        this.theReceiveQueue = this.rootObject().mallocQueue();
        this.theTransmitQueue = this.rootObject().mallocQueue();
        this.theNext = null;
        this.thePrev = null;
        this.theTopicBaseId = 0;
        this.createTopic(topic_data_val);
        this.debug(false, "init__", "topic=" + this.topicObject().objectName());
    };

    this.goObjectMalloc = function () {
        var go_module = require("./../go_modules/go_base.js")
        return go_module.malloc(this);
    },

    this.objectName = function () {
        return "clusterObject";
    };

    this.sessionObject = function () {
        return this.sessionArray(0);
    };

    this.clusterMgrObject = function () {
        return this.theClusterMgrObject;
    };

    this.rootObject = function () {
        return this.clusterMgrObject().rootObject();
    };

    this.fabricObject = function () {
        return this.clusterMgrObject().fabricObject();
    };

    this.utilObject = function () {
        return this.clusterMgrObject().utilObject();
    };

    this.topicObject = function () {
        return this.theTopicObject;
    };

    this.setTopicObject = function (val) {
        this.theTopicObject = val;
    };

    this.sessionArray = function (index_val) {
        return this.theSessionArray[index_val];
    };

    this.sessionArrayLength = function () {
        return this.theSessionArrayLength;
    };

    this.incrementSessionArrayLength = function () {
        this.theSessionArrayLength += 1;
    };

    this.prev = function () {
        return this.thePrev;
    };

    this.setPrev = function (val) {
        this.thePrev = val;
    };

    this.next = function () {
        return this.theNext;
    };

    this.setNext = function (val) {
        this.theNext = val;
    };

    this.topicBaseId = function () {
        return this.theTopicBaseId;
    };

    this.setTopicBaseId = function (val) {
        this.theTopicBaseId = val;
    };

    this.receiveQueue = function () {
        return this.theReceiveQueue;
    };

    this.transmitQueue = function () {
        return this.theTransmitQueue;
    };

    this.createTopic = function (topic_data_val) {
        var topic_data = JSON.parse(topic_data_val);
        if (topic_data.title === "go") {
            this.setTopicObject(this.goObjectMalloc());
            this.setTopicBaseId(this.rootObject().topicMallocBase());
            this.debug(false, "createTopic", "base_id=" + this.topicBaseId());
        }
    };

    this.addAdditionalSession = function (session_val) {
        this.theSessionArray[this.sessionArrayLength()] = session_val;
        this.incrementSessionArrayLength();
    };

    this.enqueueTransmitData = function (data_val) {
        this.debug(false, "enqueueTransmitData", data_val);
        this.transmitQueue().enQueue(data_val);
    };

    this.dequeueTransmitData = function () {
        var data = this.transmitQueue().deQueue();
        this.debug(false, "dequeueTransmitData", data);
        return data;
    };

    this.enqueueReceiveData = function (data_val) {
        this.debug(false, "enqueueReceiveData", data_val);
        this.receiveQueue().enQueue(data_val);
    };

    this.dequeueReceiveData = function () {
        var data = this.receiveQueue().deQueue();
        this.debug(false, "dequeueReceiveData", data);
        return data;
    };

    this.processTransmitData = function () {
        while (true) {
            var data = this.dequeueTransmitData();
            if (!data) {
                return;
            }

            var i = 0;
            while (i < this.sessionArrayLength()) {
                this.sessionArray(i).enqueueTransmitData(data);
                i += 1;
            }
        }
    };

    this.processSetupTopicData = function (json_data_val) {
        this.debug(true, "processSetupTopicData", "data=" + json_data_val);
        var topic_data = JSON.parse(json_data_val);
        if (topic_data.command === "config") {
            this.topicObject().configObject().createConfig(topic_data.data);
        }
    };

    this.processReceiveData = function () {
        while (true) {
            var data = this.dequeueReceiveData();
            if (!data) {
                return;
            }
            this.receiveStringData(data);
            this.rootObject().topicReceiveData(this.topicBaseId());
            var data = this.rootObject().topicTransmitData(this.topicBaseId());
            this.debug(true, "processReceiveData", "data=" + data);
        }
    };

    this.enqueAndPocessReceiveData = function (data_val) {
        this.debug(false, "enqueAndPocessReceiveData", data_val);
        this.enqueueReceiveData(data_val);
        this.processReceiveData();
    };

    this.receiveStringData = function (str_val) {
        this.topicObject().portObject().receiveStringData(str_val);

    };

    this.debug = function (debug_val, str1_val, str2_val) {
        if (debug_val) {
            this.logit(str1_val, str2_val);
        }
    };

    this.logit = function (str1_val, str2_val) {
        this.rootObject().LOG_IT(this.objectName() + "." + str1_val, str2_val);
    };

    this.abend = function (str1_val, str2_val) {
        this.rootObject().ABEND(this.objectName() + "." + str1_val, str2_val);
    };

    this.init__(cluster_mgr_val, topic_data_val, session_val);
}
<commit_msg>receive<commit_after>/*
 * Copyrights phwang
 * Written by Paul Hwang
 * File name: go_cluster_module.js
 */

module.exports = {
    malloc: function (cluster_mgr_val, topic_data_val, session_val) {
        return new clusterObject(cluster_mgr_val, topic_data_val, session_val);
    },
};

function clusterObject (cluster_mgr_val, topic_data_val, session_val) {
    "use strict";

    this.init__ = function (cluster_mgr_val, topic_data_val, session_val) {
        this.theClusterMgrObject = cluster_mgr_val;
        session_val.setClusterObject(this);
        this.theSessionArray = [2];
        this.theSessionArray[0] = session_val;
        this.theSessionArrayLength = 1;
        this.theReceiveQueue = this.rootObject().mallocQueue();
        this.theTransmitQueue = this.rootObject().mallocQueue();
        this.theNext = null;
        this.thePrev = null;
        this.theTopicBaseId = 0;
        this.createTopic(topic_data_val);
        this.debug(false, "init__", "topic=" + this.topicObject().objectName());
    };

    this.goObjectMalloc = function () {
        var go_module = require("./../go_modules/go_base.js")
        return go_module.malloc(this);
    },

    this.objectName = function () {
        return "clusterObject";
    };

    this.sessionObject = function () {
        return this.sessionArray(0);
    };

    this.clusterMgrObject = function () {
        return this.theClusterMgrObject;
    };

    this.rootObject = function () {
        return this.clusterMgrObject().rootObject();
    };

    this.fabricObject = function () {
        return this.clusterMgrObject().fabricObject();
    };

    this.utilObject = function () {
        return this.clusterMgrObject().utilObject();
    };

    this.topicObject = function () {
        return this.theTopicObject;
    };

    this.setTopicObject = function (val) {
        this.theTopicObject = val;
    };

    this.sessionArray = function (index_val) {
        return this.theSessionArray[index_val];
    };

    this.sessionArrayLength = function () {
        return this.theSessionArrayLength;
    };

    this.incrementSessionArrayLength = function () {
        this.theSessionArrayLength += 1;
    };

    this.prev = function () {
        return this.thePrev;
    };

    this.setPrev = function (val) {
        this.thePrev = val;
    };

    this.next = function () {
        return this.theNext;
    };

    this.setNext = function (val) {
        this.theNext = val;
    };

    this.topicBaseId = function () {
        return this.theTopicBaseId;
    };

    this.setTopicBaseId = function (val) {
        this.theTopicBaseId = val;
    };

    this.receiveQueue = function () {
        return this.theReceiveQueue;
    };

    this.transmitQueue = function () {
        return this.theTransmitQueue;
    };

    this.createTopic = function (topic_data_val) {
        var topic_data = JSON.parse(topic_data_val);
        if (topic_data.title === "go") {
            this.setTopicObject(this.goObjectMalloc());
            this.setTopicBaseId(this.rootObject().topicMallocBase());
            this.debug(false, "createTopic", "base_id=" + this.topicBaseId());
        }
    };

    this.addAdditionalSession = function (session_val) {
        this.theSessionArray[this.sessionArrayLength()] = session_val;
        this.incrementSessionArrayLength();
    };

    this.enqueueTransmitData = function (data_val) {
        this.debug(false, "enqueueTransmitData", data_val);
        this.transmitQueue().enQueue(data_val);
    };

    this.dequeueTransmitData = function () {
        var data = this.transmitQueue().deQueue();
        this.debug(false, "dequeueTransmitData", data);
        return data;
    };

    this.enqueueReceiveData = function (data_val) {
        this.debug(false, "enqueueReceiveData", data_val);
        this.receiveQueue().enQueue(data_val);
    };

    this.dequeueReceiveData = function () {
        var data = this.receiveQueue().deQueue();
        this.debug(false, "dequeueReceiveData", data);
        return data;
    };

    this.processTransmitData = function () {
        while (true) {
            var data = this.dequeueTransmitData();
            if (!data) {
                return;
            }

            var i = 0;
            while (i < this.sessionArrayLength()) {
                this.sessionArray(i).enqueueTransmitData(data);
                i += 1;
            }
        }
    };

    this.processSetupTopicData = function (json_data_val) {
        this.debug(true, "processSetupTopicData", "data=" + json_data_val);
        var topic_data = JSON.parse(json_data_val);
        if (topic_data.command === "config") {
            this.topicObject().configObject().createConfig(topic_data.data);
        }
    };

    this.processReceiveData = function () {
        while (true) {
            var data = this.dequeueReceiveData();
            if (!data) {
                return;
            }
            this.receiveStringData(data);
        }
    };

    this.enqueAndPocessReceiveData = function (data_val) {
        this.debug(false, "enqueAndPocessReceiveData", data_val);
        this.enqueueReceiveData(data_val);
        this.processReceiveData();
    };

    this.receiveStringData = function (str_val) {
        this.topicObject().portObject().receiveStringData(str_val);

        this.rootObject().topicReceiveData(this.topicBaseId());
        var data = this.rootObject().topicTransmitData(this.topicBaseId());
        this.debug(true, "processReceiveData", "data=" + data);
    };

    this.debug = function (debug_val, str1_val, str2_val) {
        if (debug_val) {
            this.logit(str1_val, str2_val);
        }
    };

    this.logit = function (str1_val, str2_val) {
        this.rootObject().LOG_IT(this.objectName() + "." + str1_val, str2_val);
    };

    this.abend = function (str1_val, str2_val) {
        this.rootObject().ABEND(this.objectName() + "." + str1_val, str2_val);
    };

    this.init__(cluster_mgr_val, topic_data_val, session_val);
}
<|endoftext|>


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

window.onload = function()
{
    if( !window.__bridje ) window.__bridje = {};
    const findForm = function(element)
    {
        let node = element;
        while (node.nodeName !== 'FORM' && node.parentNode)
        {
            node = node.parentNode;
        }
        return node.nodeName === 'FORM' ? node : null;
    };

    const ajax = function(data)
    {
        window.console && console.log('executing bridje action: ');
        window.console && console.log('      view: ' + data.view);
        window.console && console.log('      enctype: ' + data.enctype);
        window.console && console.log('      event: ' + data.event);
        let dataStr = data.sendData;
        if (typeof(dataStr) !== 'string' && typeof(dataStr.entries) === 'function')
        {
            dataStr = [...dataStr.entries()]
                      .map(e => encodeURIComponent(e[0]) + "=" + encodeURIComponent(e[1]));
        }
        window.console && console.log('      data: ' + dataStr);
        window.console && console.log('      form: ' + data.formId);
        window.console && console.log('      container: ' + data.containerId);
        window.console && console.log('      state: ' + window.__bridje.info.currState);

        try
        {
            let xhr = new XMLHttpRequest();
            xhr.open(data.method, window.location, true);
            if(data.isUrlEncoded) xhr.setRequestHeader('Content-type', data.enctype);
            xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
            xhr.setRequestHeader('Bridje-View', encodeURI(data.view));
            xhr.setRequestHeader('Bridje-Form', data.formId);
            xhr.setRequestHeader('Bridje-Container', data.containerId);
            xhr.setRequestHeader('Bridje-State', window.__bridje.info.currState);

            xhr.onload = function()
            {
                if (xhr.status === 200)
                {
                    window.__bridje.info.currState = xhr.getResponseHeader('Bridje-State') || '';
                    const location = xhr.getResponseHeader('Bridje-Location');
                    if(location && (typeof(location) === 'string'))
                    {
                        window.location = location;
                    }
                    else
                    {
                        let renderEl = document.getElementById(data.containerId);
                        if (renderEl) renderEl.outerHTML = xhr.responseText;
                        renderEl = document.getElementById(data.containerId);
                        if (renderEl)
                        {
                            initialize(renderEl);
                            window.__bridje.inAction = false;
                            window.__bridje.callback && window.__bridje.callback(renderEl, data);
                        }
                    }
                }
                else
                {
                    window.console && console.error('Request failed. Status: ' + xhr.status);
                }
                window.__bridje.inAction = false;
                removeElementActionClass(data.eventEl);
            };
            xhr.send(data.sendData);
        }
        catch (e)
        {
            window.console && console.error(e);
            window.__bridje.inAction = false;
            removeElementActionClass(data.eventEl);
        }
    };

    const execute = function(eventEl)
    {
        if (window.__bridje.inAction)
        {
            return;
        }

        window.__bridje.inAction = true;
        const form = findForm(eventEl);
        if (!form) return;

        addElementActionClass(eventEl);

        const eventId = eventEl.getAttribute('data-eventid');
        const eventInput = document.getElementById(eventId);
        let eventName = '';
        if (eventInput)
        {
            eventName = eventInput.getAttribute('name');
            eventInput.setAttribute("value", "t");
        }

        let enctype = form.getAttribute('enctype') || window.__bridje.info.enctype;
        let view = form.getAttribute('data-bridje-view') || window.__bridje.info.dataBridjeView;
        let sendData = new FormData(form);
        let method = form.getAttribute('method') || 'post';

        let isUrlEncoded = enctype === 'application/x-www-form-urlencoded';
        if(isUrlEncoded)
        {
            let params = new URLSearchParams();
            for(let pair of sendData.entries())
            {
                if(typeof(pair[1]) === 'string')
                {
                    params.append(pair[0], pair[1]);
                }
            }
            sendData = params.toString();
        }
        let containerId = form.getAttribute('data-container')
        if(!containerId) containerId = form.id;
        ajax({
            view: view,
            enctype: enctype,
            event: eventName,
            method: method,
            isUrlEncoded: isUrlEncoded,
            formId: form.id,
            containerId: containerId,
            sendData: sendData,
            eventEl: eventEl
        });
    };
    window.__bridje.execute = function(element)
    {
        execute(element);
    };

    const refresh = function(container)
    {
        if (window.__bridje.inAction)
        {
            return;
        }

        window.__bridje.inAction = true;
        let enctype = 'application/x-www-form-urlencoded';
        let method = 'post';
        let containerId = container.id;
        ajax({
            view: window.__bridje.info.dataBridjeView,
            enctype: enctype,
            event: '',
            method: method,
            isUrlEncoded: true,
            formId: '',
            containerId: containerId,
            sendData: '',
            eventEl: container
        });
    };
    window.__bridje.refresh = function(element)
    {
        refresh(element);
    };

    const removeElementActionClass = function(element)
    {
        const actionClass = element.getAttribute('data-action-class');
        if (actionClass)
        {
            const regex = new RegExp('\\b' + actionClass + '\\b','g')
            element.className.replace(regex, "");
        }
    };

    const addElementActionClass = function(element)
    {
        const actionClass = element.getAttribute('data-action-class');
        if (actionClass)
        {
            const clsArr = element.className.split(" ");
            if (clsArr.indexOf(actionClass) < 0)
            {
                element.className += " " + name;
            }
        }
    };

    const initialize = function(element)
    {
        let actions = element.getElementsByClassName('bridje-action-click');
        for (let i = 0; i < actions.length; i++)
        {
            const action = actions[i];
            if (findForm(action))
            {
                const eventId = action.getAttribute('data-eventid');
                const eventInput = document.getElementById(eventId);
                if (eventInput)
                {
                    action.onclick = function(e)
                    {
                        e && e.preventDefault();
                        execute(action);
                    };
                }
            }
        }

        actions = element.getElementsByClassName('bridje-action-change');
        for (let i = 0; i < actions.length; i++)
        {
            const action = actions[i];
            if (findForm(action))
            {
                const eventId = action.getAttribute('data-eventid');
                const eventInput = document.getElementById(eventId);
                if (eventInput)
                {
                    action.onchange = function(e)
                    {
                        e && e.preventDefault();
                        execute(action);
                    };
                }
            }
        }

        actions = element.getElementsByClassName('bridje-action-enter');
        for (let i = 0; i < actions.length; i++)
        {
            const action = actions[i];
            if (findForm(action))
            {
                const eventId = action.getAttribute('data-eventid');
                const eventInput = document.getElementById(eventId);
                if (eventInput)
                {
                    action.onkeypress = function(e)
                    {
                        if(e)
                        {
                            if (e.which == 13 || e.keyCode == 13)
                            {
                                e.preventDefault();
                                execute(action);
                            }
                        }
                    };
                }
            }
        }
    };

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

window.onload = function()
{
    if( !window.__bridje ) window.__bridje = {};
    const findForm = function(element)
    {
        let node = element;
        while (node.nodeName !== 'FORM' && node.parentNode)
        {
            node = node.parentNode;
        }
        return node.nodeName === 'FORM' ? node : null;
    };

    const ajax = function(data)
    {
        window.console && console.log('executing bridje action: ');
        window.console && console.log('      view: ' + data.view);
        window.console && console.log('      enctype: ' + data.enctype);
        window.console && console.log('      event: ' + data.event);
        let dataStr = data.sendData;
        if (typeof(dataStr) !== 'string' && typeof(dataStr.entries) === 'function')
        {
            dataStr = [...dataStr.entries()]
                      .map(e => encodeURIComponent(e[0]) + "=" + encodeURIComponent(e[1]));
        }
        window.console && console.log('      data: ' + dataStr);
        window.console && console.log('      form: ' + data.formId);
        window.console && console.log('      container: ' + data.containerId);
        window.console && console.log('      state: ' + window.__bridje.info.currState);

        try
        {
            let xhr = new XMLHttpRequest();
            xhr.open(data.method, window.location, true);
            if(data.isUrlEncoded) xhr.setRequestHeader('Content-type', data.enctype);
            xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
            xhr.setRequestHeader('Bridje-View', encodeURI(data.view));
            xhr.setRequestHeader('Bridje-Form', data.formId);
            xhr.setRequestHeader('Bridje-Container', data.containerId);
            xhr.setRequestHeader('Bridje-State', window.__bridje.info.currState);

            xhr.onload = function()
            {
                if (xhr.status === 200)
                {
                    window.__bridje.info.currState = xhr.getResponseHeader('Bridje-State') || '';
                    const location = xhr.getResponseHeader('Bridje-Location');
                    if(location && (typeof(location) === 'string'))
                    {
                        window.location = location;
                    }
                    else
                    {
                        let renderEl = document.getElementById(data.containerId);
                        if (renderEl) renderEl.outerHTML = xhr.responseText;
                        renderEl = document.getElementById(data.containerId);
                        if (renderEl)
                        {
                            initialize(renderEl);
                            window.__bridje.inAction = false;
                            window.__bridje.callback && window.__bridje.callback(renderEl, data);
                        }
                    }
                }
                else
                {
                    window.console && console.error('Request failed. Status: ' + xhr.status);
                }
                window.__bridje.inAction = false;
                removeElementActionClass(data.eventEl);
            };
            xhr.send(data.sendData);
        }
        catch (e)
        {
            window.console && console.error(e);
            window.__bridje.inAction = false;
            removeElementActionClass(data.eventEl);
        }
    };

    const execute = function(eventEl)
    {
        if (window.__bridje.inAction)
        {
            return;
        }

        window.__bridje.inAction = true;
        const form = findForm(eventEl);
        if (!form) return;

        addElementActionClass(eventEl);

        const eventId = eventEl.getAttribute('data-eventid');
        const eventInput = document.getElementById(eventId);
        let eventName = '';
        if (eventInput)
        {
            eventName = eventInput.getAttribute('name');
            eventInput.setAttribute("value", "t");
        }

        let enctype = form.getAttribute('enctype') || window.__bridje.info.enctype;
        let view = form.getAttribute('data-bridje-view') || window.__bridje.info.dataBridjeView;
        let sendData = new FormData(form);
        let method = form.getAttribute('method') || 'post';

        let isUrlEncoded = enctype === 'application/x-www-form-urlencoded';
        if(isUrlEncoded)
        {
            let params = "";
            for(let pair of sendData.entries())
            {
                if(typeof(pair[1]) === 'string')
                {
                    if (params.length > 0) { params += "&"; }
                    params += pair[0] + "=" + pair[1];
                }
            }
            sendData = params;
        }
        let containerId = form.getAttribute('data-container')
        if(!containerId) containerId = form.id;
        ajax({
            view: view,
            enctype: enctype,
            event: eventName,
            method: method,
            isUrlEncoded: isUrlEncoded,
            formId: form.id,
            containerId: containerId,
            sendData: sendData,
            eventEl: eventEl
        });
    };
    window.__bridje.execute = function(element)
    {
        execute(element);
    };

    const refresh = function(container)
    {
        if (window.__bridje.inAction)
        {
            return;
        }

        window.__bridje.inAction = true;
        let enctype = 'application/x-www-form-urlencoded';
        let method = 'post';
        let containerId = container.id;
        ajax({
            view: window.__bridje.info.dataBridjeView,
            enctype: enctype,
            event: '',
            method: method,
            isUrlEncoded: true,
            formId: '',
            containerId: containerId,
            sendData: '',
            eventEl: container
        });
    };
    window.__bridje.refresh = function(element)
    {
        refresh(element);
    };

    const removeElementActionClass = function(element)
    {
        const actionClass = element.getAttribute('data-action-class');
        if (actionClass)
        {
            const regex = new RegExp('\\b' + actionClass + '\\b','g')
            element.className.replace(regex, "");
        }
    };

    const addElementActionClass = function(element)
    {
        const actionClass = element.getAttribute('data-action-class');
        if (actionClass)
        {
            const clsArr = element.className.split(" ");
            if (clsArr.indexOf(actionClass) < 0)
            {
                element.className += " " + name;
            }
        }
    };

    const initialize = function(element)
    {
        let actions = element.getElementsByClassName('bridje-action-click');
        for (let i = 0; i < actions.length; i++)
        {
            const action = actions[i];
            if (findForm(action))
            {
                const eventId = action.getAttribute('data-eventid');
                const eventInput = document.getElementById(eventId);
                if (eventInput)
                {
                    action.onclick = function(e)
                    {
                        e && e.preventDefault();
                        execute(action);
                    };
                }
            }
        }

        actions = element.getElementsByClassName('bridje-action-change');
        for (let i = 0; i < actions.length; i++)
        {
            const action = actions[i];
            if (findForm(action))
            {
                const eventId = action.getAttribute('data-eventid');
                const eventInput = document.getElementById(eventId);
                if (eventInput)
                {
                    action.onchange = function(e)
                    {
                        e && e.preventDefault();
                        execute(action);
                    };
                }
            }
        }

        actions = element.getElementsByClassName('bridje-action-enter');
        for (let i = 0; i < actions.length; i++)
        {
            const action = actions[i];
            if (findForm(action))
            {
                const eventId = action.getAttribute('data-eventid');
                const eventInput = document.getElementById(eventId);
                if (eventInput)
                {
                    action.onkeypress = function(e)
                    {
                        if(e)
                        {
                            if (e.which == 13 || e.keyCode == 13)
                            {
                                e.preventDefault();
                                execute(action);
                            }
                        }
                    };
                }
            }
        }
    };

    initialize(document);
};
<|endoftext|>


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

Ensembl.Panel.GXA = Ensembl.Panel.Content.extend({
  init: function() {

    this.base.apply(this, arguments);

    this.elLk.target = this.el.append('
');

    $.ajax({
      url: 'http://www.ebi.ac.uk/gxa/json/expressionData?geneId=' + this.params.geneId,
      dataType: 'json',
      context: this,
      success: function(json) {
        if (json[this.params.geneId]) {
          this.insertWidget();
        } else {
          this.showError('Expression Atlas does not contain baseline expression data for ' + this.params.geneId);
        }
      },
      error: function() {
        this.showError();
      }
    });
  },

  insertWidget: function() {
    var panel = this;
    if ('expressionAtlasHeatmapHighcharts' in window) {
      try {
        expressionAtlasHeatmapHighcharts.render({
//atlasHost: "https://wwwdev.ebi.ac.uk", //uncomment for testing widget before GXA release
          params:'geneQuery=' + this.params.geneId + '&species=' + this.params.species,
          isMultiExperiment: true,
          target : this.elLk.target.attr('id'),
          fail: function() {
            panel.showError();
          }
        });
      } catch (ex) {
        console.log(ex);
        this.showError();
      }
    }
  },

  showError: function(message) {
    this.elLk.target.html(message ? message : 'Error loading GXA widget');
  }
});
<commit_msg>ENSWEB-3905: update gxa widget after their release<commit_after>/*
 * Copyright [1999-2015] Wellcome Trust Sanger Institute and the EMBL-European Bioinformatics Institute
 * Copyright [2016-2017] EMBL-European Bioinformatics Institute
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

Ensembl.Panel.GXA = Ensembl.Panel.Content.extend({
  init: function() {

    this.base.apply(this, arguments);

    this.elLk.target = this.el.append('
');

    $.ajax({
      url: 'http://www.ebi.ac.uk/gxa/json/expressionData?geneId=' + this.params.geneId,
      dataType: 'json',
      context: this,
      success: function(json) {
        if (json[this.params.geneId]) {
          this.insertWidget();
        } else {
          this.showError('Expression Atlas does not contain baseline expression data for ' + this.params.geneId);
        }
      },
      error: function() {
        this.showError();
      }
    });
  },

  insertWidget: function() {
    var panel = this;
    if ('expressionAtlasHeatmapHighcharts' in window) {
      try {
        expressionAtlasHeatmapHighcharts.render({
//atlasHost: "https://wwwdev.ebi.ac.uk", //uncomment for testing widget before GXA release
          query:{gene: this.params.geneId, species: this.params.species} ,
          isMultiExperiment: true,
          target : this.elLk.target.attr('id'),
          fail: function() {
            panel.showError();
          }
        });
      } catch (ex) {
        console.log(ex);
        this.showError();
      }
    }
  },

  showError: function(message) {
    this.elLk.target.html(message ? message : 'Error loading GXA widget');
  }
});
<|endoftext|>


<commit_before>import React, { Component } from "react";
import ResultItem from "./ResultItem";
import endpoints from "../lib/media_endpoints";

const titleCase = (string) => string[0].toUpperCase() + string.slice(1);

export default class Searchbox extends Component {
  constructor(props) {
    super(props)
    this.state = {
      selectedIndex: 0
    }
  }
  navigateDropdown(keyName) {
    const { selectedIndex, results } = this.state;
    let nextIndex = selectedIndex;
    if (keyName === 'ArrowUp') {
        nextIndex = Math.max(selectedIndex - 1, 0);
    } else {
        nextIndex = Math.min(selectedIndex + 1, results.length - 1);
    }
    this.setState({ selectedIndex: nextIndex });
  }

  captureArrowKeys(event) {
    const { setShowResults } = this.props
    // console.log(event.key);
    switch (event.key) {
      case 'ArrowUp': case 'ArrowDown':
        event.preventDefault();
        this.props.navigateDropdown(event.key === 'ArrowUp' ? -1 : 1)
        break;

      case 'Enter':
        event.preventDefault();
        console.log(this.props.searchResults[this.props.dropdownIndex]);
        this.props.submitMedia(this.props.searchResults[this.props.dropdownIndex])
        break;

      case 'Escape':
        this.props.setShowResults(false)
        break;
    }
  }

  handleOnChange(event) {
    this.props.setSearchQuery(event.target.value, this.props.searchSource)
  }

  _submitForm(e) {
    e.preventDefault();
    let query = this.query.value;
    let urlResults = endpoints.urlToMediaItem(query);

    if (urlResults.length > 0) {
      let [result] = urlResults;
      this.resultClicked(result);
      return;
    } else {
    }
  }

  resultClicked(result) {
    this.props.addItem(result);
    this.query.blur();
  }

  searchPlaceholder() {
    const {searchSource, activeFeedId} = this.props
    if (activeFeedId === 'playlists') {
      return "Enter playlist URL"
    }
    switch (searchSource) {
      case "spotify":
        return "Search for tracks on Spotify";
      case "soundcloud":
        return "Search for tracks on SoundCloud";
      case "youtube":
        return "Search for YouTube videos";
      default:
        return "Search for videos or music";
    }
  }
  render() {
    const { results, selectedIndex } = this.state;
    const {
      onToggleButton,
      activeFeedId,
      searchSource,
      onSelectSource,
      searchResultVisible,
      setShowResults,
      searchResults,
      searchQuery,
      dropdownIndex
    } = this.props
    const hidden = activeFeedId !== 'tracks'
    const options = ["spotify", "youtube", "soundcloud"]

    return (

        <form onSubmit={this._submitForm.bind(this)}>
          <select ref={elem => this.type = elem}
                  style={{'visibility': hidden ? 'hidden' : ''}}
                  value={searchSource}
                  onChange={(event) => onSelectSource(event.target.value)}
                  className={'search-type-select match-' + searchSource}>
            {options.map((value) =>
              (<option key={value} value={value}>{value}</option>)
            )}
          </select>
          <input ref={elem => this.query = elem}
                 type="search"
                 onKeyUp={this.captureArrowKeys.bind(this)}
                 onChange={(event) => this.handleOnChange(event)}
                 /*onBlur={() => setTimeout(() => setShowResults(false), 1000) }*/
                 onFocus={() => setShowResults(true)}
                 id="insert_video"
                 autoComplete="off"
                 value={searchQuery} />

          {searchResultVisible && Boolean(searchResults.length) && (

 this.resultsList = elem}>
                {searchResults.map((result, index) =>
                  (<ResultItem key={result.id} onClick={this.resultClicked.bind(this)} setSelectedNode={this.setSelectedNode} selected={index === dropdownIndex} result={result} />)
                )}

          )}
        </form>
        <button onClick={onToggleButton}>{titleCase(activeFeedId)}</button>

    );
  }
}
<commit_msg>Removed old code<commit_after>import React, { Component } from "react";
import ResultItem from "./ResultItem";
import endpoints from "../lib/media_endpoints";

const titleCase = (string) => string[0].toUpperCase() + string.slice(1);

export default class Searchbox extends Component {
  constructor(props) {
    super(props)
    this.state = {
      selectedIndex: 0
    }
  }
  navigateDropdown(keyName) {
    const { selectedIndex, results } = this.state;
    let nextIndex = selectedIndex;
    if (keyName === 'ArrowUp') {
        nextIndex = Math.max(selectedIndex - 1, 0);
    } else {
        nextIndex = Math.min(selectedIndex + 1, results.length - 1);
    }
    this.setState({ selectedIndex: nextIndex });
  }

  captureArrowKeys(event) {
    const { setShowResults } = this.props
    // console.log(event.key);
    switch (event.key) {
      case 'ArrowUp': case 'ArrowDown':
        event.preventDefault();
        this.props.navigateDropdown(event.key === 'ArrowUp' ? -1 : 1)
        break;

      case 'Enter':
        event.preventDefault();
        console.log(this.props.searchResults[this.props.dropdownIndex]);
        this.props.submitMedia(this.props.searchResults[this.props.dropdownIndex])
        break;

      case 'Escape':
        this.props.setShowResults(false)
        break;
    }
  }

  handleOnChange(event) {
    this.props.setSearchQuery(event.target.value, this.props.searchSource)
  }

  searchPlaceholder() {
    const {searchSource, activeFeedId} = this.props
    if (activeFeedId === 'playlists') {
      return "Enter playlist URL"
    }
    switch (searchSource) {
      case "spotify":
        return "Search for tracks on Spotify";
      case "soundcloud":
        return "Search for tracks on SoundCloud";
      case "youtube":
        return "Search for YouTube videos";
      default:
        return "Search for videos or music";
    }
  }
  render() {
    const { results, selectedIndex } = this.state;
    const {
      onToggleButton,
      activeFeedId,
      searchSource,
      onSelectSource,
      searchResultVisible,
      setShowResults,
      searchResults,
      searchQuery,
      dropdownIndex
    } = this.props
    const hidden = activeFeedId !== 'tracks'
    const options = ["spotify", "youtube", "soundcloud"]

    return (

        <form>
          <select ref={elem => this.type = elem}
                  style={{'visibility': hidden ? 'hidden' : ''}}
                  value={searchSource}
                  onChange={(event) => onSelectSource(event.target.value)}
                  className={'search-type-select match-' + searchSource}>
            {options.map((value) =>
              (<option key={value} value={value}>{value}</option>)
            )}
          </select>
          <input ref={elem => this.query = elem}
                 type="search"
                 onKeyUp={this.captureArrowKeys.bind(this)}
                 onChange={(event) => this.handleOnChange(event)}
                 /*onBlur={() => setTimeout(() => setShowResults(false), 1000) }*/
                 onFocus={() => setShowResults(true)}
                 id="insert_video"
                 autoComplete="off"
                 value={searchQuery} />

          {searchResultVisible && Boolean(searchResults.length) && (

 this.resultsList = elem}>
                {searchResults.map((result, index) =>
                  (<ResultItem key={result.id} onClick={this.resultClicked.bind(this)} setSelectedNode={this.setSelectedNode} selected={index === dropdownIndex} result={result} />)
                )}

          )}
        </form>
        <button onClick={onToggleButton}>{titleCase(activeFeedId)}</button>

    );
  }
}
<|endoftext|>


<commit_before>import React, { Component } from 'react';

import PageHeader from './page_header';
import GuildsTable from './guilds_table';
import {globalState} from '../state';

class DashboardGuildsList extends Component {
  constructor() {
    super();
    this.state = {guilds: null};
  }

  componentWillMount() {
    globalState.getCurrentUser().then((user) => {
      user.getGuilds().then((guilds) => {
        this.setState({guilds});
      });
    });
  }

  render() {
    return (

          Guilds

          <GuildsTable guilds={this.state.guilds}/>

    );
  }
}

class StatsPanel extends Component {
  render () {
    const panelClass = `panel panel-${this.props.color}`;
    const iconClass = `fa fa-${this.props.icon} fa-5x`;

    return (

{this.props.data || 'N/A'}

{this.props.text}

    );
  }
}

class Stats extends Component {
  constructor() {
    super();
  //   this.getStuff();
  // }

  // async getStuff() {
  //   await globalState.getCurrentUser();
  //   await globalState.getStats();
  }

  componentWillMount() {
    globalState.getStats();
  }

  getStats() {
    let statsPanels = [];
    if (globalState.user.admin) {
      globalState.getStats((stats) => {
        statsPanels.push(
            <StatsPanel color='primary' icon='comments' data={stats.messages} text='Messages' key='messages' />
        );
        statsPanels.push(
            <StatsPanel color='green' icon='server' data={stats.guilds} text='Guilds' key='guilds' />
        );
        statsPanels.push(
            <StatsPanel color='yellow' icon='user' data={stats.users} text='Users' key='users' />
        );
        statsPanels.push(
            <StatsPanel color='red' icon='hashtag' data={stats.channels} text='Channels' key='channels' />
        );
      });
    }
    return statsPanels;
  }

  render() {
    const Panels = this.getStats();
    const oof = <StatsPanel color='primary' icon='comments' data='69' text='Messages' key='messages' />;
    console.log(panels)

    // return
{panels}
;
    return (

        <Panels />
        {oof}
        {panels}
        <StatsPanel color='primary' icon='comments' data='N/A' text='Messages' key='messages' />
        <StatsPanel color='green' icon='server' data='N/A' text='Guilds' key='guilds' />
        <StatsPanel color='yellow' icon='user' data='N/A' text='Users' key='users' />
        <StatsPanel color='red' icon='hashtag' data='N/A' text='Channels' key='channels' />

    )
  }
}

class Dashboard extends Component {
  render() {
		return (

        <PageHeader name="Dashboard" />

          <Stats />

            <DashboardGuildsList />

    );
  }
}

export default Dashboard;
<commit_msg>[frontend] ok<commit_after>import React, { Component } from 'react';

import PageHeader from './page_header';
import GuildsTable from './guilds_table';
import {globalState} from '../state';

class DashboardGuildsList extends Component {
  constructor() {
    super();
    this.state = {guilds: null};
  }

  componentWillMount() {
    globalState.getCurrentUser().then((user) => {
      user.getGuilds().then((guilds) => {
        this.setState({guilds});
      });
    });
  }

  render() {
    return (

          Guilds

          <GuildsTable guilds={this.state.guilds}/>

    );
  }
}

class StatsPanel extends Component {
  render () {
    const panelClass = `panel panel-${this.props.color}`;
    const iconClass = `fa fa-${this.props.icon} fa-5x`;

    return (

{this.props.data || 'N/A'}

{this.props.text}

    );
  }
}

class Stats extends Component {
  constructor() {
    super();
  //   this.getStuff();
  // }

  // async getStuff() {
  //   await globalState.getCurrentUser();
  //   await globalState.getStats();
  }

  componentWillMount() {
    globalState.getStats();
  }

  getStats() {
    let statsPanels = [];
    if (globalState.user.admin) {
      globalState.getStats((stats) => {
        statsPanels.push(
            <StatsPanel color='primary' icon='comments' data={stats.messages} text='Messages' key='messages' />
        );
        statsPanels.push(
            <StatsPanel color='green' icon='server' data={stats.guilds} text='Guilds' key='guilds' />
        );
        statsPanels.push(
            <StatsPanel color='yellow' icon='user' data={stats.users} text='Users' key='users' />
        );
        statsPanels.push(
            <StatsPanel color='red' icon='hashtag' data={stats.channels} text='Channels' key='channels' />
        );
      });
    }
    return statsPanels;
  }

  render() {
    const Panels = this.getStats();
    const oof = <StatsPanel color='primary' icon='comments' data='69' text='Messages' key='messages' />;

    // return
{panels}
;
    return (

        <Panels />
        {oof}
        {panels}
        <StatsPanel color='primary' icon='comments' data='N/A' text='Messages' key='messages' />
        <StatsPanel color='green' icon='server' data='N/A' text='Guilds' key='guilds' />
        <StatsPanel color='yellow' icon='user' data='N/A' text='Users' key='users' />
        <StatsPanel color='red' icon='hashtag' data='N/A' text='Channels' key='channels' />

    )
  }
}

class Dashboard extends Component {
  render() {
		return (

        <PageHeader name="Dashboard" />

          <Stats />

            <DashboardGuildsList />

    );
  }
}

export default Dashboard;
<|endoftext|>