API coverage is now 100%

This commit is contained in:
Kovid Goyal 2013-07-19 12:11:07 +05:30
parent 34704c9735
commit 467dcf1a87
6 changed files with 89 additions and 2 deletions

View File

@ -1452,6 +1452,59 @@ class DB(object):
options = [(book_id, fmt.upper(), buffer(cPickle.dumps(data, -1))) for book_id, data in options.iteritems()]
self.conn.executemany('INSERT OR REPLACE INTO conversion_options(book,format,data) VALUES (?,?,?)', options)
def get_top_level_move_items(self, all_paths):
items = set(os.listdir(self.library_path))
paths = set(all_paths)
paths.update({'metadata.db', 'metadata_db_prefs_backup.json'})
path_map = {x:x for x in paths}
if not self.is_case_sensitive:
for x in items:
path_map[x.lower()] = x
items = set(path_map)
paths = {x.lower() for x in paths}
items = items.intersection(paths)
return items, path_map
def move_library_to(self, all_paths, newloc, progress=lambda x: x):
if not os.path.exists(newloc):
os.makedirs(newloc)
old_dirs = set()
items, path_map = self.get_top_level_move_items(all_paths)
for x in items:
src = os.path.join(self.library_path, x)
dest = os.path.join(newloc, path_map[x])
if os.path.isdir(src):
if os.path.exists(dest):
shutil.rmtree(dest)
shutil.copytree(src, dest)
old_dirs.add(src)
else:
if os.path.exists(dest):
os.remove(dest)
shutil.copyfile(src, dest)
x = path_map[x]
if not isinstance(x, unicode):
x = x.decode(filesystem_encoding, 'replace')
progress(x)
dbpath = os.path.join(newloc, os.path.basename(self.dbpath))
opath = self.dbpath
self.conn.close()
self.library_path, self.dbpath = newloc, dbpath
if self._conn is not None:
self._conn.close()
self._conn = None
self.conn
try:
os.unlink(opath)
except:
pass
for loc in old_dirs:
try:
shutil.rmtree(loc)
except:
pass
# }}}

View File

@ -1504,6 +1504,18 @@ class Cache(object):
identical_book_ids.add(book_id)
return identical_book_ids
@read_api
def get_top_level_move_items(self):
all_paths = {self._field_for('path', book_id).partition('/')[0] for book_id in self._all_book_ids()}
return self.backend.get_top_level_move_items(all_paths)
@write_api
def move_library_to(self, newloc, progress=None):
if progress is None:
progress = lambda x:x
all_paths = {self._field_for('path', book_id).partition('/')[0] for book_id in self._all_book_ids()}
self.backend.move_library_to(all_paths, newloc, progress=progress)
# }}}
class SortKey(object): # {{{

View File

@ -747,6 +747,7 @@ LibraryDatabase.get_books_for_category = MT(
lambda self, category, id_:self.new_api.get_books_for_category(category, id_))
LibraryDatabase.get_data_as_dict = MT(get_data_as_dict)
LibraryDatabase.find_identical_books = MT(lambda self, mi:self.new_api.find_identical_books(mi))
LibraryDatabase.get_top_level_move_items = MT(lambda self:self.new_api.get_top_level_move_items())
# }}}
# Legacy setter API {{{
@ -878,6 +879,7 @@ for meth in ('get_next_series_num_for', 'has_book', 'author_sort_from_authors'):
return func
setattr(LibraryDatabase, meth, MT(getter(meth)))
LibraryDatabase.move_library_to = MT(lambda self, newloc, progress=None:self.new_api.move_library_to(newloc, progress=progress))
# Cleaning is not required anymore
LibraryDatabase.clean = LibraryDatabase.clean_custom = MT(lambda self:None)
LibraryDatabase.clean_standard_field = MT(lambda self, field, commit=False:None)

View File

@ -79,4 +79,21 @@ class FilesystemTest(BaseTest):
f.close()
self.assertNotEqual(cache.field_for('title', 1), 'Moved', 'Title was changed despite file lock')
def test_library_move(self):
' Test moving of library '
from calibre.ptempfile import TemporaryDirectory
cache = self.init_cache()
self.assertIn('metadata.db', cache.get_top_level_move_items()[0])
all_ids = cache.all_book_ids()
fmt1 = cache.format(1, 'FMT1')
cov = cache.cover(1)
with TemporaryDirectory('moved_lib') as tdir:
cache.move_library_to(tdir)
self.assertIn('moved_lib', cache.backend.library_path)
self.assertIn('moved_lib', cache.backend.dbpath)
cache.reload_from_db()
self.assertEqual(all_ids, cache.all_book_ids())
self.assertEqual(fmt1, cache.format(1, 'FMT1'))
self.assertEqual(cov, cache.cover(1))
cache.backend.close()

View File

@ -167,6 +167,7 @@ class LegacyTest(BaseTest):
for meth, args in {
'find_identical_books': [(Metadata('title one', ['author one']),), (Metadata('unknown'),), (Metadata('xxxx'),)],
'get_top_level_move_items': [()],
'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),)],

View File

@ -3561,7 +3561,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
path = self.path(x, index_is_id=True)
path = path.split(os.sep)[0]
paths.add(path)
paths.add('metadata.db')
paths.update({'metadata.db', 'metadata_db_prefs_backup.json'})
path_map = {}
for x in paths:
path_map[x] = x
@ -3573,7 +3573,9 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
items = items.intersection(paths)
return items, path_map
def move_library_to(self, newloc, progress=lambda x: x):
def move_library_to(self, newloc, progress=None):
if progress is None:
progress = lambda x:x
if not os.path.exists(newloc):
os.makedirs(newloc)
old_dirs = set([])