Merge from trunk

This commit is contained in:
Charles Haley 2010-07-18 21:11:07 +01:00
commit a3d8ce4850
6 changed files with 111 additions and 23 deletions

View File

@ -218,9 +218,10 @@ class BooksView(QTableView): # {{{
# Only save if we have been initialized (set_database called) # Only save if we have been initialized (set_database called)
if len(self.column_map) > 0 and self.was_restored: if len(self.column_map) > 0 and self.was_restored:
state = self.get_state() state = self.get_state()
db = getattr(self.model(), 'db', None)
name = unicode(self.objectName()) name = unicode(self.objectName())
if name: if name and db is not None:
gprefs.set(name + ' books view state', state) db.prefs.set(name + ' books view state', state)
def cleanup_sort_history(self, sort_history): def cleanup_sort_history(self, sort_history):
history = [] history = []
@ -298,11 +299,27 @@ class BooksView(QTableView): # {{{
old_state['column_sizes'][name] += 12 old_state['column_sizes'][name] += 12
return old_state return old_state
def restore_state(self): def get_old_state(self):
ans = None
name = unicode(self.objectName()) name = unicode(self.objectName())
old_state = None
if name: if name:
old_state = gprefs.get(name + ' books view state', None) name += ' books view state'
db = getattr(self.model(), 'db', None)
if db is not None:
ans = db.prefs.get(name, None)
if ans is None:
ans = gprefs.get(name, None)
try:
del gprefs[name]
except:
pass
if ans is not None:
db.prefs[name] = ans
return ans
def restore_state(self):
old_state = self.get_old_state()
if old_state is None: if old_state is None:
old_state = self.get_default_state() old_state = self.get_default_state()

View File

