Format manipulation API

This commit is contained in:
Kovid Goyal 2013-07-18 16:33:24 +05:30
parent 76045d2a54
commit 51620932a8
5 changed files with 85 additions and 2 deletions

View File

@ -607,6 +607,31 @@ class Cache(object):
return False
return self.backend.has_format(book_id, fmt, name, path)
@api
def save_original_format(self, book_id, fmt):
fmt = fmt.upper()
if 'ORIGINAL' in fmt:
raise ValueError('Cannot save original of an original fmt')
fmtfile = self.format(book_id, fmt, as_file=True)
if fmtfile is None:
return False
with fmtfile:
nfmt = 'ORIGINAL_'+fmt
return self.add_format(book_id, nfmt, fmtfile, run_hooks=False)
@api
def restore_original_format(self, book_id, original_fmt):
original_fmt = original_fmt.upper()
fmtfile = self.format(book_id, original_fmt, as_file=True)
if fmtfile is not None:
fmt = original_fmt.partition('_')[2]
with self.write_lock:
with fmtfile:
self._add_format(book_id, fmt, fmtfile, run_hooks=False)
self._remove_formats({book_id:(original_fmt,)})
return True
return False
@read_api
def formats(self, book_id, verify_formats=True):
'''

View File

@ -674,6 +674,28 @@ class LibraryDatabase(object):
if notify:
self.notify('cover', [book_id])
def original_fmt(self, book_id, fmt):
nfmt = ('ORIGINAL_%s'%fmt).upper()
return nfmt if self.new_api.has_format(book_id, nfmt) else fmt
def save_original_format(self, book_id, fmt, notify=True):
ret = self.new_api.save_original_format(book_id, fmt)
if ret and notify:
self.notify('metadata', [book_id])
return ret
def restore_original_format(self, book_id, original_fmt, notify=True):
ret = self.new_api.restore_original_format(book_id, original_fmt)
if ret and notify:
self.notify('metadata', [book_id])
return ret
def remove_format(self, index, fmt, index_is_id=False, notify=True, commit=True, db_only=False):
book_id = index if index_is_id else self.id(index)
self.new_api.remove_formats({book_id:(fmt,)}, db_only=db_only)
if notify:
self.notify('metadata', [book_id])
# Private interface {{{
def __iter__(self):
for row in self.data.iterall():

View File

@ -251,4 +251,21 @@ class AddRemoveTest(BaseTest):
# }}}
def test_original_fmt(self): # {{{
' Test management of original fmt '
af, ae, at = self.assertFalse, self.assertEqual, self.assertTrue
db = self.init_cache()
fmts = db.formats(1)
af(db.has_format(1, 'ORIGINAL_FMT1'))
at(db.save_original_format(1, 'FMT1'))
at(db.has_format(1, 'ORIGINAL_FMT1'))
raw = db.format(1, 'FMT1')
ae(raw, db.format(1, 'ORIGINAL_FMT1'))
db.add_format(1, 'FMT1', BytesIO(b'replacedfmt'))
self.assertNotEqual(db.format(1, 'FMT1'), db.format(1, 'ORIGINAL_FMT1'))
at(db.restore_original_format(1, 'ORIGINAL_FMT1'))
ae(raw, db.format(1, 'FMT1'))
af(db.has_format(1, 'ORIGINAL_FMT1'))
ae(set(fmts), set(db.formats(1, verify_formats=False)))
# }}}

View File

@ -49,10 +49,10 @@ def run_funcs(self, db, ndb, funcs):
meth(*args)
else:
fmt = lambda x:x
if meth[0] in {'!', '@', '#', '+', '$', '-'}:
if meth[0] in {'!', '@', '#', '+', '$', '-', '%'}:
if meth[0] != '+':
fmt = {'!':dict, '@':lambda x:frozenset(x or ()), '#':lambda x:set((x or '').split(',')),
'$':lambda x:set(tuple(y) for y in x), '-':lambda x:None}[meth[0]]
'$':lambda x:set(tuple(y) for y in x), '-':lambda x:None, '%':lambda x: set((x or '').split(','))}[meth[0]]
else:
fmt = args[-1]
args = args[:-1]
@ -357,6 +357,10 @@ class LegacyTest(BaseTest):
self.assertEqual(legacy.cover(3, index_is_id=True), origcov)
self.assertTrue(legacy.has_cover(3))
self.assertTrue(legacy.format(1, 'FMT1', index_is_id=True))
legacy.remove_format(1, 'FMT1', index_is_id=True)
self.assertIsNone(legacy.format(1, 'FMT1', index_is_id=True))
legacy.delete_book(1)
old.delete_book(1)
self.assertNotIn(1, legacy.all_ids())
@ -726,3 +730,16 @@ class LegacyTest(BaseTest):
self.assertRaises(KeyError, ndb.custom_field_name, num=num)
# }}}
def test_legacy_original_fmt(self): # {{{
db, ndb = self.init_old(), self.init_legacy()
run_funcs(self, db, ndb, (
('original_fmt', 1, 'FMT1'),
('save_original_format', 1, 'FMT1'),
('original_fmt', 1, 'FMT1'),
('restore_original_format', 1, 'ORIGINAL_FMT1'),
('original_fmt', 1, 'FMT1'),
('%formats', 1, True),
))
db.close()
# }}}

View File

@ -1570,6 +1570,8 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
with lopen(opath, 'rb') as f:
self.add_format(book_id, fmt, f, index_is_id=True, notify=False)
self.remove_format(book_id, original_fmt, index_is_id=True, notify=notify)
return True
return False
def delete_book(self, id, notify=True, commit=True, permanent=False,
do_clean=True):