<commit_before>/*
 * roleAddController.js
 *
 * (c) 2012-2015, Ansible, Inc.
 *
 */

'use strict';

(function(angular) {

    var mod = angular.module('roleAddController', []);

    mod.controller('RoleAddCtrl', [
        '$scope',
        '$interval',
        '$timeout',
        '$analytics',
        '$q',
        'githubRepoService',
        'currentUserService',
        'importService',
        'roleService',
        'repositories',
        'notificationSecretService',
        _controller
    ]);

    function _controller(
        $scope,
        $interval,
        $timeout,
        $analytics,
        $q,
        githubRepoService,
        currentUserService,
        importService,
        roleService,
        repositories,
        notificationSecretService) {

        $scope.page_title = 'My Roles';
        $scope.loading = true;
        $scope.repositories = repositories;
        $scope.username = currentUserService.username;
        $scope.auth_orgs_url = currentUserService.auth_orgs_url;
        $scope.toggleRepository = _toggleRepository;
        $scope.refreshing = false;
        $scope.refreshRepos = _refresh;
        $scope.showIntegrations = _showIntegrations;
        $scope.cancelIntegrations = _cancelIntegrations;
        $scope.revealGithub = _revealGithub;
        $scope.revealTravis = _revealTravis;
        $scope.clearTravis = _clearTravis;
        $scope.clearGithub = _clearGithub;
        $scope.updateSettings = _updateSettings;
        $scope.reimport = _importRepository;
        $scope.github_auth = true;

        if (!(currentUserService.authenticated && currentUserService.connected_to_github)) {
            $scope.github_auth = false;
            $scope.loading = false;
            return;
        }

        if (currentUserService.cache_refreshed) {
            $scope.loading = false;
            _setup();
        } else {
            _waitForRefresh();
        }

        return;

        function _waitForRefresh() {
            var stop = $interval(function() {
                currentUserService.update().then(function(userData) {
                    if (userData.cache_refreshed) {
                        _kill();
                    }
                });
            }, 5000);

            function _kill() {
                $interval.cancel(stop);
                if ($scope.repositories.length == 0) {
                    githubRepoService.get().$promise.then(function(response) {
                        $scope.loading = false;
                        $scope.repositories = response.results;
                        _setup();
                    });
                } else {
                    $scope.loading = false;
                    _setup();
                }
            }
        }

        function _setup() {
            $scope.repositories.forEach(function(repo) {
                repo.github_secret_type = "password";
                repo.travis_token_type = "password";
                if (repo.summary_fields) {
                    repo.summary_fields.notification_secrets.forEach(function(secret) {
                        if (secret.source == 'travis') {
                            repo.travis_id = secret.id;
                            repo.travis_token = secret.secret;
                        } else {
                            repo.github_id = secret.id;
                            repo.github_secret = secret.secret;
                        }
                    });
                }
                if (repo.summary_fields && repo.summary_fields.roles.length) {
                    repo.role_id = repo.summary_fields.roles[0].id;
                    repo.role_name = repo.summary_fields.roles[0].name;
                    repo.role_namespace = repo.summary_fields.roles[0].namespace;
                    repo.master_role_name = repo.role_name;
                } else {
                    var new_name;
                    if (repo.github_repo === 'ansible') {
                        new_name = repo.github_repo;
                    } else {
                        repo.github_repo.replace(/^(ansible[-_+.]*)*(role[-_+.]*)*/g, function(match, p1, p2, offset, str) {
                            var result = str;
                            if (p1) {
                                result = result.replace(new RegExp(p1,'g'), '');
                            }
                            if (p2) {
                                result = result.replace(new RegExp(p2,'g'), '');
                            }
                            result = result.replace(/^-/,'');
                            new_name = result;
                        });
                        if (!new_name) {
                            new_name = repo.github_repo;
                        }
                    }
                    repo.role_namespace = repo.github_user
                    repo.role_name = new_name;
                    repo.master_role_name = repo.role_name;
                }
            });
        }

        function _showIntegrations(_repo) {
            _repo.show_integrations = !_repo.show_integrations;
            _repo.github_secret_type = "password";
            _repo.travis_token_type = "password";
            if (_repo.show_integrations) {
                // reveal the form. keep a copy in case user clicks cancel.
                $scope.master = {
                    travis_id: _repo.travis_id,
                    travis_token: _repo.travis_token,
                    github_id: _repo.github_id,
                    github_secret: _repo.github_secret
                };
            }
        }

        function _cancelIntegrations(_repo) {
            _repo.role_name = _repo.master_role_name
            _repo.travis_id = $scope.master.travis_id;
            _repo.travis_token = $scope.master.travis_token;
            _repo.github_id = $scope.master.github_id;
            _repo.github_secret = $scope.github_secret;
            _repo.show_integrations = !_repo.show_integrations;
        }

        function _revealGithub(_repo) {
            _repo.github_secret_type = (_repo.github_secret_type == 'password') ? 'text' : 'password';
        }

        function _revealTravis(_repo) {
            _repo.travis_token_type = (_repo.travis_token_type == 'password') ? 'text' : 'password';
        }

        function _clearTravis(_repo) {
            _repo.travis_token = null;
        }

        function _clearGithub(_repo) {
            _repo.github_secret = null;
        }

        function _updateSettings(_repo) {
            _repo.show_integrations = false;
            _updateRoleName(_repo).then(function() {
                _updateSecrets(_repo);
            });
        }

        function _updateRoleName(_repo) {
            var deferred = $q.defer();
            if (_repo.master_role_name !== _repo.role_name) {
                _repo.is_enabled = true;
                _repo.state = 'PENDING';
                _repo.master_role_name = _repo.role_name;
                importService.imports.save({
                    'github_user': _repo.github_user,
                    'github_repo': _repo.github_repo,
                    'alternate_role_name': _repo.role_name
                }).$promise.then(function(data) {
                    _checkStatus(data, deferred);
                });
            } else {
                $timeout(function() {
                    deferred.resolve();
                }, 300);
            }
            return deferred.promise;
        }

        function _updateSecrets(_repo) {
            // deleted secret
            if (_repo.travis_id && !_repo.travis_token) {
                $analytics.eventTrack('remove_travis', {
                    category: _repo.github_user + '/' + _repo.github_repo
                });
                notificationSecretService.delete({id: _repo.travis_id}).$promise.then(function(repsonse) {
                    _repo.travis_id = null;
                });
            }
            // changed secret
            if (_repo.travis_id && _repo.travis_token && !/^\*{6}/.test(_repo.travis_token)) {
                $analytics.eventTrack('change_travis', {
                    category: _repo.github_user + '/' + _repo.github_repo
                });
                notificationSecretService.put({
                    id: _repo.travis_id,
                    source: 'travis',
                    github_user: _repo.github_user,
                    github_repo: _repo.github_repo,
                    secret: _repo.travis_token
                }).$promise.then(function(response) {
                    _repo.travis_token = response.secret;
                });
            }
            // new secret
            if (!_repo.travis_id && _repo.travis_token && !/^\*{6}/.test(_repo.travis_token)) {
                $analytics.eventTrack('add_travis', {
                    category: _repo.github_user + '/' + _repo.github_repo
                });
                notificationSecretService.save({
                    source: 'travis',
                    github_user: _repo.github_user,
                    github_repo: _repo.github_repo,
                    secret: _repo.travis_token
                }).$promise.then(function(response) {
                    _repo.travis_id = response.id;
                    _repo.travis_token = response.secret;
                });
            }
        }

        function _refresh() {
            $scope.refreshing = true;
            githubRepoService.refresh().$promise.then(function(response) {
                $scope.repositories = response;
                _setup();
                $scope.refreshing = false;
                $timeout(function() {
                    $scope.$apply();
                },300);
            });
        }

        function _importRepository(_repo) {
            if (_repo.is_enabled) {
                _repo.state = 'PENDING';
                importService.imports.save({
                    'github_user': _repo.github_user,
                    'github_repo': _repo.github_repo,
                    'alternate_role_name': _repo.role_name
                }).$promise.then(_checkStatus);
            }
        }

        function _toggleRepository(_repo) {
            if (_repo.is_enabled) {
                _importRepository(_repo);
            } else {
                roleService.delete({
                    'github_user': _repo.github_user,
                    'github_repo': _repo.github_repo
                }).$promise.then(function(response) {
                    $scope.repositories.forEach(function(repo) {
                        response.deleted_roles.forEach(function(deleted) {
                            if (deleted.github_user === repo.github_user && deleted.github_repo === _repo.github_repo) {
                                repo.state = null;
                            }
                        });
                    });
                });
            }
        }

        function _checkStatus(response, deferred) {
            var stop = $interval(function(_id) {
                importService.imports.query({ id: _id}).$promise.then(function(response) {
                    $scope.repositories.every(function(repo) {
                        if (repo.github_user == response.results[0].github_user &&
                            repo.github_repo === response.results[0].github_repo) {
                            repo.state = response.results[0].state;
                            repo.role_id = response.results[0].role;
                            return false;
                        }
                        return true;
                    });
                    if (response.results[0].state == 'SUCCESS' || response.results[0].state == 'FAILED') {
                        _kill();
                    }
                });
            }, 5000, 0, false, response.results[0].id)

            function _kill() {
                $interval.cancel(stop);
                if (deferred) {
                    deferred.resolve();
                }
            }
        }
    }

})(angular);

