Exemple #1
0
class CreateDatabaseStep(BaseWizardStep):
    gladefile = 'CreateDatabaseStep'

    def post_init(self):
        self.n_patches = 0
        self.process_view = ProcessView()
        self.process_view.listen_stderr = True
        self.process_view.connect('read-line', self._on_processview__readline)
        self.process_view.connect('finished', self._on_processview__finished)
        self.expander.add(self.process_view)
        self.expander.grab_focus()
        self._maybe_create_database()

    def next_step(self):
        return LinkStep(self.wizard, self)

    def _maybe_create_database(self):
        logger.info('_maybe_create_database (db_is_local=%s, enable_production=%s)'
                    % (self.wizard.db_is_local, self.wizard.enable_production))
        if self.wizard.db_is_local:
            self._launch_stoqdbadmin()
            return
        elif self.wizard.enable_production:
            self._launch_stoqdbadmin()
            return

        self.wizard.write_pgpass()
        settings = self.wizard.settings
        self.wizard.config.load_settings(settings)

        store = settings.create_super_store()
        version = get_database_version(store)

        if version < (9, 1):
            store.close()
            error(_("Stoq requires PostgresSQL 9.1 or later, but %s found") % (
                ".".join(map(str, version))))

        try:
            check_extensions(store=store)
        except ValueError:
            store.close()
            error(_("Missing PostgreSQL extension on the server, "
                    "please install postgresql-contrib on it"))

        store.close()

        # Secondly, ask the user if he really wants to create the database,
        dbname = settings.dbname
        if yesno(_(u"The specified database '%s' does not exist.\n"
                   u"Do you want to create it?") % dbname,
                 gtk.RESPONSE_YES, _(u"Create database"), _(u"Don't create")):
            self.process_view.feed("** Creating database\r\n")
            self._launch_stoqdbadmin()
        else:
            self.process_view.feed("** Not creating database\r\n")
            self.wizard.disable_next()

    def _launch_stoqdbadmin(self):
        logger.info('_launch_stoqdbadmin')
        self.wizard.disable_back()
        self.wizard.disable_next()

        if sys.argv[0].endswith('.egg'):
            args = [sys.executable, sys.argv[0]]
        elif platform.system() == 'Windows':
            if library.uninstalled:
                args = ['stoq.bat']
            else:
                args = ['stoq.exe']
        else:
            args = ['stoq']

        args.extend([
            'dbadmin', 'init',
            '--no-load-config', '--no-register-station', '-v'])

        if self.wizard.create_examples:
            args.append('--demo')
        elif self.wizard.enable_production:
            args.append('--force')

        if self.wizard.plugins:
            args.append('--enable-plugins')
            args.append(','.join(self.wizard.plugins))
        if self.wizard.db_is_local:
            args.append('--create-dbuser')

        dbargs = self.wizard.settings.get_command_line_arguments()
        args.extend(dbargs)
        self.label.set_label(
            _("Creating a new database for Stoq, depending on the speed of "
              "your computer and the server it may take a couple of "
              "minutes to finish."))
        self.progressbar.set_text(_("Creating database..."))
        self.progressbar.set_fraction(0.05)
        logger.info(' '.join(args))
        self.process_view.execute_command(args)
        self.done_label.set_markup(
            _("Please wait while the database is being created."))

    def _parse_process_line(self, line):
        LOG_CATEGORY = 'stoqlib.database.create'
        log_pos = line.find(LOG_CATEGORY)
        if log_pos == -1:
            return
        line = line[log_pos + len(LOG_CATEGORY) + 1:]
        if line == 'SCHEMA':
            value = 0.1
            text = _("Creating base schema...")
        elif line.startswith('PATCHES:'):
            value = 0.35
            self.n_patches = int(line.split(':', 1)[1])
            text = _("Creating schema, applying patches...")
        elif line.startswith('PATCH:'):
            # 0.4 - 0.7 patches
            patch = float(line.split(':', 1)[1])
            value = 0.4 + (patch / self.n_patches) * 0.3
            text = _("Creating schema, applying patch %d ...") % (patch + 1, )
        elif line == 'INIT START':
            text = _("Creating additional database objects ...")
            value = 0.8
        elif line == 'INIT DONE' and self.wizard.create_examples:
            text = _("Creating examples ...")
            value = 0.85
        elif line.startswith('PLUGIN'):
            text = _("Activating plugins ...")
            if 'nfe' in self.wizard.plugins:
                text += ' ' + _('This may take some time.')
            value = 0.95
        else:
            return
        self.progressbar.set_fraction(value)
        self.progressbar.set_text(text)

    def _finish(self, returncode):
        logger.info('CreateDatabaseStep._finish (returncode=%s)' % returncode)
        if returncode:
            self.wizard.enable_back()
            # Failed to execute/create database
            if returncode == 30:
                # This probably happened because the user either;
                # - pressed cancel in the authentication popup
                # - user erred the password 3 times
                # Allow him to try again
                if yesno(_("Something went wrong while trying to create "
                           "the database. Try again?"),
                         gtk.RESPONSE_NO, _("Change settings"), _("Try again")):
                    return
                self._launch_stoqdbadmin()
                return
            elif returncode == 31:
                # Missing postgresql-contrib package
                self.expander.set_expanded(True)
                warning(_("Your database is missing the postgresql-contrib "
                          "package. Install it and try again"))
            else:
                # Unknown error, just inform user that something went wrong.
                self.expander.set_expanded(True)
                warning(_("Something went wrong while trying to create "
                          "the Stoq database"))
            return
        self.label.set_text("")
        self.wizard.load_config_and_call_setup()
        create_default_profile_settings()
        self.progressbar.set_text(_("Done."))
        self.progressbar.set_fraction(1.0)
        self.wizard.enable_next()
        self.done_label.set_markup(
            _("Installation successful, click <b>Forward</b> to continue."))

    # Callbacks

    def _on_processview__readline(self, view, line):
        self._parse_process_line(line)

    def _on_processview__finished(self, view, returncode):
        self._finish(returncode)
