def exec(self) -> dict:
        if not _auth.get_current_user().has_role(['admin', 'dev']):
            raise self.forbidden()

        _reload.reload()

        return {'status': True}
Esempio n. 2
0
    def exec(self) -> dict:
        if not _auth.get_current_user().has_permission('plugman_ui@manage'):
            raise self.forbidden()

        _plugman.install(self.arg('name'))
        _reload.reload()

        return {'status': True}
Esempio n. 3
0
    def exec(self) -> dict:
        if not _auth.get_current_user().has_permission('plugman_ui@manage'):
            raise self.forbidden()

        plugin_name = self.arg('name')

        _plugman.install(plugin_name)
        _reload.reload()

        return _plugman.local_plugin_info(plugin_name, False)
Esempio n. 4
0
def install(archive_path: str, delete_zip_file: bool = True):
    """Install a theme from a zip-file
    """
    logger.debug(
        'Requested theme installation from zip-file {}'.format(archive_path))

    # Create temporary directory
    tmp_dir_path = util.mk_tmp_dir(subdir='theme')

    try:
        # Extract archive to the temporary directory
        _extract_archive(archive_path, tmp_dir_path)

        # Try to initialize the theme to ensure everything is okay
        theme = _theme.Theme('tmp.theme.{}'.format(
            path.basename(tmp_dir_path)))

        # Install required pip packages
        for pkg_name, pkg_version in theme.requires['packages'].items():
            logger.info(
                "Theme '{}' requires pip package '{} {}', going to install it".
                format(theme.name, pkg_name, pkg_name, pkg_version))
            pip.install(pkg_name, pkg_version, True, reg.get('debug'))

        # Install required plugins
        for p_name, p_version in theme.requires['plugins'].items():
            if not plugman.is_installed(p_name, VersionRange(p_version)):
                logger.info(
                    "Theme '{}' requires plugin '{}', installing...".format(
                        theme.name, p_name, p_version))
                plugman.install(p_name, VersionRange(p_version))

        # Theme has been successfully initialized, so now it can be moved to the 'themes' package
        dst_path = path.join(_themes_path, theme.name)
        if path.exists(dst_path):
            logger.warn(
                "Existing theme installation at '{}' will be replaced with new one"
                .format(dst_path))
            rmtree(dst_path)

        # Move directory to the final location
        move(tmp_dir_path, dst_path)
        logger.debug("'{}' has been successfully moved to '{}'".format(
            tmp_dir_path, dst_path))

        reload.reload()

    finally:
        # Remove temporary directory
        if path.exists(tmp_dir_path):
            rmtree(tmp_dir_path)

        # Remove ZIP file
        if delete_zip_file:
            unlink(archive_path)
Esempio n. 5
0
    def exec(self):
        if not self.args:
            raise _console.error.MissingArgument('pytsite.plugman@plugins_not_specified')

        try:
            for p_name in self.args:
                _api.uninstall(p_name)
        except _error.Error as e:
            raise _console.error.CommandExecutionError(e)

        _reload.reload()
Esempio n. 6
0
def switch(package_name: str):
    """Switch current theme
    """
    if package_name not in _fallback_theme_name:
        raise _error.ThemeNotRegistered(package_name)

    # Switch only if it really necessary
    if package_name != get().package_name:
        reg.put('theme.current', package_name)  # Mark theme as current
        reg.put('theme.compiled', False)  # Mark that assets compilation needed
        reload.reload()
