From 0104da83510ba56ae7e575f529270f78cf08ee0b Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 21 Aug 2007 23:58:29 +0000 Subject: [PATCH] GUI conversion implemented. version 0.3.102 --- src/libprs500/__init__.py | 2 +- src/libprs500/ebooks/lrf/any/convert_from.py | 17 ++++--- src/libprs500/gui2/dialogs/choose_format.py | 2 +- src/libprs500/gui2/dialogs/lrf_single.py | 47 ++++++++++++-------- src/libprs500/gui2/main.py | 38 +++++++++++++++- src/libprs500/library/database.py | 16 ++++--- 6 files changed, 88 insertions(+), 34 deletions(-) diff --git a/src/libprs500/__init__.py b/src/libprs500/__init__.py index e366f91863..2fe36fefbb 100644 --- a/src/libprs500/__init__.py +++ b/src/libprs500/__init__.py @@ -13,7 +13,7 @@ ## with this program; if not, write to the Free Software Foundation, Inc., ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ''' E-book management software''' -__version__ = "0.3.101" +__version__ = "0.3.102" __docformat__ = "epytext" __author__ = "Kovid Goyal " __appname__ = 'libprs500' diff --git a/src/libprs500/ebooks/lrf/any/convert_from.py b/src/libprs500/ebooks/lrf/any/convert_from.py index a5995309f9..c4d7adf734 100644 --- a/src/libprs500/ebooks/lrf/any/convert_from.py +++ b/src/libprs500/ebooks/lrf/any/convert_from.py @@ -35,12 +35,17 @@ def largest_file(files): return file def find_htmlfile(dir): - for pair in (('*toc*.htm*', '*toc*.xhtm*'), ('*.htm*', '*.xhtm*')): - files = glob.glob(os.path.join(dir, pair[0])) - files += glob.glob(os.path.join(dir, pair[1])) - file = largest_file(files) - if file: - return file + cwd = os.getcwd() + try: + os.chdir(dir) + for pair in (('*toc*.htm*', '*toc*.xhtm*'), ('*.htm*', '*.xhtm*')): + files = glob.glob(pair[0]) + files += glob.glob(pair[1]) + file = largest_file(files) + if file: + return os.path.join(dir, file) + finally: + os.chdir(cwd) def handle_archive(path): diff --git a/src/libprs500/gui2/dialogs/choose_format.py b/src/libprs500/gui2/dialogs/choose_format.py index 69bf15bb96..d04ed09662 100644 --- a/src/libprs500/gui2/dialogs/choose_format.py +++ b/src/libprs500/gui2/dialogs/choose_format.py @@ -33,6 +33,6 @@ class ChooseFormatDialog(QDialog, Ui_ChooseFormatDialog): self.formats.setCurrentRow(0) def format(self): - self._formats[self.formats.currentRow()] + return self._formats[self.formats.currentRow()] \ No newline at end of file diff --git a/src/libprs500/gui2/dialogs/lrf_single.py b/src/libprs500/gui2/dialogs/lrf_single.py index cac2a7b905..e052142e14 100644 --- a/src/libprs500/gui2/dialogs/lrf_single.py +++ b/src/libprs500/gui2/dialogs/lrf_single.py @@ -22,6 +22,8 @@ from libprs500.gui2.dialogs.choose_format import ChooseFormatDialog from libprs500.gui2 import qstring_to_unicode, error_dialog, \ pixmap_to_data, choose_images from libprs500.ebooks.lrf import option_parser +from libprs500.ptempfile import PersistentTemporaryFile +from libprs500 import __appname__ class LRFSingleDialog(QDialog, Ui_LRFSingleDialog): @@ -51,6 +53,8 @@ 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.db = db @@ -61,34 +65,31 @@ class LRFSingleDialog(QDialog, Ui_LRFSingleDialog): self.changed = False self.read_saved_options() self.initialize_metadata() - formats = self.db.formats(self.row) + formats = [i.upper() for i in self.db.formats(self.row).split(',')] + try: + formats.remove(self.output_format) + except ValueError: + pass if not formats: d = error_dialog(window, 'No available formats', 'Cannot convert as this book has no available formats') d.exec_() - formats = [i.upper() for i in formats.split(',')] - self.selected_format = None - try: - formats.remove('LRF') - except ValueError: - pass + if len(formats) > 1: d = ChooseFormatDialog(window, 'Choose the format to convert into LRF', formats) d.exec_() if d.result() == QDialog.Accepted: self.selected_format = d.format() else: - if len(formats): - self.selected_format = formats[0] - else: - d = error_dialog(window, 'No suitable formats', 'Cannot convert as this book has no suitable formats.') - d.exec_() + self.selected_format = formats[0] + if self.selected_format: self.setWindowTitle('Convert %s to LRF'%(self.selected_format,)) + + def read_saved_options(self): - cmdline = self.db.conversion_options(self.id, 'lrf') - print 1, cmdline + cmdline = self.db.conversion_options(self.id, self.output_format.lower()) if cmdline: for opt in self.options(): try: @@ -236,7 +237,7 @@ class LRFSingleDialog(QDialog, Ui_LRFSingleDialog): args[0].accept() def build_commandline(self): - cmd = [] + cmd = [__appname__] for name in self.option_map.keys(): opt = self.option_map[name].get_opt_string() obj = getattr(self, name) @@ -256,6 +257,9 @@ class LRFSingleDialog(QDialog, Ui_LRFSingleDialog): cmd.extend(['--profile', qstring_to_unicode(self.gui_profile.currentText())]) return cmd + def title(self): + return qstring_to_unicode(self.gui_title.text()) + def write_metadata(self): title = qstring_to_unicode(self.gui_title.text()) self.db.set_title(self.id, title) @@ -263,7 +267,6 @@ class LRFSingleDialog(QDialog, Ui_LRFSingleDialog): if au: self.db.set_authors(self.id, au) aus = qstring_to_unicode(self.gui_author_sort.text()) if aus: self.db.set_author_sort(self.id, aus) - print self.db.author_sort(self.row) self.db.set_publisher(self.id, qstring_to_unicode(self.gui_publisher.text())) self.db.set_tags(self.id, qstring_to_unicode(self.tags.text()).split(',')) self.db.set_series(self.id, qstring_to_unicode(self.series.currentText())) @@ -274,8 +277,16 @@ class LRFSingleDialog(QDialog, Ui_LRFSingleDialog): def accept(self): cmdline = self.build_commandline() - # TODO: put cover into tempfile + self.cover_file = None self.write_metadata() - self.db.set_conversion_options(self.id, 'lrf', cmdline) + cover = self.db.cover(self.row) + if cover: + self.cover_file = PersistentTemporaryFile(suffix='.jpeg') + self.cover_file.write(cover) + self.cover_file.close() + self.db.set_conversion_options(self.id, self.output_format.lower(), cmdline) + if self.cover_file: + cmdline.extend(['--cover', self.cover_file.name]) + self.cmdline = [str(i) for i in cmdline] QDialog.accept(self) \ No newline at end of file diff --git a/src/libprs500/gui2/main.py b/src/libprs500/gui2/main.py index c86246c166..6aa7d7370d 100644 --- a/src/libprs500/gui2/main.py +++ b/src/libprs500/gui2/main.py @@ -25,6 +25,7 @@ from libprs500 import __version__, __appname__ from libprs500.ptempfile import PersistentTemporaryFile from libprs500.ebooks.metadata.meta import get_metadata from libprs500.ebooks.lrf.web.convert_from import main as web2lrf +from libprs500.ebooks.lrf.any.convert_from import main as any2lrf from libprs500.devices.errors import FreeSpaceError from libprs500.devices.interface import Device from libprs500.gui2 import APP_TITLE, warning_dialog, choose_files, error_dialog, \ @@ -471,7 +472,7 @@ class Main(QObject, Ui_MainWindow): self.current_view().model().save_to_disk(rows, dir) else: paths = self.current_view().model().paths(rows) - self.job_manager.run_device_job(self.books_saved, + self.job_manager.run_device_job(self.books_saved, self.device_manager.save_books_func(), paths, dir) def books_saved(self, id, description, result, exception, formatted_traceback): @@ -525,7 +526,8 @@ class Main(QObject, Ui_MainWindow): ############################### Convert #################################### def convert_bulk(self, checked): - pass + d = error_dialog(self.window, 'Cannot convert', 'Not yet implemented.') + d.exec_() def convert_single(self, checked): rows = self.library_view.selectionModel().selectedRows() @@ -533,10 +535,42 @@ class Main(QObject, Ui_MainWindow): d = error_dialog(self.window, 'Cannot convert', 'No books selected') d.exec_() + changed = False for row in rows: d = LRFSingleDialog(self.window, 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.row(), d.selected_format) + pt = PersistentTemporaryFile('.'+d.selected_format.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.title()) + + + 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): + of, fmt, book_id = self.conversion_jobs.pop(id)[2:] + if exception: + self.conversion_job_exception(id, description, exception, formatted_traceback, log) + return + data = open(of.name, 'rb') + self.library_view.model().db.add_format(book_id, fmt, data, index_is_id=True) + data.close() + self.status_bar.showMessage(description + ' completed', 2000) ############################################################################ def location_selected(self, location): diff --git a/src/libprs500/library/database.py b/src/libprs500/library/database.py index e6a570a9ab..05c05efd6b 100644 --- a/src/libprs500/library/database.py +++ b/src/libprs500/library/database.py @@ -754,9 +754,9 @@ class LibraryDatabase(object): return None return matches[0][0] - def formats(self, index): + def formats(self, index, index_is_id=False): ''' Return available formats as a comma separated list ''' - id = self.id(index) + id = index if index_is_id else self.id(index) matches = self.conn.execute('SELECT concat(format) FROM data WHERE data.book=?', (id,)).fetchall() if not matches: return None @@ -777,18 +777,21 @@ class LibraryDatabase(object): return None - def add_format(self, index, ext, stream): + def add_format(self, index, ext, stream, index_is_id=False): ''' Add the format specified by ext. If it already exists it is replaced. ''' - id = self.id(index) + id = index if index_is_id else self.id(index) stream.seek(0, 2) usize = stream.tell() stream.seek(0) data = sqlite.Binary(compress(stream.read())) - exts = self.formats(index) + exts = self.formats(index, index_is_id=index_is_id) if not exts: exts = [] + if not ext: + ext = '' + ext = ext.lower() if ext in exts: self.conn.execute('UPDATE data SET data=? WHERE format=? AND book=?', (data, ext, id)) @@ -996,7 +999,8 @@ class LibraryDatabase(object): by_author = {} for index in indices: id = self.id(index) - au = self.conn.execute('SELECT concat(sort) FROM authors WHERE authors.id IN (SELECT author from books_authors_link WHERE book=?)', (id,)).fetchone()[0] + au = self.conn.execute('SELECT author_sort FROM books WHERE id=?', + (id,)).fetchone()[0] if not by_author.has_key(au): by_author[au] = [] by_author[au].append(index)