Exemple #2
0
class UpdateSchemaStep(BaseWizardStep):
    gladefile = 'UpdateSchemaStep'

    #
    # WizardStep
    #

    def post_init(self):
        self._finished = False
        self.process_view = ProcessView()
        self.process_view.listen_stderr = True
        self.process_view.connect('read-line', self._on_processview__readline)
        self.process_view.connect('finished', self._on_processview__finished)
        self.expander.add(self.process_view)
        self._launch_stoqdbadmin()
        glib.timeout_add(50, self._on_timeout_add)

    def has_next_step(self):
        return False

    # Private

    def _parse_process_line(self, line):
        # Errors and other messages thrown by stoqdbadmin are not displayed in
        # this wizard. Using info here instead of error, so that the user can
        # still se the log.
        if line.startswith('ERROR:'):
            msg = line[7:]
            info(msg)

        LOG_CATEGORY = 'stoqlib.database.create'
        log_pos = line.find(LOG_CATEGORY)
        if log_pos == -1:
            return
        line = line[log_pos + len(LOG_CATEGORY) + 1:]
        longer = None
        if line.startswith('PATCH:'):
            patch = line.split(':', 1)[1]
            text = _("Applying patch %s ...") % (patch, )
        elif line.startswith('BACKUP-START:'):
            text = _("Creating a database backup")
            longer = _(
                'Creating a database backup in case anything goes wrong.')
        elif line.startswith('RESTORE-START:'):
            text = _("Restoring database backup")
            longer = _('Stoq update failed.\n\n'
                       'We will try to restore the current database.\n\n'
                       'This may take some time.')
        elif line.startswith('RESTORE-DONE:'):
            msg = line.split(':', 1)[1]
            text = _("Database backup restored")
            longer = _(
                'Stoq database update failed but the database was restored.\n'
                'An automatic crash report was submitted. Please, '
                'enter in contact at <b>[email protected]</b> for '
                'assistance in recovering your database and making it '
                'possible to use Stoq %s again.\n\n'
                'A backup database was created as <b>%s</b>') % (
                    stoq.version,
                    msg,
                )
        else:
            return
        self.progressbar.set_text(text)
        if not longer:
            longer = ''
        self.label.set_markup(longer)

    def _launch_stoqdbadmin(self):
        self.wizard.disable_next()
        if sys.argv[0].endswith('.egg'):
            args = [sys.executable, sys.argv[0]]
        elif platform.system() == 'Windows':
            if library.uninstalled:
                args = ['stoq.bat']
            else:
                args = ['stoq.exe']
        else:
            args = ['stoq']

        args.extend(['dbadmin', 'updateschema', '-v'])
        args.extend(api.db_settings.get_command_line_arguments())
        self.process_view.execute_command(args)
        self.progressbar.set_text(_('Applying database patches...'))

    def _finish(self, returncode):
        self._finished = True
        if returncode:
            self.wizard.cancel_button.set_label(gtk.STOCK_QUIT)
            self.progressbar.set_fraction(0.0)
        else:
            # Migration may have changed some parameters, so clear the cache.
            api.sysparam.clear_cache()
            self.wizard.cancel_button.set_sensitive(True)
            self.progressbar.set_text(_("Done. Click 'Forward' to continue"))
            self.progressbar.set_fraction(1.0)
            self.wizard.enable_next()
            self.wizard.next_button.grab_focus()

    # Callbacks

    def _on_processview__readline(self, view, line):
        self._parse_process_line(line)

    def _on_processview__finished(self, view, returncode):
        self._finish(returncode)

    def _on_timeout_add(self):
        if self._finished:
            return False
        self.progressbar.pulse()
        return True
