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)
class ImporterDialog(BasicDialog): size = (400, 300) title = _("Importer Dialog") def __init__(self, format, filename): BasicDialog.__init__(self, size=self.size, title=self.title) self.format = format self.filename = filename self._build_ui() self._execute() def _build_ui(self): self.main_label.set_text(_("Importing %s...") % (self.filename, )) self.set_ok_label(_("Done")) self.progressbar = gtk.ProgressBar() self.vbox.pack_start(self.progressbar, False, False) self.progressbar.show() self.expander = gtk.Expander(label=_("Details...")) self.expander.set_expanded(False) self.vbox.pack_start(self.expander, True, True) self.expander.show() self.vbox.set_child_packing(self.main, False, False, 0, 0) self.process_view = ProcessView() self.process_view.listen_stdout = False 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.process_view.show() self.disable_ok() def _execute(self): args = ['stoqdbadmin', 'import', '-t', self.format, '--import-filename', self.filename, '-v'] args.extend(api.db_settings.get_command_line_arguments()) self.process_view.execute_command(args) def _parse_process_line(self, line): LOG_CATEGORY = 'stoqlib.importer.create' log_pos = line.find(LOG_CATEGORY) if log_pos == -1: return line = line[log_pos + len(LOG_CATEGORY) + 1:] if line.startswith('ITEMS:'): value = 0 self.n_items = int(line.split(':', 1)[1]) text = _("Importing ...") elif line.startswith('IMPORTED-ITEMS:'): value = 1 self.imported_items = int(line.split(':', 1)[1]) text = _("Imported %d items ...") % (self.imported_items, ) elif line.startswith('ITEM:'): item = float(line.split(':', 1)[1]) value = item / self.n_items text = _("Importing item %d ...") % (item + 1, ) else: return self.progressbar.set_fraction(value) self.progressbar.set_text(text) def _finish(self, returncode): if returncode: self.expander.set_expanded(True) warning(_("Something went wrong while trying to import")) return self.progressbar.set_text(_("Done, %d items imported, %d skipped") % ( self.imported_items, self.n_items - self.imported_items)) self.progressbar.set_fraction(1.0) self.enable_ok() def _on_processview__readline(self, view, line): self._parse_process_line(line) def _on_processview__finished(self, view, returncode): self._finish(returncode)
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: 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
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: 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
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)