<commit_before>/*!
 * Module dependencies.
 */

var _ = require('underscore');
var fs = require('fs');
var gcsHelper = require('../../../lib/gcsHelper');
var grappling = require('grappling-hook');
var keystone = require('../../../');
var moment = require('moment');
var super_ = require('../Type');
var util = require('util');
var utils = require('keystone-utils');
var ExifImage = require('exif').ExifImage;
var sizeOf = require('image-size');

function extractExif(image) {
    return new Promise(function(resolve, reject) {
        try {
            new ExifImage({
                image: image
            }, function(error, exifData) {
                if (error) {
                    console.log('Error while extracting exif of image: ' + error.message);
                    resolve({});
                } else {
                    if (typeof exifData === 'object') {
                        return resolve(exifData);
                    }
                    resolve({});
                }
            });
        } catch (error) {
            console.log('Error while extracting exif of image: ' + error.message);
            resolve({});
        }
    });
}

/**
 *  FieldType Constructor
 * @extends Field
 * @api public
 */

function gcsimage(list, path, options) {
    grappling.mixin(this)
        .allowHooks('pre:upload');
    this._underscoreMethods = ['format', 'uploadFile'];
    this._fixedSize = 'full';

    // TODO: implement filtering, usage disabled for now
    options.nofilter = true;

    gcsimage.super_.call(this, list, path, options);

    // validate gcs config (has to happen after super_.call)
    if (!keystone.get('gcs config')) {
        throw new Error('Invalid Configuration\n\n' + 'gcsimage fields (' + list.key + '.' + path + ') require the "gcs config" option to be set.\n\n' + 'See http://keystonejs.com/docs/configuration/#services-gcsimage for more information.\n');
    }

    // Could be more pre- hooks, just upload for now
    if (options.pre && options.pre.upload) {
        this.pre('upload', options.pre.upload);
    }

}

/*!
 * Inherit from Field
 */

util.inherits(gcsimage, super_);

/**
 * Exposes the custom or keystone gcs config settings
 */

Object.defineProperty(gcsimage.prototype, 'gcsConfig', {
    get: function() {
        return this.options.gcsConfig || keystone.get('gcs config');
    },
});

/**
 * Registers the field on the List's Mongoose Schema.
 *
 * @api public
 */

gcsimage.prototype.addToSchema = function() {

    var field = this;
    var schema = this.list.schema;

    var paths = this.paths = {
        // fields
        artist: this._path.append('.artist'),
        bucket: this._path.append('.bucket'),
        description: this._path.append('.description'),
        filename: this._path.append('.filename'),
        filetype: this._path.append('.filetype'),
        height: this._path.append('.height'),
        originalname: this._path.append('.originalname'),
        path: this._path.append('.path'),
        resizedTargets: this._path.append('.resizedTargets'),
        size: this._path.append('.size'),
        url: this._path.append('.url'),
        width: this._path.append('.width'),

        // virtuals
        action: this._path.append('_action'),
        exists: this._path.append('.exists'),
        upload: this._path.append('_upload'),
    };

    var schemaPaths = this._path.addTo({}, {
        artist: String,
        bucket: String,
        description: String,
        filename: String,
        filetype: String,
        height: Number,
        originalname: String,
        path: String,
        resizedTargets: Object,
        size: Number,
        url: String,
        width: Number
    });

    schema.add(schemaPaths);

    var exists = function(item) {
        return (item.get(paths.url) ? true : false);
    };

    // The .exists virtual indicates whether a file is stored
    schema.virtual(paths.exists).get(function() {
        return schemaMethods.exists.apply(this);
    });

    var reset = function(item) {
        item.set(field.path, {
            artist: '',
            bucket: '',
            description: '',
            filename: '',
            filetype: '',
            height: 0,
            originalname: '',
            path: '',
            resizedTargets: {},
            size: 0,
            url: '',
            width: 0
        });
    };

    var schemaMethods = {
        exists: function() {
            return exists(this);
        },
        /**
         * Resets the value of the field
         *
         * @api public
         */
        reset: function() {
            reset(this);
        },
        /**
         * Deletes the file from gcs and resets the field
         *
         * @api public
         */
        delete: function() {
            var _this = this;
            var promise = new Promise(function(resolve, reject) {
                var gcsConfig = field.gcsConfig;
                var bucket = gcsHelper.initBucket(gcsConfig, _this.get(paths.bucket));
                var filename = _this.get(paths.filename);
                if (filename && typeof filename === 'string') {
                    var filenameWithoutExt = filename.split('.');
                    bucket.deleteFiles({
                        prefix: _this.get(paths.path) + filenameWithoutExt
                    }, function(err) {
                        if (err) {
                            return reject(err);
                        }
                        resolve();
                    });
                } else {
                    resolve();
                }
            });
            reset(this);
            return promise;
        }
    };

    _.each(schemaMethods, function(fn, key) {
        field.underscoreMethod(key, fn);
    });

    // expose a method on the field to call schema methods
    this.apply = function(item, method) {
        return schemaMethods[method].apply(item, Array.prototype.slice.call(arguments, 2));
    };

    this.bindUnderscoreMethods();
};

/**
 * Formats the field value
 *
 * @api public
 */

gcsimage.prototype.format = function(item) {
    if (this.hasFormatter()) {
        return this.options.format(item, item[this.path]);
    }
    return item.get(this.paths.url);
};

/**
 * Detects the field have formatter function
 *
 * @api public
 */

gcsimage.prototype.hasFormatter = function() {
    return typeof this.options.format === 'function';
};

/**
 * Detects whether the field has been modified
 *
 * @api public
 */

gcsimage.prototype.isModified = function(item) {
    return item.isModified(this.paths.url);
};

/**
 * Validates that a value for this field has been provided in a data object
 *
 * @api public
 */

gcsimage.prototype.inputIsValid = function(data) { // eslint-disable-line no-unused-vars
    // TODO - how should file field input be validated?
    return true;
};

/**
 * Updates the value for this field in the item from a data object
 *
 * @api public
 */

gcsimage.prototype.updateItem = function(item, data, callback) { // eslint-disable-line no-unused-vars
    // TODO - direct updating of data (not via upload)
    process.nextTick(callback);
};

/**
 * Uploads the file for this field
 *
 * @api public
 */

gcsimage.prototype.uploadFile = function(item, file, update, callback) {

    var field = this;
    var path = field.options.destination ? field.options.destination : '';
    var isPublicRead = field.options.publicRead ? field.options.publicRead : false;
    var prefix = field.options.datePrefix ? moment().format(field.options.datePrefix) + '-' : '';
    var filename = prefix + file.name;
    var split = filename.split('.');
    var filenameWithoutExt = split[0];
    var ext = split[1] || '';
    var originalname = file.originalname;
    var filetype = file.mimetype || file.type;

    if (typeof update === 'function') {
        callback = update;
        update = false;
    }

    if ((field.options.allowedTypes && !_.contains(field.options.allowedTypes, filetype) ||
        filetype.match('image.*') === null)) {
        return callback(new Error('Unsupported File Type: ' + filetype));
    }

    var doUpload = function() {

        if (typeof field.options.filename === 'function') {
            filename = field.options.filename(item, filename, originalname);
        }

        var bucket = gcsHelper.initBucket(field.gcsConfig, field.options.bucket);
        gcsHelper.uploadFileToBucket(bucket, fs.createReadStream(file.path), {
            destination: path + filename,
            filetype: filetype,
            isPublicRead: isPublicRead
        }).then(function(apiResponse) {
            // resizing image and upload resized images
            if (typeof field.options.resize === 'function') {
                var resizeFunc = field.options.resize;
                if (Array.isArray(field.options.resizeOpts) && field.options.resizeOpts.length > 0) {
                    var promises = [];
                    var targets = {};
                    var resizeOpts = field.options.resizeOpts;
                    for (var i = 0; i < resizeOpts.length; i++) {
                        var resizeOpt = resizeOpts[i] || {};
                        targets[resizeOpt.target] = {
                            url: gcsHelper.getPublicUrl(field.options.bucket,path + filenameWithoutExt + '-' + resizeOpt.target + '.' + ext)
                        };
                        promises.push(gcsHelper.uploadFileToBucket(bucket, resizeFunc(file.path, resizeOpt.width, resizeOpt.height, resizeOpt.options), {
                            destination: path + filenameWithoutExt + '-' + resizeOpt.target + '.' + ext,
                            filetype: filetype,
                            isPublicRead: isPublicRead
                        }));
                    }
                    return Promise.all(promises).then(function(values) {
                        return targets;
                    });
                } else {
                    // skip resizing
                    return;
                }
            } else {
                // skip resizing
                return;
            }
        }).then(function(targets) {
            var dimensions = sizeOf(file.path);
            return extractExif(file.path).then(function(exifData) {
                exifData.image = exifData.image || {};
                exifData.exif = exifData.exif || {};
                var fileData;
                fileData = {
                    artist: exifData.image.Artist || '',
                    bucket: field.options.bucket,
                    description: exifData.image.ImageDescription || '',
                    filename: filename,
                    filetype: filetype,
                    height: dimensions.height || exifData.exif.ExifImageHeight || exifData.image.ImageHeight || 0,
                    originalname: originalname,
                    path: path,
                    size: file.size,
                    resizedTargets: targets || {},
                    url: gcsHelper.getPublicUrl(field.options.bucket, path + filename),
                    width: dimensions.width ||  exifData.exif.ExifImageWidth || exifData.image.ImageWidth || 0
                };
                if (update) {
                    item.set(field.path, fileData);
                }
                callback(null, fileData);
            });
        }).catch(function(err) {
            console.error('UPLOADING ERROR:', err);
            bucket.deleteFiles({
                prefix: path + filenameWithoutExt
            }, function(deleteErr) {
                if (deleteErr) {
                    return callback(deleteErr);
                }
                callback(err);
            });
        });
    };

    this.callHook('pre:upload', item, file, function(err) {
        if (err) return callback(err);
        doUpload();
    });

};

/**
 * Returns a callback that handles a standard form submission for the field
 *
 * Expected form parts are
 * - `field.paths.action` in `req.body` (`clear` or `delete`)
 * - `field.paths.upload` in `req.files` (uploads the file to gcs)
 *
 * @api public
 */