Exemple #3
0
class CreateDatabaseStep(BaseWizardStep):
    gladefile = 'CreateDatabaseStep'

    def post_init(self):
        self.n_patches = 0
        self.process_view = ProcessView()
        self.process_view.listen_stderr = True
        self.process_view.connect('read-line', self._on_processview__readline)
        self.process_view.connect('finished', self._on_processview__finished)
        self.expander.add(self.process_view)
        self.expander.grab_focus()
        self._maybe_create_database()

    def next_step(self):
        return FinishInstallationStep(self.wizard)

    def _maybe_create_database(self):
        logger.info('_maybe_create_database (db_is_local=%s, remove_demo=%s)' %
                    (self.wizard.db_is_local, self.wizard.remove_demo))
        if self.wizard.db_is_local:
            self._launch_stoqdbadmin()
            return
        elif self.wizard.remove_demo:
            self._launch_stoqdbadmin()
            return

        self.wizard.write_pgpass()
        settings = self.wizard.settings
        self.wizard.config.load_settings(settings)

        # store = settings.get_super_store()
        # version = store.dbVersion()
        # if version < (8, 1):
        #     info(_("Stoq requires PostgresSQL 8.1 or later, but %s found") %
        #          ".".join(map(str, version)))
        #     store.close()
        #     return False

        # Secondly, ask the user if he really wants to create the database,
        dbname = settings.dbname
        if yesno(
                _(u"The specified database '%s' does not exist.\n"
                  u"Do you want to create it?") % dbname, gtk.RESPONSE_YES,
                _(u"Create database"), _(u"Don't create")):
            self.process_view.feed("** Creating database\r\n")
            self._launch_stoqdbadmin()
        else:
            self.process_view.feed("** Not creating database\r\n")
            self.wizard.disable_next()

    def _launch_stoqdbadmin(self):
        logger.info('_launch_stoqdbadmin')
        self.wizard.disable_back()
        self.wizard.disable_next()
        stoqdbadmin = 'stoqdbadmin'
        if platform.system() == 'Windows':
            if library.uninstalled:
                stoqdbadmin += '.bat'
            else:
                stoqdbadmin += '.exe'
            # FIXME: listen to file input for
            #        APPDATA/stoqdbadmin/stderr.log + stdout.log
        args = [
            stoqdbadmin, 'init', '--no-load-config', '--no-register-station',
            '-v'
        ]
        if self.wizard.enable_production and not self.wizard.remove_demo:
            args.append('--demo')
        if self.wizard.plugins:
            args.append('--enable-plugins')
            args.append(','.join(self.wizard.plugins))
        if self.wizard.db_is_local:
            args.append('--create-dbuser')

        dbargs = self.wizard.settings.get_command_line_arguments()
        args.extend(dbargs)
        self.label.set_label(
            _("Creating a new database for Stoq, depending on the speed of "
              "your computer and the server it may take a couple of "
              "minutes to finish."))
        self.progressbar.set_text(_("Creating database..."))
        self.progressbar.set_fraction(0.05)
        logger.info(' '.join(args))
        self.process_view.execute_command(args)
        self.done_label.set_markup(
            _("Please wait while the database is being created."))

    def _parse_process_line(self, line):
        LOG_CATEGORY = 'stoqlib.database.create'
        log_pos = line.find(LOG_CATEGORY)
        if log_pos == -1:
            return
        line = line[log_pos + len(LOG_CATEGORY) + 1:]
        if line == 'SCHEMA':
            value = 0.1
            text = _("Creating base schema...")
        elif line.startswith('PATCHES:'):
            value = 0.35
            self.n_patches = int(line.split(':', 1)[1])
            text = _("Creating schema, applying patches...")
        elif line.startswith('PATCH:'):
            # 0.4 - 0.7 patches
            patch = float(line.split(':', 1)[1])
            value = 0.4 + (patch / self.n_patches) * 0.3
            text = _("Creating schema, applying patch %d ...") % (patch + 1, )
        elif line == 'INIT START':
            text = _("Creating additional database objects ...")
            value = 0.8
        elif line == 'INIT DONE' and self.wizard.enable_production:
            text = _("Creating examples ...")
            value = 0.85
        elif line.startswith('PLUGIN'):
            text = _("Activating plugins ...")
            if 'nfe' in self.wizard.plugins:
                text += ' ' + _('This may take some time.')
            value = 0.95
        else:
            return
        self.progressbar.set_fraction(value)
        self.progressbar.set_text(text)

    def _finish(self, returncode):
        logger.info('CreateDatabaseStep._finish (returncode=%s)' % returncode)
        if returncode:
            self.wizard.enable_back()
            # Failed to execute/create database
            if returncode == 30:
                # This probably happened because the user either;
                # - pressed cancel in the authentication popup
                # - user erred the password 3 times
                # Allow him to try again
                if yesno(
                        _("Something went wrong while trying to create "
                          "the database. Try again?"), gtk.RESPONSE_NO,
                        _("Change settings"), _("Try again")):
                    return
                self._launch_stoqdbadmin()
                return
            else:
                # Unknown error, just inform user that something went wrong.
                self.expander.set_expanded(True)
                warning(
                    _("Something went wrong while trying to create "
                      "the Stoq database"))
            return
        self.label.set_text("")
        self.wizard.load_config_and_call_setup()
        create_default_profile_settings()
        ensure_admin_user(self.wizard.config.get_password())
        self.progressbar.set_text(_("Done."))
        self.progressbar.set_fraction(1.0)
        self.wizard.enable_next()
        self.done_label.set_markup(
            _("Installation successful, click <b>Forward</b> to continue."))

    # Callbacks

    def _on_processview__readline(self, view, line):
        self._parse_process_line(line)

    def _on_processview__finished(self, view, returncode):
        self._finish(returncode)