<commit_msg>Don't allow refresh while cache if refreshing.<commit_after>/*
 * roleAddController.js
 *
 * (c) 2012-2015, Ansible, Inc.
 *
 */

'use strict';

(function(angular) {

    var mod = angular.module('roleAddController', []);

    mod.controller('RoleAddCtrl', [
        '$scope',
        '$interval',
        '$timeout',
        '$analytics',
        '$q',
        'githubRepoService',
        'currentUserService',
        'importService',
        'roleService',
        'repositories',
        'notificationSecretService',
        _controller
    ]);

    function _controller(
        $scope,
        $interval,
        $timeout,
        $analytics,
        $q,
        githubRepoService,
        currentUserService,
        importService,
        roleService,
        repositories,
        notificationSecretService) {

        $scope.page_title = 'My Roles';
        $scope.loading = true;
        $scope.repositories = repositories;
        $scope.username = currentUserService.username;
        $scope.auth_orgs_url = currentUserService.auth_orgs_url;
        $scope.toggleRepository = _toggleRepository;
        $scope.refreshing = false;
        $scope.refreshRepos = _refresh;
        $scope.showIntegrations = _showIntegrations;
        $scope.cancelIntegrations = _cancelIntegrations;
        $scope.revealGithub = _revealGithub;
        $scope.revealTravis = _revealTravis;
        $scope.clearTravis = _clearTravis;
        $scope.clearGithub = _clearGithub;
        $scope.updateSettings = _updateSettings;
        $scope.reimport = _importRepository;
        $scope.github_auth = true;

        if (!(currentUserService.authenticated && currentUserService.connected_to_github)) {
            $scope.github_auth = false;
            $scope.loading = false;
            return;
        }

        if (currentUserService.cache_refreshed) {
            $scope.loading = false;
            _setup();
        } else {
            _waitForRefresh();
        }

        return;

        function _waitForRefresh() {
            var stop = $interval(function() {
                currentUserService.update().then(function(userData) {
                    if (userData.cache_refreshed) {
                        _kill();
                    }
                });
            }, 5000);

            function _kill() {
                $interval.cancel(stop);
                if ($scope.repositories.length == 0) {
                    githubRepoService.get().$promise.then(function(response) {
                        $scope.loading = false;
                        $scope.repositories = response.results;
                        _setup();
                    });
                } else {
                    $scope.loading = false;
                    _setup();
                }
            }
        }

        function _setup() {
            $scope.repositories.forEach(function(repo) {
                repo.github_secret_type = "password";
                repo.travis_token_type = "password";
                if (repo.summary_fields) {
                    repo.summary_fields.notification_secrets.forEach(function(secret) {
                        if (secret.source == 'travis') {
                            repo.travis_id = secret.id;
                            repo.travis_token = secret.secret;
                        } else {
                            repo.github_id = secret.id;
                            repo.github_secret = secret.secret;
                        }
                    });
                }
                if (repo.summary_fields && repo.summary_fields.roles.length) {
                    repo.role_id = repo.summary_fields.roles[0].id;
                    repo.role_name = repo.summary_fields.roles[0].name;
                    repo.role_namespace = repo.summary_fields.roles[0].namespace;
                    repo.master_role_name = repo.role_name;
                } else {
                    var new_name;
                    if (repo.github_repo === 'ansible') {
                        new_name = repo.github_repo;
                    } else {
                        repo.github_repo.replace(/^(ansible[-_+.]*)*(role[-_+.]*)*/g, function(match, p1, p2, offset, str) {
                            var result = str;
                            if (p1) {
                                result = result.replace(new RegExp(p1,'g'), '');
                            }
                            if (p2) {
                                result = result.replace(new RegExp(p2,'g'), '');
                            }
                            result = result.replace(/^-/,'');
                            new_name = result;
                        });
                        if (!new_name) {
                            new_name = repo.github_repo;
                        }
                    }
                    repo.role_namespace = repo.github_user
                    repo.role_name = new_name;
                    repo.master_role_name = repo.role_name;
                }
            });
        }

        function _showIntegrations(_repo) {
            _repo.show_integrations = !_repo.show_integrations;
            _repo.github_secret_type = "password";
            _repo.travis_token_type = "password";
            if (_repo.show_integrations) {
                // reveal the form. keep a copy in case user clicks cancel.
                $scope.master = {
                    travis_id: _repo.travis_id,
                    travis_token: _repo.travis_token,
                    github_id: _repo.github_id,
                    github_secret: _repo.github_secret
                };
            }
        }

        function _cancelIntegrations(_repo) {
            _repo.role_name = _repo.master_role_name
            _repo.travis_id = $scope.master.travis_id;
            _repo.travis_token = $scope.master.travis_token;
            _repo.github_id = $scope.master.github_id;
            _repo.github_secret = $scope.github_secret;
            _repo.show_integrations = !_repo.show_integrations;
        }

        function _revealGithub(_repo) {
            _repo.github_secret_type = (_repo.github_secret_type == 'password') ? 'text' : 'password';
        }

        function _revealTravis(_repo) {
            _repo.travis_token_type = (_repo.travis_token_type == 'password') ? 'text' : 'password';
        }

        function _clearTravis(_repo) {
            _repo.travis_token = null;
        }

        function _clearGithub(_repo) {
            _repo.github_secret = null;
        }

        function _updateSettings(_repo) {
            _repo.show_integrations = false;
            _updateRoleName(_repo).then(function() {
                _updateSecrets(_repo);
            });
        }

        function _updateRoleName(_repo) {
            var deferred = $q.defer();
            if (_repo.master_role_name !== _repo.role_name) {
                _repo.is_enabled = true;
                _repo.state = 'PENDING';
                _repo.master_role_name = _repo.role_name;
                importService.imports.save({
                    'github_user': _repo.github_user,
                    'github_repo': _repo.github_repo,
                    'alternate_role_name': _repo.role_name
                }).$promise.then(function(data) {
                    _checkStatus(data, deferred);
                });
            } else {
                $timeout(function() {
                    deferred.resolve();
                }, 300);
            }
            return deferred.promise;
        }

        function _updateSecrets(_repo) {
            // deleted secret
            if (_repo.travis_id && !_repo.travis_token) {
                $analytics.eventTrack('remove_travis', {
                    category: _repo.github_user + '/' + _repo.github_repo
                });
                notificationSecretService.delete({id: _repo.travis_id}).$promise.then(function(repsonse) {
                    _repo.travis_id = null;
                });
            }
            // changed secret
            if (_repo.travis_id && _repo.travis_token && !/^\*{6}/.test(_repo.travis_token)) {
                $analytics.eventTrack('change_travis', {
                    category: _repo.github_user + '/' + _repo.github_repo
                });
                notificationSecretService.put({
                    id: _repo.travis_id,
                    source: 'travis',
                    github_user: _repo.github_user,
                    github_repo: _repo.github_repo,
                    secret: _repo.travis_token
                }).$promise.then(function(response) {
                    _repo.travis_token = response.secret;
                });
            }
            // new secret
            if (!_repo.travis_id && _repo.travis_token && !/^\*{6}/.test(_repo.travis_token)) {
                $analytics.eventTrack('add_travis', {
                    category: _repo.github_user + '/' + _repo.github_repo
                });
                notificationSecretService.save({
                    source: 'travis',
                    github_user: _repo.github_user,
                    github_repo: _repo.github_repo,
                    secret: _repo.travis_token
                }).$promise.then(function(response) {
                    _repo.travis_id = response.id;
                    _repo.travis_token = response.secret;
                });
            }
        }

        function _refresh() {
            if ($scope.loading || $scope.refreshing) {
                return
            }
            $scope.refreshing = true;
            githubRepoService.refresh().$promise.then(function(response) {
                $scope.repositories = response;
                _setup();
                $scope.refreshing = false;
                $timeout(function() {
                    $scope.$apply();
                },300);
            });
        }

        function _importRepository(_repo) {
            if (_repo.is_enabled) {
                _repo.state = 'PENDING';
                importService.imports.save({
                    'github_user': _repo.github_user,
                    'github_repo': _repo.github_repo,
                    'alternate_role_name': _repo.role_name
                }).$promise.then(_checkStatus);
            }
        }

        function _toggleRepository(_repo) {
            if (_repo.is_enabled) {
                _importRepository(_repo);
            } else {
                roleService.delete({
                    'github_user': _repo.github_user,
                    'github_repo': _repo.github_repo
                }).$promise.then(function(response) {
                    $scope.repositories.forEach(function(repo) {
                        response.deleted_roles.forEach(function(deleted) {
                            if (deleted.github_user === repo.github_user && deleted.github_repo === _repo.github_repo) {
                                repo.state = null;
                            }
                        });
                    });
                });
            }
        }

        function _checkStatus(response, deferred) {
            var stop = $interval(function(_id) {
                importService.imports.query({ id: _id}).$promise.then(function(response) {
                    $scope.repositories.every(function(repo) {
                        if (repo.github_user == response.results[0].github_user &&
                            repo.github_repo === response.results[0].github_repo) {
                            repo.state = response.results[0].state;
                            repo.role_id = response.results[0].role;
                            return false;
                        }
                        return true;
                    });
                    if (response.results[0].state == 'SUCCESS' || response.results[0].state == 'FAILED') {
                        _kill();
                    }
                });
            }, 5000, 0, false, response.results[0].id)

            function _kill() {
                $interval.cancel(stop);
                if (deferred) {
                    deferred.resolve();
                }
            }
        }
    }

})(angular);

