From 207a18c7a5f2f1fb35816566e96151e02e7b8322 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 30 Mar 2012 18:55:38 +0530 Subject: [PATCH] Auto adding: When automatically adding files from a folder, automatically convert the files to the current output format after adding. This can be turned off via Preferences->Adding Books->Automatic Adding. Fixes #969053 ([Req] Auto-Convert to mobi after Auto-Add) --- src/calibre/gui2/__init__.py | 1 + src/calibre/gui2/actions/convert.py | 26 +++++++++++++++++++++-- src/calibre/gui2/auto_add.py | 23 ++++++++++++++++---- src/calibre/gui2/library/models.py | 5 +++-- src/calibre/gui2/preferences/adding.py | 1 + src/calibre/gui2/preferences/adding.ui | 29 ++++++++++++++++---------- src/calibre/gui2/tools.py | 4 ++-- src/calibre/library/database2.py | 5 +++-- 8 files changed, 71 insertions(+), 23 deletions(-) diff --git a/src/calibre/gui2/__init__.py b/src/calibre/gui2/__init__.py index e6d4ccaac0..d334816985 100644 --- a/src/calibre/gui2/__init__.py +++ b/src/calibre/gui2/__init__.py @@ -105,6 +105,7 @@ gprefs.defaults['show_files_after_save'] = True gprefs.defaults['auto_add_path'] = None gprefs.defaults['auto_add_check_for_duplicates'] = False gprefs.defaults['blocked_auto_formats'] = [] +gprefs.defaults['auto_add_auto_convert'] = True # }}} NONE = QVariant() #: Null value to return from the data function of item models diff --git a/src/calibre/gui2/actions/convert.py b/src/calibre/gui2/actions/convert.py index fc1d166685..34e03dc275 100644 --- a/src/calibre/gui2/actions/convert.py +++ b/src/calibre/gui2/actions/convert.py @@ -53,6 +53,24 @@ class ConvertAction(InterfaceAction): self.queue_convert_jobs(jobs, changed, bad, rows, previous, self.book_auto_converted, extra_job_args=[on_card]) + def auto_convert_auto_add(self, book_ids): + previous = self.gui.library_view.currentIndex() + db = self.gui.current_db + needed = set() + of = prefs['output_format'].lower() + for book_id in book_ids: + fmts = db.formats(book_id, index_is_id=True) + fmts = set(x.lower() for x in fmts.split(',')) if fmts else set() + if of not in fmts: + needed.add(book_id) + if needed: + jobs, changed, bad = convert_single_ebook(self.gui, + self.gui.library_view.model().db, needed, True, of, + show_no_format_warning=False) + if not jobs: return + self.queue_convert_jobs(jobs, changed, bad, list(needed), previous, + self.book_converted, rows_are_ids=True) + def auto_convert_mail(self, to, fmts, delete_from_library, book_ids, format, subject): previous = self.gui.library_view.currentIndex() rows = [x.row() for x in \ @@ -118,7 +136,7 @@ class ConvertAction(InterfaceAction): num, 2000) def queue_convert_jobs(self, jobs, changed, bad, rows, previous, - converted_func, extra_job_args=[]): + converted_func, extra_job_args=[], rows_are_ids=False): for func, args, desc, fmt, id, temp_files in jobs: func, _, same_fmt = func.partition(':') same_fmt = same_fmt == 'same_fmt' @@ -140,7 +158,11 @@ class ConvertAction(InterfaceAction): self.conversion_jobs[job] = tuple(args) if changed: - self.gui.library_view.model().refresh_rows(rows) + m = self.gui.library_view.model() + if rows_are_ids: + m.refresh_ids(rows) + else: + m.refresh_rows(rows) current = self.gui.library_view.currentIndex() self.gui.library_view.model().current_changed(current, previous) diff --git a/src/calibre/gui2/auto_add.py b/src/calibre/gui2/auto_add.py index a0be1b72fb..033d7124d5 100644 --- a/src/calibre/gui2/auto_add.py +++ b/src/calibre/gui2/auto_add.py @@ -113,6 +113,7 @@ class Worker(Thread): class AutoAdder(QObject): metadata_read = pyqtSignal(object) + auto_convert = pyqtSignal(object) def __init__(self, path, parent): QObject.__init__(self, parent) @@ -124,6 +125,8 @@ class AutoAdder(QObject): self.metadata_read.connect(self.add_to_db, type=Qt.QueuedConnection) QTimer.singleShot(2000, self.initialize) + self.auto_convert.connect(self.do_auto_convert, + type=Qt.QueuedConnection) elif path: prints(path, 'is not a valid directory to watch for new ebooks, ignoring') @@ -163,6 +166,7 @@ class AutoAdder(QObject): needs_rescan = False duplicates = [] + added_ids = set() for fname, tdir in data.iteritems(): paths = [os.path.join(self.worker.path, fname)] @@ -187,9 +191,12 @@ class AutoAdder(QObject): continue mi = [OPF(open(mi, 'rb'), tdir, populate_spine=False).to_book_metadata()] - dups, num = m.add_books(paths, + dups, ids = m.add_books(paths, [os.path.splitext(fname)[1][1:].upper()], mi, - add_duplicates=not gprefs['auto_add_check_for_duplicates']) + add_duplicates=not gprefs['auto_add_check_for_duplicates'], + return_ids=True) + added_ids |= set(ids) + num = len(ids) if dups: path = dups[0][0] with open(os.path.join(tdir, 'dup_cache.'+dups[1][0].lower()), @@ -217,8 +224,10 @@ class AutoAdder(QObject): _('Books with the same title as the following already ' 'exist in the database. Add them anyway?'), '\n'.join(files)): - dups, num = m.add_books(paths, formats, metadata, - add_duplicates=True) + dups, ids = m.add_books(paths, formats, metadata, + add_duplicates=True, return_ids=True) + added_ids |= set(ids) + num = len(ids) count += num for tdir in data.itervalues(): @@ -227,6 +236,9 @@ class AutoAdder(QObject): except: pass + if added_ids and gprefs['auto_add_auto_convert']: + self.auto_convert.emit(added_ids) + if count > 0: m.books_added(count) gui.status_bar.show_message(_( @@ -238,4 +250,7 @@ class AutoAdder(QObject): if needs_rescan: QTimer.singleShot(2000, self.dir_changed) + def do_auto_convert(self, added_ids): + gui = self.parent() + gui.iactions['Convert Books'].auto_convert_auto_add(added_ids) diff --git a/src/calibre/gui2/library/models.py b/src/calibre/gui2/library/models.py index 0b3c048a2e..e0047c2a70 100644 --- a/src/calibre/gui2/library/models.py +++ b/src/calibre/gui2/library/models.py @@ -187,9 +187,10 @@ class BooksModel(QAbstractTableModel): # {{{ self.db = None self.reset() - def add_books(self, paths, formats, metadata, add_duplicates=False): + def add_books(self, paths, formats, metadata, add_duplicates=False, + return_ids=False): ret = self.db.add_books(paths, formats, metadata, - add_duplicates=add_duplicates) + add_duplicates=add_duplicates, return_ids=return_ids) self.count_changed() return ret diff --git a/src/calibre/gui2/preferences/adding.py b/src/calibre/gui2/preferences/adding.py index 1e8395b4f3..fafc5b5a1c 100644 --- a/src/calibre/gui2/preferences/adding.py +++ b/src/calibre/gui2/preferences/adding.py @@ -36,6 +36,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): r('new_book_tags', prefs, setting=CommaSeparatedList) r('auto_add_path', gprefs, restart_required=True) r('auto_add_check_for_duplicates', gprefs) + r('auto_add_auto_convert', gprefs) self.filename_pattern = FilenamePattern(self) self.metadata_box.layout().insertWidget(0, self.filename_pattern) diff --git a/src/calibre/gui2/preferences/adding.ui b/src/calibre/gui2/preferences/adding.ui index 900ed62103..f04d55ff28 100644 --- a/src/calibre/gui2/preferences/adding.ui +++ b/src/calibre/gui2/preferences/adding.ui @@ -151,6 +151,19 @@ Author matching is exact. &Automatic Adding + + + + If set, this option will causes calibre to check if a file + being auto-added is already in the calibre library. + If it is, a meesage will pop up asking you whether + you want to add it anyway. + + + Check for &duplicates when auto-adding files + + + @@ -168,7 +181,7 @@ Author matching is exact. - + Ignore files with the following extensions when automatically adding @@ -187,7 +200,7 @@ Author matching is exact. - + Qt::Horizontal @@ -225,16 +238,10 @@ Author matching is exact. - - - - If set, this option will causes calibre to check if a file - being auto-added is already in the calibre library. - If it is, a meesage will pop up asking you whether - you want to add it anyway. - + + - Check for &duplicates when auto-adding files + Automatically &convert added files to the current output format diff --git a/src/calibre/gui2/tools.py b/src/calibre/gui2/tools.py index f1df707ad4..242cac5d79 100644 --- a/src/calibre/gui2/tools.py +++ b/src/calibre/gui2/tools.py @@ -25,7 +25,7 @@ from calibre.ebooks.conversion.config import GuiRecommendations, \ from calibre.gui2.convert import bulk_defaults_for_input_format def convert_single_ebook(parent, db, book_ids, auto_conversion=False, # {{{ - out_format=None): + out_format=None, show_no_format_warning=True): changed = False jobs = [] bad = [] @@ -91,7 +91,7 @@ def convert_single_ebook(parent, db, book_ids, auto_conversion=False, # {{{ except NoSupportedInputFormats: bad.append(book_id) - if bad != []: + if bad and show_no_format_warning: res = [] for id in bad: title = db.title(id, True) diff --git a/src/calibre/library/database2.py b/src/calibre/library/database2.py index 1b4e8390f1..72ff9cd08d 100644 --- a/src/calibre/library/database2.py +++ b/src/calibre/library/database2.py @@ -3243,7 +3243,8 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): return id - def add_books(self, paths, formats, metadata, add_duplicates=True): + def add_books(self, paths, formats, metadata, add_duplicates=True, + return_ids=False): ''' Add a book to the database. The result cache is not updated. :param:`paths` List of paths to book files or file-like objects @@ -3289,7 +3290,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): formats = list(duplicate[1] for duplicate in duplicates) metadata = list(duplicate[2] for duplicate in duplicates) return (paths, formats, metadata), len(ids) - return None, len(ids) + return None, (ids if return_ids else len(ids)) def import_book(self, mi, formats, notify=True, import_hooks=True, apply_import_tags=True, preserve_uuid=False):