Esempio n. 7
0
    def exec(self):
        stage = self.opt('stage')

        if stage == 1:
            installed_count = 0
            plugins_specs = {}

            if self.args:
                # Install/update specified plugins
                for p_spec in self.args:
                    match = _PLUGINS_SPEC_RE.findall(p_spec)
                    if not match:
                        raise _console.error.CommandExecutionError('Invalid plugin identifier: {}'.format(p_spec))
                    plugins_specs[match[0][0]] = match[0][1]
            else:
                # Install/update all required plugins
                plugins_specs = _package_info.requires_plugins('app')

            # Install/update plugins
            for plugin_name, plugin_version in plugins_specs.items():
                try:
                    use_cache = not self.opt('no-cache')
                    installed_count += _api.install(plugin_name, _semver.VersionRange(plugin_version), use_cache)
                except _error.Error as e:
                    raise _console.error.CommandExecutionError(e)

            # Run second stage to call plugin_install() and plugin_update() hooks for every installed plugin
            if installed_count:
                return _subprocess.run(['./console', self.name, '--stage=2']).returncode

        elif stage == 2:
            # At this point trigger _eh.on_pytsite_load() event handler, which calls plugin_install() and
            # plugin_update() for every previously installed plugin.

            # During call to plugin_* hooks some plugins (for example `theming`) can install other plugins,
            # so we need to restart application in console mode in order to call installation hooks of that plugins.
            if _api.get_update_info():
                return _subprocess.run(['./console', self.name, '--stage=3']).returncode
            elif self.opt('reload'):
                _reload.reload()

        elif stage == 3 and self.opt('reload'):
            # Let all waiting plugins process their hooks and then reload application
            _reload.reload()
Esempio n. 8
0
    def exec(self, args: tuple = (), **kwargs):
        """Execute the command.
        """
        app_path = _reg.get('paths.app')
        config_path = _reg.get('paths.config')
        stage = self.opt('stage')
        stop_after = self.opt('stop-after')

        _chdir(app_path)
        _maintenance.enable()

        d = self._get_update_data()
        if not d['update_in_progress']:
            d['pytsite_version_from'] = str(_package_info.version('pytsite'))
            d['app_version_from'] = str(_package_info.version('app'))
            d['update_in_progress'] = True
            self._set_update_data(d)

        # Stage 1: update pip and PytSite
        if stage == 1:
            _console.print_info(_lang.t('pytsite.update@updating_environment'))

            # Update pip
            _pip.install('pip', None, True, self.opt('debug'))

            # Update PytSite
            _pip.install('pytsite', _package_info.requires_pytsite('app'), True, self.opt('debug'))

            d['pytsite_version_to'] = str(_package_info.version('pytsite', False))
            self._set_update_data(d)

            # Notify listeners
            _events.fire('pytsite.update@stage_1')

            if stop_after != 1:
                _subprocess.call(['./console', 'update', '--stage=2'])
            else:
                _maintenance.disable()

        # Stage 2: update application and configuration
        elif stage == 2:
            # Notify listeners about PytSite update
            _events.fire('pytsite.update@pytsite', v_from=_semver.Version(d['pytsite_version_from']))

            # Update configuration
            if _path.exists(_path.join(config_path, '.git')):
                _console.print_info(_lang.t('pytsite.update@updating_configuration'))
                _subprocess_run(['git', '-C', config_path, 'pull'])

            # Update application
            if _path.exists(_path.join(app_path, '.git')):
                _console.print_info(_lang.t('pytsite.update@updating_application'))
                _subprocess_run(['git', '-C', app_path, 'pull'])
            d['app_version_to'] = str(_package_info.version('app', False))
            self._set_update_data(d)

            # Notify listeners
            _events.fire('pytsite.update@stage_2')

            if stop_after != 2:
                _subprocess.call(['./console', 'update', '--stage=3'])
            else:
                _maintenance.disable()

        # Stage 3: finish update process
        elif stage == 3:
            _console.print_info(_lang.t('pytsite.update@applying_updates'))

            # Notify listeners about application update
            _events.fire('pytsite.update@app', v_from=_semver.Version(d['app_version_from']))

            # Notify listeners
            _events.fire('pytsite.update@update')

            # Application's update hook
            import app
            if hasattr(app, 'app_update') and callable(app.app_update):
                app.app_update(v_from=_semver.Version(d['app_version_from']))

            # Mark that update was finished successfully
            d['update_in_progress'] = False
            self._set_update_data(d)

            # Disable maintenance mode
            _maintenance.disable()

            # Reload the application
            _reload.reload()