conversion_options API

This commit is contained in:
Kovid Goyal 2013-07-13 10:03:31 +05:30
parent 309813c8e0
commit 9ea6e0d2a9
5 changed files with 91 additions and 2 deletions

View File

@ -8,7 +8,7 @@ __copyright__ = '2011, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'
# Imports {{{ # Imports {{{
import os, shutil, uuid, json, glob, time import os, shutil, uuid, json, glob, time, cPickle
from functools import partial from functools import partial
import apsw import apsw
@ -1216,5 +1216,27 @@ class DB(object):
def get_ids_for_custom_book_data(self, name): def get_ids_for_custom_book_data(self, name):
return frozenset(r[0] for r in self.conn.execute('SELECT book FROM books_plugin_data WHERE name=?', (name,))) return frozenset(r[0] for r in self.conn.execute('SELECT book FROM books_plugin_data WHERE name=?', (name,)))
def conversion_options(self, book_id, fmt):
for (data,) in self.conn.get('SELECT data FROM conversion_options WHERE book=? AND format=?', (book_id, fmt.upper())):
if data:
return cPickle.loads(bytes(data))
def has_conversion_options(self, ids, fmt='PIPE'):
ids = frozenset(ids)
self.conn.execute('DROP TABLE IF EXISTS conversion_options_temp; CREATE TEMP TABLE conversion_options_temp (id INTEGER PRIMARY KEY);')
self.conn.executemany('INSERT INTO conversion_options_temp VALUES (?)', [(x,) for x in ids])
for (book_id,) in self.conn.get(
'SELECT book FROM conversion_options WHERE format=? AND book IN (SELECT id FROM conversion_options_temp)', (fmt.upper(),)):
return True
return False
def delete_conversion_options(self, book_ids, fmt):
self.conn.executemany('DELETE FROM conversion_options WHERE book=? AND format=?',
[(book_id, fmt.upper()) for book_id in book_ids])
def set_conversion_options(self, options, fmt):
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)
# }}} # }}}

View File

@ -1208,6 +1208,22 @@ class Cache(object):
''' Return the set of book ids for which name has data. ''' ''' Return the set of book ids for which name has data. '''
return self.backend.get_ids_for_custom_book_data(name) return self.backend.get_ids_for_custom_book_data(name)
@read_api
def conversion_options(self, book_id, fmt='PIPE'):
return self.backend.conversion_options(book_id, fmt)
@read_api
def has_conversion_options(self, ids, fmt='PIPE'):
return self.backend.has_conversion_options(ids, fmt)
@write_api
def delete_conversion_options(self, book_ids, fmt='PIPE'):
return self.backend.delete_conversion_options(book_ids, fmt)
@write_api
def set_conversion_options(self, options, fmt='PIPE'):
''' options must be a map of the form {book_id:conversion_options} '''
return self.backend.set_conversion_options(options, fmt)
# }}} # }}}

View File

@ -383,6 +383,18 @@ class LibraryDatabase(object):
break break
return ans return ans
def set_conversion_options(self, book_id, fmt, options):
self.new_api.set_conversion_options({book_id:options}, fmt=fmt)
def conversion_options(self, book_id, fmt):
return self.new_api.conversion_options(book_id, fmt=fmt)
def has_conversion_options(self, ids, format='PIPE'):
return self.new_api.has_conversion_options(ids, fmt=format)
def delete_conversion_options(self, book_id, fmt, commit=True):
self.new_api.delete_conversion_options((book_id,), fmt=fmt)
# Private interface {{{ # Private interface {{{
def __iter__(self): def __iter__(self):
for row in self.data.iterall(): for row in self.data.iterall():

View File

@ -191,6 +191,27 @@ class LegacyTest(BaseTest):
db.close() db.close()
# }}} # }}}
def test_legacy_conversion_options(self): # {{{
'Test conversion options API'
ndb = self.init_legacy()
db = self.init_old()
all_ids = ndb.new_api.all_book_ids()
op1, op2 = {'xx':'yy'}, {'yy':'zz'}
for x in (
('has_conversion_options', all_ids),
('conversion_options', 1, 'PIPE'),
('set_conversion_options', 1, 'PIPE', op1),
('has_conversion_options', all_ids),
('conversion_options', 1, 'PIPE'),
('delete_conversion_options', 1, 'PIPE'),
('has_conversion_options', all_ids),
):
meth, args = x[0], x[1:]
self.assertEqual((getattr(db, meth)(*args)), (getattr(ndb, meth)(*args)),
'The method: %s() returned different results for argument %s' % (meth, args))
db.close()
# }}}
def test_legacy_adding_books(self): # {{{ def test_legacy_adding_books(self): # {{{
'Test various adding books methods' 'Test various adding books methods'
from calibre.ebooks.metadata.book.base import Metadata from calibre.ebooks.metadata.book.base import Metadata
@ -271,7 +292,8 @@ class LegacyTest(BaseTest):
# Internal API # Internal API
'clean_user_categories', 'cleanup_tags', 'books_list_filter', 'conn', 'connect', 'construct_file_name', 'clean_user_categories', 'cleanup_tags', 'books_list_filter', 'conn', 'connect', 'construct_file_name',
'construct_path_name', 'clear_dirtied', 'commit_dirty_cache', 'initialize_database', 'initialize_dynamic', 'construct_path_name', 'clear_dirtied', 'commit_dirty_cache', 'initialize_database', 'initialize_dynamic',
'run_import_plugins', 'run_import_plugins', 'vacuum', 'set_path', 'row', 'row_factory', 'rows', 'rmtree', 'series_index_pat',
'import_old_database', 'dirtied_lock', 'dirtied_cache', 'dirty_queue_length',
} }
SKIP_ARGSPEC = { SKIP_ARGSPEC = {
'__init__', 'get_next_series_num_for', 'has_book', 'author_sort_from_authors', '__init__', 'get_next_series_num_for', 'has_book', 'author_sort_from_authors',

View File

@ -419,3 +419,20 @@ class WritingTest(BaseTest):
# }}} # }}}
def test_conversion_options(self): # {{{
' Test saving of conversion options '
cache = self.init_cache()
all_ids = cache.all_book_ids()
self.assertFalse(cache.has_conversion_options(all_ids))
self.assertIsNone(cache.conversion_options(1))
op1, op2 = {'xx':'yy'}, {'yy':'zz'}
cache.set_conversion_options({1:op1, 2:op2})
self.assertTrue(cache.has_conversion_options(all_ids))
self.assertEqual(cache.conversion_options(1), op1)
self.assertEqual(cache.conversion_options(2), op2)
cache.set_conversion_options({1:op2})
self.assertEqual(cache.conversion_options(1), op2)
cache.delete_conversion_options(all_ids)
self.assertFalse(cache.has_conversion_options(all_ids))
# }}}