Exemple #4
0
class UpdateSchemaStep(BaseWizardStep):
    gladefile = 'UpdateSchemaStep'

    #
    # WizardStep
    #

    def post_init(self):
        self._finished = False
        self.process_view = ProcessView()
        self.process_view.listen_stderr = True
        self.process_view.connect('read-line', self._on_processview__readline)
        self.process_view.connect('finished', self._on_processview__finished)
        self.expander.add(self.process_view)
        self._launch_stoqdbadmin()
        glib.timeout_add(50, self._on_timeout_add)

    def has_next_step(self):
        return False

    # Private

    def _parse_process_line(self, line):
        # Errors and other messages thrown by stoqdbadmin are not displayed in
        # this wizard. Using info here instead of error, so that the user can
        # still se the log.
        if line.startswith('ERROR:'):
            msg = line[7:]
            info(msg)

        LOG_CATEGORY = 'stoqlib.database.create'
        log_pos = line.find(LOG_CATEGORY)
        if log_pos == -1:
            return
        line = line[log_pos + len(LOG_CATEGORY) + 1:]
        longer = None
        if line.startswith('PATCH:'):
            patch = line.split(':', 1)[1]
            text = _("Applying patch %s ...") % (patch, )
        elif line.startswith('BACKUP-START:'):
            text = _("Creating a database backup")
            longer = _('Creating a database backup in case anything goes wrong.')
        elif line.startswith('RESTORE-START:'):
            text = _("Restoring database backup")
            longer = _(
                'Stoq update failed.\n\n'
                'We will try to restore the current database.\n\n'
                'This may take some time.')
        elif line.startswith('RESTORE-DONE:'):
            msg = line.split(':', 1)[1]
            text = _("Database backup restored")
            longer = _(
                'Stoq database update failed but the database was restored.\n'
                'An automatic crash report was submitted. Please, '
                'enter in contact at <b>[email protected]</b> for '
                'assistance in recovering your database and making it '
                'possible to use Stoq %s again.\n\n'
                'A backup database was created as <b>%s</b>') % (
                stoq.version, msg, )
        else:
            return
        self.progressbar.set_text(text)
        if not longer:
            longer = ''
        self.label.set_markup(longer)

    def _launch_stoqdbadmin(self):
        self.wizard.disable_next()
        args = ['stoqdbadmin', 'updateschema', '-v']
        args.extend(api.db_settings.get_command_line_arguments())
        self.process_view.execute_command(args)
        self.progressbar.set_text(_('Applying database patches...'))

    def _finish(self, returncode):
        self._finished = True
        if returncode:
            self.wizard.cancel_button.set_label(gtk.STOCK_QUIT)
            self.progressbar.set_fraction(0.0)
        else:
            # Migration may have changed some parameters, so clear the cache.
            api.sysparam.clear_cache()
            self.wizard.cancel_button.set_sensitive(True)
            self.progressbar.set_text(_("Done. Click 'Forward' to continue"))
            self.progressbar.set_fraction(1.0)
            self.wizard.enable_next()
            self.wizard.next_button.grab_focus()

    # Callbacks

    def _on_processview__readline(self, view, line):
        self._parse_process_line(line)

    def _on_processview__finished(self, view, returncode):
        self._finish(returncode)

    def _on_timeout_add(self):
        if self._finished:
            return False
        self.progressbar.pulse()
        return True
