Miscellaneous API

This commit is contained in:
Kovid Goyal 2013-07-14 15:48:56 +05:30
parent 73536b6421
commit 34abccc4f1
3 changed files with 32 additions and 11 deletions

View File

@ -63,11 +63,13 @@ class LibraryDatabase(object):
cache = self.new_api = Cache(backend)
cache.init()
self.data = View(cache)
self.id = self.data.index_to_id
self.get_property = self.data.get_property
self.last_update_check = self.last_modified()
self.book_on_device_func = None
self.is_case_sensitive = getattr(backend, 'is_case_sensitive', False)
def close(self):
self.backend.close()
@ -131,6 +133,10 @@ class LibraryDatabase(object):
for book_id in self.data.cache.all_book_ids():
yield book_id
def is_empty(self):
with self.new_api.read_lock:
return not bool(self.new_api.fields['title'].table.book_col_map)
def get_usage_count_by_id(self, field):
return [[k, v] for k, v in self.new_api.get_usage_count_by_id(field).iteritems()]
@ -161,7 +167,7 @@ class LibraryDatabase(object):
def path(self, index, index_is_id=False):
'Return the relative path to the directory containing this books files as a unicode string.'
book_id = index if index_is_id else self.data.index_to_id(index)
book_id = index if index_is_id else self.id(index)
return self.new_api.field_for('path', book_id).replace('/', os.sep)
def abspath(self, index, index_is_id=False, create_dirs=True):
@ -224,7 +230,7 @@ class LibraryDatabase(object):
def add_format(self, index, fmt, stream, index_is_id=False, path=None, notify=True, replace=True, copy_function=None):
''' path and copy_function are ignored by the new API '''
book_id = index if index_is_id else self.data.index_to_id(index)
book_id = index if index_is_id else self.id(index)
try:
return self.new_api.add_format(book_id, fmt, stream, replace=replace, run_hooks=False, dbapi=self)
except:
@ -234,7 +240,7 @@ class LibraryDatabase(object):
def add_format_with_hooks(self, index, fmt, fpath, index_is_id=False, path=None, notify=True, replace=True):
''' path is ignored by the new API '''
book_id = index if index_is_id else self.data.index_to_id(index)
book_id = index if index_is_id else self.id(index)
try:
return self.new_api.add_format(book_id, fmt, fpath, replace=replace, run_hooks=True, dbapi=self)
except:
@ -268,12 +274,12 @@ class LibraryDatabase(object):
# }}}
def get_field(self, index, key, default=None, index_is_id=False):
book_id = index if index_is_id else self.data.index_to_id(index)
book_id = index if index_is_id else self.id(index)
mi = self.new_api.get_metadata(book_id, get_cover=key == 'cover')
return mi.get(key, default)
def authors_sort_strings(self, index, index_is_id=False):
book_id = index if index_is_id else self.data.index_to_id(index)
book_id = index if index_is_id else self.id(index)
with self.new_api.read_lock:
authors = self.new_api._field_ids_for('authors', book_id)
adata = self.new_api._author_data(authors)
@ -283,7 +289,7 @@ class LibraryDatabase(object):
return ' & '.join(self.authors_sort_strings(index, index_is_id=index_is_id))
def authors_with_sort_strings(self, index, index_is_id=False):
book_id = index if index_is_id else self.data.index_to_id(index)
book_id = index if index_is_id else self.id(index)
with self.new_api.read_lock:
authors = self.new_api._field_ids_for('authors', book_id)
adata = self.new_api._author_data(authors)
@ -318,7 +324,7 @@ class LibraryDatabase(object):
return sorted(book_ids, key=lambda x:ff('series_index', x))
def books_in_series_of(self, index, index_is_id=False):
book_id = index if index_is_id else self.data.index_to_id(index)
book_id = index if index_is_id else self.id(index)
series_ids = self.new_api.field_ids_for('series', book_id)
if not series_ids:
return []
@ -349,7 +355,7 @@ class LibraryDatabase(object):
self.new_api.delete_conversion_options((book_id,), fmt=fmt)
def set(self, index, field, val, allow_case_change=False):
book_id = self.data.index_to_id(index)
book_id = self.id(index)
try:
return self.new_api.set_field(field, {book_id:val}, allow_case_change=allow_case_change)
finally:
@ -427,6 +433,9 @@ class LibraryDatabase(object):
if tag_ids:
self.new_api._remove_items('tags', tag_ids)
def has_id(self, book_id):
return book_id in self.new_api.all_book_ids()
# Private interface {{{
def __iter__(self):
for row in self.data.iterall():
@ -454,10 +463,13 @@ for prop in ('author_sort', 'authors', 'comment', 'comments', 'publisher',
return func
setattr(LibraryDatabase, prop, MT(getter(prop)))
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_identifiers = MT(
lambda self, index, index_is_id=False: self.new_api.field_for('identifiers', index if index_is_id else self.data.index_to_id(index)))
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))
# }}}
# Legacy setter API {{{