gcsimage.prototype.getRequestHandler = function(item, req, paths, callback) {

    var field = this;

    if (utils.isFunction(paths)) {
        callback = paths;
        paths = field.paths;
    } else if (!paths) {
        paths = field.paths;
    }

    callback = callback || function() {};

    return function() {

        if (req.body) {
            var action = req.body[paths.action];

            if (/^(delete|reset)$/.test(action)) {
                field.apply(item, action);
            }
        }

        if (req.files && req.files[paths.upload] && req.files[paths.upload].size) {
            var imageDelete;
            if (field.options.autoCleanup && item.get(field.paths.exists)) {
                // capture image delete promise
                imageDelete = field.apply(item, 'delete');
            }
            if (typeof imageDelete === 'undefined') {
                field.uploadFile(item, req.files[paths.upload], true, callback);
            } else {
                imageDelete.then(function(result) {
                    field.uploadFile(item, req.files[paths.upload], true, callback);
                }, function(err) {
                    callback(err);
                });
            }
        } else {
            return callback();
        }
    };
};

/**
 * Immediately handles a standard form submission for the field (see `getRequestHandler()`)
 *
 * @api public
 */

gcsimage.prototype.handleRequest = function(item, req, paths, callback) {
    this.getRequestHandler(item, req, paths, callback)();
};

/*!
 * Export class
 */

module.exports = gcsimage;
<commit_msg>calculate the width and height of resized images by original aspect ratio<commit_after>/*!
 * Module dependencies.
 */

var _ = require('lodash');
var fs = require('fs');
var gcsHelper = require('../../../lib/gcsHelper');
var grappling = require('grappling-hook');
var keystone = require('../../../');
var moment = require('moment');
var super_ = require('../Type');
var util = require('util');
var utils = require('keystone-utils');
var ExifImage = require('exif').ExifImage;
var sizeOf = require('image-size');

function extractExif(image) {
    return new Promise(function(resolve, reject) {
        try {
            new ExifImage({
                image: image
            }, function(error, exifData) {
                if (error) {
                    console.log('Error while extracting exif of image: ' + error.message);
                    resolve({});
                } else {
                    if (typeof exifData === 'object') {
                        return resolve(exifData);
                    }
                    resolve({});
                }
            });
        } catch (error) {
            console.log('Error while extracting exif of image: ' + error.message);
            resolve({});
        }
    });
}

/**
 *  FieldType Constructor
 * @extends Field
 * @api public
 */

function gcsimage(list, path, options) {
    grappling.mixin(this)
        .allowHooks('pre:upload');
    this._underscoreMethods = ['format', 'uploadFile'];
    this._fixedSize = 'full';

    // TODO: implement filtering, usage disabled for now
    options.nofilter = true;

    gcsimage.super_.call(this, list, path, options);

    // validate gcs config (has to happen after super_.call)
    if (!keystone.get('gcs config')) {
        throw new Error('Invalid Configuration\n\n' + 'gcsimage fields (' + list.key + '.' + path + ') require the "gcs config" option to be set.\n\n' + 'See http://keystonejs.com/docs/configuration/#services-gcsimage for more information.\n');
    }

    // Could be more pre- hooks, just upload for now
    if (options.pre && options.pre.upload) {
        this.pre('upload', options.pre.upload);
    }

}

/*!
 * Inherit from Field
 */

util.inherits(gcsimage, super_);

/**
 * Exposes the custom or keystone gcs config settings
 */

Object.defineProperty(gcsimage.prototype, 'gcsConfig', {
    get: function() {
        return this.options.gcsConfig || keystone.get('gcs config');
    },
});

/**
 * Registers the field on the List's Mongoose Schema.
 *
 * @api public
 */

gcsimage.prototype.addToSchema = function() {

    var field = this;
    var schema = this.list.schema;

    var paths = this.paths = {
        // fields
        artist: this._path.append('.artist'),
        bucket: this._path.append('.bucket'),
        description: this._path.append('.description'),
        filename: this._path.append('.filename'),
        filetype: this._path.append('.filetype'),
        height: this._path.append('.height'),
        originalname: this._path.append('.originalname'),
        path: this._path.append('.path'),
        resizedTargets: this._path.append('.resizedTargets'),
        size: this._path.append('.size'),
        url: this._path.append('.url'),
        width: this._path.append('.width'),

        // virtuals
        action: this._path.append('_action'),
        exists: this._path.append('.exists'),
        upload: this._path.append('_upload'),
    };

    var schemaPaths = this._path.addTo({}, {
        artist: String,
        bucket: String,
        description: String,
        filename: String,
        filetype: String,
        height: Number,
        originalname: String,
        path: String,
        resizedTargets: Object,
        size: Number,
        url: String,
        width: Number
    });

    schema.add(schemaPaths);

    var exists = function(item) {
        return (item.get(paths.url) ? true : false);
    };

    // The .exists virtual indicates whether a file is stored
    schema.virtual(paths.exists).get(function() {
        return schemaMethods.exists.apply(this);
    });

    var reset = function(item) {
        item.set(field.path, {
            artist: '',
            bucket: '',
            description: '',
            filename: '',
            filetype: '',
            height: 0,
            originalname: '',
            path: '',
            resizedTargets: {},
            size: 0,
            url: '',
            width: 0
        });
    };

    var schemaMethods = {
        exists: function() {
            return exists(this);
        },
        /**
         * Resets the value of the field
         *
         * @api public
         */
        reset: function() {
            reset(this);
        },
        /**
         * Deletes the file from gcs and resets the field
         *
         * @api public
         */
        delete: function() {
            var _this = this;
            var promise = new Promise(function(resolve, reject) {
                var gcsConfig = field.gcsConfig;
                var bucket = gcsHelper.initBucket(gcsConfig, _this.get(paths.bucket));
                var filename = _this.get(paths.filename);
                if (filename && typeof filename === 'string') {
                    var filenameWithoutExt = filename.split('.');
                    bucket.deleteFiles({
                        prefix: _this.get(paths.path) + filenameWithoutExt
                    }, function(err) {
                        if (err) {
                            return reject(err);
                        }
                        resolve();
                    });
                } else {
                    resolve();
                }
            });
            reset(this);
            return promise;
        }
    };

    _.forEach(schemaMethods, function(fn, key) {
        field.underscoreMethod(key, fn);
    });

    // expose a method on the field to call schema methods
    this.apply = function(item, method) {
        return schemaMethods[method].apply(item, Array.prototype.slice.call(arguments, 2));
    };

    this.bindUnderscoreMethods();
};

/**
 * Formats the field value
 *
 * @api public
 */

gcsimage.prototype.format = function(item) {
    if (this.hasFormatter()) {
        return this.options.format(item, item[this.path]);
    }
    return item.get(this.paths.url);
};

/**
 * Detects the field have formatter function
 *
 * @api public
 */

gcsimage.prototype.hasFormatter = function() {
    return typeof this.options.format === 'function';
};

/**
 * Detects whether the field has been modified
 *
 * @api public
 */

gcsimage.prototype.isModified = function(item) {
    return item.isModified(this.paths.url);
};

/**
 * Validates that a value for this field has been provided in a data object
 *
 * @api public
 */

gcsimage.prototype.inputIsValid = function(data) { // eslint-disable-line no-unused-vars
    // TODO - how should file field input be validated?
    return true;
};

/**
 * Updates the value for this field in the item from a data object
 *
 * @api public
 */

gcsimage.prototype.updateItem = function(item, data, callback) { // eslint-disable-line no-unused-vars
    // TODO - direct updating of data (not via upload)
    process.nextTick(callback);
};

/**
 * Uploads the file for this field
 *
 * @api public
 */

gcsimage.prototype.uploadFile = function(item, file, update, callback) {

    var field = this;
    var path = field.options.destination ? field.options.destination : '';
    var isPublicRead = field.options.publicRead ? field.options.publicRead : false;
    var prefix = field.options.datePrefix ? moment().format(field.options.datePrefix) + '-' : '';
    var filename = prefix + file.name;
    var split = filename.split('.');
    var filenameWithoutExt = split[0];
    var ext = split[1] || '';
    var originalname = file.originalname;
    var filetype = file.mimetype || file.type;

    if (typeof update === 'function') {
        callback = update;
        update = false;
    }

    if ((field.options.allowedTypes && !_.indexOf(field.options.allowedTypes, filetype) ||
        filetype.match('image.*') === null)) {
        return callback(new Error('Unsupported File Type: ' + filetype));
    }

    var doUpload = function() {

        if (typeof field.options.filename === 'function') {
            filename = field.options.filename(item, filename, originalname);
        }

        var bucket = gcsHelper.initBucket(field.gcsConfig, field.options.bucket);
        gcsHelper.uploadFileToBucket(bucket, fs.createReadStream(file.path), {
            destination: path + filename,
            filetype: filetype,
            isPublicRead: isPublicRead
        }).then(function(apiResponse) {
            // resizing image and upload resized images
            if (typeof field.options.resize === 'function') {
                var resizeFunc = field.options.resize;
                if (Array.isArray(field.options.resizeOpts) && field.options.resizeOpts.length > 0) {
                    var promises = [];
                    var targets = {};
                    var resizeOpts = field.options.resizeOpts;
                    for (var i = 0; i < resizeOpts.length; i++) {
                        var resizeOpt = resizeOpts[i] || {};
                        targets[resizeOpt.target] = {
                            url: gcsHelper.getPublicUrl(field.options.bucket,path + filenameWithoutExt + '-' + resizeOpt.target + '.' + ext),
                            width: resizeOpt.width,
                            height: resizeOpt.height
                        };
                        promises.push(gcsHelper.uploadFileToBucket(bucket, resizeFunc(file.path, resizeOpt.width, resizeOpt.height, resizeOpt.options), {
                            destination: path + filenameWithoutExt + '-' + resizeOpt.target + '.' + ext,
                            filetype: filetype,
                            isPublicRead: isPublicRead
                        }));
                    }
                    return Promise.all(promises).then(function(values) {
                        return targets;
                    });
                } else {
                    // skip resizing
                    return;
                }
            } else {
                // skip resizing
                return;
            }
        }).then(function(targets) {
            var dimensions = sizeOf(file.path);

            if (targets) {
                try {
                    _.forEach(targets, function(target) {
                        if (typeof target.width === 'number' && typeof target.height !== 'number') {
                            if (target.width < dimensions.width) {
                                target.height = Math.round((target.width / dimensions.width) * dimensions.height);
                            } else {
                                target.height = dimensions.height;
                            }
                        } else if (typeof target.height === 'number' && typeof target.width !== 'number') {
                            if (target.height < dimensions.height) {
                                target.width = Math.round((target.height / dimensions.height) * dimensions.width);
                            } else {
                                target.width = dimensions.width;
                            }
                        }
                    })
                } catch (e) {
                    console.warn('Calculating width and height of resized image occurs error ', e);
                }
            }
            return extractExif(file.path).then(function(exifData) {
                exifData.image = exifData.image || {};
                exifData.exif = exifData.exif || {};
                var fileData;
                fileData = {
                    artist: exifData.image.Artist || '',
                    bucket: field.options.bucket,
                    description: exifData.image.ImageDescription || '',
                    filename: filename,
                    filetype: filetype,
                    height: dimensions.height || exifData.exif.ExifImageHeight || exifData.image.ImageHeight || 0,
                    originalname: originalname,
                    path: path,
                    size: file.size,
                    resizedTargets: targets || {},
                    url: gcsHelper.getPublicUrl(field.options.bucket, path + filename),
                    width: dimensions.width ||  exifData.exif.ExifImageWidth || exifData.image.ImageWidth || 0
                };
                if (update) {
                    item.set(field.path, fileData);
                }
                callback(null, fileData);
            });
        }).catch(function(err) {
            console.error('UPLOADING ERROR:', err);
            bucket.deleteFiles({
                prefix: path + filenameWithoutExt
            }, function(deleteErr) {
                if (deleteErr) {
                    return callback(deleteErr);
                }
                callback(err);
            });
        });
    };

    this.callHook('pre:upload', item, file, function(err) {
        if (err) return callback(err);
        doUpload();
    });

};

