mirror of
https://github.com/ankitects/anki.git
synced 2025-09-24 16:56:36 -04:00
store profiles as blobs
the cPickle data may not be valid utf8, and even with text_factory=str this seems to cause problems sometimes
This commit is contained in:
parent
47521cff9a
commit
89a5777585
2 changed files with 20 additions and 23 deletions
|
@ -17,13 +17,11 @@ except ImportError:
|
||||||
Error = sqlite.Error
|
Error = sqlite.Error
|
||||||
|
|
||||||
class DB(object):
|
class DB(object):
|
||||||
def __init__(self, path, text=None, timeout=0):
|
def __init__(self, path, timeout=0):
|
||||||
encpath = path
|
encpath = path
|
||||||
if isinstance(encpath, unicode):
|
if isinstance(encpath, unicode):
|
||||||
encpath = path.encode("utf-8")
|
encpath = path.encode("utf-8")
|
||||||
self._db = sqlite.connect(encpath, timeout=timeout)
|
self._db = sqlite.connect(encpath, timeout=timeout)
|
||||||
if text:
|
|
||||||
self._db.text_factory = text
|
|
||||||
self._path = path
|
self._path = path
|
||||||
self.echo = os.environ.get("DBECHO")
|
self.echo = os.environ.get("DBECHO")
|
||||||
self.mod = False
|
self.mod = False
|
||||||
|
|
|
@ -74,6 +74,9 @@ class ProfileManager(object):
|
||||||
self.firstRun = self._loadMeta()
|
self.firstRun = self._loadMeta()
|
||||||
# did the user request a profile to start up with?
|
# did the user request a profile to start up with?
|
||||||
if profile:
|
if profile:
|
||||||
|
if profile not in self.profiles():
|
||||||
|
QMessageBox.critical(None, "Error", "Requested profile does not exist.")
|
||||||
|
sys.exit(1)
|
||||||
try:
|
try:
|
||||||
self.load(profile)
|
self.load(profile)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
|
@ -99,15 +102,13 @@ a flash drive.""" % self.base)
|
||||||
######################################################################
|
######################################################################
|
||||||
|
|
||||||
def profiles(self):
|
def profiles(self):
|
||||||
return sorted(
|
return sorted(x for x in
|
||||||
unicode(x, "utf8") for x in
|
|
||||||
self.db.list("select name from profiles")
|
self.db.list("select name from profiles")
|
||||||
if x != "_global")
|
if x != "_global")
|
||||||
|
|
||||||
def load(self, name, passwd=None):
|
def load(self, name, passwd=None):
|
||||||
prof = cPickle.loads(
|
data = self.db.scalar("select cast(data as blob) from profiles where name = ?", name)
|
||||||
self.db.scalar("select data from profiles where name = ?",
|
prof = cPickle.loads(str(data))
|
||||||
name.encode("utf8")))
|
|
||||||
if prof['key'] and prof['key'] != self._pwhash(passwd):
|
if prof['key'] and prof['key'] != self._pwhash(passwd):
|
||||||
self.name = None
|
self.name = None
|
||||||
return False
|
return False
|
||||||
|
@ -118,23 +119,21 @@ a flash drive.""" % self.base)
|
||||||
|
|
||||||
def save(self):
|
def save(self):
|
||||||
sql = "update profiles set data = ? where name = ?"
|
sql = "update profiles set data = ? where name = ?"
|
||||||
self.db.execute(sql, cPickle.dumps(self.profile),
|
self.db.execute(sql, buffer(cPickle.dumps(self.profile)), self.name)
|
||||||
self.name.encode("utf8"))
|
self.db.execute(sql, buffer(cPickle.dumps(self.meta)), "_global")
|
||||||
self.db.execute(sql, cPickle.dumps(self.meta), "_global")
|
|
||||||
self.db.commit()
|
self.db.commit()
|
||||||
|
|
||||||
def create(self, name):
|
def create(self, name):
|
||||||
prof = profileConf.copy()
|
prof = profileConf.copy()
|
||||||
self.db.execute("insert into profiles values (?, ?)",
|
self.db.execute("insert into profiles values (?, ?)",
|
||||||
name.encode("utf8"), cPickle.dumps(prof))
|
name, buffer(cPickle.dumps(prof)))
|
||||||
self.db.commit()
|
self.db.commit()
|
||||||
|
|
||||||
def remove(self, name):
|
def remove(self, name):
|
||||||
p = self.profileFolder()
|
p = self.profileFolder()
|
||||||
if os.path.exists(p):
|
if os.path.exists(p):
|
||||||
send2trash(p)
|
send2trash(p)
|
||||||
self.db.execute("delete from profiles where name = ?",
|
self.db.execute("delete from profiles where name = ?", name)
|
||||||
name.encode("utf8"))
|
|
||||||
self.db.commit()
|
self.db.commit()
|
||||||
|
|
||||||
def rename(self, name):
|
def rename(self, name):
|
||||||
|
@ -163,7 +162,7 @@ a flash drive.""" % self.base)
|
||||||
|
|
||||||
# update name
|
# update name
|
||||||
self.db.execute("update profiles set name = ? where name = ?",
|
self.db.execute("update profiles set name = ? where name = ?",
|
||||||
name.encode("utf8"), oldName.encode("utf-8"))
|
name, oldName)
|
||||||
# rename folder
|
# rename folder
|
||||||
try:
|
try:
|
||||||
os.rename(oldFolder, newFolder)
|
os.rename(oldFolder, newFolder)
|
||||||
|
@ -253,7 +252,7 @@ and no other programs are accessing your profile folders, then try again."""))
|
||||||
Anki's prefs.db file was corrupt and has been recreated. If you were using multiple \
|
Anki's prefs.db file was corrupt and has been recreated. If you were using multiple \
|
||||||
profiles, please add them back using the same names to recover your cards.""")
|
profiles, please add them back using the same names to recover your cards.""")
|
||||||
try:
|
try:
|
||||||
self.db = DB(path, text=str)
|
self.db = DB(path)
|
||||||
self.db.execute("""
|
self.db.execute("""
|
||||||
create table if not exists profiles
|
create table if not exists profiles
|
||||||
(name text primary key, data text not null);""")
|
(name text primary key, data text not null);""")
|
||||||
|
@ -263,9 +262,9 @@ create table if not exists profiles
|
||||||
if not new:
|
if not new:
|
||||||
# load previously created
|
# load previously created
|
||||||
try:
|
try:
|
||||||
self.meta = cPickle.loads(
|
data = self.db.scalar(
|
||||||
self.db.scalar(
|
"select cast(data as blob) from profiles where name = '_global'")
|
||||||
"select data from profiles where name = '_global'"))
|
self.meta = cPickle.loads(str(data))
|
||||||
return
|
return
|
||||||
except:
|
except:
|
||||||
recover()
|
recover()
|
||||||
|
@ -273,7 +272,7 @@ create table if not exists profiles
|
||||||
# create a default global profile
|
# create a default global profile
|
||||||
self.meta = metaConf.copy()
|
self.meta = metaConf.copy()
|
||||||
self.db.execute("insert or replace into profiles values ('_global', ?)",
|
self.db.execute("insert or replace into profiles values ('_global', ?)",
|
||||||
cPickle.dumps(metaConf))
|
buffer(cPickle.dumps(metaConf)))
|
||||||
self._setDefaultLang()
|
self._setDefaultLang()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@ -351,6 +350,6 @@ please see:
|
||||||
def setLang(self, code):
|
def setLang(self, code):
|
||||||
self.meta['defaultLang'] = code
|
self.meta['defaultLang'] = code
|
||||||
sql = "update profiles set data = ? where name = ?"
|
sql = "update profiles set data = ? where name = ?"
|
||||||
self.db.execute(sql, cPickle.dumps(self.meta), "_global")
|
self.db.execute(sql, buffer(cPickle.dumps(self.meta)), "_global")
|
||||||
self.db.commit()
|
self.db.commit()
|
||||||
anki.lang.setLang(code, local=False)
|
anki.lang.setLang(code, local=False)
|
||||||
|
|
Loading…
Reference in a new issue