Exemple #5
0
class UpdateSchemaStep(BaseWizardStep):
    gladefile = "UpdateSchemaStep"

    #
    # WizardStep
    #

    def post_init(self):
        self._finished = False
        self.process_view = ProcessView()
        self.process_view.listen_stderr = True
        self.process_view.connect("read-line", self._on_processview__readline)
        self.process_view.connect("finished", self._on_processview__finished)
        self.expander.add(self.process_view)
        self._launch_stoqdbadmin()
        glib.timeout_add(50, self._on_timeout_add)

    def has_next_step(self):
        return False

    # Private

    def _parse_process_line(self, line):
        # Errors and other messages thrown by stoqdbadmin are not displayed in
        # this wizard. Using info here instead of error, so that the user can
        # still se the log.
        if line.startswith("ERROR:"):
            msg = line[7:]
            info(msg)

        LOG_CATEGORY = "stoqlib.database.create"
        log_pos = line.find(LOG_CATEGORY)
        if log_pos == -1:
            return
        line = line[log_pos + len(LOG_CATEGORY) + 1 :]
        longer = None
        if line.startswith("PATCH:"):
            patch = line.split(":", 1)[1]
            text = _("Applying patch %s ...") % (patch,)
        elif line.startswith("BACKUP-START:"):
            text = _("Creating a database backup")
            longer = _("Creating a database backup in case anything goes wrong.")
        elif line.startswith("RESTORE-START:"):
            text = _("Restoring database backup")
            longer = _(
                "Stoq update failed.\n\n" "We will try to restore the current database.\n\n" "This may take some time."
            )
        elif line.startswith("RESTORE-DONE:"):
            msg = line.split(":", 1)[1]
            text = _("Database backup restored")
            longer = _(
                "Stoq database update failed but the database was restored.\n"
                "An automatic crash report was submitted. Please, "
                "enter in contact at <b>[email protected]</b> for "
                "assistance in recovering your database and making it "
                "possible to use Stoq %s again.\n\n"
                "A backup database was created as <b>%s</b>"
            ) % (stoq.version, msg)
        else:
            return
        self.progressbar.set_text(text)
        if not longer:
            longer = ""
        self.label.set_markup(longer)

    def _launch_stoqdbadmin(self):
        self.wizard.disable_next()
        if sys.argv[0].endswith(".egg"):
            args = [sys.executable, sys.argv[0]]
        elif platform.system() == "Windows":
            if library.uninstalled:
                args = ["stoq.bat"]
            else:
                # We should use stoq-cmd here, but the output is breaking
                # the process view
                args = ["stoq.exe"]
        else:
            args = ["stoq"]

        args.extend(["dbadmin", "updateschema", "-v"])
        args.extend(api.db_settings.get_command_line_arguments())
        self.process_view.execute_command(args)
        self.progressbar.set_text(_("Applying database patches..."))

    def _finish(self, returncode):
        self._finished = True
        if returncode:
            self.wizard.cancel_button.set_label(gtk.STOCK_QUIT)
            self.progressbar.set_fraction(0.0)
        else:
            # Migration may have changed some parameters, so clear the cache.
            api.sysparam.clear_cache()
            self.wizard.cancel_button.set_sensitive(True)
            self.progressbar.set_text(_("Done. Click 'Forward' to continue"))
            self.progressbar.set_fraction(1.0)
            self.wizard.enable_next()
            self.wizard.next_button.grab_focus()

    # Callbacks

    def _on_processview__readline(self, view, line):
        self._parse_process_line(line)

    def _on_processview__finished(self, view, returncode):
        self._finish(returncode)

    def _on_timeout_add(self):
        if self._finished:
            return False
        self.progressbar.pulse()
        return True