/**
 * Returns a callback that handles a standard form submission for the field
 *
 * Expected form parts are
 * - `field.paths.action` in `req.body` (`clear` or `delete`)
 * - `field.paths.upload` in `req.files` (uploads the file to gcs)
 *
 * @api public
 */

gcsimage.prototype.getRequestHandler = function(item, req, paths, callback) {

    var field = this;

    if (utils.isFunction(paths)) {
        callback = paths;
        paths = field.paths;
    } else if (!paths) {
        paths = field.paths;
    }

    callback = callback || function() {};

    return function() {

        if (req.body) {
            var action = req.body[paths.action];

            if (/^(delete|reset)$/.test(action)) {
                field.apply(item, action);
            }
        }

        if (req.files && req.files[paths.upload] && req.files[paths.upload].size) {
            var imageDelete;
            if (field.options.autoCleanup && item.get(field.paths.exists)) {
                // capture image delete promise
                imageDelete = field.apply(item, 'delete');
            }
            if (typeof imageDelete === 'undefined') {
                field.uploadFile(item, req.files[paths.upload], true, callback);
            } else {
                imageDelete.then(function(result) {
                    field.uploadFile(item, req.files[paths.upload], true, callback);
                }, function(err) {
                    callback(err);
                });
            }
        } else {
            return callback();
        }
    };
};

/**
 * Immediately handles a standard form submission for the field (see `getRequestHandler()`)
 *
 * @api public
 */

gcsimage.prototype.handleRequest = function(item, req, paths, callback) {
    this.getRequestHandler(item, req, paths, callback)();
};

/*!
 * Export class
 */

module.exports = gcsimage;
<|endoftext|>


<commit_before>var contentType = require("content-type");

var html = ["text/html", "application/xml+xhtml", "application/xhtml+xml"];
var css = ["text/css"];
var javascript = [
    "text/javascript",
    "application/javascript",
    "application/x-javascript"
];

function shouldProcess(config, data) {
    return config.processContentTypes.indexOf(data.contentType) != -1;
}

function parse(data) {
    try {
        return contentType.parse(data.headers["content-type"]);
    } catch (ex) {
        return {
            type: "",
            parameters: {}
        };
    }
}

function setHeader(data) {
    var type = getType(data);
    if (type) {
        data.headers["content-type"] = contentType.format({
            type: getType(data),
            parameters: {
                charset: "UTF-8"
            }
        });
    }
}

function getType(data) {
    return parse(data).type;
}

function getCharset(data) {
    return parse(data).parameters.charset;
}

module.exports.shouldProcess = shouldProcess;
module.exports.getType = getType;
module.exports.getCharset = getCharset;
module.exports.setHeader = setHeader;
module.exports.html = html;
module.exports.css = css;
module.exports.javascript = javascript;
<commit_msg>naming consistency for content types<commit_after>var contentType = require("content-type");

var html = ["text/html", "application/xml+xhtml", "application/xhtml+xml"];
var css = ["text/css"];
var javascript = [
    "text/javascript",
    "application/javascript",
    "application/x-javascript"
];

function shouldProcess(config, data) {
    return config.processContentTypes.indexOf(data.contentType) != -1;
}

function parse(data) {
    try {
        return contentType.parse(data.headers["content-type"]);
    } catch (ex) {
        return {
            type: "",
            parameters: {}
        };
    }
}

function setHeader(data) {
    var type = getType(data);
    if (type) {
        data.headers["content-type"] = contentType.format({
            type: getType(data),
            parameters: {
                charset: "UTF-8"
            }
        });
    }
}

function getType(data) {
    return parse(data).type;
}

function getCharset(data) {
    return parse(data).parameters.charset;
}

module.exports.shouldProcess = shouldProcess;
module.exports.getType = getType;
module.exports.getCharset = getCharset;
module.exports.setHeader = setHeader;
module.exports.html = html;
module.exports.css = css;
module.exports.js = javascript;
module.exports.javascript = javascript; // for backwards-compatibility
<|endoftext|>


<commit_before>import View from '../../modules/view';
import Button from '../../components/newButton/button'
import collectionUser from '../../models/collectionUser';

import './scoreboard.tmpl.xml';
import './users.tmpl.xml';
import path from '../../tools/getPath';

export default class Scoreboard extends View {
  constructor() {
    super();
    this.users = new collectionUser();

    // this.addUsers = this.addUsers.bind(this);
  }

  addUsers() {
    let {data, remainingPages = 10} = this.users.getUsers();

    if (remainingPages === 0) {
      this._el.querySelector('.button').setAttribute('style', 'display: none;');
    }

    console.log(window.fest[path + 'views/scoreboard/users.tmpl'](data));

    this._el.querySelector('.scoreboard__table').appendChild = window.fest[path + 'views/scoreboard/users.tmpl'](data);
  }

  init() {
    this._el.className = 'scoreboard';
    this._el.innerHTML = window.fest[path + 'views/scoreboard/scoreboard.tmpl']();
    this.addUsers();

    // let data = [{user: {login: 'gfgfgfgf'}}, {user: {login: 'гешпкоп', id: 'ffgfg', rating: 'gfgf'}}];

    let button1 = new Button('Single Player', {style: 'dart'});
    button1.on('click', this.addUsers.bind(this));

    this._el.querySelector('.scoreboard').appendChild(button1.render());
    document.querySelector('.content').appendChild(this._el);
  }

}
<commit_msg>коммит на коммите, сори не настроенн локально сервер<commit_after>import View from '../../modules/view';
import Button from '../../components/newButton/button'
import collectionUser from '../../models/collectionUser';

import './scoreboard.tmpl.xml';
import './users.tmpl.xml';
import path from '../../tools/getPath';

export default class Scoreboard extends View {
  constructor() {
    super();
    this.users = new collectionUser();

    // this.addUsers = this.addUsers.bind(this);
  }

  addUsers() {
    let {data, remainingPages = 10} = this.users.getUsers();

    if (remainingPages === 0) {
      this._el.querySelector('.button').setAttribute('style', 'display: none;');
    }

    console.log(window.fest[path + 'views/scoreboard/users.tmpl'](data));

    this._el.querySelector('.scoreboard__table').appendChild(window.fest[path + 'views/scoreboard/users.tmpl'](data));
  }

  init() {
    this._el.className = 'scoreboard';
    this._el.innerHTML = window.fest[path + 'views/scoreboard/scoreboard.tmpl']();
    this.addUsers();

    // let data = [{user: {login: 'gfgfgfgf'}}, {user: {login: 'гешпкоп', id: 'ffgfg', rating: 'gfgf'}}];

    let button1 = new Button('Single Player', {style: 'dart'});
    button1.on('click', this.addUsers.bind(this));

    this._el.querySelector('.scoreboard').appendChild(button1.render());
    document.querySelector('.content').appendChild(this._el);
  }

}
<|endoftext|>


<commit_before>var editor;

function apiCall(method, path, params, cb) {
  $.ajax({
    url: path,
    method: method,
    cache: false,
    data: params,
    success: function(data) {
      cb(data);
    },
    error: function(xhr, status, data) {
      cb(jQuery.parseJSON(xhr.responseText));
    }
  });
}

function getTables(cb)                { apiCall("get", "/tables", {}, cb); }
function getTableStructure(table, cb) { apiCall("get", "/tables/" + table, {}, cb); }
function getTableIndexes(table, cb)   { apiCall("get", "/tables/" + table + "/indexes", {}, cb); }
function getHistory(cb)               { apiCall("get", "/history", {}, cb); }

function executeQuery(query, cb) {
  apiCall("post", "/query", { query: query }, cb);
}

function explainQuery(query, cb) {
  apiCall("post", "/explain", { query: query }, cb);
}

