diff --git a/src/calibre/db/cache.py b/src/calibre/db/cache.py index aeceafbb8b..5b9243a7b7 100644 --- a/src/calibre/db/cache.py +++ b/src/calibre/db/cache.py @@ -1086,17 +1086,18 @@ class Cache(object): return self._search_api(self, query, restriction, virtual_fields=virtual_fields, book_ids=book_ids) @read_api - def books_in_virtual_library(self, vl, search_restriction=None): + def books_in_virtual_library(self, vl, search_restriction=None, virtual_fields=None): ' Return the set of books in the specified virtual library ' vl = self._pref('virtual_libraries', {}).get(vl) if vl else None if not vl and not search_restriction: return self.all_book_ids() # We utilize the search restriction cache to speed this up + srch = partial(self._search, virtual_fields=virtual_fields) if vl: if search_restriction: - return frozenset(self._search('', vl) & self._search('', search_restriction)) - return frozenset(self._search('', vl)) - return frozenset(self._search('', search_restriction)) + return frozenset(srch('', vl) & srch('', search_restriction)) + return frozenset(srch('', vl)) + return frozenset(srch('', search_restriction)) @read_api def number_of_books_in_virtual_library(self, vl=None, search_restriction=None): @@ -2214,8 +2215,11 @@ class Cache(object): c = defaultdict(list) libraries = self._pref('virtual_libraries', {}) for lib, expr in libraries.items(): - for book in self._search(expr, virtual_fields=virtual_fields): - c[book].append(lib) + try: + for book in self._search(expr, virtual_fields=virtual_fields): + c[book].append(lib) + except Exception as e: + c[book].append(_('[Error in virtual library {0}: {1}]').format(lib, str(e))) self.vls_for_books_cache = {b:tuple(sorted(libs, key=sort_key)) for b, libs in c.items()} if not book_ids: book_ids = self._all_book_ids() diff --git a/src/calibre/db/search.py b/src/calibre/db/search.py index c8f69d9f04..246264b9ef 100644 --- a/src/calibre/db/search.py +++ b/src/calibre/db/search.py @@ -513,7 +513,8 @@ class Parser(SearchQueryParser): # {{{ if not vl: raise ParseException(_('No such Virtual library: {}').format(query)) try: - return candidates & self.dbcache.books_in_virtual_library(query) + return candidates & self.dbcache.books_in_virtual_library( + query, virtual_fields=self.virtual_fields) except RuntimeError: raise ParseException(_('Virtual library search is recursive: {}').format(query)) diff --git a/src/calibre/gui2/tag_browser/model.py b/src/calibre/gui2/tag_browser/model.py index c05c638d71..4f38e57d2b 100644 --- a/src/calibre/gui2/tag_browser/model.py +++ b/src/calibre/gui2/tag_browser/model.py @@ -312,7 +312,7 @@ class TagsModel(QAbstractItemModel): # {{{ search_item_renamed = pyqtSignal() tag_item_renamed = pyqtSignal() refresh_required = pyqtSignal() - restriction_error = pyqtSignal() + restriction_error = pyqtSignal(object) drag_drop_finished = pyqtSignal(object) user_categories_edited = pyqtSignal(object, object) user_category_added = pyqtSignal() @@ -1113,12 +1113,11 @@ class TagsModel(QAbstractItemModel): # {{{ data = self.db.new_api.get_categories(sort=sort, book_ids=self.get_book_ids_to_use(), first_letter_sort=self.collapse_model == 'first letter') - except: - import traceback + except Exception as e: traceback.print_exc() data = self.db.new_api.get_categories(sort=sort, first_letter_sort=self.collapse_model == 'first letter') - self.restriction_error.emit() + self.restriction_error.emit(str(e)) if self.filter_categories_by: if self.filter_categories_by.startswith('='): diff --git a/src/calibre/gui2/tag_browser/ui.py b/src/calibre/gui2/tag_browser/ui.py index 2b95377ea6..eb9cbcda79 100644 --- a/src/calibre/gui2/tag_browser/ui.py +++ b/src/calibre/gui2/tag_browser/ui.py @@ -99,9 +99,10 @@ class TagBrowserMixin(object): # {{{ def user_categories_edited(self): self.library_view.model().refresh() - def do_restriction_error(self): + def do_restriction_error(self, e): error_dialog(self.tags_view, _('Invalid search restriction'), - _('The current search restriction is invalid'), show=True) + _('The current search restriction is invalid'), + det_msg=str(e) if e else '', show=True) def do_add_subcategory(self, on_category_key, new_category_name=None): ''' diff --git a/src/calibre/gui2/tag_browser/view.py b/src/calibre/gui2/tag_browser/view.py index 6159cf695f..715adae45f 100644 --- a/src/calibre/gui2/tag_browser/view.py +++ b/src/calibre/gui2/tag_browser/view.py @@ -172,7 +172,7 @@ class TagsView(QTreeView): # {{{ tag_item_renamed = pyqtSignal() search_item_renamed = pyqtSignal() drag_drop_finished = pyqtSignal(object) - restriction_error = pyqtSignal() + restriction_error = pyqtSignal(object) tag_item_delete = pyqtSignal(object, object, object, object, object) tag_identifier_delete = pyqtSignal(object, object) apply_tag_to_selected = pyqtSignal(object, object, object)