diff --git a/src/calibre/db/search.py b/src/calibre/db/search.py index 5a02a5e5da..334bc046d8 100644 --- a/src/calibre/db/search.py +++ b/src/calibre/db/search.py @@ -525,8 +525,35 @@ class Parser(SearchQueryParser): candidates, upf) return self.keypair_search(query, field_iter, candidates, upf) + # check for user categories + if len(location) >= 2 and location.startswith('@'): + return self.get_user_category_matches(location[1:], icu_lower(query), candidates) + return matches + def get_user_category_matches(self, location, query, candidates): + matches = set() + if len(query) < 2: + return matches + + user_cats = self.dbcache.pref('user_categories') + c = set(candidates) + + if query.startswith('.'): + check_subcats = True + query = query[1:] + else: + check_subcats = False + + for key in user_cats: + if key == location or (check_subcats and key.startswith(location + '.')): + for (item, category, ign) in user_cats[key]: + s = self.get_matches(category, '=' + item, candidates=c) + c -= s + matches |= s + if query == 'false': + return candidates - matches + return matches class Search(object): diff --git a/src/calibre/db/tests/metadata.db b/src/calibre/db/tests/metadata.db index 4bd6dfe4f9..94748877b6 100644 Binary files a/src/calibre/db/tests/metadata.db and b/src/calibre/db/tests/metadata.db differ diff --git a/src/calibre/db/tests/reading.py b/src/calibre/db/tests/reading.py index 2fa49033c0..627a692860 100644 --- a/src/calibre/db/tests/reading.py +++ b/src/calibre/db/tests/reading.py @@ -220,6 +220,7 @@ class ReadingTest(BaseTest): # TODO: Tests for searching the size column and # cover:true|false + # TODO: Tests for user categories searching )} old = None