<|endoftext|>


<commit_before>L.ToolbarAction = L.Handler.extend({
	statics: {
		baseClass: 'leaflet-toolbar-icon'
	},

	options: {
		toolbarIcon: {
			html: '',
			className: '',
			tooltip: ''
		},
		subToolbar: L.toolbar()
	},

	initialize: function(options) {
		var defaultIconOptions = L.ToolbarAction.prototype.options.toolbarIcon;

		L.setOptions(this, options);
		this.options.toolbarIcon = L.extend({}, defaultIconOptions, this.options.toolbarIcon);
	},

	enable: function() {
		if (this._enabled) { return; }
		this._enabled = true;

		if (this.addHooks) { this.addHooks(); }
	},

	disable: function() {
		if (!this._enabled) { return; }
		this._enabled = false;

		if (this.removeHooks) { this.removeHooks(); }
	},

	_createIcon: function(toolbar, container, args) {
		var iconOptions = this.options.toolbarIcon;

		this.toolbar = toolbar;
		this._icon = L.DomUtil.create('li', '', container);
		this._link = L.DomUtil.create('a', '', this._icon);

		this._link.innerHTML = iconOptions.html;
		this._link.setAttribute('href', '#');
		this._link.setAttribute('title', iconOptions.tooltip);

		L.DomUtil.addClass(this._link, this.constructor.baseClass);
		if (iconOptions.className) {
			L.DomUtil.addClass(this._link, iconOptions.className);
		}

		L.DomEvent.on(this._link, 'click', this.enable, this);

		/* Add secondary toolbar */
		this._addSubToolbar(toolbar, this._icon, args);
	},

	_addSubToolbar: function(toolbar, container, args) {
		var subToolbar = this.options.subToolbar,
			addHooks = this.addHooks,
			removeHooks = this.removeHooks;

		/* For calculating the nesting depth. */
		subToolbar.parentToolbar = toolbar;

		if (subToolbar.options.actions.length > 0) {
			/* Make a copy of args so as not to pollute the args array used by other actions. */
			args = [].slice.call(args);
			args.push(this);

			subToolbar.addTo.apply(subToolbar, args);
			subToolbar.appendToContainer(container);

			this.addHooks = function(map) {
				addHooks.call(this, map);
				subToolbar._show();
			};

			this.removeHooks = function(map) {
				removeHooks.call(this, map);
				subToolbar._hide();
			};
		}
	}
});

L.ToolbarAction.extendOptions = function(options) {
	return this.extend({ options: options });
};
<commit_msg>Don't use constructor internally<commit_after>L.ToolbarAction = L.Handler.extend({
	statics: {
		baseClass: 'leaflet-toolbar-icon'
	},

	options: {
		toolbarIcon: {
			html: '',
			className: '',
			tooltip: ''
		},
		subToolbar: L.Toolbar()
	},

	initialize: function(options) {
		var defaultIconOptions = L.ToolbarAction.prototype.options.toolbarIcon;

		L.setOptions(this, options);
		this.options.toolbarIcon = L.extend({}, defaultIconOptions, this.options.toolbarIcon);
	},

	enable: function() {
		if (this._enabled) { return; }
		this._enabled = true;

		if (this.addHooks) { this.addHooks(); }
	},

	disable: function() {
		if (!this._enabled) { return; }
		this._enabled = false;

		if (this.removeHooks) { this.removeHooks(); }
	},

	_createIcon: function(toolbar, container, args) {
		var iconOptions = this.options.toolbarIcon;

		this.toolbar = toolbar;
		this._icon = L.DomUtil.create('li', '', container);
		this._link = L.DomUtil.create('a', '', this._icon);

		this._link.innerHTML = iconOptions.html;
		this._link.setAttribute('href', '#');
		this._link.setAttribute('title', iconOptions.tooltip);

		L.DomUtil.addClass(this._link, this.constructor.baseClass);
		if (iconOptions.className) {
			L.DomUtil.addClass(this._link, iconOptions.className);
		}

		L.DomEvent.on(this._link, 'click', this.enable, this);

		/* Add secondary toolbar */
		this._addSubToolbar(toolbar, this._icon, args);
	},

	_addSubToolbar: function(toolbar, container, args) {
		var subToolbar = this.options.subToolbar,
			addHooks = this.addHooks,
			removeHooks = this.removeHooks;

		/* For calculating the nesting depth. */
		subToolbar.parentToolbar = toolbar;

		if (subToolbar.options.actions.length > 0) {
			/* Make a copy of args so as not to pollute the args array used by other actions. */
			args = [].slice.call(args);
			args.push(this);

			subToolbar.addTo.apply(subToolbar, args);
			subToolbar.appendToContainer(container);

			this.addHooks = function(map) {
				addHooks.call(this, map);
				subToolbar._show();
			};

			this.removeHooks = function(map) {
				removeHooks.call(this, map);
				subToolbar._hide();
			};
		}
	}
});

L.ToolbarAction.extendOptions = function(options) {
	return this.extend({ options: options });
};
<|endoftext|>


<commit_before>var mmm = require('mmmagic');
var peek = require('buffer-peek-stream');

var magicMime = new mmm.Magic(mmm.MAGIC_MIME);

function streamMmmagic(stream, options, callback) {

  if (!callback) {
    callback = options;
    options = {
      splitMime: true
    };
  }

  var wantSplit = options.splitMime === undefined ? true : options.splitMime;
  var magicFile = config.magicFile;

  // peek 16K which is more than you need for type but gives libmagic a better chance of
  // accurately detecting the encoding
  return peek(stream, 16384, function (err, buf, dest) {
    if (err) return callback(err, null, dest);

    var magic = magicFile
        ? new mmm.Magic(magicFile, mmm.MAGIC_MIME)
        : magicMime;

    magic.detect(buf, function (err, res) {
      if (err) return callback(err, null, dest);
      if (wantSplit) {
        res = splitMime(res);
      }
      callback(null, res, dest);
    });
  });
}

var config = {
    magicFile: null
};

streamMmmagic.config = config;
module.exports = streamMmmagic;

var _splitMime = /^(.*); charset=(.*)$/;
function splitMime(s) {
  var p = s.match(_splitMime);
  return {
    type: p[1],
    encoding: p[2]
  };
}
<commit_msg>Store Magic objects created for certain magic files<commit_after>var mmm = require('mmmagic');
var peek = require('buffer-peek-stream');

function streamMmmagic(stream, options, callback) {

  if (!callback) {
    callback = options;
    options = {
      splitMime: true
    };
  }

  var wantSplit = options.splitMime === undefined ? true : options.splitMime;
  var magicFile = config.magicFile;

  // peek 16K which is more than you need for type but gives libmagic a better chance of
  // accurately detecting the encoding
  return peek(stream, 16384, function (err, buf, dest) {
    if (err) return callback(err, null, dest);

    var magic;
    if (magicFile) {
      if (magicFiles.hasOwnProperty(magicFile)) {
        magic = magicFiles[magicFile];
      }
      else {
        magic = magicFiles[magicFile] = new mmm.Magic(magicFile, mmm.MAGIC_MIME);
      }
    }
    else {
      magic = _magic;
    }

    magic.detect(buf, function (err, res) {
      if (err) return callback(err, null, dest);
      if (wantSplit) {
        res = splitMime(res);
      }
      callback(null, res, dest);
    });
  });
}

var _magic = new mmm.Magic(mmm.MAGIC_MIME);
var magicFiles = {};
var config = {
    magicFile: null
};

streamMmmagic.config = config;
module.exports = streamMmmagic;

var _splitMime = /^(.*); charset=(.*)$/;
function splitMime(s) {
  var p = s.match(_splitMime);
  return {
    type: p[1],
    encoding: p[2]
  };
}
<|endoftext|>


<commit_before>/**
 * External dependencies
 */
import PropTypes from 'prop-types';

/**
 * WordPress dependencies
 */
import { useEffect, useState } from '@wordpress/element';
import { __ } from '@wordpress/i18n';

/**
 * Internal dependencies
 */
import useStory from '../../app/story/useStory';
import { ActionButton } from '../button';
import { SimplePanel } from './panel';

// @todo Only display if one element selected.
function BackgroundPanel( { selectedElements, onSetProperties } ) {
	// Remove background: check if is background.
	const { state: { currentPage }, actions: { setBackgroundElement } } = useStory();
	const { id, overlay, opacity } = selectedElements[ 0 ];
	const isBackground = currentPage.backgroundElementId === id;

	// To add: Remove as background; Opacity; Overlay

	const [ state, setState ] = useState( { isBackground, opacity, overlay } );
	useEffect( () => {
		setState( { isBackground } );
	}, [ isBackground ] );
	const handleClick = ( ) => {
		const newIsBackground = ! state.isBackground;
		const newState = { isBackground: newIsBackground, opacity: 100, overlay: null };
		setState( newState );
		const backgroundId = newIsBackground ? selectedElements[ 0 ].id : null;
		setBackgroundElement( { elementId: backgroundId } );
		onSetProperties( newState );
	};
	return (
		<SimplePanel name="position" title={ __( 'Background', 'amp' ) } onSubmit={ ( event ) => event.preventDefault() }>
			<ActionButton onClick={ handleClick }>
				{ state.isBackground ? __( 'Remove as Background', 'amp' ) : __( 'Set as background', 'amp' ) }
			</ActionButton>
		</SimplePanel>
	);
}

