mirror of
git://github.com/kovidgoyal/calibre.git
synced 2026-05-08 19:43:54 +02:00
Merge branch 'master' of https://github.com/cbhaley/calibre
Fixes #1924247 [Possible to create recursive VL that crashes Calibre](https://bugs.launchpad.net/calibre/+bug/1924247)
This commit is contained in:
commit
095515b6e8
5 changed files with 19 additions and 14 deletions
|
|
@ -1086,17 +1086,18 @@ def search(self, query, restriction='', virtual_fields=None, book_ids=None):
|
|||
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 @@ def virtual_libraries_for_books(self, book_ids, virtual_fields=None):
|
|||
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()
|
||||
|
|
|
|||
|
|
@ -513,7 +513,8 @@ def get_matches(self, location, query, candidates=None,
|
|||
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))
|
||||
|
||||
|
|
|
|||
|
|
@ -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 @@ def _get_category_nodes(self, sort):
|
|||
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('='):
|
||||
|
|
|
|||
|
|
@ -99,9 +99,10 @@ def init_tag_browser_mixin(self, db):
|
|||
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):
|
||||
'''
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Reference in a new issue