function loadTables() {
  getTables(function(data) {
    data.forEach(function(item) {
      $("
" + item + "
").appendTo("#tables");
    });
  });
}

function escapeHtml(str) {
  if (str != null || str != undefined) {
    return jQuery("
").text(str).html();
  }

  return "null";
}

function resetTable() {
  $("#results").
    attr("data-mode", "").
    text("").
    removeClass("empty").
    removeClass("history");
}

function buildTable(results) {
  resetTable();

  if (results.error) {
    $("
ERROR: " + results.error + "

").appendTo("#results");
    $("#results").addClass("empty");
    return;
  }

  if (!results.rows) {
    $("
No records found

").appendTo("#results");
    $("#results").addClass("empty");
    return;
  }

  var cols = "";
  var rows = "";

  results.columns.forEach(function(col) {
    cols += "" + col + "	";
  });

  results.rows.forEach(function(row) {
    var r = "";
    for (i in row) { r += "
" + escapeHtml(row[i]) + "
	"; }
    rows += "
" + r + "
";
  });

  $("
" + cols + "

" + rows + "</tobdy>").appendTo("#results");
}

function setCurrentTab(id) {
  $("#nav ul li.selected").removeClass("selected");
  $("#" + id).addClass("selected");
}

function showQueryHistory() {
  getHistory(function(data) {
    var rows = [];

    for(i in data) {
      rows.unshift([parseInt(i) + 1, data[i]]);
    }

    buildTable({ columns: ["id", "query"], rows: rows });

    setCurrentTab("table_history");
    $("#input").hide();
    $("#output").addClass("full");
    $("#results").addClass("history");
  });
}

function showTableIndexes() {
  var name = $("#tables li.selected").text();

  if (name.length == 0) {
    alert("Please select a table!");
    return;
  }

  getTableIndexes(name, function(data) {
    setCurrentTab("table_indexes");
    buildTable(data);

    $("#input").hide();
    $("#output").addClass("full");
  });
}

function showTableInfo() {
  var name = $("#tables li.selected").text();

  if (name.length == 0) {
    alert("Please select a table!");
    return;
  }

  apiCall("get", "/tables/" + name + "/info", {}, function(data) {
    $(".table-information ul").show();
    $("#table_total_size").text(data.total_size);
    $("#table_data_size").text(data.data_size);
    $("#table_index_size").text(data.index_size);
    $("#table_rows_count").text(data.rows_count);
    $("#table_encoding").text("Unknown");
  });
}

function showTableContent() {
  var name = $("#tables li.selected").text();

  if (name.length == 0) {
    alert("Please select a table!");
    return;
  }

  var query = "SELECT * FROM \"" + name + "\" LIMIT 100;";

  executeQuery(query, function(data) {
    buildTable(data);
    setCurrentTab("table_content");

    $("#results").attr("data-mode", "browse");
    $("#input").hide();
    $("#output").addClass("full");
  });
}

function showTableStructure() {
  var name = $("#tables li.selected").text();

  if (name.length == 0) {
    alert("Please select a table!");
    return;
  }

  getTableStructure(name, function(data) {
    setCurrentTab("table_structure");
    buildTable(data);
  });
}

function runQuery() {
  setCurrentTab("table_query");

  $("#run").attr("disabled", "disabled");
  $("#explain").attr("disabled", "disabled");
  $("#csv").attr("disabled", "disabled");
  $("#query_progress").show();

  var query = $.trim(editor.getValue());

  if (query.length == 0) {
    $("#run").removeAttr("disabled");
    $("#explain").removeAttr("disabled");
    $("#csv").removeAttr("disabled");
    $("#query_progress").hide();
    return;
  }

  executeQuery(query, function(data) {
    buildTable(data);

    $("#run").removeAttr("disabled");
    $("#explain").removeAttr("disabled");
    $("#csv").removeAttr("disabled");
    $("#query_progress").hide();
    $("#input").show();
    $("#output").removeClass("full");
  });
}

function runExplain() {
  setCurrentTab("table_query");

  $("#run").attr("disabled", "disabled");
  $("#explain").attr("disabled", "disabled");
  $("#csv").attr("disabled", "disabled");
  $("#query_progress").show();

  var query = $.trim(editor.getValue());

  if (query.length == 0) {
    $("#run").removeAttr("disabled");
    $("#explain").removeAttr("disabled");
    $("#csv").removeAttr("disabled");
    $("#query_progress").hide();
    return;
  }

  explainQuery(query, function(data) {
    buildTable(data);

    $("#run").removeAttr("disabled");
    $("#explain").removeAttr("disabled");
    $("#csv").removeAttr("disabled");
    $("#query_progress").hide();
    $("#input").show();
    $("#output").removeClass("full");
  });
}

function exportToCSV() {
  var query = $.trim(editor.getValue());

  if (query.length == 0) {
    return;
  }

  // Replace line breaks with spaces
  query = query.replace(/\n/g, " ");

  setCurrentTab("table_query");

  var url = "http://" + window.location.host + "/query?format=csv&query=" + query;
  var win = window.open(url, '_blank');

  win.focus();
}

function initEditor() {
  editor = ace.edit("custom_query");

  editor.getSession().setMode("ace/mode/pgsql");
  editor.getSession().setTabSize(2);
  editor.getSession().setUseSoftTabs(true);
}

$(document).ready(function() {
  initEditor();

  $("#table_content").on("click",   function() { showTableContent();   });
  $("#table_structure").on("click", function() { showTableStructure(); });
  $("#table_indexes").on("click",   function() { showTableIndexes();   });
  $("#table_history").on("click",   function() { showQueryHistory();   });

  $("#table_query").on("click", function() {
    setCurrentTab("table_query");
    $("#input").show();
    $("#output").removeClass("full");
  });

  $("#run").on("click", function() {
    runQuery();
  });

  $("#explain").on("click", function() {
    runExplain();
  });

  $("#csv").on("click", function() {
    exportToCSV();
  });

  $("#results").on("click", "tr", function() {
    $("#results tr.selected").removeClass();
    $(this).addClass("selected");
  });

  $("#tables").on("click", "li", function() {
    $("#tables li.selected").removeClass("selected");
    $(this).addClass("selected");
    showTableContent();
    showTableInfo();
  });

  loadTables();
});<commit_msg>Set focus on editor when switching to 'SQL Query' view, fixes #28<commit_after>var editor;

function apiCall(method, path, params, cb) {
  $.ajax({
    url: path,
    method: method,
    cache: false,
    data: params,
    success: function(data) {
      cb(data);
    },
    error: function(xhr, status, data) {
      cb(jQuery.parseJSON(xhr.responseText));
    }
  });
}

function getTables(cb)                { apiCall("get", "/tables", {}, cb); }
function getTableStructure(table, cb) { apiCall("get", "/tables/" + table, {}, cb); }
function getTableIndexes(table, cb)   { apiCall("get", "/tables/" + table + "/indexes", {}, cb); }
function getHistory(cb)               { apiCall("get", "/history", {}, cb); }

function executeQuery(query, cb) {
  apiCall("post", "/query", { query: query }, cb);
}

function explainQuery(query, cb) {
  apiCall("post", "/explain", { query: query }, cb);
}

function loadTables() {
  getTables(function(data) {
    data.forEach(function(item) {
      $("
" + item + "
").appendTo("#tables");
    });
  });
}

function escapeHtml(str) {
  if (str != null || str != undefined) {
    return jQuery("
").text(str).html();
  }

  return "null";
}

function resetTable() {
  $("#results").
    attr("data-mode", "").
    text("").
    removeClass("empty").
    removeClass("history");
}

function buildTable(results) {
  resetTable();

  if (results.error) {
    $("
ERROR: " + results.error + "

").appendTo("#results");
    $("#results").addClass("empty");
    return;
  }

  if (!results.rows) {
    $("
No records found

").appendTo("#results");
    $("#results").addClass("empty");
    return;
  }

  var cols = "";
  var rows = "";

  results.columns.forEach(function(col) {
    cols += "" + col + "	";
  });

  results.rows.forEach(function(row) {
    var r = "";
    for (i in row) { r += "
" + escapeHtml(row[i]) + "
	"; }
    rows += "
" + r + "
";
  });

  $("
" + cols + "

" + rows + "</tobdy>").appendTo("#results");
}

function setCurrentTab(id) {
  $("#nav ul li.selected").removeClass("selected");
  $("#" + id).addClass("selected");
}

function showQueryHistory() {
  getHistory(function(data) {
    var rows = [];

    for(i in data) {
      rows.unshift([parseInt(i) + 1, data[i]]);
    }

    buildTable({ columns: ["id", "query"], rows: rows });

    setCurrentTab("table_history");
    $("#input").hide();
    $("#output").addClass("full");
    $("#results").addClass("history");
  });
}

function showTableIndexes() {
  var name = $("#tables li.selected").text();

  if (name.length == 0) {
    alert("Please select a table!");
    return;
  }

  getTableIndexes(name, function(data) {
    setCurrentTab("table_indexes");
    buildTable(data);

    $("#input").hide();
    $("#output").addClass("full");
  });
}

function showTableInfo() {
  var name = $("#tables li.selected").text();

  if (name.length == 0) {
    alert("Please select a table!");
    return;
  }

  apiCall("get", "/tables/" + name + "/info", {}, function(data) {
    $(".table-information ul").show();
    $("#table_total_size").text(data.total_size);
    $("#table_data_size").text(data.data_size);
    $("#table_index_size").text(data.index_size);
    $("#table_rows_count").text(data.rows_count);
    $("#table_encoding").text("Unknown");
  });
}

function showTableContent() {
  var name = $("#tables li.selected").text();

  if (name.length == 0) {
    alert("Please select a table!");
    return;
  }

  var query = "SELECT * FROM \"" + name + "\" LIMIT 100;";

  executeQuery(query, function(data) {
    buildTable(data);
    setCurrentTab("table_content");

    $("#results").attr("data-mode", "browse");
    $("#input").hide();
    $("#output").addClass("full");
  });
}

function showTableStructure() {
  var name = $("#tables li.selected").text();

  if (name.length == 0) {
    alert("Please select a table!");
    return;
  }

  getTableStructure(name, function(data) {
    setCurrentTab("table_structure");
    buildTable(data);
  });
}

function showQueryPanel() {
  setCurrentTab("table_query");
  editor.focus();

  $("#input").show();
  $("#output").removeClass("full");
}

function runQuery() {
  setCurrentTab("table_query");

  $("#run").attr("disabled", "disabled");
  $("#explain").attr("disabled", "disabled");
  $("#csv").attr("disabled", "disabled");
  $("#query_progress").show();

  var query = $.trim(editor.getValue());

  if (query.length == 0) {
    $("#run").removeAttr("disabled");
    $("#explain").removeAttr("disabled");
    $("#csv").removeAttr("disabled");
    $("#query_progress").hide();
    return;
  }

  executeQuery(query, function(data) {
    buildTable(data);

    $("#run").removeAttr("disabled");
    $("#explain").removeAttr("disabled");
    $("#csv").removeAttr("disabled");
    $("#query_progress").hide();
    $("#input").show();
    $("#output").removeClass("full");
  });
}

function runExplain() {
  setCurrentTab("table_query");

  $("#run").attr("disabled", "disabled");
  $("#explain").attr("disabled", "disabled");
  $("#csv").attr("disabled", "disabled");
  $("#query_progress").show();

  var query = $.trim(editor.getValue());

  if (query.length == 0) {
    $("#run").removeAttr("disabled");
    $("#explain").removeAttr("disabled");
    $("#csv").removeAttr("disabled");
    $("#query_progress").hide();
    return;
  }

  explainQuery(query, function(data) {
    buildTable(data);

    $("#run").removeAttr("disabled");
    $("#explain").removeAttr("disabled");
    $("#csv").removeAttr("disabled");
    $("#query_progress").hide();
    $("#input").show();
    $("#output").removeClass("full");
  });
}

function exportToCSV() {
  var query = $.trim(editor.getValue());

  if (query.length == 0) {
    return;
  }

  // Replace line breaks with spaces
  query = query.replace(/\n/g, " ");

  setCurrentTab("table_query");

  var url = "http://" + window.location.host + "/query?format=csv&query=" + query;
  var win = window.open(url, '_blank');

  win.focus();
}

function initEditor() {
  editor = ace.edit("custom_query");

  editor.getSession().setMode("ace/mode/pgsql");
  editor.getSession().setTabSize(2);
  editor.getSession().setUseSoftTabs(true);
}

$(document).ready(function() {
  initEditor();

  $("#table_content").on("click",   function() { showTableContent();   });
  $("#table_structure").on("click", function() { showTableStructure(); });
  $("#table_indexes").on("click",   function() { showTableIndexes();   });
  $("#table_history").on("click",   function() { showQueryHistory();   });
  $("#table_query").on("click",     function() { showQueryPanel();     });

  $("#run").on("click", function() {
    runQuery();
  });

  $("#explain").on("click", function() {
    runExplain();
  });

  $("#csv").on("click", function() {
    exportToCSV();
  });

  $("#results").on("click", "tr", function() {
    $("#results tr.selected").removeClass();
    $(this).addClass("selected");
  });

  $("#tables").on("click", "li", function() {
    $("#tables li.selected").removeClass("selected");
    $(this).addClass("selected");
    showTableContent();
    showTableInfo();
  });

  loadTables();
});<|endoftext|>


<commit_before>$(document).ready(function(){
    var map;

    var imagesPool = (function(){
        var icons = {};
        function iconExists(type) {
            return typeof icons[type] !== 'undefined';
        }

        function iconGet(type) {
            if (typeof icons[type] !== 'undefined') {
                return icons[type];
            }

            var icon = new google.maps.MarkerImage(
                'static/images/vehicle-types/' + type + '.png',
                 new google.maps.Size(20, 20),
                 new google.maps.Point(0, 0),
                 new google.maps.Point(10, 10)
            );
            icons[type] = icon;

            return icon;
        }

        return {
            iconGet: iconGet
        }
    })();

    var linesPool = (function() {
        var routes = {};

        function positionOnRouteAtPercentGet(ids, perc) {
            var route = routes[ids[0] + '_' + ids[1]];

            var dC = 0;
            var dAC = route['length']*perc;

            for (var i=1; i<route['points'].length; i++) {
                var pA = route['points'][i-1];
                var pB = route['points'][i];
                var d12 = google.maps.geometry.spherical.computeDistanceBetween(pA, pB);
                if ((dC + d12) > dAC) {
                    return google.maps.geometry.spherical.interpolate(pA, pB, (dAC - dC)/d12);
                }
                dC += d12;
            }

            return null;
        }

        function routeExists(a, b) {
          if (typeof routes[a + '_' + b] !== 'undefined') {
              return true;
          }
          if (typeof routes[b + '_' + a] !== 'undefined') {
              return true;
          }

          return false;
        }

        function routeAdd(a, b, edges) {
            var routePoints = [];
            $.each(edges, function(k, edgeID) {
                var edge = simcity_topology_edges[Math.abs(edgeID)];

                var points = google.maps.geometry.encoding.decodePath(edge);
                if (edgeID < 0) {
                    points.reverse();
                }
                // TODO - use some MVCArray magic to remove the last element of edges when concatenating ?
                routePoints = routePoints.concat(points);
            });

            routeLength = google.maps.geometry.spherical.computeLength(routePoints).toFixed(3);

            routes[a + '_' + b] = {
                'points': routePoints,
                'length': routeLength
            };
            routes[b + '_' + a] = {
                'points': routePoints.slice().reverse(),
                'length': routeLength
            };
        }

        return {
            positionGet: positionOnRouteAtPercentGet,
            routeExists: routeExists,
            routeAdd: routeAdd
        }
    })();
    var time_helpers = (function(){
        function hms2s(hms) {
            var parts = hms.split(':');
            return parseInt(parts[0], 10)*3600 + parseInt(parts[1], 10)*60 + parseInt(parts[2], 10);
        }
        function s2hms(dayS) {
            function pad2Dec(what) {
                return (what < 10 ? '0' + what : what);
            }

            // From http://stackoverflow.com/questions/1322732/convert-seconds-to-hh-mm-ss-with-javascript
            var hours = Math.floor(dayS / 3600);
            dayS %= 3600;
            var minutes = Math.floor(dayS / 60);
            var seconds = dayS % 60;

            return pad2Dec(hours) + ':' + pad2Dec(minutes) + ':' + pad2Dec(seconds);
        }
        return {
            hms2s: hms2s,
            s2hms: s2hms
        }
    })();
    var timer = (function(){
        var delay = 0;

        function getNow() {
            var now = new Date();

            var hours = now.getHours();
            var minutes = now.getMinutes();
            var seconds = now.getSeconds();

            return hours*3600 + minutes*60 + seconds;
        }

        function getDaySeconds() {
            return getNow() - delay;
        }

        function init(hms) {
            if (typeof(hms) !== 'undefined') {
                delay = getNow() - time_helpers.hms2s(hms);
            }

            var timeContainer = $('#day_time');
            function paintHM() {
                timeContainer.text(time_helpers.s2hms(getDaySeconds()));
            }

            setInterval(function(){
                paintHM();
            }, 1000);
        }

        function getHM() {
          var hms = time_helpers.s2hms(getDaySeconds());
          return hms.substring(0, 5);
        }

        return {
            init: init,
            getTime: getDaySeconds,
            getHM: getHM
        }
    })();

    var map_helpers = (function(){
        function init() {
            var mapStyles = [
              {
                featureType: "poi.business",
                stylers: [
                  { visibility: "off" }
                ]
              },{
                featureType: "road",
                elementType: "labels",
                stylers: [
                  { visibility: "off" }
                ]
              },{
                featureType: "road",
                elementType: "labels",
                stylers: [
                  { visibility: "off" }
                ]
              },{
                featureType: "road",
                elementType: "geometry",
                stylers: [
                  { visibility: "simplified" },
                  { lightness: 70 }
                ]
              },{
                featureType: "transit.line",
                stylers: [
                  { visibility: "off" }
                ]
              },{
                featureType: "transit.station.bus",
                stylers: [
                  { visibility: "off" }
                ]
              }
            ];

            var start = new google.maps.LatLng(47.378057, 8.5402338);
            var myOptions = {
              zoom: 15,
              center: start,
              mapTypeId: google.maps.MapTypeId.ROADMAP,
              styles: mapStyles
            }
            map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);

            var layer = null;
            layer = new google.maps.FusionTablesLayer({
              query: {
                select: 'geometry',
                from: '1497331'
              },
              clickable: false,
              map: map
            });
            var stations_layer = new google.maps.FusionTablesLayer({
              query: {
                select: 'geometry',
                from: '1497361'
              },
              clickable: false,
              map: map
            });
            layer = new google.maps.FusionTablesLayer({
              query: {
                select: 'geometry',
                from: '812706'
              },
              clickable: false,
              map: map
            });

            google.maps.event.addListener(map, 'idle', function() {
                var zoom = map.getZoom();
                if (zoom < 12) {
                    if (stations_layer.getMap() !== null) {
                        stations_layer.setMap(null);
                    }
                } else {
                    if (stations_layer.getMap() === null) {
                        stations_layer.setMap(map);
                    }
                }
            });
        }

        return {
            init: init
        }
    })();

    var vehicle_helpers = (function(){
        var vehicles = [];

        function Vehicle(params) {
            this.id             = params['id'];
            this.stations       = params['sts'];
            this.depS           = params['deps'];
            this.arrS           = params['arrs'];

            $.each(params.edges, function(index, edge) {
                if (index === 0) { return; }

                if (linesPool.routeExists(params['sts'][index-1], params['sts'][index])) {
                    return;
                }

                linesPool.routeAdd(params['sts'][index-1], params['sts'][index], params['edges'][index].split(','));
            });

            this.marker = new google.maps.Marker({
                position: new google.maps.LatLng(0, 0),
                icon: imagesPool.iconGet(params['type']),
                map: map,
                title: params['name'] + ' (' + this.id + ')'
            });
        }
        Vehicle.prototype.render = function() {
            function animate() {
                var hms = timer.getTime();

                var info = {
                    state: null
                };
                for (var i=0; i<that.arrS.length; i++) {
                    if (hms < that.arrS[i]) {
                        if (hms > that.depS[i]) {
                            info = {
                                state: 'motion',
                                stations: [that.stations[i], that.stations[i+1]],
                                percent: (hms - that.depS[i])/(that.arrS[i] - that.depS[i]),
                                message: that.id + '> ' + time_helpers.s2hms(hms) + ' From ' + that.stations[i] + ' --TO-- ' + that.stations[i+1]
                            };
                        } else {
                            info = {
                                state: 'station',
                                station: that.stations[i],
                                timeLeft: that.depS[i] - hms,
                                message: that.id + '> ' + time_helpers.s2hms(hms) + ' In station ' + that.stations[i] + ' until ' + time_helpers.s2hms(that.depS[i])
                            };
                        }
                        break;
                    }
                }

                // TODO - move me above - is waste of code
                switch (info.state) {
                    case 'station':
                        // TODO - if is not yet on the map, add it (first vertex of the route)
                        setTimeout(animate, info.timeLeft*1000);
                        break;
                    case 'motion':
                        var pos = linesPool.positionGet(info.stations, info.percent);
                        if (pos === null) {
                            console.log('Couldnt get the position of ' + that.id + ' between stations: ' + info.stations);
                            break;
                        }

                        if (map.getBounds().contains(pos)) {
                            if (that.marker.getMap() === null) {
                                that.marker.setMap(map);
                            }
                            that.marker.setPosition(pos);
                        } else {
                            that.marker.setMap(null);
                        }

                        setTimeout(animate, 500);
                        break;
                    default:
                        that.marker.setMap(null);
                        break;
                }
            }

            var that = this;
            animate();
        };

        return {
            get: function() {
                $.ajax({
                  url: 'feed/vehicles/' + timer.getHM(),
                  dataType: 'json',
                  success: function(vehicles) {
                    $.each(vehicles, function(index, data) {
                        if (vehicles.indexOf(data['id']) !== -1) {
                            console.log("Vehicle %s is already added", data['id']);
                            return;
                        }

                        var v = new Vehicle(data);
                        v.render();
                        vehicles.push(data['id']);
                    });
                  }
                });
            }
        }
    })();

    // END HELPERS

    var nowHMS = '10:16:55';
    timer.init(nowHMS);
    map_helpers.init();
    vehicle_helpers.get();
});<commit_msg>Started to load new vehicles every 5 minutes<commit_after>$(document).ready(function(){
    var map;

    var imagesPool = (function(){
        var icons = {};
        function iconExists(type) {
            return typeof icons[type] !== 'undefined';
        }

        function iconGet(type) {
            if (typeof icons[type] !== 'undefined') {
                return icons[type];
            }

            var icon = new google.maps.MarkerImage(
                'static/images/vehicle-types/' + type + '.png',
                 new google.maps.Size(20, 20),
                 new google.maps.Point(0, 0),
                 new google.maps.Point(10, 10)
            );
            icons[type] = icon;

            return icon;
        }

        return {
            iconGet: iconGet
        }
    })();

    var linesPool = (function() {
        var routes = {};

        function positionOnRouteAtPercentGet(ids, perc) {
            var route = routes[ids[0] + '_' + ids[1]];

            var dC = 0;
            var dAC = route['length']*perc;

            for (var i=1; i<route['points'].length; i++) {
                var pA = route['points'][i-1];
                var pB = route['points'][i];
                var d12 = google.maps.geometry.spherical.computeDistanceBetween(pA, pB);
                if ((dC + d12) > dAC) {
                    return google.maps.geometry.spherical.interpolate(pA, pB, (dAC - dC)/d12);
                }
                dC += d12;
            }

            return null;
        }

        function routeExists(a, b) {
          if (typeof routes[a + '_' + b] !== 'undefined') {
              return true;
          }
          if (typeof routes[b + '_' + a] !== 'undefined') {
              return true;
          }

          return false;
        }

        function routeAdd(a, b, edges) {
            var routePoints = [];
            $.each(edges, function(k, edgeID) {
                var edge = simcity_topology_edges[Math.abs(edgeID)];

                var points = google.maps.geometry.encoding.decodePath(edge);
                if (edgeID < 0) {
                    points.reverse();
                }
                // TODO - use some MVCArray magic to remove the last element of edges when concatenating ?
                routePoints = routePoints.concat(points);
            });

            routeLength = google.maps.geometry.spherical.computeLength(routePoints).toFixed(3);

            routes[a + '_' + b] = {
                'points': routePoints,
                'length': routeLength
            };
            routes[b + '_' + a] = {
                'points': routePoints.slice().reverse(),
                'length': routeLength
            };
        }

        return {
            positionGet: positionOnRouteAtPercentGet,
            routeExists: routeExists,
            routeAdd: routeAdd
        }
    })();
    var time_helpers = (function(){
        function hms2s(hms) {
            var parts = hms.split(':');
            return parseInt(parts[0], 10)*3600 + parseInt(parts[1], 10)*60 + parseInt(parts[2], 10);
        }
        function s2hms(dayS) {
            function pad2Dec(what) {
                return (what < 10 ? '0' + what : what);
            }

            // From http://stackoverflow.com/questions/1322732/convert-seconds-to-hh-mm-ss-with-javascript
            var hours = Math.floor(dayS / 3600);
            dayS %= 3600;
            var minutes = Math.floor(dayS / 60);
            var seconds = dayS % 60;

            return pad2Dec(hours) + ':' + pad2Dec(minutes) + ':' + pad2Dec(seconds);
        }
        return {
            hms2s: hms2s,
            s2hms: s2hms
        }
    })();
    var timer = (function(){
        var delay = 0;

        function getNow() {
            var now = new Date();

            var hours = now.getHours();
            var minutes = now.getMinutes();
            var seconds = now.getSeconds();

            return hours*3600 + minutes*60 + seconds;
        }

        function getDaySeconds() {
            return getNow() - delay;
        }

        function init(hms) {
            if (typeof(hms) !== 'undefined') {
                delay = getNow() - time_helpers.hms2s(hms);
            }

            var timeContainer = $('#day_time');
            function paintHM() {
                timeContainer.text(time_helpers.s2hms(getDaySeconds()));
            }

            setInterval(function(){
                paintHM();
            }, 1000);
        }

        function getHM() {
          var hms = time_helpers.s2hms(getDaySeconds());
          return hms.substring(0, 5);
        }

        return {
            init: init,
            getTime: getDaySeconds,
            getHM: getHM
        }
    })();

    var map_helpers = (function(){
        function init() {
            var mapStyles = [
              {
                featureType: "poi.business",
                stylers: [
                  { visibility: "off" }
                ]
              },{
                featureType: "road",
                elementType: "labels",
                stylers: [
                  { visibility: "off" }
                ]
              },{
                featureType: "road",
                elementType: "labels",
                stylers: [
                  { visibility: "off" }
                ]
              },{
                featureType: "road",
                elementType: "geometry",
                stylers: [
                  { visibility: "simplified" },
                  { lightness: 70 }
                ]
              },{
                featureType: "transit.line",
                stylers: [
                  { visibility: "off" }
                ]
              },{
                featureType: "transit.station.bus",
                stylers: [
                  { visibility: "off" }
                ]
              }
            ];

            var start = new google.maps.LatLng(47.378057, 8.5402338);
            var myOptions = {
              zoom: 15,
              center: start,
              mapTypeId: google.maps.MapTypeId.ROADMAP,
              styles: mapStyles
            }
            map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);

            var layer = null;
            layer = new google.maps.FusionTablesLayer({
              query: {
                select: 'geometry',
                from: '1497331'
              },
              clickable: false,
              map: map
            });
            var stations_layer = new google.maps.FusionTablesLayer({
              query: {
                select: 'geometry',
                from: '1497361'
              },
              clickable: false,
              map: map
            });
            layer = new google.maps.FusionTablesLayer({
              query: {
                select: 'geometry',
                from: '812706'
              },
              clickable: false,
              map: map
            });

            google.maps.event.addListener(map, 'idle', function() {
                var zoom = map.getZoom();
                if (zoom < 12) {
                    if (stations_layer.getMap() !== null) {
                        stations_layer.setMap(null);
                    }
                } else {
                    if (stations_layer.getMap() === null) {
                        stations_layer.setMap(map);
                    }
                }
            });
        }

        return {
            init: init
        }
    })();

    var vehicle_helpers = (function(){
        var vehicleIDs = [];

        function Vehicle(params) {
            this.id             = params['id'];
            this.stations       = params['sts'];
            this.depS           = params['deps'];
            this.arrS           = params['arrs'];

            $.each(params.edges, function(index, edge) {
                if (index === 0) { return; }

                if (linesPool.routeExists(params['sts'][index-1], params['sts'][index])) {
                    return;
                }

                linesPool.routeAdd(params['sts'][index-1], params['sts'][index], params['edges'][index].split(','));
            });

            this.marker = new google.maps.Marker({
                position: new google.maps.LatLng(0, 0),
                icon: imagesPool.iconGet(params['type']),
                map: map,
                title: params['name'] + ' (' + this.id + ')'
            });
        }
        Vehicle.prototype.render = function() {
            function animate() {
                var hms = timer.getTime();

                var info = {
                    state: null
                };
                for (var i=0; i<that.arrS.length; i++) {
                    if (hms < that.arrS[i]) {
                        if (hms > that.depS[i]) {
                            info = {
                                state: 'motion',
                                stations: [that.stations[i], that.stations[i+1]],
                                percent: (hms - that.depS[i])/(that.arrS[i] - that.depS[i]),
                                message: that.id + '> ' + time_helpers.s2hms(hms) + ' From ' + that.stations[i] + ' --TO-- ' + that.stations[i+1]
                            };
                        } else {
                            info = {
                                state: 'station',
                                station: that.stations[i],
                                timeLeft: that.depS[i] - hms,
                                message: that.id + '> ' + time_helpers.s2hms(hms) + ' In station ' + that.stations[i] + ' until ' + time_helpers.s2hms(that.depS[i])
                            };
                        }
                        break;
                    }
                }

                // TODO - move me above - is waste of code
                switch (info.state) {
                    case 'station':
                        // TODO - if is not yet on the map, add it (first vertex of the route)
                        setTimeout(animate, info.timeLeft*1000);
                        break;
                    case 'motion':
                        var pos = linesPool.positionGet(info.stations, info.percent);
                        if (pos === null) {
                            console.log('Couldnt get the position of ' + that.id + ' between stations: ' + info.stations);
                            break;
                        }

                        if (map.getBounds().contains(pos)) {
                            if (that.marker.getMap() === null) {
                                that.marker.setMap(map);
                            }
                            that.marker.setPosition(pos);
                        } else {
                            that.marker.setMap(null);
                        }

                        setTimeout(animate, 500);
                        break;
                    default:
                        that.marker.setMap(null);
                        break;
                }
            }

            var that = this;
            animate();
        };

        return {
            get: function() {
                $.ajax({
                  url: 'feed/vehicles/' + timer.getHM(),
                  dataType: 'json',
                  success: function(vehicles) {
                    $.each(vehicles, function(index, data) {
                        if (vehicleIDs.indexOf(data['id']) !== -1) { return; }

                        var v = new Vehicle(data);
                        v.render();
                        vehicleIDs.push(data['id']);
                    });
                  }
                });
            }
        }
    })();

    // END HELPERS

    var nowHMS = '10:16:55';
    timer.init(nowHMS);
    map_helpers.init();
    vehicle_helpers.get();
    setInterval(vehicle_helpers.get, 5*60*1000);
});<|endoftext|>


<commit_before>function get_icon(type) {
    var size = 12;
    var zoom = map.getZoom();
    return L.icon({
        iconSize: [size * zoom, size * zoom],
        iconAnchor: [size * zoom / 2, size * zoom],
        iconUrl: imgdir + '/markers/' + type + '.svg'
    });
}

var map = L.map('map', {
    attributionControl: false
}).fitWorld();

map.on("click", function (e) {
    var latlng = e.latlng;

    function get_marker(latlng) {
        var marker = L.marker(latlng, {
            icon: get_icon("NEW"),
            draggable: true
        });
        $(map).one("zoomend", function (e) {
            if (map.hasLayer(marker)) {
                map.removeLayer(marker);
                get_marker(marker._latlng);
            }
        });
        $(map).one("click", function() {
            map.removeLayer(marker);
        });
        marker.on("click", function() {
            var latlng = this._latlng;
            // TODO: popup, etc.
            alert("marker is at " + latlng.lat + "," + latlng.lng);
        });
        map.addLayer(marker);
    }

    get_marker(latlng);
});

L.tileLayer(imgdir + '/tiles/{z}/{x}/{y}.png', {
    // Have a look in static/img/tiles.
    // The directories present there correspond to zoom levels.
    minZoom: 0,
    maxZoom: 6,
    tms: true,
    noWrap: true
}).addTo(map);

function get_dp_layer() {
    var layer = L.geoJson(all_dps_geojson, {
        filter: function (feature) {
            return feature.geometry.coordinates[0] != null &&
                feature.geometry.coordinates[0] != null;
        },
        pointToLayer: function (feature, latlng) {
            var marker = L.marker(latlng, {
                icon: get_icon(feature.properties.last_state)
            });
            marker.on("click",
                function (e) {
                    var dp = e.target.feature;
                    show_dp_modal(dp.properties.number, "report");
                }
            );
            return marker;
        }
    });
    $(map).one("zoomend", function () {
        map.removeLayer(layer);
        dp_layer = get_dp_layer();
        map.addLayer(dp_layer);
    });
    return layer;
}

var dp_layer = get_dp_layer();
map.addLayer(dp_layer);

/* vim: set expandtab ts=4 sw=4: */
<commit_msg>Add popup and create dp button to map<commit_after>function get_icon(type) {
    var size = 12;
    var zoom = map.getZoom();
    return L.icon({
        iconSize: [size * zoom, size * zoom],
        iconAnchor: [size * zoom / 2, size * zoom],
        iconUrl: imgdir + '/markers/' + type + '.svg',
        popupAnchor: [0, -size * zoom]
    });
}

var map = L.map('map', {
    attributionControl: false
}).fitWorld();

var foo;

map.on("click", function (e) {
    var latlng = e.latlng;
    function get_marker(latlng) {
        var marker = L.marker(latlng, {
            icon: get_icon("NEW"),
            draggable: true
        });
        $(map).one("zoomend", function (e) {
            if (map.hasLayer(marker)) {
                map.removeLayer(marker);
                get_marker(marker._latlng);
            }
        });
        $(map).one("click", function() {
            map.removeLayer(marker);
        });
        marker.bindPopup(L.popup({closeButton: false}).setContent(
            "<button class='btn btn-primary' id='new-dp-button'>" +
            "Create a new drop point" +
            "</button>"
        ));
        map.addLayer(marker);
        return marker;
    }
    var marker = get_marker(latlng);
    marker.openPopup();
});

L.tileLayer(imgdir + '/tiles/{z}/{x}/{y}.png', {
    // Have a look in static/img/tiles.
    // The directories present there correspond to zoom levels.
    minZoom: 0,
    maxZoom: 6,
    tms: true,
    noWrap: true
}).addTo(map);

function get_dp_layer() {
    var layer = L.geoJson(all_dps_geojson, {
        filter: function (feature) {
            return feature.geometry.coordinates[0] != null &&
                feature.geometry.coordinates[0] != null;
        },
        pointToLayer: function (feature, latlng) {
            var marker = L.marker(latlng, {
                icon: get_icon(feature.properties.last_state)
            });
            marker.on("click",
                function (e) {
                    var dp = e.target.feature;
                    show_dp_modal(dp.properties.number, "report");
                }
            );
            return marker;
        }
    });
    $(map).one("zoomend", function () {
        map.removeLayer(layer);
        dp_layer = get_dp_layer();
        map.addLayer(dp_layer);
    });
    return layer;
}

var dp_layer = get_dp_layer();
map.addLayer(dp_layer);

/* vim: set expandtab ts=4 sw=4: */
<|endoftext|>


<commit_before>const statsd = require('./statsd')
const githubQueue = require('./github-queue')
const _ = require('lodash')

const { getNewLockfile } = require('../lib/lockfile')
const { getLockfilePath } = require('../utils/utils')

const Log = require('gk-log')
const dbs = require('../lib/dbs')

global.Promise = require('bluebird')

module.exports = async (
  {
    installationId,
    newBranch,
    branch,
    owner,
    repoName,
    repoDoc,
    message,
    transforms,
    path,
    transform,
    processLockfiles,
    lockFileCommitMessage
  }
) => {
  if (!transforms) transforms = [{ transform, path, message }]
  const ghqueue = githubQueue(installationId)
  let contents = {}

  const commits = (await Promise.mapSeries(transforms, async (
    { path, transform, message, create },
    index
  ) => {
    let blob = {}
    try {
      if (contents[path]) {
        blob.content = contents[path]
      } else {
        if (path === 'README.md') {
          blob = await ghqueue.read(github => github.repos.getReadme({ owner, repo: repoName, ref: branch }))
          path = blob.path
        } else {
          blob = await ghqueue.read(github => github.repos.getContent({
            owner,
            repo: repoName,
            path,
            ref: branch
          }))
        }
      }
    } catch (e) {
      if (e.code !== 404) throw e
      if (!create) return
    }
    let oldContent
    if (contents[path]) {
      oldContent = contents[path]
    } else {
      oldContent = blob.content ? Buffer.from(blob.content, 'base64').toString() : ''
    }

    contents[path] = await transform(oldContent, path)
    if (!contents[path] || contents[path] === oldContent) return
    return { path, content: contents[path], message, index }
  })).filter(c => c)

  if (commits.length === 0) return

  /*
  After processing all the transforms and checking whether they generated any commits,
  we check each commit whether it affected a `package.json`, and generate its lockfile,
  if applicable.

  Note that there are no transforms for these commits. They are added on to the end of
  the commits array and receive an index value, but that doesn’t correspond to an index
  of the transforms array.

  Transforms array:
  ['readme', 'travis', 'package.json', 'yay/package.json']
  Commit array with lockfiles (lockfiles are in reverse order):
  ['readme', 'travis', 'package.json', 'yay/package.json', 'yay/package-lock.json', 'package-lock.json']

  */
  if (processLockfiles && repoDoc && repoDoc.files) {
    const logs = dbs.getLogsDb()
    const log = Log({logsDb: logs, accountId: repoDoc.accountId, repoSlug: repoDoc.fullName, context: 'create-branch'})
    // we need to iterate over every changed package file, not every package file commit
    // we reverse because we want the most recent commit with the all the changes to the file (the last one)
    // we clone because we don’t actually want to do the commits backwards
    const dedupedCommits = _.uniqBy(_.clone(commits).reverse(), commit => commit.path)
    for (const commit of dedupedCommits) {
      // continue skips the current iteration but continues with the for loop as a whole
      if (!commit.path.includes('package.json')) continue
      const lockfilePath = getLockfilePath(repoDoc.files, commit.path)

      if (!lockfilePath) continue
      log.info('starting lockfile update', {lockfilePath})

      const oldLockfile = await ghqueue.read(github => github.repos.getContent({ path: lockfilePath, owner, repo: repoName }))
      const oldLockfileContent = Buffer.from(oldLockfile.content, 'base64').toString()
      log.info('received existing lockfile from GitHub')

      const isNpm = lockfilePath.includes('package-lock.json')
      try {
        const {ok, contents} = await getNewLockfile(commit.content, oldLockfileContent, isNpm)
        if (ok) {
          // !ok means the old and new lockfile are the same, so we don’t make a commit
          log.info('new lockfile contents produced')
          statsd.increment('lockfiles')
          commits.push({
            path: lockfilePath,
            content: contents,
            message: lockFileCommitMessage,
            index: commits.length
          })
        }
      } catch (e) {
        log.error('error fetching updated lockfile from exec server', {e})
      }
    }
  }

  const head = await ghqueue.read(github => github.gitdata.getReference({
    owner,
    repo: repoName,
    ref: `heads/${branch}`
  }))

  const createCommits = async (sha, { path, content, message, index }) => {
    const newTree = await ghqueue.write(github => github.gitdata.createTree({
      owner,
      repo: repoName,
      base_tree: sha,
      tree: [{ path, content, mode: '100644', type: 'blob' }]
    }))

    const commit = await ghqueue.write(github => github.gitdata.createCommit({
      owner,
      repo: repoName,
      message,
      tree: newTree.sha,
      parents: [sha]
    }))
    /*
      .created is written back into the original transform which is still used
      after create-branch is called from wherever, create-initial-branch for example. So after
      create-branch returns its SHA to create-initial-branch, the latter can check whether, for
      example, travis.yml or readme.md were modified. This is then passed into create-pr or
      whatever else sends messages to humans, where we can then notify them which files were
      MODIFIED (so the key is actually a misnomer).

      ⚠ Lockfiles only have commits, not transforms, so when they try to write back to their
      transform, they can’t, because there is none. That’s why we check whether there’s something at
      every index we want to update.
    */
    if (transforms[index]) {
      transforms[index].created = true
    }

    return commit.sha
  }

  const sha = await Promise.reduce(commits, createCommits, head.object.sha)

  try {
    await ghqueue.write(github => github.gitdata.createReference({
      owner,
      repo: repoName,
      sha,
      ref: 'refs/heads/' + newBranch
    }))
  } catch (err) {
    if (!err.message.includes('already exists')) throw err

    const branch = await ghqueue.read(github => github.repos.getBranch({
      owner,
      repo: repoName,
      branch: newBranch
    }))

    if (branch.commit.committer.type !== 'Bot') throw err

    return branch.commit.sha
  }

  statsd.increment('branches')

  return sha
}
<commit_msg>chore(create-branch): don’t log the entire lockfile on error<commit_after>const statsd = require('./statsd')
const githubQueue = require('./github-queue')
const _ = require('lodash')

const { getNewLockfile } = require('../lib/lockfile')
const { getLockfilePath } = require('../utils/utils')

const Log = require('gk-log')
const dbs = require('../lib/dbs')

global.Promise = require('bluebird')

module.exports = async (
  {
    installationId,
    newBranch,
    branch,
    owner,
    repoName,
    repoDoc,
    message,
    transforms,
    path,
    transform,
    processLockfiles,
    lockFileCommitMessage
  }
) => {
  if (!transforms) transforms = [{ transform, path, message }]
  const ghqueue = githubQueue(installationId)
  let contents = {}

  const commits = (await Promise.mapSeries(transforms, async (
    { path, transform, message, create },
    index
  ) => {
    let blob = {}
    try {
      if (contents[path]) {
        blob.content = contents[path]
      } else {
        if (path === 'README.md') {
          blob = await ghqueue.read(github => github.repos.getReadme({ owner, repo: repoName, ref: branch }))
          path = blob.path
        } else {
          blob = await ghqueue.read(github => github.repos.getContent({
            owner,
            repo: repoName,
            path,
            ref: branch
          }))
        }
      }
    } catch (e) {
      if (e.code !== 404) throw e
      if (!create) return
    }
    let oldContent
    if (contents[path]) {
      oldContent = contents[path]
    } else {
      oldContent = blob.content ? Buffer.from(blob.content, 'base64').toString() : ''
    }

    contents[path] = await transform(oldContent, path)
    if (!contents[path] || contents[path] === oldContent) return
    return { path, content: contents[path], message, index }
  })).filter(c => c)

  if (commits.length === 0) return

  /*
  After processing all the transforms and checking whether they generated any commits,
  we check each commit whether it affected a `package.json`, and generate its lockfile,
  if applicable.

  Note that there are no transforms for these commits. They are added on to the end of
  the commits array and receive an index value, but that doesn’t correspond to an index
  of the transforms array.

  Transforms array:
  ['readme', 'travis', 'package.json', 'yay/package.json']
  Commit array with lockfiles (lockfiles are in reverse order):
  ['readme', 'travis', 'package.json', 'yay/package.json', 'yay/package-lock.json', 'package-lock.json']

  */
  if (processLockfiles && repoDoc && repoDoc.files) {
    const logs = dbs.getLogsDb()
    const log = Log({logsDb: logs, accountId: repoDoc.accountId, repoSlug: repoDoc.fullName, context: 'create-branch'})
    // we need to iterate over every changed package file, not every package file commit
    // we reverse because we want the most recent commit with the all the changes to the file (the last one)
    // we clone because we don’t actually want to do the commits backwards
    const dedupedCommits = _.uniqBy(_.clone(commits).reverse(), commit => commit.path)
    for (const commit of dedupedCommits) {
      // continue skips the current iteration but continues with the for loop as a whole
      if (!commit.path.includes('package.json')) continue
      const lockfilePath = getLockfilePath(repoDoc.files, commit.path)

      if (!lockfilePath) continue
      log.info('starting lockfile update', {lockfilePath})

      const oldLockfile = await ghqueue.read(github => github.repos.getContent({ path: lockfilePath, owner, repo: repoName }))
      const oldLockfileContent = Buffer.from(oldLockfile.content, 'base64').toString()
      log.info('received existing lockfile from GitHub')

      const isNpm = lockfilePath.includes('package-lock.json')
      try {
        const {ok, contents} = await getNewLockfile(commit.content, oldLockfileContent, isNpm)
        if (ok) {
          // !ok means the old and new lockfile are the same, so we don’t make a commit
          log.info('new lockfile contents produced')
          statsd.increment('lockfiles')
          commits.push({
            path: lockfilePath,
            content: contents,
            message: lockFileCommitMessage,
            index: commits.length
          })
        }
      } catch (e) {
        log.error('error fetching updated lockfile from exec server', {e: e.error})
      }
    }
  }

  const head = await ghqueue.read(github => github.gitdata.getReference({
    owner,
    repo: repoName,
    ref: `heads/${branch}`
  }))

  const createCommits = async (sha, { path, content, message, index }) => {
    const newTree = await ghqueue.write(github => github.gitdata.createTree({
      owner,
      repo: repoName,
      base_tree: sha,
      tree: [{ path, content, mode: '100644', type: 'blob' }]
    }))

    const commit = await ghqueue.write(github => github.gitdata.createCommit({
      owner,
      repo: repoName,
      message,
      tree: newTree.sha,
      parents: [sha]
    }))
    /*
      .created is written back into the original transform which is still used
      after create-branch is called from wherever, create-initial-branch for example. So after
      create-branch returns its SHA to create-initial-branch, the latter can check whether, for
      example, travis.yml or readme.md were modified. This is then passed into create-pr or
      whatever else sends messages to humans, where we can then notify them which files were
      MODIFIED (so the key is actually a misnomer).

      ⚠ Lockfiles only have commits, not transforms, so when they try to write back to their
      transform, they can’t, because there is none. That’s why we check whether there’s something at
      every index we want to update.
    */
    if (transforms[index]) {
      transforms[index].created = true
    }

    return commit.sha
  }

  const sha = await Promise.reduce(commits, createCommits, head.object.sha)

  try {
    await ghqueue.write(github => github.gitdata.createReference({
      owner,
      repo: repoName,
      sha,
      ref: 'refs/heads/' + newBranch
    }))
  } catch (err) {
    if (!err.message.includes('already exists')) throw err

    const branch = await ghqueue.read(github => github.repos.getBranch({
      owner,
      repo: repoName,
      branch: newBranch
    }))

    if (branch.commit.committer.type !== 'Bot') throw err

    return branch.commit.sha
  }

  statsd.increment('branches')

  return sha
}
<|endoftext|>


<commit_before>/*
Case Conductor is a Test Case Management system.
Copyright (C) 2011-2012 Mozilla

This file is part of Case Conductor.

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

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

You should have received a copy of the GNU General Public License
along with Case Conductor.  If not, see <http://www.gnu.org/licenses/>.
*/
/*jslint    browser:    true,
            indent:     4,
            confusion:  true */
/*global    ich, jQuery */

var CC = (function (CC, $) {

    'use strict';

    CC.owa = function () {
        var trigger = $('#owa a'),
            url = trigger.data('url'),
            installCallback = function (result) {
                // great - display a message, or redirect to a launch page
                var msg = 'Successfully registered!';
                ich.message({message: msg, tags: 'success'}).appendTo($('#messages ul'));
                $('#messages ul').messages();
            },
            errorCallback = function (result) {
                // whoops - result.code and result.message have details
                var msg = 'Unable to register due to ' + result.code + ': ' + result.message;
                ich.message({message: msg, tags: 'error'}).appendTo($('#messages ul'));
                $('#messages ul').messages();
            },
            register = function () {
                navigator.mozApps.install(
                    url,
                    {},
                    installCallback,
                    errorCallback
                );
            };

        trigger.click(function (e) {
            e.preventDefault();
            if (url) { register(); }
        });
    };

    return CC;

}(CC || {}, jQuery));<commit_msg>update owa js to match new api<commit_after>/*
Case Conductor is a Test Case Management system.
Copyright (C) 2011-2012 Mozilla

This file is part of Case Conductor.

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

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

You should have received a copy of the GNU General Public License
along with Case Conductor.  If not, see <http://www.gnu.org/licenses/>.
*/
/*jslint    browser:    true,
            indent:     4,
            confusion:  true */
/*global    ich, jQuery */

var CC = (function (CC, $) {

    'use strict';

    CC.owa = function () {
        var trigger = $('#owa a'),
            url = trigger.data('url'),
            installCallback = function () {
                // great - display a message, or redirect to a launch page
                var msg = 'Successfully registered!';
                ich.message({message: msg, tags: 'success'}).appendTo($('#messages ul'));
                $('#messages ul').messages();
            },
            errorCallback = function () {
                // whoops - result.code and result.message have details
                var msg = 'Could not install: ' + this.error;
                ich.message({message: msg, tags: 'error'}).appendTo($('#messages ul'));
                $('#messages ul').messages();
            },
            result;

        trigger.click(function (e) {
            e.preventDefault();
            if (url) {
                result = navigator.mozApps.install(url, {});
                result.onsuccess = installCallback;
                result.onerror = errorCallback;
            }
        });
    };

    return CC;

}(CC || {}, jQuery));<|endoftext|>