BackgroundPanel.propTypes = {
	selectedElements: PropTypes.array.isRequired,
	onSetProperties: PropTypes.func.isRequired,
};

export default BackgroundPanel;
<commit_msg>Remove some more old unused code.<commit_after>/**
 * External dependencies
 */
import PropTypes from 'prop-types';

/**
 * WordPress dependencies
 */
import { useEffect, useState } from '@wordpress/element';
import { __ } from '@wordpress/i18n';

/**
 * Internal dependencies
 */
import useStory from '../../app/story/useStory';
import { ActionButton } from '../button';
import { SimplePanel } from './panel';

// @todo Only display if one element selected.
function BackgroundPanel( { selectedElements, onSetProperties } ) {
	// Remove background: check if is background.
	const { state: { currentPage }, actions: { setBackgroundElement } } = useStory();
	const { id, overlay, opacity } = selectedElements[ 0 ];
	const isBackground = currentPage.backgroundElementId === id;

	// To add: Remove as background; Opacity; Overlay

	const [ state, setState ] = useState( { isBackground, opacity, overlay } );
	useEffect( () => {
		setState( { isBackground } );
	}, [ isBackground ] );
	const handleClick = ( ) => {
		const newIsBackground = ! state.isBackground;
		const newState = { isBackground: newIsBackground, opacity: 100, overlay: null };
		setState( newState );
		const backgroundId = newIsBackground ? selectedElements[ 0 ].id : null;
		setBackgroundElement( { elementId: backgroundId } );
		onSetProperties( newState );
	};
	return (
		<SimplePanel name="position" title={ __( 'Background', 'amp' ) }>
			<ActionButton onClick={ handleClick }>
				{ state.isBackground ? __( 'Remove as Background', 'amp' ) : __( 'Set as background', 'amp' ) }
			</ActionButton>
		</SimplePanel>
	);
}

BackgroundPanel.propTypes = {
	selectedElements: PropTypes.array.isRequired,
	onSetProperties: PropTypes.func.isRequired,
};

export default BackgroundPanel;
<|endoftext|>


<commit_before>var sm = new (require('sphericalmercator'))();
var Stats = require('./stream-util').Stats;
var Tile = require('./stream-util').Tile;
var Info = require('./stream-util').Info;
var limitBounds = require('./stream-util').limitBounds;
var isEmpty = require('./stream-util').isEmpty;
var addChildren = require('./stream-util').addChildren;
var sumChildren = require('./stream-util').sumChildren;
var multiread = require('./stream-util').multiread;
var getTileRetry = require('./stream-util').getTileRetry;
var Readable = require('stream').Readable;
var util = require('util');
var validate = require('./tilelive.js').validate;

module.exports = Pyramid;
util.inherits(Pyramid, Readable);

function Pyramid(source, options) {
    if (!source) throw new TypeError('Tilesource required');

    options = options || {};

    if (options.bounds !== undefined && !Array.isArray(options.bounds))
        throw new TypeError('options.bounds must be an array of the form [w,s,e,n]');
    if (options.minzoom !== undefined && typeof options.minzoom !== 'number')
        throw new TypeError('options.minzoom must be a positive integer');
    if (options.maxzoom !== undefined && typeof options.maxzoom !== 'number')
        throw new TypeError('options.maxzoom must be a positive integer');

    this.source = source;
    this.bounds = options.bounds;
    this.minzoom = options.minzoom;
    this.maxzoom = options.maxzoom;
    this.pending = 0;
    this.queue = [];
    this.bboxes = undefined;
    this.cursor = undefined;
    this.stats = new Stats();
    this.length = 0;
    this.job = options.job || false;
    this.retry = options.retry || 0;

    Readable.call(this, { objectMode: true });
}

Pyramid.prototype._params = function(callback) {
    var stream = this;
    stream.source.getInfo(function(err, info) {
        if (err) return stream.emit('error', err);
        stream.bounds = stream.bounds !== undefined ? stream.bounds : info.bounds;
        stream.minzoom = stream.minzoom !== undefined ? stream.minzoom : info.minzoom;
        stream.maxzoom = stream.maxzoom !== undefined ? stream.maxzoom : info.maxzoom;
        if (stream.bounds === undefined) return stream.emit('error', new Error('No bounds determined'));
        if (stream.minzoom === undefined) return stream.emit('error', new Error('No minzoom determined'));
        if (stream.maxzoom === undefined) return stream.emit('error', new Error('No maxzoom determined'));

        if (stream.job) {
            var dx = (stream.bounds[2] - stream.bounds[0]) / stream.job.total;
            stream.bounds = [
                stream.bounds[0] + stream.job.num * dx,
                stream.bounds[1],
                stream.bounds[0] + (stream.job.num + 1) * dx,
                stream.bounds[3]
            ];
        }

        stream.bboxes = {};
        var boundsArray = limitBounds(stream.bounds);
        var valid = validate({bounds:boundsArray});
        if (valid instanceof Error) return stream.emit('error', new Error(valid.message));

        for (var z = stream.minzoom; z <= stream.maxzoom; z++) {
            stream.bboxes[z] = sm.xyz(boundsArray, z);
            stream.stats.total +=
                (stream.bboxes[z].maxX - stream.bboxes[z].minX + 1) *
                (stream.bboxes[z].maxY - stream.bboxes[z].minY + 1);
        }

        stream.cursor = {
            z: stream.minzoom,
            x: stream.bboxes[stream.minzoom].minX,
            y: stream.bboxes[stream.minzoom].minY
        };

        callback(null, info);
    });
};

Pyramid.prototype._read = function() {
    var stream = this;

    // Defer gets until info is retrieved and there is a cursor to be used.
    if (!stream.bboxes) return stream._params(function(err, info) {
        if (err) return stream.emit('error', err);
        stream.length = stream.stats.total;
        stream.emit('length', stream.length);
        stream.push(new Info(info));
    });

    multiread(stream, function get(push) {
        var z, x, y, tile;
        if (stream.queue.length) {
            var queued = stream.queue.shift();
            z = queued.z;
            x = queued.x;
            y = queued.y;
            stream.pending++;
            stream.stats.ops++;
            getTileRetry(stream.source, z, x, y, stream.retry, done);
            // Do not repeat buffers in a pyramid fashion for now as
            // there are possible false positives in upstream solid
            // detection.
            //
            // if (queued.buffer) {
            //     done(null, queued.buffer);
            // } else {
            //     getTileRetry(stream.source, z, x, y, stream.retry, done);
            // }
            return true;
        } else if (stream.cursor) {
            z = stream.cursor.z;
            x = stream.cursor.x;
            y = stream.cursor.y;
            nextShallow(stream);
            stream.pending++;
            stream.stats.ops++;
            getTileRetry(stream.source, z, x, y, stream.retry, done);
            return true;
        } else {
            return push(null) && false;
        }
        function done(err, buffer, headers) {
            headers = headers || {};
            stream.pending--;
            if (err && !(/does not exist$/).test(err.message)) {
                stream.emit('error', err);
            } else if (err || isEmpty(buffer)) {
                tile = new Tile(z, x, y);
                if (headers.painted) {
                    addChildren(tile, stream.bboxes, stream.queue);
                    stream.stats.skipped++;
                    stream.stats.done++;
                    get(push);
                } else {
                    var sum = sumChildren(tile, stream.bboxes);
                    stream.stats.skipped += 1 + sum;
                    stream.stats.done += 1 + sum;
                    // Update length
                    stream.length -= 1 + sum;
                    stream.emit('length', stream.length);
                    get(push);
                }
            } else {
                tile = new Tile(z, x, y, buffer);
                addChildren(tile, stream.bboxes, stream.queue);
                stream.stats.done++;
                push(tile);
            }
        }
    });
};

// Increment a tile cursor to the next position on the lowest zoom level.
function nextShallow(stream) {
    if (!stream.cursor) return false;
    var cursor = stream.cursor;
    cursor.x++;
    var bbox = stream.bboxes[cursor.z];
    if (cursor.x > bbox.maxX) {
        cursor.x = bbox.minX;
        cursor.y++;
    }
    if (cursor.y > bbox.maxY) {
        stream.cursor = false;
        return false;
    }
    return true;
}
<commit_msg>Changed the name of the header for painted<commit_after>var sm = new (require('sphericalmercator'))();
var Stats = require('./stream-util').Stats;
var Tile = require('./stream-util').Tile;
var Info = require('./stream-util').Info;
var limitBounds = require('./stream-util').limitBounds;
var isEmpty = require('./stream-util').isEmpty;
var addChildren = require('./stream-util').addChildren;
var sumChildren = require('./stream-util').sumChildren;
var multiread = require('./stream-util').multiread;
var getTileRetry = require('./stream-util').getTileRetry;
var Readable = require('stream').Readable;
var util = require('util');
var validate = require('./tilelive.js').validate;

module.exports = Pyramid;
util.inherits(Pyramid, Readable);

