diff --git a/anki/deck.py b/anki/deck.py index a6fb30a1b..dd483793b 100644 --- a/anki/deck.py +++ b/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 ########################################################################## diff --git a/anki/sched.py b/anki/sched.py index f3758a8e5..988ba7426 100644 --- a/anki/sched.py +++ b/anki/sched.py @@ -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 diff --git a/anki/stats.py b/anki/stats.py index 08f899fc7..286dcd080 100644 --- a/anki/stats.py +++ b/anki/stats.py @@ -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)) diff --git a/anki/storage.py b/anki/storage.py index da15eee58..471c53f52 100644 --- a/anki/storage.py +++ b/anki/storage.py @@ -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})) diff --git a/tests/test_cards.py b/tests/test_cards.py index fc348d395..0ee8f5209 100644 --- a/tests/test_cards.py +++ b/tests/test_cards.py @@ -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' diff --git a/tests/test_deck.py b/tests/test_deck.py index d9330ebaf..8f47f8629 100644 --- a/tests/test_deck.py +++ b/tests/test_deck.py @@ -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() diff --git a/tests/test_sched.py b/tests/test_sched.py index 321e8947b..10d3d49af 100644 --- a/tests/test_sched.py +++ b/tests/test_sched.py @@ -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 diff --git a/tests/test_undo.py b/tests/test_undo.py index 755e80ee6..dd909fc6a 100644 --- a/tests/test_undo.py +++ b/tests/test_undo.py @@ -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"