class GuiRunner(QObject): '''Make sure an event loop is running before starting the main work of initialization''' def __init__(self, opts, args, actions, listener, app, gui_debug=None): self.startup_time = monotonic() self.timed_print('Starting up...') self.opts, self.args, self.listener, self.app = opts, args, listener, app self.gui_debug = gui_debug self.actions = actions self.main = None QObject.__init__(self) self.splash_screen = None self.timer = QTimer.singleShot(1, self.initialize) def timed_print(self, *a, **kw): if DEBUG: prints('[{:.2f}]'.format(monotonic() - self.startup_time), *a, **kw) def start_gui(self, db): from calibre.gui2.ui import Main self.timed_print('Constructing main UI...') main = self.main = Main(self.opts, gui_debug=self.gui_debug) if self.splash_screen is not None: self.splash_screen.show_message( _('Initializing user interface...')) try: with gprefs: # Only write gui.json after initialization is complete main.initialize(self.library_path, db, self.listener, self.actions) finally: self.timed_print('main UI initialized...') if self.splash_screen is not None: self.timed_print('Hiding splash screen') self.splash_screen.finish(main) self.timed_print('splash screen hidden') self.splash_screen = None self.timed_print( 'Started up in %.2f seconds' % (monotonic() - self.startup_time), 'with', len(db.data), 'books') main.set_exception_handler() if len(self.args) > 1: main.handle_cli_args(self.args[1:]) for event in self.app.file_event_hook.events: main.handle_cli_args(event) self.app.file_event_hook = main.handle_cli_args def choose_dir(self, initial_dir): self.hide_splash_screen() return choose_dir( self.splash_screen, 'choose calibre library', _('Choose a location for your new calibre e-book library'), default_dir=initial_dir) def show_error(self, title, msg, det_msg=''): self.hide_splash_screen() with self.app: error_dialog(self.splash_screen, title, msg, det_msg=det_msg, show=True) def initialization_failed(self): print('Catastrophic failure initializing GUI, bailing out...') QCoreApplication.exit(1) raise SystemExit(1) def initialize_db_stage2(self, db, tb): from calibre.db.legacy import LibraryDatabase if db is None and tb is not None: # DB Repair failed self.show_error( _('Repairing failed'), _('The database repair failed. Starting with a new empty library.' ), det_msg=tb) if db is None: candidate = self.choose_dir(get_default_library_path()) if not candidate: self.initialization_failed() try: self.library_path = candidate db = LibraryDatabase(candidate) except: self.show_error( _('Bad database location'), _('Bad database location %r. calibre will now quit.') % self.library_path, det_msg=traceback.format_exc()) self.initialization_failed() self.timed_print('db initialized') try: self.start_gui(db) except Exception: self.show_error( _('Startup error'), _('There was an error during {0} startup. Parts of {0} may not function.' ' Click Show details to learn more.').format(__appname__), det_msg=traceback.format_exc()) def initialize_db(self): from calibre.db.legacy import LibraryDatabase db = None self.timed_print('Initializing db...') try: db = LibraryDatabase(self.library_path) except apsw.Error: with self.app: self.hide_splash_screen() repair = question_dialog( self.splash_screen, _('Corrupted database'), _('The library database at %s appears to be corrupted. Do ' 'you want calibre to try and rebuild it automatically? ' 'The rebuild may not be completely successful. ' 'If you say No, a new empty calibre library will be created.' ) % force_unicode(self.library_path, filesystem_encoding), det_msg=traceback.format_exc()) if repair: if iswindows: # On some windows systems the existing db file gets locked # by something when running restore from the main process. # So run the restore in a separate process. windows_repair(self.library_path) self.app.quit() return if repair_library(self.library_path): db = LibraryDatabase(self.library_path) except: self.show_error(_('Bad database location'), _('Bad database location %r. Will start with ' ' a new, empty calibre library') % self.library_path, det_msg=traceback.format_exc()) self.initialize_db_stage2(db, None) def show_splash_screen(self): self.timed_print('Showing splash screen...') self.splash_screen = SplashScreen() self.splash_screen.show() self.splash_screen.show_message( _('Starting %s: Loading books...') % __appname__) self.timed_print('splash screen shown') def hide_splash_screen(self): if self.splash_screen is not None: self.splash_screen.hide() self.splash_screen = None def initialize(self, *args): if gprefs['show_splash_screen'] and not self.opts.start_in_tray: self.show_splash_screen() self.library_path = get_library_path(self) if not self.library_path: self.initialization_failed() self.initialize_db()
class GuiRunner(QObject): '''Make sure an event loop is running before starting the main work of initialization''' def __init__(self, opts, args, actions, listener, app, gui_debug=None): self.startup_time = monotonic() self.timed_print('Starting up...') self.opts, self.args, self.listener, self.app = opts, args, listener, app self.gui_debug = gui_debug self.actions = actions self.main = None QObject.__init__(self) self.splash_screen = None self.timer = QTimer.singleShot(1, self.initialize) def timed_print(self, *a, **kw): if DEBUG: prints('[{:.2f}]'.format(monotonic() - self.startup_time), *a, **kw) def start_gui(self, db): from calibre.gui2.ui import Main self.timed_print('Constructing main UI...') main = self.main = Main(self.opts, gui_debug=self.gui_debug) if self.splash_screen is not None: self.splash_screen.show_message(_('Initializing user interface...')) try: with gprefs: # Only write gui.json after initialization is complete main.initialize(self.library_path, db, self.listener, self.actions) finally: self.timed_print('main UI initialized...') if self.splash_screen is not None: self.timed_print('Hiding splash screen') self.splash_screen.finish(main) self.timed_print('splash screen hidden') self.splash_screen = None self.timed_print('Started up in %.2f seconds'%(monotonic() - self.startup_time), 'with', len(db.data), 'books') main.set_exception_handler() if len(self.args) > 1: main.handle_cli_args(self.args[1:]) for event in self.app.file_event_hook.events: main.handle_cli_args(event) self.app.file_event_hook = main.handle_cli_args def choose_dir(self, initial_dir): self.hide_splash_screen() return choose_dir(self.splash_screen, 'choose calibre library', _('Choose a location for your new calibre e-book library'), default_dir=initial_dir) def show_error(self, title, msg, det_msg=''): self.hide_splash_screen() with self.app: error_dialog(self.splash_screen, title, msg, det_msg=det_msg, show=True) def initialization_failed(self): print('Catastrophic failure initializing GUI, bailing out...') QCoreApplication.exit(1) raise SystemExit(1) def initialize_db_stage2(self, db, tb): from calibre.db.legacy import LibraryDatabase if db is None and tb is not None: # DB Repair failed self.show_error(_('Repairing failed'), _( 'The database repair failed. Starting with a new empty library.'), det_msg=tb) if db is None: candidate = self.choose_dir(get_default_library_path()) if not candidate: self.initialization_failed() try: self.library_path = candidate db = LibraryDatabase(candidate) except: self.show_error(_('Bad database location'), _( 'Bad database location %r. calibre will now quit.')%self.library_path, det_msg=traceback.format_exc()) self.initialization_failed() self.timed_print('db initialized') try: self.start_gui(db) except Exception: self.show_error(_('Startup error'), _( 'There was an error during {0} startup. Parts of {0} may not function.' ' Click Show details to learn more.').format(__appname__), det_msg=traceback.format_exc()) def initialize_db(self): from calibre.db.legacy import LibraryDatabase db = None self.timed_print('Initializing db...') try: db = LibraryDatabase(self.library_path) except apsw.Error: with self.app: self.hide_splash_screen() repair = question_dialog(self.splash_screen, _('Corrupted database'), _('The library database at %s appears to be corrupted. Do ' 'you want calibre to try and rebuild it automatically? ' 'The rebuild may not be completely successful. ' 'If you say No, a new empty calibre library will be created.') % force_unicode(self.library_path, filesystem_encoding), det_msg=traceback.format_exc() ) if repair: if iswindows: # On some windows systems the existing db file gets locked # by something when running restore from the main process. # So run the restore in a separate process. windows_repair(self.library_path) self.app.quit() return if repair_library(self.library_path): db = LibraryDatabase(self.library_path) except: self.show_error(_('Bad database location'), _('Bad database location %r. Will start with ' ' a new, empty calibre library')%self.library_path, det_msg=traceback.format_exc()) self.initialize_db_stage2(db, None) def show_splash_screen(self): self.timed_print('Showing splash screen...') self.splash_screen = SplashScreen() self.splash_screen.show() self.splash_screen.show_message(_('Starting %s: Loading books...') % __appname__) self.timed_print('splash screen shown') def hide_splash_screen(self): if self.splash_screen is not None: self.splash_screen.hide() self.splash_screen = None def initialize(self, *args): if gprefs['show_splash_screen'] and not self.opts.start_in_tray: self.show_splash_screen() self.library_path = get_library_path(self) if not self.library_path: self.initialization_failed() self.initialize_db()
class GuiRunner(QObject): '''Make sure an event loop is running before starting the main work of initialization''' def __init__(self, opts, args, actions, listener, app, gui_debug=None): self.startup_time = time.time() self.opts, self.args, self.listener, self.app = opts, args, listener, app self.gui_debug = gui_debug self.actions = actions self.main = None QObject.__init__(self) self.splash_screen = None self.timer = QTimer.singleShot(1, self.initialize) if DEBUG: prints('Starting up...') def start_gui(self, db): from calibre.gui2.ui import Main main = self.main = Main(self.opts, gui_debug=self.gui_debug) if self.splash_screen is not None: self.splash_screen.show_message( _('Initializing user interface...')) try: with gprefs: # Only write gui.json after initialization is complete main.initialize(self.library_path, db, self.listener, self.actions) finally: if self.splash_screen is not None: self.splash_screen.finish(main) self.splash_screen = None if DEBUG: prints( 'Started up in %.2f seconds' % (time.time() - self.startup_time), 'with', len(db.data), 'books') add_filesystem_book = partial( main.iactions['Add Books'].add_filesystem_book, allow_device=False) main.set_exception_handler() if len(self.args) > 1: files = [ os.path.abspath(p) for p in self.args[1:] if not os.path.isdir(p) ] if len(files) < len(sys.argv[1:]): prints('Ignoring directories passed as command line arguments') if files: add_filesystem_book(files) for event in self.app.file_event_hook.events: add_filesystem_book(event) self.app.file_event_hook = add_filesystem_book def choose_dir(self, initial_dir): self.hide_splash_screen() return choose_dir( self.splash_screen, 'choose calibre library', _('Choose a location for your new calibre e-book library'), default_dir=initial_dir) def show_error(self, title, msg, det_msg=''): self.hide_splash_screen() with self.app: error_dialog(self.splash_screen, title, msg, det_msg=det_msg, show=True) def initialization_failed(self): print 'Catastrophic failure initializing GUI, bailing out...' QCoreApplication.exit(1) raise SystemExit(1) def initialize_db_stage2(self, db, tb): from calibre.db.legacy import LibraryDatabase if db is None and tb is not None: # DB Repair failed self.show_error( _('Repairing failed'), _('The database repair failed. Starting with a new empty library.' ), det_msg=tb) if db is None: candidate = self.choose_dir(get_default_library_path()) if not candidate: self.initialization_failed() try: self.library_path = candidate db = LibraryDatabase(candidate) except: self.show_error( _('Bad database location'), _('Bad database location %r. calibre will now quit.') % self.library_path, det_msg=traceback.format_exc()) self.initialization_failed() try: self.start_gui(db) except Exception: self.show_error( _('Startup error'), _('There was an error during {0} startup. Parts of {0} may not function.' ' Click Show details to learn more.').format(__appname__), det_msg=traceback.format_exc()) def initialize_db(self): from calibre.db.legacy import LibraryDatabase db = None try: db = LibraryDatabase(self.library_path) except apsw.Error: with self.app: self.hide_splash_screen() repair = question_dialog( self.splash_screen, _('Corrupted database'), _('The library database at %s appears to be corrupted. Do ' 'you want calibre to try and rebuild it automatically? ' 'The rebuild may not be completely successful. ' 'If you say No, a new empty calibre library will be created.' ) % force_unicode(self.library_path, filesystem_encoding), det_msg=traceback.format_exc()) if repair: if repair_library(self.library_path): db = LibraryDatabase(self.library_path) except: self.show_error(_('Bad database location'), _('Bad database location %r. Will start with ' ' a new, empty calibre library') % self.library_path, det_msg=traceback.format_exc()) self.initialize_db_stage2(db, None) def show_splash_screen(self): self.splash_screen = SplashScreen() self.splash_screen.show() self.splash_screen.show_message( _('Starting %s: Loading books...') % __appname__) def hide_splash_screen(self): if self.splash_screen is not None: self.splash_screen.hide() self.splash_screen = None def initialize(self, *args): if gprefs['show_splash_screen'] and not self.opts.start_in_tray: self.show_splash_screen() self.library_path = get_library_path(self) if not self.library_path: self.initialization_failed() self.initialize_db()