function Pyramid(source, options) {
    if (!source) throw new TypeError('Tilesource required');

    options = options || {};

    if (options.bounds !== undefined && !Array.isArray(options.bounds))
        throw new TypeError('options.bounds must be an array of the form [w,s,e,n]');
    if (options.minzoom !== undefined && typeof options.minzoom !== 'number')
        throw new TypeError('options.minzoom must be a positive integer');
    if (options.maxzoom !== undefined && typeof options.maxzoom !== 'number')
        throw new TypeError('options.maxzoom must be a positive integer');

    this.source = source;
    this.bounds = options.bounds;
    this.minzoom = options.minzoom;
    this.maxzoom = options.maxzoom;
    this.pending = 0;
    this.queue = [];
    this.bboxes = undefined;
    this.cursor = undefined;
    this.stats = new Stats();
    this.length = 0;
    this.job = options.job || false;
    this.retry = options.retry || 0;

    Readable.call(this, { objectMode: true });
}

Pyramid.prototype._params = function(callback) {
    var stream = this;
    stream.source.getInfo(function(err, info) {
        if (err) return stream.emit('error', err);
        stream.bounds = stream.bounds !== undefined ? stream.bounds : info.bounds;
        stream.minzoom = stream.minzoom !== undefined ? stream.minzoom : info.minzoom;
        stream.maxzoom = stream.maxzoom !== undefined ? stream.maxzoom : info.maxzoom;
        if (stream.bounds === undefined) return stream.emit('error', new Error('No bounds determined'));
        if (stream.minzoom === undefined) return stream.emit('error', new Error('No minzoom determined'));
        if (stream.maxzoom === undefined) return stream.emit('error', new Error('No maxzoom determined'));

        if (stream.job) {
            var dx = (stream.bounds[2] - stream.bounds[0]) / stream.job.total;
            stream.bounds = [
                stream.bounds[0] + stream.job.num * dx,
                stream.bounds[1],
                stream.bounds[0] + (stream.job.num + 1) * dx,
                stream.bounds[3]
            ];
        }

        stream.bboxes = {};
        var boundsArray = limitBounds(stream.bounds);
        var valid = validate({bounds:boundsArray});
        if (valid instanceof Error) return stream.emit('error', new Error(valid.message));

        for (var z = stream.minzoom; z <= stream.maxzoom; z++) {
            stream.bboxes[z] = sm.xyz(boundsArray, z);
            stream.stats.total +=
                (stream.bboxes[z].maxX - stream.bboxes[z].minX + 1) *
                (stream.bboxes[z].maxY - stream.bboxes[z].minY + 1);
        }

        stream.cursor = {
            z: stream.minzoom,
            x: stream.bboxes[stream.minzoom].minX,
            y: stream.bboxes[stream.minzoom].minY
        };

        callback(null, info);
    });
};

Pyramid.prototype._read = function() {
    var stream = this;

    // Defer gets until info is retrieved and there is a cursor to be used.
    if (!stream.bboxes) return stream._params(function(err, info) {
        if (err) return stream.emit('error', err);
        stream.length = stream.stats.total;
        stream.emit('length', stream.length);
        stream.push(new Info(info));
    });

    multiread(stream, function get(push) {
        var z, x, y, tile;
        if (stream.queue.length) {
            var queued = stream.queue.shift();
            z = queued.z;
            x = queued.x;
            y = queued.y;
            stream.pending++;
            stream.stats.ops++;
            getTileRetry(stream.source, z, x, y, stream.retry, done);
            // Do not repeat buffers in a pyramid fashion for now as
            // there are possible false positives in upstream solid
            // detection.
            //
            // if (queued.buffer) {
            //     done(null, queued.buffer);
            // } else {
            //     getTileRetry(stream.source, z, x, y, stream.retry, done);
            // }
            return true;
        } else if (stream.cursor) {
            z = stream.cursor.z;
            x = stream.cursor.x;
            y = stream.cursor.y;
            nextShallow(stream);
            stream.pending++;
            stream.stats.ops++;
            getTileRetry(stream.source, z, x, y, stream.retry, done);
            return true;
        } else {
            return push(null) && false;
        }
        function done(err, buffer, headers) {
            headers = headers || {};
            stream.pending--;
            if (err && !(/does not exist$/).test(err.message)) {
                stream.emit('error', err);
            } else if (err || isEmpty(buffer)) {
                tile = new Tile(z, x, y);
                if (headers['x-tilelive-contains-data']) {
                    addChildren(tile, stream.bboxes, stream.queue);
                    stream.stats.skipped++;
                    stream.stats.done++;
                    get(push);
                } else {
                    var sum = sumChildren(tile, stream.bboxes);
                    stream.stats.skipped += 1 + sum;
                    stream.stats.done += 1 + sum;
                    // Update length
                    stream.length -= 1 + sum;
                    stream.emit('length', stream.length);
                    get(push);
                }
            } else {
                tile = new Tile(z, x, y, buffer);
                addChildren(tile, stream.bboxes, stream.queue);
                stream.stats.done++;
                push(tile);
            }
        }
    });
};

// Increment a tile cursor to the next position on the lowest zoom level.
function nextShallow(stream) {
    if (!stream.cursor) return false;
    var cursor = stream.cursor;
    cursor.x++;
    var bbox = stream.bboxes[cursor.z];
    if (cursor.x > bbox.maxX) {
        cursor.x = bbox.minX;
        cursor.y++;
    }
    if (cursor.y > bbox.maxY) {
        stream.cursor = false;
        return false;
    }
    return true;
}
<|endoftext|>


<commit_before>/**
 * Created by ferron on 10/3/18 1:04 PM
 * adapted from split-file-stream library
 * URL : https://github.com/dannycho7/split-file-stream/blob/master/index.js
 * credit @dannycho7
 */

const fs = require('fs')
const bytes = require('bytes')
const generateFilePath = (rootFileName, numFiles) => `${rootFileName}.split-${numFiles}`

const _splitToStream = (outStreamCreate, fileStream, partitionStreamSize, callback) => {
  const outStreams = [], {highWaterMark: defaultChunkSize} = fileStream._readableState // eslint-disable-line one-var
  let currentOutStream
  let currentFileSize = 0
  let fileStreamEnded = false
  let finishedWriteStreams = 0
  let openStream = false
  let partitionNum = 0

  const endCurrentWriteStream = () => {
    currentOutStream.end()
    currentOutStream = null
    currentFileSize = 0
    openStream = false
  }

  const writeStreamFinishHandler = () => {
    finishedWriteStreams++
    if (fileStreamEnded && partitionNum === finishedWriteStreams) {
      callback(outStreams)
    }
  }

  fileStream.on('readable', () => {
    let chunk
    while ((chunk = fileStream.read(Math.min(partitionStreamSize - currentFileSize, defaultChunkSize))) !== null) {
      if (openStream === false) {
        currentOutStream = outStreamCreate(partitionNum)
        currentOutStream.on('finish', writeStreamFinishHandler)
        outStreams.push(currentOutStream)
        partitionNum++
        openStream = true
      }

      currentOutStream.write(chunk)
      currentFileSize += chunk.length

      if (currentFileSize === partitionStreamSize) {
        endCurrentWriteStream()
      }
    }
  })

  fileStream.on('end', () => {
    if (currentOutStream) {
      endCurrentWriteStream()
    }
    fileStreamEnded = true
  })
}

const split = (fileStream, maxFileSize, rootFilePath, callback) => {
  const partitionNames = []

  const outStreamCreate = (partitionNum) => {
    let filePath = generateFilePath(rootFilePath, partitionNum)
    return fs.createWriteStream(filePath)
  }

  _splitToStream(outStreamCreate, fileStream, bytes(maxFileSize), (fileWriteStreams) => {
    fileWriteStreams.forEach((fileWriteStream) => partitionNames.push(fileWriteStream['path']))
    callback(partitionNames)
  })
}

module.exports = {
  split,
  _splitToStream
}
<commit_msg>added support for chunks outputting.<commit_after>/**
 * Created by ferron on 10/3/18 1:04 PM
 * adapted from split-file-stream library
 * URL : https://github.com/dannycho7/split-file-stream/blob/master/index.js
 * credit by : @dannycho7
 */

const fs = require('fs')
const bytes = require('bytes')
const generateFilePath = (rootFileName, numFiles) => `${rootFileName}.split-${numFiles}`
const defaultChunkSize = 64 * 1024

const _splitToStream = (outStreamCreate, chunk, partitionStreamSize, callback) => {
  const outStreams = []
  let currentOutStream
  let currentFileSize = 0
  let finishedWriteStreams = 0
  let openStream = false
  let partitionNum = 0

  const endCurrentWriteStream = () => {
    currentOutStream.end()
    currentOutStream = null
    currentFileSize = 0
    openStream = false
  }

  const writeStreamFinishHandler = () => {
    finishedWriteStreams++
    if (partitionNum === finishedWriteStreams) {
      callback(outStreams)
    }
  }

  while (Math.min(partitionStreamSize - currentFileSize, defaultChunkSize)) {
    if (openStream === false) {
      currentOutStream = outStreamCreate(partitionNum)
      currentOutStream.on('finish', writeStreamFinishHandler)
      outStreams.push(currentOutStream)
      partitionNum++
      openStream = true
    }

    currentOutStream.write(chunk)
    currentFileSize += chunk.length

    if (currentFileSize === partitionStreamSize || chunk === '') {
      endCurrentWriteStream()
    }
  }
}