Exemple #6
0
class CreateDatabaseStep(BaseWizardStep):
    gladefile = 'CreateDatabaseStep'

    def post_init(self):
        self.n_patches = 0
        self.process_view = ProcessView()
        self.process_view.listen_stderr = True
        self.process_view.connect('read-line', self._on_processview__readline)
        self.process_view.connect('finished', self._on_processview__finished)
        self.expander.add(self.process_view)
        self.expander.grab_focus()
        self._maybe_create_database()

    def next_step(self):
        return LinkStep(self.wizard, self)

    def _maybe_create_database(self):
        logger.info(
            '_maybe_create_database (db_is_local=%s, enable_production=%s)' %
            (self.wizard.db_is_local, self.wizard.enable_production))
        if self.wizard.db_is_local:
            self._launch_stoqdbadmin()
            return
        elif self.wizard.enable_production:
            self._launch_stoqdbadmin()
            return

        self.wizard.write_pgpass()
        settings = self.wizard.settings
        self.wizard.config.load_settings(settings)

        store = settings.create_super_store()
        version = get_database_version(store)

        if version < (9, 1):
            store.close()
            error(
                _("Stoq requires PostgresSQL 9.1 or later, but %s found") %
                (".".join(map(str, version))))

        try:
            check_extensions(store=store)
        except ValueError:
            store.close()
            error(
                _("Missing PostgreSQL extension on the server, "
                  "please install postgresql-contrib on it"))

        store.close()
        self.process_view.feed("** Creating database\r\n")
        self._launch_stoqdbadmin()

    def _launch_stoqdbadmin(self):
        logger.info('_launch_stoqdbadmin')
        self.wizard.disable_back()
        self.wizard.disable_next()

        if sys.argv[0].endswith('.egg'):
            args = [sys.executable, sys.argv[0]]
        elif platform.system() == 'Windows':
            if library.uninstalled:
                args = ['stoq.bat']
            else:
                args = ['stoq-cmd.exe']
        else:
            args = ['stoq']

        args.extend([
            'dbadmin', 'init', '--no-load-config', '--no-register-station',
            '-v'
        ])

        if self.wizard.create_examples:
            args.append('--demo')
        elif self.wizard.enable_production:
            args.append('--force')

        if self.wizard.db_is_local:
            args.append('--create-dbuser')

        dbargs = self.wizard.settings.get_command_line_arguments()
        args.extend(dbargs)
        self.label.set_label(
            _("Creating a new database for Stoq, depending on the speed of "
              "your computer and the server it may take a couple of "
              "minutes to finish."))
        self.progressbar.set_text(_("Creating database..."))
        self.progressbar.set_fraction(0.05)
        logger.info(' '.join(args))
        self.process_view.execute_command(args)
        self.done_label.set_markup(
            _("Please wait while the database is being created."))

    def _parse_process_line(self, line):
        LOG_CATEGORY = 'stoqlib.database.create'
        log_pos = line.find(LOG_CATEGORY)
        if log_pos == -1:
            return
        line = line[log_pos + len(LOG_CATEGORY) + 1:]
        if line == 'SCHEMA':
            value = 0.1
            text = _("Creating base schema...")
        elif line.startswith('PATCHES:'):
            value = 0.35
            self.n_patches = int(line.split(':', 1)[1])
            text = _("Creating schema, applying patches...")
        elif line.startswith('PATCH:'):
            # 0.4 - 0.7 patches
            patch = float(line.split(':', 1)[1])
            value = 0.4 + (patch / self.n_patches) * 0.3
            text = _("Creating schema, applying patch %d ...") % (patch + 1, )
        elif line == 'INIT START':
            text = _("Creating additional database objects ...")
            value = 0.8
        elif line == 'INIT DONE' and self.wizard.create_examples:
            text = _("Creating examples ...")
            value = 0.85
        elif line.startswith('PLUGIN'):
            text = _("Activating plugins ...")
            if 'nfe' in self.wizard.plugins:
                text += ' ' + _('This may take some time.')
            value = 0.95
        else:
            return
        self.progressbar.set_fraction(value)
        self.progressbar.set_text(text)

    def _finish(self, returncode):
        logger.info('CreateDatabaseStep._finish (returncode=%s)' % returncode)
        if returncode:
            self.wizard.enable_back()
            # Failed to execute/create database
            if returncode == 30:
                # This probably happened because the user either;
                # - pressed cancel in the authentication popup
                # - user erred the password 3 times
                # Allow him to try again
                if yesno(
                        _("Something went wrong while trying to create "
                          "the database. Try again?"), Gtk.ResponseType.NO,
                        _("Change settings"), _("Try again")):
                    return
                self._launch_stoqdbadmin()
                return
            elif returncode == 31:
                # Missing postgresql-contrib package
                self.expander.set_expanded(True)
                warning(
                    _("Your database is missing the postgresql-contrib "
                      "package. Install it and try again"))
            else:
                # Unknown error, just inform user that something went wrong.
                self.expander.set_expanded(True)
                warning(
                    _("Something went wrong while trying to create "
                      "the Stoq database"))
            return
        self.label.set_text("")
        self.wizard.load_config_and_call_setup()
        create_default_profile_settings()
        self.progressbar.set_text(_("Done."))
        self.progressbar.set_fraction(1.0)
        self.wizard.enable_next()
        self.done_label.set_markup(
            _("Installation successful, click <b>Forward</b> to continue."))

    # Callbacks

    def _on_processview__readline(self, view, line):
        self._parse_process_line(line)

    def _on_processview__finished(self, view, returncode):
        self._finish(returncode)