From 87c34c73cca2ab014993446b3b88160ad319ece0 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 21 Feb 2008 04:23:10 +0000 Subject: [PATCH] Implement Bulk conversion of ebooks --- src/libprs500/ebooks/lrf/__init__.py | 15 ++++++ src/libprs500/gui2/dialogs/lrf_single.py | 42 ++++++++++++---- src/libprs500/gui2/main.py | 63 +++++++++++++++++++++--- 3 files changed, 103 insertions(+), 17 deletions(-) diff --git a/src/libprs500/ebooks/lrf/__init__.py b/src/libprs500/ebooks/lrf/__init__.py index 77fbd0ed33..fc136d3751 100644 --- a/src/libprs500/ebooks/lrf/__init__.py +++ b/src/libprs500/ebooks/lrf/__init__.py @@ -33,6 +33,21 @@ from libprs500 import __appname__, __version__, __author__, iswindows, OptionPar __docformat__ = "epytext" +preferred_source_formats = [ + 'LIT', + 'MOBI', + 'HTML', + 'HTM', + 'XHTM', + 'XHTML', + 'PRC', + 'RTF', + 'PDF', + 'TXT', + 'ZIP', + 'RAR' + ] + class LRFParseError(Exception): pass diff --git a/src/libprs500/gui2/dialogs/lrf_single.py b/src/libprs500/gui2/dialogs/lrf_single.py index c044f4e079..755f95d7d2 100644 --- a/src/libprs500/gui2/dialogs/lrf_single.py +++ b/src/libprs500/gui2/dialogs/lrf_single.py @@ -47,6 +47,18 @@ class LRFSingleDialog(QDialog, Ui_LRFSingleDialog): src = opt.get_opt_string() return 'gui_' + src[2:].replace('-', '_') + def initialize_common(self): + self.output_format = 'LRF' + self.setup_tooltips() + self.initialize_options() + global font_family_model + if font_family_model is None: + font_family_model = FontFamilyModel() + self.font_family_model = font_family_model + self.gui_serif_family.setModel(self.font_family_model) + self.gui_sans_family.setModel(self.font_family_model) + self.gui_mono_family.setModel(self.font_family_model) + def __init__(self, window, db, row): QDialog.__init__(self, window) Ui_LRFSingleDialog.__init__(self) @@ -57,22 +69,13 @@ class LRFSingleDialog(QDialog, Ui_LRFSingleDialog): QObject.connect(self.cover_button, SIGNAL("clicked(bool)"), self.select_cover) self.categoryList.leaveEvent = self.reset_help self.reset_help() - self.output_format = 'LRF' self.selected_format = None - self.setup_tooltips() - self.initialize_options() + self.initialize_common() self.db = db self.row = row self.cover_changed = False self.cpixmap = None self.changed = False - global font_family_model - if font_family_model is None: - font_family_model = FontFamilyModel() - self.font_family_model = font_family_model - self.gui_serif_family.setModel(self.font_family_model) - self.gui_sans_family.setModel(self.font_family_model) - self.gui_mono_family.setModel(self.font_family_model) self.load_saved_global_defaults() @@ -379,4 +382,23 @@ class LRFSingleDialog(QDialog, Ui_LRFSingleDialog): else: QSettings().setValue('LRF conversion defaults', QVariant(QByteArray(cPickle.dumps(cmdline)))) QDialog.accept(self) + +class LRFBulkDialog(LRFSingleDialog): + + def __init__(self, window): + QDialog.__init__(self, window) + Ui_LRFSingleDialog.__init__(self) + self.setupUi(self) + + self.categoryList.takeItem(0) + self.stack.removeWidget(self.stack.widget(0)) + self.categoryList.setCurrentRow(0) + + self.initialize_common() + self.setWindowTitle(_('Bulk convert ebooks to LRF')) + + def accept(self): + self.cmdline = self.cmdline = [unicode(i) for i in self.build_commandline()] + self.cover_file = None + QDialog.accept(self) \ No newline at end of file diff --git a/src/libprs500/gui2/main.py b/src/libprs500/gui2/main.py index e01e4c0137..4a924cd808 100644 --- a/src/libprs500/gui2/main.py +++ b/src/libprs500/gui2/main.py @@ -42,7 +42,7 @@ from libprs500.gui2.dialogs.metadata_single import MetadataSingleDialog from libprs500.gui2.dialogs.metadata_bulk import MetadataBulkDialog from libprs500.gui2.dialogs.jobs import JobsDialog from libprs500.gui2.dialogs.conversion_error import ConversionErrorDialog -from libprs500.gui2.dialogs.lrf_single import LRFSingleDialog +from libprs500.gui2.dialogs.lrf_single import LRFSingleDialog, LRFBulkDialog from libprs500.gui2.dialogs.config import ConfigDialog from libprs500.gui2.dialogs.search import SearchDialog from libprs500.gui2.dialogs.user_profiles import UserProfiles @@ -52,6 +52,7 @@ from libprs500.library.database import DatabaseLocked from libprs500.ebooks.metadata.meta import set_metadata from libprs500.ebooks.metadata import MetaInformation from libprs500.ebooks import BOOK_EXTENSIONS +from libprs500.ebooks.lrf import preferred_source_formats as LRF_PREFERRED_SOURCE_FORMATS @@ -586,9 +587,61 @@ class Main(MainWindow, Ui_MainWindow): ############################################################################ ############################### Convert #################################### + def convert_bulk(self, checked): - d = error_dialog(self, _('Cannot convert'), _('Not yet implemented.')) + rows = self.library_view.selectionModel().selectedRows() + if not rows or len(rows) == 0: + d = error_dialog(self, _('Cannot convert'), _('No books selected')) + d.exec_() + return + d = LRFBulkDialog(self) d.exec_() + if d.result() != QDialog.Accepted: + return + bad_rows = [] + + self.status_bar.showMessage('Starting Bulk conversion of %d books'%len(rows), 2000) + + for i, row in enumerate([r.row() for r in rows]): + cmdline = list(d.cmdline) + data = None + for fmt in LRF_PREFERRED_SOURCE_FORMATS: + try: + data = self.library_view.model().db.format(row, fmt.upper()) + break + except: + continue + if data is None: + bad_rows.append(row) + continue + pt = PersistentTemporaryFile('.'+fmt.lower()) + pt.write(data) + pt.close() + of = PersistentTemporaryFile('.lrf') + of.close() + cmdline.extend(['-o', of.name]) + cmdline.append(pt.name) + id = self.job_manager.run_conversion_job(self.book_converted, + 'any2lrf', args=[cmdline], + job_description='Convert book %d of %d'%(i, len(rows))) + + + self.conversion_jobs[id] = (d.cover_file, pt, of, d.output_format, + self.library_view.model().db.id(row)) + + + res = [] + for row in bad_rows: + title = self.library_view.model().db.title(row) + res.append('
  • %s
  • '%title) + if res: + msg = '

    Could not convert %d of %d books, because no suitable source format was found.

    '%(len(res), len(rows), '\n'.join(res)) + warning_dialog(self, 'Could not convert some books', msg).exec_() + + + + + def set_conversion_defaults(self, checked): d = LRFSingleDialog(self, None, None) @@ -600,13 +653,11 @@ class Main(MainWindow, Ui_MainWindow): d = error_dialog(self, _('Cannot convert'), _('No books selected')) d.exec_() - changed = False for row in [r.row() for r in rows]: d = LRFSingleDialog(self, self.library_view.model().db, row) if d.selected_format: d.exec_() if d.result() == QDialog.Accepted: - changed = True cmdline = d.cmdline data = self.library_view.model().db.format(row, d.selected_format) pt = PersistentTemporaryFile('.'+d.selected_format.lower()) @@ -622,9 +673,7 @@ class Main(MainWindow, Ui_MainWindow): self.conversion_jobs[id] = (d.cover_file, pt, of, d.output_format, d.id) - if changed: - self.library_view.model().resort(reset=False) - self.library_view.model().research() + def book_converted(self, id, description, result, exception, formatted_traceback, log):