mirror of
https://github.com/ankitects/anki.git
synced 2025-09-22 16:02:23 -04:00
merge deck.qconf and deck.conf
This commit is contained in:
parent
a30836445e
commit
6a00419ebc
8 changed files with 47 additions and 57 deletions
22
anki/deck.py
22
anki/deck.py
|
@ -18,9 +18,8 @@ from anki.errors import AnkiError
|
|||
import anki.latex # sets up hook
|
||||
import anki.cards, anki.facts, anki.template, anki.cram, anki.find
|
||||
|
||||
# Settings related to queue building. These may be loaded without the rest of
|
||||
# the config to check due counts faster on mobile clients.
|
||||
defaultQconf = {
|
||||
defaultConf = {
|
||||
# scheduling options
|
||||
'groups': [],
|
||||
'newPerDay': 20,
|
||||
'newToday': [0, 0], # currentDay, count
|
||||
|
@ -31,10 +30,7 @@ defaultQconf = {
|
|||
'collapseTime': 1200,
|
||||
'repLim': 0,
|
||||
'timeLim': 600,
|
||||
}
|
||||
|
||||
# other options
|
||||
defaultConf = {
|
||||
# other config
|
||||
'nextPos': 1,
|
||||
'mediaURL': "",
|
||||
'fontFamilies': [
|
||||
|
@ -86,15 +82,13 @@ class _Deck(object):
|
|||
self.dty,
|
||||
self.syncName,
|
||||
self.lastSync,
|
||||
self.qconf,
|
||||
self.conf,
|
||||
models,
|
||||
groups,
|
||||
gconf,
|
||||
tags) = self.db.first("""
|
||||
select crt, mod, scm, dty, syncName, lastSync,
|
||||
qconf, conf, models, groups, gconf, tags from deck""")
|
||||
self.qconf = simplejson.loads(self.qconf)
|
||||
conf, models, groups, gconf, tags from deck""")
|
||||
self.conf = simplejson.loads(self.conf)
|
||||
self.models.load(models)
|
||||
self.groups.load(groups, gconf)
|
||||
|
@ -105,11 +99,9 @@ qconf, conf, models, groups, gconf, tags from deck""")
|
|||
self.mod = intTime() if mod is None else mod
|
||||
self.db.execute(
|
||||
"""update deck set
|
||||
crt=?, mod=?, scm=?, dty=?, syncName=?, lastSync=?,
|
||||
qconf=?, conf=?""",
|
||||
crt=?, mod=?, scm=?, dty=?, syncName=?, lastSync=?, conf=?""",
|
||||
self.crt, self.mod, self.scm, self.dty,
|
||||
self.syncName, self.lastSync,
|
||||
simplejson.dumps(self.qconf),
|
||||
simplejson.dumps(self.conf))
|
||||
self.models.flush()
|
||||
self.groups.flush()
|
||||
|
@ -165,9 +157,11 @@ qconf=?, conf=?""",
|
|||
return not self.syncingEnabled() or self.scm > self.lastSync
|
||||
|
||||
def setDirty(self):
|
||||
"Signal there are temp. suspended cards that need cleaning up on close."
|
||||
self.dty = True
|
||||
|
||||
def cleanup(self):
|
||||
"Unsuspend any temporarily suspended cards."
|
||||
if self.dty:
|
||||
self.sched.onClose()
|
||||
self.dty = False
|
||||
|
@ -338,7 +332,7 @@ qconf=?, conf=?""",
|
|||
return card
|
||||
|
||||
def randomNew(self):
|
||||
return self.qconf['newOrder'] == NEW_CARDS_RANDOM
|
||||
return self.conf['newOrder'] == NEW_CARDS_RANDOM
|
||||
|
||||
# Cards
|
||||
##########################################################################
|
||||
|
|
|
@ -49,7 +49,7 @@ class Scheduler(object):
|
|||
# put it in the learn queue
|
||||
card.queue = 1
|
||||
card.type = 1
|
||||
self.deck.qconf['newToday'][1] += 1
|
||||
self.deck.conf['newToday'][1] += 1
|
||||
if card.queue == 1:
|
||||
self._answerLrnCard(card, ease)
|
||||
elif card.queue == 2:
|
||||
|
@ -125,11 +125,11 @@ order by time desc limit 10)""")
|
|||
|
||||
def allCounts(self):
|
||||
"Return counts for all groups, without building queue."
|
||||
conf = self.deck.qconf['groups']
|
||||
conf = self.deck.conf['groups']
|
||||
if conf:
|
||||
self.deck.qconf['groups'] = []
|
||||
self.deck.conf['groups'] = []
|
||||
self._resetCounts()
|
||||
self.deck.qconf['groups'] = conf
|
||||
self.deck.conf['groups'] = conf
|
||||
return self.counts()
|
||||
|
||||
def _resetCounts(self):
|
||||
|
@ -232,7 +232,7 @@ from cards group by gid""", self.today):
|
|||
# FIXME: need to keep track of reps for timebox and new card introduction
|
||||
|
||||
def _resetNewCount(self):
|
||||
l = self.deck.qconf
|
||||
l = self.deck.conf
|
||||
if l['newToday'][0] != self.today:
|
||||
# it's a new day; reset counts
|
||||
l['newToday'] = [self.today, 0]
|
||||
|
@ -261,7 +261,7 @@ queue = 0 %s order by due limit %d""" % (self._groupLimit(),
|
|||
if self.newQueue:
|
||||
(id, due) = self.newQueue.pop()
|
||||
# move any siblings to the end?
|
||||
if self.deck.qconf['newTodayOrder'] == NEW_TODAY_ORD:
|
||||
if self.deck.conf['newTodayOrder'] == NEW_TODAY_ORD:
|
||||
n = len(self.newQueue)
|
||||
while self.newQueue and self.newQueue[-1][1] == due:
|
||||
self.newQueue.insert(0, self.newQueue.pop())
|
||||
|
@ -273,7 +273,7 @@ queue = 0 %s order by due limit %d""" % (self._groupLimit(),
|
|||
return id
|
||||
|
||||
def _updateNewCardRatio(self):
|
||||
if self.deck.qconf['newSpread'] == NEW_CARDS_DISTRIBUTE:
|
||||
if self.deck.conf['newSpread'] == NEW_CARDS_DISTRIBUTE:
|
||||
if self.newCount:
|
||||
self.newCardModulus = (
|
||||
(self.newCount + self.revCount) / self.newCount)
|
||||
|
@ -287,9 +287,9 @@ queue = 0 %s order by due limit %d""" % (self._groupLimit(),
|
|||
"True if it's time to display a new card when distributing."
|
||||
if not self.newCount:
|
||||
return False
|
||||
if self.deck.qconf['newSpread'] == NEW_CARDS_LAST:
|
||||
if self.deck.conf['newSpread'] == NEW_CARDS_LAST:
|
||||
return False
|
||||
elif self.deck.qconf['newSpread'] == NEW_CARDS_FIRST:
|
||||
elif self.deck.conf['newSpread'] == NEW_CARDS_FIRST:
|
||||
return True
|
||||
elif self.newCardModulus:
|
||||
return self.reps and self.reps % self.newCardModulus == 0
|
||||
|
@ -302,7 +302,7 @@ queue = 0 %s order by due limit %d""" % (self._groupLimit(),
|
|||
select count() from (select id from cards where
|
||||
queue = 1 %s and due < ? limit %d)""" % (
|
||||
self._groupLimit(), self.reportLimit),
|
||||
intTime() + self.deck.qconf['collapseTime'])
|
||||
intTime() + self.deck.conf['collapseTime'])
|
||||
|
||||
def _resetLrn(self):
|
||||
self.lrnQueue = self.deck.db.all("""
|
||||
|
@ -314,7 +314,7 @@ limit %d""" % (self._groupLimit(), self.reportLimit), lim=self.dayCutoff)
|
|||
if self.lrnQueue:
|
||||
cutoff = time.time()
|
||||
if collapse:
|
||||
cutoff += self.deck.qconf['collapseTime']
|
||||
cutoff += self.deck.conf['collapseTime']
|
||||
if self.lrnQueue[0][0] < cutoff:
|
||||
id = heappop(self.lrnQueue)[1]
|
||||
self.lrnCount -= 1
|
||||
|
@ -347,7 +347,7 @@ limit %d""" % (self._groupLimit(), self.reportLimit), lim=self.dayCutoff)
|
|||
card.due = int(time.time() + delay)
|
||||
heappush(self.lrnQueue, (card.due, card.id))
|
||||
# if it's due within the cutoff, increment count
|
||||
if delay <= self.deck.qconf['collapseTime']:
|
||||
if delay <= self.deck.conf['collapseTime']:
|
||||
self.lrnCount += 1
|
||||
self._logLrn(card, ease, conf, leaving, type)
|
||||
|
||||
|
@ -440,7 +440,7 @@ select id from cards where
|
|||
queue = 2 %s and due <= :lim order by %s limit %d""" % (
|
||||
self._groupLimit(), self._revOrder(), self.queueLimit),
|
||||
lim=self.today)
|
||||
if self.deck.qconf['revOrder'] == REV_CARDS_RANDOM:
|
||||
if self.deck.conf['revOrder'] == REV_CARDS_RANDOM:
|
||||
r = random.Random()
|
||||
r.seed(self.today)
|
||||
r.shuffle(self.revQueue)
|
||||
|
@ -461,7 +461,7 @@ queue = 2 %s and due <= :lim order by %s limit %d""" % (
|
|||
def _revOrder(self):
|
||||
return ("ivl desc",
|
||||
"ivl",
|
||||
"due")[self.deck.qconf['revOrder']]
|
||||
"due")[self.deck.conf['revOrder']]
|
||||
|
||||
# Answering a review card
|
||||
##########################################################################
|
||||
|
@ -598,7 +598,7 @@ queue = 2 %s and due <= :lim order by %s limit %d""" % (
|
|||
return self.deck.groups.conf(card.gid)
|
||||
|
||||
def _groupLimit(self):
|
||||
l = self.deck.qconf['groups']
|
||||
l = self.deck.conf['groups']
|
||||
if not l:
|
||||
# everything
|
||||
return ""
|
||||
|
@ -630,7 +630,7 @@ queue = 2 %s and due <= :lim order by %s limit %d""" % (
|
|||
self._nextDueMsg())
|
||||
|
||||
def _finishedSubtitle(self):
|
||||
if self.deck.qconf['groups']:
|
||||
if self.deck.conf['groups']:
|
||||
return _("You have finished the selected groups for now.")
|
||||
else:
|
||||
return _("You have finished the deck for now.")
|
||||
|
@ -670,7 +670,7 @@ queue = 2 %s and due <= :lim order by %s limit %d""" % (
|
|||
|
||||
def newTomorrow(self):
|
||||
"Number of new cards tomorrow."
|
||||
lim = self.deck.qconf['newPerDay']
|
||||
lim = self.deck.conf['newPerDay']
|
||||
return self.deck.db.scalar(
|
||||
"select count() from (select id from cards where "
|
||||
"queue = 0 %s limit %d)" % (self._groupLimit(), lim))
|
||||
|
@ -760,7 +760,7 @@ queue = 2 %s and due <= :lim order by %s limit %d""" % (
|
|||
def updateDynamicIndices(self):
|
||||
# determine required columns
|
||||
required = []
|
||||
if self.deck.qconf['revOrder'] in (
|
||||
if self.deck.conf['revOrder'] in (
|
||||
REV_CARDS_OLD_FIRST, REV_CARDS_NEW_FIRST):
|
||||
required.append("interval")
|
||||
cols = ["queue", "due", "gid"] + required
|
||||
|
|
|
@ -675,7 +675,7 @@ $(function () {
|
|||
return ""
|
||||
|
||||
def _revlogLimit(self):
|
||||
lim = self.deck.qconf['groups']
|
||||
lim = self.deck.conf['groups']
|
||||
if self.selective and lim:
|
||||
return ("cid in (select id from cards where gid in %s)" %
|
||||
ids2str(lim))
|
||||
|
|
|
@ -65,7 +65,6 @@ create table if not exists deck (
|
|||
dty integer not null,
|
||||
syncName text not null,
|
||||
lastSync integer not null,
|
||||
qconf text not null,
|
||||
conf text not null,
|
||||
models text not null,
|
||||
groups text not null,
|
||||
|
@ -127,14 +126,13 @@ create table if not exists revlog (
|
|||
);
|
||||
|
||||
insert or ignore into deck
|
||||
values(1,0,0,0,%(v)s,0,'',0,'','','{}','','','{}');
|
||||
values(1,0,0,0,%(v)s,0,'',0,'','{}','','','{}');
|
||||
""" % ({'v':CURRENT_VERSION}))
|
||||
import anki.deck
|
||||
import anki.groups
|
||||
if setDeckConf:
|
||||
db.execute("""
|
||||
update deck set qconf = ?, conf = ?, groups = ?, gconf = ?""",
|
||||
simplejson.dumps(anki.deck.defaultQconf),
|
||||
update deck set conf = ?, groups = ?, gconf = ?""",
|
||||
simplejson.dumps(anki.deck.defaultConf),
|
||||
simplejson.dumps({'1': {'name': _("Default"), 'conf': 1,
|
||||
'mod': intTime()}}),
|
||||
|
@ -339,30 +337,29 @@ def _migrateDeckTbl(db):
|
|||
db.execute("""
|
||||
insert or replace into deck select id, cast(created as int), :t,
|
||||
:t, 99, 0, ifnull(syncName, ""), cast(lastSync as int),
|
||||
"", "", "", "", "", "" from decks""", t=intTime())
|
||||
"", "", "", "", "" from decks""", t=intTime())
|
||||
# update selective study
|
||||
qconf = anki.deck.defaultQconf.copy()
|
||||
conf = anki.deck.defaultConf.copy()
|
||||
# delete old selective study settings, which we can't auto-upgrade easily
|
||||
keys = ("newActive", "newInactive", "revActive", "revInactive")
|
||||
for k in keys:
|
||||
db.execute("delete from deckVars where key=:k", k=k)
|
||||
# copy other settings, ignoring deck order as there's a new default
|
||||
qconf['newSpread'] = db.scalar(
|
||||
conf['newSpread'] = db.scalar(
|
||||
"select newCardSpacing from decks")
|
||||
qconf['newOrder'] = db.scalar(
|
||||
conf['newOrder'] = db.scalar(
|
||||
"select newCardOrder from decks")
|
||||
qconf['newPerDay'] = db.scalar(
|
||||
conf['newPerDay'] = db.scalar(
|
||||
"select newCardsPerDay from decks")
|
||||
# fetch remaining settings from decks table
|
||||
conf = anki.deck.defaultConf.copy()
|
||||
data = {}
|
||||
keys = ("sessionRepLimit", "sessionTimeLimit")
|
||||
for k in keys:
|
||||
conf[k] = db.scalar("select %s from decks" % k)
|
||||
# random and due options merged
|
||||
qconf['revOrder'] = 2
|
||||
conf['revOrder'] = 2
|
||||
# no reverse option anymore
|
||||
qconf['newOrder'] = min(1, qconf['newOrder'])
|
||||
conf['newOrder'] = min(1, conf['newOrder'])
|
||||
# add any deck vars and save
|
||||
dkeys = ("hexCache", "cssCache")
|
||||
for (k, v) in db.execute("select * from deckVars").fetchall():
|
||||
|
@ -371,8 +368,7 @@ insert or replace into deck select id, cast(created as int), :t,
|
|||
else:
|
||||
conf[k] = v
|
||||
import anki.groups
|
||||
db.execute("update deck set qconf = :l,conf = :c,groups=:g,gconf=:gc",
|
||||
l=simplejson.dumps(qconf),
|
||||
db.execute("update deck set conf=:c,groups=:g,gconf=:gc",
|
||||
c=simplejson.dumps(conf),
|
||||
g=simplejson.dumps({'1': {'name': _("Default"), 'conf': 1}}),
|
||||
gc=simplejson.dumps({'1': anki.groups.defaultConf}))
|
||||
|
|
|
@ -18,7 +18,7 @@ def test_genCards():
|
|||
assert deck.cardCount() == 2
|
||||
assert cards[0].due == f.id
|
||||
# should work on random mode too
|
||||
deck.qconf['newOrder'] = NEW_CARDS_RANDOM
|
||||
deck.conf['newOrder'] = NEW_CARDS_RANDOM
|
||||
f = deck.newFact()
|
||||
f['Front'] = u'1'
|
||||
f['Back'] = u'2'
|
||||
|
|
|
@ -143,7 +143,7 @@ def test_groups():
|
|||
# should get the same id
|
||||
assert deck.groups.id("new group") == g
|
||||
# by default, everything should be shown
|
||||
assert not deck.qconf['groups']
|
||||
assert not deck.conf['groups']
|
||||
|
||||
def test_selective():
|
||||
deck = getEmptyDeck()
|
||||
|
|
|
@ -65,7 +65,7 @@ def test_newOrder():
|
|||
d.addFact(f)
|
||||
# generate second half
|
||||
d.db.execute("update cards set gid = random()")
|
||||
d.qconf['newPerDay'] = 100
|
||||
d.conf['newPerDay'] = 100
|
||||
d.reset()
|
||||
# cards should be sorted by id
|
||||
assert d.sched.newQueue == list(reversed(sorted(d.sched.newQueue)))
|
||||
|
@ -387,7 +387,7 @@ def test_cram():
|
|||
c.startTimer()
|
||||
c.flush()
|
||||
cardcopy = copy.copy(c)
|
||||
d.qconf['groups'] = [1]
|
||||
d.conf['groups'] = [1]
|
||||
d.cramGroups()
|
||||
# first, test with initial intervals preserved
|
||||
conf = d.sched._lrnConf(c)
|
||||
|
@ -449,7 +449,7 @@ def test_cram():
|
|||
assert c.ivl == 1
|
||||
assert c.due == d.sched.today + 1
|
||||
# users should be able to cram entire deck too
|
||||
d.qconf['groups'] = []
|
||||
d.conf['groups'] = []
|
||||
d.cramGroups()
|
||||
assert d.sched.counts()[0] > 0
|
||||
|
||||
|
@ -465,7 +465,7 @@ def test_cramLimits():
|
|||
c.due = d.sched.today + 1 + i
|
||||
c.flush()
|
||||
# the default cram should return all three
|
||||
d.qconf['groups'] = [1]
|
||||
d.conf['groups'] = [1]
|
||||
d.cramGroups()
|
||||
assert d.sched.counts()[0] == 3
|
||||
# if we start from the day after tomorrow, it should be 2
|
||||
|
@ -601,7 +601,7 @@ def test_counts():
|
|||
# with the default settings, there's no count limit
|
||||
assert d.sched.counts() == (2,2,2)
|
||||
# check limit to one group
|
||||
d.qconf['groups'] = [1]
|
||||
d.conf['groups'] = [1]
|
||||
d.reset()
|
||||
assert d.sched.counts() == (1,1,1)
|
||||
# we don't need to build the queue to get the counts
|
||||
|
|
|
@ -7,9 +7,9 @@ def test_op():
|
|||
# should have no undo by default
|
||||
assert not d.undoName()
|
||||
# let's adjust a study option
|
||||
assert d.qconf['repLim'] == 0
|
||||
assert d.conf['repLim'] == 0
|
||||
d.save("studyopts")
|
||||
d.qconf['repLim'] = 10
|
||||
d.conf['repLim'] = 10
|
||||
# it should be listed as undoable
|
||||
assert d.undoName() == "studyopts"
|
||||
# with about 5 minutes until it's clobbered
|
||||
|
@ -17,7 +17,7 @@ def test_op():
|
|||
# undoing should restore the old value
|
||||
d.undo()
|
||||
assert not d.undoName()
|
||||
assert d.qconf['repLim'] == 0
|
||||
assert d.conf['repLim'] == 0
|
||||
# an (auto)save will clear the undo
|
||||
d.save("foo")
|
||||
assert d.undoName() == "foo"
|
||||
|
|
Loading…
Reference in a new issue