const split = (chunk, maxFileSize, rootFilePath, callback) => {
  const partitionNames = []

  const outStreamCreate = (partitionNum) => {
    let filePath = generateFilePath(rootFilePath, partitionNum)
    return fs.createWriteStream(filePath)
  }

  _splitToStream(outStreamCreate, chunk, bytes(maxFileSize), (fileWriteStreams) => {
    fileWriteStreams.forEach((fileWriteStream) => partitionNames.push(fileWriteStream['path']))
    callback(partitionNames)
  })
}

module.exports = {
  split,
  _splitToStream
}
<|endoftext|>


<commit_before>var escape     = require('escape-string-regexp')
var forceArray = require('force-array')
var stream     = require('stream')
var strip      = require('strip-ansi')
var util       = require('util')

function SupposeStream(options) {
  if(!(this instanceof SupposeStream)) return new SupposeStream(options)

  SupposeStream.super_.call(this)

  var debug
  var stripAnsi
  if(options)
  {
    debug = (options instanceof stream.Writable) ? options : options.debug
    if(options.stripAnsi) stripAnsi = strip
  }

  this.expects = []

  var readBuffer = ''
  var needNew = true
  var sentEof = false

  var condition
  var responses

  this._transform = function(chunk, encoding, callback)
  {
    if(debug) debug.write(chunk)

    readBuffer += chunk.toString()
    if(needNew)
    {
      var expect = this.expects.shift()

      condition = expect && expect.condition
      responses = expect && expect.responses

      if(!expect && !sentEof)
      {
        // this.expects was always empty
        this.push(null)
        sentEof = true
      }

      needNew = false
    }

    const buffer = stripAnsi ? stripAnsi(readBuffer) : readBuffer

    var match
    switch(typeof condition)
    {
      case 'string':
        match = new RegExp(escape(condition) + `[^\S\r\n]*`).test(buffer);
      break

      case 'object':
        match = buffer.match(condition)
    }

    if(match)
    {
      match = (match instanceof Array) ? match.slice(1) : []

      readBuffer = ''
      needNew = true

      for(let response of responses)
      {
        if(response instanceof Function)
          response.apply(this, match)
        else
        {
          this.push(response)

          if(debug) debug.write(response, 'utf8')
        }
      }

      if(!this.expects.length)
      {
        this.push(null)
        sentEof = true
      }
    }

    callback()
  }
}
util.inherits(SupposeStream, stream.Transform)

SupposeStream.prototype.when = function(condition, response) {
  var expect =
  {
    condition: condition,
    responses: forceArray(response)
  }

  this.expects.push(expect)

  return this
}

SupposeStream.prototype.respond = function(response) {
  var expects = this.expects
  var expect = expects[expects.length-1]

  expect.responses = expect.responses.concat(response)

  return this
}

module.exports = SupposeStream
<commit_msg>Use the return value of a response argument whose value is a function<commit_after>var escape     = require('escape-string-regexp')
var forceArray = require('force-array')
var stream     = require('stream')
var strip      = require('strip-ansi')
var util       = require('util')

function SupposeStream(options) {
  if(!(this instanceof SupposeStream)) return new SupposeStream(options)

  SupposeStream.super_.call(this)

  var debug
  var stripAnsi
  if(options)
  {
    debug = (options instanceof stream.Writable) ? options : options.debug
    if(options.stripAnsi) stripAnsi = strip
  }

  this.expects = []

  var readBuffer = ''
  var needNew = true
  var sentEof = false

  var condition
  var responses

  this._transform = function(chunk, encoding, callback)
  {
    if(debug) debug.write(chunk)

    readBuffer += chunk.toString()
    if(needNew)
    {
      var expect = this.expects.shift()

      condition = expect && expect.condition
      responses = expect && expect.responses

      if(!expect && !sentEof)
      {
        // this.expects was always empty
        this.push(null)
        sentEof = true
      }

      needNew = false
    }

    const buffer = stripAnsi ? stripAnsi(readBuffer) : readBuffer

    var match
    switch(typeof condition)
    {
      case 'string':
        match = new RegExp(escape(condition) + `[^\S\r\n]*`).test(buffer);
      break

      case 'object':
        match = buffer.match(condition)
    }

    if(match)
    {
      match = (match instanceof Array) ? match.slice(1) : []

      readBuffer = ''
      needNew = true

      for(let response of responses)
      {
        if(response instanceof Function) response = response.apply(this, match)

        this.push(response)

        if(debug) debug.write(response, 'utf8')
      }

      if(!this.expects.length)
      {
        this.push(null)
        sentEof = true
      }
    }

    callback()
  }
}
util.inherits(SupposeStream, stream.Transform)

SupposeStream.prototype.when = function(condition, response) {
  var expect =
  {
    condition: condition,
    responses: forceArray(response)
  }

  this.expects.push(expect)

  return this
}

SupposeStream.prototype.respond = function(response) {
  var expects = this.expects
  var expect = expects[expects.length-1]

  expect.responses = expect.responses.concat(response)

  return this
}

module.exports = SupposeStream
<|endoftext|>


<commit_before>'use strict';

var Utils = require('../../utils')
  , _ = require('lodash')
  , Promise = require('../../promise')
  , AbstractQuery = require('../abstract/query')
  , QueryTypes = require('../../query-types')
  , sequelizeErrors = require('../../errors.js')
  , parserStore = require('../parserStore')('sqlite');

var Query = function(database, sequelize, options) {
  this.database = database;
  this.sequelize = sequelize;
  this.instance = options.instance;
  this.model = options.model;
  this.options = _.extend({
    logging: console.log,
    plain: false,
    raw: false
  }, options || {});

  this.checkLoggingOption();
};
Utils.inherit(Query, AbstractQuery);

Query.prototype.getInsertIdField = function() {
  return 'lastID';
};

/**
 * rewrite query with parameters
 */
Query.formatBindParameters = function(sql, values, dialect) {
  var bindParam = [];
  if (Array.isArray(values)) {
    bindParam = {};
    values.forEach(function(v, i) {
      bindParam['$'+(i+1)] = v;
    });
    sql = AbstractQuery.formatBindParameters(sql, values, dialect, { skipValueReplace: true })[0];
  } else {
    bindParam = {};
    if (typeof values === 'object') {
      Object.keys(values).forEach(function(k) {
        bindParam['$'+k] = values[k];
      });
    }
    sql = AbstractQuery.formatBindParameters(sql, values, dialect, { skipValueReplace: true })[0];
  }
  return [sql, bindParam];
};

Query.prototype.$collectModels = function(include, prefix) {
  var ret = {};

  if (include) {
    include.forEach(function (include) {
      var key;
      if (!prefix) {
        key = include.as;
      } else {
        key = prefix + '.' + include.as;
      }
      ret[key] = include.model;

      if (include.include) {
        _.merge(ret, this.$collectModels(include.include, key));
      }
    }, this);
  }

  return ret;
};

