def get_library_path(parent=None): library_path = prefs['library_path'] if library_path is None: # Need to migrate to new database layout base = os.path.expanduser('~') if iswindows: base = winutil.special_folder_path(winutil.CSIDL_PERSONAL) if not base or not os.path.exists(base): from PyQt4.Qt import QDir base = unicode(QDir.homePath()).replace('/', os.sep) candidate = choose_dir(None, 'choose calibre library', _('Choose a location for your calibre e-book library'), default_dir=base) if not candidate: candidate = os.path.join(base, 'Calibre Library') library_path = os.path.abspath(candidate) if not os.path.exists(library_path): try: os.makedirs(library_path) except: error_dialog(parent, _('Failed to create library'), _('Failed to create calibre library at: %r.')%library_path, det_msg=traceback.format_exc(), show=True) library_path = choose_dir(parent, 'choose calibre library', _('Choose a location for your new calibre e-book library'), default_dir=get_default_library_path()) return library_path
def choose_loc(self, *args): base = get_portable_base() if base is None: loc = choose_dir(self, "choose library location", _("Choose location for calibre library")) else: name = force_unicode("choose library loc at" + base, filesystem_encoding) loc = choose_dir(self, name, _("Choose location for calibre library"), default_dir=base, no_save_dir=True) if loc is not None: self.location.setText(loc)
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 error_dialog(self.splash_screen, _('Repairing failed'), _('The database repair failed. Starting with ' 'a new empty library.'), det_msg=tb, show=True) if db is None: candidate = choose_dir(self.splash_screen, 'choose calibre library', _('Choose a location for your new calibre e-book library'), default_dir=get_default_library_path()) if not candidate: self.initialization_failed() try: self.library_path = candidate db = LibraryDatabase(candidate) except: error_dialog(self.splash_screen, _('Bad database location'), _('Bad database location %r. calibre will now quit.' )%self.library_path, det_msg=traceback.format_exc(), show=True) self.initialization_failed() try: self.start_gui(db) except Exception: error_dialog(self.main, _('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(), show=True)
def save_pdf(self, pdf_file, pdf_base_file): ''' Save the PDF file in the final location :param pdf_file: The path to the PDF file :param pdf_base_file: The desired file name and relative path ''' from os import rename, makedirs from os.path import basename, dirname, join, exists from calibre.constants import DEBUG from calibre.gui2 import choose_dir from calibre.gui2.dialogs.message_box import MessageBox from calibre.gui2 import error_dialog path = choose_dir(self.gui, 'save to disk dialog', _('Choose destination directory')) if not path: return save_file = join(path, pdf_base_file) base_dir = dirname(save_file) try: makedirs(base_dir) except BaseException: if not exists(base_dir): raise try: rename(pdf_file, save_file) except: error_dialog(self.gui, _('Could not save PDF'), _("Error writing the PDF file:\n%s" % save_file), show=True) return if DEBUG: print(save_file) MessageBox(MessageBox.INFO, _('File saved'), _("PDF file saved in:\n%s") % save_file).exec_()
def getDirectory(self): c = choose_dir(self, _(PLUGIN_NAME + 'dir_chooser'), _('Select Default Directory To Unpack Kindle Book/Mobi To')) if c: self.directory_txtBox.setReadOnly(False) self.directory_txtBox.setText(c) self.directory_txtBox.setReadOnly(True)
def export_selected(self): names = self.selected_names if not names: return path = choose_dir(self, 'tweak_book_export_selected', _('Choose location')) if path: self.export_requested.emit(names, path)
def catalog_generated(self, job): if job.result: # Problems during catalog generation # jobs.results is a list - the first entry is the intended title for the dialog # Subsequent strings are error messages dialog_title = job.result.pop(0) if re.match('warning:', job.result[0].lower()): msg = _("Catalog generation complete, with warnings.") warning_dialog(self.gui, dialog_title, msg, det_msg='\n'.join(job.result), show=True) else: job.result.append("Catalog generation terminated.") error_dialog(self.gui, dialog_title,'\n'.join(job.result),show=True) return if job.failed: return self.gui.job_exception(job) id = self.gui.library_view.model().add_catalog(job.catalog_file_path, job.catalog_title) self.gui.library_view.model().reset() if job.catalog_sync: sync = dynamic.get('catalogs_to_be_synced', set([])) sync.add(id) dynamic.set('catalogs_to_be_synced', sync) self.gui.status_bar.show_message(_('Catalog generated.'), 3000) self.gui.sync_catalogs() if job.fmt not in ['EPUB','MOBI']: export_dir = choose_dir(self.gui, _('Export Catalog Directory'), _('Select destination for %(title)s.%(fmt)s') % dict( title=job.catalog_title, fmt=job.fmt.lower())) if export_dir: destination = os.path.join(export_dir, '%s.%s' % ( sanitize_file_name_unicode(job.catalog_title), job.fmt.lower())) shutil.copyfile(job.catalog_file_path, destination)
def initialize_db_stage2(self, db, tb): if db is None and tb is not None: # DB Repair failed error_dialog(self.splash_screen, _('Repairing failed'), _('The database repair failed. Starting with ' 'a new empty library.'), det_msg=tb, show=True) if db is None: candidate = choose_dir(self.splash_screen, 'choose calibre library', _('Choose a location for your new calibre e-book library'), default_dir=get_default_library_path()) if not candidate: self.initialization_failed() try: self.library_path = candidate db = self.db_class(candidate) except: error_dialog(self.splash_screen, _('Bad database location'), _('Bad database location %r. calibre will now quit.' )%self.library_path, det_msg=traceback.format_exc(), show=True) self.initialization_failed() self.start_gui(db)
def choose_root_folder(self, *args): x = self.get_root_folder() if x is None: x = '~' x = choose_dir(self, 'add wizard choose root folder', _('Choose root folder'), default_dir=x) if x is not None: self.opt_root_folder.setText(os.path.abspath(x))
def choose_dir(self, initial_dir): self.hide_splash_screen() return choose_dir( None, "choose calibre library", _("Choose a location for your new calibre e-book library"), default_dir=initial_dir, )
def directoryChooser(self): ''' Select a folder, or use the one specified in the config widget. ''' if cfg.plugin_prefs['Always_Use_Unpack_Folder']: return cfg.plugin_prefs['Unpack_Folder'] else: return choose_dir(self.gui, _(PLUGIN_NAME + 'dir_chooser'), _('Select Directory To Unpack Kindle/Mobi Book To'))
def add_recursive(self, single): root = choose_dir(self.gui, 'recursive book import root dir dialog', _('Select root folder')) if not root: return lp = os.path.normcase(os.path.abspath(self.gui.current_db.library_path)) if lp.startswith(os.path.normcase(os.path.abspath(root)) + os.pathsep): return error_dialog(self.gui, _('Cannot add'), _( 'Cannot add books from the folder: %s as it contains the currently opened calibre library') % root, show=True) self.do_add_recursive(root, single)
def validate_export(self): path = choose_dir(self, 'export-calibre-dir', _('Choose a directory to export to')) if not path: return False if os.listdir(path): error_dialog(self, _('Export dir not empty'), _( 'The directory you choose to export the data to must be empty.'), show=True) return False self.export_dir = path return True
def add_recursive(self, single): root = choose_dir(self.gui, 'recursive book import root dir dialog', 'Select root folder') if not root: return from calibre.gui2.add import Adder self._adder = Adder(self.gui, self.gui.library_view.model().db, self.Dispatcher(self._files_added), spare_server=self.gui.spare_server) self.gui.tags_view.disable_recounting = True self._adder.add_recursive(root, single)
def select_import_folder(self): path = choose_dir(self, 'choose-export-folder-for-import', _('Select folder with exported data')) if path is None: return try: self.importer = Importer(path) except Exception as e: import traceback return error_dialog(self, _('Not valid'), _( 'The folder {0} is not valid: {1}').format(path, as_unicode(e)), det_msg=traceback.format_exc(), show=True) self.setup_select_libraries_panel() self.import_panel.stack.setCurrentIndex(1)
def add_recursive(self, single): root = choose_dir(self.gui, 'recursive book import root dir dialog', _('Select root folder')) if not root: return lp = os.path.normcase(os.path.abspath( self.gui.current_db.library_path)) if lp.startswith(os.path.normcase(os.path.abspath(root)) + os.pathsep): return error_dialog( self.gui, _('Cannot add'), _('Cannot add books from the folder: %s as it contains the currently opened calibre library' ) % root, show=True) self.do_add_recursive(root, single)
def validate_export(self): path = choose_dir(self, 'export-calibre-dir', _('Choose a folder to export to')) if not path: return False if os.listdir(path): error_dialog( self, _('Export folder not empty'), _('The folder you choose to export the data to must be empty.' ), show=True) return False self.export_dir = path return True
def save_to_disk(self, checked, single_dir=False, single_format=None, rows=None, write_opf=None, save_cover=None): if rows is None: rows = self.gui.current_view().selectionModel().selectedRows() if not rows or len(rows) == 0: return error_dialog(self.gui, _('Cannot save to disk'), _('No books selected'), show=True) path = choose_dir(self.gui, 'save to disk dialog', _('Choose destination directory')) if not path: return dpath = os.path.abspath(path).replace('/', os.sep)+os.sep lpath = self.gui.library_view.model().db.library_path.replace('/', os.sep)+os.sep if dpath.startswith(lpath): return error_dialog(self.gui, _('Not allowed'), _('You are trying to save files into the calibre ' 'library. This can cause corruption of your ' 'library. Save to disk is meant to export ' 'files from your calibre library elsewhere.'), show=True) if self.gui.current_view() is self.gui.library_view: from calibre.gui2.add import Saver from calibre.library.save_to_disk import config opts = config().parse() if single_format is not None: opts.formats = single_format # Special case for Kindle annotation files if single_format.lower() in ['mbp','pdr','tan']: opts.to_lowercase = False opts.save_cover = False opts.write_opf = False opts.template = opts.send_template opts.single_dir = single_dir if write_opf is not None: opts.write_opf = write_opf if save_cover is not None: opts.save_cover = save_cover self._saver = Saver(self.gui, self.gui.library_view.model().db, Dispatcher(self._books_saved), rows, path, opts, spare_server=self.gui.spare_server) else: paths = self.gui.current_view().model().paths(rows) self.gui.device_manager.save_books( Dispatcher(self.books_saved), paths, path)
def select_import_folder(self): path = choose_dir(self, 'choose-export-folder-for-import', _('Select folder with exported data')) if path is None: return try: self.importer = Importer(path) except Exception as e: import traceback return error_dialog(self, _('Not valid'), _('The folder {0} is not valid: {1}').format( path, as_unicode(e)), det_msg=traceback.format_exc(), show=True) self.setup_select_libraries_panel() self.import_panel.stack.setCurrentIndex(1)
def create_theme(folder=None, parent=None): if folder is None: folder = choose_dir(parent, 'create-icon-theme-folder', _( 'Choose a folder from which to read the icons')) if not folder: return report = read_theme_from_folder(folder) d = ThemeCreateDialog(parent, report) if d.exec_() != d.Accepted: return d.save_metadata() raw = create_themeball(d.report) dest = choose_save_file(parent, 'create-icon-theme-dest', _( 'Choose destination for icon theme'), [(_('ZIP files'), ['zip'])], initial_filename='my-calibre-icon-theme.zip') if dest: with open(dest, 'wb') as f: f.write(raw)
def create_theme(folder=None, parent=None): if folder is None: folder = choose_dir(parent, 'create-icon-theme-folder', _( 'Choose a folder from which to read the icons')) if not folder: return report = read_theme_from_folder(folder) d = ThemeCreateDialog(parent, report) if d.exec_() != d.Accepted: return d.save_metadata() raw, prefix = create_themeball(d.report) dest = choose_save_file(parent, 'create-icon-theme-dest', _( 'Choose destination for icon theme'), [(_('ZIP files'), ['zip'])], initial_filename=prefix + '.zip') if dest: with open(dest, 'wb') as f: f.write(raw)
def select_import_folder(self): path = choose_dir(self, 'choose-export-folder-for-import', _('Select folder with exported data')) if path is None: return if not question_dialog(self, _('Are you sure?'), _( 'Importing calibre data means all libraries, settings, plugins, etc will be imported. This is' ' a security risk, only proceed if the data you are importing was previously generated by you, using the calibre' ' export functionality.' )): return try: self.importer = Importer(path) except Exception as e: import traceback return error_dialog(self, _('Not valid'), _( 'The folder {0} is not valid: {1}').format(path, as_unicode(e)), det_msg=traceback.format_exc(), show=True) self.setup_select_libraries_panel() self.import_panel.stack.setCurrentIndex(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 error_dialog(self.splash_screen, _('Repairing failed'), _('The database repair failed. Starting with ' 'a new empty library.'), det_msg=tb, show=True) if db is None: candidate = choose_dir( self.splash_screen, 'choose calibre library', _('Choose a location for your new calibre e-book library'), default_dir=get_default_library_path()) if not candidate: self.initialization_failed() try: self.library_path = candidate db = LibraryDatabase(candidate) except: error_dialog( self.splash_screen, _('Bad database location'), _('Bad database location %r. calibre will now quit.') % self.library_path, det_msg=traceback.format_exc(), show=True) self.initialization_failed() try: self.start_gui(db) except Exception: error_dialog( self.main, _('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(), show=True)
def save_to_disk(self, checked, single_dir=False, single_format=None, rows=None, write_opf=None, save_cover=None): if rows is None: rows = self.gui.current_view().selectionModel().selectedRows() if not rows or len(rows) == 0: return error_dialog(self.gui, _('Cannot save to disk'), _('No books selected'), show=True) path = choose_dir(self.gui, 'save to disk dialog', _('Choose destination directory')) if not path: return dpath = os.path.abspath(path).replace('/', os.sep)+os.sep lpath = self.gui.library_view.model().db.library_path.replace('/', os.sep)+os.sep if dpath.startswith(lpath): return error_dialog(self.gui, _('Not allowed'), _('You are trying to save files into the calibre ' 'library. This can cause corruption of your ' 'library. Save to disk is meant to export ' 'files from your calibre library elsewhere.'), show=True) if self.gui.current_view() is self.gui.library_view: from calibre.gui2.save import Saver from calibre.library.save_to_disk import config opts = config().parse() if single_format is not None: opts.formats = single_format # Special case for Kindle annotation files if single_format.lower() in ['mbp','pdr','tan']: opts.to_lowercase = False opts.save_cover = False opts.write_opf = False opts.template = opts.send_template opts.single_dir = single_dir if write_opf is not None: opts.write_opf = write_opf if save_cover is not None: opts.save_cover = save_cover book_ids = set(map(self.gui.library_view.model().id, rows)) Saver(book_ids, self.gui.current_db, opts, path, parent=self.gui, pool=self.gui.spare_pool()) else: paths = self.gui.current_view().model().paths(rows) self.gui.device_manager.save_books( Dispatcher(self.books_saved), paths, path)
def catalog_generated(self, job): if job.result: # Problems during catalog generation # jobs.results is a list - the first entry is the intended title for the dialog # Subsequent strings are error messages dialog_title = job.result.pop(0) if re.search('warning', job.result[0].lower()): msg = _("Catalog generation complete, with warnings.") warning_dialog(self.gui, dialog_title, msg, det_msg='\n'.join(job.result), show=True) else: job.result.append("Catalog generation terminated.") error_dialog(self.gui, dialog_title,'\n'.join(job.result),show=True) return if job.failed: return self.gui.job_exception(job) if dynamic.get('catalog_add_to_library', True): id = self.gui.library_view.model().add_catalog(job.catalog_file_path, job.catalog_title) self.gui.library_view.model().beginResetModel(), self.gui.library_view.model().endResetModel() if job.catalog_sync: sync = dynamic.get('catalogs_to_be_synced', set([])) sync.add(id) dynamic.set('catalogs_to_be_synced', sync) self.gui.status_bar.show_message(_('Catalog generated.'), 3000) self.gui.sync_catalogs() if not dynamic.get('catalog_add_to_library', True) or job.fmt not in {'EPUB','MOBI', 'AZW3'}: export_dir = choose_dir(self.gui, _('Export Catalog Directory'), _('Select destination for %(title)s.%(fmt)s') % dict( title=job.catalog_title, fmt=job.fmt.lower())) if export_dir: destination = os.path.join(export_dir, '%s.%s' % ( sanitize_file_name(job.catalog_title), job.fmt.lower())) try: shutil.copyfile(job.catalog_file_path, destination) except EnvironmentError as err: if getattr(err, 'errno', None) == errno.EACCES: # Permission denied import traceback error_dialog(self.gui, _('Permission denied'), _('Could not open %s. Is it being used by another' ' program?')%destination, det_msg=traceback.format_exc(), show=True) return raise
def catalog_generated(self, job): if job.result: # Problems during catalog generation # jobs.results is a list - the first entry is the intended title for the dialog # Subsequent strings are error messages dialog_title = job.result.pop(0) if re.search('warning', job.result[0].lower()): msg = _("Catalog generation complete, with warnings.") warning_dialog(self.gui, dialog_title, msg, det_msg='\n'.join(job.result), show=True) else: job.result.append("Catalog generation terminated.") error_dialog(self.gui, dialog_title,'\n'.join(job.result),show=True) return if job.failed: return self.gui.job_exception(job) if dynamic.get('catalog_add_to_library', True): id = self.gui.library_view.model().add_catalog(job.catalog_file_path, job.catalog_title) self.gui.library_view.model().beginResetModel(), self.gui.library_view.model().endResetModel() if job.catalog_sync: sync = dynamic.get('catalogs_to_be_synced', set()) sync.add(id) dynamic.set('catalogs_to_be_synced', sync) self.gui.status_bar.show_message(_('Catalog generated.'), 3000) self.gui.sync_catalogs() if not dynamic.get('catalog_add_to_library', True) or job.fmt not in {'EPUB','MOBI', 'AZW3'}: export_dir = choose_dir(self.gui, _('Export Catalog Directory'), _('Select destination for %(title)s.%(fmt)s') % dict( title=job.catalog_title, fmt=job.fmt.lower())) if export_dir: destination = os.path.join(export_dir, '%s.%s' % ( sanitize_file_name(job.catalog_title), job.fmt.lower())) try: shutil.copyfile(job.catalog_file_path, destination) except EnvironmentError as err: if getattr(err, 'errno', None) == errno.EACCES: # Permission denied import traceback error_dialog(self.gui, _('Permission denied'), _('Could not open %s. Is it being used by another' ' program?')%destination, det_msg=traceback.format_exc(), show=True) return raise
def catalog_generated(self, job): if job.result: # Problems during catalog generation # jobs.results is a list - the first entry is the intended title for the dialog # Subsequent strings are error messages dialog_title = job.result.pop(0) if re.match('warning:', job.result[0].lower()): msg = _("Catalog generation complete, with warnings.") warning_dialog(self.gui, dialog_title, msg, det_msg='\n'.join(job.result), show=True) else: job.result.append("Catalog generation terminated.") error_dialog(self.gui, dialog_title, '\n'.join(job.result), show=True) return if job.failed: return self.gui.job_exception(job) id = self.gui.library_view.model().add_catalog(job.catalog_file_path, job.catalog_title) self.gui.library_view.model().reset() if job.catalog_sync: sync = dynamic.get('catalogs_to_be_synced', set([])) sync.add(id) dynamic.set('catalogs_to_be_synced', sync) self.gui.status_bar.show_message(_('Catalog generated.'), 3000) self.gui.sync_catalogs() if job.fmt not in ['EPUB', 'MOBI']: export_dir = choose_dir( self.gui, _('Export Catalog Directory'), _('Select destination for %(title)s.%(fmt)s') % dict(title=job.catalog_title, fmt=job.fmt.lower())) if export_dir: destination = os.path.join( export_dir, '%s.%s' % (sanitize_file_name_unicode( job.catalog_title), job.fmt.lower())) shutil.copyfile(job.catalog_file_path, destination)
def change(self): from calibre.db.legacy import LibraryDatabase x = choose_dir(self, 'database location dialog', _('Select location for books')) if x: if (iswindows and len(x) > LibraryDatabase.WINDOWS_LIBRARY_PATH_LIMIT): return error_dialog(self, _('Too long'), _('Path to library too long. Must be less than' ' %d characters.')%(LibraryDatabase.WINDOWS_LIBRARY_PATH_LIMIT), show=True) if not os.path.exists(x): try: os.makedirs(x) except: return error_dialog(self, _('Bad location'), _('Failed to create a folder at %s')%x, det_msg=traceback.format_exc(), show=True) if self.is_library_dir_suitable(x): self.location.setText(x) else: self.show_library_dir_error(x)
def create_theme(folder=None, parent=None): if folder is None: folder = choose_dir(parent, 'create-icon-theme-folder', _( 'Choose a folder from which to read the icons')) if not folder: return report = read_theme_from_folder(folder) d = ThemeCreateDialog(parent, report) if d.exec_() != d.Accepted: return d.save_metadata() d = Compress(d.report, parent=parent) d.exec_() if d.wasCanceled() or d.raw is None: return raw, prefix = d.raw, d.prefix dest = choose_save_file(parent, 'create-icon-theme-dest', _( 'Choose destination for icon theme'), [(_('ZIP files'), ['zip'])], initial_filename=prefix + '.zip') if dest: with lopen(dest, 'wb') as f: f.write(raw)
def choose_aa_path(self): path = choose_dir(self, 'auto add path choose', _('Choose a folder')) if path: self.opt_auto_add_path.setText(path)
def set_debug_dir(self): x = choose_dir(self, 'conversion debug dir', _('Choose debug folder')) if x: self.opt_debug_pipeline.setText(x)
def browse(self): d = choose_dir(self, "choose_library_for_copy", _("Choose Library")) if d: self.le.setText(d)
def choose_dir(self, initial_dir): self.hide_splash_screen() return choose_dir(None, 'choose calibre library', _('Choose a location for your new calibre e-book library'), default_dir=initial_dir)
def browse(self): d = choose_dir(self, 'choose_library_for_copy', _('Choose Library')) if d: self.le.setText(d)
def choose_loc(self, *args): loc = choose_dir(self, 'choose library location', _('Choose location for calibre library')) if loc is not None: self.location.setText(loc)
def choose_dir(self): d = choose_dir(self, 'library moved choose new loc', _('New library location'), default_dir=self.oldloc) if d is not None: self.loc.setText(d)
def add_recursive(self, single): root = choose_dir(self.gui, 'recursive book import root dir dialog', _('Select root folder')) if not root: return self.do_add_recursive(root, single)
def select_folder(self): path = choose_dir(self, 'select-folder-for-imported-library', _('Choose a folder for this library')) if path is not None: self.le.setText(path)
def _get_dest_directory_name(self): path = choose_dir(self, 'backup annotations destination dialog','Choose destination directory') if path: self.dest_directory_edit.setText(path)
def choose_aa_path(self): path = choose_dir(self, "auto add path choose", _("Choose a folder")) if path: self.opt_auto_add_path.setText(path)
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)