From 76045d2a5490addb8d0e7e79a2af326e91864d82 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 18 Jul 2013 15:25:30 +0530 Subject: [PATCH] categories API --- src/calibre/db/cache.py | 14 ++++++++++++++ src/calibre/db/fields.py | 10 ++++++++++ src/calibre/db/legacy.py | 3 +++ src/calibre/db/tests/legacy.py | 2 ++ 4 files changed, 29 insertions(+) diff --git a/src/calibre/db/cache.py b/src/calibre/db/cache.py index d9dda41aa3..82dd762077 100644 --- a/src/calibre/db/cache.py +++ b/src/calibre/db/cache.py @@ -401,6 +401,12 @@ class Cache(object): def get_item_name(self, field, item_id): return self.fields[field].table.id_map[item_id] + @read_api + def get_item_id(self, field, item_name): + ' Return the item id for item_name (case-insensitive) ' + rmap = {icu_lower(v) if isinstance(v, unicode) else v:k for k, v in self.fields[field].table.id_map.iteritems()} + return rmap.get(icu_lower(item_name) if isinstance(item_name, unicode) else item_name, None) + @read_api def author_data(self, author_ids=None): ''' @@ -1413,6 +1419,14 @@ class Cache(object): def set_custom_column_metadata(self, num, name=None, label=None, is_editable=None, display=None): return self.backend.set_custom_column_metadata(num, name=name, label=label, is_editable=is_editable, display=display) + @read_api + def get_books_for_category(self, category, item_id_or_composite_value): + f = self.fields[category] + if hasattr(f, 'get_books_for_val'): + # Composite field + return f.get_books_for_val(item_id_or_composite_value, self._get_metadata, self._all_book_ids()) + return self._books_for_field(f.name, item_id_or_composite_value) + # }}} class SortKey(object): # {{{ diff --git a/src/calibre/db/fields.py b/src/calibre/db/fields.py index dd0165b44e..e028ff5d99 100644 --- a/src/calibre/db/fields.py +++ b/src/calibre/db/fields.py @@ -211,6 +211,16 @@ class CompositeField(OneToOneField): ans.append(c) return ans + def get_books_for_val(self, value, get_metadata, book_ids): + is_multiple = self.table.metadata['is_multiple'].get('cache_to_list', None) + ans = set() + for book_id in book_ids: + val = self.get_value_with_cache(book_id, get_metadata) + vals = {x.strip() for x in val.split(is_multiple)} if is_multiple else [val] + if value in vals: + ans.add(book_id) + return ans + class OnDeviceField(OneToOneField): def __init__(self, name, table): diff --git a/src/calibre/db/legacy.py b/src/calibre/db/legacy.py index b079c776bb..f7cab21baf 100644 --- a/src/calibre/db/legacy.py +++ b/src/calibre/db/legacy.py @@ -717,10 +717,13 @@ LibraryDatabase.format_hash = MT(lambda self, book_id, fmt:self.new_api.format_h LibraryDatabase.index = MT(lambda self, book_id, cache=False:self.data.id_to_index(book_id)) LibraryDatabase.has_cover = MT(lambda self, book_id:self.new_api.field_for('cover', book_id)) LibraryDatabase.get_tags = MT(lambda self, book_id:set(self.new_api.field_for('tags', book_id))) +LibraryDatabase.get_categories = MT(lambda self, sort='name', ids=None, icon_map=None:self.new_api.get_categories(sort=sort, book_ids=ids, icon_map=icon_map)) LibraryDatabase.get_identifiers = MT( lambda self, index, index_is_id=False: self.new_api.field_for('identifiers', index if index_is_id else self.id(index))) LibraryDatabase.isbn = MT( lambda self, index, index_is_id=False: self.get_identifiers(index, index_is_id=index_is_id).get('isbn', None)) +LibraryDatabase.get_books_for_category = MT( + lambda self, category, id_:self.new_api.get_books_for_category(category, id_)) # }}} # Legacy setter API {{{ diff --git a/src/calibre/db/tests/legacy.py b/src/calibre/db/tests/legacy.py index 091d344e2d..936eb12e44 100644 --- a/src/calibre/db/tests/legacy.py +++ b/src/calibre/db/tests/legacy.py @@ -161,10 +161,12 @@ class LegacyTest(BaseTest): from datetime import timedelta ndb = self.init_legacy(self.cloned_library) db = self.init_old() + newstag = ndb.new_api.get_item_id('tags', 'news') self.assertEqual(dict(db.prefs), dict(ndb.prefs)) for meth, args in { + 'get_books_for_category': [('tags', newstag), ('#formats', 'FMT1')], 'get_next_series_num_for': [('A Series One',)], 'get_id_from_uuid':[('ddddd',), (db.uuid(1, True),)], 'cover':[(0,), (1,), (2,)],