Query.prototype.run = function(sql, parameters) {
  var self = this
    , promise;

  this.sql = sql;
  var method = self.getDatabaseMethod();
  if (method === 'exec') {
    // exec does not support bind parameter
    sql = AbstractQuery.formatBindParameters(sql, self.options.bind, self.options.dialect, { skipUnescape: true })[0];
    this.sql = sql;
  }

  //do we need benchmark for this query execution
  var benchmark = this.sequelize.options.benchmark || this.options.benchmark;

  if (benchmark) {
    var queryBegin = Date.now();
  } else {
    this.sequelize.log('Executing (' + (this.database.uuid || 'default') + '): ' + this.sql, this.options);
  }

  promise = new Promise(function(resolve) {
    var columnTypes = {};
    self.database.serialize(function() {
      var executeSql = function() {
        if (self.sql.indexOf('-- ') === 0) {
          return resolve();
        } else {
          resolve(new Promise(function(resolve, reject) {
            var afterExecute = function(err, results) {

              if (benchmark) {
                self.sequelize.log('Executed (' + (self.database.uuid || 'default') + '): ' + self.sql, (Date.now() - queryBegin), self.options);
              }

              if (err) {
                err.sql = self.sql;
                reject(self.formatError(err));
              } else {
                var metaData = this
                  , result = self.instance;

                // add the inserted row id to the instance
                if (self.isInsertQuery(results, metaData)) {
                  self.handleInsertQuery(results, metaData);

                  if (!self.instance) {
                    result = metaData[self.getInsertIdField()];
                  }
                }

                if (self.sql.indexOf('sqlite_master') !== -1) {
                  result = results.map(function(resultSet) { return resultSet.name; });
                } else if (self.isSelectQuery()) {
                  if (!self.options.raw) {
                    // This is a map of prefix strings to models, e.g. user.projects -> Project model
                    var prefixes = self.$collectModels(self.options.include);

                    results = results.map(function(result) {
                      return _.mapValues(result, function (value, name) {
                        var model;
                        if (name.indexOf('.') !== -1) {
                          var lastind = name.lastIndexOf('.');

                          model = prefixes[name.substr(0, lastind)];

                          name = name.substr(lastind + 1);
                        } else {
                          model = self.options.model;
                        }

                        var tableName = model.getTableName().toString().replace(/`/g, '')
                          , tableTypes = columnTypes[tableName];

                        if (tableTypes && !(name in tableTypes)) {
                          // The column is aliased
                           _.forOwn(model.rawAttributes, function (attribute, key) {
                            if (name === key && attribute.field) {
                              name = attribute.field;
                              return false;
                            }
                          });
                        }

                        var type = tableTypes[name];
                        if (type) {
                          if (type.indexOf('(') !== -1) {
                            // Remove the lenght part
                            type = type.substr(0, type.indexOf('('));
                          }
                          type = type.replace('UNSIGNED', '').replace('ZEROFILL', '');
                          type = type.trim().toUpperCase();
                          var parse = parserStore.get(type);

                          if (value !== null && parse) {
                            return parse(value, { timezone: self.sequelize.options.timezone});
                          }
                        }
                        return value;
                      });
                    });
                  }

                  result = self.handleSelectQuery(results);
                } else if (self.isShowOrDescribeQuery()) {
                  result = results;
                } else if (self.sql.indexOf('PRAGMA INDEX_LIST') !== -1) {
                  result = self.handleShowIndexesQuery(results);
                } else if (self.sql.indexOf('PRAGMA INDEX_INFO') !== -1) {
                  result = results;
                } else if (self.sql.indexOf('PRAGMA TABLE_INFO') !== -1) {
                  // this is the sqlite way of getting the metadata of a table
                  result = {};

                  var defaultValue;
                  results.forEach(function(_result) {
                    if (_result.dflt_value === null) {
                      // Column schema omits any "DEFAULT ..."
                      defaultValue = undefined;
                    } else if (_result.dflt_value === 'NULL') {
                      // Column schema is a "DEFAULT NULL"
                      defaultValue = null;
                    } else {
                      defaultValue = _result.dflt_value;
                    }

                    result[_result.name] = {
                      type: _result.type,
                      allowNull: (_result.notnull === 0),
                      defaultValue: defaultValue,
                      primaryKey : (_result.pk === 1)
                    };

                    if (result[_result.name].type === 'TINYINT(1)') {
                      result[_result.name].defaultValue = { '0': false, '1': true }[result[_result.name].defaultValue];
                    }

                    if (typeof result[_result.name].defaultValue === 'string') {
                      result[_result.name].defaultValue = result[_result.name].defaultValue.replace(/'/g, '');
                    }
                  });
                } else if (self.sql.indexOf('PRAGMA foreign_keys;') !== -1) {
                  result = results[0];
                } else if (self.sql.indexOf('PRAGMA foreign_keys') !== -1) {
                  result = results;
                } else if (self.sql.indexOf('PRAGMA foreign_key_list') !== -1) {
                  result = results;
                } else if ([QueryTypes.BULKUPDATE, QueryTypes.BULKDELETE].indexOf(self.options.type) !== -1) {
                  result = metaData.changes;
                } else if (self.options.type === QueryTypes.UPSERT) {
                  result = undefined;
                } else if (self.options.type === QueryTypes.VERSION) {
                  result = results[0].version;
                } else if (self.options.type === QueryTypes.RAW) {
                  result = [results, metaData];
                }

                resolve(result);
              }
            };

            if (method === 'exec') {
              // exec does not support bind parameter
              self.database[method](self.sql, afterExecute);
            } else {
              if (!parameters) parameters = [];
              self.database[method](self.sql, parameters, afterExecute);
            }
          }));
          return null;
        }
      };

      if ((self.getDatabaseMethod() === 'all')) {
        var tableNames = [];
        if (self.options && self.options.tableNames) {
          tableNames = self.options.tableNames;
        } else if (/FROM `(.*?)`/i.exec(self.sql)) {
          tableNames.push(/FROM `(.*?)`/i.exec(self.sql)[1]);
        }

        // If we already have the metadata for the table, there's no need to ask for it again
        tableNames = _.filter(tableNames, function (tableName) {
          return !(tableName in columnTypes) && tableName !== 'sqlite_master';
        });

        if (!tableNames.length) {
          return executeSql();
        } else {
          return Promise.map(tableNames, function(tableName) {
            return new Promise(function(resolve) {
              tableName = tableName.replace(/`/g, '');
              columnTypes[tableName] = {};

              self.database.all('PRAGMA table_info(`' + tableName + '`)', function(err, results) {
                if (!err) {
                  results.forEach(function (result) {
                    columnTypes[tableName][result.name] = result.type;
                  });
                }
                resolve();
              });
            });
          }).then(executeSql);
        }
      } else {
        return executeSql();
      }
    });
  });

  return promise;
};

Query.prototype.formatError = function (err) {
  var match;

  switch (err.code) {
    case 'SQLITE_CONSTRAINT':
      match = err.message.match(/FOREIGN KEY constraint failed/);
      if (match !== null) {
        return new sequelizeErrors.ForeignKeyConstraintError({
          parent :err
        });
      }

      var fields = [];

      // Sqlite pre 2.2 behavior - Error: SQLITE_CONSTRAINT: columns x, y are not unique
      match = err.message.match(/columns (.*?) are/);
      if (match !== null && match.length >= 2) {
        fields = match[1].split(', ');
      } else {

        // Sqlite post 2.2 behavior - Error: SQLITE_CONSTRAINT: UNIQUE constraint failed: table.x, table.y
        match = err.message.match(/UNIQUE constraint failed: (.*)/);
        if (match !== null && match.length >= 2) {
          fields = match[1].split(', ').map(function (columnWithTable) {
            return columnWithTable.split('.')[1];
          });
        }
      }

      var errors = []
        , self = this
        , message = 'Validation error';

      fields.forEach(function(field) {
        errors.push(new sequelizeErrors.ValidationErrorItem(
          self.getUniqueConstraintErrorMessage(field),
          'unique violation', field, self.instance && self.instance[field]));
      });

      if (this.model) {
        _.forOwn(this.model.uniqueKeys, function(constraint) {
          if (_.isEqual(constraint.fields, fields) && !!constraint.msg) {
            message = constraint.msg;
            return false;
          }
        });
      }

      return new sequelizeErrors.UniqueConstraintError({
        message: message,
        errors: errors,
        parent: err,
        fields: fields
      });

    case 'SQLITE_BUSY':
      return new sequelizeErrors.TimeoutError(err);

    default:
      return new sequelizeErrors.DatabaseError(err);
  }
};

Query.prototype.handleShowIndexesQuery = function (data) {
  var self = this;

  // Sqlite returns indexes so the one that was defined last is returned first. Lets reverse that!
  return this.sequelize.Promise.map(data.reverse(), function (item) {
    item.fields = [];
    item.primary = false;
    item.unique = !!item.unique;

    return self.run('PRAGMA INDEX_INFO(`' + item.name + '`)').then(function (columns) {
      columns.forEach(function (column) {
        item.fields[column.seqno] = {
          attribute: column.name,
          length: undefined,
          order: undefined,
        };
      });

      return item;
    });
  });
};

Query.prototype.getDatabaseMethod = function() {
  if (this.isUpsertQuery()) {
    return 'exec'; // Needed to run multiple queries in one
  } else if (this.isInsertQuery() || this.isUpdateQuery() || this.isBulkUpdateQuery() || (this.sql.toLowerCase().indexOf('CREATE TEMPORARY TABLE'.toLowerCase()) !== -1) || this.options.type === QueryTypes.BULKDELETE) {
    return 'run';
  } else {
    return 'all';
  }
};

module.exports = Query;
<commit_msg>fix 5755 for v3 branch (#6865)<commit_after>'use strict';

var Utils = require('../../utils')
  , _ = require('lodash')
  , Promise = require('../../promise')
  , AbstractQuery = require('../abstract/query')
  , QueryTypes = require('../../query-types')
  , sequelizeErrors = require('../../errors.js')
  , parserStore = require('../parserStore')('sqlite');

var Query = function(database, sequelize, options) {
  this.database = database;
  this.sequelize = sequelize;
  this.instance = options.instance;
  this.model = options.model;
  this.options = _.extend({
    logging: console.log,
    plain: false,
    raw: false
  }, options || {});

  this.checkLoggingOption();
};
Utils.inherit(Query, AbstractQuery);

Query.prototype.getInsertIdField = function() {
  return 'lastID';
};

/**
 * rewrite query with parameters
 */
Query.formatBindParameters = function(sql, values, dialect) {
  var bindParam = [];
  if (Array.isArray(values)) {
    bindParam = {};
    values.forEach(function(v, i) {
      bindParam['$'+(i+1)] = v;
    });
    sql = AbstractQuery.formatBindParameters(sql, values, dialect, { skipValueReplace: true })[0];
  } else {
    bindParam = {};
    if (typeof values === 'object') {
      Object.keys(values).forEach(function(k) {
        bindParam['$'+k] = values[k];
      });
    }
    sql = AbstractQuery.formatBindParameters(sql, values, dialect, { skipValueReplace: true })[0];
  }
  return [sql, bindParam];
};

Query.prototype.$collectModels = function(include, prefix) {
  var ret = {};

  if (include) {
    include.forEach(function (include) {
      var key;
      if (!prefix) {
        key = include.as;
      } else {
        key = prefix + '.' + include.as;
      }
      ret[key] = include.model;

      if (include.include) {
        _.merge(ret, this.$collectModels(include.include, key));
      }
    }, this);
  }

  return ret;
};

Query.prototype.run = function(sql, parameters) {
  var self = this
    , promise;

  this.sql = sql;
  var method = self.getDatabaseMethod();
  if (method === 'exec') {
    // exec does not support bind parameter
    sql = AbstractQuery.formatBindParameters(sql, self.options.bind, self.options.dialect, { skipUnescape: true })[0];
    this.sql = sql;
  }

  //do we need benchmark for this query execution
  var benchmark = this.sequelize.options.benchmark || this.options.benchmark;

  if (benchmark) {
    var queryBegin = Date.now();
  } else {
    this.sequelize.log('Executing (' + (this.database.uuid || 'default') + '): ' + this.sql, this.options);
  }

  promise = new Promise(function(resolve) {
    var columnTypes = {};
    self.database.serialize(function() {
      var executeSql = function() {
        if (self.sql.indexOf('-- ') === 0) {
          return resolve();
        } else {
          resolve(new Promise(function(resolve, reject) {
            var afterExecute = function(err, results) {

              if (benchmark) {
                self.sequelize.log('Executed (' + (self.database.uuid || 'default') + '): ' + self.sql, (Date.now() - queryBegin), self.options);
              }

              if (err) {
                err.sql = self.sql;
                reject(self.formatError(err));
              } else {
                var metaData = this
                  , result = self.instance;

                // add the inserted row id to the instance
                if (self.isInsertQuery(results, metaData)) {
                  self.handleInsertQuery(results, metaData);

                  if (!self.instance) {
                    result = metaData[self.getInsertIdField()];
                  }
                }

                if (self.sql.indexOf('sqlite_master') !== -1) {
                  result = results.map(function(resultSet) { return resultSet.name; });
                } else if (self.isSelectQuery()) {
                  if (!self.options.raw) {
                    // This is a map of prefix strings to models, e.g. user.projects -> Project model
                    var prefixes = self.$collectModels(self.options.include);

                    results = results.map(function(result) {
                      return _.mapValues(result, function (value, name) {
                        var model;
                        if (name.indexOf('.') !== -1) {
                          var lastind = name.lastIndexOf('.');

                          model = prefixes[name.substr(0, lastind)];

                          name = name.substr(lastind + 1);
                        } else {
                          model = self.options.model;
                        }

                        var tableName = model.getTableName().toString().replace(/`/g, '')
                          , tableTypes = columnTypes[tableName] || {};

                        if (tableTypes && !(name in tableTypes)) {
                          // The column is aliased
                           _.forOwn(model.rawAttributes, function (attribute, key) {
                            if (name === key && attribute.field) {
                              name = attribute.field;
                              return false;
                            }
                          });
                        }

                        var type = tableTypes[name];
                        if (type) {
                          if (type.indexOf('(') !== -1) {
                            // Remove the lenght part
                            type = type.substr(0, type.indexOf('('));
                          }
                          type = type.replace('UNSIGNED', '').replace('ZEROFILL', '');
                          type = type.trim().toUpperCase();
                          var parse = parserStore.get(type);

                          if (value !== null && parse) {
                            return parse(value, { timezone: self.sequelize.options.timezone});
                          }
                        }
                        return value;
                      });
                    });
                  }

                  result = self.handleSelectQuery(results);
                } else if (self.isShowOrDescribeQuery()) {
                  result = results;
                } else if (self.sql.indexOf('PRAGMA INDEX_LIST') !== -1) {
                  result = self.handleShowIndexesQuery(results);
                } else if (self.sql.indexOf('PRAGMA INDEX_INFO') !== -1) {
                  result = results;
                } else if (self.sql.indexOf('PRAGMA TABLE_INFO') !== -1) {
                  // this is the sqlite way of getting the metadata of a table
                  result = {};

                  var defaultValue;
                  results.forEach(function(_result) {
                    if (_result.dflt_value === null) {
                      // Column schema omits any "DEFAULT ..."
                      defaultValue = undefined;
                    } else if (_result.dflt_value === 'NULL') {
                      // Column schema is a "DEFAULT NULL"
                      defaultValue = null;
                    } else {
                      defaultValue = _result.dflt_value;
                    }

                    result[_result.name] = {
                      type: _result.type,
                      allowNull: (_result.notnull === 0),
                      defaultValue: defaultValue,
                      primaryKey : (_result.pk === 1)
                    };

                    if (result[_result.name].type === 'TINYINT(1)') {
                      result[_result.name].defaultValue = { '0': false, '1': true }[result[_result.name].defaultValue];
                    }

                    if (typeof result[_result.name].defaultValue === 'string') {
                      result[_result.name].defaultValue = result[_result.name].defaultValue.replace(/'/g, '');
                    }
                  });
                } else if (self.sql.indexOf('PRAGMA foreign_keys;') !== -1) {
                  result = results[0];
                } else if (self.sql.indexOf('PRAGMA foreign_keys') !== -1) {
                  result = results;
                } else if (self.sql.indexOf('PRAGMA foreign_key_list') !== -1) {
                  result = results;
                } else if ([QueryTypes.BULKUPDATE, QueryTypes.BULKDELETE].indexOf(self.options.type) !== -1) {
                  result = metaData.changes;
                } else if (self.options.type === QueryTypes.UPSERT) {
                  result = undefined;
                } else if (self.options.type === QueryTypes.VERSION) {
                  result = results[0].version;
                } else if (self.options.type === QueryTypes.RAW) {
                  result = [results, metaData];
                }

                resolve(result);
              }
            };

            if (method === 'exec') {
              // exec does not support bind parameter
              self.database[method](self.sql, afterExecute);
            } else {
              if (!parameters) parameters = [];
              self.database[method](self.sql, parameters, afterExecute);
            }
          }));
          return null;
        }
      };

      if ((self.getDatabaseMethod() === 'all')) {
        var tableNames = [];
        if (self.options && self.options.tableNames) {
          tableNames = self.options.tableNames;
        } else if (/FROM `(.*?)`/i.exec(self.sql)) {
          tableNames.push(/FROM `(.*?)`/i.exec(self.sql)[1]);
        }

        // If we already have the metadata for the table, there's no need to ask for it again
        tableNames = _.filter(tableNames, function (tableName) {
          return !(tableName in columnTypes) && tableName !== 'sqlite_master';
        });

        if (!tableNames.length) {
          return executeSql();
        } else {
          return Promise.map(tableNames, function(tableName) {
            return new Promise(function(resolve) {
              tableName = tableName.replace(/`/g, '');
              columnTypes[tableName] = {};

              self.database.all('PRAGMA table_info(`' + tableName + '`)', function(err, results) {
                if (!err) {
                  results.forEach(function (result) {
                    columnTypes[tableName][result.name] = result.type;
                  });
                }
                resolve();
              });
            });
          }).then(executeSql);
        }
      } else {
        return executeSql();
      }
    });
  });

  return promise;
};

Query.prototype.formatError = function (err) {
  var match;

  switch (err.code) {
    case 'SQLITE_CONSTRAINT':
      match = err.message.match(/FOREIGN KEY constraint failed/);
      if (match !== null) {
        return new sequelizeErrors.ForeignKeyConstraintError({
          parent :err
        });
      }

      var fields = [];

      // Sqlite pre 2.2 behavior - Error: SQLITE_CONSTRAINT: columns x, y are not unique
      match = err.message.match(/columns (.*?) are/);
      if (match !== null && match.length >= 2) {
        fields = match[1].split(', ');
      } else {

        // Sqlite post 2.2 behavior - Error: SQLITE_CONSTRAINT: UNIQUE constraint failed: table.x, table.y
        match = err.message.match(/UNIQUE constraint failed: (.*)/);
        if (match !== null && match.length >= 2) {
          fields = match[1].split(', ').map(function (columnWithTable) {
            return columnWithTable.split('.')[1];
          });
        }
      }

      var errors = []
        , self = this
        , message = 'Validation error';

      fields.forEach(function(field) {
        errors.push(new sequelizeErrors.ValidationErrorItem(
          self.getUniqueConstraintErrorMessage(field),
          'unique violation', field, self.instance && self.instance[field]));
      });

      if (this.model) {
        _.forOwn(this.model.uniqueKeys, function(constraint) {
          if (_.isEqual(constraint.fields, fields) && !!constraint.msg) {
            message = constraint.msg;
            return false;
          }
        });
      }

      return new sequelizeErrors.UniqueConstraintError({
        message: message,
        errors: errors,
        parent: err,
        fields: fields
      });

    case 'SQLITE_BUSY':
      return new sequelizeErrors.TimeoutError(err);

    default:
      return new sequelizeErrors.DatabaseError(err);
  }
};

Query.prototype.handleShowIndexesQuery = function (data) {
  var self = this;

  // Sqlite returns indexes so the one that was defined last is returned first. Lets reverse that!
  return this.sequelize.Promise.map(data.reverse(), function (item) {
    item.fields = [];
    item.primary = false;
    item.unique = !!item.unique;

    return self.run('PRAGMA INDEX_INFO(`' + item.name + '`)').then(function (columns) {
      columns.forEach(function (column) {
        item.fields[column.seqno] = {
          attribute: column.name,
          length: undefined,
          order: undefined,
        };
      });

      return item;
    });
  });
};

Query.prototype.getDatabaseMethod = function() {
  if (this.isUpsertQuery()) {
    return 'exec'; // Needed to run multiple queries in one
  } else if (this.isInsertQuery() || this.isUpdateQuery() || this.isBulkUpdateQuery() || (this.sql.toLowerCase().indexOf('CREATE TEMPORARY TABLE'.toLowerCase()) !== -1) || this.options.type === QueryTypes.BULKDELETE) {
    return 'run';
  } else {
    return 'all';
  }
};

module.exports = Query;
<|endoftext|>