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),
}