View File

@ -161,6 +161,10 @@ class LegacyTest(BaseTest):
'get_next_series_num_for': [('A Series One',)],
'author_sort_from_authors': [(['Author One', 'Author Two', 'Unknown'],)],
'has_book':[(Metadata('title one'),), (Metadata('xxxx1111'),)],
'has_id':[(1,), (2,), (3,), (9999,)],
'id':[(1,), (2,), (0,),],
'index':[(1,), (2,), (3,), ],
'is_empty':[()],
'all_author_names':[()],
'all_tag_names':[()],
'all_series_names':[()],
@ -332,7 +336,7 @@ class LegacyTest(BaseTest):
'construct_path_name', 'clear_dirtied', 'commit_dirty_cache', 'initialize_database', 'initialize_dynamic',
'run_import_plugins', 'vacuum', 'set_path', 'row', 'row_factory', 'rows', 'rmtree', 'series_index_pat',
'import_old_database', 'dirtied_lock', 'dirtied_cache', 'dirty_queue_length', 'dirty_books_referencing',
'windows_check_if_files_in_use', 'get_metadata_for_dump', 'get_a_dirtied_book',
'windows_check_if_files_in_use', 'get_metadata_for_dump', 'get_a_dirtied_book', 'dirtied_sequence',
}
SKIP_ARGSPEC = {
'__init__',
@ -432,7 +436,7 @@ class LegacyTest(BaseTest):
('set_author_sort', 3, 'new_aus'),
('set_comment', 1, ''), ('set_comment', 2, None), ('set_comment', 3, '<p>a comment</p>'),
('set_has_cover', 1, True), ('set_has_cover', 2, True), ('set_has_cover', 3, 1),
('set_identifiers', 2, {'test':'', 'a':'b'}), ('set_identifiers', 3, {'id':'1', 'url':'http://acme.com'}), ('set_identifiers', 1, {}),
('set_identifiers', 2, {'test':'', 'a':'b'}), ('set_identifiers', 3, {'id':'1', 'isbn':'9783161484100'}), ('set_identifiers', 1, {}),
('set_languages', 1, ('en',)),
('set_languages', 2, ()),
('set_languages', 3, ('deu', 'spa', 'fra')),
@ -458,6 +462,7 @@ class LegacyTest(BaseTest):
('series', 0), ('series', 1), ('series', 2),
('series_index', 0), ('series_index', 1), ('series_index', 2),
('uuid', 0), ('uuid', 1), ('uuid', 2),
('isbn', 0), ('isbn', 1), ('isbn', 2),
('@tags', 0), ('@tags', 1), ('@tags', 2),
('@all_tags',),
('@get_all_identifier_types',),
@ -516,3 +521,4 @@ class LegacyTest(BaseTest):
# }}}

View File

@ -161,6 +161,9 @@ class View(object):
def index_to_id(self, idx):
return self._map_filtered[idx]
def id_to_index(self, book_id):
return self._map.index(book_id)
def _get(self, field, idx, index_is_id=True, default_value=None, fmt=lambda x:x):
id_ = idx if index_is_id else self.index_to_id(idx)
if index_is_id and id_ not in self.cache.all_book_ids():