diff --git a/src/calibre/gui2/device.py b/src/calibre/gui2/device.py index ed001c30ba..46cf9895d4 100644 --- a/src/calibre/gui2/device.py +++ b/src/calibre/gui2/device.py @@ -577,7 +577,7 @@ class DeviceGUI(object): def sync_to_device(self, on_card, delete_from_library, - specific_format=None, send_rows=None, auto_convert=True): + specific_format=None, send_rows=None, do_auto_convert=True): rows = self.library_view.selectionModel().selectedRows() if send_rows is None else send_rows if not self.device_manager or not rows or len(rows) == 0: return @@ -585,8 +585,12 @@ class DeviceGUI(object): _files, _auto_rows = self.library_view.model().get_preferred_formats(rows, self.device_manager.device_class.FORMATS, paths=True, set_metadata=True, - specific_format=specific_format) - rows = list(set(rows).difference(_auto_rows)) + specific_format=specific_format, + exclude_auto=do_auto_convert) + if do_auto_convert: + rows = list(set(rows).difference(_auto_rows)) + else: + _auto_rows = [] ids = iter(self.library_view.model().id(r) for r in rows) metadata = self.library_view.model().get_metadata(rows) @@ -626,9 +630,9 @@ class DeviceGUI(object): if _auto_rows != []: for row in _auto_rows: if specific_format == None: - formats = self.library_view.model().db.formats(row).split(',') - formats = formats if formats != None else [] - if set(formats).intersection(available_input_formats()) is not None and set(self.device_manager.device_class.FORMATS).intersection(available_output_formats()) is not None: + formats = [f.lower() for f in self.library_view.model().db.formats(row).split(',')] + formats = formats if formats != None else [] + if list(set(formats).intersection(available_input_formats())) != [] and list(set(self.device_manager.device_class.FORMATS).intersection(available_output_formats())) != []: auto.append(row) else: bad.append(self.library_view.model().title(row)) @@ -646,10 +650,10 @@ class DeviceGUI(object): for fmt in self.device_manager.device_class.FORMATS: if fmt in list(set(self.device_manager.device_class.FORMATS).intersection(set(available_output_formats()))): format = fmt - break + break + d.exec_() self.auto_convert(_auto_rows, on_card, format) - d.exec_() - + if bad: bad = '\n'.join('
  • %s
  • '%(i,) for i in bad) d = warning_dialog(self, _('No suitable formats'), diff --git a/src/calibre/gui2/library.py b/src/calibre/gui2/library.py index 1f3ed31478..c67f9bc1b0 100644 --- a/src/calibre/gui2/library.py +++ b/src/calibre/gui2/library.py @@ -420,7 +420,8 @@ class BooksModel(QAbstractTableModel): def get_preferred_formats(self, rows, formats, paths=False, - set_metadata=False, specific_format=None): + set_metadata=False, specific_format=None, + exclude_auto=False): ans = [] need_auto = [] if specific_format is not None: @@ -448,7 +449,8 @@ class BooksModel(QAbstractTableModel): ans.append(pt) else: need_auto.append(row) - ans.append(None) + if not exclude_auto: + ans.append(None) return ans, need_auto def id(self, row): diff --git a/src/calibre/gui2/main.py b/src/calibre/gui2/main.py index dcece08a3e..fee500bdb9 100644 --- a/src/calibre/gui2/main.py +++ b/src/calibre/gui2/main.py @@ -969,17 +969,9 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI): def auto_convert(self, rows, on_card, format): previous = self.library_view.currentIndex() - comics, others = [], [] - db = self.library_view.model().db - for r in rows: - formats = db.formats(r) - if not formats: continue - formats = formats.lower().split(',') - if 'cbr' in formats or 'cbz' in formats: - comics.append(r) - else: - others.append(r) - jobs, changed, bad_rows = auto_convert_ebook(format, self, self.library_view.model().db, comics, others) + jobs, changed, bad_rows = auto_convert_ebook(format, self, self.library_view.model().db, rows) + if jobs is None: + return for func, args, desc, fmt, id, temp_files in jobs: if id not in bad_rows: job = self.job_manager.run_job(Dispatcher(self.book_auto_converted), @@ -1063,7 +1055,7 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI): if job.exception is not None: self.job_exception(job) return - data = open(temp_files[-1].name, 'rb') + data = open(temp_files[0].name, 'rb') self.library_view.model().db.add_format(book_id, fmt, data, index_is_id=True) data.close() self.status_bar.showMessage(job.description + (' completed'), 2000) @@ -1080,7 +1072,7 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI): self.library_view.model().current_changed(current, QModelIndex()) r = self.library_view.model().index(self.library_view.model().db.row(book_id), 0) - self.sync_to_device(on_card, False, specific_format=fmt, send_rows=[r], auto_convert=False) + self.sync_to_device(on_card, False, specific_format=fmt, send_rows=[r], do_auto_convert=False) def book_converted(self, job): temp_files, fmt, book_id = self.conversion_jobs.pop(job) diff --git a/src/calibre/gui2/tools.py b/src/calibre/gui2/tools.py index 07587d3c25..e6bbf543e1 100644 --- a/src/calibre/gui2/tools.py +++ b/src/calibre/gui2/tools.py @@ -9,6 +9,7 @@ Logic for setting up conversion jobs import os from PyQt4.Qt import QDialog +from calibre.customize.ui import available_input_formats from calibre.utils.config import prefs from calibre.gui2.dialogs.lrf_single import LRFSingleDialog, LRFBulkDialog from calibre.gui2.dialogs.epub import Config as EPUBConvert @@ -22,6 +23,11 @@ from calibre.ebooks.epub.from_any import SOURCE_FORMATS as EPUB_PREFERRED_SOURCE from calibre.ebooks.mobi.from_any import config as mobiconfig from calibre.ebooks.lrf.comic.convert_from import config as comicconfig +# Ordered list of source formats. Items closer to the beginning are +# preferred for conversion over those toward the end. +PREFERRED_SOURCE_FORMATS = ['epub', 'lit', 'mobi', 'prc', 'azw', 'fb2', 'odt', 'rtf', + 'txt', 'pdf', 'oebzip', 'htm', 'html'] + def get_dialog(fmt): return { 'epub':EPUBConvert, @@ -34,101 +40,77 @@ def get_config(fmt): 'mobi':mobiconfig, }[fmt] -def auto_convert(fmt, parent, db, comics, others): +def auto_convert(fmt, parent, db, rows): changed = False jobs = [] - total = sum(map(len, (others, comics))) + total = len(rows) if total == 0: - return + return None, None, None parent.status_bar.showMessage(_('Starting auto conversion of %d books')%total, 2000) i = 0 bad_rows = [] - for i, row in enumerate(others+comics): + for i, row in enumerate(rows): row_id = db.id(row) - if row in others: - temp_files = [] - - data = None - for _fmt in EPUB_PREFERRED_SOURCE_FORMATS: - try: - data = db.format(row, _fmt.upper()) - if data is not None: - break - except: - continue - if data is None: - bad_rows.append(row) - continue + temp_files = [] - defaults = db.conversion_options(db.id(row), fmt) - defaults = defaults if defaults else '' - options = get_config(fmt)(defaults=defaults).parse() - - mi = db.get_metadata(row) - opf = OPFCreator(os.getcwdu(), mi) - opf_file = PersistentTemporaryFile('.opf') - opf.render(opf_file) - opf_file.close() - pt = PersistentTemporaryFile('.'+_fmt.lower()) - pt.write(data) - pt.close() - of = PersistentTemporaryFile('.'+fmt) - of.close() - cover = db.cover(row) - cf = None - if cover: - cf = PersistentTemporaryFile('.jpeg') - cf.write(cover) - cf.close() - options.cover = cf.name - options.output = of.name - options.from_opf = opf_file.name - args = [options, pt.name] - desc = _('Auto convert book %d of %d (%s)')%(i+1, total, repr(mi.title)) - temp_files = [cf] if cf is not None else [] - temp_files.extend([opf_file, pt, of]) - jobs.append(('any2'+fmt, args, desc, fmt.upper(), row_id, temp_files)) - - changed = True - else: - defaults = db.conversion_options(db.id(row), fmt) - defaults = defaults if defaults else '' - options = comicconfig(defaults=defaults).parse() - - mi = db.get_metadata(row) - if mi.title: - options.title = mi.title - if mi.authors: - options.author = ','.join(mi.authors) - data = None - for _fmt in ['cbz', 'cbr']: - try: - data = db.format(row, _fmt.upper()) - if data is not None: - break - except: - continue - - if data is None: + data = None + in_formats = [f.lower() for f in db.formats(row).split(',')] + in_formats = list(set(in_formats).intersection(available_input_formats())) + for _fmt in PREFERRED_SOURCE_FORMATS: + if _fmt in in_formats: + data = _fmt + break + if data is None: + if in_formats != []: + data = list(in_formats)[0] + else: bad_rows.append(row) continue - - pt = PersistentTemporaryFile('.'+_fmt.lower()) - pt.write(data) - pt.close() - of = PersistentTemporaryFile('.'+fmt) - of.close() - setattr(options, 'output', of.name) - options.verbose = 1 - args = [pt.name, options] - desc = _('Convert book %d of %d (%s)')%(i+1, total, repr(mi.title)) - jobs.append(('comic2'+fmt, args, desc, fmt.upper(), row_id, [pt, of])) - - changed = True + +# defaults = db.conversion_options(db.id(row), fmt) +# defaults = defaults if defaults else '' +# options = get_config(fmt)(defaults=defaults).parse() + +# mi = db.get_metadata(row) +# opf = OPFCreator(os.getcwdu(), mi) +# opf_file = PersistentTemporaryFile('.opf') +# opf.render(opf_file) +# opf_file.close() +# pt = PersistentTemporaryFile('.'+_fmt.lower()) +# pt.write(data) +# pt.close() +# of = PersistentTemporaryFile('.'+fmt) +# of.close() +# cover = db.cover(row) +# cf = None +# if cover: +# cf = PersistentTemporaryFile('.jpeg') +# cf.write(cover) +# cf.close() +# options.cover = cf.name +# options.output = of.name +# options.from_opf = opf_file.name +# args = [options, pt.name] +# desc = _('Auto convert book %d of %d (%s)')%(i+1, total, repr(mi.title)) +# temp_files = [cf] if cf is not None else [] +# temp_files.extend([opf_file, pt, of]) +# jobs.append(('any2'+fmt, args, desc, fmt.upper(), row_id, temp_files)) + + mi = db.get_metadata(row) + in_file = db.format_abspath(row, data) + out_file = PersistentTemporaryFile('.'+fmt.lower()) + out_file.write(data) + out_file.close() + desc = _('Auto convert book %d of %d (%s)')%(i+1, total, repr(mi.title)) + args = [['', in_file, out_file.name]] + temp_files = [out_file] + jobs.append(('ebook-convert', args, desc, fmt.upper(), row_id, temp_files)) + + changed = True if bad_rows: res = [] @@ -141,9 +123,6 @@ def auto_convert(fmt, parent, db, comics, others): return jobs, changed, bad_rows -def auto_convert_lrf(fmt, parent, db, comics, others): - pass - def convert_single(fmt, parent, db, comics, others): changed = False jobs = [] diff --git a/src/calibre/parallel.py b/src/calibre/parallel.py index 4969877da9..90a2969c86 100644 --- a/src/calibre/parallel.py +++ b/src/calibre/parallel.py @@ -79,6 +79,9 @@ PARALLEL_FUNCS = { 'comic2mobi' : ('calibre.ebooks.mobi.from_comic', 'convert', {}, 'notification'), + + 'ebook-convert' : + ('calibre.ebooks.conversion.cli', 'main', {}, None), }