@ -19,6 +19,7 @@ from calibre.library.schema_upgrades import SchemaUpgrade
from calibre.library.caches import ResultCache from calibre.library.caches import ResultCache
from calibre.library.custom_columns import CustomColumns from calibre.library.custom_columns import CustomColumns
from calibre.library.sqlite import connect, IntegrityError, DBThread from calibre.library.sqlite import connect, IntegrityError, DBThread
from calibre.library.prefs import DBPrefs
from calibre.ebooks.metadata import string_to_authors, authors_to_string, \ from calibre.ebooks.metadata import string_to_authors, authors_to_string, \
MetaInformation MetaInformation
from calibre.ebooks.metadata.meta import get_metadata, metadata_from_formats from calibre.ebooks.metadata.meta import get_metadata, metadata_from_formats
@ -140,6 +141,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
self.initialize_dynamic() self.initialize_dynamic()
def initialize_dynamic(self): def initialize_dynamic(self):
self.prefs = DBPrefs(self)
self.conn.executescript(''' self.conn.executescript('''
DROP TRIGGER IF EXISTS author_insert_trg; DROP TRIGGER IF EXISTS author_insert_trg;
CREATE TEMP TRIGGER author_insert_trg CREATE TEMP TRIGGER author_insert_trg

View File

@ -0,0 +1,49 @@
#!/usr/bin/env python
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
__license__ = 'GPL v3'
__copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en'
import json
from calibre.constants import preferred_encoding
from calibre.utils.config import to_json, from_json
class DBPrefs(dict):
def __init__(self, db):
dict.__init__(self)
self.db = db
for key, val in self.db.conn.get('SELECT key,val FROM preferences'):
val = self.raw_to_object(val)
dict.__setitem__(self, key, val)
def raw_to_object(self, raw):
if not isinstance(raw, unicode):
raw = raw.decode(preferred_encoding)
return json.loads(raw, object_hook=from_json)
def to_raw(self, val):
return json.dumps(val, indent=2, default=to_json)
def __getitem__(self, key):
return dict.__getitem__(self, key)
def __delitem__(self, key):
dict.__delitem__(self, key)
self.db.conn.execute('DELETE FROM preferences WHERE key=?', (key,))
self.db.conn.commit()
def __setitem__(self, key, val):
raw = self.to_raw(val)
self.db.conn.execute('DELETE FROM preferences WHERE key=?', (key,))
self.db.conn.execute('INSERT INTO preferences (key,val) VALUES (?,?)', (key,
raw))
self.db.conn.commit()
dict.__setitem__(self, key, val)
def set(self, key, val):
self.__setitem__(key, val)

View File

@ -387,3 +387,14 @@ class SchemaUpgrade(object):
self.conn.execute('UPDATE authors SET sort=author_to_author_sort(name)') self.conn.execute('UPDATE authors SET sort=author_to_author_sort(name)')
def upgrade_version_12(self):
'DB based preference store'
script = '''
DROP TABLE IF EXISTS preferences;
CREATE TABLE preferences(id INTEGER PRIMARY KEY,
key TEXT NON NULL,
val TEXT NON NULL,
UNIQUE(key));
'''
self.conn.executescript(script)

View File

@ -66,7 +66,7 @@ and save it to a new file.
""" """
import ctypes, sys, os import ctypes, sys, os, glob
from ctypes import util from ctypes import util
iswindows = 'win32' in sys.platform or 'win64' in sys.platform iswindows = 'win32' in sys.platform or 'win64' in sys.platform
isosx = 'darwin' in sys.platform isosx = 'darwin' in sys.platform
@ -85,7 +85,8 @@ elif iswindows:
_lib = flib if isfrozen else 'CORE_RL_wand_' _lib = flib if isfrozen else 'CORE_RL_wand_'
else: else:
if isfrozen: if isfrozen:
_lib = os.path.join(sys.frozen_path, 'libMagickWand.so.2') _lib = glob.glob(os.path.join(sys.frozen_path,
'libMagickWand.so.*'))[-1]
else: else:
_lib = util.find_library('MagickWand') _lib = util.find_library('MagickWand')
if _lib is None: if _lib is None:

View File

@ -6,15 +6,16 @@ __docformat__ = 'restructuredtext en'
''' '''
Manage application-wide preferences. Manage application-wide preferences.
''' '''
import os, re, cPickle, textwrap, traceback, plistlib, json, base64 import os, re, cPickle, textwrap, traceback, plistlib, json, base64, datetime
from copy import deepcopy from copy import deepcopy
from functools import partial from functools import partial
from optparse import OptionParser as _OptionParser from optparse import OptionParser as _OptionParser
from optparse import IndentedHelpFormatter from optparse import IndentedHelpFormatter
from collections import defaultdict
from calibre.constants import terminal_controller, iswindows, isosx, \ from calibre.constants import terminal_controller, iswindows, isosx, \
__appname__, __version__, __author__, plugins __appname__, __version__, __author__, plugins
from calibre.utils.lock import LockError, ExclusiveFile from calibre.utils.lock import LockError, ExclusiveFile
from collections import defaultdict
if os.environ.has_key('CALIBRE_CONFIG_DIRECTORY'): if os.environ.has_key('CALIBRE_CONFIG_DIRECTORY'):
config_dir = os.path.abspath(os.environ['CALIBRE_CONFIG_DIRECTORY']) config_dir = os.path.abspath(os.environ['CALIBRE_CONFIG_DIRECTORY'])
@ -632,27 +633,34 @@ class XMLConfig(dict):
f.truncate() f.truncate()
f.write(raw) f.write(raw)
def to_json(obj):
if isinstance(obj, bytearray):
return {'__class__': 'bytearray',
'__value__': base64.standard_b64encode(bytes(obj))}
if isinstance(obj, datetime.datetime):
from calibre.utils.date import isoformat
return {'__class__': 'datetime.datetime',
'__value__': isoformat(obj, as_utc=True)}
raise TypeError(repr(obj) + ' is not JSON serializable')
def from_json(obj):
if '__class__' in obj:
if obj['__class__'] == 'bytearray':
return bytearray(base64.standard_b64decode(obj['__value__']))
if obj['__class__'] == 'datetime.datetime':
from calibre.utils.date import parse_date
return parse_date(obj['__value__'], assume_utc=True)
return obj
class JSONConfig(XMLConfig): class JSONConfig(XMLConfig):
EXTENSION = '.json' EXTENSION = '.json'
def to_json(self, obj):
if isinstance(obj, bytearray):
return {'__class__': 'bytearray',
'__value__': base64.standard_b64encode(bytes(obj))}
raise TypeError(repr(obj) + ' is not JSON serializable')
def from_json(self, obj):
if '__class__' in obj:
if obj['__class__'] == 'bytearray':
return bytearray(base64.standard_b64decode(obj['__value__']))
return obj
def raw_to_object(self, raw): def raw_to_object(self, raw):
return json.loads(raw.decode('utf-8'), object_hook=self.from_json) return json.loads(raw.decode('utf-8'), object_hook=from_json)
def to_raw(self): def to_raw(self):
return json.dumps(self, indent=2, default=self.to_json) return json.dumps(self, indent=2, default=to_json)
def __getitem__(self, key): def __getitem__(self, key):
return dict.__getitem__(self, key) return dict.__getitem__(self, key)